From 401b2d71ebc8b452691967c5c79ac3719275b6f5 Mon Sep 17 00:00:00 2001 From: rfeng Date: Wed, 9 Sep 2009 16:30:45 +0000 Subject: Fix the calculation of prefixes and add a test case git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@813042 13f79535-47bb-0310-9956-ffa450edef68 --- .../tuscany/sca/common/xml/xpath/XPathHelper.java | 28 +++-- .../sca/common/xml/xpath/XPathHelperTestCase.java | 120 +++++++++++++++++++++ 2 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelperTestCase.java diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelper.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelper.java index cbf8fa9f61..491837c7ee 100644 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelper.java +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelper.java @@ -62,14 +62,27 @@ public class XPathHelper { public XPath newXPath() { return factory.newXPath(); } - + public XPathExpression compile(NamespaceContext context, String expression) throws XPathExpressionException { XPath path = newXPath(); - path.setNamespaceContext(getNamespaceContext(expression, context)); + context = getNamespaceContext(expression, context); + return compile(path, context, expression); + } + + public XPathExpression compile(XPath path, NamespaceContext context, String expression) + throws XPathExpressionException { + path.setNamespaceContext(context); return path.compile(expression); } - private NamespaceContext getNamespaceContext(String expression, NamespaceContext context) { + /** + * Take a snapshot of the given namespace context based on the prefixes found in the expression. + * In StAX, the prefix/namespace mapping in the namespace context can change as the event moves + * @param expression + * @param context + * @return + */ + public NamespaceContext getNamespaceContext(String expression, NamespaceContext context) { NamespaceContextImpl nsContext = new NamespaceContextImpl(null); for (String prefix : getPrefixes(expression)) { @@ -81,6 +94,11 @@ public class XPathHelper { return nsContext; } + /** + * Parse the XPath expression to collect all the prefixes for namespaces + * @param expression + * @return A collection of prefixes + */ private Collection getPrefixes(String expression) { List prefixes = new ArrayList(); prefixes.add(""); @@ -95,14 +113,12 @@ public class XPathHelper { if (XMLCharHelper.isNCName(prefix.charAt(j))) { continue; } - j--; break; } + // j is before the first char of the prefix if (j != (prefix.length() - 1) && XMLCharHelper.isNCNameStart(prefix.charAt(j + 1))) { prefixes.add(prefix.substring(j + 1)); } - break; - } return prefixes; } diff --git a/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelperTestCase.java b/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelperTestCase.java new file mode 100644 index 0000000000..6bd37cb34e --- /dev/null +++ b/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/xpath/XPathHelperTestCase.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * 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 org.apache.tuscany.sca.common.xml.xpath; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; + +import org.apache.tuscany.sca.common.xml.dom.DOMHelper; +import org.apache.tuscany.sca.common.xml.stax.StAXHelper; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * + */ +public class XPathHelperTestCase { + private static XPathHelper xpathHelper; + private static StAXHelper staxHelper; + private static DOMHelper domHelper; + + private static String XML = + "" + "" + + "" + + "" + + ""; + + private static String XPATH = + "" + ""; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); + xpathHelper = XPathHelper.getInstance(registry); + domHelper = DOMHelper.getInstance(registry); + staxHelper = StAXHelper.getInstance(registry); + } + + @Test + public void testNewXPath() { + XPath path = xpathHelper.newXPath(); + Assert.assertNotNull(path); + } + + @Test + public void testCompile() throws Exception { + XMLStreamReader reader = staxHelper.createXMLStreamReader(XPATH); + reader.nextTag(); + String xpath = reader.getAttributeValue(null, "attachTo"); + XPathExpression expression = xpathHelper.compile(reader.getNamespaceContext(), xpath); + // Advance the reader so that the namespace context changes its prefix/namespace mapping + reader.nextTag(); + reader.close(); + + Document doc = domHelper.load(XML); + NodeList nodes = (NodeList)expression.evaluate(doc, XPathConstants.NODESET); + Assert.assertEquals(1, nodes.getLength()); + Node node = nodes.item(0); + Assert.assertTrue(node instanceof Element); + Assert.assertEquals(node.getNodeName(), "c:child1"); + } + + @Test + public void testCompile2() throws Exception { + XMLStreamReader reader = staxHelper.createXMLStreamReader(XPATH); + reader.nextTag(); + String xpathExp = reader.getAttributeValue(null, "attachTo"); + XPath xpath = xpathHelper.newXPath(); + // Compile the expression without taking a snapshot of the namespace context + XPathExpression expression = xpathHelper.compile(xpath, reader.getNamespaceContext(), xpathExp); + // Advance the reader so that the namespace context changes its prefix/namespace mapping + reader.nextTag(); + reader.close(); + + Document doc = domHelper.load(XML); + NodeList nodes = (NodeList)expression.evaluate(doc, XPathConstants.NODESET); + Assert.assertEquals(1, nodes.getLength()); + Node node = nodes.item(0); + Assert.assertTrue(node instanceof Element); + Assert.assertEquals(node.getNodeName(), "c:child1"); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + xpathHelper = null; + } + +} -- cgit v1.2.3