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 package org.jaxen.pattern;
64
65 import java.util.Iterator;
66 import java.util.List;
67 import java.util.ListIterator;
68
69 import org.jaxen.JaxenException;
70 import org.jaxen.JaxenHandler;
71 import org.jaxen.expr.DefaultAllNodeStep;
72 import org.jaxen.expr.DefaultCommentNodeStep;
73 import org.jaxen.expr.DefaultFilterExpr;
74 import org.jaxen.expr.DefaultNameStep;
75 import org.jaxen.expr.DefaultProcessingInstructionNodeStep;
76 import org.jaxen.expr.DefaultStep;
77 import org.jaxen.expr.DefaultTextNodeStep;
78 import org.jaxen.expr.DefaultXPathFactory;
79 import org.jaxen.expr.Expr;
80 import org.jaxen.expr.FilterExpr;
81 import org.jaxen.expr.LocationPath;
82 import org.jaxen.expr.Predicate;
83 import org.jaxen.expr.PredicateSet;
84 import org.jaxen.expr.Step;
85 import org.jaxen.expr.UnionExpr;
86 import org.jaxen.saxpath.Axis;
87 import org.jaxen.saxpath.XPathReader;
88 import org.jaxen.saxpath.helpers.XPathReaderFactory;
89
90
91 /*** <code>PatternParser</code> is a helper class for parsing
92 * XSLT patterns
93 *
94 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
95 */
96 public class PatternParser
97 {
98 private static final boolean TRACE = false;
99
100 private static final boolean USE_HANDLER = false;
101
102 public static Pattern parse(String text) throws JaxenException, org.jaxen.saxpath.SAXPathException
103
104 {
105
106 if ( USE_HANDLER )
107
108 {
109
110 XPathReader reader = XPathReaderFactory.createReader();
111
112 PatternHandler handler = new PatternHandler();
113
114
115
116 handler.setXPathFactory( new DefaultXPathFactory() );
117
118 reader.setXPathHandler( handler );
119
120 reader.parse( text );
121
122
123
124 return handler.getPattern();
125
126 }
127
128 else
129
130 {
131
132 XPathReader reader = XPathReaderFactory.createReader();
133
134 JaxenHandler handler = new JaxenHandler();
135
136
137
138 handler.setXPathFactory( new DefaultXPathFactory() );
139
140 reader.setXPathHandler( handler );
141
142 reader.parse( text );
143
144
145
146 Pattern pattern = convertExpr( handler.getXPathExpr().getRootExpr() );
147
148 return pattern.simplify();
149
150 }
151
152 }
153
154
155
156 protected static Pattern convertExpr(Expr expr) throws JaxenException
157
158 {
159
160 if ( TRACE )
161
162 {
163
164 System.out.println( "Converting: " + expr + " into a pattern." );
165
166 }
167
168
169
170 if ( expr instanceof LocationPath )
171
172 {
173
174 return convertExpr( (LocationPath) expr );
175
176 }
177
178 else if ( expr instanceof FilterExpr )
179
180 {
181
182 LocationPathPattern answer = new LocationPathPattern();
183
184 answer.addFilter( (FilterExpr) expr );
185
186 return answer;
187
188 }
189
190 else if ( expr instanceof UnionExpr )
191
192 {
193
194 UnionExpr unionExpr = (UnionExpr) expr;
195
196 Pattern lhs = convertExpr( unionExpr.getLHS() );
197
198 Pattern rhs = convertExpr( unionExpr.getRHS() );
199
200 return new UnionPattern( lhs, rhs );
201
202 }
203
204 else
205
206 {
207
208 LocationPathPattern answer = new LocationPathPattern();
209
210 answer.addFilter( new DefaultFilterExpr( expr,
211 new PredicateSet()) );
212
213 return answer;
214
215 }
216
217 }
218
219
220
221 protected static LocationPathPattern convertExpr(LocationPath locationPath) throws JaxenException
222
223 {
224
225 LocationPathPattern answer = new LocationPathPattern();
226
227
228
229 List steps = locationPath.getSteps();
230
231
232
233
234
235 LocationPathPattern path = answer;
236
237 boolean first = true;
238
239 for ( ListIterator iter = steps.listIterator( steps.size() ); iter.hasPrevious(); )
240
241 {
242
243 Step step = (Step) iter.previous();
244
245 if ( first )
246
247 {
248
249 first = false;
250
251 path = convertStep( path, step );
252
253 }
254
255 else
256
257 {
258
259 if ( navigationStep( step ) )
260
261 {
262
263 LocationPathPattern parent = new LocationPathPattern();
264
265 int axis = step.getAxis();
266
267 if ( axis == Axis.DESCENDANT || axis == Axis.DESCENDANT_OR_SELF )
268
269 {
270
271 path.setAncestorPattern( parent );
272
273 }
274
275 else
276
277 {
278
279 path.setParentPattern( parent );
280
281 }
282
283 path = parent;
284
285 }
286
287 path = convertStep( path, step );
288
289 }
290
291 }
292
293 if ( locationPath.isAbsolute() )
294
295 {
296
297 LocationPathPattern parent = new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
298
299 path.setParentPattern( parent );
300
301 }
302
303 return answer;
304
305 }
306
307
308
309 protected static LocationPathPattern convertStep(LocationPathPattern path, Step step) throws JaxenException
310
311 {
312
313 if ( step instanceof DefaultAllNodeStep )
314
315 {
316
317 int axis = step.getAxis();
318
319 if ( axis == Axis.ATTRIBUTE )
320
321 {
322
323 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
324
325 }
326
327 else
328
329 {
330
331 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
332
333 }
334
335 }
336
337 else if ( step instanceof DefaultCommentNodeStep )
338
339 {
340
341 path.setNodeTest( NodeTypeTest.COMMENT_TEST );
342
343 }
344
345 else if ( step instanceof DefaultProcessingInstructionNodeStep )
346
347 {
348
349 path.setNodeTest( NodeTypeTest.PROCESSING_INSTRUCTION_TEST );
350
351 }
352
353 else if ( step instanceof DefaultTextNodeStep )
354
355 {
356
357 path.setNodeTest( TextNodeTest.SINGLETON );
358
359 }
360
361 else if ( step instanceof DefaultCommentNodeStep )
362
363 {
364
365 path.setNodeTest( NodeTypeTest.COMMENT_TEST );
366
367 }
368
369 else if ( step instanceof DefaultNameStep )
370
371 {
372
373 DefaultNameStep nameStep = (DefaultNameStep) step;
374
375 String localName = nameStep.getLocalName();
376
377 String prefix = nameStep.getPrefix();
378
379 int axis = nameStep.getAxis();
380
381 short nodeType = Pattern.ELEMENT_NODE;
382
383 if ( axis == Axis.ATTRIBUTE )
384
385 {
386
387 nodeType = Pattern.ATTRIBUTE_NODE;
388
389 }
390
391 if ( nameStep.isMatchesAnyName() )
392
393 {
394
395 if ( prefix.length() == 0 || prefix.equals( "*" ) )
396
397 {
398
399 if ( axis == Axis.ATTRIBUTE )
400
401 {
402
403 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
404
405 }
406
407 else
408
409 {
410
411 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
412
413 }
414
415 }
416
417 else
418
419 {
420
421 path.setNodeTest( new NamespaceTest( prefix, nodeType ) );
422
423 }
424
425 }
426
427 else
428
429 {
430
431 path.setNodeTest( new NameTest( localName, nodeType ) );
432
433
434
435 }
436
437 return convertDefaultStep(path, nameStep);
438
439 }
440
441 else if ( step instanceof DefaultStep )
442
443 {
444
445 return convertDefaultStep(path, (DefaultStep) step);
446
447 }
448
449 else
450
451 {
452
453 throw new JaxenException( "Cannot convert: " + step + " to a Pattern" );
454
455 }
456
457 return path;
458
459 }
460
461
462
463 protected static LocationPathPattern convertDefaultStep(LocationPathPattern path, DefaultStep step) throws JaxenException
464
465 {
466
467 List predicates = step.getPredicates();
468
469 if ( ! predicates.isEmpty() )
470
471 {
472
473 DefaultFilterExpr filter = new DefaultFilterExpr(new PredicateSet());
474
475 for ( Iterator iter = predicates.iterator(); iter.hasNext(); )
476
477 {
478
479 filter.addPredicate( (Predicate) iter.next() );
480
481 }
482
483 path.addFilter( filter );
484
485 }
486
487 return path;
488
489 }
490
491
492
493 protected static boolean navigationStep( Step step )
494
495 {
496
497 if ( step instanceof DefaultNameStep )
498
499 {
500
501 return true;
502
503 }
504
505 else
506
507 if ( step.getClass().equals( DefaultStep.class ) )
508
509 {
510
511 return ! step.getPredicates().isEmpty();
512
513 }
514
515 else
516
517 {
518
519 return true;
520
521 }
522
523 }
524
525 }
526