KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdom > xpath > JaxenXPath


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

56
57 package org.jdom.xpath;
58
59
60 import java.util.*;
61
62 import org.jaxen.*;
63 import org.jaxen.jdom.*;
64 import org.jdom.*;
65
66
67 /**
68  * A non-public concrete XPath implementation for Jaxen.
69  *
70  * @version $Revision: 1.19 $, $Date: 2004/09/03 07:27:39 $
71  * @author Laurent Bihanic
72  */

73 class JaxenXPath extends XPath { // package protected
74

75     private static final String JavaDoc CVS_ID =
76     "@(#) $RCSfile: JaxenXPath.java,v $ $Revision: 1.19 $ $Date: 2004/09/03 07:27:39 $ $Name: $";
77
78    /**
79     * The compiled XPath object to select nodes. This attribute can
80     * not be made final as it needs to be set upon object
81     * deserialization.
82     */

83    private transient JDOMXPath xPath;
84
85    /**
86     * The current context for XPath expression evaluation.
87     */

88    private Object JavaDoc currentContext;
89
90    /**
91     * Creates a new XPath wrapper object, compiling the specified
92     * XPath expression.
93     *
94     * @param expr the XPath expression to wrap.
95     *
96     * @throws JDOMException if the XPath expression is invalid.
97     */

98    public JaxenXPath(String JavaDoc expr) throws JDOMException {
99       setXPath(expr);
100    }
101
102    /**
103     * Evaluates the wrapped XPath expression and returns the list
104     * of selected items.
105     *
106     * @param context the node to use as context for evaluating
107     * the XPath expression.
108     *
109     * @return the list of selected items, which may be of types: {@link Element},
110     * {@link Attribute}, {@link Text}, {@link CDATA},
111     * {@link Comment}, {@link ProcessingInstruction}, Boolean,
112     * Double, or String.
113     *
114     * @throws JDOMException if the evaluation of the XPath
115     * expression on the specified context
116     * failed.
117     */

118    public List selectNodes(Object JavaDoc context) throws JDOMException {
119       try {
120          currentContext = context;
121
122          return xPath.selectNodes(context);
123       }
124       catch (JaxenException ex1) {
125          throw new JDOMException("XPath error while evaluating \"" +
126                         xPath.toString() + "\": " + ex1.getMessage(), ex1);
127       }
128       finally {
129          currentContext = null;
130       }
131    }
132
133    /**
134     * Evaluates the wrapped XPath expression and returns the first
135     * entry in the list of selected nodes (or atomics).
136     *
137     * @param context the node to use as context for evaluating
138     * the XPath expression.
139     *
140     * @return the first selected item, which may be of types: {@link Element},
141     * {@link Attribute}, {@link Text}, {@link CDATA},
142     * {@link Comment}, {@link ProcessingInstruction}, Boolean,
143     * Double, String, or <code>null</code> if no item was selected.
144     *
145     * @throws JDOMException if the evaluation of the XPath
146     * expression on the specified context
147     * failed.
148     */

149    public Object JavaDoc selectSingleNode(Object JavaDoc context) throws JDOMException {
150       try {
151          currentContext = context;
152
153          return xPath.selectSingleNode(context);
154       }
155       catch (JaxenException ex1) {
156          throw new JDOMException("XPath error while evaluating \"" +
157                         xPath.toString() + "\": " + ex1.getMessage(), ex1);
158       }
159       finally {
160          currentContext = null;
161       }
162    }
163
164    /**
165     * Returns the string value of the first node selected by applying
166     * the wrapped XPath expression to the given context.
167     *
168     * @param context the element to use as context for evaluating
169     * the XPath expression.
170     *
171     * @return the string value of the first node selected by applying
172     * the wrapped XPath expression to the given context.
173     *
174     * @throws JDOMException if the XPath expression is invalid or
175     * its evaluation on the specified context
176     * failed.
177     */

178    public String JavaDoc valueOf(Object JavaDoc context) throws JDOMException {
179       try {
180          currentContext = context;
181
182          return xPath.stringValueOf(context);
183       }
184       catch (JaxenException ex1) {
185          throw new JDOMException("XPath error while evaluating \"" +
186                         xPath.toString() + "\": " + ex1.getMessage(), ex1);
187       }
188       finally {
189          currentContext = null;
190       }
191    }
192
193    /**
194     * Returns the number value of the first item selected by applying
195     * the wrapped XPath expression to the given context.
196     *
197     * @param context the element to use as context for evaluating
198     * the XPath expression.
199     *
200     * @return the number value of the first item selected by applying
201     * the wrapped XPath expression to the given context,
202     * <code>null</code> if no node was selected or the
203     * special value {@link java.lang.Double#NaN}
204     * (Not-a-Number) if the selected value can not be
205     * converted into a number value.
206     *
207     * @throws JDOMException if the XPath expression is invalid or
208     * its evaluation on the specified context
209     * failed.
210     */

211    public Number JavaDoc numberValueOf(Object JavaDoc context) throws JDOMException {
212       try {
213          currentContext = context;
214
215          return xPath.numberValueOf(context);
216       }
217       catch (JaxenException ex1) {
218          throw new JDOMException("XPath error while evaluating \"" +
219                         xPath.toString() + "\": " + ex1.getMessage(), ex1);
220       }
221       finally {
222          currentContext = null;
223       }
224    }
225
226    /**
227     * Defines an XPath variable and sets its value.
228     *
229     * @param name the variable name.
230     * @param value the variable value.
231     *
232     * @throws IllegalArgumentException if <code>name</code> is not
233     * a valid XPath variable name
234     * or if the value type is not
235     * supported by the underlying
236     * implementation
237     */

238    public void setVariable(String JavaDoc name, Object JavaDoc value)
239                                         throws IllegalArgumentException JavaDoc {
240       Object JavaDoc o = xPath.getVariableContext();
241       if (o instanceof SimpleVariableContext) {
242            ((SimpleVariableContext)o).setVariableValue(null, name, value);
243       }
244    }
245
246    /**
247     * Adds a namespace definition to the list of namespaces known of
248     * this XPath expression.
249     * <p>
250     * <strong>Note</strong>: In XPath, there is no such thing as a
251     * 'default namespace'. The empty prefix <b>always</b> resolves
252     * to the empty namespace URI.</p>
253     *
254     * @param namespace the namespace.
255     */

256    public void addNamespace(Namespace namespace) {
257       try {
258          xPath.addNamespace(namespace.getPrefix(), namespace.getURI());
259       }
260       catch (JaxenException ex1) { /* Can't happen here. */ }
261    }
262
263    /**
264     * Returns the wrapped XPath expression as a string.
265     *
266     * @return the wrapped XPath expression as a string.
267     */

268    public String JavaDoc getXPath() {
269       return (xPath.toString());
270    }
271
272    /**
273     * Compiles and sets the XPath expression wrapped by this object.
274     *
275     * @param expr the XPath expression to wrap.
276     *
277     * @throws JDOMException if the XPath expression is invalid.
278     */

279    private void setXPath(String JavaDoc expr) throws JDOMException {
280       try {
281          xPath = new JDOMXPath(expr);
282          xPath.setNamespaceContext(new NSContext());
283       }
284       catch (Exception JavaDoc ex1) {
285          throw new JDOMException(
286                         "Invalid XPath expression: \"" + expr + "\"", ex1);
287       }
288    }
289
290    public String JavaDoc toString() {
291       return (xPath.toString());
292    }
293
294    public boolean equals(Object JavaDoc o) {
295       if (o instanceof JaxenXPath) {
296          JaxenXPath x = (JaxenXPath)o;
297
298          return (super.equals(o) &&
299                  xPath.toString().equals(x.xPath.toString()));
300       }
301       return false;
302    }
303
304    public int hashCode() {
305       return xPath.hashCode();
306    }
307
308    private class NSContext extends SimpleNamespaceContext {
309       public NSContext() {
310          super();
311       }
312
313       /**
314        * <i>[Jaxen NamespaceContext interface support]</i> Translates
315        * the provided namespace prefix into the matching bound
316        * namespace URI.
317        *
318        * @param prefix the namespace prefix to resolve.
319        *
320        * @return the namespace URI matching the prefix.
321        */

322       public String JavaDoc translateNamespacePrefixToUri(String JavaDoc prefix) {
323          if ((prefix == null) || (prefix.length() == 0)) {
324             return null;
325          }
326
327          String JavaDoc uri = super.translateNamespacePrefixToUri(prefix);
328          if (uri == null) {
329             Object JavaDoc ctx = currentContext;
330             if (ctx != null) {
331                Element elt = null;
332
333                // Get closer element node
334
if (ctx instanceof Element) {
335                   elt = (Element)ctx;
336                } else if (ctx instanceof Attribute) {
337                   elt = ((Attribute)ctx).getParent();
338                } else if (ctx instanceof Content) {
339                   elt = ((Content) ctx).getParentElement();
340                } else if (ctx instanceof Document) {
341                   elt = ((Document)ctx).getRootElement();
342                }
343
344                if (elt != null) {
345                   Namespace ns = elt.getNamespace(prefix);
346                   if (ns != null) {
347                      uri = ns.getURI();
348                   }
349                }
350             }
351          }
352          return uri;
353       }
354    }
355 }
356
357
Popular Tags