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