1 /*
2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.xml.xpath;
27 
28 import javax.xml.namespace.NamespaceContext;
29 import javax.xml.namespace.QName;
30 import org.xml.sax.InputSource;
31 
32 /**
33  * {@code XPath} provides access to the XPath evaluation environment and expressions.
34  * The XPath evaluation is affected by the factors described in the following table.
35  *
36  * <a id="XPath-evaluation"></a>
37  * <table class="striped">
38  *    <caption>Evaluation of XPath Expressions</caption>
39  *    <thead>
40  *      <tr>
41  *        <th scope="col">Factor</th>
42  *        <th scope="col">Behavior</th>
43  *      </tr>
44  *    </thead>
45  *    <tbody>
46  *    <tr>
47  *      <th scope="row">context</th>
48  *      <td>
49  *        The type of the context is implementation-dependent. If the value is
50  *        null, the operation must have no dependency on the context, otherwise
51  *        an XPathExpressionException will be thrown.
52  *
53  *        For the purposes of evaluating XPath expressions, a DocumentFragment
54  *        is treated like a Document node.
55  *      </td>
56  *    </tr>
57  *    <tr>
58  *      <th scope="row">variables</th>
59  *      <td>
60  *        If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}
61  *        set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}.
62  *        An {@link XPathExpressionException} is raised if the variable resolver is undefined or
63  *        the resolver returns {@code null} for the variable.
64  *        The value of a variable must be immutable through the course of any single evaluation.
65  *      </td>
66  *    </tr>
67  *    <tr>
68  *      <th scope="row">functions</th>
69  *      <td>
70  *        If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}
71  *        set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}.
72  *        An {@link XPathExpressionException} is raised if the function resolver is undefined or
73  *        the function resolver returns {@code null} for the function.
74  *      </td>
75  *    </tr>
76  *    <tr>
77  *      <th scope="row">QNames</th>
78  *      <td>
79  *        QNames in the expression are resolved against the XPath namespace context
80  *        set with {@link #setNamespaceContext(NamespaceContext nsContext)}.
81  *      </td>
82  *    </tr>
83  *    <tr>
84  *      <th scope="row">result</th>
85  *      <td>
86  *        This result of evaluating an expression is converted to an instance of the desired return type.
87  *        Valid return types are defined in {@link XPathConstants}.
88  *        Conversion to the return type follows XPath conversion rules.
89  *      </td>
90  *    </tr>
91  *    </tbody>
92  * </table>
93  *
94  * <p>An XPath object is not thread-safe and not reentrant.
95  * In other words, it is the application's responsibility to make
96  * sure that one {@link XPath} object is not used from
97  * more than one thread at any given time, and while the {@code evaluate}
98  * method is invoked, applications may not recursively call
99  * the {@code evaluate} method.
100  *
101  * @author  Norman Walsh
102  * @author  Jeff Suttor
103  * @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a>
104  * @since 1.5
105  */
106 public interface XPath {
107 
108 
109     /**
110      * Reset this {@code XPath} to its original configuration.
111      *
112      * <p>{@code XPath} is reset to the same state as when it was created with
113      * {@link XPathFactory#newXPath()}.
114      * {@code reset()} is designed to allow the reuse of existing {@code XPath}s
115      * thus saving resources associated with the creation of new {@code XPath}s.
116      *
117      * <p>The reset {@code XPath} is not guaranteed to have the same
118      * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
119      * or {@link NamespaceContext} {@code Object}s, e.g. {@link Object#equals(Object obj)}.
120      * It is guaranteed to have a functionally equal {@code XPathFunctionResolver},
121      * {@code XPathVariableResolver} and {@code NamespaceContext}.
122      */
reset()123     public void reset();
124 
125     /**
126      * Establish a variable resolver.
127      *
128      * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
129      *
130      * @param resolver Variable resolver.
131      *
132      * @throws NullPointerException If {@code resolver} is {@code null}.
133      */
setXPathVariableResolver(XPathVariableResolver resolver)134     public void setXPathVariableResolver(XPathVariableResolver resolver);
135 
136     /**
137        * Return the current variable resolver.
138        *
139        * <p>{@code null} is returned in no variable resolver is in effect.
140        *
141        * @return Current variable resolver.
142        */
getXPathVariableResolver()143     public XPathVariableResolver getXPathVariableResolver();
144 
145     /**
146        * Establish a function resolver.
147        *
148        * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
149        *
150        * @param resolver XPath function resolver.
151        *
152        * @throws NullPointerException If {@code resolver} is {@code null}.
153        */
setXPathFunctionResolver(XPathFunctionResolver resolver)154     public void setXPathFunctionResolver(XPathFunctionResolver resolver);
155 
156     /**
157        * Return the current function resolver.
158        * <p>
159        * {@code null} is returned in no function resolver is in effect.
160        *
161        * @return Current function resolver.
162        */
getXPathFunctionResolver()163     public XPathFunctionResolver getXPathFunctionResolver();
164 
165     /**
166        * Establish a namespace context.
167        *
168        * <p>A {@code NullPointerException} is thrown if {@code nsContext} is {@code null}.
169        *
170        * @param nsContext Namespace context to use.
171        *
172        * @throws NullPointerException If {@code nsContext} is {@code null}.
173        */
setNamespaceContext(NamespaceContext nsContext)174     public void setNamespaceContext(NamespaceContext nsContext);
175 
176     /**
177        * Return the current namespace context.
178        *
179        * <p>{@code null} is returned in no namespace context is in effect.
180        *
181        * @return Current Namespace context.
182        */
getNamespaceContext()183     public NamespaceContext getNamespaceContext();
184 
185     /**
186        * Compile an XPath expression for later evaluation.
187        *
188        * <p>If {@code expression} contains any {@link XPathFunction}s,
189        * they must be available via the {@link XPathFunctionResolver}.
190        * An {@link XPathExpressionException} will be thrown if the
191        * {@code XPathFunction}
192        * cannot be resovled with the {@code XPathFunctionResolver}.
193        *
194        * <p>If {@code expression} contains any variables, the
195        * {@link XPathVariableResolver} in effect
196        * <strong>at compile time</strong> will be used to resolve them.
197        *
198        * @param expression The XPath expression.
199        *
200        * @return Compiled XPath expression.
201 
202        * @throws XPathExpressionException If {@code expression} cannot be compiled.
203        * @throws NullPointerException If {@code expression} is {@code null}.
204        */
compile(String expression)205     public XPathExpression compile(String expression)
206         throws XPathExpressionException;
207 
208     /**
209      * Evaluate an {@code XPath} expression in the specified context and
210      * return the result as the specified type.
211      *
212      * <p>
213      * See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a>
214      * for context item evaluation, variable, function and {@code QName} resolution
215      * and return type conversion.
216      * <p>
217      * The parameter {@code item} represents the context the XPath expression
218      * will be operated on. The type of the context is implementation-dependent.
219      * If the value is {@code null}, the operation must have no dependency on
220      * the context, otherwise an XPathExpressionException will be thrown.
221      *
222      * @implNote
223      * The type of the context is usually {@link org.w3c.dom.Node}.
224      *
225      * @param expression The XPath expression.
226      * @param item The context the XPath expression will be evaluated in.
227      * @param returnType The result type expected to be returned by the XPath expression.
228      *
229      * @return The result of evaluating an XPath expression as an {@code Object} of {@code returnType}.
230      *
231      * @throws XPathExpressionException If {@code expression} cannot be evaluated.
232      * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants} (
233      * {@link XPathConstants#NUMBER NUMBER},
234      * {@link XPathConstants#STRING STRING},
235      * {@link XPathConstants#BOOLEAN BOOLEAN},
236      * {@link XPathConstants#NODE NODE} or
237      * {@link XPathConstants#NODESET NODESET}).
238      * @throws NullPointerException If {@code expression or returnType} is {@code null}.
239      */
evaluate(String expression, Object item, QName returnType)240     public Object evaluate(String expression, Object item, QName returnType)
241         throws XPathExpressionException;
242 
243     /**
244      * Evaluate an XPath expression in the specified context and return the result as a {@code String}.
245      *
246      * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a {@code returnType} of
247      * {@link XPathConstants#STRING}.
248      *
249      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
250      * variable, function and QName resolution and return type conversion.
251      *
252      * <p>
253      * The parameter {@code item} represents the context the XPath expression
254      * will be operated on. The type of the context is implementation-dependent.
255      * If the value is {@code null}, the operation must have no dependency on
256      * the context, otherwise an XPathExpressionException will be thrown.
257      *
258      * @implNote
259      * The type of the context is usually {@link org.w3c.dom.Node}.
260      *
261      * @param expression The XPath expression.
262      * @param item The context the XPath expression will be evaluated in.
263      *
264      * @return The result of evaluating an XPath expression as a {@code String}.
265      *
266      * @throws XPathExpressionException If {@code expression} cannot be evaluated.
267      * @throws NullPointerException If {@code expression} is {@code null}.
268      */
evaluate(String expression, Object item)269     public String evaluate(String expression, Object item)
270         throws XPathExpressionException;
271 
272     /**
273      * Evaluate an XPath expression in the context of the specified {@code InputSource}
274      * and return the result as the specified type.
275      *
276      * <p>This method builds a data model for the {@link InputSource} and calls
277      * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.
278      *
279      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
280      * variable, function and QName resolution and return type conversion.
281      *
282      * @param expression The XPath expression.
283      * @param source The input source of the document to evaluate over.
284      * @param returnType The desired return type.
285      *
286      * @return The {@code Object} that encapsulates the result of evaluating the expression.
287      *
288      * @throws XPathExpressionException If expression cannot be evaluated.
289      * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
290      * @throws NullPointerException If {@code expression, source or returnType} is {@code null}.
291      */
evaluate( String expression, InputSource source, QName returnType)292     public Object evaluate(
293         String expression,
294         InputSource source,
295         QName returnType)
296         throws XPathExpressionException;
297 
298     /**
299      * Evaluate an XPath expression in the context of the specified {@code InputSource}
300      * and return the result as a {@code String}.
301      *
302      * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
303      * {@code returnType} of {@link XPathConstants#STRING}.
304      *
305      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
306      * variable, function and QName resolution and return type conversion.
307      *
308      * @param expression The XPath expression.
309      * @param source The {@code InputSource} of the document to evaluate over.
310      *
311      * @return The {@code String} that is the result of evaluating the expression and
312      *   converting the result to a {@code String}.
313      *
314      * @throws XPathExpressionException If expression cannot be evaluated.
315      * @throws NullPointerException If {@code expression or source} is {@code null}.
316      */
evaluate(String expression, InputSource source)317     public String evaluate(String expression, InputSource source)
318         throws XPathExpressionException;
319 
320     /**
321      * Evaluate an XPath expression in the specified context and return
322      * the result with the type specified through the {@code class type}
323      *
324      * <p>
325      * The parameter {@code item} represents the context the XPath expression
326      * will be operated on. The type of the context is implementation-dependent.
327      * If the value is {@code null}, the operation must have no dependency on
328      * the context, otherwise an XPathExpressionException will be thrown.
329      *
330      * @implNote
331      * The type of the context is usually {@link org.w3c.dom.Node}.
332      *
333      * @implSpec
334      * The default implementation in the XPath API is equivalent to:
335      * <pre> {@code
336      *     (T)evaluate(expression, item,
337      *           XPathEvaluationResult.XPathResultType.getQNameType(type));
338      * }</pre>
339      *
340      * Since the {@code evaluate} method does not support the
341      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
342      * XPathEvaluationResult as the type will result in IllegalArgumentException.
343      * Any implementation supporting the
344      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
345      * this method.
346      *
347      * @param <T> The class type that will be returned by the XPath expression.
348      * @param expression The XPath expression.
349      * @param item The context the XPath expression will be evaluated in.
350      * @param type The class type expected to be returned by the XPath expression.
351      *
352      * @return The result of evaluating the expression.
353      *
354      * @throws XPathExpressionException If the expression cannot be evaluated.
355      * @throws IllegalArgumentException If {@code type} is not of the types
356      * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType},
357      * or XPathEvaluationResult is specified as the type but an implementation supporting the
358      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
359      * @throws NullPointerException If {@code expression or type} is {@code null}.
360      *
361      * @since 9
362      */
evaluateExpression(String expression, Object item, Class<T> type)363     default <T>T evaluateExpression(String expression, Object item, Class<T> type)
364         throws XPathExpressionException {
365         return type.cast(evaluate(expression, item,
366                 XPathEvaluationResult.XPathResultType.getQNameType(type)));
367     }
368 
369     /**
370      * Evaluate an XPath expression in the specified context. This is equivalent to
371      * calling {@link #evaluateExpression(String expression, Object item, Class type)}
372      * with type {@link XPathEvaluationResult}:
373      * <pre> {@code
374      *     evaluateExpression(expression, item, XPathEvaluationResult.class);
375      * }</pre>
376      * <p>
377      * The parameter {@code item} represents the context the XPath expression
378      * will be operated on. The type of the context is implementation-dependent.
379      * If the value is {@code null}, the operation must have no dependency on
380      * the context, otherwise an XPathExpressionException will be thrown.
381      *
382      * @implNote
383      * The type of the context is usually {@link org.w3c.dom.Node}.
384      *
385      * @implSpec
386      * The default implementation in the XPath API is equivalent to:
387      * <pre> {@code
388      *     evaluateExpression(expression, item, XPathEvaluationResult.class);
389      * }</pre>
390      *
391      * Since the {@code evaluate} method does not support the
392      * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
393      * type, the default implementation of this method will always throw an
394      * IllegalArgumentException. Any implementation supporting the
395      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
396      * override this method.
397      *
398      * @param expression The XPath expression.
399      * @param item The context the XPath expression will be evaluated in.
400      *
401      * @return The result of evaluating the expression.
402      *
403      * @throws XPathExpressionException If the expression cannot be evaluated.
404      * @throws IllegalArgumentException If the implementation of this method
405      * does not support the
406      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
407      * @throws NullPointerException If {@code expression} is {@code null}.
408      *
409      * @since 9
410      */
evaluateExpression(String expression, Object item)411     default XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
412         throws XPathExpressionException
413     {
414         return evaluateExpression(expression, item, XPathEvaluationResult.class);
415     }
416 
417     /**
418      * Evaluate an XPath expression in the context of the specified {@code source}
419      * and return the result as specified.
420      * <p>
421      * This method builds a data model for the {@link InputSource} and calls
422      * {@link #evaluateExpression(String expression, Object item, Class type)}
423      * on the resulting document object. The data model is usually
424      * {@link org.w3c.dom.Document}
425      *
426      * @implSpec
427      * The default implementation in the XPath API is equivalent to:
428      * <pre> {@code
429            (T)evaluate(expression, source,
430                 XPathEvaluationResult.XPathResultType.getQNameType(type));
431      * }</pre>
432      *
433      * Since the {@code evaluate} method does not support the
434      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
435      * XPathEvaluationResult as the type will result in IllegalArgumentException.
436      * Any implementation supporting the
437      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
438      * this method.
439      *
440      * @param <T> The class type that will be returned by the XPath expression.
441      * @param expression The XPath expression.
442      * @param source The input source of the document to evaluate over.
443      * @param type The class type expected to be returned by the XPath expression.
444      *
445      * @return The result of evaluating the expression.
446      *
447      * @throws XPathExpressionException If the expression cannot be evaluated.
448      * @throws IllegalArgumentException If {@code type} is not of the types
449      * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
450      * XPathResultType}, or XPathEvaluationResult is specified as the type but an
451      * implementation supporting the
452      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
453      * @throws NullPointerException If {@code expression, source or type}is {@code null}.
454      *
455      * @since 9
456      */
evaluateExpression(String expression, InputSource source, Class<T> type)457     default <T>T evaluateExpression(String expression, InputSource source, Class<T> type)
458         throws XPathExpressionException
459     {
460         return type.cast(evaluate(expression, source,
461                 XPathEvaluationResult.XPathResultType.getQNameType(type)));
462     }
463 
464     /**
465      * Evaluate an XPath expression in the specified context. This is equivalent to
466      * calling {@link #evaluateExpression(String expression, Object item, Class type)}
467      * with type {@link XPathEvaluationResult}:
468      * <pre> {@code
469      *     evaluateExpression(expression, item, XPathEvaluationResult.class);
470      * }</pre>
471      *
472      * @implSpec
473      * The default implementation in the XPath API is equivalent to:
474      * <pre> {@code
475      *     evaluateExpression(expression, source, XPathEvaluationResult.class);
476      * }</pre>
477      *
478      * Since the {@code evaluate} method does not support the
479      * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
480      * type, the default implementation of this method will always throw an
481      * IllegalArgumentException. Any implementation supporting the
482      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
483      * override this method.
484      *
485      * @param expression The XPath expression.
486      * @param source The input source of the document to evaluate over.
487      *
488      * @return The result of evaluating the expression.
489      *
490      * @throws XPathExpressionException If the expression cannot be evaluated.
491      * @throws IllegalArgumentException If the implementation of this method
492      * does not support the
493      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
494      * @throws NullPointerException If {@code expression or source} is {@code null}.
495      *
496      * @since 9
497      */
evaluateExpression(String expression, InputSource source)498     default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
499         throws XPathExpressionException
500     {
501         return evaluateExpression(expression, source, XPathEvaluationResult.class);
502     }
503 }
504