1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| package org.apache.tapestry.test; |
16 |
| |
17 |
| import java.io.BufferedInputStream; |
18 |
| import java.io.IOException; |
19 |
| import java.io.InputStream; |
20 |
| import java.net.URL; |
21 |
| import java.util.HashMap; |
22 |
| import java.util.Iterator; |
23 |
| import java.util.Map; |
24 |
| import java.util.Properties; |
25 |
| |
26 |
| import javax.xml.parsers.SAXParser; |
27 |
| import javax.xml.parsers.SAXParserFactory; |
28 |
| |
29 |
| import org.apache.hivemind.ApplicationRuntimeException; |
30 |
| import org.apache.hivemind.Resource; |
31 |
| import org.apache.hivemind.parse.AbstractParser; |
32 |
| import org.apache.hivemind.parse.ElementParseInfo; |
33 |
| import org.apache.tapestry.test.assertions.AssertOutput; |
34 |
| import org.apache.tapestry.test.assertions.AssertRegexp; |
35 |
| import org.apache.tapestry.test.assertions.RegexpMatch; |
36 |
| import org.apache.tapestry.util.xml.DocumentParseException; |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| |
44 |
| |
45 |
| public class IntegrationTestScriptParser extends AbstractParser |
46 |
| { |
47 |
| private ScriptDescriptor _scriptDescriptor; |
48 |
| |
49 |
| private Map _attributes; |
50 |
| |
51 |
| private String _elementName; |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| private final Map _elementParseInfo = new HashMap(); |
57 |
| |
58 |
11
| public IntegrationTestScriptParser()
|
59 |
| { |
60 |
11
| initializeFromPropertiesFile();
|
61 |
| } |
62 |
| |
63 |
11
| private void initializeFromPropertiesFile()
|
64 |
| { |
65 |
11
| Properties p = new Properties();
|
66 |
11
| InputStream stream = null;
|
67 |
| |
68 |
11
| try
|
69 |
| { |
70 |
| |
71 |
11
| InputStream rawStream = getClass().getResourceAsStream("ScriptParser.properties");
|
72 |
11
| stream = new BufferedInputStream(rawStream);
|
73 |
| |
74 |
11
| p.load(stream);
|
75 |
| |
76 |
11
| stream.close();
|
77 |
11
| stream = null;
|
78 |
| } |
79 |
| catch (IOException ex) |
80 |
| { |
81 |
0
| throw new ApplicationRuntimeException(ex);
|
82 |
| } |
83 |
| finally |
84 |
| { |
85 |
11
| close(stream);
|
86 |
| } |
87 |
| |
88 |
11
| initializeFromProperties(p);
|
89 |
| } |
90 |
| |
91 |
11
| private void initializeFromProperties(Properties p)
|
92 |
| { |
93 |
11
| Iterator i = p.keySet().iterator();
|
94 |
11
| while (i.hasNext())
|
95 |
| { |
96 |
132
| String key = (String) i.next();
|
97 |
132
| String value = p.getProperty(key);
|
98 |
| |
99 |
132
| initializeFromProperty(key, value);
|
100 |
| } |
101 |
| } |
102 |
| |
103 |
132
| private void initializeFromProperty(String key, String value)
|
104 |
| { |
105 |
| |
106 |
| |
107 |
132
| if (!key.startsWith("required."))
|
108 |
11
| return;
|
109 |
| |
110 |
121
| int lastDotx = key.lastIndexOf('.');
|
111 |
| |
112 |
121
| String elementName = key.substring(9, lastDotx);
|
113 |
121
| String attributeName = key.substring(lastDotx + 1);
|
114 |
| |
115 |
121
| boolean required = value.equalsIgnoreCase("true");
|
116 |
| |
117 |
121
| ElementParseInfo epi = getElementParseInfo(elementName);
|
118 |
| |
119 |
121
| epi.addAttribute(attributeName, required);
|
120 |
| } |
121 |
| |
122 |
11
| private void close(InputStream stream)
|
123 |
| { |
124 |
11
| try
|
125 |
| { |
126 |
11
| if (stream != null)
|
127 |
0
| stream.close();
|
128 |
| } |
129 |
| catch (IOException ex) |
130 |
| { |
131 |
| |
132 |
| } |
133 |
| } |
134 |
| |
135 |
11
| public ScriptDescriptor parse(Resource script)
|
136 |
| { |
137 |
11
| initializeParser(script, STATE_INITIAL);
|
138 |
| |
139 |
11
| try
|
140 |
| { |
141 |
11
| startParse();
|
142 |
| |
143 |
8
| return _scriptDescriptor;
|
144 |
| } |
145 |
| finally |
146 |
| { |
147 |
11
| resetParser();
|
148 |
| } |
149 |
| } |
150 |
| |
151 |
11
| private void startParse()
|
152 |
| { |
153 |
11
| try
|
154 |
| { |
155 |
11
| SAXParserFactory factory = SAXParserFactory.newInstance();
|
156 |
| |
157 |
11
| SAXParser parser = factory.newSAXParser();
|
158 |
| |
159 |
11
| Resource resource = getResource();
|
160 |
| |
161 |
11
| URL url = resource.getResourceURL();
|
162 |
| |
163 |
11
| InputStream is = url.openStream();
|
164 |
| |
165 |
11
| parser.parse(is, this);
|
166 |
| } |
167 |
| catch (Exception ex) |
168 |
| { |
169 |
3
| throw new DocumentParseException(ex.getMessage(), getResource(), ex);
|
170 |
| } |
171 |
| } |
172 |
| |
173 |
11
| protected void initializeParser(Resource resource, int startState)
|
174 |
| { |
175 |
11
| super.initializeParser(resource, startState);
|
176 |
| |
177 |
11
| _attributes = new HashMap();
|
178 |
| } |
179 |
| |
180 |
11
| protected void resetParser()
|
181 |
| { |
182 |
11
| _attributes = null;
|
183 |
11
| _elementName = null;
|
184 |
11
| _scriptDescriptor = null;
|
185 |
| |
186 |
11
| super.resetParser();
|
187 |
| } |
188 |
| |
189 |
| private static final int STATE_INITIAL = 0; |
190 |
| |
191 |
| private static final int STATE_TEST_SCRIPT = 1; |
192 |
| |
193 |
| private static final int STATE_SERVLET = 2; |
194 |
| |
195 |
| private static final int STATE_REQUEST = 4; |
196 |
| |
197 |
| private static final int STATE_ASSERT_OUTPUT = 5; |
198 |
| |
199 |
| private static final int STATE_ASSERT_REGEXP = 6; |
200 |
| |
201 |
| private static final int STATE_MATCH = 7; |
202 |
| |
203 |
| private static final int STATE_NO_CONTENT = 1000; |
204 |
| |
205 |
39
| protected void begin(String elementName, Map attributes)
|
206 |
| { |
207 |
39
| _elementName = elementName;
|
208 |
39
| _attributes = attributes;
|
209 |
| |
210 |
39
| switch (getState())
|
211 |
| { |
212 |
11
| case STATE_INITIAL:
|
213 |
11
| beginInitial();
|
214 |
9
| break;
|
215 |
| |
216 |
14
| case STATE_TEST_SCRIPT:
|
217 |
14
| beginTestScript();
|
218 |
13
| break;
|
219 |
| |
220 |
3
| case STATE_SERVLET:
|
221 |
3
| beginServlet();
|
222 |
3
| break;
|
223 |
| |
224 |
7
| case STATE_REQUEST:
|
225 |
7
| beginRequest();
|
226 |
7
| break;
|
227 |
| |
228 |
4
| case STATE_ASSERT_REGEXP:
|
229 |
4
| beginAssertRegexp();
|
230 |
4
| break;
|
231 |
| |
232 |
0
| default:
|
233 |
0
| unexpectedElement(_elementName);
|
234 |
| } |
235 |
| } |
236 |
| |
237 |
35
| protected void end(String elementName)
|
238 |
| { |
239 |
35
| _elementName = elementName;
|
240 |
| |
241 |
35
| switch (getState())
|
242 |
| { |
243 |
1
| case STATE_ASSERT_OUTPUT:
|
244 |
| |
245 |
1
| endAssertOutput();
|
246 |
1
| break;
|
247 |
| |
248 |
2
| case STATE_ASSERT_REGEXP:
|
249 |
2
| endAssertRegexp();
|
250 |
2
| break;
|
251 |
| |
252 |
4
| case STATE_MATCH:
|
253 |
4
| endMatch();
|
254 |
4
| break;
|
255 |
| |
256 |
28
| default:
|
257 |
28
| break;
|
258 |
| } |
259 |
| |
260 |
35
| pop();
|
261 |
| |
262 |
| } |
263 |
| |
264 |
11
| private void beginInitial()
|
265 |
| { |
266 |
11
| if (_elementName.equals("test-script"))
|
267 |
| { |
268 |
11
| enterTestScript();
|
269 |
9
| return;
|
270 |
| } |
271 |
| |
272 |
0
| unexpectedElement(_elementName);
|
273 |
| } |
274 |
| |
275 |
14
| private void beginTestScript()
|
276 |
| { |
277 |
14
| if (_elementName.equals("servlet"))
|
278 |
| { |
279 |
7
| enterServlet();
|
280 |
6
| return;
|
281 |
| } |
282 |
| |
283 |
7
| if (_elementName.equals("request"))
|
284 |
| { |
285 |
7
| enterRequest();
|
286 |
7
| return;
|
287 |
| } |
288 |
| |
289 |
0
| unexpectedElement(_elementName);
|
290 |
| } |
291 |
| |
292 |
3
| private void beginServlet()
|
293 |
| { |
294 |
3
| if (_elementName.equals("init-parameter"))
|
295 |
| { |
296 |
3
| enterInitParameter();
|
297 |
3
| return;
|
298 |
| } |
299 |
| |
300 |
0
| unexpectedElement(_elementName);
|
301 |
| } |
302 |
| |
303 |
7
| private void enterRequest()
|
304 |
| { |
305 |
7
| validateAttributes();
|
306 |
| |
307 |
7
| String servletName = getAttribute("servlet");
|
308 |
7
| String servletPath = getAttribute("servlet-path", "/app");
|
309 |
| |
310 |
7
| RequestDescriptor rd = new RequestDescriptor();
|
311 |
7
| rd.setServletName(servletName);
|
312 |
7
| rd.setServletPath(servletPath);
|
313 |
| |
314 |
7
| ScriptDescriptor sd = (ScriptDescriptor) peekObject();
|
315 |
| |
316 |
7
| sd.addRequestDescriptor(rd);
|
317 |
| |
318 |
7
| push(_elementName, rd, STATE_REQUEST);
|
319 |
| } |
320 |
| |
321 |
7
| public void beginRequest()
|
322 |
| { |
323 |
7
| if (_elementName.equals("parameter"))
|
324 |
| { |
325 |
4
| enterParameter();
|
326 |
4
| return;
|
327 |
| } |
328 |
| |
329 |
3
| if (_elementName.equals("assert-output"))
|
330 |
| { |
331 |
1
| enterAssertOutput();
|
332 |
1
| return;
|
333 |
| } |
334 |
| |
335 |
2
| if (_elementName.equals("assert-regexp"))
|
336 |
| { |
337 |
2
| enterAssertRegexp();
|
338 |
2
| return;
|
339 |
| } |
340 |
| |
341 |
0
| unexpectedElement(_elementName);
|
342 |
| } |
343 |
| |
344 |
1
| private void enterAssertOutput()
|
345 |
| { |
346 |
1
| validateAttributes();
|
347 |
| |
348 |
1
| AssertOutput ao = new AssertOutput();
|
349 |
1
| RequestDescriptor rd = (RequestDescriptor) peekObject();
|
350 |
| |
351 |
1
| rd.addAssertion(ao);
|
352 |
| |
353 |
1
| push(_elementName, ao, STATE_ASSERT_OUTPUT, false);
|
354 |
| } |
355 |
| |
356 |
2
| private void enterAssertRegexp()
|
357 |
| { |
358 |
2
| validateAttributes();
|
359 |
| |
360 |
2
| int subgroup = getIntAttribute("subgroup", 0);
|
361 |
| |
362 |
2
| AssertRegexp ar = new AssertRegexp();
|
363 |
2
| ar.setSubgroup(subgroup);
|
364 |
| |
365 |
2
| RequestDescriptor rd = (RequestDescriptor) peekObject();
|
366 |
| |
367 |
2
| rd.addAssertion(ar);
|
368 |
| |
369 |
2
| push(_elementName, ar, STATE_ASSERT_REGEXP, false);
|
370 |
| } |
371 |
| |
372 |
4
| private void beginAssertRegexp()
|
373 |
| { |
374 |
4
| if (_elementName.equals("match"))
|
375 |
| { |
376 |
4
| enterMatch();
|
377 |
4
| return;
|
378 |
| } |
379 |
| |
380 |
0
| unexpectedElement(_elementName);
|
381 |
| } |
382 |
| |
383 |
4
| private void enterMatch()
|
384 |
| { |
385 |
4
| validateAttributes();
|
386 |
| |
387 |
4
| RegexpMatch m = new RegexpMatch();
|
388 |
4
| AssertRegexp ar = (AssertRegexp) peekObject();
|
389 |
| |
390 |
4
| ar.addMatch(m);
|
391 |
| |
392 |
4
| push(_elementName, m, STATE_MATCH, false);
|
393 |
| } |
394 |
| |
395 |
1
| private void endAssertOutput()
|
396 |
| { |
397 |
1
| String content = peekContent();
|
398 |
1
| AssertOutput ao = (AssertOutput) peekObject();
|
399 |
| |
400 |
1
| ao.setExpectedSubstring(content);
|
401 |
| } |
402 |
| |
403 |
2
| private void endAssertRegexp()
|
404 |
| { |
405 |
2
| String content = peekContent();
|
406 |
| |
407 |
2
| AssertRegexp ar = (AssertRegexp) peekObject();
|
408 |
| |
409 |
2
| ar.setRegexp(content);
|
410 |
| } |
411 |
| |
412 |
4
| private void endMatch()
|
413 |
| { |
414 |
4
| String content = peekContent();
|
415 |
| |
416 |
4
| RegexpMatch m = (RegexpMatch) peekObject();
|
417 |
| |
418 |
4
| m.setExpectedString(content);
|
419 |
| } |
420 |
| |
421 |
7
| protected String peekContent()
|
422 |
| { |
423 |
7
| String rawContent = super.peekContent();
|
424 |
| |
425 |
7
| if (rawContent == null)
|
426 |
0
| return null;
|
427 |
| |
428 |
7
| return rawContent.trim();
|
429 |
| } |
430 |
| |
431 |
4
| private void enterParameter()
|
432 |
| { |
433 |
4
| validateAttributes();
|
434 |
| |
435 |
4
| String name = getAttribute("name");
|
436 |
4
| String value = getAttribute("value");
|
437 |
| |
438 |
4
| RequestDescriptor rd = (RequestDescriptor) peekObject();
|
439 |
| |
440 |
4
| rd.addParameter(name, value);
|
441 |
| |
442 |
4
| push(_elementName, null, STATE_NO_CONTENT);
|
443 |
| } |
444 |
| |
445 |
3
| private void enterInitParameter()
|
446 |
| { |
447 |
3
| validateAttributes();
|
448 |
| |
449 |
3
| String name = getAttribute("name");
|
450 |
3
| String value = getAttribute("value");
|
451 |
| |
452 |
3
| ServletDescriptor sd = (ServletDescriptor) peekObject();
|
453 |
| |
454 |
3
| sd.addInitParameter(name, value);
|
455 |
| |
456 |
3
| push(_elementName, null, STATE_NO_CONTENT);
|
457 |
| } |
458 |
| |
459 |
11
| private void enterTestScript()
|
460 |
| { |
461 |
11
| validateAttributes();
|
462 |
| |
463 |
9
| String contextName = getAttribute("context");
|
464 |
9
| String directory = getAttribute("directory");
|
465 |
| |
466 |
9
| ScriptDescriptor sd = new ScriptDescriptor();
|
467 |
9
| sd.setContextName(contextName);
|
468 |
9
| sd.setRootDirectory(directory);
|
469 |
| |
470 |
9
| _scriptDescriptor = sd;
|
471 |
| |
472 |
9
| push(_elementName, sd, STATE_TEST_SCRIPT);
|
473 |
| } |
474 |
| |
475 |
7
| private void enterServlet()
|
476 |
| { |
477 |
7
| validateAttributes();
|
478 |
| |
479 |
7
| String name = getAttribute("name");
|
480 |
7
| String className = getAttribute("class", "org.apache.tapestry.ApplicationServlet");
|
481 |
| |
482 |
7
| ServletDescriptor sd = new ServletDescriptor();
|
483 |
7
| sd.setName(name);
|
484 |
7
| sd.setClassName(className);
|
485 |
| |
486 |
| |
487 |
| |
488 |
7
| sd.setLocation(getLocation());
|
489 |
| |
490 |
7
| ScriptDescriptor scriptDescriptor = (ScriptDescriptor) peekObject();
|
491 |
| |
492 |
7
| scriptDescriptor.addServletDescriptor(sd);
|
493 |
| |
494 |
6
| push(_elementName, sd, STATE_SERVLET);
|
495 |
| } |
496 |
| |
497 |
48
| private String getAttribute(String name)
|
498 |
| { |
499 |
48
| return (String) _attributes.get(name);
|
500 |
| } |
501 |
| |
502 |
14
| private String getAttribute(String name, String defaultValue)
|
503 |
| { |
504 |
14
| if (!_attributes.containsKey(name))
|
505 |
11
| return defaultValue;
|
506 |
| |
507 |
3
| return (String) _attributes.get(name);
|
508 |
| } |
509 |
| |
510 |
39
| private void validateAttributes()
|
511 |
| { |
512 |
39
| Iterator i = _attributes.keySet().iterator();
|
513 |
| |
514 |
39
| ElementParseInfo epi = getElementParseInfo(_elementName);
|
515 |
| |
516 |
| |
517 |
| |
518 |
39
| while (i.hasNext())
|
519 |
| { |
520 |
46
| String name = (String) i.next();
|
521 |
| |
522 |
46
| if (!epi.isKnown(name))
|
523 |
1
| throw new DocumentParseException(ScriptMessages.unexpectedAttributeInElement(
|
524 |
| name, |
525 |
| _elementName), getLocation(), null); |
526 |
| } |
527 |
| |
528 |
| |
529 |
| |
530 |
38
| i = epi.getRequiredNames();
|
531 |
38
| while (i.hasNext())
|
532 |
| { |
533 |
31
| String name = (String) i.next();
|
534 |
| |
535 |
31
| if (!_attributes.containsKey(name))
|
536 |
1
| throw new DocumentParseException(ScriptMessages.missingRequiredAttribute(
|
537 |
| name, |
538 |
| _elementName), getLocation(), null); |
539 |
| } |
540 |
| |
541 |
| } |
542 |
| |
543 |
160
| private ElementParseInfo getElementParseInfo(String elementName)
|
544 |
| { |
545 |
160
| ElementParseInfo result = (ElementParseInfo) _elementParseInfo.get(elementName);
|
546 |
| |
547 |
160
| if (result == null)
|
548 |
| { |
549 |
68
| result = new ElementParseInfo();
|
550 |
68
| _elementParseInfo.put(elementName, result);
|
551 |
| } |
552 |
| |
553 |
160
| return result;
|
554 |
| } |
555 |
| |
556 |
2
| private int getIntAttribute(String name, int defaultValue)
|
557 |
| { |
558 |
2
| String attributeValue = getAttribute(name);
|
559 |
| |
560 |
2
| if (attributeValue == null)
|
561 |
1
| return defaultValue;
|
562 |
| |
563 |
1
| try
|
564 |
| { |
565 |
1
| return Integer.parseInt(attributeValue);
|
566 |
| } |
567 |
| catch (NumberFormatException ex) |
568 |
| { |
569 |
0
| throw new ApplicationRuntimeException(ScriptMessages.invalidIntAttribute(
|
570 |
| name, |
571 |
| _elementName, |
572 |
| getLocation(), |
573 |
| attributeValue), getLocation(), ex); |
574 |
| } |
575 |
| } |
576 |
| } |