14c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/* 24c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 34c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or more contributor license agreements. See the NOTICE file 44c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed with this work for additional information 54c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * regarding copyright ownership. The ASF licenses this file 64c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 74c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * you may not use this file except in compliance with the License. 84c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * You may obtain a copy of the License at 94c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * Unless required by applicable law or agreed to in writing, software 134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * See the License for the specific language governing permissions and 164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * limitations under the License. 174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson// $Id: XPathImpl.java 524814 2007-04-02 15:52:11Z zongaro $ 194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpackage org.apache.xpath.jaxp; 214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.namespace.QName; 234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.namespace.NamespaceContext; 244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.xpath.XPathExpressionException; 254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.xpath.XPathConstants; 264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.xpath.XPathFunctionResolver; 274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.xpath.XPathVariableResolver; 284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.xpath.XPathExpression; 294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xml.dtm.DTM; 314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.*; 324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.objects.XObject; 334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xpath.res.XPATHErrorResources; 344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.apache.xalan.res.XSLMessages; 354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.Node; 374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.DOMImplementation; 384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.Document; 394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.w3c.dom.traversal.NodeIterator; 404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.InputSource; 424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport org.xml.sax.SAXException; 434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport javax.xml.parsers.*; 454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonimport java.io.IOException; 474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson/** 494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * The XPathImpl class provides implementation for the methods defined in 504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * javax.xml.xpath.XPath interface. This provide simple access to the results 514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * of an XPath expression. 524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @version $Revision: 524814 $ 554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @author Ramesh Mandava 564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilsonpublic class XPathImpl implements javax.xml.xpath.XPath { 584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Private variables 604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private XPathVariableResolver variableResolver; 614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private XPathFunctionResolver functionResolver; 624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private XPathVariableResolver origVariableResolver; 634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private XPathFunctionResolver origFunctionResolver; 644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private NamespaceContext namespaceContext=null; 654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private JAXPPrefixResolver prefixResolver; 664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // By default Extension Functions are allowed in XPath Expressions. If 674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Secure Processing Feature is set on XPathFactory then the invocation of 684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // extensions function need to throw XPathFunctionException 694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean featureSecureProcessing = false; 704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) { 724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.origVariableResolver = this.variableResolver = vr; 734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.origFunctionResolver = this.functionResolver = fr; 744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, 774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson boolean featureSecureProcessing ) { 784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.origVariableResolver = this.variableResolver = vr; 794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.origFunctionResolver = this.functionResolver = fr; 804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.featureSecureProcessing = featureSecureProcessing; 814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Establishes a variable resolver.</p> 854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param resolver Variable Resolver 874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setXPathVariableResolver(XPathVariableResolver resolver) { 894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( resolver == null ) { 904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"XPathVariableResolver"} ); 934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException( fmsg ); 944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.variableResolver = resolver; 964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Returns the current variable resolver.</p> 1004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Current variable resolver 1024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public XPathVariableResolver getXPathVariableResolver() { 1044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return variableResolver; 1054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Establishes a function resolver.</p> 1094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param resolver XPath function resolver 1114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setXPathFunctionResolver(XPathFunctionResolver resolver) { 1134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( resolver == null ) { 1144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 1154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 1164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"XPathFunctionResolver"} ); 1174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException( fmsg ); 1184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.functionResolver = resolver; 1204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Returns the current function resolver.</p> 1244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Current function resolver 1264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public XPathFunctionResolver getXPathFunctionResolver() { 1284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return functionResolver; 1294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Establishes a namespace context.</p> 1334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param nsContext Namespace context to use 1354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void setNamespaceContext(NamespaceContext nsContext) { 1374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( nsContext == null ) { 1384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 1394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 1404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"NamespaceContext"} ); 1414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException( fmsg ); 1424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.namespaceContext = nsContext; 1444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.prefixResolver = new JAXPPrefixResolver ( nsContext ); 1454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 1484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Returns the current namespace context.</p> 1494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 1504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Current Namespace context 1514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 1524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public NamespaceContext getNamespaceContext() { 1534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return namespaceContext; 1544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private static Document d = null; 1574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private static DocumentBuilder getParser() { 1594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try { 1604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // we'd really like to cache those DocumentBuilders, but we can't because: 1614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // 1. thread safety. parsers are not thread-safe, so at least 1624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // we need one instance per a thread. 1634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // 2. parsers are non-reentrant, so now we are looking at having a 1644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // pool of parsers. 1654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // 3. then the class loading issue. The look-up procedure of 1664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // DocumentBuilderFactory.newInstance() depends on context class loader 1674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // and system properties, which may change during the execution of JVM. 1684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // 1694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // so we really have to create a fresh DocumentBuilder every time we need one 1704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // - KK 1714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 1724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson dbf.setNamespaceAware( true ); 1734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson dbf.setValidating( false ); 1744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return dbf.newDocumentBuilder(); 1754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch (ParserConfigurationException e) { 1764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // this should never happen with a well-behaving JAXP implementation. 1774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new Error(e.toString()); 1784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private static Document getDummyDocument( ) { 1824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // we don't need synchronization here; even if two threads 1834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // enter this code at the same time, we just waste a little time 1844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if(d==null) { 1854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson DOMImplementation dim = getParser().getDOMImplementation(); 1864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson d = dim.createDocument("http://java.sun.com/jaxp/xpath", 1874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson "dummyroot", null); 1884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return d; 1904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 1914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private XObject eval(String expression, Object contextItem) 1944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException { 1954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson org.apache.xpath.XPath xpath = new org.apache.xpath.XPath( expression, 1964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson null, prefixResolver, org.apache.xpath.XPath.SELECT ); 1974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson org.apache.xpath.XPathContext xpathSupport = null; 1984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 1994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Create an XPathContext that doesn't support pushing and popping of 2004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // variable resolution scopes. Sufficient for simple XPath 1.0 2014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // expressions. 2024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( functionResolver != null ) { 2034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson JAXPExtensionsProvider jep = new JAXPExtensionsProvider( 2044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson functionResolver, featureSecureProcessing ); 2054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xpathSupport = new org.apache.xpath.XPathContext(jep, false); 2064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } else { 2074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xpathSupport = new org.apache.xpath.XPathContext(false); 2084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject xobj = null; 2114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xpathSupport.setVarStack(new JAXPVariableStack(variableResolver)); 2134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // If item is null, then we will create a a Dummy contextNode 2154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( contextItem instanceof Node ) { 2164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xobj = xpath.execute (xpathSupport, (Node)contextItem, 2174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson prefixResolver ); 2184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } else { 2194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver ); 2204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return xobj; 2234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 2264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p> 2274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 2294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * for context item evaluation, 2304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * variable, function and <code>QName</code> resolution and return type conversion.</p> 2314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} ( 2334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathConstants#NUMBER NUMBER}, 2344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathConstants#STRING STRING}, 2354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathConstants#BOOLEAN BOOLEAN}, 2364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathConstants#NODE NODE} or 2374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathConstants#NODESET NODESET}) 2384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * then an <code>IllegalArgumentException</code> is thrown.</p> 2394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If a <code>null</code> value is provided for 2414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>item</code>, an empty document will be used for the 2424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * context. 2434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a 2444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>NullPointerException</code> is thrown.</p> 2454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param expression The XPath expression. 2474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param item The starting context (node or node list, for example). 2484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param returnType The desired return type. 2494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>. 2514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 2524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws XPathExpressionException If <code>expression</code> cannot be evaluated. 2534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. 2544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>. 2554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 2564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Object evaluate(String expression, Object item, QName returnType) 2574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws XPathExpressionException { 2584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( expression == null ) { 2594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 2604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 2614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"XPath expression"} ); 2624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException ( fmsg ); 2634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType == null ) { 2654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 2664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 2674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"returnType"} ); 2684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException ( fmsg ); 2694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Checking if requested returnType is supported. returnType need to 2714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // be defined in XPathConstants 2724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( !isSupported ( returnType ) ) { 2734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 2744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 2754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] { returnType.toString() } ); 2764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new IllegalArgumentException ( fmsg ); 2774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try { 2804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject resultObject = eval( expression, item ); 2824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return getResultAsType( resultObject, returnType ); 2834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch ( java.lang.NullPointerException npe ) { 2844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // If VariableResolver returns null Or if we get 2854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // NullPointerException at this stage for some other reason 2864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // then we have to reurn XPathException 2874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new XPathExpressionException ( npe ); 2884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch ( javax.xml.transform.TransformerException te ) { 2894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Throwable nestedException = te.getException(); 2904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { 2914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw (javax.xml.xpath.XPathFunctionException)nestedException; 2924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } else { 2934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // For any other exceptions we need to throw 2944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathExpressionException ( as per spec ) 2954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new XPathExpressionException ( te ); 2964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 2984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 2994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private boolean isSupported( QName returnType ) { 3024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( ( returnType.equals( XPathConstants.STRING ) ) || 3034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ( returnType.equals( XPathConstants.NUMBER ) ) || 3044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ( returnType.equals( XPathConstants.BOOLEAN ) ) || 3054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ( returnType.equals( XPathConstants.NODE ) ) || 3064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson ( returnType.equals( XPathConstants.NODESET ) ) ) { 3074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return true; 3094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return false; 3114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson private Object getResultAsType( XObject resultObject, QName returnType ) 3144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws javax.xml.transform.TransformerException { 3154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathConstants.STRING 3164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType.equals( XPathConstants.STRING ) ) { 3174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return resultObject.str(); 3184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathConstants.NUMBER 3204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType.equals( XPathConstants.NUMBER ) ) { 3214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return new Double ( resultObject.num()); 3224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathConstants.BOOLEAN 3244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType.equals( XPathConstants.BOOLEAN ) ) { 3254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return new Boolean( resultObject.bool()); 3264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathConstants.NODESET ---ORdered, UNOrdered??? 3284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType.equals( XPathConstants.NODESET ) ) { 3294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return resultObject.nodelist(); 3304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // XPathConstants.NODE 3324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType.equals( XPathConstants.NODE ) ) { 3334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson NodeIterator ni = resultObject.nodeset(); 3344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson //Return the first node, or null 3354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return ni.nextNode(); 3364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 3384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 3394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] { returnType.toString()}); 3404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new IllegalArgumentException( fmsg ); 3414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p> 3474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of 3494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathConstants#STRING}.</p> 3504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec 3524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * for context item evaluation, 3534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * variable, function and QName resolution and return type conversion.</p> 3544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If a <code>null</code> value is provided for 3564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>item</code>, an empty document will be used for the 3574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * context. 3584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p> 3594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param expression The XPath expression. 3614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param item The starting context (node or node list, for example). 3624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The <code>String</code> that is the result of evaluating the expression and 3644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * converting the result to a <code>String</code>. 3654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws XPathExpressionException If <code>expression</code> cannot be evaluated. 3674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws NullPointerException If <code>expression</code> is <code>null</code>. 3684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public String evaluate(String expression, Object item) 3704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws XPathExpressionException { 3714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return (String)this.evaluate( expression, item, XPathConstants.STRING ); 3724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 3754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Compile an XPath expression for later evaluation.</p> 3764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If <code>expression</code> contains any {@link XPathFunction}s, 3784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * they must be available via the {@link XPathFunctionResolver}. 3794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code> 3804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * cannot be resovled with the <code>XPathFunctionResolver</code>.</p> 3814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p> 3834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param expression The XPath expression. 3854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 3864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return Compiled XPath expression. 3874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 3884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws XPathExpressionException If <code>expression</code> cannot be compiled. 3894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws NullPointerException If <code>expression</code> is <code>null</code>. 3904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 3914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public XPathExpression compile(String expression) 3924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws XPathExpressionException { 3934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( expression == null ) { 3944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 3954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 3964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"XPath expression"} ); 3974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException ( fmsg ); 3984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 3994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try { 4004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson org.apache.xpath.XPath xpath = new XPath (expression, null, 4014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson prefixResolver, org.apache.xpath.XPath.SELECT ); 4024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Can have errorListener 4034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, 4044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson prefixResolver, functionResolver, variableResolver, 4054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson featureSecureProcessing ); 4064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return ximpl; 4074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch ( javax.xml.transform.TransformerException te ) { 4084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new XPathExpressionException ( te ) ; 4094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 4144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> 4154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * and return the result as the specified type.</p> 4164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>This method builds a data model for the {@link InputSource} and calls 4184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p> 4194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 4214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * for context item evaluation, 4224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * variable, function and QName resolution and return type conversion.</p> 4234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants}, 4254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * then an <code>IllegalArgumentException</code> is thrown.</p> 4264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>, 4284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * then a <code>NullPointerException</code> is thrown.</p> 4294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param expression The XPath expression. 4314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param source The input source of the document to evaluate over. 4324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param returnType The desired return type. 4334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The <code>Object</code> that encapsulates the result of evaluating the expression. 4354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 4364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws XPathExpressionException If expression cannot be evaluated. 4374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}. 4384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code> 4394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * is <code>null</code>. 4404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 4414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public Object evaluate(String expression, InputSource source, 4424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson QName returnType) throws XPathExpressionException { 4434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson // Checking validity of different parameters 4444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if( source== null ) { 4454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4464c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 4474c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"source"} ); 4484c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException ( fmsg ); 4494c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4504c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( expression == null ) { 4514c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4524c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 4534c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"XPath expression"} ); 4544c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException ( fmsg ); 4554c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4564c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( returnType == null ) { 4574c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4584c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_ARG_CANNOT_BE_NULL, 4594c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] {"returnType"} ); 4604c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new NullPointerException ( fmsg ); 4614c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4624c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4634c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson //Checking if requested returnType is supported. 4644c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson //returnType need to be defined in XPathConstants 4654c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( !isSupported ( returnType ) ) { 4664c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson String fmsg = XSLMessages.createXPATHMessage( 4674c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE, 4684c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson new Object[] { returnType.toString() } ); 4694c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new IllegalArgumentException ( fmsg ); 4704c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4714c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4724c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson try { 4734c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4744c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Document document = getParser().parse( source ); 4754c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4764c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson XObject resultObject = eval( expression, document ); 4774c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return getResultAsType( resultObject, returnType ); 4784c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch ( SAXException e ) { 4794c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new XPathExpressionException ( e ); 4804c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch( IOException e ) { 4814c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new XPathExpressionException ( e ); 4824c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } catch ( javax.xml.transform.TransformerException te ) { 4834c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson Throwable nestedException = te.getException(); 4844c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) { 4854c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw (javax.xml.xpath.XPathFunctionException)nestedException; 4864c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } else { 4874c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throw new XPathExpressionException ( te ); 4884c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4894c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4904c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4914c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 4924c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4934c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4944c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4954c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 4964c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 4974c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code> 4984c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * and return the result as a <code>String</code>.</p> 4994c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5004c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a 5014c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>returnType</code> of {@link XPathConstants#STRING}.</p> 5024c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5034c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec 5044c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * for context item evaluation, 5054c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * variable, function and QName resolution and return type conversion.</p> 5064c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5074c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>If <code>expression</code> or <code>source</code> is <code>null</code>, 5084c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * then a <code>NullPointerException</code> is thrown.</p> 5094c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5104c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param expression The XPath expression. 5114c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @param source The <code>InputSource</code> of the document to evaluate over. 5124c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5134c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @return The <code>String</code> that is the result of evaluating the expression and 5144c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * converting the result to a <code>String</code>. 5154c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5164c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws XPathExpressionException If expression cannot be evaluated. 5174c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>. 5184c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5194c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public String evaluate(String expression, InputSource source) 5204c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson throws XPathExpressionException { 5214c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson return (String)this.evaluate( expression, source, XPathConstants.STRING ); 5224c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5234c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5244c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson /** 5254c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>Reset this <code>XPath</code> to its original configuration.</p> 5264c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5274c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p><code>XPath</code> is reset to the same state as when it was created with 5284c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathFactory#newXPath()}. 5294c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s 5304c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * thus saving resources associated with the creation of new <code>XPath</code>s.</p> 5314c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * 5324c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <p>The reset <code>XPath</code> is not guaranteed to have the same 5334c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * {@link XPathFunctionResolver}, {@link XPathVariableResolver} 5344c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}. 5354c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>, 5364c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * <code>XPathVariableResolver</code> 5374c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson * and <code>NamespaceContext</code>.</p> 5384c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson */ 5394c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson public void reset() { 5404c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.variableResolver = this.origVariableResolver; 5414c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.functionResolver = this.origFunctionResolver; 5424c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson this.namespaceContext = null; 5434c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson } 5444c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson 5454c7a0d97cf2b27790e6236965a1d798d710d7ec7Jesse Wilson} 546