From 6c76f5b3bd4070b6040bd96ad4af02c43062db92 Mon Sep 17 00:00:00 2001 From: Jonas Partner Date: Tue, 19 Aug 2008 12:33:46 +0000 Subject: [PATCH] modified unmarshalling transformer to support payloads consistently with xslt transformer INT-311 --- .../XmlMarshallingTransformerParser.java | 6 ++ .../config/XsltPayloadTransformerParser.java | 6 ++ .../xml/config/spring-integration-xml-1.0.xsd | 2 + .../xml/source/DomSourceFactory.java | 21 ++--- .../integration/xml/source/SourceFactory.java | 5 ++ .../xml/source/StringSourceFactory.java | 22 ++++-- .../XmlPayloadMarshallingTransformer.java | 24 ++++-- .../XmlPayloadUnmarshallingTransformer.java | 59 ++++++++++---- .../transformer/XsltPayloadTransformer.java | 79 +++++++++++++------ .../xml/config/StubResultTransformer.java | 34 ++++++++ ...shallingTransformerParserTests-context.xml | 13 ++- .../XmlMarshallingTransformerParserTests.java | 10 +++ ...mlUnmarshallingTransformerParserTests.java | 2 +- ...tPayloadTransformerParserTests-context.xml | 11 +++ .../XsltPayloadTransformerParserTests.java | 14 +++- .../XsltPayloadTransformerTest.java | 3 +- 16 files changed, 241 insertions(+), 70 deletions(-) create mode 100644 org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/StubResultTransformer.java diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParser.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParser.java index c0cd5f3c55..e6d26c5950 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParser.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParser.java @@ -26,6 +26,7 @@ import org.springframework.integration.xml.result.DomResultFactory; import org.springframework.integration.xml.result.StringResultFactory; import org.springframework.integration.xml.transformer.XmlPayloadMarshallingTransformer; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** @@ -45,10 +46,15 @@ public class XmlMarshallingTransformerParser extends ParserContext parserContext, BeanDefinitionBuilder builder) { String resultFactory = element.getAttribute("result-factory"); String marshaller = element.getAttribute("marshaller"); + String resultTransformer = element.getAttribute("result-transformer"); + Assert.hasText(marshaller, "the 'marshaller' attribute is required"); Assert.hasText(resultFactory, "the 'result-factory' attribute is required"); builder.addConstructorArgReference(marshaller); + if(StringUtils.hasText(resultTransformer)){ + builder.addConstructorArgReference(resultTransformer); + } if (resultFactory.equals("DOMResult")) { try { diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java index 514e2284a3..0a65f868ae 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/XsltPayloadTransformerParser.java @@ -41,6 +41,8 @@ public class XsltPayloadTransformerParser extends AbstractPayloadTransformerPars protected void parsePayloadTransformer(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String xslResource = element.getAttribute("xsl-resource"); String xslTemplates = element.getAttribute("xsl-templates"); + String resultTransformer = element.getAttribute("result-transformer"); + boolean bothHaveText = StringUtils.hasText(xslResource) && StringUtils.hasText(xslTemplates); boolean oneHasText = StringUtils.hasText(xslResource) || StringUtils.hasText(xslTemplates); Assert.state(!bothHaveText && oneHasText, @@ -61,6 +63,10 @@ public class XsltPayloadTransformerParser extends AbstractPayloadTransformerPars if (StringUtils.hasText(resultFactory)) { builder.addPropertyReference("resultFactory", resultFactory); } + + if(StringUtils.hasText(resultTransformer)){ + builder.addConstructorArgReference(resultTransformer); + } } } diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/spring-integration-xml-1.0.xsd b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/spring-integration-xml-1.0.xsd index 1014a9d517..1c7b60e2cb 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/spring-integration-xml-1.0.xsd +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/config/spring-integration-xml-1.0.xsd @@ -36,6 +36,7 @@ + @@ -69,6 +70,7 @@ use="optional" /> + diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java index 310613d29d..cdbda46930 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/DomSourceFactory.java @@ -22,11 +22,10 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; +import org.springframework.integration.message.MessagingException; import org.w3c.dom.Document; import org.xml.sax.InputSource; -import org.springframework.integration.message.MessagingException; - /** * {@link SourceFactory} implementation which supports creation of a * {@link DOMSource} from a {@link Document} or {@link String} payload. @@ -38,7 +37,6 @@ public class DomSourceFactory implements SourceFactory { private final DocumentBuilderFactory docBuilderFactory; - public DomSourceFactory() { this.docBuilderFactory = DocumentBuilderFactory.newInstance(); } @@ -49,14 +47,19 @@ public class DomSourceFactory implements SourceFactory { public Source createSource(Object payload) { - if (Document.class.isAssignableFrom(payload.getClass())) { - return createDomSourceForDocument((Document) payload); + Source source = null; + if (payload instanceof Document) { + source = createDomSourceForDocument((Document) payload); } else if (payload instanceof String) { - return createDomSourceForString((String) payload); + source = createDomSourceForString((String) payload); } + + if(source == null){ throw new MessagingException("Failed to create Source for payload type [" + payload.getClass().getName() + "]"); + } + return source; } protected DOMSource createDomSourceForDocument(Document document) { @@ -66,11 +69,11 @@ public class DomSourceFactory implements SourceFactory { protected DOMSource createDomSourceForString(String s) { try { - Document doc = docBuilderFactory.newDocumentBuilder().parse(new InputSource(new StringReader(s))); + Document doc = docBuilderFactory.newDocumentBuilder().parse( + new InputSource(new StringReader(s))); DOMSource source = new DOMSource(doc.getDocumentElement()); return source; - } - catch (Exception e) { + } catch (Exception e) { throw new MessagingException("Exception creating DOMSource", e); } } diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/SourceFactory.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/SourceFactory.java index 9acf501a02..75a93e54de 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/SourceFactory.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/SourceFactory.java @@ -26,6 +26,11 @@ import javax.xml.transform.Source; */ public interface SourceFactory { + /** + * Create appropriate {@link Source} instance for payload + * @param payload + * @return + */ Source createSource(Object payload); } diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/StringSourceFactory.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/StringSourceFactory.java index e80395f961..bb544cefaf 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/StringSourceFactory.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/StringSourceFactory.java @@ -26,9 +26,11 @@ import org.springframework.xml.transform.StringSource; import org.w3c.dom.Document; /** + * {@link SourceFactory} implementation which supports creation of a + * {@link StringSource} from either a {@link Document} or {@link String} payload * * @author Jonas Partner - * + * */ public class StringSourceFactory implements SourceFactory { @@ -43,14 +45,20 @@ public class StringSourceFactory implements SourceFactory { } public Source createSource(Object payload) { - if (Document.class.isAssignableFrom(payload.getClass())) { - return createStringSourceForDocument((Document) payload); + Source source = null; + if (payload instanceof Document) { + source = createStringSourceForDocument((Document) payload); } else if (payload instanceof String) { - return new StringSource((String) payload); + source = new StringSource((String) payload); } - throw new MessagingException( - "Failed to create Source for payload type [" - + payload.getClass().getName() + "]"); + + if (source == null) { + throw new MessagingException( + "Failed to create Source for payload type [" + + payload.getClass().getName() + "]"); + } + return source; + } protected StringSource createStringSourceForDocument(Document doc) { diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformer.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformer.java index de2853401b..b9159240a1 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformer.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformer.java @@ -35,19 +35,27 @@ import org.springframework.util.Assert; * @author Mark Fisher * @author Jonas Partner */ -public class XmlPayloadMarshallingTransformer implements PayloadTransformer { +public class XmlPayloadMarshallingTransformer implements + PayloadTransformer { private final Marshaller marshaller; - private ResultFactory resultFactory = new DomResultFactory(); + private volatile ResultFactory resultFactory; + private final ResultTransformer resultTransformer; - public XmlPayloadMarshallingTransformer(Marshaller marshaller) throws ParserConfigurationException { + public XmlPayloadMarshallingTransformer(Marshaller marshaller, + ResultTransformer resultTransformer) throws ParserConfigurationException { Assert.notNull(marshaller, "a marshaller is required"); this.marshaller = marshaller; + this.resultTransformer = resultTransformer; resultFactory = new DomResultFactory(); } + public XmlPayloadMarshallingTransformer(Marshaller marshaller) + throws ParserConfigurationException { + this(marshaller, null); + } public void setResultFactory(ResultFactory resultFactory) { Assert.notNull(resultFactory, "ResultFactory must not be null"); @@ -58,18 +66,22 @@ public class XmlPayloadMarshallingTransformer implements PayloadTransformer { +public class XmlPayloadUnmarshallingTransformer implements + PayloadTransformer { + + private volatile boolean alwaysUseSourceFactory = false; private final Unmarshaller unmarshaller; - - private SourceFactory sourceFactory = new DomSourceFactory(); - + + private volatile SourceFactory sourceFactory = new DomSourceFactory(); public XmlPayloadUnmarshallingTransformer(Unmarshaller unmarshaller) { this.unmarshaller = unmarshaller; } - - public void setSourceFactory(SourceFactory sourceFactory) { - this.sourceFactory = sourceFactory; - } - public Object transform(Object payload) { Source source = null; - if (Source.class.isAssignableFrom(payload.getClass())) { + if (alwaysUseSourceFactory) { + source = sourceFactory.createSource(payload); + } else if (payload instanceof String) { + source = new StringSource((String) payload); + } else if (payload instanceof Document) { + source = new DOMSource((Document) payload); + } else if (payload instanceof Source) { source = (Source) payload; - } - else if (this.sourceFactory != null) { + } else { source = this.sourceFactory.createSource(payload); } @@ -66,10 +75,26 @@ public class XmlPayloadUnmarshallingTransformer implements PayloadTransformer + + + - + + + + + + diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParserTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParserTests.java index 607e2e6e31..c842799862 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParserTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlMarshallingTransformerParserTests.java @@ -56,6 +56,16 @@ public class XmlMarshallingTransformerParserTests { Document doc = (Document) ((DOMResult) result.getPayload()).getNode(); assertEquals("Wrong palyoad", "hello", doc.getDocumentElement().getTextContent()); } + + @Test + public void testDefaultWithResultTransformer() throws Exception { + MessageHandler transformer = (MessageHandler) appContext.getBean("marshallingTransfomerWithResultTransformer"); + GenericMessage message = new GenericMessage("hello"); + Message result = transformer.handle(message); + assertTrue("Wrong payload type", result.getPayload() instanceof String); + String resultPayload = (String)result.getPayload(); + assertEquals("Wrong palyoad", "testReturn", resultPayload); + } @Test public void testDOMResult() throws Exception { diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlUnmarshallingTransformerParserTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlUnmarshallingTransformerParserTests.java index 2bad7ec5c4..c4f5b357b7 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlUnmarshallingTransformerParserTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XmlUnmarshallingTransformerParserTests.java @@ -68,7 +68,7 @@ public class XmlUnmarshallingTransformerParserTests { "test"); Message result = transformer.handle(message); assertEquals("Wrong payload after unmarshalling", "unmarshalled", result.getPayload()); - assertTrue("Wrong source passed to unmarshaller", unmarshaller.sourcesPassed.poll() instanceof DOMSource); + assertTrue("Wrong source passed to unmarshaller", unmarshaller.sourcesPassed.poll() instanceof StringSource); } @Test diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests-context.xml b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests-context.xml index 8c8a15391c..361492d143 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests-context.xml +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests-context.xml @@ -12,7 +12,18 @@ + + + + + + + + + diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests.java index d9edce1da3..acf9e4f456 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/config/XsltPayloadTransformerParserTests.java @@ -70,5 +70,17 @@ public class XsltPayloadTransformerParserTests { Document doc = (Document) ((DOMResult) result.getPayload()).getNode(); assertEquals("Wrong payload", "test", doc.getDocumentElement().getTextContent()); } - + + @Test + public void testWithTemplatesAndResultTransformer() throws Exception { + MessageHandler messageTransformer = (MessageHandler) applicationContext + .getBean("xsltTransformerWithTemplatesAndResultTransformer"); + GenericMessage message = new GenericMessage(XmlTestUtil.getDomSourceForString(doc)); + Message result = messageTransformer.handle(message); + + assertEquals("Wrong payload type", String.class, result.getPayload().getClass()); + String strResult = (String)result.getPayload(); + assertEquals("Wrong payload", "testReturn", strResult); + } + } diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTest.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTest.java index 859b6aca9a..482caa9909 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTest.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XsltPayloadTransformerTest.java @@ -97,8 +97,7 @@ public class XsltPayloadTransformerTest { @Test public void testSourceWithResultTransformer() throws Exception { Integer returnValue = new Integer(13); - transformer - .setResultTransformer(new StubResultTransformer(returnValue)); + transformer = new XsltPayloadTransformer(getXslResource(), new StubResultTransformer(returnValue)); Object transformed = transformer .transform(new StringSource(docAsString)); assertEquals("Wrong value from result conversion", returnValue,