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