19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// $Id: XPathImpl.java 524814 2007-04-02 15:52:11Z zongaro $ 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath.jaxp; 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.namespace.QName; 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.namespace.NamespaceContext; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.xpath.XPathExpressionException; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.xpath.XPathConstants; 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.xpath.XPathFunctionResolver; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.xpath.XPathVariableResolver; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.xpath.XPathExpression; 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM; 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.*; 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject; 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.res.XPATHErrorResources; 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages; 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node; 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.DOMImplementation; 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Document; 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.traversal.NodeIterator; 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.InputSource; 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXException; 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.parsers.*; 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException; 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The XPathImpl class provides implementation for the methods defined in 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * javax.xml.xpath.XPath interface. This provide simple access to the results 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of an XPath expression. 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @version $Revision: 524814 $ 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @author Ramesh Mandava 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class XPathImpl implements javax.xml.xpath.XPath { 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Private variables 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private XPathVariableResolver variableResolver; 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private XPathFunctionResolver functionResolver; 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private XPathVariableResolver origVariableResolver; 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private XPathFunctionResolver origFunctionResolver; 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private NamespaceContext namespaceContext=null; 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private JAXPPrefixResolver prefixResolver; 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // By default Extension Functions are allowed in XPath Expressions. If 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Secure Processing Feature is set on XPathFactory then the invocation of 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // extensions function need to throw XPathFunctionException 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private boolean featureSecureProcessing = false; 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) { 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.origVariableResolver = this.variableResolver = vr; 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.origFunctionResolver = this.functionResolver = fr; 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean featureSecureProcessing ) { 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.origVariableResolver = this.variableResolver = vr; 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.origFunctionResolver = this.functionResolver = fr; 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.featureSecureProcessing = featureSecureProcessing; 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Establishes a variable resolver.</p> 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param resolver Variable Resolver 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setXPathVariableResolver(XPathVariableResolver resolver) { 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( resolver == null ) { 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"XPathVariableResolver"} ); 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException( fmsg ); 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.variableResolver = resolver; 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Returns the current variable resolver.</p> 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Current variable resolver 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XPathVariableResolver getXPathVariableResolver() { 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return variableResolver; 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Establishes a function resolver.</p> 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param resolver XPath function resolver 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setXPathFunctionResolver(XPathFunctionResolver resolver) { 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( resolver == null ) { 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"XPathFunctionResolver"} ); 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException( fmsg ); 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.functionResolver = resolver; 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Returns the current function resolver.</p> 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Current function resolver 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XPathFunctionResolver getXPathFunctionResolver() { 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return functionResolver; 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Establishes a namespace context.</p> 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param nsContext Namespace context to use 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setNamespaceContext(NamespaceContext nsContext) { 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( nsContext == null ) { 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"NamespaceContext"} ); 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException( fmsg ); 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.namespaceContext = nsContext; 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.prefixResolver = new JAXPPrefixResolver ( nsContext ); 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Returns the current namespace context.</p> 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Current Namespace context 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public NamespaceContext getNamespaceContext() { 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return namespaceContext; 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static Document d = null; 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static DocumentBuilder getParser() { 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // we'd really like to cache those DocumentBuilders, but we can't because: 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1. thread safety. parsers are not thread-safe, so at least 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // we need one instance per a thread. 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 2. parsers are non-reentrant, so now we are looking at having a 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // pool of parsers. 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3. then the class loading issue. The look-up procedure of 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // DocumentBuilderFactory.newInstance() depends on context class loader 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // and system properties, which may change during the execution of JVM. 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // so we really have to create a fresh DocumentBuilder every time we need one 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // - KK 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dbf.setNamespaceAware( true ); 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson dbf.setValidating( false ); 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return dbf.newDocumentBuilder(); 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch (ParserConfigurationException e) { 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // this should never happen with a well-behaving JAXP implementation. 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new Error(e.toString()); 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static Document getDummyDocument( ) { 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // we don't need synchronization here; even if two threads 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // enter this code at the same time, we just waste a little time 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(d==null) { 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson DOMImplementation dim = getParser().getDOMImplementation(); 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson d = dim.createDocument("http://java.sun.com/jaxp/xpath", 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson "dummyroot", null); 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return d; 1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private XObject eval(String expression, Object contextItem) 1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws javax.xml.transform.TransformerException { 1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xpath.XPath xpath = new org.apache.xpath.XPath( expression, 1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson null, prefixResolver, org.apache.xpath.XPath.SELECT ); 1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xpath.XPathContext xpathSupport = null; 1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Create an XPathContext that doesn't support pushing and popping of 2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // variable resolution scopes. Sufficient for simple XPath 1.0 2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // expressions. 2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( functionResolver != null ) { 2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson JAXPExtensionsProvider jep = new JAXPExtensionsProvider( 2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson functionResolver, featureSecureProcessing ); 2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xpathSupport = new org.apache.xpath.XPathContext(jep, false); 2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xpathSupport = new org.apache.xpath.XPathContext(false); 2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject xobj = null; 2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xpathSupport.setVarStack(new JAXPVariableStack(variableResolver)); 2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If item is null, then we will create a a Dummy contextNode 2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( contextItem instanceof Node ) { 2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xobj = xpath.execute (xpathSupport, (Node)contextItem, 2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prefixResolver ); 2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver ); 2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return xobj; 2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p> 2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for context item evaluation, 2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * variable, function and <code>QName</code> resolution and return type conversion.</p> 2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} ( 2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathConstants#NUMBER NUMBER}, 2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathConstants#STRING STRING}, 2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathConstants#BOOLEAN BOOLEAN}, 2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathConstants#NODE NODE} or 2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathConstants#NODESET NODESET}) 2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * then an <code>IllegalArgumentException</code> is thrown.</p> 2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If a <code>null</code> value is provided for 2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>item</code>, an empty document will be used for the 2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * context. 2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a 2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>NullPointerException</code> is thrown.</p> 2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param expression The XPath expression. 2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param item The starting context (node or node list, for example). 2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param returnType The desired return type. 2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>. 2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws XPathExpressionException If <code>expression</code> cannot be evaluated. 2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. 2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>. 2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public Object evaluate(String expression, Object item, QName returnType) 2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws XPathExpressionException { 2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( expression == null ) { 2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"XPath expression"} ); 2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException ( fmsg ); 2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType == null ) { 2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"returnType"} ); 2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException ( fmsg ); 2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Checking if requested returnType is supported. returnType need to 2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // be defined in XPathConstants 2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( !isSupported ( returnType ) ) { 2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] { returnType.toString() } ); 2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new IllegalArgumentException ( fmsg ); 2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject resultObject = eval( expression, item ); 2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return getResultAsType( resultObject, returnType ); 2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch ( java.lang.NullPointerException npe ) { 2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If VariableResolver returns null Or if we get 2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // NullPointerException at this stage for some other reason 2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // then we have to reurn XPathException 2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new XPathExpressionException ( npe ); 2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch ( javax.xml.transform.TransformerException te ) { 2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Throwable nestedException = te.getException(); 2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { 2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw (javax.xml.xpath.XPathFunctionException)nestedException; 2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // For any other exceptions we need to throw 2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XPathExpressionException ( as per spec ) 2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new XPathExpressionException ( te ); 2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private boolean isSupported( QName returnType ) { 3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( ( returnType.equals( XPathConstants.STRING ) ) || 3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ( returnType.equals( XPathConstants.NUMBER ) ) || 3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ( returnType.equals( XPathConstants.BOOLEAN ) ) || 3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ( returnType.equals( XPathConstants.NODE ) ) || 3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ( returnType.equals( XPathConstants.NODESET ) ) ) { 3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return true; 3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return false; 3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private Object getResultAsType( XObject resultObject, QName returnType ) 3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws javax.xml.transform.TransformerException { 3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XPathConstants.STRING 3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType.equals( XPathConstants.STRING ) ) { 3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return resultObject.str(); 3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XPathConstants.NUMBER 3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType.equals( XPathConstants.NUMBER ) ) { 3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return new Double ( resultObject.num()); 3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XPathConstants.BOOLEAN 3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType.equals( XPathConstants.BOOLEAN ) ) { 3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return new Boolean( resultObject.bool()); 3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XPathConstants.NODESET ---ORdered, UNOrdered??? 3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType.equals( XPathConstants.NODESET ) ) { 3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return resultObject.nodelist(); 3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // XPathConstants.NODE 3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType.equals( XPathConstants.NODE ) ) { 3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson NodeIterator ni = resultObject.nodeset(); 3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //Return the first node, or null 3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return ni.nextNode(); 3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] { returnType.toString()}); 3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new IllegalArgumentException( fmsg ); 3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p> 3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of 3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathConstants#STRING}.</p> 3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec 3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for context item evaluation, 3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * variable, function and QName resolution and return type conversion.</p> 3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If a <code>null</code> value is provided for 3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>item</code>, an empty document will be used for the 3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * context. 3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p> 3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param expression The XPath expression. 3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param item The starting context (node or node list, for example). 3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The <code>String</code> that is the result of evaluating the expression and 3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * converting the result to a <code>String</code>. 3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws XPathExpressionException If <code>expression</code> cannot be evaluated. 3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws NullPointerException If <code>expression</code> is <code>null</code>. 3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String evaluate(String expression, Object item) 3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws XPathExpressionException { 3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (String)this.evaluate( expression, item, XPathConstants.STRING ); 3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Compile an XPath expression for later evaluation.</p> 3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If <code>expression</code> contains any {@link XPathFunction}s, 3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * they must be available via the {@link XPathFunctionResolver}. 3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code> 3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * cannot be resovled with the <code>XPathFunctionResolver</code>.</p> 3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p> 3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param expression The XPath expression. 3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Compiled XPath expression. 3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws XPathExpressionException If <code>expression</code> cannot be compiled. 3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws NullPointerException If <code>expression</code> is <code>null</code>. 3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XPathExpression compile(String expression) 3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws XPathExpressionException { 3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( expression == null ) { 3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"XPath expression"} ); 3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException ( fmsg ); 3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xpath.XPath xpath = new XPath (expression, null, 4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prefixResolver, org.apache.xpath.XPath.SELECT ); 4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Can have errorListener 4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, 4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prefixResolver, functionResolver, variableResolver, 4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson featureSecureProcessing ); 4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return ximpl; 4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch ( javax.xml.transform.TransformerException te ) { 4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new XPathExpressionException ( te ) ; 4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> 4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and return the result as the specified type.</p> 4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>This method builds a data model for the {@link InputSource} and calls 4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p> 4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for context item evaluation, 4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * variable, function and QName resolution and return type conversion.</p> 4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants}, 4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * then an <code>IllegalArgumentException</code> is thrown.</p> 4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>, 4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * then a <code>NullPointerException</code> is thrown.</p> 4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param expression The XPath expression. 4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param source The input source of the document to evaluate over. 4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param returnType The desired return type. 4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The <code>Object</code> that encapsulates the result of evaluating the expression. 4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws XPathExpressionException If expression cannot be evaluated. 4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. 4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code> 4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * is <code>null</code>. 4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public Object evaluate(String expression, InputSource source, 4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson QName returnType) throws XPathExpressionException { 4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Checking validity of different parameters 4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if( source== null ) { 4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"source"} ); 4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException ( fmsg ); 4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( expression == null ) { 4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"XPath expression"} ); 4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException ( fmsg ); 4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( returnType == null ) { 4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] {"returnType"} ); 4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new NullPointerException ( fmsg ); 4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //Checking if requested returnType is supported. 4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //returnType need to be defined in XPathConstants 4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( !isSupported ( returnType ) ) { 4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new Object[] { returnType.toString() } ); 4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new IllegalArgumentException ( fmsg ); 4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try { 4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Document document = getParser().parse( source ); 4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject resultObject = eval( expression, document ); 4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return getResultAsType( resultObject, returnType ); 4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch ( SAXException e ) { 4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new XPathExpressionException ( e ); 4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch( IOException e ) { 4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new XPathExpressionException ( e ); 4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } catch ( javax.xml.transform.TransformerException te ) { 4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Throwable nestedException = te.getException(); 4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { 4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw (javax.xml.xpath.XPathFunctionException)nestedException; 4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } else { 4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new XPathExpressionException ( te ); 4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> 4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and return the result as a <code>String</code>.</p> 4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a 5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>returnType</code> of {@link XPathConstants#STRING}.</p> 5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for context item evaluation, 5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * variable, function and QName resolution and return type conversion.</p> 5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>If <code>expression</code> or <code>source</code> is <code>null</code>, 5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * then a <code>NullPointerException</code> is thrown.</p> 5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param expression The XPath expression. 5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param source The <code>InputSource</code> of the document to evaluate over. 5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The <code>String</code> that is the result of evaluating the expression and 5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * converting the result to a <code>String</code>. 5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws XPathExpressionException If expression cannot be evaluated. 5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>. 5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public String evaluate(String expression, InputSource source) 5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws XPathExpressionException { 5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (String)this.evaluate( expression, source, XPathConstants.STRING ); 5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>Reset this <code>XPath</code> to its original configuration.</p> 5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p><code>XPath</code> is reset to the same state as when it was created with 5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathFactory#newXPath()}. 5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s 5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * thus saving resources associated with the creation of new <code>XPath</code>s.</p> 5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>The reset <code>XPath</code> is not guaranteed to have the same 5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link XPathFunctionResolver}, {@link XPathVariableResolver} 5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}. 5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>, 5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <code>XPathVariableResolver</code> 5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and <code>NamespaceContext</code>.</p> 5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void reset() { 5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.variableResolver = this.origVariableResolver; 5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.functionResolver = this.origFunctionResolver; 5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.namespaceContext = null; 5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} 546