diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/DomResultFactory.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/DomResultFactory.java new file mode 100644 index 0000000000..e341c688a7 --- /dev/null +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/DomResultFactory.java @@ -0,0 +1,35 @@ +/* + * 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.result; + +import javax.xml.transform.Result; +import javax.xml.transform.dom.DOMResult; + +import org.springframework.integration.message.Message; + +/** + * + * @author Jonas Partner + * + */ +public class DomResultFactory implements ResultFactory { + + public Result getNewResult(Message message) { + return new DOMResult(); + } + +} diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/ResultFactory.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/ResultFactory.java new file mode 100644 index 0000000000..5e5d121010 --- /dev/null +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/ResultFactory.java @@ -0,0 +1,33 @@ +/* + * 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.result; + +import javax.xml.transform.Result; + +import org.springframework.integration.message.Message; + +/** + * Factory to create {@link ResultFactory} possibly taking into account the + * passed {@link Message} instance + * @author Jonas Partner + * + */ +public interface ResultFactory { + + Result getNewResult(Message message); + +} diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/StringResultFactory.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/StringResultFactory.java new file mode 100644 index 0000000000..b7f8e65cf5 --- /dev/null +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/result/StringResultFactory.java @@ -0,0 +1,35 @@ +/* + * 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.result; + +import javax.xml.transform.Result; + +import org.springframework.integration.message.Message; +import org.springframework.xml.transform.StringResult; + +/** + * + * @author Jonas Partner + * + */ +public class StringResultFactory implements ResultFactory { + + public Result getNewResult(Message message) { + return new StringResult(); + } + +} 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 new file mode 100644 index 0000000000..e2161db652 --- /dev/null +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/source/SourceFactory.java @@ -0,0 +1,33 @@ +/* + * 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.source; + +import javax.xml.transform.Source; + +import org.springframework.integration.message.Message; + +/** + * Factory to create instances of {@link Source} possibly taking into account + * the contents of the passed {@link Message} + * @author Jonas Partner + * + */ +public interface SourceFactory { + + Source getSourceForMessage(Message message); + +} 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 71c2921b61..7fbb0a7048 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 @@ -19,21 +19,19 @@ package org.springframework.integration.xml.transformer; import java.io.IOException; import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.dom.DOMResult; - -import org.w3c.dom.Document; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageHandlingException; import org.springframework.integration.transformer.MessageTransformer; +import org.springframework.integration.xml.result.DomResultFactory; +import org.springframework.integration.xml.result.ResultFactory; import org.springframework.oxm.Marshaller; import org.springframework.oxm.Unmarshaller; -import org.springframework.xml.transform.StringResult; +import org.springframework.util.Assert; /** - * An implementation of {@link MessageTransformer} that delegates to an - * OXM {@link Marshaller} and/or {@link Unmarshaller}. + * An implementation of {@link MessageTransformer} that delegates to an OXM + * {@link Marshaller} * * @author Mark Fisher */ @@ -41,68 +39,37 @@ public class XmlPayloadMarshallingTransformer implements MessageTransformer { private final Marshaller marshaller; - private final Unmarshaller unmarshaller; - - - public XmlPayloadMarshallingTransformer(Marshaller marshaller, Unmarshaller unmarshaller) { - this.marshaller = marshaller; - this.unmarshaller = unmarshaller; - } + private ResultFactory resultFactory = new DomResultFactory(); public XmlPayloadMarshallingTransformer(Marshaller marshaller) { + Assert.notNull(marshaller, " a marshaller is required"); this.marshaller = marshaller; - this.unmarshaller = (marshaller != null && marshaller instanceof Unmarshaller) ? - (Unmarshaller) marshaller : null; } + public void setResultFactory(ResultFactory resultFactory) { + this.resultFactory = resultFactory; + } @SuppressWarnings("unchecked") public void transform(Message message) { Object transformedPayload = null; Object originalPayload = message.getPayload(); - if (originalPayload instanceof Source) { - if (this.unmarshaller == null) { - throw new MessageHandlingException(message, "no Unmarshaller available"); - } - try { - transformedPayload = this.unmarshaller.unmarshal((Source) originalPayload); - } - catch (IOException e) { - throw new MessageHandlingException(message, "failed to unmarshal payload", e); - } + Result result = this.resultFactory.getNewResult(message); + if (result == null) { + throw new MessageHandlingException(message, "Unable to marshall payload, ResultFactory returned null"); } - else { - if (this.marshaller == null) { - throw new MessageHandlingException(message, "no Marshaller available"); - } - Result result = this.createResult(originalPayload); - if (result == null) { - throw new MessageHandlingException(message, "Unable to marshal payload; expected [" - + String.class.getName() + "] or [" + Document.class.getName() + "] but received [" - + originalPayload.getClass().getName() + "]."); - } - try { - this.marshaller.marshal(originalPayload, result); - transformedPayload = result; - } - catch (IOException e) { - throw new MessageHandlingException(message, "failed to marshal payload", e); - } + try { + this.marshaller.marshal(originalPayload, result); + transformedPayload = result; } + catch (IOException e) { + throw new MessageHandlingException(message, "failed to marshal payload", e); + } + if (transformedPayload == null) { throw new MessageHandlingException(message, "failed to transform payload"); } message.setPayload(transformedPayload); } - protected Result createResult(Object objectToMarshal) { - if (objectToMarshal instanceof String) { - return new StringResult(); - } - if (objectToMarshal instanceof Document) { - return new DOMResult(); - } - return null; - } - } diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadUnmarshallingTransfomer.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadUnmarshallingTransfomer.java new file mode 100644 index 0000000000..073d72d745 --- /dev/null +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XmlPayloadUnmarshallingTransfomer.java @@ -0,0 +1,74 @@ +/* + * 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.transformer; + +import java.io.IOException; + +import javax.xml.transform.Source; + +import org.springframework.integration.message.Message; +import org.springframework.integration.message.MessagingException; +import org.springframework.integration.transformer.MessageTransformer; +import org.springframework.integration.xml.source.SourceFactory; +import org.springframework.oxm.Unmarshaller; + +/** + * An implementation of {@link MessageTransformer} that delegates to an OXM + * {@link Unmarshaller} + * + * @author Jonas Partner + */ +public class XmlPayloadUnmarshallingTransfomer implements MessageTransformer { + + private final Unmarshaller unmarshaller; + + private SourceFactory sourceFactory; + + public XmlPayloadUnmarshallingTransfomer(Unmarshaller unmarshaller) { + this.unmarshaller = unmarshaller; + } + + public void setSourceFactory(SourceFactory sourceFactory) { + this.sourceFactory = sourceFactory; + } + + @SuppressWarnings("unchecked") + public void transform(Message message) { + Source source = null; + if (Source.class.isAssignableFrom(message.getPayload().getClass())) { + source = (Source) message.getPayload(); + } + else if (sourceFactory != null) { + source = sourceFactory.getSourceForMessage(message); + } + + if (source == null) { + throw new MessagingException(message, + "Could not transform message payload not assignable from javax.xml.transform.Source and no conversion possible"); + } + + Object unmarshalled; + try { + unmarshalled = unmarshaller.unmarshal(source); + } + catch (IOException ioE) { + throw new MessagingException(message, "Exception unamrshalling payload", ioE); + } + message.setPayload(unmarshalled); + } + +} diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java index acd37efb48..7050c37c24 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/transformer/XsltPayloadTransformer.java @@ -43,17 +43,14 @@ public class XsltPayloadTransformer implements MessageTransformer { private final Templates templates; - public XsltPayloadTransformer(Templates templates) { this.templates = templates; } - public XsltPayloadTransformer(Resource xslResource) throws Exception { this.templates = TransformerFactory.newInstance().newTemplates(new StreamSource(xslResource.getInputStream())); } - @SuppressWarnings("unchecked") public void transform(Message message) { try { @@ -67,8 +64,8 @@ public class XsltPayloadTransformer implements MessageTransformer { this.transformString(message); } else { - throw new MessagingException(message, - "Unsupported payload type for transformation: " + message.getPayload().getClass().getName()); + throw new MessagingException(message, "Unsupported payload type for transformation: " + + message.getPayload().getClass().getName()); } } catch (TransformerException e) { @@ -92,7 +89,7 @@ public class XsltPayloadTransformer implements MessageTransformer { @SuppressWarnings("unchecked") protected void transformDocument(Message message) throws TransformerException { - Document doc = (Document)message.getPayload(); + Document doc = (Document) message.getPayload(); DOMResult result = new DOMResult(); this.templates.newTransformer().transform(new DOMSource(doc), result); message.setPayload(result.getNode()); diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformerTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformerTests.java index 2e304efbd4..abb39792c6 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformerTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadMarshallingTransformerTests.java @@ -19,20 +19,19 @@ package org.springframework.integration.xml.transformer; import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import javax.xml.transform.Result; -import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; import org.junit.Test; - -import org.springframework.integration.message.GenericMessage; import org.springframework.integration.message.Message; import org.springframework.integration.message.StringMessage; +import org.springframework.integration.xml.result.StringResultFactory; import org.springframework.oxm.Marshaller; -import org.springframework.oxm.Unmarshaller; import org.springframework.oxm.XmlMappingException; import org.springframework.xml.transform.StringResult; -import org.springframework.xml.transform.StringSource; /** * @author Mark Fisher @@ -41,26 +40,29 @@ public class XmlPayloadMarshallingTransformerTests { @Test public void testStringToStringResult() { - Marshaller marshaller = new TestMarshaller(); + TestMarshaller marshaller = new TestMarshaller(); XmlPayloadMarshallingTransformer transformer = new XmlPayloadMarshallingTransformer(marshaller); + transformer.setResultFactory(new StringResultFactory()); Message message = new StringMessage("world"); transformer.transform(message); assertEquals(StringResult.class, message.getPayload().getClass()); assertEquals("hello world", message.getPayload().toString()); + assertEquals("world", marshaller.payloads.get(0)); } @Test - public void testStringSourceToString() { - Marshaller marshaller = new TestMarshaller(); + public void testDefaultResultFactory() { + TestMarshaller marshaller = new TestMarshaller(); XmlPayloadMarshallingTransformer transformer = new XmlPayloadMarshallingTransformer(marshaller); - Message message = new GenericMessage(new StringSource("world")); + Message message = new StringMessage("world"); transformer.transform(message); - assertEquals(String.class, message.getPayload().getClass()); - assertEquals("hello world", message.getPayload().toString()); + assertEquals(DOMResult.class, message.getPayload().getClass()); + assertEquals("world", marshaller.payloads.get(0)); } + private static class TestMarshaller implements Marshaller { - private static class TestMarshaller implements Marshaller, Unmarshaller { + List payloads = new ArrayList(); @SuppressWarnings("unchecked") public boolean supports(Class clazz) { @@ -68,19 +70,13 @@ public class XmlPayloadMarshallingTransformerTests { } public void marshal(Object originalPayload, Result result) throws XmlMappingException, IOException { + payloads.add(originalPayload); if (result instanceof StringResult) { - ((StringResult) result).getWriter().write("hello " + originalPayload); + ((StringResult) result).getWriter().write("hello world"); } + } - public Object unmarshal(Source source) throws XmlMappingException, IOException { - if (source instanceof StringSource) { - char[] chars = new char[8]; - ((StringSource) source).getReader().read(chars); - return "hello " + new String(chars).trim(); - } - return null; - } } } diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadUnmarshallingTransfomerTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadUnmarshallingTransfomerTests.java new file mode 100644 index 0000000000..c27085102d --- /dev/null +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/transformer/XmlPayloadUnmarshallingTransfomerTests.java @@ -0,0 +1,65 @@ +/* + * 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.transformer; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import javax.xml.transform.Source; + +import org.junit.Test; +import org.springframework.integration.message.GenericMessage; +import org.springframework.integration.message.Message; +import org.springframework.oxm.Unmarshaller; +import org.springframework.oxm.XmlMappingException; +import org.springframework.xml.transform.StringSource; + +/** + * + * @author Jonas Partner + * + */ +public class XmlPayloadUnmarshallingTransfomerTests { + + @Test + public void testStringSourceToString() { + Unmarshaller unmarshaller = new TestUnmarshaller(); + XmlPayloadUnmarshallingTransfomer transformer = new XmlPayloadUnmarshallingTransfomer(unmarshaller); + Message message = new GenericMessage(new StringSource("world")); + transformer.transform(message); + assertEquals(String.class, message.getPayload().getClass()); + assertEquals("hello world", message.getPayload().toString()); + } + + private static class TestUnmarshaller implements Unmarshaller { + public Object unmarshal(Source source) throws XmlMappingException, IOException { + if (source instanceof StringSource) { + char[] chars = new char[8]; + ((StringSource) source).getReader().read(chars); + return "hello " + new String(chars).trim(); + } + return null; + } + + @SuppressWarnings("unchecked") + public boolean supports(Class clazz) { + return true; + } + } + +} 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 0e270d9b9f..ceff9495f6 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 @@ -38,35 +38,36 @@ import org.xml.sax.InputSource; /** * * @author Jonas Partner - * + * */ public class XsltPayloadTransformerTest { XsltPayloadTransformer transformer; - + @Before - public void setUp() throws Exception{ + public void setUp() throws Exception { transformer = new XsltPayloadTransformer(getXslResource()); } - + @Test public void testDocumentAsPayload() throws Exception { Document input = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new InputSource(new StringReader(getInputString()))); GenericMessage documentMessage = new GenericMessage(input); transformer.transform(documentMessage); - String rootNodeName = ((Document)documentMessage.getPayload()).getDocumentElement().getNodeName(); + String rootNodeName = ((Document) documentMessage.getPayload()).getDocumentElement().getNodeName(); assertEquals("Wrong name for root element after transform", "bob", rootNodeName); } - + @Test public void testXmlAsStringPayload() throws Exception { StringMessage message = new StringMessage(getInputString()); transformer.transform(message); - String rootNodeName = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(message.getPayload()))).getDocumentElement().getNodeName(); + String rootNodeName = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( + new InputSource(new StringReader(message.getPayload()))).getDocumentElement().getNodeName(); assertEquals("Wrong name for root element after transform", "bob", rootNodeName); } - + @Test public void testSourceAsPayload() throws Exception { GenericMessage message = new GenericMessage(new StringSource(getInputString())); @@ -74,29 +75,25 @@ public class XsltPayloadTransformerTest { DOMResult result = new DOMResult(); TransformerFactory.newInstance().newTransformer().transform(message.getPayload(), result); - String rootNodeName = ((Document)result.getNode()).getDocumentElement().getNodeName(); + String rootNodeName = ((Document) result.getNode()).getDocumentElement().getNodeName(); assertEquals("Wrong name for root element after transform", "bob", rootNodeName); } - + @Test(expected = MessagingException.class) public void testNonXmlString() throws Exception { transformer.transform(new StringMessage("test")); } - + @Test(expected = MessagingException.class) public void testUnsupportedPayloadType() throws Exception { transformer.transform(new GenericMessage(new Long(12))); } - - - - public String getInputString() { return "test"; } - public Resource getXslResource() throws Exception{ + public Resource getXslResource() throws Exception { String xsl = "test"; return new ByteArrayResource(xsl.getBytes("UTF-8")); }