View Javadoc

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