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