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