org.junit.jupiter
@@ -172,7 +180,7 @@
-
+
maven-compiler-plugin
@@ -183,13 +191,6 @@
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M6
-
-
org.apache.felix
@@ -223,17 +224,15 @@
org.glassfish.jstl.integration
- !org.apache.xpath,
- !org.apache.xpath.objects,
- !org.apache.xpath.jaxp,
+ !org.apache.bcel,
+ !org.apache.regexp,
!org.apache.xml,
!org.apache.xml.dtm,
!org.apache.xml.utils,
- !org.apache.xalan,
- !org.apache.xalan.res,
+ !org.apache.xpath,
+ !org.apache.xpath.jaxp,
+ !org.apache.xpath.objects,
!org.apache.xpath.res,
- !org.apache.regexp,
- !org.apache.bcel,
!java_cup.runtime,
!trax,
org.xml.sax.ext,
@@ -251,7 +250,7 @@
-
+
org.apache.maven.plugins
@@ -272,7 +271,7 @@
-
+
org.apache.maven.plugins
@@ -333,12 +332,9 @@
-
-
+
- org.apache.maven.plugins
maven-source-plugin
- 3.2.1
true
@@ -346,15 +342,12 @@
attach-sources
- jar-no-fork
+ jar-no-fork
-
-
+
org.codehaus.mojo
build-helper-maven-plugin
@@ -375,7 +368,6 @@
- org.apache.maven.plugins
maven-javadoc-plugin
3.3.1
@@ -414,76 +406,74 @@ Copyright © 2019, ${current.year} Eclipse Foundation. All rights reserved.
-
-
-
-
- tlddocs
-
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 3.0.0
-
-
- generateTldDoc
- prepare-package
-
- java
-
-
- true
- false
- com.sun.tlddoc.TLDDoc
-
- -doctitle
- Jakarta Tags doc
- -windowtitle
- Jakarta Tags Doc
- -d
- ${project.build.directory}/tlddoc
- ${project.basedir}/src/main/resources/META-INF/sql.tld
- ${project.basedir}/src/main/resources/META-INF/x.tld
- ${project.basedir}/src/main/resources/META-INF/fmt.tld
- ${project.basedir}/src/main/resources/META-INF/c.tld
- ${project.basedir}/src/main/resources/META-INF/fn.tld
-
-
-
-
-
-
- org.glassfish.web
- tagsdoc
- 1.0-SNAPSHOT
-
-
-
-
-
-
-
+
+
+
+ tlddocs
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.0.0
+
+
+ generateTldDoc
+ prepare-package
+
+ java
+
+
+ true
+ false
+ com.sun.tlddoc.TLDDoc
+
+ -doctitle
+ Jakarta Tags doc
+ -windowtitle
+ Jakarta Tags Doc
+ -d
+ ${project.build.directory}/tlddoc
+ ${project.basedir}/src/main/resources/META-INF/sql.tld
+ ${project.basedir}/src/main/resources/META-INF/x.tld
+ ${project.basedir}/src/main/resources/META-INF/fmt.tld
+ ${project.basedir}/src/main/resources/META-INF/c.tld
+ ${project.basedir}/src/main/resources/META-INF/fn.tld
+
+
+
+
+
+
+ org.glassfish.web
+ tagsdoc
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/DocumentBuilderProvider.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/DocumentBuilderProvider.java
new file mode 100644
index 0000000..f7ae781
--- /dev/null
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/DocumentBuilderProvider.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022 Eclipse Foundation and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.apache.taglibs.standard.tag.common.xml;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+/**
+ * Provides preconfigured {@link DocumentBuilder} instances.
+ *
+ * @author David Matejcek
+ */
+public class DocumentBuilderProvider {
+
+ private static final DocumentBuilderFactory DBF;
+ private static final DocumentBuilderFactory DBF_SECURE;
+ static {
+ DBF = DocumentBuilderFactory.newInstance();
+ DBF.setNamespaceAware(true);
+ DBF.setValidating(false);
+
+ DBF_SECURE = DocumentBuilderFactory.newInstance();
+ DBF_SECURE.setNamespaceAware(true);
+ DBF_SECURE.setValidating(false);
+ try {
+ DBF_SECURE.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch (ParserConfigurationException e) {
+ throw new Error("Parser does not support secure processing");
+ }
+ }
+
+ /**
+ * Creates a namespace-aware {@link DocumentBuilder} with disabled validation.
+ *
+ * Note that {@link DocumentBuilder} instances are not thread-safe and their implementation can
+ * be chosen as described in {@link DocumentBuilderFactory} documentation.
+ *
+ * @return new {@link DocumentBuilder} instance.
+ */
+ public static DocumentBuilder createDocumentBuilder() {
+ try {
+ return DBF.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new Error("Could not initialize the DocumentBuilder!", e);
+ }
+ }
+
+
+ /**
+ * Creates a namespace-aware {@link DocumentBuilder} with disabled validation and enabled
+ * {@link XMLConstants#FEATURE_SECURE_PROCESSING}.
+ *
+ * Note that {@link DocumentBuilder} instances are not thread-safe and their implementation can
+ * be chosen as described in {@link DocumentBuilderFactory} documentation.
+ *
+ * @return new {@link DocumentBuilder} instance.
+ */
+ public static DocumentBuilder createSecureDocumentBuilder() {
+ try {
+ return DBF_SECURE.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new Error("Could not initialize the DocumentBuilder!", e);
+ }
+ }
+}
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLNodeList.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLNodeList.java
new file mode 100644
index 0000000..f6312ed
--- /dev/null
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLNodeList.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022 Eclipse Foundation and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.apache.taglibs.standard.tag.common.xml;
+
+import java.util.Vector;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+class JSTLNodeList extends Vector implements NodeList {
+
+ private static final long serialVersionUID = -1217630367839271134L;
+
+ Vector nodeVector;
+
+ JSTLNodeList(Vector nodeVector) {
+ this.nodeVector = nodeVector;
+ }
+
+
+ JSTLNodeList(NodeList nl) {
+ nodeVector = new Vector<>();
+ // p("[JSTLNodeList] nodelist details");
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node currNode = nl.item(i);
+ // XPathUtil.printDetails ( currNode );
+ nodeVector.add(i, currNode);
+ }
+ }
+
+
+ JSTLNodeList(Node n) {
+ nodeVector = new Vector<>();
+ nodeVector.addElement(n);
+ }
+
+
+ JSTLNodeList(Object o) {
+ nodeVector = new Vector<>();
+
+ if (o instanceof NodeList) {
+ NodeList nl = (NodeList) o;
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node currNode = nl.item(i);
+ // XPathUtil.printDetails ( currNode );
+ nodeVector.add(i, currNode);
+ }
+ } else {
+ nodeVector.addElement(o);
+ }
+ }
+
+
+ @Override
+ public Node item(int index) {
+ return (Node) nodeVector.elementAt(index);
+ }
+
+
+ @Override
+ public Object elementAt(int index) {
+ return nodeVector.elementAt(index);
+ }
+
+
+ @Override
+ public Object get(int index) {
+ return nodeVector.get(index);
+ }
+
+
+ @Override
+ public int getLength() {
+ return nodeVector.size();
+ }
+
+
+ @Override
+ public int size() {
+ return nodeVector.size();
+ }
+
+ // Can implement other Vector methods to redirect those methods to
+ // the vector in the variable param. As we are not using them as part
+ // of this implementation we are not doing that here. If this changes
+ // then we need to override those methods accordingly
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathFactory.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathFactory.java
index 8b41af9..0db4ba5 100644
--- a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathFactory.java
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathFactory.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
@@ -17,18 +18,21 @@
package org.apache.taglibs.standard.tag.common.xml;
+import javax.xml.xpath.XPath;
+
import org.apache.xpath.jaxp.XPathFactoryImpl;
/**
* This factory class is added to provide access to our own implementation
* of XPath, so that we can support a generic Object type in return type
- * arguement for XPath's evaluate instance method.
- *
+ * arguement for XPath's evaluate instance method.
+ *
* @author dhirup
*/
public class JSTLXPathFactory extends XPathFactoryImpl {
-
- public javax.xml.xpath.XPath newXPath() {
- return new org.apache.taglibs.standard.tag.common.xml.JSTLXPathImpl(null, null);
- }
+
+ @Override
+ public XPath newXPath() {
+ return new JSTLXPathImpl(null, null);
+ }
}
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathImpl.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathImpl.java
index 2a00917..624ea1f 100644
--- a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathImpl.java
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/JSTLXPathImpl.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
@@ -17,541 +18,298 @@
package org.apache.taglibs.standard.tag.common.xml;
+import java.io.IOException;
-import javax.xml.namespace.QName;
import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPathExpressionException;
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFunctionException;
import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathVariableResolver;
-import javax.xml.xpath.XPathExpression;
import org.apache.xml.dtm.DTM;
-import org.apache.xpath.*;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.jaxp.JAXPExtensionsProvider;
+import org.apache.xpath.jaxp.JAXPPrefixResolver;
+import org.apache.xpath.jaxp.JAXPVariableStack;
+import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xalan.res.XSLMessages;
-
-import org.w3c.dom.Node;
-import org.w3c.dom.DOMImplementation;
+import org.apache.xpath.res.XPATHMessages;
import org.w3c.dom.Document;
+import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeIterator;
-
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import javax.xml.parsers.*;
-
-import java.io.IOException;
-
/**
* The JSTLXPathImpl class provides implementation for the methods defined in
* javax.xml.xpath.XPath interface. This provide simple access to the results
- * of an XPath expression.
- *
- * This class provides our own implementation of XPath, so that we can support
- * a generic Object type in returnType arguement for XPath's evaluate instance
+ * of an XPath expression.
+ *
+ * This class provides our own implementation of XPath, so that we can support
+ * a generic Object type in returnType arguement for XPath's evaluate instance
* method.
*
- * Most of the implementation is exactly similar to what is already provided in
+ * Most of the implementation is exactly similar to what is already provided in
* com.sun.org.apache.xpath.internal.jaxp.XPathImpl.java
*/
-public class JSTLXPathImpl implements javax.xml.xpath.XPath {
+class JSTLXPathImpl implements javax.xml.xpath.XPath {
+
+ private final XPathVariableResolver origVariableResolver;
+ private final XPathFunctionResolver origFunctionResolver;
- // Private variables
private XPathVariableResolver variableResolver;
private XPathFunctionResolver functionResolver;
- private XPathVariableResolver origVariableResolver;
- private XPathFunctionResolver origFunctionResolver;
- private NamespaceContext namespaceContext=null;
- private org.apache.xpath.jaxp.JAXPPrefixResolver prefixResolver;
- // By default Extension Functions are allowed in XPath Expressions. If
+ private NamespaceContext namespaceContext;
+ private JAXPPrefixResolver prefixResolver;
+
+ // By default Extension Functions are allowed in XPath Expressions. If
// Secure Processing Feature is set on XPathFactory then the invocation of
// extensions function need to throw XPathFunctionException
- private boolean featureSecureProcessing = false;
+ private boolean featureSecureProcessing;
- JSTLXPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) {
+ JSTLXPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
this.origVariableResolver = this.variableResolver = vr;
this.origFunctionResolver = this.functionResolver = fr;
}
- JSTLXPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr,
- boolean featureSecureProcessing ) {
+
+ JSTLXPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr, boolean featureSecureProcessing) {
this.origVariableResolver = this.variableResolver = vr;
this.origFunctionResolver = this.functionResolver = fr;
this.featureSecureProcessing = featureSecureProcessing;
}
- /**
- * Establishes a variable resolver.
- *
- * @param resolver Variable Resolver
- */
+
+ @Override
+ public void reset() {
+ this.variableResolver = this.origVariableResolver;
+ this.functionResolver = this.origFunctionResolver;
+ this.namespaceContext = null;
+ }
+
+
+ @Override
public void setXPathVariableResolver(XPathVariableResolver resolver) {
- if ( resolver == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"XPathVariableResolver"} );
- throw new NullPointerException( fmsg );
+ if (resolver == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"XPathVariableResolver"});
+ throw new NullPointerException(fmsg);
}
this.variableResolver = resolver;
}
- /**
- * Returns the current variable resolver.
- *
- * @return Current variable resolver
- */
+
+ @Override
public XPathVariableResolver getXPathVariableResolver() {
return variableResolver;
}
- /**
- * Establishes a function resolver.
- *
- * @param resolver XPath function resolver
- */
+
+ @Override
public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
- if ( resolver == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"XPathFunctionResolver"} );
- throw new NullPointerException( fmsg );
+ if (resolver == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"XPathFunctionResolver"});
+ throw new NullPointerException(fmsg);
}
this.functionResolver = resolver;
}
- /**
- * Returns the current function resolver.
- *
- * @return Current function resolver
- */
+
+ @Override
public XPathFunctionResolver getXPathFunctionResolver() {
return functionResolver;
}
- /**
- * Establishes a namespace context.
- *
- * @param nsContext Namespace context to use
- */
+
+ @Override
public void setNamespaceContext(NamespaceContext nsContext) {
- if ( nsContext == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"NamespaceContext"} );
- throw new NullPointerException( fmsg );
+ if (nsContext == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"NamespaceContext"});
+ throw new NullPointerException(fmsg);
}
this.namespaceContext = nsContext;
- this.prefixResolver = new org.apache.xpath.jaxp.JAXPPrefixResolver ( nsContext );
+ this.prefixResolver = new JAXPPrefixResolver(nsContext);
}
- /**
- * Returns the current namespace context.
- *
- * @return Current Namespace context
- */
+
+ @Override
public NamespaceContext getNamespaceContext() {
return namespaceContext;
}
- private static Document d = null;
-
- private static DocumentBuilder getParser() {
- try {
- // we'd really like to cache those DocumentBuilders, but we can't because:
- // 1. thread safety. parsers are not thread-safe, so at least
- // we need one instance per a thread.
- // 2. parsers are non-reentrant, so now we are looking at having a
- // pool of parsers.
- // 3. then the class loading issue. The look-up procedure of
- // DocumentBuilderFactory.newInstance() depends on context class loader
- // and system properties, which may change during the execution of JVM.
- //
- // so we really have to create a fresh DocumentBuilder every time we need one
- // - KK
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware( true );
- dbf.setValidating( false );
- return dbf.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- // this should never happen with a well-behaving JAXP implementation.
- throw new Error(e);
- }
- }
- private static Document getDummyDocument( ) {
- // we don't need synchronization here; even if two threads
- // enter this code at the same time, we just waste a little time
- if(d==null) {
- DOMImplementation dim = getParser().getDOMImplementation();
- d = dim.createDocument("http://java.sun.com/jaxp/xpath",
- "dummyroot", null);
+ @Override
+ public XPathExpression compile(String expression)
+ throws XPathExpressionException {
+ // This is never used in JSTL
+ if (expression == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"XPath expression"});
+ throw new NullPointerException(fmsg);
}
- return d;
+ return null;
}
-
- private XObject eval(String expression, Object contextItem)
- throws javax.xml.transform.TransformerException {
- org.apache.xpath.XPath xpath = new org.apache.xpath.XPath( expression,
- null, prefixResolver, org.apache.xpath.XPath.SELECT );
- org.apache.xpath.XPathContext xpathSupport = null;
- if ( functionResolver != null ) {
- org.apache.xpath.jaxp.JAXPExtensionsProvider jep =
- new org.apache.xpath.jaxp.JAXPExtensionsProvider(
- functionResolver, featureSecureProcessing );
- xpathSupport = new org.apache.xpath.XPathContext( jep );
- } else {
- xpathSupport = new org.apache.xpath.XPathContext();
- }
- XObject xobj = null;
-
- xpathSupport.setVarStack(new org.apache.xpath.jaxp.JAXPVariableStack(variableResolver));
-
- // If item is null, then we will create a a Dummy contextNode
- if ( contextItem instanceof Node ) {
- xobj = xpath.execute (xpathSupport, (Node)contextItem,
- prefixResolver );
- } else {
- xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
- }
-
- return xobj;
- }
-
- /**
- * Evaluate an XPath
expression in the specified context and return the result as the specified type.
- *
- * See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
- * for context item evaluation,
- * variable, function and QName
resolution and return type conversion.
- *
- * If returnType
is not one of the types defined in {@link XPathConstants} (
- * {@link XPathConstants#NUMBER NUMBER},
- * {@link XPathConstants#STRING STRING},
- * {@link XPathConstants#BOOLEAN BOOLEAN},
- * {@link XPathConstants#NODE NODE} or
- * {@link XPathConstants#NODESET NODESET})
- * then an IllegalArgumentException
is thrown.
- *
- * If a null
value is provided for
- * item
, an empty document will be used for the
- * context.
- * If expression
or returnType
is null
, then a
- * NullPointerException
is thrown.
- *
- * @param expression The XPath expression.
- * @param item The starting context (node or node list, for example).
- * @param returnType The desired return type.
- *
- * @return Result of evaluating an XPath expression as an Object
of returnType
.
- *
- * @throws XPathExpressionException If expression
cannot be evaluated.
- * @throws IllegalArgumentException If returnType
is not one of the types defined in {@link XPathConstants}.
- * @throws NullPointerException If expression
or returnType
is null
.
- */
- public Object evaluate(String expression, Object item, QName returnType)
- throws XPathExpressionException {
- if ( expression == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"XPath expression"} );
- throw new NullPointerException ( fmsg );
+ @Override
+ public Object evaluate(String expression, Object item, QName returnType) throws XPathExpressionException {
+ if (expression == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"XPath expression"});
+ throw new NullPointerException(fmsg);
}
- if ( returnType == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"returnType"} );
- throw new NullPointerException ( fmsg );
+ if (returnType == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"returnType"});
+ throw new NullPointerException(fmsg);
}
// Checking if requested returnType is supported. returnType need to
// be defined in XPathConstants or JSTLXPathConstants
- if ( !isSupported ( returnType ) ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
- new Object[] { returnType.toString() } );
- throw new IllegalArgumentException ( fmsg );
+ if (!isSupported(returnType)) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+ new Object[] {returnType.toString()});
+ throw new IllegalArgumentException(fmsg);
}
try {
-
- XObject resultObject = eval( expression, item );
- return getResultAsType( resultObject, returnType );
- } catch ( java.lang.NullPointerException npe ) {
- // If VariableResolver returns null Or if we get
+ XObject resultObject = eval(expression, item);
+ return getResultAsType(resultObject, returnType);
+ } catch (NullPointerException npe) {
+ // If VariableResolver returns null Or if we get
// NullPointerException at this stage for some other reason
- // then we have to reurn XPathException
- throw new XPathExpressionException ( npe );
- } catch ( javax.xml.transform.TransformerException te ) {
+ // then we have to reurn XPathException
+ throw new XPathExpressionException(npe);
+ } catch (TransformerException te) {
Throwable nestedException = te.getException();
- if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
- throw (javax.xml.xpath.XPathFunctionException)nestedException;
- } else {
- // For any other exceptions we need to throw
- // XPathExpressionException ( as per spec )
- throw new XPathExpressionException ( te );
+ if (nestedException instanceof XPathFunctionException) {
+ throw (XPathFunctionException) nestedException;
}
- }
-
+ // For any other exceptions we need to throw
+ // XPathExpressionException ( as per spec )
+ throw new XPathExpressionException(te);
+ }
}
- private boolean isSupported( QName returnType ) {
- if ( ( returnType.equals( XPathConstants.STRING ) ) ||
- ( returnType.equals( XPathConstants.NUMBER ) ) ||
- ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
- ( returnType.equals( XPathConstants.NODE ) ) ||
- ( returnType.equals( XPathConstants.NODESET ) ) ||
- ( returnType.equals( JSTLXPathConstants.OBJECT ) ) ) {
-
- return true;
- }
- return false;
- }
- private Object getResultAsType( XObject resultObject, QName returnType )
- throws javax.xml.transform.TransformerException {
- // XPathConstants.STRING
- if ( returnType.equals( XPathConstants.STRING ) ) {
- return resultObject.str();
- }
- // XPathConstants.NUMBER
- if ( returnType.equals( XPathConstants.NUMBER ) ) {
- return new Double ( resultObject.num());
+ @Override
+ public String evaluate(String expression, Object item) throws XPathExpressionException {
+ return (String) this.evaluate(expression, item, XPathConstants.STRING);
+ }
+
+
+ @Override
+ public Object evaluate(String expression, InputSource source, QName returnType) throws XPathExpressionException {
+ // Checking validity of different parameters
+ if (source == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"source"});
+ throw new NullPointerException(fmsg);
}
- // XPathConstants.BOOLEAN
- if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
- return Boolean.valueOf( resultObject.bool());
+ if (expression == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"XPath expression"});
+ throw new NullPointerException(fmsg);
}
- // XPathConstants.NODESET ---ORdered, UNOrdered???
- if ( returnType.equals( XPathConstants.NODESET ) ) {
- return resultObject.nodelist();
+ if (returnType == null) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+ new Object[] {"returnType"});
+ throw new NullPointerException(fmsg);
}
- // XPathConstants.NODE
- if ( returnType.equals( XPathConstants.NODE ) ) {
- NodeIterator ni = resultObject.nodeset();
- //Return the first node, or null
- return ni.nextNode();
+
+ // Checking if requested returnType is supported.
+ // returnType need to be defined in XPathConstants
+ if (!isSupported(returnType)) {
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+ new Object[] {returnType.toString()});
+ throw new IllegalArgumentException(fmsg);
}
- // JSTLXPathConstants.OBJECT
- if ( returnType.equals( JSTLXPathConstants.OBJECT ) ) {
- if (resultObject instanceof org.apache.xpath.objects.XNodeSet)
- return resultObject.nodelist();
- else
- return resultObject.object();
+
+ try {
+ Document document = DocumentBuilderProvider.createDocumentBuilder().parse(source);
+ XObject resultObject = eval(expression, document);
+ return getResultAsType(resultObject, returnType);
+ } catch (SAXException e) {
+ throw new XPathExpressionException(e);
+ } catch (IOException e) {
+ throw new XPathExpressionException(e);
+ } catch (TransformerException te) {
+ Throwable nestedException = te.getException();
+ if (nestedException instanceof XPathFunctionException) {
+ throw (XPathFunctionException) nestedException;
+ }
+ throw new XPathExpressionException(te);
}
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
- new Object[] { returnType.toString()});
- throw new IllegalArgumentException( fmsg );
}
-
-
-
- /**
- * Evaluate an XPath expression in the specified context and return the result as a String
.
- *
- * This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a returnType
of
- * {@link XPathConstants#STRING}.
- *
- * See "Evaluation of XPath Expressions" of JAXP 1.3 spec
- * for context item evaluation,
- * variable, function and QName resolution and return type conversion.
- *
- * If a null
value is provided for
- * item
, an empty document will be used for the
- * context.
- * If expression
is null
, then a NullPointerException
is thrown.
- *
- * @param expression The XPath expression.
- * @param item The starting context (node or node list, for example).
- *
- * @return The String
that is the result of evaluating the expression and
- * converting the result to a String
.
- *
- * @throws XPathExpressionException If expression
cannot be evaluated.
- * @throws NullPointerException If expression
is null
.
- */
- public String evaluate(String expression, Object item)
- throws XPathExpressionException {
- return (String)this.evaluate( expression, item, XPathConstants.STRING );
+
+
+ @Override
+ public String evaluate(String expression, InputSource source) throws XPathExpressionException {
+ return (String) this.evaluate(expression, source, XPathConstants.STRING);
}
- /**
- * Compile an XPath expression for later evaluation.
- *
- * If expression
contains any {@link javax.xml.xpath.XPathFunction}s,
- * they must be available via the {@link XPathFunctionResolver}.
- * An {@link XPathExpressionException} will be thrown if the XPathFunction
- * cannot be resovled with the XPathFunctionResolver
.
- *
- * If expression
is null
, a NullPointerException
is thrown.
- *
- * @param expression The XPath expression.
- *
- * @return Compiled XPath expression.
-
- * @throws XPathExpressionException If expression
cannot be compiled.
- * @throws NullPointerException If expression
is null
.
- */
- public XPathExpression compile(String expression)
- throws XPathExpressionException {
- // This is never used in JSTL
- if ( expression == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"XPath expression"} );
- throw new NullPointerException ( fmsg );
+
+ private XObject eval(String expression, Object contextItem) throws TransformerException {
+ XPath xpath = new XPath(expression, null, prefixResolver, XPath.SELECT);
+ final XPathContext xpathSupport;
+ if (functionResolver != null) {
+ JAXPExtensionsProvider jep = new JAXPExtensionsProvider(functionResolver, featureSecureProcessing);
+ xpathSupport = new XPathContext(jep);
+ } else {
+ xpathSupport = new XPathContext();
}
- return null;
- /*
- try {
- com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null,
- prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
- // Can have errorListener
- com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl ximpl =
- new com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl (xpath,
- prefixResolver, functionResolver, variableResolver,
- featureSecureProcessing );
- return ximpl;
- } catch ( javax.xml.transform.TransformerException te ) {
- throw new XPathExpressionException ( te ) ;
+
+ xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
+
+ // If item is null, then we will create a a Dummy contextNode
+ if (contextItem instanceof Node) {
+ return xpath.execute(xpathSupport, (Node) contextItem, prefixResolver);
}
- **/
+ return xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
}
- /**
- * Evaluate an XPath expression in the context of the specified InputSource
- * and return the result as the specified type.
- *
- * This method builds a data model for the {@link InputSource} and calls
- * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.
- *
- * See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
- * for context item evaluation,
- * variable, function and QName resolution and return type conversion.
- *
- * If returnType
is not one of the types defined in {@link XPathConstants},
- * then an IllegalArgumentException
is thrown.
- *
- * If expression
, source
or returnType
is null
,
- * then a NullPointerException
is thrown.
- *
- * @param expression The XPath expression.
- * @param source The input source of the document to evaluate over.
- * @param returnType The desired return type.
- *
- * @return The Object
that encapsulates the result of evaluating the expression.
- *
- * @throws XPathExpressionException If expression cannot be evaluated.
- * @throws IllegalArgumentException If returnType
is not one of the types defined in {@link XPathConstants}.
- * @throws NullPointerException If expression
, source
or returnType
- * is null
.
- */
- public Object evaluate(String expression, InputSource source,
- QName returnType) throws XPathExpressionException {
- // Checking validity of different parameters
- if( source== null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"source"} );
- throw new NullPointerException ( fmsg );
+ private boolean isSupported(QName returnType) {
+ return returnType.equals(XPathConstants.STRING) || returnType.equals(XPathConstants.NUMBER)
+ || returnType.equals(XPathConstants.BOOLEAN) || returnType.equals(XPathConstants.NODE)
+ || returnType.equals(XPathConstants.NODESET) || returnType.equals(JSTLXPathConstants.OBJECT);
+ }
+
+
+ private Object getResultAsType(XObject resultObject, QName returnType) throws TransformerException {
+ if (returnType.equals(XPathConstants.STRING)) {
+ return resultObject.str();
}
- if ( expression == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"XPath expression"} );
- throw new NullPointerException ( fmsg );
+ if (returnType.equals(XPathConstants.NUMBER)) {
+ return Double.valueOf(resultObject.num());
}
- if ( returnType == null ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
- new Object[] {"returnType"} );
- throw new NullPointerException ( fmsg );
+ if (returnType.equals(XPathConstants.BOOLEAN)) {
+ return Boolean.valueOf(resultObject.bool());
}
-
- //Checking if requested returnType is supported.
- //returnType need to be defined in XPathConstants
- if ( !isSupported ( returnType ) ) {
- String fmsg = XSLMessages.createXPATHMessage(
- XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
- new Object[] { returnType.toString() } );
- throw new IllegalArgumentException ( fmsg );
+ // XPathConstants.NODESET ---ORdered, UNOrdered???
+ if (returnType.equals(XPathConstants.NODESET)) {
+ return resultObject.nodelist();
}
-
- try {
-
- Document document = getParser().parse( source );
-
- XObject resultObject = eval( expression, document );
- return getResultAsType( resultObject, returnType );
- } catch ( SAXException e ) {
- throw new XPathExpressionException ( e );
- } catch( IOException e ) {
- throw new XPathExpressionException ( e );
- } catch ( javax.xml.transform.TransformerException te ) {
- Throwable nestedException = te.getException();
- if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
- throw (javax.xml.xpath.XPathFunctionException)nestedException;
- } else {
- throw new XPathExpressionException ( te );
+ if (returnType.equals(XPathConstants.NODE)) {
+ NodeIterator ni = resultObject.nodeset();
+ // Return the first node, or null
+ return ni.nextNode();
+ }
+ if (returnType.equals(JSTLXPathConstants.OBJECT)) {
+ if (resultObject instanceof XNodeSet) {
+ return resultObject.nodelist();
}
+ return resultObject.object();
}
-
- }
-
-
-
-
- /**
- * Evaluate an XPath expression in the context of the specified InputSource
- * and return the result as a String
.
- *
- * This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
- * returnType
of {@link XPathConstants#STRING}.
- *
- * See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
- * for context item evaluation,
- * variable, function and QName resolution and return type conversion.
- *
- * If expression
or source
is null
,
- * then a NullPointerException
is thrown.
- *
- * @param expression The XPath expression.
- * @param source The InputSource
of the document to evaluate over.
- *
- * @return The String
that is the result of evaluating the expression and
- * converting the result to a String
.
- *
- * @throws XPathExpressionException If expression cannot be evaluated.
- * @throws NullPointerException If expression
or source
is null
.
- */
- public String evaluate(String expression, InputSource source)
- throws XPathExpressionException {
- return (String)this.evaluate( expression, source, XPathConstants.STRING );
- }
-
- /**
- * Reset this XPath
to its original configuration.
- *
- * XPath
is reset to the same state as when it was created with
- * {@link javax.xml.xpath.XPathFactory#newXPath()}.
- * reset()
is designed to allow the reuse of existing XPath
s
- * thus saving resources associated with the creation of new XPath
s.
- *
- * The reset XPath
is not guaranteed to have the same
- * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
- * or {@link NamespaceContext} Object
s, e.g. {@link Object#equals(Object obj)}.
- * It is guaranteed to have a functionally equal XPathFunctionResolver
,
- * XPathVariableResolver
- * and NamespaceContext
.
- */
- public void reset() {
- this.variableResolver = this.origVariableResolver;
- this.functionResolver = this.origFunctionResolver;
- this.namespaceContext = null;
+ String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+ new Object[] {returnType.toString()});
+ throw new IllegalArgumentException(fmsg);
}
-
}
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
index 025c505..ed1c15e 100644
--- a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/ParseSupport.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
@@ -17,21 +18,20 @@
package org.apache.taglibs.standard.tag.common.xml;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.jsp.JspException;
+import jakarta.servlet.jsp.JspTagException;
+import jakarta.servlet.jsp.PageContext;
+import jakarta.servlet.jsp.tagext.BodyTagSupport;
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.jsp.JspException;
-import jakarta.servlet.jsp.JspTagException;
-import jakarta.servlet.jsp.PageContext;
-import jakarta.servlet.jsp.tagext.BodyTagSupport;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
@@ -72,7 +72,6 @@ public abstract class ParseSupport extends BodyTagSupport {
private int scopeDom; // processed 'scopeDom' attr
// state in support of XML parsing...
- private DocumentBuilderFactory dbf;
private DocumentBuilder db;
private TransformerFactory tf;
private TransformerHandler th;
@@ -91,7 +90,6 @@ private void init() {
xml = null;
systemId = null;
filter = null;
- dbf = null;
db = null;
tf = null;
th = null;
@@ -107,18 +105,7 @@ private void init() {
public int doEndTag() throws JspException {
try {
- // set up our DocumentBuilder
- if (dbf == null) {
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- try {
- dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch (ParserConfigurationException e) {
- throw new AssertionError("Parser does not support secure processing");
- }
- }
- db = dbf.newDocumentBuilder();
+ db = DocumentBuilderProvider.createSecureDocumentBuilder();
// if we've gotten a filter, set up a transformer to support it
if (filter != null) {
@@ -167,8 +154,6 @@ else if (xmlText instanceof Reader)
throw new JspException(ex);
} catch (IOException ex) {
throw new JspException(ex);
- } catch (ParserConfigurationException ex) {
- throw new JspException(ex);
} catch (TransformerConfigurationException ex) {
throw new JspException(ex);
}
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
index 7fb7c1e..aca5059 100644
--- a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/TransformSupport.java
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved.
* Copyright 2004 The Apache Software Foundation
*
@@ -17,6 +18,12 @@
package org.apache.taglibs.standard.tag.common.xml;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.jsp.JspException;
+import jakarta.servlet.jsp.JspTagException;
+import jakarta.servlet.jsp.PageContext;
+import jakarta.servlet.jsp.tagext.BodyTagSupport;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
@@ -24,14 +31,8 @@
import java.io.Writer;
import java.util.List;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.jsp.JspException;
-import jakarta.servlet.jsp.JspTagException;
-import jakarta.servlet.jsp.PageContext;
-import jakarta.servlet.jsp.tagext.BodyTagSupport;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -81,7 +82,6 @@ public abstract class TransformSupport extends BodyTagSupport {
private Transformer t; // actual Transformer
private TransformerFactory tf; // reusable factory
private DocumentBuilder db; // reusable factory
- private DocumentBuilderFactory dbf; // reusable factory
//*********************************************************************
@@ -115,21 +115,9 @@ public int doStartTag() throws JspException {
//************************************
// Initialize
-
- // set up our DocumentBuilderFactory if necessary
- if (dbf == null) {
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setValidating(false);
- try {
- dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch (ParserConfigurationException e) {
- throw new AssertionError("Parser does not support secure processing");
- }
- }
- if (db == null)
- db = dbf.newDocumentBuilder();
-
+ if (db == null) {
+ db = DocumentBuilderProvider.createSecureDocumentBuilder();
+ }
// set up the TransformerFactory if necessary
if (tf == null) {
tf = TransformerFactory.newInstance();
diff --git a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java
index fbb2b9f..60d0238 100644
--- a/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java
+++ b/impl/src/main/java/org/apache/taglibs/standard/tag/common/xml/XPathUtil.java
@@ -1,7 +1,8 @@
/*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 1997-2020 Oracle and/or its affiliates. All rights reserved.
- * Copyright 2004 The Apache Software Foundation
* Copyright (c) 2020 Payara Services Ltd.
+ * Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,341 +20,155 @@
package org.apache.taglibs.standard.tag.common.xml;
import java.util.List;
-import java.util.Vector;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import jakarta.servlet.jsp.JspTagException;
import jakarta.servlet.jsp.PageContext;
import jakarta.servlet.jsp.tagext.Tag;
import jakarta.servlet.jsp.tagext.TagSupport;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathVariableResolver;
-import javax.xml.xpath.XPathFactoryConfigurationException;
-
import org.apache.taglibs.standard.resources.Resources;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
/**
- * Support for tag handlers that evaluate XPath expressions.
+ * Support for tag handlers that evaluate XPath expressions.
*
* @author Shawn Bayern
* @author Ramesh Mandava ( ramesh.mandava@sun.com )
* @author Pierre Delisle ( pierre.delisle@sun.com )
* @author Dongbin Nie
+ * @author David Matejcek
*/
-// would ideally be a base class, but some of our user handlers already
-// have their own parents
public class XPathUtil {
-
- //*********************************************************************
- // Constructor
-
+
+ private static final String PAGE_NS_URL = "http://java.sun.com/jstl/xpath/page";
+ private static final String REQUEST_NS_URL = "http://java.sun.com/jstl/xpath/request";
+ private static final String SESSION_NS_URL = "http://java.sun.com/jstl/xpath/session";
+ private static final String APP_NS_URL = "http://java.sun.com/jstl/xpath/app";
+ private static final String PARAM_NS_URL = "http://java.sun.com/jstl/xpath/param";
+ private static final String INITPARAM_NS_URL = "http://java.sun.com/jstl/xpath/initParam";
+ private static final String COOKIE_NS_URL = "http://java.sun.com/jstl/xpath/cookie";
+ private static final String HEADER_NS_URL = "http://java.sun.com/jstl/xpath/header";
+
+ private static final XPathFactory XPATH_FACTORY = new JSTLXPathFactory();
+ private static final JSTLXPathNamespaceContext JSTL_XPATH_NS_CTX = initXPathNamespaceContext();
+
+ private final PageContext pageContext;
+
/**
* Constructs a new XPathUtil object associated with the given
* PageContext.
*/
public XPathUtil(PageContext pc) {
pageContext = pc;
- }
-
- //*********************************************************************
- // Support for JSTL variable resolution
-
- // The URLs
- private static final String PAGE_NS_URL
- = "http://java.sun.com/jstl/xpath/page";
- private static final String REQUEST_NS_URL
- = "http://java.sun.com/jstl/xpath/request";
- private static final String SESSION_NS_URL
- = "http://java.sun.com/jstl/xpath/session";
- private static final String APP_NS_URL
- = "http://java.sun.com/jstl/xpath/app";
- private static final String PARAM_NS_URL
- = "http://java.sun.com/jstl/xpath/param";
- private static final String INITPARAM_NS_URL
- = "http://java.sun.com/jstl/xpath/initParam";
- private static final String COOKIE_NS_URL
- = "http://java.sun.com/jstl/xpath/cookie";
- private static final String HEADER_NS_URL
- = "http://java.sun.com/jstl/xpath/header";
-
- //*********************************************************************
- // Support for XPath evaluation
-
- private PageContext pageContext;
-
- private static final String XPATH_FACTORY_CLASS_NAME =
- "org.apache.taglibs.standard.tag.common.xml.JSTLXPathFactory";
- private static XPathFactory XPATH_FACTORY;
-
- private static JSTLXPathNamespaceContext jstlXPathNamespaceContext = null;
-
- private static DocumentBuilderFactory dbf = null;
-
- static {
- initXPathFactory();
- initXPathNamespaceContext();
- initDocumentBuilderFactory();
}
- private static void initXPathFactory() {
- // If the system property DEFAULT_PROPERTY_NAME + ":uri" is present,
- // where uri is the parameter to this method, then its value is read
- // as a class name. The method will try to create a new instance of
- // this class by using the class loader, and returns it if it is
- // successfully created.
- if (System.getSecurityManager() != null) {
- AccessController.doPrivileged(new PrivilegedAction(){
- public Object run(){
- System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME +
- ":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
- XPATH_FACTORY_CLASS_NAME);
- return null;
- }
- });
- } else {
- System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME +
- ":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI,
- XPATH_FACTORY_CLASS_NAME);
- }
- try {
- XPATH_FACTORY = XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI);
- } catch (XPathFactoryConfigurationException xpce) {
- xpce.printStackTrace();
- }
- }
-
- /** Initialize globally useful data. */
- private static void initXPathNamespaceContext() {
- // register supported namespaces
- jstlXPathNamespaceContext = new JSTLXPathNamespaceContext();
- jstlXPathNamespaceContext.addNamespace("pageScope", PAGE_NS_URL);
- jstlXPathNamespaceContext.addNamespace("requestScope", REQUEST_NS_URL);
- jstlXPathNamespaceContext.addNamespace("sessionScope", SESSION_NS_URL);
- jstlXPathNamespaceContext.addNamespace("applicationScope", APP_NS_URL);
- jstlXPathNamespaceContext.addNamespace("param", PARAM_NS_URL);
- jstlXPathNamespaceContext.addNamespace("initParam", INITPARAM_NS_URL);
- jstlXPathNamespaceContext.addNamespace("header", HEADER_NS_URL);
- jstlXPathNamespaceContext.addNamespace("cookie", COOKIE_NS_URL);
- }
-
- private static void initDocumentBuilderFactory() {
- dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware( true );
- dbf.setValidating( false );
- }
-
- /**
- * Create a new empty document.
- *
- * This method always allocates a new document as its root node might be
- * exposed to other tags and potentially be mutated.
- *
- * @return a new empty document
- */
- private static Document newEmptyDocument() {
- try {
- DocumentBuilder db = dbf.newDocumentBuilder();
- return db.newDocument();
- } catch (ParserConfigurationException e) {
- throw new AssertionError();
- }
- }
-
+
/**
- * Evaluate an XPath expression to a String value.
+ * Evaluate an XPath expression to a String value.
*/
- public String valueOf(Node contextNode, String xpathString)
- throws JspTagException {
- // p("******** valueOf(" + n + ", " + xpathString + ")");
- XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
-
+ public String valueOf(Node contextNode, String xpathString) throws JspTagException {
XPath xpath = XPATH_FACTORY.newXPath();
- xpath.setNamespaceContext(jstlXPathNamespaceContext);
- xpath.setXPathVariableResolver(jxvr);
+ xpath.setNamespaceContext(JSTL_XPATH_NS_CTX);
+ xpath.setXPathVariableResolver(new JSTLXPathVariableResolver(pageContext));
try {
return xpath.evaluate(xpathString, contextNode);
} catch (XPathExpressionException ex) {
throw new JspTagException(ex.toString(), ex);
}
}
-
-
- /**
- * Evaluate an XPath expression to a boolean value.
+
+
+ /**
+ * Evaluate an XPath expression to a boolean value.
*/
- public boolean booleanValueOf(Node contextNode, String xpathString)
- throws JspTagException {
- XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
-
+ public boolean booleanValueOf(Node contextNode, String xpathString) throws JspTagException {
XPath xpath = XPATH_FACTORY.newXPath();
- xpath.setNamespaceContext(jstlXPathNamespaceContext);
- xpath.setXPathVariableResolver(jxvr);
+ xpath.setNamespaceContext(JSTL_XPATH_NS_CTX);
+ xpath.setXPathVariableResolver(new JSTLXPathVariableResolver(pageContext));
try {
- return ((Boolean) xpath.evaluate(
- xpathString, contextNode, XPathConstants.BOOLEAN)).booleanValue();
+ return ((Boolean) xpath.evaluate(xpathString, contextNode, XPathConstants.BOOLEAN)).booleanValue();
} catch (XPathExpressionException ex) {
- throw new JspTagException(
- Resources.getMessage("XPATH_ERROR_XOBJECT", ex.toString()), ex);
+ throw new JspTagException(Resources.getMessage("XPATH_ERROR_XOBJECT", ex.toString()), ex);
}
}
-
- /**
- * Evaluate an XPath expression to a List of nodes.
+
+
+ /**
+ * Evaluate an XPath expression to a List of nodes.
*/
- public List selectNodes(Node contextNode, String xpathString)
- throws JspTagException {
- XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
-
+ public List selectNodes(Node contextNode, String xpathString) throws JspTagException {
try {
XPath xpath = XPATH_FACTORY.newXPath();
- xpath.setNamespaceContext(jstlXPathNamespaceContext);
- xpath.setXPathVariableResolver(jxvr);
- Object nl = xpath.evaluate(
- xpathString, contextNode, JSTLXPathConstants.OBJECT);
- return new JSTLNodeList( nl );
- } catch (XPathExpressionException ex ) {
+ xpath.setNamespaceContext(JSTL_XPATH_NS_CTX);
+ xpath.setXPathVariableResolver(new JSTLXPathVariableResolver(pageContext));
+ Object nl = xpath.evaluate(xpathString, contextNode, JSTLXPathConstants.OBJECT);
+ return new JSTLNodeList(nl);
+ } catch (XPathExpressionException ex) {
throw new JspTagException(ex.toString(), ex);
}
}
-
- /**
- * Evaluate an XPath expression to a single node.
+
+
+ /**
+ * Evaluate an XPath expression to a single node.
*/
- public Node selectSingleNode(Node contextNode, String xpathString)
- throws JspTagException {
- //p("selectSingleNode of XPathUtil = passed node:" +
- // "xpathString => " + n + " : " + xpathString );
+ public Node selectSingleNode(Node contextNode, String xpathString) throws JspTagException {
XPathVariableResolver jxvr = new JSTLXPathVariableResolver(pageContext);
-
try {
XPath xpath = XPATH_FACTORY.newXPath();
- xpath.setNamespaceContext(jstlXPathNamespaceContext);
+ xpath.setNamespaceContext(JSTL_XPATH_NS_CTX);
xpath.setXPathVariableResolver(jxvr);
- return (Node) xpath.evaluate(
- xpathString, contextNode, XPathConstants.NODE);
+ return (Node) xpath.evaluate(xpathString, contextNode, XPathConstants.NODE);
} catch (XPathExpressionException ex) {
- throw new JspTagException(ex.toString(), ex);
- }
- }
-
- //*********************************************************************
- // Static support for context retrieval from parent tag
-
- public static Node getContext(Tag t) throws JspTagException {
- ForEachTag xt =
- (ForEachTag) TagSupport.findAncestorWithClass(
- t, ForEachTag.class);
- if (xt == null)
- return newEmptyDocument();
- else
- return (xt.getContext());
- }
-
- //*********************************************************************
- // Utility methods
-
- private static void p(String s) {
- System.out.println("[XPathUtil] " + s);
- }
-
- public static void printDetails(Node n) {
- p("\n\nDetails of Node = > " + n ) ;
- p("Name:Type:Node Value = > " + n.getNodeName() +
- ":" + n.getNodeType() + ":" + n.getNodeValue() ) ;
- p("Namespace URI : Prefix : localName = > " +
- n.getNamespaceURI() + ":" +n.getPrefix() + ":" + n.getLocalName());
- p("\n Node has children => " + n.hasChildNodes() );
- if ( n.hasChildNodes() ) {
- NodeList nl = n.getChildNodes();
- p("Number of Children => " + nl.getLength() );
- for ( int i=0; i implements NodeList {
-
- Vector nodeVector;
-
- public JSTLNodeList ( Vector nodeVector ) {
- this.nodeVector = nodeVector;
- }
-
- public JSTLNodeList ( NodeList nl ) {
- nodeVector = new Vector<>();
- //p("[JSTLNodeList] nodelist details");
- for ( int i=0; i();
- nodeVector.addElement( n );
- }
- public JSTLNodeList (Object o) {
- nodeVector = new Vector<>();
-
- if (o instanceof NodeList) {
- NodeList nl = (NodeList)o;
- for ( int i=0; i " + nodeVector.size() );
- return nodeVector.size( );
+ /**
+ * Create a new empty document.
+ *
+ * This method always allocates a new document as its root node might be
+ * exposed to other tags and potentially be mutated.
+ *
+ * @return a new empty document
+ */
+ private static Document newEmptyDocument() {
+ return DocumentBuilderProvider.createDocumentBuilder().newDocument();
}
-
- // Can implement other Vector methods to redirect those methods to
- // the vector in the variable param. As we are not using them as part
- // of this implementation we are not doing that here. If this changes
- // then we need to override those methods accordingly
-
}
-
+