KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jaxen > dom4j > DocumentNavigator


1 package org.jaxen.dom4j;
2
3 /*
4  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom4j/DocumentNavigator.java,v 1.29 2005/06/15 23:42:39 bewins Exp $
5  * $Revision: 1.29 $
6  * $Date: 2005/06/15 23:42:39 $
7  *
8  * ====================================================================
9  *
10  * Copyright (C) 2000-2005 bob mcwhirter & James Strachan.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  * notice, this list of conditions, and the following disclaimer.
19  *
20  * 2. Redistributions in binary form must reproduce the above copyright
21  * notice, this list of conditions, and the disclaimer that follows
22  * these conditions in the documentation and/or other materials
23  * provided with the distribution.
24  *
25  * 3. The name "Jaxen" must not be used to endorse or promote products
26  * derived from this software without prior written permission. For
27  * written permission, please contact license@jaxen.org.
28  *
29  * 4. Products derived from this software may not be called "Jaxen", nor
30  * may "Jaxen" appear in their name, without prior written permission
31  * from the Jaxen Project Management (pm@jaxen.org).
32  *
33  * In addition, we request (but do not require) that you include in the
34  * end-user documentation provided with the redistribution and/or in the
35  * software itself an acknowledgement equivalent to the following:
36  * "This product includes software developed by the
37  * Jaxen Project (http://www.jaxen.org/)."
38  * Alternatively, the acknowledgment may be graphical using the logos
39  * available at http://www.jaxen.org/
40  *
41  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44  * DISCLAIMED. IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
45  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  *
54  * ====================================================================
55  * This software consists of voluntary contributions made by many
56  * individuals on behalf of the Jaxen Project and was originally
57  * created by bob mcwhirter <bob@werken.com> and
58  * James Strachan <jstrachan@apache.org>. For more information on the
59  * Jaxen Project, please see <http://www.jaxen.org/>.
60  *
61  * $Id: DocumentNavigator.java,v 1.29 2005/06/15 23:42:39 bewins Exp $
62 */

63
64 import java.util.ArrayList JavaDoc;
65 import java.util.HashSet JavaDoc;
66 import java.util.Iterator JavaDoc;
67 import java.util.List JavaDoc;
68
69 import org.dom4j.Attribute;
70 import org.dom4j.Branch;
71 import org.dom4j.CDATA;
72 import org.dom4j.Comment;
73 import org.dom4j.Document;
74 import org.dom4j.DocumentException;
75 import org.dom4j.Element;
76 import org.dom4j.Namespace;
77 import org.dom4j.Node;
78 import org.dom4j.ProcessingInstruction;
79 import org.dom4j.QName;
80 import org.dom4j.Text;
81 import org.dom4j.io.SAXReader;
82 import org.jaxen.DefaultNavigator;
83 import org.jaxen.FunctionCallException;
84 import org.jaxen.NamedAccessNavigator;
85 import org.jaxen.Navigator;
86 import org.jaxen.XPath;
87 import org.jaxen.JaxenConstants;
88 import org.jaxen.saxpath.SAXPathException;
89 import org.jaxen.util.SingleObjectIterator;
90
91 /**
92  * Interface for navigating around the DOM4J object model.
93  *
94  * <p>
95  * This class is not intended for direct usage, but is
96  * used by the Jaxen engine during evaluation.
97  * </p>
98  *
99  * @see XPath
100  *
101  * @author <a HREF="mailto:bob@werken.com">bob mcwhirter</a>
102  * @author Stephen Colebourne
103  */

104 public class DocumentNavigator extends DefaultNavigator implements NamedAccessNavigator
105 {
106     
107     private transient SAXReader reader;
108
109     /** Singleton implementation.
110      */

111     private static class Singleton
112     {
113         /** Singleton instance.
114          */

115         private static DocumentNavigator instance = new DocumentNavigator();
116     }
117
118     /** Retrieve the singleton instance of this <code>DocumentNavigator</code>.
119      */

120     public static Navigator getInstance()
121     {
122         return Singleton.instance;
123     }
124
125     public boolean isElement(Object JavaDoc obj)
126     {
127         return obj instanceof Element;
128     }
129
130     public boolean isComment(Object JavaDoc obj)
131     {
132         return obj instanceof Comment;
133     }
134
135     public boolean isText(Object JavaDoc obj)
136     {
137         return ( obj instanceof Text
138                  ||
139                  obj instanceof CDATA );
140     }
141
142     public boolean isAttribute(Object JavaDoc obj)
143     {
144         return obj instanceof Attribute;
145     }
146
147     public boolean isProcessingInstruction(Object JavaDoc obj)
148     {
149         return obj instanceof ProcessingInstruction;
150     }
151
152     public boolean isDocument(Object JavaDoc obj)
153     {
154         return obj instanceof Document;
155     }
156
157     public boolean isNamespace(Object JavaDoc obj)
158     {
159         return obj instanceof Namespace;
160     }
161
162     public String JavaDoc getElementName(Object JavaDoc obj)
163     {
164         Element elem = (Element) obj;
165
166         return elem.getName();
167     }
168
169     public String JavaDoc getElementNamespaceUri(Object JavaDoc obj)
170     {
171         Element elem = (Element) obj;
172         
173         String JavaDoc uri = elem.getNamespaceURI();
174         if ( uri == null)
175             return "";
176         else
177             return uri;
178     }
179
180     public String JavaDoc getElementQName(Object JavaDoc obj)
181     {
182         Element elem = (Element) obj;
183
184         return elem.getQualifiedName();
185     }
186
187     public String JavaDoc getAttributeName(Object JavaDoc obj)
188     {
189         Attribute attr = (Attribute) obj;
190
191         return attr.getName();
192     }
193
194     public String JavaDoc getAttributeNamespaceUri(Object JavaDoc obj)
195     {
196         Attribute attr = (Attribute) obj;
197
198         String JavaDoc uri = attr.getNamespaceURI();
199         if ( uri == null)
200             return "";
201         else
202             return uri;
203     }
204
205     public String JavaDoc getAttributeQName(Object JavaDoc obj)
206     {
207         Attribute attr = (Attribute) obj;
208
209         return attr.getQualifiedName();
210     }
211
212     public Iterator JavaDoc getChildAxisIterator(Object JavaDoc contextNode)
213     {
214         Iterator JavaDoc result = null;
215         if ( contextNode instanceof Branch )
216         {
217             Branch node = (Branch) contextNode;
218             result = node.nodeIterator();
219         }
220         if (result != null) {
221             return result;
222         }
223         return JaxenConstants.EMPTY_ITERATOR;
224     }
225
226     /**
227      * Retrieves an <code>Iterator</code> over the child elements that
228      * match the supplied name.
229      *
230      * @param contextNode the origin context node
231      * @param localName the local name of the children to return, always present
232      * @param namespacePrefix the prefix of the namespace of the children to return
233      * @param namespaceURI the uri of the namespace of the children to return
234      * @return an Iterator that traverses the named children, or null if none
235      */

236     public Iterator JavaDoc getChildAxisIterator(
237             Object JavaDoc contextNode, String JavaDoc localName, String JavaDoc namespacePrefix, String JavaDoc namespaceURI) {
238
239         if ( contextNode instanceof Element ) {
240             Element node = (Element) contextNode;
241             return node.elementIterator(QName.get(localName, namespacePrefix, namespaceURI));
242         }
243         if ( contextNode instanceof Document ) {
244             Document node = (Document) contextNode;
245             Element el = node.getRootElement();
246             if (el.getName().equals(localName) == false) {
247                 return JaxenConstants.EMPTY_ITERATOR;
248             }
249             if (namespaceURI != null) {
250                 if (namespaceURI.equals(el.getNamespaceURI()) == false) {
251                     return JaxenConstants.EMPTY_ITERATOR;
252                 }
253             }
254             return new SingleObjectIterator(el);
255         }
256
257         return JaxenConstants.EMPTY_ITERATOR;
258     }
259
260     public Iterator JavaDoc getParentAxisIterator(Object JavaDoc contextNode)
261     {
262         if ( contextNode instanceof Document )
263         {
264             return JaxenConstants.EMPTY_ITERATOR;
265         }
266
267         Node node = (Node) contextNode;
268
269         Object JavaDoc parent = node.getParent();
270
271         if ( parent == null )
272         {
273             parent = node.getDocument();
274         }
275         
276         return new SingleObjectIterator( parent );
277     }
278
279     public Iterator JavaDoc getAttributeAxisIterator(Object JavaDoc contextNode)
280     {
281         if ( ! ( contextNode instanceof Element ) )
282         {
283             return JaxenConstants.EMPTY_ITERATOR;
284         }
285
286         Element elem = (Element) contextNode;
287
288         return elem.attributeIterator();
289     }
290
291     /**
292      * Retrieves an <code>Iterator</code> over the attribute elements that
293      * match the supplied name.
294      *
295      * @param contextNode the origin context node
296      * @param localName the local name of the attributes to return, always present
297      * @param namespacePrefix the prefix of the namespace of the attributes to return
298      * @param namespaceURI the URI of the namespace of the attributes to return
299      * @return an Iterator that traverses the named attributes, not null
300      */

301     public Iterator JavaDoc getAttributeAxisIterator(
302             Object JavaDoc contextNode, String JavaDoc localName, String JavaDoc namespacePrefix, String JavaDoc namespaceURI) {
303
304         if ( contextNode instanceof Element ) {
305             Element node = (Element) contextNode;
306             Attribute attr = node.attribute(QName.get(localName, namespacePrefix, namespaceURI));
307             if (attr == null) {
308                 return JaxenConstants.EMPTY_ITERATOR;
309             }
310             return new SingleObjectIterator(attr);
311         }
312         return JaxenConstants.EMPTY_ITERATOR;
313     }
314         
315     public Iterator JavaDoc getNamespaceAxisIterator(Object JavaDoc contextNode)
316     {
317         if ( ! ( contextNode instanceof Element ) )
318         {
319             return JaxenConstants.EMPTY_ITERATOR;
320         }
321
322         Element element = (Element) contextNode;
323         List JavaDoc nsList = new ArrayList JavaDoc();
324         HashSet JavaDoc prefixes = new HashSet JavaDoc();
325         for ( Element context = element; context != null; context = context.getParent() ) {
326             List JavaDoc declaredNS = new ArrayList JavaDoc(context.declaredNamespaces());
327             declaredNS.add(context.getNamespace());
328
329             for ( Iterator JavaDoc iter = context.attributes().iterator(); iter.hasNext(); )
330             {
331                 Attribute attr = (Attribute) iter.next();
332                 declaredNS.add(attr.getNamespace());
333             }
334
335             for ( Iterator JavaDoc iter = declaredNS.iterator(); iter.hasNext(); )
336             {
337                 Namespace namespace = (Namespace) iter.next();
338                 if (namespace != Namespace.NO_NAMESPACE)
339                 {
340                     String JavaDoc prefix = namespace.getPrefix();
341                     if ( ! prefixes.contains( prefix ) ) {
342                         prefixes.add( prefix );
343                         nsList.add( namespace.asXPathResult( element ) );
344                     }
345                 }
346             }
347         }
348         nsList.add( Namespace.XML_NAMESPACE.asXPathResult( element ) );
349         return nsList.iterator();
350     }
351
352     public Object JavaDoc getDocumentNode(Object JavaDoc contextNode)
353     {
354         if ( contextNode instanceof Document )
355         {
356             return contextNode;
357         }
358         else if ( contextNode instanceof Node )
359         {
360             Node node = (Node) contextNode;
361             return node.getDocument();
362         }
363         return null;
364     }
365
366     /** Returns a parsed form of the given xpath string, which will be suitable
367      * for queries on DOM4J documents.
368      */

369     public XPath parseXPath (String JavaDoc xpath) throws SAXPathException
370     {
371         return new Dom4jXPath(xpath);
372     }
373
374     public Object JavaDoc getParentNode(Object JavaDoc contextNode)
375     {
376         if ( contextNode instanceof Node )
377         {
378             Node node = (Node) contextNode;
379             Object JavaDoc answer = node.getParent();
380             if ( answer == null )
381             {
382                 answer = node.getDocument();
383                 if (answer == contextNode) {
384                     return null;
385                 }
386             }
387             return answer;
388         }
389         return null;
390     }
391
392     public String JavaDoc getTextStringValue(Object JavaDoc obj)
393     {
394         return getNodeStringValue( (Node) obj );
395     }
396
397     public String JavaDoc getElementStringValue(Object JavaDoc obj)
398     {
399         return getNodeStringValue( (Node) obj );
400     }
401
402     public String JavaDoc getAttributeStringValue(Object JavaDoc obj)
403     {
404         return getNodeStringValue( (Node) obj );
405     }
406
407     private String JavaDoc getNodeStringValue(Node node)
408     {
409         return node.getStringValue();
410     }
411
412     public String JavaDoc getNamespaceStringValue(Object JavaDoc obj)
413     {
414         Namespace ns = (Namespace) obj;
415
416         return ns.getURI();
417     }
418
419     public String JavaDoc getNamespacePrefix(Object JavaDoc obj)
420     {
421         Namespace ns = (Namespace) obj;
422
423         return ns.getPrefix();
424     }
425
426     public String JavaDoc getCommentStringValue(Object JavaDoc obj)
427     {
428         Comment cmt = (Comment) obj;
429
430         return cmt.getText();
431     }
432     
433     public String JavaDoc translateNamespacePrefixToUri(String JavaDoc prefix, Object JavaDoc context)
434     {
435         Element element = null;
436         if ( context instanceof Element )
437         {
438             element = (Element) context;
439         }
440         else if ( context instanceof Node )
441         {
442             Node node = (Node) context;
443             element = node.getParent();
444         }
445         if ( element != null )
446         {
447             Namespace namespace = element.getNamespaceForPrefix( prefix );
448
449             if ( namespace != null )
450             {
451                 return namespace.getURI();
452             }
453         }
454         return null;
455     }
456     
457     public short getNodeType(Object JavaDoc node)
458     {
459         if ( node instanceof Node )
460         {
461             return ((Node) node).getNodeType();
462         }
463         return 0;
464     }
465     
466     public Object JavaDoc getDocument(String JavaDoc uri) throws FunctionCallException
467     {
468         try
469         {
470             return getSAXReader().read( uri );
471         }
472         catch (DocumentException e)
473         {
474             throw new FunctionCallException("Failed to parse document for URI: " + uri, e);
475         }
476     }
477
478     public String JavaDoc getProcessingInstructionTarget(Object JavaDoc obj)
479     {
480         ProcessingInstruction pi = (ProcessingInstruction) obj;
481
482         return pi.getTarget();
483     }
484
485     public String JavaDoc getProcessingInstructionData(Object JavaDoc obj)
486     {
487         ProcessingInstruction pi = (ProcessingInstruction) obj;
488
489         return pi.getText();
490     }
491     
492     // Properties
493
//-------------------------------------------------------------------------
494
public SAXReader getSAXReader()
495     {
496         if ( reader == null )
497         {
498             reader = new SAXReader();
499             reader.setMergeAdjacentText( true );
500         }
501         return reader;
502     }
503     
504     public void setSAXReader(SAXReader reader)
505     {
506         this.reader = reader;
507     }
508     
509 }
510
Popular Tags