1 package org.jaxen.dom4j;
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 import java.util.ArrayList;
52 import java.util.HashSet;
53 import java.util.Iterator;
54 import java.util.List;
55
56 import org.dom4j.Attribute;
57 import org.dom4j.Branch;
58 import org.dom4j.CDATA;
59 import org.dom4j.Comment;
60 import org.dom4j.Document;
61 import org.dom4j.DocumentException;
62 import org.dom4j.Element;
63 import org.dom4j.Namespace;
64 import org.dom4j.Node;
65 import org.dom4j.ProcessingInstruction;
66 import org.dom4j.QName;
67 import org.dom4j.Text;
68 import org.dom4j.io.SAXReader;
69 import org.jaxen.DefaultNavigator;
70 import org.jaxen.FunctionCallException;
71 import org.jaxen.NamedAccessNavigator;
72 import org.jaxen.Navigator;
73 import org.jaxen.XPath;
74 import org.jaxen.JaxenConstants;
75 import org.jaxen.saxpath.SAXPathException;
76 import org.jaxen.util.SingleObjectIterator;
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public class DocumentNavigator extends DefaultNavigator implements NamedAccessNavigator
92 {
93
94
95 private static final long serialVersionUID = 5582300797286535936L;
96 private transient SAXReader reader;
97
98
99
100 private static class Singleton
101 {
102
103
104 private static DocumentNavigator instance = new DocumentNavigator();
105 }
106
107
108
109 public static Navigator getInstance()
110 {
111 return Singleton.instance;
112 }
113
114 public boolean isElement(Object obj)
115 {
116 return obj instanceof Element;
117 }
118
119 public boolean isComment(Object obj)
120 {
121 return obj instanceof Comment;
122 }
123
124 public boolean isText(Object obj)
125 {
126 return ( obj instanceof Text
127 ||
128 obj instanceof CDATA );
129 }
130
131 public boolean isAttribute(Object obj)
132 {
133 return obj instanceof Attribute;
134 }
135
136 public boolean isProcessingInstruction(Object obj)
137 {
138 return obj instanceof ProcessingInstruction;
139 }
140
141 public boolean isDocument(Object obj)
142 {
143 return obj instanceof Document;
144 }
145
146 public boolean isNamespace(Object obj)
147 {
148 return obj instanceof Namespace;
149 }
150
151 public String getElementName(Object obj)
152 {
153 Element elem = (Element) obj;
154
155 return elem.getName();
156 }
157
158 public String getElementNamespaceUri(Object obj)
159 {
160 Element elem = (Element) obj;
161
162 String uri = elem.getNamespaceURI();
163 if ( uri == null)
164 return "";
165 else
166 return uri;
167 }
168
169 public String getElementQName(Object obj)
170 {
171 Element elem = (Element) obj;
172
173 return elem.getQualifiedName();
174 }
175
176 public String getAttributeName(Object obj)
177 {
178 Attribute attr = (Attribute) obj;
179
180 return attr.getName();
181 }
182
183 public String getAttributeNamespaceUri(Object obj)
184 {
185 Attribute attr = (Attribute) obj;
186
187 String uri = attr.getNamespaceURI();
188 if ( uri == null)
189 return "";
190 else
191 return uri;
192 }
193
194 public String getAttributeQName(Object obj)
195 {
196 Attribute attr = (Attribute) obj;
197
198 return attr.getQualifiedName();
199 }
200
201 public Iterator getChildAxisIterator(Object contextNode)
202 {
203 Iterator result = null;
204 if ( contextNode instanceof Branch )
205 {
206 Branch node = (Branch) contextNode;
207 result = node.nodeIterator();
208 }
209 if (result != null) {
210 return result;
211 }
212 return JaxenConstants.EMPTY_ITERATOR;
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226 public Iterator getChildAxisIterator(
227 Object contextNode, String localName, String namespacePrefix, String namespaceURI) {
228
229 if ( contextNode instanceof Element ) {
230 Element node = (Element) contextNode;
231 return node.elementIterator(QName.get(localName, namespacePrefix, namespaceURI));
232 }
233 if ( contextNode instanceof Document ) {
234 Document node = (Document) contextNode;
235 Element el = node.getRootElement();
236 if (el == null || el.getName().equals(localName) == false) {
237 return JaxenConstants.EMPTY_ITERATOR;
238 }
239 if (namespaceURI != null) {
240 if (namespaceURI.equals(el.getNamespaceURI()) == false) {
241 return JaxenConstants.EMPTY_ITERATOR;
242 }
243 }
244 return new SingleObjectIterator(el);
245 }
246
247 return JaxenConstants.EMPTY_ITERATOR;
248 }
249
250 public Iterator getParentAxisIterator(Object contextNode)
251 {
252 if ( contextNode instanceof Document )
253 {
254 return JaxenConstants.EMPTY_ITERATOR;
255 }
256
257 Node node = (Node) contextNode;
258
259 Object parent = node.getParent();
260
261 if ( parent == null )
262 {
263 parent = node.getDocument();
264 }
265
266 return new SingleObjectIterator( parent );
267 }
268
269 public Iterator getAttributeAxisIterator(Object contextNode)
270 {
271 if ( ! ( contextNode instanceof Element ) )
272 {
273 return JaxenConstants.EMPTY_ITERATOR;
274 }
275
276 Element elem = (Element) contextNode;
277
278 return elem.attributeIterator();
279 }
280
281
282
283
284
285
286
287
288
289
290
291 public Iterator getAttributeAxisIterator(
292 Object contextNode, String localName, String namespacePrefix, String namespaceURI) {
293
294 if ( contextNode instanceof Element ) {
295 Element node = (Element) contextNode;
296 Attribute attr = node.attribute(QName.get(localName, namespacePrefix, namespaceURI));
297 if (attr == null) {
298 return JaxenConstants.EMPTY_ITERATOR;
299 }
300 return new SingleObjectIterator(attr);
301 }
302 return JaxenConstants.EMPTY_ITERATOR;
303 }
304
305 public Iterator getNamespaceAxisIterator(Object contextNode)
306 {
307 if ( ! ( contextNode instanceof Element ) )
308 {
309 return JaxenConstants.EMPTY_ITERATOR;
310 }
311
312 Element element = (Element) contextNode;
313 List nsList = new ArrayList();
314 HashSet prefixes = new HashSet();
315 for ( Element context = element; context != null; context = context.getParent() ) {
316 List declaredNS = new ArrayList(context.declaredNamespaces());
317 declaredNS.add(context.getNamespace());
318
319 for ( Iterator iter = context.attributes().iterator(); iter.hasNext(); )
320 {
321 Attribute attr = (Attribute) iter.next();
322 declaredNS.add(attr.getNamespace());
323 }
324
325 for ( Iterator iter = declaredNS.iterator(); iter.hasNext(); )
326 {
327 Namespace namespace = (Namespace) iter.next();
328 if (namespace != Namespace.NO_NAMESPACE)
329 {
330 String prefix = namespace.getPrefix();
331 if ( ! prefixes.contains( prefix ) ) {
332 prefixes.add( prefix );
333 nsList.add( namespace.asXPathResult( element ) );
334 }
335 }
336 }
337 }
338 nsList.add( Namespace.XML_NAMESPACE.asXPathResult( element ) );
339 return nsList.iterator();
340 }
341
342 public Object getDocumentNode(Object contextNode)
343 {
344 if ( contextNode instanceof Document )
345 {
346 return contextNode;
347 }
348 else if ( contextNode instanceof Node )
349 {
350 Node node = (Node) contextNode;
351 return node.getDocument();
352 }
353 return null;
354 }
355
356
357
358
359 public XPath parseXPath (String xpath) throws SAXPathException
360 {
361 return new Dom4jXPath(xpath);
362 }
363
364 public Object getParentNode(Object contextNode)
365 {
366 if ( contextNode instanceof Node )
367 {
368 Node node = (Node) contextNode;
369 Object answer = node.getParent();
370 if ( answer == null )
371 {
372 answer = node.getDocument();
373 if (answer == contextNode) {
374 return null;
375 }
376 }
377 return answer;
378 }
379 return null;
380 }
381
382 public String getTextStringValue(Object obj)
383 {
384 return getNodeStringValue( (Node) obj );
385 }
386
387 public String getElementStringValue(Object obj)
388 {
389 return getNodeStringValue( (Node) obj );
390 }
391
392 public String getAttributeStringValue(Object obj)
393 {
394 return getNodeStringValue( (Node) obj );
395 }
396
397 private String getNodeStringValue(Node node)
398 {
399 return node.getStringValue();
400 }
401
402 public String getNamespaceStringValue(Object obj)
403 {
404 Namespace ns = (Namespace) obj;
405
406 return ns.getURI();
407 }
408
409 public String getNamespacePrefix(Object obj)
410 {
411 Namespace ns = (Namespace) obj;
412
413 return ns.getPrefix();
414 }
415
416 public String getCommentStringValue(Object obj)
417 {
418 Comment cmt = (Comment) obj;
419
420 return cmt.getText();
421 }
422
423 public String translateNamespacePrefixToUri(String prefix, Object context)
424 {
425 Element element = null;
426 if ( context instanceof Element )
427 {
428 element = (Element) context;
429 }
430 else if ( context instanceof Node )
431 {
432 Node node = (Node) context;
433 element = node.getParent();
434 }
435 if ( element != null )
436 {
437 Namespace namespace = element.getNamespaceForPrefix( prefix );
438
439 if ( namespace != null )
440 {
441 return namespace.getURI();
442 }
443 }
444 return null;
445 }
446
447 public short getNodeType(Object node)
448 {
449 if ( node instanceof Node )
450 {
451 return ((Node) node).getNodeType();
452 }
453 return 0;
454 }
455
456 public Object getDocument(String uri) throws FunctionCallException
457 {
458 try
459 {
460 return getSAXReader().read( uri );
461 }
462 catch (DocumentException e)
463 {
464 throw new FunctionCallException("Failed to parse document for URI: " + uri, e);
465 }
466 }
467
468 public String getProcessingInstructionTarget(Object obj)
469 {
470 ProcessingInstruction pi = (ProcessingInstruction) obj;
471
472 return pi.getTarget();
473 }
474
475 public String getProcessingInstructionData(Object obj)
476 {
477 ProcessingInstruction pi = (ProcessingInstruction) obj;
478
479 return pi.getText();
480 }
481
482
483
484 public SAXReader getSAXReader()
485 {
486 if ( reader == null )
487 {
488 reader = new SAXReader();
489 reader.setMergeAdjacentText( true );
490 }
491 return reader;
492 }
493
494 public void setSAXReader(SAXReader reader)
495 {
496 this.reader = reader;
497 }
498
499 }