From: <bo...@us...> - 2010-04-29 06:14:40
|
Revision: 362 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=362&view=rev Author: bodewig Date: 2010-04-29 06:14:31 +0000 (Thu, 29 Apr 2010) Log Message: ----------- New XPath engine for Java 2.0 Modified Paths: -------------- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/Jaxp13XpathEngine.java trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/XMLUnitNamespaceContext2Jaxp13.java Added Paths: ----------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/xpath/ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/xpath/XPathEngine.java Added: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/xpath/XPathEngine.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/xpath/XPathEngine.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/xpath/XPathEngine.java 2010-04-29 06:14:31 UTC (rev 362) @@ -0,0 +1,146 @@ +/* + This file is licensed to You 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 net.sf.xmlunit.xpath; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.transform.Source; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import net.sf.xmlunit.exceptions.ConfigurationException; +import net.sf.xmlunit.exceptions.XMLUnitException; +import net.sf.xmlunit.util.Convert; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class XPathEngine { + private final XPath xpath; + + public XPathEngine(XPathFactory fac) { + try { + xpath = fac.newXPath(); + } catch (Exception e) { + throw new ConfigurationException(e); + } + } + + public XPathEngine() { + this(XPathFactory.newInstance()); + } + + public Iterable<Node> selectNodes(String xPath, Source s) { + try { + NodeList nl = (NodeList) xpath.evaluate(xPath, + Convert.toInputSource(s), + XPathConstants.NODESET); + return new IterableNodeList(nl); + } catch (XPathExpressionException ex) { + throw new XMLUnitException(ex); + } + } + + public String evaluate(String xPath, Source s) { + try { + return xpath.evaluate(xPath, Convert.toInputSource(s)); + } catch (XPathExpressionException ex) { + throw new XMLUnitException(ex); + } + } + + public void setNamespaceContext(Map<String, String> prefix2Uri) { + xpath.setNamespaceContext(new NC(prefix2Uri)); + } + + private static class NC implements NamespaceContext { + private final Map<String, String> prefix2Uri; + + private NC(Map<String, String> prefix2Uri) { + this.prefix2Uri = prefix2Uri; + } + + public String getNamespaceURI(String prefix) { + if (prefix == null) { + throw new IllegalArgumentException("prefix must not be null"); + } + if (XMLConstants.XML_NS_PREFIX.equals(prefix)) { + return XMLConstants.XML_NS_URI; + } + if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) { + return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; + } + String uri = prefix2Uri.get(prefix); + return uri != null ? uri : XMLConstants.NULL_NS_URI; + } + + public String getPrefix(String uri) { + Iterator i = getPrefixes(uri); + return i.hasNext() ? (String) i.next() : null; + } + + public Iterator getPrefixes(String uri) { + if (uri == null) { + throw new IllegalArgumentException("uri must not be null"); + } + Collection<String> c = new HashSet<String>(); + boolean done = false; + if (XMLConstants.XML_NS_URI.equals(uri)) { + c.add(XMLConstants.XML_NS_PREFIX); + done = true; + } + if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri)) { + c.add(XMLConstants.XMLNS_ATTRIBUTE); + done = true; + } + if (!done) { + for (Map.Entry<String, String> entry : prefix2Uri.entrySet()) { + if (uri.equals(entry.getValue())) { + c.add(entry.getKey()); + } + } + } + return c.iterator(); + } + } + + private static class IterableNodeList implements Iterable<Node> { + private final NodeList nl; + private final int length; + private int current = 0; + private IterableNodeList(NodeList nl) { + this.nl = nl; + length = nl.getLength(); + } + public Iterator<Node> iterator() { + return new Iterator<Node>() { + public void remove() { + throw new UnsupportedOperationException(); + } + public Node next() { + return nl.item(current++); + } + public boolean hasNext() { + return current < length; + } + }; + } + } + +} Property changes on: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/xpath/XPathEngine.java ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/Jaxp13XpathEngine.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/Jaxp13XpathEngine.java 2010-04-29 06:13:34 UTC (rev 361) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/Jaxp13XpathEngine.java 2010-04-29 06:14:31 UTC (rev 362) @@ -42,32 +42,39 @@ import org.custommonkey.xmlunit.exceptions.ConfigurationException; import org.custommonkey.xmlunit.exceptions.XpathException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.xml.transform.dom.DOMSource; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import net.sf.xmlunit.exceptions.XMLUnitException; +import net.sf.xmlunit.xpath.XPathEngine; + /** * XPath engine based on javax.xml.xpath. */ public class Jaxp13XpathEngine implements XpathEngine { - private final XPath xpath; + private final XPathEngine engine; public Jaxp13XpathEngine() throws ConfigurationException { try { - XPathFactory f = null; + XPathEngine e = null; if (XMLUnit.getXPathFactory() != null) { - f = (XPathFactory) Class.forName(XMLUnit.getXPathFactory()) - .newInstance(); + e = new XPathEngine((XPathFactory) Class + .forName(XMLUnit.getXPathFactory()) + .newInstance()); } else { - f = XPathFactory.newInstance(); + e = new XPathEngine(); } - - xpath = f.newXPath(); + engine = e; + } catch (net.sf.xmlunit.exceptions.ConfigurationException ex) { + throw new ConfigurationException(ex.getCause()); } catch (Exception ex) { throw new ConfigurationException(ex); } @@ -84,10 +91,12 @@ public NodeList getMatchingNodes(String select, Document document) throws XpathException { try { - return (NodeList) xpath.evaluate(select, document, - XPathConstants.NODESET); - } catch (XPathExpressionException ex) { - throw new XpathException(ex); + return new NodeListForIterable(engine + .selectNodes(select, + new DOMSource(document)) + ); + } catch (XMLUnitException ex) { + throw new XpathException(ex.getCause()); } } @@ -103,13 +112,34 @@ public String evaluate(String select, Document document) throws XpathException { try { - return xpath.evaluate(select, document); - } catch (XPathExpressionException ex) { - throw new XpathException(ex); + return engine.evaluate(select, new DOMSource(document)); + } catch (XMLUnitException ex) { + throw new XpathException(ex.getCause()); } } public void setNamespaceContext(NamespaceContext ctx) { - xpath.setNamespaceContext(new XMLUnitNamespaceContext2Jaxp13(ctx)); + engine.setNamespaceContext(XMLUnitNamespaceContext2Jaxp13 + .turnIntoMap(ctx)); } + + private static class NodeListForIterable implements NodeList { + private final List<Node> l; + + private NodeListForIterable(Iterable<Node> it) { + ArrayList<Node> a = new ArrayList<Node>(); + for (Node n : it) { + a.add(n); + } + l = Collections.unmodifiableList(a); + } + + public int getLength() { + return l.size(); + } + + public Node item(int idx) { + return l.get(idx); + } + } } Modified: trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/XMLUnitNamespaceContext2Jaxp13.java =================================================================== --- trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/XMLUnitNamespaceContext2Jaxp13.java 2010-04-29 06:13:34 UTC (rev 361) +++ trunk/xmlunit/src/main/java-legacy/org/custommonkey/xmlunit/jaxp13/XMLUnitNamespaceContext2Jaxp13.java 2010-04-29 06:14:31 UTC (rev 362) @@ -91,7 +91,7 @@ return i.hasNext() ? (String) i.next() : null; } - private static Map turnIntoMap(NamespaceContext ctx) { + static Map turnIntoMap(NamespaceContext ctx) { HashMap/*<String, String>*/ m = new HashMap(); for (Iterator i = ctx.getPrefixes(); i.hasNext(); ) { String prefix = (String) i.next(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |