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