diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/DefaultXmlPayloadConverter.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/DefaultXmlPayloadConverter.java
new file mode 100644
index 0000000000..ac114f8e76
--- /dev/null
+++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/DefaultXmlPayloadConverter.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2002-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.integration.xml;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.springframework.integration.message.MessagingException;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+/**
+ * Supports {@link Document} and {@link String}
+ * @author Jonas Partner
+ *
+ */
+public class DefaultXmlPayloadConverter implements XmlPayloadConverter {
+
+ private DocumentBuilderFactory documentBuilderFactory;
+
+ public DefaultXmlPayloadConverter() {
+ this.documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ this.documentBuilderFactory.setNamespaceAware(true);
+ }
+
+ public DefaultXmlPayloadConverter(DocumentBuilderFactory documentBuilderFactory) {
+ this.documentBuilderFactory = documentBuilderFactory;
+ }
+
+ public Document convertToDocument(Object object) {
+ Document doc;
+ if (object instanceof Document) {
+ doc = (Document) object;
+ }
+ else if (object instanceof String) {
+ try {
+ doc = getDocumentBuilder().parse(new InputSource(new StringReader((String) object)));
+ }
+ catch (Exception e) {
+ throw new MessagingException("Failed to parse String payload " + object, e);
+ }
+ }
+ else {
+ throw new MessagingException("Unsupported payload type " + object.getClass().getName());
+ }
+ return doc;
+ }
+
+ protected synchronized DocumentBuilder getDocumentBuilder() {
+ try {
+ return this.documentBuilderFactory.newDocumentBuilder();
+ }
+ catch (ParserConfigurationException e) {
+ throw new MessagingException("Failed to create a new DocumentBuilder", e);
+ }
+ }
+
+}
diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/XmlPayloadConverter.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/XmlPayloadConverter.java
new file mode 100644
index 0000000000..690fc748da
--- /dev/null
+++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/XmlPayloadConverter.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2002-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.integration.xml;
+
+import org.w3c.dom.Document;
+
+
+/**
+ * Converter for creating XML {@link Document} instances
+ * @author Jonas Partner
+ *
+ */
+public interface XmlPayloadConverter {
+
+ public Document convertToDocument(Object object);
+
+}
diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolver.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolver.java
index 30d86bb8da..a1f9cb9356 100644
--- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolver.java
+++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolver.java
@@ -18,15 +18,15 @@ package org.springframework.integration.xml.router;
import java.util.List;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Node;
-
import org.springframework.integration.message.Message;
import org.springframework.integration.router.AbstractMultiChannelNameResolver;
-import org.springframework.integration.xml.util.XPathUtils;
+import org.springframework.integration.xml.DefaultXmlPayloadConverter;
+import org.springframework.integration.xml.XmlPayloadConverter;
import org.springframework.util.Assert;
import org.springframework.xml.xpath.NodeMapper;
import org.springframework.xml.xpath.XPathExpression;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
/**
* @author Jonas Partner
@@ -35,15 +35,15 @@ public class XPathMultiChannelNameResolver extends AbstractMultiChannelNameResol
private final XPathExpression xPathExpression;
- private volatile NodeMapper nodeMapper = new TextContentNodeMapper();
+ private volatile XmlPayloadConverter payloadConvertor = new DefaultXmlPayloadConverter();
+ private volatile NodeMapper nodeMapper = new TextContentNodeMapper();
public XPathMultiChannelNameResolver(XPathExpression xPathExpression) {
Assert.notNull("XPathExpression must not be null");
this.xPathExpression = xPathExpression;
}
-
public void setNodeMapper(NodeMapper nodeMapper) {
Assert.notNull(nodeMapper, "NodeMapper must not be null");
this.nodeMapper = nodeMapper;
@@ -51,11 +51,15 @@ public class XPathMultiChannelNameResolver extends AbstractMultiChannelNameResol
@SuppressWarnings("unchecked")
public String[] resolveChannelNames(Message> message) {
- Node node = XPathUtils.extractPayloadAsNode(message);
+ Node node = payloadConvertor.convertToDocument(message.getPayload());
List channelNamesList = this.xPathExpression.evaluate(node, this.nodeMapper);
return (String[]) channelNamesList.toArray(new String[channelNamesList.size()]);
}
+ public void setPayloadConvertor(XmlPayloadConverter payloadConvertor) {
+ this.payloadConvertor = payloadConvertor;
+ }
+
private static class TextContentNodeMapper implements NodeMapper {
public Object mapNode(Node node, int nodeNum) throws DOMException {
diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolver.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolver.java
index 39a67ddfc9..0e864e5743 100644
--- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolver.java
+++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolver.java
@@ -16,13 +16,13 @@
package org.springframework.integration.xml.router;
-import org.w3c.dom.Node;
-
import org.springframework.integration.message.Message;
import org.springframework.integration.router.AbstractSingleChannelNameResolver;
-import org.springframework.integration.xml.util.XPathUtils;
+import org.springframework.integration.xml.DefaultXmlPayloadConverter;
+import org.springframework.integration.xml.XmlPayloadConverter;
import org.springframework.util.Assert;
import org.springframework.xml.xpath.XPathExpression;
+import org.w3c.dom.Node;
/**
* @author Jonas Partner
@@ -31,6 +31,7 @@ public class XPathSingleChannelNameResolver extends AbstractSingleChannelNameRes
private final XPathExpression xPathExpression;
+ private volatile XmlPayloadConverter payloadConvertor = new DefaultXmlPayloadConverter();
public XPathSingleChannelNameResolver(XPathExpression xPathExpression) {
Assert.notNull("XPathExpression must be provided");
@@ -38,8 +39,12 @@ public class XPathSingleChannelNameResolver extends AbstractSingleChannelNameRes
}
public String resolveChannelName(Message> message) {
- Node node = XPathUtils.extractPayloadAsNode(message);
+ Node node = payloadConvertor.convertToDocument(message.getPayload());
return xPathExpression.evaluateAsString(node);
}
+ public void setPayloadConvertor(XmlPayloadConverter payloadConvertor) {
+ this.payloadConvertor = payloadConvertor;
+ }
+
}
diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/util/XPathUtils.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/util/XPathUtils.java
deleted file mode 100644
index 4560f3ee3b..0000000000
--- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/util/XPathUtils.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2002-2008 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.integration.xml.util;
-
-import org.w3c.dom.Node;
-
-import org.springframework.integration.message.Message;
-import org.springframework.integration.message.MessagingException;
-
-/**
- * @author Jonas Partner
- * @author Mark Fisher
- */
-public abstract class XPathUtils {
-
- /**
- * Return the given Message's payload as a Node if possible, else an Exception will be thrown.
- */
- public static Node extractPayloadAsNode(Message> message) {
- if (!Node.class.isAssignableFrom(message.getPayload().getClass())) {
- throw new MessagingException(message, "payload is not assignable to [" + Node.class.getName() + "] so can not be evaluated");
- }
- return (Node) message.getPayload();
- }
-
-}
diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/DefaultXmlPayloadConverterTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/DefaultXmlPayloadConverterTests.java
new file mode 100644
index 0000000000..682e4babcb
--- /dev/null
+++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/DefaultXmlPayloadConverterTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2002-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.integration.xml;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.Assert;
+
+import org.custommonkey.xmlunit.XMLAssert;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+public class DefaultXmlPayloadConverterTests {
+
+ DefaultXmlPayloadConverter converter;
+
+ Document testDocument;
+
+ String testDocumentAsString = "hello";
+
+ @Before
+ public void setUp() throws Exception{
+ converter = new DefaultXmlPayloadConverter();
+ testDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+ new InputSource(new StringReader(testDocumentAsString)));
+ }
+
+ @Test
+ public void testWithString() {
+ Document doc = converter.convertToDocument("hello");
+ XMLAssert.assertXMLEqual(testDocument, doc);
+ }
+
+ @Test
+ public void testWithDocument() {
+ Document doc = converter.convertToDocument(testDocument);
+ Assert.assertTrue(doc == testDocument);
+ }
+
+}
diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolverTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolverTests.java
index 8a738dc09e..9d95e6a3ca 100644
--- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolverTests.java
+++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathMultiChannelNameResolverTests.java
@@ -19,15 +19,13 @@ package org.springframework.integration.xml.router;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
-import org.w3c.dom.Document;
-
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.message.StringMessage;
-import org.springframework.integration.xml.router.XPathMultiChannelNameResolver;
import org.springframework.integration.xml.util.XmlTestUtil;
import org.springframework.xml.xpath.XPathExpression;
import org.springframework.xml.xpath.XPathExpressionFactory;
+import org.w3c.dom.Document;
/**
* @author Jonas Partner
@@ -56,6 +54,17 @@ public class XPathMultiChannelNameResolverTests {
assertEquals("Wrong channel name", "bOne", channelNames[0]);
assertEquals("Wrong channel name", "bTwo", channelNames[1]);
}
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testMultipleNodeValuesAsString() throws Exception {
+ XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/book");
+ XPathMultiChannelNameResolver resolver = new XPathMultiChannelNameResolver(expression);
+ String[] channelNames = resolver.resolveChannelNames(new GenericMessage("bOnebTwo"));
+ assertEquals("Wrong number of channels returend", 2, channelNames.length);
+ assertEquals("Wrong channel name", "bOne", channelNames[0]);
+ assertEquals("Wrong channel name", "bTwo", channelNames[1]);
+ }
@Test(expected = MessagingException.class)
public void testNonNodePayload() throws Exception {
diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolverTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolverTests.java
index 4a12621d7e..bbb433f787 100644
--- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolverTests.java
+++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/router/XPathSingleChannelNameResolverTests.java
@@ -36,12 +36,22 @@ public class XPathSingleChannelNameResolverTests {
@Test
@SuppressWarnings("unchecked")
public void testSimpleDocType() throws Exception {
- Document doc = XmlTestUtil.getDocumentForString("");
+ Document doc = XmlTestUtil.getDocumentForString("");
XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type");
XPathSingleChannelNameResolver resolver = new XPathSingleChannelNameResolver(expression);
String channelName = resolver.resolveChannelName(new GenericMessage(doc));
assertEquals("Wrong channel name", "one", channelName);
}
+
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testSimpleStringDoc() throws Exception {
+ XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type");
+ XPathSingleChannelNameResolver resolver = new XPathSingleChannelNameResolver(expression);
+ String channelName = resolver.resolveChannelName(new GenericMessage(""));
+ assertEquals("Wrong channel name", "one", channelName);
+ }
@Test(expected = MessagingException.class)
public void testNonNodePayload() throws Exception {