1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 package org.jaxen;
65
66 import java.util.Iterator;
67 import java.util.LinkedList;
68
69 import org.jaxen.expr.DefaultXPathFactory;
70 import org.jaxen.expr.Expr;
71 import org.jaxen.expr.FilterExpr;
72 import org.jaxen.expr.FunctionCallExpr;
73 import org.jaxen.expr.LocationPath;
74 import org.jaxen.expr.Predicate;
75 import org.jaxen.expr.Predicated;
76 import org.jaxen.expr.Step;
77 import org.jaxen.expr.XPathExpr;
78 import org.jaxen.expr.XPathFactory;
79 import org.jaxen.saxpath.Operator;
80 import org.jaxen.saxpath.XPathHandler;
81
82 /*** SAXPath <code>XPathHandler</code> implementation capable
83 * of building Jaxen expression trees which can walk various
84 * different object models.
85 *
86 * @author bob mcwhirter (bob@werken.com)
87 */
88 public class JaxenHandler implements XPathHandler
89 {
90 private XPathFactory xpathFactory;
91 private XPathExpr xpath;
92 protected boolean simplified;
93
94 protected LinkedList stack;
95
96 /*** Construct.
97 */
98 public JaxenHandler()
99 {
100 this.stack = new LinkedList();
101 this.xpathFactory = new DefaultXPathFactory();
102 }
103
104 /*** Set the Jaxen <code>XPathFactory</code> to use
105 * during the parse to construct the XPath expression tree.
106 *
107 * @param xpathFactory the factory to use during the parse
108 */
109 public void setXPathFactory(XPathFactory xpathFactory)
110 {
111 this.xpathFactory = xpathFactory;
112 }
113
114 /*** Retrieve the Jaxen <code>XPathFactory</code> used
115 * during the parse to construct the XPath expression tree.
116 *
117 * @return the <code>XPathFactory</code> used during the parse.
118 */
119 public XPathFactory getXPathFactory()
120 {
121 return this.xpathFactory;
122 }
123
124 /*** Retrieve the simplified Jaxen XPath expression tree.
125 *
126 * <p>
127 * This method is only valid once <code>XPathReader.parse(...)</code>
128 * successfully returned.
129 * </p>
130 *
131 * @return the XPath expression tree
132 */
133 public XPathExpr getXPathExpr()
134 {
135 return getXPathExpr( true );
136 }
137
138 /*** Retrieve the Jaxen XPath expression tree, optionally
139 * simplified.
140 *
141 * <p>
142 * This method is only valid once <code>XPathReader.parse(...)</code>
143 * successfully returned.
144 * </p>
145 *
146 * @return the XPath expression tree
147 */
148 public XPathExpr getXPathExpr(boolean shouldSimplify)
149 {
150 if ( shouldSimplify && ! this.simplified )
151 {
152
153 this.xpath.simplify();
154 this.simplified = true;
155 }
156
157 return this.xpath;
158 }
159
160 public void startXPath() throws JaxenException
161 {
162
163 this.simplified = false;
164 pushFrame();
165 }
166
167 public void endXPath() throws JaxenException
168 {
169
170 this.xpath = getXPathFactory().createXPath( (Expr) pop() );
171
172 popFrame();
173 }
174
175 public void startPathExpr() throws JaxenException
176 {
177
178 pushFrame();
179 }
180
181 public void endPathExpr() throws JaxenException
182 {
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 FilterExpr filterExpr;
199 LocationPath locationPath;
200
201 Object popped;
202
203
204
205 if ( stackSize() == 2 )
206 {
207 locationPath = (LocationPath) pop();
208 filterExpr = (FilterExpr) pop();
209 }
210 else
211 {
212 popped = pop();
213
214 if ( popped instanceof LocationPath )
215 {
216 locationPath = (LocationPath) popped;
217 filterExpr = null;
218 }
219 else
220 {
221 locationPath = null;
222 filterExpr = (FilterExpr) popped;
223 }
224 }
225 popFrame();
226
227 push( getXPathFactory().createPathExpr( filterExpr,
228 locationPath ) );
229 }
230
231 public void startAbsoluteLocationPath() throws JaxenException
232 {
233
234 pushFrame();
235
236 push( getXPathFactory().createAbsoluteLocationPath() );
237 }
238
239 public void endAbsoluteLocationPath() throws JaxenException
240 {
241
242 endLocationPath();
243 }
244
245 public void startRelativeLocationPath() throws JaxenException
246 {
247
248 pushFrame();
249
250 push( getXPathFactory().createRelativeLocationPath() );
251 }
252
253 public void endRelativeLocationPath() throws JaxenException
254 {
255
256 endLocationPath();
257 }
258
259 protected void endLocationPath() throws JaxenException
260 {
261 LocationPath path = (LocationPath) peekFrame().removeFirst();
262
263 addSteps( path,
264 popFrame().iterator() );
265
266 push( path );
267 }
268
269 protected void addSteps(LocationPath locationPath,
270 Iterator stepIter)
271 {
272 while ( stepIter.hasNext() )
273 {
274 locationPath.addStep( (Step) stepIter.next() );
275 }
276 }
277
278 public void startNameStep(int axis,
279 String prefix,
280 String localName) throws JaxenException
281 {
282
283 pushFrame();
284
285 push( getXPathFactory().createNameStep( axis,
286 prefix,
287 localName ) );
288 }
289
290 public void endNameStep() throws JaxenException
291 {
292
293 endStep();
294 }
295
296 public void startTextNodeStep(int axis) throws JaxenException
297 {
298
299 pushFrame();
300
301 push( getXPathFactory().createTextNodeStep( axis ) );
302 }
303
304 public void endTextNodeStep() throws JaxenException
305 {
306
307 endStep();
308 }
309
310 public void startCommentNodeStep(int axis) throws JaxenException
311 {
312
313 pushFrame();
314
315 push( getXPathFactory().createCommentNodeStep( axis ) );
316 }
317
318 public void endCommentNodeStep() throws JaxenException
319 {
320
321 endStep();
322 }
323
324 public void startAllNodeStep(int axis) throws JaxenException
325 {
326
327 pushFrame();
328
329 push( getXPathFactory().createAllNodeStep( axis ) );
330 }
331
332 public void endAllNodeStep() throws JaxenException
333 {
334
335 endStep();
336 }
337
338 public void startProcessingInstructionNodeStep(int axis,
339 String name) throws JaxenException
340 {
341
342 pushFrame();
343
344 push( getXPathFactory().createProcessingInstructionNodeStep( axis,
345 name ) );
346 }
347
348 public void endProcessingInstructionNodeStep() throws JaxenException
349 {
350
351 endStep();
352 }
353
354 protected void endStep()
355 {
356 Step step = (Step) peekFrame().removeFirst();
357
358 addPredicates( step,
359 popFrame().iterator() );
360
361 push( step );
362 }
363
364 public void startPredicate() throws JaxenException
365 {
366
367 pushFrame();
368 }
369
370 public void endPredicate() throws JaxenException
371 {
372
373 Predicate predicate = getXPathFactory().createPredicate( (Expr) pop() );
374
375 popFrame();
376
377 push( predicate );
378 }
379
380 public void startFilterExpr() throws JaxenException
381 {
382
383 pushFrame();
384 }
385
386 public void endFilterExpr() throws JaxenException
387 {
388
389 Expr expr = (Expr) peekFrame().removeFirst();
390
391 FilterExpr filter = getXPathFactory().createFilterExpr( expr );
392
393 Iterator predIter = popFrame().iterator();
394
395 addPredicates( filter,
396 predIter );
397
398 push( filter );
399 }
400
401 protected void addPredicates(Predicated obj,
402 Iterator predIter)
403 {
404 while ( predIter.hasNext() )
405 {
406 obj.addPredicate( (Predicate) predIter.next() );
407 }
408 }
409
410 protected void returnExpr()
411 {
412 Expr expr = (Expr) pop();
413 popFrame();
414 push( expr );
415 }
416
417 public void startOrExpr() throws JaxenException
418 {
419
420 }
421
422 public void endOrExpr(boolean create) throws JaxenException
423 {
424
425
426 if ( create )
427 {
428
429 Expr rhs = (Expr) pop();
430 Expr lhs = (Expr) pop();
431
432 push( getXPathFactory().createOrExpr( lhs,
433 rhs ) );
434 }
435 }
436
437 public void startAndExpr() throws JaxenException
438 {
439
440 }
441
442 public void endAndExpr(boolean create) throws JaxenException
443 {
444
445
446 if ( create )
447 {
448
449
450 Expr rhs = (Expr) pop();
451 Expr lhs = (Expr) pop();
452
453 push( getXPathFactory().createAndExpr( lhs,
454 rhs ) );
455 }
456 }
457
458 public void startEqualityExpr() throws JaxenException
459 {
460
461 }
462
463 public void endEqualityExpr(int operator) throws JaxenException
464 {
465
466
467 if ( operator != Operator.NO_OP )
468 {
469
470
471 Expr rhs = (Expr) pop();
472 Expr lhs = (Expr) pop();
473
474 push( getXPathFactory().createEqualityExpr( lhs,
475 rhs,
476 operator ) );
477 }
478 }
479
480 public void startRelationalExpr() throws JaxenException
481 {
482
483 }
484
485 public void endRelationalExpr(int operator) throws JaxenException
486 {
487
488
489 if ( operator != Operator.NO_OP )
490 {
491
492
493 Expr rhs = (Expr) pop();
494 Expr lhs = (Expr) pop();
495
496 push( getXPathFactory().createRelationalExpr( lhs,
497 rhs,
498 operator ) );
499 }
500 }
501
502 public void startAdditiveExpr() throws JaxenException
503 {
504
505 }
506
507 public void endAdditiveExpr(int operator) throws JaxenException
508 {
509
510
511 if ( operator != Operator.NO_OP )
512 {
513
514
515 Expr rhs = (Expr) pop();
516 Expr lhs = (Expr) pop();
517
518 push( getXPathFactory().createAdditiveExpr( lhs,
519 rhs,
520 operator ) );
521 }
522 }
523
524 public void startMultiplicativeExpr() throws JaxenException
525 {
526
527 }
528
529 public void endMultiplicativeExpr(int operator) throws JaxenException
530 {
531
532
533 if ( operator != Operator.NO_OP )
534 {
535
536
537 Expr rhs = (Expr) pop();
538 Expr lhs = (Expr) pop();
539
540 push( getXPathFactory().createMultiplicativeExpr( lhs,
541 rhs,
542 operator ) );
543 }
544 }
545
546 public void startUnaryExpr() throws JaxenException
547 {
548
549 }
550
551 public void endUnaryExpr(int operator) throws JaxenException
552 {
553
554
555 if ( operator != Operator.NO_OP )
556 {
557 push( getXPathFactory().createUnaryExpr( (Expr) pop(),
558 operator ) );
559 }
560 }
561
562 public void startUnionExpr() throws JaxenException
563 {
564
565 }
566
567 public void endUnionExpr(boolean create) throws JaxenException
568 {
569
570 if ( create )
571 {
572
573 Expr rhs = (Expr) pop();
574 Expr lhs = (Expr) pop();
575
576 push( getXPathFactory().createUnionExpr( lhs,
577 rhs ) );
578 }
579 }
580
581 public void number(int number) throws JaxenException
582 {
583
584 push( getXPathFactory().createNumberExpr( number ) );
585 }
586
587 public void number(double number) throws JaxenException
588 {
589
590 push( getXPathFactory().createNumberExpr( number ) );
591 }
592
593 public void literal(String literal) throws JaxenException
594 {
595 push( getXPathFactory().createLiteralExpr( literal ) );
596 }
597
598 public void variableReference(String prefix,
599 String variableName) throws JaxenException
600 {
601 push( getXPathFactory().createVariableReferenceExpr( prefix,
602 variableName ) );
603 }
604
605 public void startFunction(String prefix,
606 String functionName) throws JaxenException
607 {
608 pushFrame();
609 push( getXPathFactory().createFunctionCallExpr( prefix,
610 functionName ) );
611 }
612
613 public void endFunction() throws JaxenException
614 {
615 FunctionCallExpr function = (FunctionCallExpr) peekFrame().removeFirst();
616
617 addParameters( function,
618 popFrame().iterator() );
619
620 push( function );
621 }
622
623 protected void addParameters(FunctionCallExpr function,
624 Iterator paramIter)
625 {
626 while ( paramIter.hasNext() )
627 {
628 function.addParameter( (Expr) paramIter.next() );
629 }
630 }
631
632 protected int stackSize()
633 {
634 return peekFrame().size();
635 }
636
637 protected void push(Object obj)
638 {
639 peekFrame().addLast( obj );
640
641
642 }
643
644 protected Object pop()
645 {
646
647 return peekFrame().removeLast();
648 }
649
650 protected boolean canPop()
651 {
652 return ( peekFrame().size() > 0 );
653 }
654
655 protected void pushFrame()
656 {
657 this.stack.addLast( new LinkedList() );
658
659 }
660
661 protected LinkedList popFrame()
662 {
663
664 return (LinkedList) this.stack.removeLast();
665 }
666
667 protected LinkedList peekFrame()
668 {
669 return (LinkedList) this.stack.getLast();
670 }
671 }