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