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 } |