src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java

Print this page


   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 1999-2004 The Apache Software Foundation.





   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 // $Id: XPathExpressionImpl.java,v 1.3 2005/09/27 09:40:43 sunithareddy Exp $
  21 
  22 package com.sun.org.apache.xpath.internal.jaxp;
  23 
  24 import com.sun.org.apache.xpath.internal.*;
  25 import javax.xml.transform.TransformerException;
  26 
  27 import com.sun.org.apache.xpath.internal.objects.XObject;
  28 import com.sun.org.apache.xml.internal.dtm.DTM;
  29 import com.sun.org.apache.xml.internal.utils.PrefixResolver;
  30 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
  31 import com.sun.org.apache.xalan.internal.res.XSLMessages;
  32 import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
  33 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
  34 
  35 import javax.xml.namespace.NamespaceContext;
  36 import javax.xml.namespace.QName;
  37 import javax.xml.xpath.XPathExpressionException;
  38 import javax.xml.xpath.XPathConstants;



  39 import javax.xml.xpath.XPathFunctionResolver;
  40 import javax.xml.xpath.XPathVariableResolver;
  41 import javax.xml.xpath.XPathConstants;
  42 
  43 import org.w3c.dom.Node;
  44 import org.w3c.dom.Document;
  45 import org.w3c.dom.DOMImplementation;
  46 import org.w3c.dom.traversal.NodeIterator;
  47 import javax.xml.parsers.DocumentBuilderFactory;
  48 import javax.xml.parsers.DocumentBuilder;
  49 
  50 import org.xml.sax.InputSource;
  51 
  52 /**
  53  * The XPathExpression interface encapsulates a (compiled) XPath expression.
  54  *
  55  * @author  Ramesh Mandava
  56  */
  57 public class XPathExpressionImpl  implements javax.xml.xpath.XPathExpression{
  58 
  59     private XPathFunctionResolver functionResolver;
  60     private XPathVariableResolver variableResolver;
  61     private JAXPPrefixResolver prefixResolver;
  62     private com.sun.org.apache.xpath.internal.XPath xpath;
  63 
  64     // By default Extension Functions are allowed in XPath Expressions. If
  65     // Secure Processing Feature is set on XPathFactory then the invocation of
  66     // extensions function need to throw XPathFunctionException
  67     private boolean featureSecureProcessing = false;
  68 
  69     private boolean useServicesMechanism = true;
  70 
  71     private final FeatureManager featureManager;
  72 
  73     /** Protected constructor to prevent direct instantiation; use compile()
  74      * from the context.
  75      */
  76     protected XPathExpressionImpl() {
  77         this(null, null, null, null,
  78              false, true, new FeatureManager());
  79     };
  80 
  81     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
  82             JAXPPrefixResolver prefixResolver,
  83             XPathFunctionResolver functionResolver,
  84             XPathVariableResolver variableResolver ) {
  85         this(xpath, prefixResolver, functionResolver, variableResolver,
  86              false, true, new FeatureManager());
  87     };
  88 
  89     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
  90             JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
  91             XPathVariableResolver variableResolver, boolean featureSecureProcessing,
  92             boolean useServicesMechanism, FeatureManager featureManager ) {
  93         this.xpath = xpath;
  94         this.prefixResolver = prefixResolver;
  95         this.functionResolver = functionResolver;
  96         this.variableResolver = variableResolver;
  97         this.featureSecureProcessing = featureSecureProcessing;
  98         this.useServicesMechanism = useServicesMechanism;
  99         this.featureManager = featureManager;
 100     };
 101 
 102     public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath ) {
 103         this.xpath = xpath;
 104     }
 105 
 106     public Object eval(Object item, QName returnType)
 107             throws javax.xml.transform.TransformerException {
 108         XObject resultObject = eval ( item );
 109         return getResultAsType( resultObject, returnType );
 110     }
 111 
 112     private XObject eval ( Object contextItem )
 113             throws javax.xml.transform.TransformerException {
 114         com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
 115         if ( functionResolver != null ) {
 116             JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
 117                     functionResolver, featureSecureProcessing, featureManager );
 118             xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
 119         } else {
 120             xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
 121         }
 122 
 123         xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
 124         XObject xobj = null;
 125 
 126         Node contextNode = (Node)contextItem;
 127         // We always need to have a ContextNode with Xalan XPath implementation
 128         // To allow simple expression evaluation like 1+1 we are setting
 129         // dummy Document as Context Node
 130 
 131         if ( contextNode == null )
 132             xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
 133         else
 134             xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
 135 
 136         return xobj;
 137     }
 138 
 139 
 140     /**
 141      * <p>Evaluate the compiled XPath expression in the specified context and
 142      *  return the result as the specified type.</p>
 143      *
 144      * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
 145      * for context item evaluation,
 146      * variable, function and QName resolution and return type conversion.</p>
 147      *
 148      * <p>If <code>returnType</code> is not one of the types defined
 149      * in {@link XPathConstants},
 150      * then an <code>IllegalArgumentException</code> is thrown.</p>
 151      *
 152      * <p>If a <code>null</code> value is provided for
 153      * <code>item</code>, an empty document will be used for the
 154      * context.
 155      * If <code>returnType</code> is <code>null</code>, then a
 156      * <code>NullPointerException</code> is thrown.</p>
 157      *
 158      * @param item The starting context (node or node list, for example).
 159      * @param returnType The desired return type.
 160      *
 161      * @return The <code>Object</code> that is the result of evaluating the
 162      * expression and converting the result to
 163      *   <code>returnType</code>.
 164      *
 165      * @throws XPathExpressionException If the expression cannot be evaluated.
 166      * @throws IllegalArgumentException If <code>returnType</code> is not one
 167      * of the types defined in {@link XPathConstants}.
 168      * @throws NullPointerException If  <code>returnType</code> is
 169      * <code>null</code>.
 170      */
 171     public Object evaluate(Object item, QName returnType)
 172         throws XPathExpressionException {
 173         //Validating parameters to enforce constraints defined by JAXP spec
 174         if ( returnType == null ) {
 175            //Throwing NullPointerException as defined in spec
 176             String fmsg = XSLMessages.createXPATHMessage(
 177                     XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
 178                     new Object[] {"returnType"} );
 179             throw new NullPointerException( fmsg );
 180         }
 181         // Checking if requested returnType is supported. returnType need to be
 182         // defined in XPathConstants
 183         if ( !isSupported ( returnType ) ) {
 184             String fmsg = XSLMessages.createXPATHMessage(
 185                     XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
 186                     new Object[] { returnType.toString() } );
 187             throw new IllegalArgumentException ( fmsg );
 188         }
 189         try {
 190             return eval( item, returnType);
 191         } catch ( java.lang.NullPointerException npe ) {
 192             // If VariableResolver returns null Or if we get
 193             // NullPointerException at this stage for some other reason
 194             // then we have to reurn XPathException
 195             throw new XPathExpressionException ( npe );
 196         } catch ( javax.xml.transform.TransformerException te ) {
 197             Throwable nestedException = te.getException();
 198             if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
 199                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
 200             } else {
 201                 // For any other exceptions we need to throw
 202                 // XPathExpressionException ( as per spec )
 203                 throw new XPathExpressionException( te);
 204             }
 205         }
 206 
 207     }
 208 
 209     /**
 210      * <p>Evaluate the compiled XPath expression in the specified context and
 211      * return the result as a <code>String</code>.</p>
 212      *
 213      * <p>This method calls {@link #evaluate(Object item, QName returnType)}
 214      * with a <code>returnType</code> of
 215      * {@link XPathConstants#STRING}.</p>
 216      *
 217      * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
 218      *  for context item evaluation,
 219      * variable, function and QName resolution and return type conversion.</p>
 220      *
 221      * <p>If a <code>null</code> value is provided for
 222      * <code>item</code>, an empty document will be used for the
 223      * context.
 224      *
 225      * @param item The starting context (node or node list, for example).
 226      *
 227      * @return The <code>String</code> that is the result of evaluating the
 228      * expression and converting the result to a
 229      *   <code>String</code>.
 230      *
 231      * @throws XPathExpressionException If the expression cannot be evaluated.
 232      */
 233     public String evaluate(Object item)
 234         throws XPathExpressionException {
 235         return (String)this.evaluate( item, XPathConstants.STRING );
 236     }
 237 
 238 
 239 
 240     static DocumentBuilderFactory dbf = null;
 241     static DocumentBuilder db = null;
 242     static Document d = null;
 243 
 244     /**
 245      * <p>Evaluate the compiled XPath expression in the context of the
 246      * specified <code>InputSource</code> and return the result as the
 247      *  specified type.</p>
 248      *
 249      * <p>This method builds a data model for the {@link InputSource} and calls
 250      * {@link #evaluate(Object item, QName returnType)} on the resulting
 251      * document object.</p>
 252      *
 253      * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
 254      *  for context item evaluation,
 255      * variable, function and QName resolution and return type conversion.</p>
 256      *
 257      * <p>If <code>returnType</code> is not one of the types defined in
 258      * {@link XPathConstants},
 259      * then an <code>IllegalArgumentException</code> is thrown.</p>
 260      *
 261      *<p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
 262      * then a <code>NullPointerException</code> is thrown.</p>
 263      *
 264      * @param source The <code>InputSource</code> of the document to evaluate
 265      * over.
 266      * @param returnType The desired return type.
 267      *
 268      * @return The <code>Object</code> that is the result of evaluating the
 269      * expression and converting the result to
 270      *   <code>returnType</code>.
 271      *
 272      * @throws XPathExpressionException If the expression cannot be evaluated.
 273      * @throws IllegalArgumentException If <code>returnType</code> is not one
 274      * of the types defined in {@link XPathConstants}.
 275      * @throws NullPointerException If  <code>source</code> or
 276      * <code>returnType</code> is <code>null</code>.
 277      */
 278     public Object evaluate(InputSource source, QName returnType)
 279         throws XPathExpressionException {
 280         if ( ( source == null ) || ( returnType == null ) ) {
 281             String fmsg = XSLMessages.createXPATHMessage(
 282                     XPATHErrorResources.ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
 283                     null );
 284             throw new NullPointerException ( fmsg );
 285         }
 286         // Checking if requested returnType is supported. returnType need to be
 287         // defined in XPathConstants
 288         if ( !isSupported ( returnType ) ) {
 289             String fmsg = XSLMessages.createXPATHMessage(
 290                     XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
 291                     new Object[] { returnType.toString() } );
 292             throw new IllegalArgumentException ( fmsg );
 293         }
 294         try {
 295             if ( dbf == null ) {
 296                 dbf = FactoryImpl.getDOMFactory(useServicesMechanism);
 297                 dbf.setNamespaceAware( true );
 298                 dbf.setValidating( false );
 299             }
 300             db = dbf.newDocumentBuilder();
 301             Document document = db.parse( source );
 302             return eval(  document, returnType );
 303         } catch ( Exception e ) {
 304             throw new XPathExpressionException ( e );
 305         }
 306     }
 307 
 308     /**
 309      * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
 310      * <code>String</code>.</p>
 311      *
 312      * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
 313      * {@link XPathConstants#STRING}.</p>
 314      *
 315      * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
 316      * for context item evaluation,
 317      * variable, function and QName resolution and return type conversion.</p>
 318      *
 319      * <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
 320      *
 321      * @param source The <code>InputSource</code> of the document to evaluate over.
 322      *
 323      * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
 324      *   <code>String</code>.
 325      *
 326      * @throws XPathExpressionException If the expression cannot be evaluated.
 327      * @throws NullPointerException If  <code>source</code> is <code>null</code>.
 328      */
 329     public String evaluate(InputSource source)
 330         throws XPathExpressionException {
 331         return (String)this.evaluate( source, XPathConstants.STRING );
 332     }
 333 
 334     private boolean isSupported( QName returnType ) {
 335         // XPathConstants.STRING
 336         if ( ( returnType.equals( XPathConstants.STRING ) ) ||
 337              ( returnType.equals( XPathConstants.NUMBER ) ) ||
 338              ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
 339              ( returnType.equals( XPathConstants.NODE ) ) ||
 340              ( returnType.equals( XPathConstants.NODESET ) )  ) {
 341 
 342             return true;







 343         }
 344         return false;
 345      }
 346 
 347      private Object getResultAsType( XObject resultObject, QName returnType )
 348         throws javax.xml.transform.TransformerException {
 349         // XPathConstants.STRING
 350         if ( returnType.equals( XPathConstants.STRING ) ) {
 351             return resultObject.str();
 352         }
 353         // XPathConstants.NUMBER
 354         if ( returnType.equals( XPathConstants.NUMBER ) ) {
 355             return new Double ( resultObject.num());
 356         }
 357         // XPathConstants.BOOLEAN
 358         if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
 359             return new Boolean( resultObject.bool());


 360         }
 361         // XPathConstants.NODESET ---ORdered, UNOrdered???
 362         if ( returnType.equals( XPathConstants.NODESET ) ) {
 363             return resultObject.nodelist();



 364         }
 365         // XPathConstants.NODE
 366         if ( returnType.equals( XPathConstants.NODE ) ) {
 367             NodeIterator ni = resultObject.nodeset();
 368             //Return the first node, or null
 369             return ni.nextNode();
 370         }
 371         // If isSupported check is already done then the execution path
 372         // shouldn't come here. Being defensive
 373         String fmsg = XSLMessages.createXPATHMessage(
 374                 XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
 375                 new Object[] { returnType.toString()});
 376         throw new IllegalArgumentException ( fmsg );
 377     }
 378 





 379  }
   1 /*
   2  * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.

   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *




  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */

  20 
  21 package com.sun.org.apache.xpath.internal.jaxp;
  22 









  23 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
  24 import com.sun.org.apache.xpath.internal.objects.XObject;

  25 import javax.xml.namespace.QName;
  26 import javax.xml.transform.TransformerException;
  27 import javax.xml.xpath.XPathConstants;
  28 import javax.xml.xpath.XPathEvaluationResult;
  29 import javax.xml.xpath.XPathExpression;
  30 import javax.xml.xpath.XPathExpressionException;
  31 import javax.xml.xpath.XPathFunctionResolver;
  32 import javax.xml.xpath.XPathVariableResolver;



  33 import org.w3c.dom.Document;
  34 import org.w3c.dom.Node;




  35 import org.xml.sax.InputSource;
  36 
  37 /**
  38  * The XPathExpression interface encapsulates a (compiled) XPath expression.
  39  *
  40  * @author  Ramesh Mandava
  41  */
  42 public class XPathExpressionImpl extends XPathImplUtil implements XPathExpression {
  43 



  44     private com.sun.org.apache.xpath.internal.XPath xpath;
  45 









  46     /** Protected constructor to prevent direct instantiation; use compile()
  47      * from the context.
  48      */
  49     protected XPathExpressionImpl() {
  50         this(null, null, null, null,
  51              false, true, new FeatureManager());
  52     };
  53 
  54     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
  55             JAXPPrefixResolver prefixResolver,
  56             XPathFunctionResolver functionResolver,
  57             XPathVariableResolver variableResolver) {
  58         this(xpath, prefixResolver, functionResolver, variableResolver,
  59              false, true, new FeatureManager());
  60     };
  61 
  62     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
  63             JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
  64             XPathVariableResolver variableResolver, boolean featureSecureProcessing,
  65             boolean useServiceMechanism, FeatureManager featureManager) {
  66         this.xpath = xpath;
  67         this.prefixResolver = prefixResolver;
  68         this.functionResolver = functionResolver;
  69         this.variableResolver = variableResolver;
  70         this.featureSecureProcessing = featureSecureProcessing;
  71         this.useServiceMechanism = useServiceMechanism;
  72         this.featureManager = featureManager;
  73     };
  74 
  75     public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath) {
  76         this.xpath = xpath;
  77     }
  78 
  79     public Object eval(Object item, QName returnType)
  80             throws javax.xml.transform.TransformerException {
  81         XObject resultObject = eval(item, xpath);
  82         return getResultAsType(resultObject, returnType);
  83     }
  84 
  85     @Override


























































  86     public Object evaluate(Object item, QName returnType)
  87         throws XPathExpressionException {
  88         isSupported(returnType);















  89         try {
  90             return eval(item, returnType);
  91         } catch (java.lang.NullPointerException npe) {
  92             // If VariableResolver returns null Or if we get
  93             // NullPointerException at this stage for some other reason
  94             // then we have to reurn XPathException
  95             throw new XPathExpressionException (npe);
  96         } catch (javax.xml.transform.TransformerException te) {
  97             Throwable nestedException = te.getException();
  98             if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
  99                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
 100             } else {
 101                 // For any other exceptions we need to throw
 102                 // XPathExpressionException (as per spec)
 103                 throw new XPathExpressionException(te);
 104             }
 105         }
 106 
 107     }
 108 
 109     @Override























 110     public String evaluate(Object item)
 111         throws XPathExpressionException {
 112         return (String)this.evaluate(item, XPathConstants.STRING);
 113     }
 114 
 115     @Override







































 116     public Object evaluate(InputSource source, QName returnType)
 117         throws XPathExpressionException {
 118         isSupported (returnType);













 119         try {
 120             Document document = getDocument(source);
 121             return eval(document, returnType);
 122         } catch (TransformerException e) {
 123             throw new XPathExpressionException(e);
 124         }





 125     }

 126 
 127     @Override




















 128     public String evaluate(InputSource source)
 129         throws XPathExpressionException {
 130         return (String)this.evaluate(source, XPathConstants.STRING);
 131     }
 132 
 133     @Override
 134     public <T>T evaluateExpression(Object item, Class<T> type)
 135         throws XPathExpressionException {
 136         isSupportedClassType(type);



 137 
 138         try {
 139             XObject resultObject = eval(item, xpath);
 140             if (type.isAssignableFrom(XPathEvaluationResult.class)) {
 141                 XPathEvaluationResult<?> x = getXPathResult(resultObject);
 142 
 143                 return (T)x;
 144             } else {
 145                 return XPathResultImpl.getValue(resultObject, type);
 146             }


 147 
 148         } catch (javax.xml.transform.TransformerException te) {
 149             throw new XPathExpressionException(te);



 150         }



 151     }
 152 
 153     @Override
 154     public XPathEvaluationResult<?> evaluateExpression(Object item)
 155         throws XPathExpressionException {
 156         return evaluateExpression(item, XPathEvaluationResult.class);
 157     }
 158 
 159     @Override
 160     public <T>T  evaluateExpression(InputSource source, Class<T> type)
 161             throws XPathExpressionException {
 162         Document document = getDocument(source);
 163         return evaluateExpression(document, type);
 164     }













 165 
 166     @Override
 167     public XPathEvaluationResult evaluateExpression(InputSource source)
 168         throws XPathExpressionException {
 169         return evaluateExpression(source, XPathEvaluationResult.class);
 170     }
 171  }