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
26package javax.xml.xpath;
27
28import javax.xml.namespace.NamespaceContext;
29import javax.xml.namespace.QName;
30import 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  <a href="Norman.Walsh@Sun.com">Norman Walsh</a>
102 * @author  <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a>
103 * @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a>
104 * @since 1.5
105 */
106public 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     */
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     */
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       */
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       */
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       */
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       */
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       */
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       */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
498    default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
499        throws XPathExpressionException
500    {
501        return evaluateExpression(expression, source, XPathEvaluationResult.class);
502    }
503}
504