diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/SourceEndpointParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java similarity index 55% rename from org.springframework.integration/src/main/java/org/springframework/integration/config/SourceEndpointParser.java rename to org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java index c80591fb49..5f9bd17f31 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/SourceEndpointParser.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/ChannelAdapterParser.java @@ -18,26 +18,38 @@ package org.springframework.integration.config; import org.w3c.dom.Element; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.ConfigurationException; import org.springframework.integration.endpoint.SourceEndpoint; +import org.springframework.integration.endpoint.TargetEndpoint; +import org.springframework.integration.handler.MethodInvokingTarget; +import org.springframework.integration.message.MethodInvokingSource; import org.springframework.integration.scheduling.PollingSchedule; import org.springframework.integration.scheduling.Schedule; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; /** - * Parser for the element. + * Parser for the element. * * @author Mark Fisher */ -public class SourceEndpointParser extends AbstractSimpleBeanDefinitionParser { +public class ChannelAdapterParser extends AbstractSimpleBeanDefinitionParser { protected final Class getBeanClass(Element element) { - return SourceEndpoint.class; + boolean hasSource = StringUtils.hasText(element.getAttribute("source")); + boolean hasTarget = StringUtils.hasText(element.getAttribute("target")); + if (!(hasSource ^ hasTarget)) { + throw new ConfigurationException("exactly one of 'source' or 'target' is required"); + } + return hasSource ? SourceEndpoint.class : TargetEndpoint.class; } protected boolean shouldGenerateId() { @@ -49,21 +61,31 @@ public class SourceEndpointParser extends AbstractSimpleBeanDefinitionParser { } protected boolean isEligibleAttribute(String name) { - return (!"source".equals(name) && !"channel".equals(name) && super.isEligibleAttribute(name)); + return (!"source".equals(name) + && !"target".equals(name) + && !"channel".equals(name) + && super.isEligibleAttribute(name)); } @Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String source = element.getAttribute("source"); - if (!StringUtils.hasText(source)) { - throw new ConfigurationException("'source' is required"); - } - String output = element.getAttribute("channel"); - if (!StringUtils.hasText(output)) { + String target = element.getAttribute("target"); + String channel = element.getAttribute("channel"); + if (!StringUtils.hasText(channel)) { throw new ConfigurationException("'channel' is required"); } - builder.addConstructorArgReference(source); - builder.addPropertyValue("outputChannelName", output); + boolean isSource = StringUtils.hasText(source); + if (isSource) { + builder.addConstructorArgReference(this.resolveConstructorArgument( + source, MethodInvokingSource.class, element, parserContext)); + builder.addPropertyValue("outputChannelName", channel); + } + else { + builder.addConstructorArgReference(this.resolveConstructorArgument( + target, MethodInvokingTarget.class, element, parserContext)); + builder.addPropertyValue("inputChannelName", channel); + } Element scheduleElement = DomUtils.getChildElementByTagName(element, "schedule"); if (scheduleElement != null) { builder.addPropertyValue("schedule", this.parseSchedule(scheduleElement)); @@ -76,6 +98,19 @@ public class SourceEndpointParser extends AbstractSimpleBeanDefinitionParser { } } + private String resolveConstructorArgument(String ref, Class targetClass, Element element, ParserContext parserContext) { + String method = element.getAttribute("method"); + if (StringUtils.hasText(method)) { + BeanDefinition adapterDef = new RootBeanDefinition(targetClass); + adapterDef.getPropertyValues().addPropertyValue("object", new RuntimeBeanReference(ref)); + adapterDef.getPropertyValues().addPropertyValue("methodName", method); + String adapterBeanName = parserContext.getReaderContext().generateBeanName(adapterDef); + parserContext.registerBeanComponent(new BeanComponentDefinition(adapterDef, adapterBeanName)); + return adapterBeanName; + } + return ref; + } + /** * Subclasses may override this method to control the creation of the {@link Schedule}. The default * implementation creates a {@link PollingSchedule} instance based on the provided "period" attribute. diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java index cc15097c5b..f02dab11f9 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/IntegrationNamespaceHandler.java @@ -64,11 +64,8 @@ public class IntegrationNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("priority-channel", new PriorityChannelParser()); registerBeanDefinitionParser("rendezvous-channel", new RendezvousChannelParser()); registerBeanDefinitionParser("thread-local-channel", new ThreadLocalChannelParser()); - registerBeanDefinitionParser("source-adapter", new MethodInvokingAdapterParser()); - registerBeanDefinitionParser("target-adapter", new MethodInvokingAdapterParser()); - registerBeanDefinitionParser("source-endpoint", new SourceEndpointParser()); registerBeanDefinitionParser("handler-endpoint", new HandlerEndpointParser()); - registerBeanDefinitionParser("target-endpoint", new TargetEndpointParser()); + registerBeanDefinitionParser("channel-adapter", new ChannelAdapterParser()); registerBeanDefinitionParser("gateway", new GatewayParser()); registerBeanDefinitionParser("handler", new HandlerParser()); registerBeanDefinitionParser("handler-chain", new HandlerParser()); diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd index a7ce65fedd..54364546ba 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd +++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/spring-integration-core-1.0.xsd @@ -168,58 +168,30 @@ - + - Defines a source endpoint. + Defines a Channel Adapter that is capable of either receiving from a MessageSource and sending + the result to a MessageChannel or receiving from a MessageChannel and sending the result to a + MessageTarget. Therefore, either "source" or "target" should be provided (but never both). - - + + - - + + + + - - - - Defines a MethodInvokingSource. - - - - - - - - - Defines a target endpoint. - - - - - - - - - - - - - - - Defines a MethodInvokingTarget. - - - - @@ -228,10 +200,16 @@ - + + + + + + + @@ -417,38 +395,6 @@ - - - - Defines common configuration properties of target message endpoints. - - - - - - - - - - - - - - - - - - Base type for method-invoking adapters. - - - - - - - - - - diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/channel/config/TestSourceBean.java b/org.springframework.integration/src/test/java/org/springframework/integration/channel/config/TestSource.java similarity index 68% rename from org.springframework.integration/src/test/java/org/springframework/integration/channel/config/TestSourceBean.java rename to org.springframework.integration/src/test/java/org/springframework/integration/channel/config/TestSource.java index 3860bae5ac..6ed3aa5a0a 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/channel/config/TestSourceBean.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/channel/config/TestSource.java @@ -16,20 +16,24 @@ package org.springframework.integration.channel.config; +import org.springframework.integration.message.Message; +import org.springframework.integration.message.MessageSource; +import org.springframework.integration.message.StringMessage; + /** * @author Mark Fisher */ -public class TestSourceBean { +public class TestSource implements MessageSource { private final String text; - public TestSourceBean(String text) { + public TestSource(String text) { this.text = text; } - public String getText() { - return this.text; + public Message receive() { + return new StringMessage(this.text); } } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/messageEndpointBeanPostProcessorTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/messageEndpointBeanPostProcessorTests.xml index e6297bc8ad..59ef1256a0 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/config/messageEndpointBeanPostProcessorTests.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/messageEndpointBeanPostProcessorTests.xml @@ -31,29 +31,29 @@ - + - + - + - + - - + - @@ -61,7 +61,7 @@ - + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/dispatcher/directChannelParserTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/dispatcher/directChannelParserTests.xml index 05397f28c3..c3eb918fd8 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/dispatcher/directChannelParserTests.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/dispatcher/directChannelParserTests.xml @@ -9,11 +9,9 @@ - + - - - + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/handler/adapterTestsWithNamespace.xml b/org.springframework.integration/src/test/java/org/springframework/integration/handler/adapterTestsWithNamespace.xml index 02a64bebc1..3c33549674 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/handler/adapterTestsWithNamespace.xml +++ b/org.springframework.integration/src/test/java/org/springframework/integration/handler/adapterTestsWithNamespace.xml @@ -11,13 +11,11 @@ - + - + - - - +