1 /* 2 * Copyright (c) 2003, 2017, 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.xpath.internal.*; 24 import com.sun.org.apache.xpath.internal.objects.XObject; 25 import javax.xml.namespace.NamespaceContext; 26 import javax.xml.namespace.QName; 27 import javax.xml.transform.TransformerException; 28 import javax.xml.xpath.XPathConstants; 29 import javax.xml.xpath.XPathEvaluationResult; 30 import javax.xml.xpath.XPathExpression; 31 import javax.xml.xpath.XPathExpressionException; 32 import javax.xml.xpath.XPathFunctionResolver; 33 import javax.xml.xpath.XPathVariableResolver; 34 import jdk.xml.internal.JdkXmlFeatures; 35 import org.w3c.dom.Document; 36 import org.xml.sax.InputSource; 37 38 /** 39 * The XPathImpl class provides implementation for the methods defined in 40 * javax.xml.xpath.XPath interface. This provides simple access to the results 41 * of an XPath expression. 42 * 43 * @author Ramesh Mandava 44 * 45 * Updated 12/04/2014: 46 * New methods: evaluateExpression 47 * Refactored to share code with XPathExpressionImpl. 48 */ 49 public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath { 50 51 // Private variables 52 private XPathVariableResolver origVariableResolver; 53 private XPathFunctionResolver origFunctionResolver; 54 private NamespaceContext namespaceContext=null; 55 XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr)56 XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) { 57 this(vr, fr, false, new JdkXmlFeatures(false)); 58 } 59 XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr, boolean featureSecureProcessing, JdkXmlFeatures featureManager)60 XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr, 61 boolean featureSecureProcessing, JdkXmlFeatures featureManager) { 62 this.origVariableResolver = this.variableResolver = vr; 63 this.origFunctionResolver = this.functionResolver = fr; 64 this.featureSecureProcessing = featureSecureProcessing; 65 this.featureManager = featureManager; 66 overrideDefaultParser = featureManager.getFeature( 67 JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER); 68 69 } 70 71 72 //-Override- setXPathVariableResolver(XPathVariableResolver resolver)73 public void setXPathVariableResolver(XPathVariableResolver resolver) { 74 requireNonNull(resolver, "XPathVariableResolver"); 75 this.variableResolver = resolver; 76 } 77 78 //-Override- getXPathVariableResolver()79 public XPathVariableResolver getXPathVariableResolver() { 80 return variableResolver; 81 } 82 83 //-Override- setXPathFunctionResolver(XPathFunctionResolver resolver)84 public void setXPathFunctionResolver(XPathFunctionResolver resolver) { 85 requireNonNull(resolver, "XPathFunctionResolver"); 86 this.functionResolver = resolver; 87 } 88 89 //-Override- getXPathFunctionResolver()90 public XPathFunctionResolver getXPathFunctionResolver() { 91 return functionResolver; 92 } 93 94 //-Override- setNamespaceContext(NamespaceContext nsContext)95 public void setNamespaceContext(NamespaceContext nsContext) { 96 requireNonNull(nsContext, "NamespaceContext"); 97 this.namespaceContext = nsContext; 98 this.prefixResolver = new JAXPPrefixResolver (nsContext); 99 } 100 101 //-Override- getNamespaceContext()102 public NamespaceContext getNamespaceContext() { 103 return namespaceContext; 104 } 105 106 /** 107 * Evaluate an {@code XPath} expression in the specified context. 108 * @param expression The XPath expression. 109 * @param contextItem The starting context. 110 * @return an XObject as the result of evaluating the expression 111 * @throws TransformerException if evaluating fails 112 */ eval(String expression, Object contextItem)113 private XObject eval(String expression, Object contextItem) 114 throws TransformerException { 115 requireNonNull(expression, "XPath expression"); 116 com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath(expression, 117 null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT); 118 119 return eval(contextItem, xpath); 120 } 121 122 //-Override- evaluate(String expression, Object item, QName returnType)123 public Object evaluate(String expression, Object item, QName returnType) 124 throws XPathExpressionException { 125 //this check is necessary before calling eval to maintain binary compatibility 126 requireNonNull(expression, "XPath expression"); 127 isSupported(returnType); 128 129 try { 130 131 XObject resultObject = eval(expression, item); 132 return getResultAsType(resultObject, returnType); 133 } catch (java.lang.NullPointerException npe) { 134 // If VariableResolver returns null Or if we get 135 // NullPointerException at this stage for some other reason 136 // then we have to reurn XPathException 137 throw new XPathExpressionException (npe); 138 } catch (TransformerException te) { 139 Throwable nestedException = te.getException(); 140 if (nestedException instanceof javax.xml.xpath.XPathFunctionException) { 141 throw (javax.xml.xpath.XPathFunctionException)nestedException; 142 } else { 143 // For any other exceptions we need to throw 144 // XPathExpressionException (as per spec) 145 throw new XPathExpressionException (te); 146 } 147 } 148 149 } 150 151 //-Override- evaluate(String expression, Object item)152 public String evaluate(String expression, Object item) 153 throws XPathExpressionException { 154 return (String)this.evaluate(expression, item, XPathConstants.STRING); 155 } 156 157 //-Override- compile(String expression)158 public XPathExpression compile(String expression) 159 throws XPathExpressionException { 160 requireNonNull(expression, "XPath expression"); 161 try { 162 com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null, 163 prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT); 164 // Can have errorListener 165 XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, 166 prefixResolver, functionResolver, variableResolver, 167 featureSecureProcessing, featureManager); 168 return ximpl; 169 } catch (TransformerException te) { 170 throw new XPathExpressionException (te) ; 171 } 172 } 173 174 //-Override- evaluate(String expression, InputSource source, QName returnType)175 public Object evaluate(String expression, InputSource source, 176 QName returnType) throws XPathExpressionException { 177 isSupported(returnType); 178 179 try { 180 Document document = getDocument(source); 181 XObject resultObject = eval(expression, document); 182 return getResultAsType(resultObject, returnType); 183 } catch (TransformerException te) { 184 Throwable nestedException = te.getException(); 185 if (nestedException instanceof javax.xml.xpath.XPathFunctionException) { 186 throw (javax.xml.xpath.XPathFunctionException)nestedException; 187 } else { 188 throw new XPathExpressionException (te); 189 } 190 } 191 } 192 193 //-Override- evaluate(String expression, InputSource source)194 public String evaluate(String expression, InputSource source) 195 throws XPathExpressionException { 196 return (String)this.evaluate(expression, source, XPathConstants.STRING); 197 } 198 199 //-Override- reset()200 public void reset() { 201 this.variableResolver = this.origVariableResolver; 202 this.functionResolver = this.origFunctionResolver; 203 this.namespaceContext = null; 204 } 205 206 //-Override- evaluateExpression(String expression, Object item, Class<T> type)207 public <T> T evaluateExpression(String expression, Object item, Class<T> type) 208 throws XPathExpressionException { 209 isSupportedClassType(type); 210 try { 211 XObject resultObject = eval(expression, item); 212 if (type.isAssignableFrom(XPathEvaluationResult.class)) { 213 return getXPathResult(resultObject, type); 214 } else { 215 return XPathResultImpl.getValue(resultObject, type); 216 } 217 } catch (TransformerException te) { 218 throw new XPathExpressionException (te); 219 } 220 } 221 222 //-Override- evaluateExpression(String expression, Object item)223 public XPathEvaluationResult<?> evaluateExpression(String expression, Object item) 224 throws XPathExpressionException { 225 return evaluateExpression(expression, item, XPathEvaluationResult.class); 226 } 227 228 //-Override- evaluateExpression(String expression, InputSource source, Class<T> type)229 public <T> T evaluateExpression(String expression, InputSource source, Class<T> type) 230 throws XPathExpressionException { 231 Document document = getDocument(source); 232 return evaluateExpression(expression, document, type); 233 } 234 235 //-Override- evaluateExpression(String expression, InputSource source)236 public XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source) 237 throws XPathExpressionException { 238 return evaluateExpression(expression, source, XPathEvaluationResult.class); 239 } 240 } 241