View Javadoc
1   /*
2    * Copyright 2000-2002 bob mcwhirter & James Strachan.
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are
7    * met:
8    * 
9    *   * Redistributions of source code must retain the above copyright
10   *     notice, this list of conditions and the following disclaimer.
11   * 
12   *   * Redistributions in binary form must reproduce the above copyright
13   *     notice, this list of conditions and the following disclaimer in the
14   *     documentation and/or other materials provided with the distribution.
15   * 
16   *   * Neither the name of the Jaxen Project nor the names of its
17   *     contributors may be used to endorse or promote products derived 
18   *     from this software without specific prior written permission.
19   * 
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21   * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22   * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31   *
32   * ====================================================================
33   * This software consists of voluntary contributions made by many 
34   * individuals on behalf of the Jaxen Project and was originally 
35   * created by bob mcwhirter <bob@werken.com> and 
36   * James Strachan <jstrachan@apache.org>.  For more information on the 
37   * Jaxen Project, please see <http://www.jaxen.org/>.
38   * 
39   */
40  
41  package org.jaxen.javabean;
42  
43  import org.jaxen.Context;
44  import org.jaxen.BaseXPath;
45  import org.jaxen.JaxenException;
46  
47  import java.util.List;
48  import java.util.ArrayList;
49  import java.util.Collection;
50  import java.util.Iterator;
51  
52  /** An XPath implementation for JavaBeans.
53   *
54   * <p>This is the main entry point for matching an XPath against a JavaBean
55   * tree.  You create a compiled XPath object, then match it against
56   * one or more context nodes using the {@link #selectNodes(Object)}
57   * method, as in the following example:</p>
58   *
59   * <pre>
60   * Node node = ...;
61   * XPath path = new JavaBeanXPath("a/b/c");
62   * List results = path.selectNodes(node);
63   * </pre>
64   *
65   * @see BaseXPath
66   *
67   * @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
68   *
69   */
70  public class JavaBeanXPath extends BaseXPath
71  {
72  
73      private static final long serialVersionUID = -1567521943360266313L;
74  
75      /** Construct given an XPath expression string.
76       *
77       *  @param xpathExpr the XPath expression
78       *
79       *  @throws JaxenException if there is a syntax error while
80       *          parsing the expression
81       */
82      public JavaBeanXPath(String xpathExpr) throws JaxenException
83      {
84          super( xpathExpr, DocumentNavigator.getInstance() );
85      }
86  
87      @Override
88      protected Context getContext(Object node)
89      {
90          if ( node instanceof Context )
91          {
92              return (Context) node;
93          }
94  
95          if ( node instanceof Element )
96          {
97              return super.getContext( node );
98          }
99  
100         if ( node instanceof List )
101         {
102             List<Element> newList = new ArrayList<Element>();
103 
104             for ( Iterator listIter = ((List)node).iterator();
105                   listIter.hasNext(); )
106             {
107                 newList.add( new Element( null, "root", listIter.next() ) );
108             }
109 
110             return super.getContext( newList );
111         }
112 
113         return super.getContext( new Element( null, "root", node ) );
114     }
115 
116     @Override
117     public Object evaluate(Object node)
118         throws JaxenException
119     {
120         Object result = super.evaluate( node );
121 
122         if ( result instanceof Element )
123         {
124             return ((Element)result).getObject();
125         }
126         else if ( result instanceof Collection )
127         {
128             List<Object> newList = new ArrayList<Object>();
129 
130             for ( Iterator<Object> listIter = ((Collection)result).iterator();
131                   listIter.hasNext(); )
132             {
133                 Object member = listIter.next();
134 
135                 if ( member instanceof Element )
136                 {
137                     newList.add( ((Element)member).getObject() );
138                 }
139                 else
140                 {
141                     newList.add( member );
142                 }
143             }
144 
145             return newList;
146         }
147 
148         return result;
149     }
150 }