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 private static final boolean USE_HANDLER = false;
100 public static Pattern parse(String text) throws JaxenException, org.jaxen.saxpath.SAXPathException
101 {
102 if ( USE_HANDLER )
103 {
104 XPathReader reader = XPathReaderFactory.createReader();
105 PatternHandler handler = new PatternHandler();
106
107 handler.setXPathFactory( new DefaultXPathFactory() );
108 reader.setXPathHandler( handler );
109 reader.parse( text );
110
111 return handler.getPattern();
112 }
113 else
114 {
115 XPathReader reader = XPathReaderFactory.createReader();
116 JaxenHandler handler = new JaxenHandler();
117
118 handler.setXPathFactory( new DefaultXPathFactory() );
119 reader.setXPathHandler( handler );
120 reader.parse( text );
121
122 Pattern pattern = convertExpr( handler.getXPathExpr().getRootExpr() );
123 return pattern.simplify();
124 }
125 }
126
127 protected static Pattern convertExpr(Expr expr) throws JaxenException
128 {
129 if ( TRACE )
130 {
131 System.out.println( "Converting: " + expr + " into a pattern." );
132 }
133
134 if ( expr instanceof LocationPath )
135 {
136 return convertExpr( (LocationPath) expr );
137 }
138 else if ( expr instanceof FilterExpr )
139 {
140 LocationPathPattern answer = new LocationPathPattern();
141 answer.addFilter( (FilterExpr) expr );
142 return answer;
143 }
144 else if ( expr instanceof UnionExpr )
145 {
146 UnionExpr unionExpr = (UnionExpr) expr;
147 Pattern lhs = convertExpr( unionExpr.getLHS() );
148 Pattern rhs = convertExpr( unionExpr.getRHS() );
149 return new UnionPattern( lhs, rhs );
150 }
151 else
152 {
153 LocationPathPattern answer = new LocationPathPattern();
154 answer.addFilter( new DefaultFilterExpr( expr,
155 new PredicateSet()) );
156 return answer;
157 }
158 }
159
160 protected static LocationPathPattern convertExpr(LocationPath locationPath) throws JaxenException
161 {
162 LocationPathPattern answer = new LocationPathPattern();
163
164 List steps = locationPath.getSteps();
165
166
167 LocationPathPattern path = answer;
168 boolean first = true;
169 for ( ListIterator iter = steps.listIterator( steps.size() ); iter.hasPrevious(); )
170 {
171 Step step = (Step) iter.previous();
172 if ( first )
173 {
174 first = false;
175 path = convertStep( path, step );
176 }
177 else
178 {
179 if ( navigationStep( step ) )
180 {
181 LocationPathPattern parent = new LocationPathPattern();
182 int axis = step.getAxis();
183 if ( axis == Axis.DESCENDANT || axis == Axis.DESCENDANT_OR_SELF )
184 {
185 path.setAncestorPattern( parent );
186 }
187 else
188 {
189 path.setParentPattern( parent );
190 }
191 path = parent;
192 }
193 path = convertStep( path, step );
194 }
195 }
196 if ( locationPath.isAbsolute() )
197 {
198 LocationPathPattern parent = new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
199 path.setParentPattern( parent );
200 }
201 return answer;
202 }
203
204 protected static LocationPathPattern convertStep(LocationPathPattern path, Step step) throws JaxenException
205 {
206 if ( step instanceof DefaultAllNodeStep )
207 {
208 int axis = step.getAxis();
209 if ( axis == Axis.ATTRIBUTE )
210 {
211 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
212 }
213 else
214 {
215 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
216 }
217 }
218 else if ( step instanceof DefaultCommentNodeStep )
219 {
220 path.setNodeTest( NodeTypeTest.COMMENT_TEST );
221 }
222 else if ( step instanceof DefaultProcessingInstructionNodeStep )
223 {
224 path.setNodeTest( NodeTypeTest.PROCESSING_INSTRUCTION_TEST );
225 }
226 else if ( step instanceof DefaultTextNodeStep )
227 {
228 path.setNodeTest( TextNodeTest.SINGLETON );
229 }
230 else if ( step instanceof DefaultCommentNodeStep )
231 {
232 path.setNodeTest( NodeTypeTest.COMMENT_TEST );
233 }
234 else if ( step instanceof DefaultNameStep )
235 {
236 DefaultNameStep nameStep = (DefaultNameStep) step;
237 String localName = nameStep.getLocalName();
238 String prefix = nameStep.getPrefix();
239 int axis = nameStep.getAxis();
240 short nodeType = Pattern.ELEMENT_NODE;
241 if ( axis == Axis.ATTRIBUTE )
242 {
243 nodeType = Pattern.ATTRIBUTE_NODE;
244 }
245 if ( nameStep.isMatchesAnyName() )
246 {
247 if ( prefix.length() == 0 || prefix.equals( "*" ) )
248 {
249 if ( axis == Axis.ATTRIBUTE )
250 {
251 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
252 }
253 else
254 {
255 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
256 }
257 }
258 else
259 {
260 path.setNodeTest( new NamespaceTest( prefix, nodeType ) );
261 }
262 }
263 else
264 {
265 path.setNodeTest( new NameTest( localName, nodeType ) );
266
267 }
268 return convertDefaultStep(path, nameStep);
269 }
270 else if ( step instanceof DefaultStep )
271 {
272 return convertDefaultStep(path, (DefaultStep) step);
273 }
274 else
275 {
276 throw new JaxenException( "Cannot convert: " + step + " to a Pattern" );
277 }
278 return path;
279 }
280
281 protected static LocationPathPattern convertDefaultStep(LocationPathPattern path, DefaultStep step) throws JaxenException
282 {
283 List predicates = step.getPredicates();
284 if ( ! predicates.isEmpty() )
285 {
286 DefaultFilterExpr filter = new DefaultFilterExpr(new PredicateSet());
287 for ( Iterator iter = predicates.iterator(); iter.hasNext(); )
288 {
289 filter.addPredicate( (Predicate) iter.next() );
290 }
291 path.addFilter( filter );
292 }
293 return path;
294 }
295
296 protected static boolean navigationStep( Step step )
297 {
298 if ( step instanceof DefaultNameStep )
299 {
300 return true;
301 }
302 else
303 if ( step.getClass().equals( DefaultStep.class ) )
304 {
305 return ! step.getPredicates().isEmpty();
306 }
307 else
308 {
309 return true;
310 }
311 }
312
313 }
314