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