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 package org.jaxen.pattern;
49
50 import java.util.ArrayList;
51 import java.util.Iterator;
52 import java.util.List;
53
54 import org.jaxen.Context;
55 import org.jaxen.JaxenException;
56 import org.jaxen.Navigator;
57 import org.jaxen.expr.FilterExpr;
58 import org.jaxen.util.SingletonList;
59
60
61
62
63
64
65
66
67
68
69 public class LocationPathPattern extends Pattern {
70
71
72 private NodeTest nodeTest = AnyNodeTest.getInstance();
73
74
75 private Pattern parentPattern;
76
77
78 private Pattern ancestorPattern;
79
80
81 private List filters;
82
83
84 private boolean absolute;
85
86
87 public LocationPathPattern()
88 {
89 }
90
91 public LocationPathPattern(NodeTest nodeTest)
92 {
93 this.nodeTest = nodeTest;
94 }
95
96 public Pattern simplify()
97 {
98 if ( parentPattern != null )
99 {
100 parentPattern = parentPattern.simplify();
101 }
102 if ( ancestorPattern != null )
103 {
104 ancestorPattern = ancestorPattern.simplify();
105 }
106 if ( filters == null )
107 {
108 if ( parentPattern == null && ancestorPattern == null )
109 {
110 return nodeTest;
111 }
112 if ( parentPattern != null && ancestorPattern == null )
113 {
114 if ( nodeTest instanceof AnyNodeTest )
115 {
116 return parentPattern;
117 }
118 }
119 }
120 return this;
121 }
122
123
124
125 public void addFilter(FilterExpr filter)
126 {
127 if ( filters == null )
128 {
129 filters = new ArrayList();
130 }
131 filters.add( filter );
132 }
133
134
135
136
137 public void setParentPattern(Pattern parentPattern)
138 {
139 this.parentPattern = parentPattern;
140 }
141
142
143
144
145 public void setAncestorPattern(Pattern ancestorPattern)
146 {
147 this.ancestorPattern = ancestorPattern;
148 }
149
150
151
152 public void setNodeTest(NodeTest nodeTest) throws JaxenException
153 {
154 if ( this.nodeTest instanceof AnyNodeTest )
155 {
156 this.nodeTest = nodeTest;
157 }
158 else
159 {
160 throw new JaxenException( "Attempt to overwrite nodeTest: " + this.nodeTest + " with: " + nodeTest );
161 }
162 }
163
164
165
166 public boolean matches( Object node, Context context ) throws JaxenException
167 {
168 Navigator navigator = context.getNavigator();
169
170
171
172
173
174
175
176 if (! nodeTest.matches(node, context) )
177 {
178 return false;
179 }
180
181 if (parentPattern != null)
182 {
183 Object parent = navigator.getParentNode( node );
184 if ( parent == null )
185 {
186 return false;
187 }
188 if ( ! parentPattern.matches( parent, context ) )
189 {
190 return false;
191 }
192 }
193
194 if (ancestorPattern != null) {
195 Object ancestor = navigator.getParentNode( node );
196 while (true)
197 {
198 if ( ancestorPattern.matches( ancestor, context ) )
199 {
200 break;
201 }
202 if ( ancestor == null )
203 {
204 return false;
205 }
206 if ( navigator.isDocument( ancestor ) )
207 {
208 return false;
209 }
210 ancestor = navigator.getParentNode( ancestor );
211 }
212 }
213
214 if (filters != null)
215 {
216 List list = new SingletonList(node);
217
218 context.setNodeSet( list );
219
220
221
222 boolean answer = true;
223
224 for (Iterator iter = filters.iterator(); iter.hasNext(); )
225 {
226 FilterExpr filter = (FilterExpr) iter.next();
227
228 if ( ! filter.asBoolean( context ) )
229 {
230 answer = false;
231 break;
232 }
233 }
234
235
236 context.setNodeSet( list );
237
238 return answer;
239 }
240 return true;
241 }
242
243 public double getPriority()
244 {
245 if ( filters != null )
246 {
247 return 0.5;
248 }
249 return nodeTest.getPriority();
250 }
251
252
253 public short getMatchType()
254 {
255 return nodeTest.getMatchType();
256 }
257
258 public String getText()
259 {
260 StringBuffer buffer = new StringBuffer();
261 if ( absolute )
262 {
263 buffer.append( "/" );
264 }
265 if (ancestorPattern != null)
266 {
267 String text = ancestorPattern.getText();
268 if ( text.length() > 0 )
269 {
270 buffer.append( text );
271 buffer.append( "//" );
272 }
273 }
274 if (parentPattern != null)
275 {
276 String text = parentPattern.getText();
277 if ( text.length() > 0 )
278 {
279 buffer.append( text );
280 buffer.append( "/" );
281 }
282 }
283 buffer.append( nodeTest.getText() );
284
285 if ( filters != null )
286 {
287 buffer.append( "[" );
288 for (Iterator iter = filters.iterator(); iter.hasNext(); )
289 {
290 FilterExpr filter = (FilterExpr) iter.next();
291 buffer.append( filter.getText() );
292 }
293 buffer.append( "]" );
294 }
295 return buffer.toString();
296 }
297
298 public String toString()
299 {
300 return super.toString() + "[ absolute: " + absolute + " parent: " + parentPattern + " ancestor: "
301 + ancestorPattern + " filters: " + filters + " nodeTest: "
302 + nodeTest + " ]";
303 }
304
305 public boolean isAbsolute()
306 {
307 return absolute;
308 }
309
310 public void setAbsolute(boolean absolute)
311 {
312 this.absolute = absolute;
313 }
314
315 public boolean hasAnyNodeTest()
316 {
317 return nodeTest instanceof AnyNodeTest;
318 }
319
320 }