From 3b1841fb44f9e6134cd7d501818fb9d703904d7c Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 18 Apr 2007 22:49:47 +0000 Subject: [PATCH] Removed the Xalan XPathExpression, since Xalan *is* JAXP 1.3. Added NodeMapper functionality to XPathExpression. --- .../http/WsdlDefinitionHandlerAdapter.java | 13 +- .../xpath/JaxenXPathExpressionFactory.java | 51 +++++- .../xpath/Jaxp13XPathExpressionFactory.java | 42 ++++- .../springframework/xml/xpath/NodeMapper.java | 2 + .../xml/xpath/XPathExpression.java | 56 ++++-- .../xml/xpath/XPathExpressionFactory.java | 30 +-- .../xml/xpath/XPathExpressionFactoryBean.java | 2 +- .../xpath/XalanXPathExpressionFactory.java | 173 ------------------ .../springframework/xml/xpath/package.html | 2 +- ...bstractXPathExpressionFactoryTestCase.java | 43 ++++- .../XalanXPathExpressionFactoryTest.java | 33 ---- 11 files changed, 175 insertions(+), 272 deletions(-) delete mode 100644 xml/src/main/java/org/springframework/xml/xpath/XalanXPathExpressionFactory.java delete mode 100644 xml/src/test/java/org/springframework/xml/xpath/XalanXPathExpressionFactoryTest.java diff --git a/core/src/main/java/org/springframework/ws/transport/http/WsdlDefinitionHandlerAdapter.java b/core/src/main/java/org/springframework/ws/transport/http/WsdlDefinitionHandlerAdapter.java index a5da0b37..c8f26591 100644 --- a/core/src/main/java/org/springframework/ws/transport/http/WsdlDefinitionHandlerAdapter.java +++ b/core/src/main/java/org/springframework/ws/transport/http/WsdlDefinitionHandlerAdapter.java @@ -18,6 +18,8 @@ package org.springframework.ws.transport.http; import java.net.MalformedURLException; import java.net.URL; +import java.util.Iterator; +import java.util.List; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -40,7 +42,6 @@ import org.springframework.xml.xpath.XPathExpression; import org.springframework.xml.xpath.XPathExpressionFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; -import org.w3c.dom.Node; /** * Adapter to use the WsdlDefinition interface with the generic DispatcherServlet. Reads the @@ -73,9 +74,7 @@ import org.w3c.dom.Node; */ public class WsdlDefinitionHandlerAdapter extends TransformerObjectSupport implements HandlerAdapter, InitializingBean { - /** - * Default XPath expression used for extracting all location attributes from the WSDL definition. - */ + /** Default XPath expression used for extracting all location attributes from the WSDL definition. */ public static final String DEFAULT_LOCATION_EXPRESSION = "//@location"; private static final String CONTENT_TYPE = "text/xml"; @@ -191,9 +190,9 @@ public class WsdlDefinitionHandlerAdapter extends TransformerObjectSupport imple * @see #transformLocation(String,javax.servlet.http.HttpServletRequest) */ protected void transformLocations(Document definitionDocument, HttpServletRequest request) throws Exception { - Node[] locationNodes = locationXPathExpression.evaluateAsNodes(definitionDocument); - for (int i = 0; i < locationNodes.length; i++) { - Attr location = (Attr) locationNodes[i]; + List locationNodes = locationXPathExpression.evaluateAsNodeList(definitionDocument); + for (Iterator iterator = locationNodes.iterator(); iterator.hasNext();) { + Attr location = (Attr) iterator.next(); if (location != null && StringUtils.hasLength(location.getValue())) { String newLocation = transformLocation(location.getValue(), request); logger.debug("Transforming [" + location.getValue() + "] to [" + newLocation + "]"); diff --git a/xml/src/main/java/org/springframework/xml/xpath/JaxenXPathExpressionFactory.java b/xml/src/main/java/org/springframework/xml/xpath/JaxenXPathExpressionFactory.java index ad8bf0f2..bca4597e 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/JaxenXPathExpressionFactory.java +++ b/xml/src/main/java/org/springframework/xml/xpath/JaxenXPathExpressionFactory.java @@ -16,6 +16,7 @@ package org.springframework.xml.xpath; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -23,6 +24,7 @@ import org.jaxen.JaxenException; import org.jaxen.SimpleNamespaceContext; import org.jaxen.XPath; import org.jaxen.dom.DOMXPath; +import org.w3c.dom.DOMException; import org.w3c.dom.Node; /** @@ -71,9 +73,7 @@ abstract class JaxenXPathExpressionFactory { } } - /** - * Jaxen implementation of the XPathExpression interface. - */ + /** Jaxen implementation of the XPathExpression interface. */ private static class JaxenXpathExpression implements XPathExpression { private XPath xpath; @@ -118,10 +118,49 @@ abstract class JaxenXPathExpressionFactory { } } - public Node[] evaluateAsNodes(Node node) { + public List evaluateAsNodeList(Node node) { try { - List result = xpath.selectNodes(node); - return (Node[]) result.toArray(new Node[result.size()]); + return xpath.selectNodes(node); + } + catch (JaxenException ex) { + throw new XPathException("Could not evaluate XPath expression [" + xpath + "] :" + ex.getMessage(), ex); + } + } + + public Object evaluateAsObject(Node context, NodeMapper nodeMapper) throws XPathException { + try { + Node result = (Node) xpath.selectSingleNode(context); + if (result != null) { + try { + return nodeMapper.mapNode(result, 0); + } + catch (DOMException ex) { + throw new XPathException("Mapping resulted in DOMException", ex); + } + } + else { + return null; + } + } + catch (JaxenException ex) { + throw new XPathException("Could not evaluate XPath expression [" + xpath + "] :" + ex.getMessage(), ex); + } + } + + public List evaluate(Node context, NodeMapper nodeMapper) throws XPathException { + try { + List nodes = xpath.selectNodes(context); + List results = new ArrayList(nodes.size()); + for (int i = 0; i < nodes.size(); i++) { + Node node = (Node) nodes.get(i); + try { + results.add(nodeMapper.mapNode(node, i)); + } + catch (DOMException ex) { + throw new XPathException("Mapping resulted in DOMException", ex); + } + } + return results; } catch (JaxenException ex) { throw new XPathException("Could not evaluate XPath expression [" + xpath + "] :" + ex.getMessage(), ex); diff --git a/xml/src/main/java/org/springframework/xml/xpath/Jaxp13XPathExpressionFactory.java b/xml/src/main/java/org/springframework/xml/xpath/Jaxp13XPathExpressionFactory.java index f430628d..f0cac8c2 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/Jaxp13XPathExpressionFactory.java +++ b/xml/src/main/java/org/springframework/xml/xpath/Jaxp13XPathExpressionFactory.java @@ -16,6 +16,8 @@ package org.springframework.xml.xpath; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.xpath.XPath; @@ -24,6 +26,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.springframework.xml.namespace.SimpleNamespaceContext; +import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -96,9 +99,9 @@ abstract class Jaxp13XPathExpressionFactory { return (String) evaluate(node, XPathConstants.STRING); } - public Node[] evaluateAsNodes(Node node) { + public List evaluateAsNodeList(Node node) { NodeList nodeList = (NodeList) evaluate(node, XPathConstants.NODESET); - return toNodeArray(nodeList); + return toNodeList(nodeList); } private Object evaluate(Node node, QName returnType) { @@ -113,10 +116,10 @@ abstract class Jaxp13XPathExpressionFactory { } } - private Node[] toNodeArray(NodeList nodeList) { - Node[] result = new Node[nodeList.getLength()]; + private List toNodeList(NodeList nodeList) { + List result = new ArrayList(nodeList.getLength()); for (int i = 0; i < nodeList.getLength(); i++) { - result[i] = nodeList.item(i); + result.add(nodeList.item(i)); } return result; } @@ -134,6 +137,35 @@ abstract class Jaxp13XPathExpressionFactory { public Node evaluateAsNode(Node node) { return (Node) evaluate(node, XPathConstants.NODE); } + + public Object evaluateAsObject(Node node, NodeMapper nodeMapper) throws XPathException { + Node result = (Node) evaluate(node, XPathConstants.NODE); + if (result != null) { + try { + return nodeMapper.mapNode(result, 0); + } + catch (DOMException ex) { + throw new XPathException("Mapping resulted in DOMException", ex); + } + } + else { + return null; + } + } + + public List evaluate(Node node, NodeMapper nodeMapper) throws XPathException { + NodeList nodes = (NodeList) evaluate(node, XPathConstants.NODESET); + List results = new ArrayList(nodes.getLength()); + for (int i = 0; i < nodes.getLength(); i++) { + try { + results.add(nodeMapper.mapNode(nodes.item(i), i)); + } + catch (DOMException ex) { + throw new XPathException("Mapping resulted in DOMException", ex); + } + } + return results; + } } } diff --git a/xml/src/main/java/org/springframework/xml/xpath/NodeMapper.java b/xml/src/main/java/org/springframework/xml/xpath/NodeMapper.java index 7cf35b19..8122b3b1 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/NodeMapper.java +++ b/xml/src/main/java/org/springframework/xml/xpath/NodeMapper.java @@ -27,6 +27,8 @@ import org.w3c.dom.Node; * @author Arjen Poutsma * @see XPathOperations#evaluate(String,javax.xml.transform.Source,NodeMapper) * @see XPathOperations#evaluateAsObject(String,javax.xml.transform.Source,NodeMapper) + * @see XPathExpression#evaluate(org.w3c.dom.Node,NodeMapper) + * @see XPathExpression#evaluateAsObject(org.w3c.dom.Node,NodeMapper) */ public interface NodeMapper { diff --git a/xml/src/main/java/org/springframework/xml/xpath/XPathExpression.java b/xml/src/main/java/org/springframework/xml/xpath/XPathExpression.java index 637b3e39..ac50bb49 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/XPathExpression.java +++ b/xml/src/main/java/org/springframework/xml/xpath/XPathExpression.java @@ -16,6 +16,8 @@ package org.springframework.xml.xpath; +import java.util.List; + import org.w3c.dom.Node; /** @@ -35,48 +37,74 @@ public interface XPathExpression { * * @param node the starting point * @return the result of the evaluation + * @throws XPathException in case of XPath errors * @see XPath specification */ - boolean evaluateAsBoolean(Node node); + boolean evaluateAsBoolean(Node node) throws XPathException; /** - * Evaluates the given expression as a Node. Returns the evaluation of the expression, or - * null if it is invalid. + * Evaluates the given expression as a {@link Node}. Returns the evaluation of the expression, or null + * if it is invalid. * * @param node the starting point * @return the result of the evaluation + * @throws XPathException in case of XPath errors * @see XPath specification */ - Node evaluateAsNode(Node node); + Node evaluateAsNode(Node node) throws XPathException; /** - * Evaluates the given expression, and returns all Nodes that conform to it. Returns and empty array if + * Evaluates the given expression, and returns all {@link Node} objects that conform to it. Returns an empty list if * no result could be found. * * @param node the starting point - * @return the Nodes that are selected by the expression + * @return a list of Nodes that are selected by the expression + * @throws XPathException in case of XPath errors * @see XPath specification */ - Node[] evaluateAsNodes(Node node); + List evaluateAsNodeList(Node node) throws XPathException; /** * Evaluates the given expression as a number (double). Returns the numeric evaluation of the - * expression, or Double.NaN if it is invalid. + * expression, or {@link Double#NaN} if it is invalid. * * @param node the starting point * @return the result of the evaluation - * @see Double#NaN + * @throws XPathException in case of XPath errors * @see XPath specification */ - double evaluateAsNumber(Node node); + double evaluateAsNumber(Node node) throws XPathException; /** - * Evaluates the given expression, and returns the first Node that conforms to it. Returns - * null if no result could be found. + * Evaluates the given expression as a String. Returns null if no result could be found. * * @param node the starting point - * @return the first Node that is selected by the expression + * @return the result of the evaluation + * @throws XPathException in case of XPath errors * @see XPath specification */ - String evaluateAsString(Node node); + String evaluateAsString(Node node) throws XPathException; + + /** + * Evaluates the given expression, mapping a single {@link Node} result to a Java object via a {@link NodeMapper}. + * + * @param node the starting point + * @param nodeMapper object that will map one object per node + * @return the single mapped object + * @throws XPathException in case of XPath errors + * @see XPath specification + */ + Object evaluateAsObject(Node node, NodeMapper nodeMapper) throws XPathException; + + /** + * Evaluates the given expression, mapping each result {@link Node} objects to a Java object via a {@link + * NodeMapper}. + * + * @param node the starting point + * @param nodeMapper object that will map one object per node + * @return the result list, containing mapped objects + * @throws XPathException in case of XPath errors + * @see XPath specification + */ + List evaluate(Node node, NodeMapper nodeMapper) throws XPathException; } diff --git a/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactory.java b/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactory.java index 523871c6..82569e0f 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactory.java +++ b/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactory.java @@ -26,11 +26,11 @@ import org.springframework.util.ClassUtils; import org.springframework.xml.JaxpVersion; /** - * Factory for compiled XPathExpressions, being aware of JAXP 1.3+ XPath functionality, Jaxen, and Xalan. - * Mainly for internal use of the framework. + * Factory for compiled XPathExpressions, being aware of JAXP 1.3+ XPath functionality, and Jaxen. Mainly + * for internal use of the framework. *

* The goal of this class is to avoid runtime dependencies a specific XPath engine, simply using the best XPath - * implementation that is available. Prefers JAXP 1.3+ XPath implementations to Jaxen, and falls back to Xalan. + * implementation that is available. Prefers JAXP 1.3+ XPath implementations to Jaxen. * * @author Arjen Poutsma * @see XPathExpression @@ -39,16 +39,12 @@ public abstract class XPathExpressionFactory { private static final Log logger = LogFactory.getLog(XPathExpressionFactory.class); - private static final String XALAN_XPATH_CLASS_NAME = "org.apache.xpath.XPath"; - - private static boolean xalanXPathAvailable; - private static final String JAXEN_CLASS_NAME = "org.jaxen.XPath"; private static boolean jaxenAvailable; static { - // Check whether JAXP 1.3, Resin, Jaxen, or Xalan are available + // Check whether JAXP 1.3, or Jaxen are available if (JaxpVersion.getJaxpVersion() >= JaxpVersion.JAXP_13) { logger.info("JAXP 1.3 available"); } @@ -60,14 +56,6 @@ public abstract class XPathExpressionFactory { catch (ClassNotFoundException ex) { jaxenAvailable = false; } - try { - ClassUtils.forName(XALAN_XPATH_CLASS_NAME); - xalanXPathAvailable = true; - logger.info("Xalan available"); - } - catch (ClassNotFoundException ex) { - xalanXPathAvailable = false; - } } /** @@ -75,7 +63,7 @@ public abstract class XPathExpressionFactory { * * @param expression the XPath expression * @return the compiled XPath expression - * @throws IllegalStateException if neither JAXP 1.3+, Jaxen, or Xalan are available + * @throws IllegalStateException if neither JAXP 1.3+, or Jaxen are available * @throws XPathParseException if the given expression cannot be parsed */ public static XPathExpression createXPathExpression(String expression) @@ -90,7 +78,7 @@ public abstract class XPathExpressionFactory { * @param expression the XPath expression * @param namespaces a map that binds string prefixes to string namespaces * @return the compiled XPath expression - * @throws IllegalStateException if neither JAXP 1.3+, Jaxen, or Xalan are available + * @throws IllegalStateException if neither JAXP 1.3+, or Jaxen are available * @throws XPathParseException if the given expression cannot be parsed */ public static XPathExpression createXPathExpression(String expression, Map namespaces) @@ -104,13 +92,9 @@ public abstract class XPathExpressionFactory { logger.debug("Creating [org.jaxen.XPath]"); return JaxenXPathExpressionFactory.createXPathExpression(expression, namespaces); } - else if (xalanXPathAvailable) { - logger.debug("Creating [org.apache.xpath.XPath]"); - return XalanXPathExpressionFactory.createXPathExpression(expression, namespaces); - } else { throw new IllegalStateException( - "Could not create XPathExpression: could not locate JAXP 1.3, Resin, Xalan on the class path"); + "Could not create XPathExpression: could not locate JAXP 1.3, or Jaxen on the class path"); } } diff --git a/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java b/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java index 65c3af11..af13e1df 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java +++ b/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java @@ -26,7 +26,7 @@ import org.springframework.util.Assert; * Spring {@link FactoryBean} for {@link XPathExpression} object. Facilitates injection of XPath expressions into * endpoint beans. *

- * Uses {@link XPathExpressionFactory} underneath, so support is provided for JAXP 1.3, Jaxen, and Xalan XPaths. + * Uses {@link XPathExpressionFactory} underneath, so support is provided for JAXP 1.3, and Jaxen XPaths. * * @author Arjen Poutsma * @see #setExpression(String) diff --git a/xml/src/main/java/org/springframework/xml/xpath/XalanXPathExpressionFactory.java b/xml/src/main/java/org/springframework/xml/xpath/XalanXPathExpressionFactory.java deleted file mode 100644 index c636f54f..00000000 --- a/xml/src/main/java/org/springframework/xml/xpath/XalanXPathExpressionFactory.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2006 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.xml.xpath; - -import java.util.Map; - -import javax.xml.transform.TransformerException; - -import org.apache.xml.utils.PrefixResolver; -import org.apache.xpath.XPath; -import org.apache.xpath.XPathContext; -import org.apache.xpath.objects.XObject; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.traversal.NodeIterator; - -/** - * Xalan-specific factory creating XPathExpressions. - * - * @author Arjen Poutsma - * @see #createXPathExpression(String) - */ -abstract class XalanXPathExpressionFactory { - - /** - * Creates a Xalan XPathExpression from the given string expression. - * - * @param expression the XPath expression - * @return the compiled XPathExpression - * @throws XPathParseException when the given expression cannot be parsed - */ - static XPathExpression createXPathExpression(String expression) { - try { - XPath xpath = new XPath(expression, null, null, XPath.SELECT); - return new XalanXPathExpression(xpath); - } - catch (TransformerException ex) { - throw new org.springframework.xml.xpath.XPathParseException( - "Could not compile [" + expression + "] to a XPathExpression: " + ex.getMessage(), ex); - } - } - - /** - * Creates a Xalan XPathExpression from the given string expression and namespaces. - * - * @param expression the XPath expression - * @return the compiled XPathExpression - * @throws XPathParseException when the given expression cannot be parsed - */ - public static XPathExpression createXPathExpression(String expression, Map namespaces) { - try { - PrefixResolver prefixResolver = new SimplePrefixResolver(namespaces); - XPath xpath = new XPath(expression, null, prefixResolver, XPath.SELECT); - return new XalanXPathExpression(xpath); - } - catch (TransformerException ex) { - throw new org.springframework.xml.xpath.XPathParseException( - "Could not compile [" + expression + "] to a XPathExpression: " + ex.getMessage(), ex); - } - } - - /** - * Xalan implementation of the XPathExpression interface. - */ - private static class XalanXPathExpression implements XPathExpression { - - private XPath xpath; - - private XPathContext context = new XPathContext(); - - private XalanXPathExpression(XPath xpath) { - this.xpath = xpath; - } - - public Node evaluateAsNode(Node node) { - try { - XObject result = xpath.execute(context, node, null); - NodeIterator iterator = result.nodeset(); - return iterator.nextNode(); - } - catch (TransformerException ex) { - throw new XPathException("Could not evaluate XPath expression:" + ex.getMessage(), ex); - } - } - - public boolean evaluateAsBoolean(Node node) { - try { - XObject result = xpath.execute(context, node, null); - return result.bool(); - } - catch (TransformerException ex) { - throw new XPathException("Could not evaluate XPath expression:" + ex.getMessage(), ex); - } - } - - public double evaluateAsNumber(Node node) { - try { - XObject result = xpath.execute(context, node, null); - return result.num(); - } - catch (TransformerException ex) { - throw new XPathException("Could not evaluate XPath expression:" + ex.getMessage(), ex); - } - } - - public String evaluateAsString(Node node) { - try { - XObject result = xpath.execute(context, node, null); - return result.str(); - } - catch (TransformerException ex) { - throw new XPathException("Could not evaluate XPath expression:" + ex.getMessage(), ex); - } - } - - public Node[] evaluateAsNodes(Node node) { - try { - XObject result = xpath.execute(context, node, null); - return toNodeArray(result.nodelist()); - } - catch (TransformerException ex) { - throw new XPathException("Could not evaluate XPath expression:" + ex.getMessage(), ex); - } - } - - private Node[] toNodeArray(NodeList nodeList) { - Node[] result = new Node[nodeList.getLength()]; - for (int i = 0; i < nodeList.getLength(); i++) { - result[i] = nodeList.item(i); - } - return result; - } - } - - private static class SimplePrefixResolver implements PrefixResolver { - - private Map namespaces; - - private SimplePrefixResolver(Map namespaces) { - this.namespaces = namespaces; - } - - public String getNamespaceForPrefix(String prefix) { - return (String) namespaces.get(prefix); - } - - public String getNamespaceForPrefix(String prefix, Node node) { - return (String) namespaces.get(prefix); - } - - public String getBaseIdentifier() { - return null; - } - - public boolean handlesNullPrefixes() { - return false; - } - } -} diff --git a/xml/src/main/java/org/springframework/xml/xpath/package.html b/xml/src/main/java/org/springframework/xml/xpath/package.html index 36e7692e..5330ca07 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/package.html +++ b/xml/src/main/java/org/springframework/xml/xpath/package.html @@ -1,5 +1,5 @@ -Provides XPathTemplate implementations, and various classes for XPath evaluation using JAXP 1.3, Jaxen, and Xalan. +Provides XPathTemplate implementations, and various classes for XPath evaluation using JAXP 1.3, and Jaxen. diff --git a/xml/src/test/java/org/springframework/xml/xpath/AbstractXPathExpressionFactoryTestCase.java b/xml/src/test/java/org/springframework/xml/xpath/AbstractXPathExpressionFactoryTestCase.java index d535ce13..bc2049ce 100644 --- a/xml/src/test/java/org/springframework/xml/xpath/AbstractXPathExpressionFactoryTestCase.java +++ b/xml/src/test/java/org/springframework/xml/xpath/AbstractXPathExpressionFactoryTestCase.java @@ -19,18 +19,18 @@ package org.springframework.xml.xpath; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; +import java.util.List; import java.util.Map; - import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import junit.framework.TestCase; +import org.springframework.util.StringUtils; +import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.SAXException; -import org.springframework.util.StringUtils; - public abstract class AbstractXPathExpressionFactoryTestCase extends TestCase { private Document noNamespacesDocument; @@ -137,18 +137,18 @@ public abstract class AbstractXPathExpressionFactoryTestCase extends TestCase { assertEquals("Invalid localname", "child", result.getLocalName()); } - public void testEvaluateAsNodesNamespaces() throws IOException, SAXException { + public void testEvaluateAsNodeListNamespaces() throws IOException, SAXException { XPathExpression expression = createXPathExpression("/prefix1:root/prefix2:child/*", namespaces); - Node[] results = expression.evaluateAsNodes(namespacesDocument); + List results = expression.evaluateAsNodeList(namespacesDocument); assertNotNull("Invalid result", results); - assertEquals("Invalid amount of results", 3, results.length); + assertEquals("Invalid amount of results", 3, results.size()); } - public void testEvaluateAsNodesNoNamespaces() throws IOException, SAXException { + public void testEvaluateAsNodeListNoNamespaces() throws IOException, SAXException { XPathExpression expression = createXPathExpression("/root/child/*"); - Node[] results = expression.evaluateAsNodes(noNamespacesDocument); + List results = expression.evaluateAsNodeList(noNamespacesDocument); assertNotNull("Invalid result", results); - assertEquals("Invalid amount of results", 3, results.length); + assertEquals("Invalid amount of results", 3, results.size()); } public void testEvaluateAsStringInvalidNamespaces() throws IOException, SAXException { @@ -176,6 +176,31 @@ public abstract class AbstractXPathExpressionFactoryTestCase extends TestCase { assertEquals("Invalid result", "text", result); } + public void testEvaluateAsObject() throws Exception { + XPathExpression expression = createXPathExpression("/root/child"); + String result = (String) expression.evaluateAsObject(noNamespacesDocument, new NodeMapper() { + public Object mapNode(Node node, int nodeNum) throws DOMException { + return node.getLocalName(); + } + }); + assertNotNull("Invalid result", result); + assertEquals("Invalid localname", "child", result); + } + + public void testEvaluate() throws Exception { + XPathExpression expression = createXPathExpression("/root/child/*"); + List results = expression.evaluate(noNamespacesDocument, new NodeMapper() { + public Object mapNode(Node node, int nodeNum) throws DOMException { + return node.getLocalName(); + } + }); + assertNotNull("Invalid result", results); + assertEquals("Invalid amount of results", 3, results.size()); + assertEquals("Invalid first result", "text", results.get(0)); + assertEquals("Invalid first result", "number", results.get(1)); + assertEquals("Invalid first result", "boolean", results.get(2)); + } + public void testInvalidExpression() { try { createXPathExpression("\\"); diff --git a/xml/src/test/java/org/springframework/xml/xpath/XalanXPathExpressionFactoryTest.java b/xml/src/test/java/org/springframework/xml/xpath/XalanXPathExpressionFactoryTest.java deleted file mode 100644 index b2a222d6..00000000 --- a/xml/src/test/java/org/springframework/xml/xpath/XalanXPathExpressionFactoryTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2006 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.xml.xpath; - -import java.util.Map; - -/** - * @author Arjen Poutsma - */ -public class XalanXPathExpressionFactoryTest extends AbstractXPathExpressionFactoryTestCase { - - protected XPathExpression createXPathExpression(String expression) { - return XalanXPathExpressionFactory.createXPathExpression(expression); - } - - protected XPathExpression createXPathExpression(String expression, Map prefixes) { - return XalanXPathExpressionFactory.createXPathExpression(expression, prefixes); - } -}