From 4cfe029eea7b5ab461571a83c9ba1af8a818e74a Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 17 Apr 2007 14:30:42 +0000 Subject: [PATCH] Added XPathExpressionFactoryBean. --- core-tiger/pom.xml | 4 - core/pom.xml | 4 - oxm/pom.xml | 5 -- pom.xml | 4 + security/pom.xml | 4 - src/changes/changes.xml | 2 + .../xpath/Jaxp13XPathExpressionFactory.java | 13 ++-- .../xml/xpath/XPathExpressionFactoryBean.java | 73 +++++++++++++++++++ .../xpath/XPathExpressionFactoryBeanTest.java | 38 ++++++++++ 9 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java create mode 100644 xml/src/test/java/org/springframework/xml/xpath/XPathExpressionFactoryBeanTest.java diff --git a/core-tiger/pom.xml b/core-tiger/pom.xml index 90e86973..b26fba0b 100644 --- a/core-tiger/pom.xml +++ b/core-tiger/pom.xml @@ -32,10 +32,6 @@ spring-ws-core - - org.springframework - spring-beans - org.springframework spring-context diff --git a/core/pom.xml b/core/pom.xml index 82310dcd..e72be312 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,10 +22,6 @@ spring-oxm - - org.springframework - spring-beans - org.springframework spring-context diff --git a/oxm/pom.xml b/oxm/pom.xml index 5482d5b1..813dc47b 100644 --- a/oxm/pom.xml +++ b/oxm/pom.xml @@ -63,11 +63,6 @@ org.springframework.ws spring-xml - - - org.springframework - spring-beans - xml-apis diff --git a/pom.xml b/pom.xml index bad4e05b..401b4192 100644 --- a/pom.xml +++ b/pom.xml @@ -657,6 +657,10 @@ org.springframework spring-core + + org.springframework + spring-beans + junit junit diff --git a/security/pom.xml b/security/pom.xml index 02ae1931..d83d4cc1 100644 --- a/security/pom.xml +++ b/security/pom.xml @@ -22,10 +22,6 @@ test - - org.springframework - spring-beans - org.springframework spring-dao diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 83ac0b21..75cf4634 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -6,6 +6,8 @@ + Added XPathExpressionFactoryBean, for injection of XPath expressions + Default message factory for WebServiceTemplate Add faults into dynamically created WSDL Added MethodEndpoint functionality, invoking methods for 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 0fa35e10..34fbead2 100644 --- a/xml/src/main/java/org/springframework/xml/xpath/Jaxp13XPathExpressionFactory.java +++ b/xml/src/main/java/org/springframework/xml/xpath/Jaxp13XPathExpressionFactory.java @@ -17,18 +17,16 @@ package org.springframework.xml.xpath; import java.util.Map; - import javax.xml.namespace.QName; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.springframework.xml.namespace.SimpleNamespaceContext; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.springframework.xml.namespace.SimpleNamespaceContext; - /** * JAXP 1.3-specific factory creating XPathExpressions. * @@ -85,9 +83,7 @@ abstract class Jaxp13XPathExpressionFactory { } } - /** - * JAXP 1.3 implementation of the XPathExpression interface. - */ + /** JAXP 1.3 implementation of the XPathExpression interface. */ private static class Jaxp13XPathExpression implements XPathExpression { javax.xml.xpath.XPathExpression xpathExpression; @@ -107,7 +103,10 @@ abstract class Jaxp13XPathExpressionFactory { private Object evaluate(Node node, QName returnType) { try { - return xpathExpression.evaluate(node, returnType); + // XPathExpression is not thread-safe + synchronized (xpathExpression) { + return xpathExpression.evaluate(node, returnType); + } } catch (XPathExpressionException ex) { throw new XPathException("Could not evaluate XPath expression:" + ex.getMessage(), ex); diff --git a/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java b/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java new file mode 100644 index 00000000..65c3af11 --- /dev/null +++ b/xml/src/main/java/org/springframework/xml/xpath/XPathExpressionFactoryBean.java @@ -0,0 +1,73 @@ +/* + * Copyright 2007 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.Properties; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +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. + * + * @author Arjen Poutsma + * @see #setExpression(String) + */ +public class XPathExpressionFactoryBean implements FactoryBean, InitializingBean { + + private Properties namespaces; + + private String expressionString; + + private XPathExpression expression; + + /** Sets the XPath expression. Setting this property is required. */ + public void setExpression(String expression) { + expressionString = expression; + } + + /** Sets the namespaces for the expressions. The given properties binds string prefixes to string namespaces. */ + public void setNamespaces(Properties namespaces) { + this.namespaces = namespaces; + } + + public void afterPropertiesSet() throws IllegalStateException, XPathParseException { + Assert.notNull(expressionString, "expression is required"); + if (namespaces == null || namespaces.isEmpty()) { + expression = XPathExpressionFactory.createXPathExpression(expressionString); + } + else { + expression = XPathExpressionFactory.createXPathExpression(expressionString, namespaces); + } + } + + public Object getObject() throws Exception { + return expression; + } + + public Class getObjectType() { + return XPathExpression.class; + } + + public boolean isSingleton() { + return true; + } +} diff --git a/xml/src/test/java/org/springframework/xml/xpath/XPathExpressionFactoryBeanTest.java b/xml/src/test/java/org/springframework/xml/xpath/XPathExpressionFactoryBeanTest.java new file mode 100644 index 00000000..ed61bdde --- /dev/null +++ b/xml/src/test/java/org/springframework/xml/xpath/XPathExpressionFactoryBeanTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2007 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 junit.framework.TestCase; + +public class XPathExpressionFactoryBeanTest extends TestCase { + + private XPathExpressionFactoryBean factoryBean; + + protected void setUp() throws Exception { + factoryBean = new XPathExpressionFactoryBean(); + } + + public void testFactoryBean() throws Exception { + factoryBean.setExpression("/root"); + factoryBean.afterPropertiesSet(); + Object result = factoryBean.getObject(); + assertNotNull("No result obtained", result); + assertTrue("No XPathExpression returned", result instanceof XPathExpression); + assertTrue("Not a singleton", factoryBean.isSingleton()); + assertEquals("Not a XPathExpresison", XPathExpression.class, factoryBean.getObjectType()); + } +} \ No newline at end of file