diff --git a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/splitter/XPathMessageSplitter.java b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/splitter/XPathMessageSplitter.java index 86d48c3fc4..4327e4eac4 100644 --- a/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/splitter/XPathMessageSplitter.java +++ b/org.springframework.integration.xml/src/main/java/org/springframework/integration/xml/splitter/XPathMessageSplitter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * 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. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.xml.splitter; import java.util.ArrayList; @@ -29,26 +30,30 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + import org.springframework.integration.message.Message; import org.springframework.integration.message.MessagingException; -import org.springframework.integration.splitter.AbstractSplitter; +import org.springframework.integration.splitter.AbstractMessageSplitter; import org.springframework.integration.xml.DefaultXmlPayloadConverter; import org.springframework.integration.xml.XmlPayloadConverter; import org.springframework.util.Assert; import org.springframework.xml.transform.StringResult; import org.springframework.xml.xpath.XPathExpression; import org.springframework.xml.xpath.XPathExpressionFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; /** - * Use {@link XPathExpression} to split a {@link Document} or {@link String} - * payload into a {@link NodeList} each {@link Node} is then - * @author Jonas Partner + * Message Splitter that uses an {@link XPathExpression} to split a + * {@link Document} or {@link String} payload into a {@link NodeList}. The + * return value will be either Strings or {@link Node}s depending on the + * received payload type. Additionally, node types will be converted to + * Documents if the 'createDocuments' property is set to true. * + * @author Jonas Partner */ -public class XPathMessageSplitter extends AbstractSplitter { +public class XPathMessageSplitter extends AbstractMessageSplitter { private final XPathExpression xpathExpression; @@ -58,6 +63,7 @@ public class XPathMessageSplitter extends AbstractSplitter { private volatile XmlPayloadConverter xmlPayloadConverter = new DefaultXmlPayloadConverter(); + public XPathMessageSplitter(String expression) { this(expression, new HashMap()); } @@ -72,28 +78,41 @@ public class XPathMessageSplitter extends AbstractSplitter { this.documentBuilderFactory.setNamespaceAware(true); } + + public void setCreateDocuments(boolean createDocuments) { + this.createDocuments = createDocuments; + } + + public void setDocumentBuilder(DocumentBuilderFactory documentBuilderFactory) { + Assert.notNull(documentBuilderFactory, "DocumentBuilderFactory must not be null"); + this.documentBuilderFactory = documentBuilderFactory; + } + + public void setXmlPayloadConverter(XmlPayloadConverter xmlPayloadConverter) { + Assert.notNull(xmlPayloadConverter, "XmlPayloadConverter must not be null"); + this.xmlPayloadConverter = xmlPayloadConverter; + } + @Override protected Object splitMessage(Message message) { try { Object payload = message.getPayload(); - Object toReturn = null; - + Object result = null; if (payload instanceof Node) { - toReturn = splitNodePayload((Node) payload, message); + result = splitNodePayload((Node) payload, message); } else if (payload instanceof String) { payload = xmlPayloadConverter.convertToDocument(payload); - toReturn = splitStringPayload(message); + result = splitStringPayload(message); } - return toReturn; + return result; } catch (ParserConfigurationException e) { - throw new MessagingException(message, "Error creating DocumentBuilder", e); + throw new MessagingException(message, "failed to create DocumentBuilder", e); } catch (Exception e) { - throw new MessagingException(message, "Error transforming payload", e); + throw new MessagingException(message, "failed to split Message payload", e); } - } private Object splitStringPayload(Message message) throws ParserConfigurationException, @@ -116,7 +135,7 @@ public class XPathMessageSplitter extends AbstractSplitter { if (nodeList.size() == 0) { throw new MessagingException(message, "Could not split message with XPath " + xpathExpression); } - if (createDocuments) { + if (this.createDocuments) { return convertNodesToDocuments(nodeList); } return nodeList; @@ -124,9 +143,7 @@ public class XPathMessageSplitter extends AbstractSplitter { } private List convertNodesToDocuments(List nodeList) throws ParserConfigurationException { - DocumentBuilder documentBuilder; - documentBuilder = getNewDocumentBuilder(); - + DocumentBuilder documentBuilder = this.getNewDocumentBuilder(); List docList = new ArrayList(nodeList.size()); for (Node node : nodeList) { Document doc = documentBuilder.newDocument(); @@ -136,24 +153,9 @@ public class XPathMessageSplitter extends AbstractSplitter { return docList; } - public void setCreateDocuments(boolean createDocuments) { - this.createDocuments = createDocuments; - } - - public void setDocumentBuilder(DocumentBuilderFactory documentBuilderFactory) { - Assert.notNull(documentBuilderFactory, "Document builder can not be null"); - this.documentBuilderFactory = documentBuilderFactory; - } - - public void setXmlPayloadConverter(XmlPayloadConverter xmlPayloadConverter) { - Assert.notNull(xmlPayloadConverter, "Xml Payload converter can not be null"); - this.xmlPayloadConverter = xmlPayloadConverter; - - } - protected DocumentBuilder getNewDocumentBuilder() throws ParserConfigurationException { - synchronized (documentBuilderFactory) { - return documentBuilderFactory.newDocumentBuilder(); + synchronized (this.documentBuilderFactory) { + return this.documentBuilderFactory.newDocumentBuilder(); } } diff --git a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/splitter/XPathMessageSplitterTests.java b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/splitter/XPathMessageSplitterTests.java index 7b8bb25a52..171865d635 100644 --- a/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/splitter/XPathMessageSplitterTests.java +++ b/org.springframework.integration.xml/src/test/java/org/springframework/integration/xml/splitter/XPathMessageSplitterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * 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. @@ -13,67 +13,82 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.xml.splitter; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.List; import org.junit.Before; import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.message.GenericMessage; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessagingException; import org.springframework.integration.xml.util.XmlTestUtil; -import org.w3c.dom.Document; -import org.w3c.dom.Node; +/** + * @author Jonas Partner + */ public class XPathMessageSplitterTests { - String splittingXPath = "/orders/order"; - - XPathMessageSplitter splitter; + private String splittingXPath = "/orders/order"; + private XPathMessageSplitter splitter; + + private QueueChannel replyChannel = new QueueChannel(); + + @Before public void setUp(){ splitter = new XPathMessageSplitter(splittingXPath); + splitter.setOutputChannel(replyChannel); } - + + @Test - public void splitDocument() throws Exception{ + public void splitDocument() throws Exception { Document doc = XmlTestUtil.getDocumentForString("onetwothree"); - List> docMessages = splitter.split(new GenericMessage(doc)); + splitter.onMessage(new GenericMessage(doc)); + List> docMessages = this.replyChannel.clear(); assertEquals("Wrong number of messages", 3, docMessages.size()); for (Message message : docMessages) { assertTrue("unexpected payload type" + message.getPayload().getClass().getName(), message.getPayload() instanceof Node); assertFalse("unexpected payload type" + message.getPayload().getClass().getName(), message.getPayload() instanceof Document); } } - - @Test(expected=MessagingException.class) - public void splitDocumentThatDoesNotMatch() throws Exception{ + + @Test(expected = MessagingException.class) + public void splitDocumentThatDoesNotMatch() throws Exception { Document doc = XmlTestUtil.getDocumentForString(""); - splitter.split(new GenericMessage(doc)); + splitter.onMessage(new GenericMessage(doc)); } - + @Test - public void splitDocumentWithCreateDocumentsTrue() throws Exception{ + public void splitDocumentWithCreateDocumentsTrue() throws Exception { splitter.setCreateDocuments(true); Document doc = XmlTestUtil.getDocumentForString("onetwothree"); - List> docMessages = splitter.split(new GenericMessage(doc)); + splitter.onMessage(new GenericMessage(doc)); + List> docMessages = this.replyChannel.clear(); assertEquals("Wrong number of messages", 3, docMessages.size()); for (Message message : docMessages) { assertTrue("unexpected payload type" + message.getPayload().getClass().getName(), message.getPayload() instanceof Document); } } - - + @Test - public void splitStringXml() throws Exception{ - List> docMessages = splitter.split(new GenericMessage("onetwothree")); + public void splitStringXml() throws Exception { + String payload = "onetwothree"; + splitter.onMessage(new GenericMessage(payload)); + List> docMessages = this.replyChannel.clear(); assertEquals("Wrong number of messages", 3, docMessages.size()); for (Message message : docMessages) { - System.out.println(message); assertTrue("unexpected payload type " + message.getPayload().getClass().getName(), message.getPayload() instanceof String); } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/SplitterParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/SplitterParser.java index 11a1adcde6..4ccce3c490 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/SplitterParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/SplitterParser.java @@ -20,8 +20,9 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.integration.splitter.DefaultMessageSplitter; import org.springframework.integration.splitter.MethodInvokingSplitter; -import org.springframework.integration.splitter.SplitterEndpoint; +import org.springframework.util.StringUtils; /** * Parser for the <splitter/> element. @@ -32,12 +33,17 @@ public class SplitterParser extends AbstractEndpointParser { @Override protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SplitterEndpoint.class); - if (element.hasAttribute("ref")) { - String adapterBeanName = this.parseAdapter(element, parserContext, MethodInvokingSplitter.class); - builder.addConstructorArgReference(adapterBeanName); + if (element.hasAttribute(REF_ATTRIBUTE)) { + String ref = element.getAttribute(REF_ATTRIBUTE); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MethodInvokingSplitter.class); + builder.addConstructorArgReference(ref); + if (StringUtils.hasText(element.getAttribute(METHOD_ATTRIBUTE))) { + String method = element.getAttribute(METHOD_ATTRIBUTE); + builder.addConstructorArgValue(method); + } + return builder; } - return builder; + return BeanDefinitionBuilder.genericBeanDefinition(DefaultMessageSplitter.class); } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/SplitterAnnotationPostProcessor.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/SplitterAnnotationPostProcessor.java index e3a930ecec..886e7960c6 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/SplitterAnnotationPostProcessor.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/annotation/SplitterAnnotationPostProcessor.java @@ -22,7 +22,6 @@ import org.springframework.integration.annotation.Splitter; import org.springframework.integration.bus.MessageBus; import org.springframework.integration.message.MessageConsumer; import org.springframework.integration.splitter.MethodInvokingSplitter; -import org.springframework.integration.splitter.SplitterEndpoint; /** * Post-processor for Methods annotated with {@link Splitter @Splitter}. @@ -38,8 +37,7 @@ public class SplitterAnnotationPostProcessor extends AbstractMethodAnnotationPos @Override protected MessageConsumer createConsumer(Object bean, Method method, Splitter annotation) { - MethodInvokingSplitter splitter = new MethodInvokingSplitter(bean, method); - return new SplitterEndpoint(splitter); + return new MethodInvokingSplitter(bean, method); } } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/CompositeMessage.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/CompositeMessage.java index d7e0fa8645..685b55e976 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/CompositeMessage.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/CompositeMessage.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; - /** * @author Mark Fisher */ diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/AbstractSplitter.java b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java similarity index 73% rename from org.springframework.integration/src/main/java/org/springframework/integration/splitter/AbstractSplitter.java rename to org.springframework.integration/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java index b8b4387daa..1e74b00ec4 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/AbstractSplitter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java @@ -20,17 +20,30 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.springframework.integration.endpoint.AbstractReplyProducingMessageConsumer; +import org.springframework.integration.message.CompositeMessage; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageBuilder; import org.springframework.integration.message.MessageHeaders; /** + * Base class for Message-splitting consumers. + * * @author Mark Fisher */ -public abstract class AbstractSplitter implements Splitter { +public abstract class AbstractMessageSplitter extends AbstractReplyProducingMessageConsumer { - public List> split(Message message) { + @Override + protected final boolean shouldSplitComposite() { + return true; + } + + @Override + protected final Message handle(Message message) { Object result = this.splitMessage(message); + if (result == null) { + return null; + } MessageHeaders requestHeaders = message.getHeaders(); List> results = new ArrayList>(); if (result instanceof Collection) { @@ -55,11 +68,20 @@ public abstract class AbstractSplitter implements Splitter { if (results.isEmpty()) { return null; } - return results; + return new CompositeMessage(results); } + /** + * Subclasses must override this method to split the received Message. The + * return value may be a Collection or Array. The individual elements may + * be Messages, but it is not necessary. If the elements are not Messages, + * each will be provided as the payload of a Message. It is also acceptable + * to return a single Object or Message. In that case, a single reply + * Message will be produced. + */ protected abstract Object splitMessage(Message message); + private Message createSplitMessage(Object item, MessageHeaders requestHeaders, int sequenceNumber, int sequenceSize) { if (item instanceof Message) { return setSplitMessageHeaders(MessageBuilder.fromMessage((Message) item), diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/DefaultSplitter.java b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/DefaultMessageSplitter.java similarity index 80% rename from org.springframework.integration/src/main/java/org/springframework/integration/splitter/DefaultSplitter.java rename to org.springframework.integration/src/main/java/org/springframework/integration/splitter/DefaultMessageSplitter.java index a039830f17..a12df642a2 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/DefaultSplitter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/DefaultMessageSplitter.java @@ -23,9 +23,14 @@ import java.util.StringTokenizer; import org.springframework.integration.message.Message; /** + * The default Message Splitter implementation. Returns individual Messages + * after receiving an array or Collection. If a value is provided for the + * 'delimiters' property, then String payloads will be tokenized based on + * those delimiters. + * * @author Mark Fisher */ -public class DefaultSplitter extends AbstractSplitter { +public class DefaultMessageSplitter extends AbstractMessageSplitter { private volatile String delimiters; @@ -39,7 +44,7 @@ public class DefaultSplitter extends AbstractSplitter { this.delimiters = delimiters; } - public Object splitMessage(Message message) { + protected final Object splitMessage(Message message) { Object payload = message.getPayload(); if (payload instanceof String && this.delimiters != null) { List tokens = new ArrayList(); diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java index 302bb1aaa7..e873e380e2 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/MethodInvokingSplitter.java @@ -19,11 +19,15 @@ package org.springframework.integration.splitter; import java.lang.reflect.Method; import org.springframework.beans.factory.InitializingBean; +import org.springframework.integration.annotation.Splitter; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageMappingMethodInvoker; +import org.springframework.integration.util.DefaultMethodResolver; +import org.springframework.integration.util.MethodResolver; +import org.springframework.util.Assert; /** - * A {@link Splitter} implementation that invokes the specified method + * A Message Splitter implementation that invokes the specified method * on the given object. The method's return value will be split if it * is a Collection or Array. If the return value is not a Collection or * Array, then the single Object will be returned as the payload of a @@ -31,7 +35,9 @@ import org.springframework.integration.message.MessageMappingMethodInvoker; * * @author Mark Fisher */ -public class MethodInvokingSplitter extends AbstractSplitter implements Splitter, InitializingBean { +public class MethodInvokingSplitter extends AbstractMessageSplitter implements InitializingBean { + + private final MethodResolver methodResolver = new DefaultMethodResolver(Splitter.class); private final MessageMappingMethodInvoker invoker; @@ -44,6 +50,14 @@ public class MethodInvokingSplitter extends AbstractSplitter implements Splitter this.invoker = new MessageMappingMethodInvoker(object, methodName); } + public MethodInvokingSplitter(Object object) { + Assert.notNull(object, "object must not be null"); + Method method = this.methodResolver.findMethod(object.getClass()); + Assert.notNull(method, "unable to resolve Splitter method on target class [" + + object.getClass() + "]"); + this.invoker = new MessageMappingMethodInvoker(object, method); + } + public void afterPropertiesSet() throws Exception { this.invoker.afterPropertiesSet(); diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/Splitter.java b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/Splitter.java deleted file mode 100644 index 11c24104c6..0000000000 --- a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/Splitter.java +++ /dev/null @@ -1,33 +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.splitter; - -import java.util.List; - -import org.springframework.integration.message.Message; - -/** - * Strategy interface for splitting a single {@link Message} - * into multiple Messages. - * - * @author Mark Fisher - */ -public interface Splitter { - - List> split(Message message); - -} diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/SplitterEndpoint.java b/org.springframework.integration/src/main/java/org/springframework/integration/splitter/SplitterEndpoint.java deleted file mode 100644 index 097557fe26..0000000000 --- a/org.springframework.integration/src/main/java/org/springframework/integration/splitter/SplitterEndpoint.java +++ /dev/null @@ -1,58 +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.splitter; - -import java.util.List; - -import org.springframework.integration.endpoint.AbstractReplyProducingMessageConsumer; -import org.springframework.integration.message.CompositeMessage; -import org.springframework.integration.message.Message; -import org.springframework.util.Assert; - -/** - * @author Mark Fisher - */ -public class SplitterEndpoint extends AbstractReplyProducingMessageConsumer { - - private final Splitter splitter; - - - public SplitterEndpoint() { - this(new DefaultSplitter()); - } - - public SplitterEndpoint(Splitter splitter) { - Assert.notNull(splitter, "splitter must not be null"); - this.splitter = splitter; - } - - - @Override - protected boolean shouldSplitComposite() { - return true; - } - - @Override - protected Message handle(Message message) { - List> results = this.splitter.split(message); - if (results == null || results.isEmpty()) { - return null; - } - return new CompositeMessage(results); - } - -} diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/endpoint/CorrelationIdTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/endpoint/CorrelationIdTests.java index 35329a5296..6e21538f93 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/endpoint/CorrelationIdTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/endpoint/CorrelationIdTests.java @@ -23,12 +23,10 @@ import org.junit.Test; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; -import org.springframework.integration.endpoint.ServiceActivatorEndpoint; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageBuilder; import org.springframework.integration.message.StringMessage; import org.springframework.integration.splitter.MethodInvokingSplitter; -import org.springframework.integration.splitter.SplitterEndpoint; /** * @author Mark Fisher @@ -118,10 +116,9 @@ public class CorrelationIdTests { QueueChannel testChannel = new QueueChannel(); MethodInvokingSplitter splitter = new MethodInvokingSplitter( new TestBean(), TestBean.class.getMethod("split", String.class)); - SplitterEndpoint endpoint = new SplitterEndpoint(splitter); - endpoint.setOutputChannel(testChannel); + splitter.setOutputChannel(testChannel); splitter.afterPropertiesSet(); - endpoint.onMessage(message); + splitter.onMessage(message); Message reply1 = testChannel.receive(100); Message reply2 = testChannel.receive(100); assertEquals(message.getHeaders().getId(), reply1.getHeaders().getCorrelationId()); diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java index 2c4f8655d3..9149f40878 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/splitter/DefaultSplitterTests.java @@ -24,6 +24,7 @@ import java.util.List; import org.junit.Test; +import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageBuilder; @@ -36,8 +37,11 @@ public class DefaultSplitterTests { public void splitMessageWithArrayPayload() throws Exception { String[] payload = new String[] { "x", "y", "z" }; Message message = MessageBuilder.withPayload(payload).build(); - DefaultSplitter splitter = new DefaultSplitter(); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + DefaultMessageSplitter splitter = new DefaultMessageSplitter(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); assertEquals(3, replies.size()); Message reply1 = replies.get(0); assertNotNull(reply1); @@ -54,8 +58,11 @@ public class DefaultSplitterTests { public void splitMessageWithCollectionPayload() throws Exception { List payload = Arrays.asList(new String[] { "x", "y", "z" }); Message> message = MessageBuilder.withPayload(payload).build(); - DefaultSplitter splitter = new DefaultSplitter(); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + DefaultMessageSplitter splitter = new DefaultMessageSplitter(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); assertEquals(3, replies.size()); Message reply1 = replies.get(0); assertNotNull(reply1); diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/splitter/MethodInvokingSplitterTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/splitter/MethodInvokingSplitterTests.java index 24952d3195..6e7b58097e 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/splitter/MethodInvokingSplitterTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/splitter/MethodInvokingSplitterTests.java @@ -27,6 +27,8 @@ import java.util.List; import org.junit.Test; import org.springframework.integration.annotation.Header; +import org.springframework.integration.annotation.Splitter; +import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.message.Message; import org.springframework.integration.message.MessageBuilder; import org.springframework.integration.message.StringMessage; @@ -43,7 +45,10 @@ public class MethodInvokingSplitterTests { public void splitStringToStringArray() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("stringToStringArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -56,7 +61,10 @@ public class MethodInvokingSplitterTests { public void splitStringToStringList() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("stringToStringList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -69,7 +77,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToStringArray() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("messageToStringArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -82,7 +93,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToStringList() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("messageToStringList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -95,7 +109,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToMessageArray() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("messageToMessageArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -108,7 +125,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToMessageList() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("messageToMessageList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -121,7 +141,10 @@ public class MethodInvokingSplitterTests { public void splitStringToMessageArray() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("stringToMessageArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -134,7 +157,10 @@ public class MethodInvokingSplitterTests { public void splitStringToMessageList() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("stringToMessageList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -147,7 +173,10 @@ public class MethodInvokingSplitterTests { public void splitStringToStringArrayConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "stringToStringArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -160,7 +189,10 @@ public class MethodInvokingSplitterTests { public void splitStringToStringListConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "stringToStringList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -173,7 +205,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToStringArrayConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "messageToStringArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -186,7 +221,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToStringListConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "messageToStringList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -199,7 +237,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToMessageArrayConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "messageToMessageArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -212,7 +253,10 @@ public class MethodInvokingSplitterTests { public void splitMessageToMessageListConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "messageToMessageList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -225,7 +269,10 @@ public class MethodInvokingSplitterTests { public void splitStringToMessageArrayConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "stringToMessageArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -238,7 +285,10 @@ public class MethodInvokingSplitterTests { public void splitStringToMessageListConfiguredByMethodName() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, "stringToMessageList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -248,10 +298,13 @@ public class MethodInvokingSplitterTests { } @Test - public void testHeaderForObjectReturnValues() throws Exception { + public void headerForObjectReturnValues() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("stringToStringArray"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals(new Integer(2), reply1.getHeaders().getSequenceSize()); @@ -265,10 +318,13 @@ public class MethodInvokingSplitterTests { } @Test - public void testHeaderForMessageReturnValues() throws Exception { + public void headerForMessageReturnValues() throws Exception { StringMessage message = new StringMessage("foo.bar"); MethodInvokingSplitter splitter = this.getSplitter("messageToMessageList"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals(new Integer(2), reply1.getHeaders().getSequenceSize()); @@ -286,7 +342,10 @@ public class MethodInvokingSplitterTests { Message message = MessageBuilder.withPayload("ignored") .setHeader("testHeader", "foo.bar").build(); MethodInvokingSplitter splitter = this.getSplitter("splitHeader"); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("foo", reply1.getPayload()); @@ -301,7 +360,10 @@ public class MethodInvokingSplitterTests { .setHeader("testHeader", "c.d").build(); Method splittingMethod = this.testBean.getClass().getMethod("splitPayloadAndHeader", String.class, String.class); MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean, splittingMethod); - List> replies = splitter.split(message); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); Message reply1 = replies.get(0); assertNotNull(reply1); assertEquals("a", reply1.getPayload()); @@ -316,6 +378,50 @@ public class MethodInvokingSplitterTests { assertEquals("d", reply4.getPayload()); } + @Test + public void singleAnnotation() { + StringMessage message = new StringMessage("foo.bar"); + SingleAnnotationTestBean annotatedBean = new SingleAnnotationTestBean(); + MethodInvokingSplitter splitter = new MethodInvokingSplitter(annotatedBean); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); + Message reply1 = replies.get(0); + assertNotNull(reply1); + assertEquals("foo", reply1.getPayload()); + Message reply2 = replies.get(1); + assertNotNull(reply2); + assertEquals("bar", reply2.getPayload()); + } + + @Test(expected = IllegalArgumentException.class) + public void multipleAnnotations() { + new MethodInvokingSplitter(new MultipleAnnotationTestBean()); + } + + @Test + public void singlePublicMethod() { + StringMessage message = new StringMessage("foo.bar"); + SinglePublicMethodTestBean testBean = new SinglePublicMethodTestBean(); + MethodInvokingSplitter splitter = new MethodInvokingSplitter(testBean); + QueueChannel replyChannel = new QueueChannel(); + splitter.setOutputChannel(replyChannel); + splitter.onMessage(message); + List> replies = replyChannel.clear(); + Message reply1 = replies.get(0); + assertNotNull(reply1); + assertEquals("foo", reply1.getPayload()); + Message reply2 = replies.get(1); + assertNotNull(reply2); + assertEquals("bar", reply2.getPayload()); + } + + @Test(expected = IllegalArgumentException.class) + public void multiplePublicMethods() { + new MethodInvokingSplitter(new MultiplePublicMethodTestBean()); + } + private MethodInvokingSplitter getSplitter(String methodName) throws Exception { Class paramType = methodName.startsWith("message") ? Message.class : String.class; @@ -395,4 +501,55 @@ public class MethodInvokingSplitterTests { } } + + public static class SingleAnnotationTestBean { + + @Splitter + public String[] annotatedMethod(String input) { + return input.split("\\."); + } + + public String[] anotherMethod(String input) { + throw new UnsupportedOperationException("incorrect test invocation"); + } + } + + + public static class MultipleAnnotationTestBean { + + @Splitter + public String[] method1(String input) { + throw new UnsupportedOperationException("incorrect test invocation"); + } + + @Splitter + public String[] method2(String input) { + throw new UnsupportedOperationException("incorrect test invocation"); + } + } + + + public static class SinglePublicMethodTestBean { + + public String[] publicMethod(String input) { + return input.split("\\."); + } + + String[] anotherMethod(String input) { + throw new UnsupportedOperationException("incorrect test invocation"); + } + } + + + public static class MultiplePublicMethodTestBean { + + public String[] method1(String input) { + throw new UnsupportedOperationException("incorrect test invocation"); + } + + public String[] method2(String input) { + throw new UnsupportedOperationException("incorrect test invocation"); + } + } + }