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.QName;
  29 import org.xml.sax.InputSource;
  30 
  31 /**
  32  * {@code XPathExpression} provides access to compiled XPath expressions.
  33  * The XPath evaluation is affected by the factors described in the following table.
  34  *
  35  * <a id="XPathExpression-evaluation"></a>
  36  * <table class="striped">
  37  *    <caption>Evaluation of XPath Expressions</caption>
  38  *    <thead>
  39  *      <tr>
  40  *        <th>Factor</th>
  41  *        <th>Behavior</th>
  42  *      </tr>
  43  *    </thead>
  44  *    <tbody>
  45  *    <tr>
  46  *      <td>context</td>
  47  *      <td>
  48  *        The type of the context is implementation-dependent. If the value is
  49  *        null, the operation must have no dependency on the context, otherwise
  50  *        an XPathExpressionException will be thrown.
  51  *
  52  *        For the purposes of evaluating XPath expressions, a DocumentFragment
  53  *        is treated like a Document node.
  54  *      </td>
  55  *    </tr>
  56  *    <tr>
  57  *      <td>variables</td>
  58  *      <td>
  59  *        If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}.
  60  *        An {@link XPathExpressionException} is raised if the variable resolver is undefined or
  61  *        the resolver returns {@code null} for the variable.
  62  *        The value of a variable must be immutable through the course of any single evaluation.
  63  *      </td>
  64  *    </tr>
  65  *    <tr>
  66  *      <td>functions</td>
  67  *      <td>
  68  *        If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}.
  69  *        An {@link XPathExpressionException} is raised if the function resolver is undefined or
  70  *        the function resolver returns {@code null} for the function.
  71  *      </td>
  72  *    </tr>
  73  *    <tr>
  74  *      <td>QNames</td>
  75  *      <td>
  76  *        QNames in the expression are resolved against the XPath namespace context.
  77  *      </td>
  78  *    </tr>
  79  *    <tr>
  80  *      <td>result</td>
  81  *      <td>
  82  *        This result of evaluating an expression is converted to an instance of the desired return type.
  83  *        Valid return types are defined in {@link XPathConstants}.
  84  *        Conversion to the return type follows XPath conversion rules.
  85  *      </td>
  86  *    </tr>
  87  *   </tbody>
  88  * </table>
  89  *
  90  * <p>An XPath expression is not thread-safe and not reentrant.
  91  * In other words, it is the application's responsibility to make
  92  * sure that one {@link XPathExpression} object is not used from
  93  * more than one thread at any given time, and while the {@code evaluate}
  94  * method is invoked, applications may not recursively call
  95  * the {@code evaluate} method.
  96  *
  97  * @author  <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a>
  98  * @author  <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
  99  * @see <a href="http://www.w3.org/TR/xpath#section-Expressions">XML Path Language (XPath) Version 1.0, Expressions</a>
 100  * @since 1.5
 101  */
 102 public interface XPathExpression {
 103 
 104 
 105     /**
 106      * Evaluate the compiled XPath expression in the specified context and return the result as the specified type.
 107      *
 108      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
 109      * variable, function and QName resolution and return type conversion.
 110      *
 111      * <p>
 112      * The parameter {@code item} represents the context the XPath expression
 113      * will be operated on. The type of the context is implementation-dependent.
 114      * If the value is {@code null}, the operation must have no dependency on
 115      * the context, otherwise an XPathExpressionException will be thrown.
 116      *
 117      * @implNote
 118      * The type of the context is usually {@link org.w3c.dom.Node}.
 119      *
 120      * @param item The context the XPath expression will be evaluated in.
 121      * @param returnType The result type expected to be returned by the XPath expression.
 122      *
 123      * @return The {@code Object} that is the result of evaluating the expression and converting the result to
 124      *   {@code returnType}.
 125      *
 126      * @throws XPathExpressionException If the expression cannot be evaluated.
 127      * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
 128      * @throws NullPointerException If {@code returnType} is {@code null}.
 129      */
 130     public Object evaluate(Object item, QName returnType)
 131         throws XPathExpressionException;
 132 
 133     /**
 134      * Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}.
 135      *
 136      * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a {@code returnType} of
 137      * {@link XPathConstants#STRING}.
 138      *
 139      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
 140      * variable, function and QName resolution and return type conversion.
 141      *
 142      * <p>
 143      * The parameter {@code item} represents the context the XPath expression
 144      * will be operated on. The type of the context is implementation-dependent.
 145      * If the value is {@code null}, the operation must have no dependency on
 146      * the context, otherwise an XPathExpressionException will be thrown.
 147      *
 148      * @implNote
 149      * The type of the context is usually {@link org.w3c.dom.Node}.
 150      *
 151      * @param item The context the XPath expression will be evaluated in.
 152      *
 153      * @return The result of evaluating an XPath expression as a {@code String}.
 154      *
 155      * @throws XPathExpressionException If the expression cannot be evaluated.
 156      */
 157     public String evaluate(Object item)
 158         throws XPathExpressionException;
 159 
 160     /**
 161      * Evaluate the compiled XPath expression in the context
 162      * of the specified {@code InputSource} and return the result as the
 163      * specified type.
 164      *
 165      * <p>This method builds a data model for the {@link InputSource} and calls
 166      * {@link #evaluate(Object item, QName returnType)} on the resulting document object.
 167      *
 168      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
 169      * variable, function and QName resolution and return type conversion.
 170      *
 171      * <p>If {@code returnType} is not one of the types defined in {@link XPathConstants},
 172      * then an {@code IllegalArgumentException} is thrown.
 173      *
 174      * <p>If {@code source} or {@code returnType} is {@code null},
 175      * then a {@code NullPointerException} is thrown.
 176      *
 177      * @param source The {@code InputSource} of the document to evaluate over.
 178      * @param returnType The desired return type.
 179      *
 180      * @return The {@code Object} that is the result of evaluating the expression and converting the result to
 181      *   {@code returnType}.
 182      *
 183      * @throws XPathExpressionException If the expression cannot be evaluated.
 184      * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
 185      * @throws NullPointerException If {@code source or returnType} is {@code null}.
 186      */
 187     public Object evaluate(InputSource source, QName returnType)
 188         throws XPathExpressionException;
 189 
 190     /**
 191      * Evaluate the compiled XPath expression in the context
 192      * of the specified {@code InputSource} and return the result as a
 193      * {@code String}.
 194      *
 195      * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a {@code returnType} of
 196      * {@link XPathConstants#STRING}.
 197      *
 198      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
 199      * variable, function and QName resolution and return type conversion.
 200      *
 201      * <p>If {@code source} is {@code null}, then a {@code NullPointerException} is thrown.
 202      *
 203      * @param source The {@code InputSource} of the document to evaluate over.
 204      *
 205      * @return The {@code String} that is the result of evaluating the expression and converting the result to a
 206      *   {@code String}.
 207      *
 208      * @throws XPathExpressionException If the expression cannot be evaluated.
 209      * @throws NullPointerException If {@code source} is {@code null}.
 210      */
 211     public String evaluate(InputSource source)
 212         throws XPathExpressionException;
 213 
 214     /**
 215      * Evaluate the compiled XPath expression in the specified context, and return
 216      * the result with the type specified through the {@code class type}.
 217      *
 218      * <p>
 219      * The parameter {@code item} represents the context the XPath expression
 220      * will be operated on. The type of the context is implementation-dependent.
 221      * If the value is {@code null}, the operation must have no dependency on
 222      * the context, otherwise an XPathExpressionException will be thrown.
 223      *
 224      * @implNote
 225      * The type of the context is usually {@link org.w3c.dom.Node}.
 226      *
 227      * @implSpec
 228      * The default implementation in the XPath API is equivalent to:
 229      * <pre> {@code
 230      *     (T)evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type));
 231      * }</pre>
 232      *
 233      * Since the {@code evaluate} method does not support the
 234      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
 235      * XPathEvaluationResult as the type will result in IllegalArgumentException.
 236      * Any implementation supporting the
 237      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
 238      * this method.
 239      *
 240      * @param <T> The class type that will be returned by the XPath expression.
 241      * @param item The context the XPath expression will be evaluated in.
 242      * @param type The class type expected to be returned by the XPath expression.
 243      *
 244      * @return The result of evaluating the expression.
 245      *
 246      * @throws XPathExpressionException If the expression cannot be evaluated.
 247      * @throws IllegalArgumentException If {@code type} is not of the types
 248      * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
 249      * XPathResultType}, or XPathEvaluationResult is specified as the type but an
 250      * implementation supporting the
 251      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
 252      * @throws NullPointerException If {@code type} is {@code null}.
 253      *
 254      * @since 9
 255      */
 256     default <T>T evaluateExpression(Object item, Class<T> type)
 257         throws XPathExpressionException
 258     {
 259         return type.cast(evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type)));
 260     }
 261 
 262     /**
 263      * Evaluate the compiled XPath expression in the specified context. This is
 264      * equivalent to calling {@link #evaluateExpression(Object item, Class type)}
 265      * with type {@link XPathEvaluationResult}:
 266      * <pre> {@code
 267      *     evaluateExpression(item, XPathEvaluationResult.class);
 268      * }</pre>
 269      * <p>
 270      * The parameter {@code item} represents the context the XPath expression
 271      * will be operated on. The type of the context is implementation-dependent.
 272      * If the value is {@code null}, the operation must have no dependency on
 273      * the context, otherwise an XPathExpressionException will be thrown.
 274      *
 275      * @implNote
 276      * The type of the context is usually {@link org.w3c.dom.Node}.
 277      *
 278      * @implSpec
 279      * The default implementation in the XPath API is equivalent to:
 280      * <pre> {@code
 281      *     evaluateExpression(item, XPathEvaluationResult.class);
 282      * }</pre>
 283      *
 284      * Since the {@code evaluate} method does not support the
 285      * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
 286      * type, the default implementation of this method will always throw an
 287      * IllegalArgumentException. Any implementation supporting the
 288      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
 289      * override this method.
 290      *
 291      * @param item The context the XPath expression will be evaluated in.
 292      *
 293      * @return The result of evaluating the expression.
 294      *
 295      * @throws XPathExpressionException If the expression cannot be evaluated.
 296      * @throws IllegalArgumentException If the implementation of this method
 297      * does not support the
 298      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
 299      *
 300      * @since 9
 301      */
 302     default XPathEvaluationResult<?> evaluateExpression(Object item)
 303         throws XPathExpressionException
 304     {
 305         return evaluateExpression(item, XPathEvaluationResult.class);
 306     }
 307 
 308     /**
 309      * Evaluate the compiled XPath expression in the specified context,
 310      * and return the result with the type specified through the {@code class type}
 311      * <p>
 312      * This method builds a data model for the {@link InputSource} and calls
 313      * {@link #evaluateExpression(Object item, Class type)} on the resulting
 314      * document object.
 315      * <P>
 316      * By default, the JDK's data model is {@link org.w3c.dom.Document}.
 317      *
 318      * @implSpec
 319      * The default implementation in the XPath API is equivalent to:
 320      * <pre> {@code
 321            (T)evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type));
 322      * }</pre>
 323      *
 324      * Since the {@code evaluate} method does not support the
 325      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
 326      * XPathEvaluationResult as the type will result in IllegalArgumentException.
 327      * Any implementation supporting the
 328      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
 329      * this method.
 330      *
 331      * @param <T> The class type that will be returned by the XPath expression.
 332      * @param source The {@code InputSource} of the document to evaluate over.
 333      * @param type The class type expected to be returned by the XPath expression.
 334      *
 335      * @return The result of evaluating the expression.
 336      *
 337      * @throws XPathExpressionException If the expression cannot be evaluated.
 338      * @throws IllegalArgumentException If {@code type} is not of the types
 339      * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
 340      * XPathResultType}, or XPathEvaluationResult is specified as the type but an
 341      * implementation supporting the
 342      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type
 343      * is not available.
 344      * @throws NullPointerException If {@code source or type} is {@code null}.
 345      *
 346      * @since 9
 347      */
 348     default <T>T evaluateExpression(InputSource source, Class<T> type)
 349         throws XPathExpressionException
 350     {
 351         return type.cast(evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type)));
 352     }
 353 
 354     /**
 355      * Evaluate the compiled XPath expression in the specified context. This is
 356      * equivalent to calling {@link #evaluateExpression(InputSource source, Class type)}
 357      * with type {@link XPathEvaluationResult}:
 358      * <pre> {@code
 359      *     evaluateExpression(source, XPathEvaluationResult.class);
 360      * }</pre>
 361      *
 362      * @implSpec
 363      * The default implementation in the XPath API is equivalent to:
 364      * <pre> {@code
 365      *     (XPathEvaluationResult)evaluateExpression(source, XPathEvaluationResult.class);
 366      * }</pre>
 367      *
 368      * Since the {@code evaluate} method does not support the
 369      * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
 370      * type, the default implementation of this method will always throw an
 371      * IllegalArgumentException. Any implementation supporting the
 372      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
 373      * override this method.
 374      *
 375      * @param source The {@code InputSource} of the document to evaluate over.
 376      *
 377      * @return The result of evaluating the expression.
 378      *
 379      * @throws XPathExpressionException If the expression cannot be evaluated.
 380      * @throws IllegalArgumentException If the implementation of this method
 381      * does not support the
 382      * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
 383      * @throws NullPointerException If {@code source} is {@code null}.
 384      *
 385      * @since 9
 386      */
 387     default XPathEvaluationResult<?> evaluateExpression(InputSource source)
 388         throws XPathExpressionException
 389     {
 390         return evaluateExpression(source, XPathEvaluationResult.class);
 391     }
 392 }