diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java index 627562a418..2da47959ae 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java @@ -33,6 +33,7 @@ import org.springframework.integration.channel.config.DirectChannelParser; import org.springframework.integration.channel.config.PriorityChannelParser; import org.springframework.integration.channel.config.QueueChannelParser; import org.springframework.integration.channel.config.RendezvousChannelParser; +import org.springframework.integration.router.config.SplitterParser; import org.springframework.util.ClassUtils; /** @@ -64,6 +65,7 @@ public class IntegrationNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("target-endpoint", new TargetEndpointParser()); registerBeanDefinitionParser("handler", new HandlerParser()); registerBeanDefinitionParser("handler-chain", new HandlerParser()); + registerBeanDefinitionParser("splitter", new SplitterParser()); registerBeanDefinitionParser("aggregator", new AggregatorParser()); Map> parserMappings = this.loadAdapterParserMappings(); try { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd b/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd index bc32f7a68f..9fed29d416 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd @@ -279,6 +279,20 @@ + + + + + Defines a Splitter. + + + + + + + + + diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/SplitterMessageHandlerAdapter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/SplitterMessageHandlerAdapter.java index 0dcc7c2fb6..c7625bc801 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/SplitterMessageHandlerAdapter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/SplitterMessageHandlerAdapter.java @@ -56,6 +56,12 @@ public class SplitterMessageHandlerAdapter extends AbstractMessageHandlerAdapter } } + public SplitterMessageHandlerAdapter(Object object, String methodName, String outputChannelName) { + Assert.hasText(outputChannelName, "output channel name is required"); + this.setObject(object); + this.setMethodName(methodName); + this.outputChannelName = outputChannelName; + } public void setChannelRegistry(ChannelRegistry channelRegistry) { this.channelRegistry = channelRegistry; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/config/SplitterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/router/config/SplitterParser.java new file mode 100644 index 0000000000..699a1ea8f9 --- /dev/null +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/config/SplitterParser.java @@ -0,0 +1,53 @@ +/* + * 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.router.config; + +import org.w3c.dom.Element; + +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.integration.ConfigurationException; +import org.springframework.integration.router.SplitterMessageHandlerAdapter; +import org.springframework.util.StringUtils; + +/** + * Parser for the <splitter/> element. + * + * @author Mark Fisher + */ +public class SplitterParser extends AbstractSingleBeanDefinitionParser { + + @Override + protected Class getBeanClass(Element element) { + return SplitterMessageHandlerAdapter.class; + } + + @Override + protected void doParse(Element element, BeanDefinitionBuilder builder) { + String ref = element.getAttribute("ref"); + String methodName = element.getAttribute("method"); + String outputChannelName = element.getAttribute("output-channel"); + if (!StringUtils.hasText(ref) || !StringUtils.hasText(methodName) || !StringUtils.hasText(outputChannelName)) { + throw new ConfigurationException( + "The 'ref', 'method', and 'output-channel' attributes are all required."); + } + builder.addConstructorArgReference(ref); + builder.addConstructorArgValue(methodName); + builder.addConstructorArgValue(outputChannelName); + } + +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/SplitterMessageHandlerAdapterTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/SplitterMessageHandlerAdapterTests.java index 08b975e1bb..32bab71417 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/router/SplitterMessageHandlerAdapterTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/SplitterMessageHandlerAdapterTests.java @@ -164,6 +164,54 @@ public class SplitterMessageHandlerAdapterTests { adapter.handle(message); } + @Test + public void testSplitPayloadToStringArrayConfiguredByMethodName() throws Exception { + StringMessage message = new StringMessage("foo.bar"); + SplitterMessageHandlerAdapter adapter = new SplitterMessageHandlerAdapter( + testBean, "stringToStringArray", "testChannel"); + adapter.setChannelRegistry(channelRegistry); + adapter.afterPropertiesSet(); + adapter.handle(message); + Message reply1 = testChannel.receive(0); + assertNotNull(reply1); + assertEquals("foo", reply1.getPayload()); + Message reply2 = testChannel.receive(0); + assertNotNull(reply2); + assertEquals("bar", reply2.getPayload()); + } + + @Test + public void testSplitMessageToStringArrayConfiguredByMethodName() throws Exception { + StringMessage message = new StringMessage("foo.bar"); + SplitterMessageHandlerAdapter adapter = new SplitterMessageHandlerAdapter( + testBean, "messageToStringArray", "testChannel"); + adapter.setChannelRegistry(channelRegistry); + adapter.afterPropertiesSet(); + adapter.handle(message); + Message reply1 = testChannel.receive(0); + assertNotNull(reply1); + assertEquals("foo", reply1.getPayload()); + Message reply2 = testChannel.receive(0); + assertNotNull(reply2); + assertEquals("bar", reply2.getPayload()); + } + + @Test + public void testSplitStringToMessageListConfiguredByMethodName() throws Exception { + StringMessage message = new StringMessage("foo.bar"); + SplitterMessageHandlerAdapter adapter = new SplitterMessageHandlerAdapter( + testBean, "stringToMessageList", "testChannel"); + adapter.setChannelRegistry(channelRegistry); + adapter.afterPropertiesSet(); + adapter.handle(message); + Message reply1 = testChannel.receive(0); + assertNotNull(reply1); + assertEquals("foo", reply1.getPayload()); + Message reply2 = testChannel.receive(0); + assertNotNull(reply2); + assertEquals("bar", reply2.getPayload()); + } + @Test public void testHeaderForObjectReturnValues() throws Exception { StringMessage message = new StringMessage("foo.bar"); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java new file mode 100644 index 0000000000..264d542e25 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/SplitterParserTests.java @@ -0,0 +1,53 @@ +/* + * 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.router.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.channel.MessageChannel; +import org.springframework.integration.message.Message; +import org.springframework.integration.message.StringMessage; + +/** + * @author Mark Fisher + */ +public class SplitterParserTests { + + @Test + public void test() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "splitterParserTests.xml", this.getClass()); + context.start(); + MessageChannel channel1 = (MessageChannel) context.getBean("channel1"); + MessageChannel channel2 = (MessageChannel) context.getBean("channel2"); + channel1.send(new StringMessage("this.is.a.test")); + Message result1 = channel2.receive(1000); + assertEquals("this", result1.getPayload()); + Message result2 = channel2.receive(1000); + assertEquals("is", result2.getPayload()); + Message result3 = channel2.receive(1000); + assertEquals("a", result3.getPayload()); + Message result4 = channel2.receive(1000); + assertEquals("test", result4.getPayload()); + assertNull(channel2.receive(0)); + } + +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/TestSplitter.java b/spring-integration-core/src/test/java/org/springframework/integration/router/config/TestSplitter.java new file mode 100644 index 0000000000..c8d004e255 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/TestSplitter.java @@ -0,0 +1,28 @@ +/* + * 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.router.config; + +/** + * @author Mark Fisher + */ +public class TestSplitter { + + public String[] split(String input) { + return input.split("\\."); + } + +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml new file mode 100644 index 0000000000..24372693ec --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + +