View Javadoc

1   /*
2    $Id: DocumentNavigator.java 1161 2006-06-03 20:36:00Z elharo $
3   
4    Copyright 2003 The Werken Company. All Rights Reserved.
5    
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are
8   met:
9   
10    * Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12  
13    * Redistributions in binary form must reproduce the above copyright
14      notice, this list of conditions and the following disclaimer in the
15      documentation and/or other materials provided with the distribution.
16  
17    * Neither the name of the Jaxen Project nor the names of its
18      contributors may be used to endorse or promote products derived 
19      from this software without specific prior written permission.
20  
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  
33   */
34  package org.jaxen.javabean;
35  
36  import java.lang.reflect.Method;
37  import java.lang.reflect.InvocationTargetException;
38  import java.util.Iterator;
39  import java.util.Collection;
40  
41  import org.jaxen.DefaultNavigator;
42  import org.jaxen.FunctionCallException;
43  import org.jaxen.NamedAccessNavigator;
44  import org.jaxen.Navigator;
45  import org.jaxen.XPath;
46  import org.jaxen.JaxenConstants;
47  import org.jaxen.util.SingleObjectIterator;
48  
49  /** 
50   * Interface for navigating around a JavaBean object model.
51   *
52   * <p>
53   * This class is not intended for direct usage, but is
54   * used by the Jaxen engine during evaluation.
55   * </p>
56   *
57   * @see XPath
58   *
59   * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
60   */
61  public class DocumentNavigator
62      extends DefaultNavigator
63      implements NamedAccessNavigator
64  {
65  
66      /**
67       * 
68       */
69      private static final long serialVersionUID = -1768605107626726499L;
70  
71      /** Empty Class array. */
72      private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
73  
74      /** Empty Object array. */
75      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
76  
77      /** Singleton implementation.
78       */
79      private static final DocumentNavigator instance = new DocumentNavigator();
80  
81      /** Retrieve the singleton instance of this <code>DocumentNavigator</code>.
82       */
83      public static Navigator getInstance()
84      {
85          return instance;
86      }
87  
88      public boolean isElement(Object obj)
89      {
90          return (obj instanceof Element);
91      }
92  
93      public boolean isComment(Object obj)
94      {
95          return false;
96      }
97  
98      public boolean isText(Object obj)
99      {
100         return ( obj instanceof String );
101     }
102 
103     public boolean isAttribute(Object obj)
104     {
105         return false;
106     }
107 
108     public boolean isProcessingInstruction(Object obj)
109     {
110         return false;
111     }
112 
113     public boolean isDocument(Object obj)
114     {
115         return false;
116     }
117 
118     public boolean isNamespace(Object obj)
119     {
120         return false;
121     }
122 
123     public String getElementName(Object obj)
124     {
125         return ((Element)obj).getName();
126     }
127 
128     public String getElementNamespaceUri(Object obj)
129     {
130         return "";
131     }
132 
133     public String getElementQName(Object obj)
134     {
135         return "";
136     }
137 
138     public String getAttributeName(Object obj)
139     {
140         return "";
141     }
142 
143     public String getAttributeNamespaceUri(Object obj)
144     {
145         return "";
146     }
147 
148     public String getAttributeQName(Object obj)
149     {
150         return "";
151     }
152 
153     public Iterator getChildAxisIterator(Object contextNode)
154     {
155         return JaxenConstants.EMPTY_ITERATOR;
156     }
157 
158     /**
159      * Retrieves an <code>Iterator</code> over the child elements that
160      * match the supplied name.
161      *
162      * @param contextNode  the origin context node
163      * @param localName  the local name of the children to return, always present
164      * @param namespacePrefix  the prefix of the namespace of the children to return
165      * @param namespaceURI  the namespace URI of the children to return
166      * @return an Iterator that traverses the named children, or null if none
167      */
168     public Iterator getChildAxisIterator(Object contextNode,
169                                          String localName,
170                                          String namespacePrefix,
171                                          String namespaceURI)
172     {
173         Class cls = ((Element)contextNode).getObject().getClass();
174 
175         String methodName = javacase( localName );
176 
177         Method method = null;
178         
179         try
180         {
181             method = cls.getMethod( "get" + methodName, EMPTY_CLASS_ARRAY );
182         }
183         catch (NoSuchMethodException e)
184         {
185             try
186             {
187                 method = cls.getMethod( "get" + methodName + "s", EMPTY_CLASS_ARRAY );
188             }
189             catch (NoSuchMethodException ee)
190             {
191                 try
192                 {
193                     method = cls.getMethod( localName, EMPTY_CLASS_ARRAY );
194                 }
195                 catch (NoSuchMethodException eee)
196                 {
197                     method = null;
198                 }
199             }
200         }
201 
202         if ( method == null )
203         {
204             return JaxenConstants.EMPTY_ITERATOR;
205         }
206 
207         try
208         {
209             Object result = method.invoke( ((Element)contextNode).getObject(), EMPTY_OBJECT_ARRAY );
210             
211             if ( result == null )
212             {
213                 return JaxenConstants.EMPTY_ITERATOR;
214             } 
215             
216             if ( result instanceof Collection )
217             {
218                 return new ElementIterator( (Element) contextNode, localName, ((Collection)result).iterator() );
219             }
220             
221             if ( result.getClass().isArray() )
222             {
223                 return JaxenConstants.EMPTY_ITERATOR;
224             }
225             
226             return new SingleObjectIterator( new Element( (Element) contextNode, localName, result ) );
227         }
228         catch (IllegalAccessException e)
229         {
230             // swallow
231         }
232         catch (InvocationTargetException e)
233         {
234             // swallow
235         }
236 
237         return JaxenConstants.EMPTY_ITERATOR;
238     }
239 
240     public Iterator getParentAxisIterator(Object contextNode)
241     {
242         if ( contextNode instanceof Element )
243         {
244             return new SingleObjectIterator( ((Element)contextNode).getParent() );
245         }
246 
247         return JaxenConstants.EMPTY_ITERATOR;
248     }
249 
250     public Iterator getAttributeAxisIterator(Object contextNode)
251     {
252         return JaxenConstants.EMPTY_ITERATOR;
253     }
254 
255     /**
256      * Retrieves an <code>Iterator</code> over the attribute elements that
257      * match the supplied name.
258      *
259      * @param contextNode  the origin context node
260      * @param localName  the local name of the attributes to return, always present
261      * @param namespacePrefix  the prefix of the namespace of the attributes to return
262      * @param namespaceURI  the namespace URI of the attributes to return
263      * @return an Iterator that traverses the named attributes, not null
264      */
265     public Iterator getAttributeAxisIterator(Object contextNode,
266                                              String localName,
267                                              String namespacePrefix,
268                                              String namespaceURI) {
269         return JaxenConstants.EMPTY_ITERATOR;
270     }
271         
272     public Iterator getNamespaceAxisIterator(Object contextNode)
273     {
274         return JaxenConstants.EMPTY_ITERATOR;
275     }
276 
277     public Object getDocumentNode(Object contextNode)
278     {
279         return null;
280     }
281 
282     public Object getParentNode(Object contextNode)
283     {
284         if ( contextNode instanceof Element )
285         {
286             return ((Element)contextNode).getParent();
287         }
288 
289         return JaxenConstants.EMPTY_ITERATOR;
290     }
291 
292     public String getTextStringValue(Object obj)
293     {
294         if ( obj instanceof Element )
295         {
296             return ((Element)obj).getObject().toString();
297         }
298         return obj.toString();
299     }
300 
301     public String getElementStringValue(Object obj)
302     {
303         if ( obj instanceof Element )
304         {
305             return ((Element)obj).getObject().toString();
306         }
307         return obj.toString();
308     }
309 
310     public String getAttributeStringValue(Object obj)
311     {
312         return obj.toString();
313     }
314 
315     public String getNamespaceStringValue(Object obj)
316     {
317         return obj.toString();
318     }
319 
320     public String getNamespacePrefix(Object obj)
321     {
322         return null;
323     }
324 
325     public String getCommentStringValue(Object obj)
326     {
327         return null;
328     }
329     
330     public String translateNamespacePrefixToUri(String prefix, Object context)
331     {
332         return null;
333     }
334     
335     public short getNodeType(Object node) 
336     {
337         return 0;
338     }
339     
340     public Object getDocument(String uri) throws FunctionCallException
341     {
342         return null;
343     }
344 
345     public String getProcessingInstructionTarget(Object obj)
346     {
347         return null;
348     }
349 
350     public String getProcessingInstructionData(Object obj)
351     {
352         return null;
353     }
354 
355     public XPath parseXPath(String xpath)
356         throws org.jaxen.saxpath.SAXPathException
357     {
358         return new JavaBeanXPath( xpath );
359     }
360 
361     protected String javacase(String name)
362     {
363         if ( name.length() == 0 )
364         {
365             return name;
366         }
367         else if ( name.length() == 1 )
368         {
369             return name.toUpperCase();
370         } 
371 
372         return name.substring( 0, 1 ).toUpperCase() + name.substring( 1 );
373     }
374 }