INT-1038, INT-1047 Changed IntegrationNamespaceUtils.parseInnerHandlerDefinition to register and return BeanComponentDefinition, Fixed MethodInvokingOutboundChannelAdapter, added test to ChannelAdapterParserTest

This commit is contained in:
Oleg Zhurakousky
2010-03-27 15:07:01 +00:00
parent 5321887567
commit 4a527a8e19
9 changed files with 89 additions and 22 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.config.xml;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
@@ -36,7 +37,7 @@ abstract class AbstractDelegatingConsumerEndpointParser extends AbstractConsumer
@Override
protected final BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(this.getFactoryBeanClassName());
BeanDefinition innerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
BeanComponentDefinition innerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
String ref = element.getAttribute(REF_ATTRIBUTE);
String expression = element.getAttribute(EXPRESSION_ATTRIBUTE);
boolean hasRef = StringUtils.hasText(ref);

View File

@@ -59,7 +59,7 @@ public abstract class AbstractOutboundChannelAdapterParser extends AbstractChann
AbstractBeanDefinition definition = this.parseConsumer(element, parserContext);
if (definition == null) {
parserContext.getReaderContext().error(
"Consumer parsing must return a BeanDefinition.", element);
"Consumer parsing must return a BeanComponentDefinition.", element);
}
String order = element.getAttribute("order");
if (StringUtils.hasText(order)) {

View File

@@ -19,6 +19,7 @@ package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
@@ -63,7 +64,7 @@ public class AggregatorParser extends AbstractConsumerEndpointParser {
@Override
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
BeanDefinition innerHandlerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
BeanComponentDefinition innerHandlerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
String ref = element.getAttribute(REF_ATTRIBUTE);
BeanDefinitionBuilder builder;

View File

@@ -22,6 +22,7 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
@@ -180,24 +181,28 @@ public abstract class IntegrationNamespaceUtils {
}
}
public static BeanDefinition parseInnerHandlerDefinition(Element element, ParserContext parserContext){
public static BeanComponentDefinition parseInnerHandlerDefinition(Element element, ParserContext parserContext){
// parses out inner bean definition for concrete implementation if defined
List<Element> childElements = DomUtils.getChildElementsByTagName(element, "bean");
BeanDefinition innerDefinition = null;
BeanComponentDefinition innerComponentDefinition = null;
if (childElements != null && childElements.size() == 1){
Element beanElement = childElements.get(0);
BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(beanElement);
bdHolder = delegate.decorateBeanDefinitionIfRequired(beanElement, bdHolder);
innerDefinition = bdHolder.getBeanDefinition();
BeanDefinitionReaderUtils.registerWithGeneratedName((AbstractBeanDefinition) innerDefinition, parserContext.getRegistry());
BeanDefinition inDef = bdHolder.getBeanDefinition();
String beanName = BeanDefinitionReaderUtils.generateBeanName(inDef, parserContext.getRegistry());
innerComponentDefinition = new BeanComponentDefinition(inDef, beanName);
parserContext.registerBeanComponent(innerComponentDefinition);
}
String ref = element.getAttribute(REF_ATTRIBUTE);
Assert.isTrue(!(StringUtils.hasText(ref) && innerDefinition != null), "Ambiguous definition. Inner bean " +
(innerDefinition == null ? innerDefinition : innerDefinition.getBeanClassName()) + " declaration and \"ref\" " + ref +
" are not allowed together.");
return innerDefinition;
Assert.isTrue(!(StringUtils.hasText(ref) && innerComponentDefinition != null), "Ambiguous definition. Inner bean " +
(innerComponentDefinition == null
? innerComponentDefinition
: innerComponentDefinition.getBeanDefinition().getBeanClassName()) + " declaration and \"ref\" " + ref +
" are not allowed together.");
return innerComponentDefinition;
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
@@ -32,9 +33,15 @@ public class MethodInvokingInboundChannelAdapterParser extends AbstractPollingIn
@Override
protected String parseSource(Element element, ParserContext parserContext) {
String sourceRef = element.getAttribute("ref");
BeanComponentDefinition bcDef = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
String sourceRef = null;
if (bcDef != null){
sourceRef = bcDef.getBeanName();
} else {
sourceRef = element.getAttribute("ref");
}
if (!StringUtils.hasText(sourceRef)) {
parserContext.getReaderContext().error("The 'ref' attribute is required.", element);
parserContext.getReaderContext().error("Either 'ref' attribute or inner-bean consumer definition is required.", element);
}
String methodName = element.getAttribute("method");
if (StringUtils.hasText(methodName)) {

View File

@@ -16,15 +16,14 @@
package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the &lt;outbound-channel-adapter/&gt; element.
@@ -35,7 +34,13 @@ import org.springframework.util.StringUtils;
public class MethodInvokingOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
protected String parseAndRegisterConsumer(Element element, ParserContext parserContext) {
String consumerRef = element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE);
BeanComponentDefinition consumerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
String consumerRef = null;
if (consumerDefinition == null){
consumerRef = element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE);
} else {
consumerRef = consumerDefinition.getBeanName();
}
if (element.hasAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE)) {
consumerRef = BeanDefinitionReaderUtils.registerWithGeneratedName(
this.parseConsumer(element, parserContext), parserContext.getRegistry());
@@ -48,7 +53,7 @@ public class MethodInvokingOutboundChannelAdapterParser extends AbstractOutbound
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder invokerBuilder = BeanDefinitionBuilder.genericBeanDefinition(
IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.MethodInvokingMessageHandler");
BeanDefinition innerHandlerDefinition =
BeanComponentDefinition innerHandlerDefinition =
IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
if (innerHandlerDefinition == null){
Assert.hasText(element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE),

View File

@@ -16,12 +16,11 @@
package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for the &lt;service-activator&gt; element.
@@ -33,7 +32,7 @@ public class ServiceActivatorParser extends AbstractConsumerEndpointParser {
@Override
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
BeanDefinition innerHandlerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
BeanComponentDefinition innerHandlerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
IntegrationNamespaceUtils.BASE_PACKAGE + ".handler.ServiceActivatingHandler");

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd">
<channel id="queueChannel">
<queue capacity="1"/>
</channel>
<inbound-channel-adapter id="methodInvokingSource" method="getMessage" channel="queueChannel" auto-startup="false">
<poller max-messages-per-poll="1">
<interval-trigger interval="10000"/>
</poller>
<beans:bean class="org.springframework.integration.config.ChannelAdapterParserTests$SampleBean"/>
</inbound-channel-adapter>
</beans:beans>

View File

@@ -39,16 +39,20 @@ import org.springframework.integration.message.StringMessage;
/**
* @author Mark Fisher
* @author Oleg Zhurakousky
*/
public class ChannelAdapterParserTests {
private AbstractApplicationContext applicationContext;
private AbstractApplicationContext applicationContextInner;
@Before
public void setUp() {
this.applicationContext = new ClassPathXmlApplicationContext(
"ChannelAdapterParserTests-context.xml", this.getClass());
this.applicationContextInner = new ClassPathXmlApplicationContext(
"ChannelAdapterParserTests-inner-context.xml", this.getClass());
}
@After
@@ -74,6 +78,23 @@ public class ChannelAdapterParserTests {
message = channel.receive(100);
assertNull(message);
}
@Test
public void methodInvokingSourceStoppedByApplicationContextInner() {
String beanName = "methodInvokingSource";
PollableChannel channel = (PollableChannel) this.applicationContextInner.getBean("queueChannel");
// TestBean testBean = (TestBean) this.applicationContextInner.getBean("testBean");
// testBean.store("source test");
Object adapter = this.applicationContextInner.getBean(beanName);
assertNotNull(adapter);
assertTrue(adapter instanceof SourcePollingChannelAdapter);
this.applicationContextInner.start();
Message<?> message = channel.receive(1000);
assertNotNull(message);
//assertEquals("source test", testBean.getMessage());
this.applicationContextInner.stop();
message = channel.receive(100);
assertNull(message);
}
@Test
public void targetOnly() {
@@ -180,4 +201,11 @@ public class ChannelAdapterParserTests {
channelResolver.resolveChannelName("methodInvokingSource");
}
public static class SampleBean{
private String message = "hello";
String getMessage() {
return message;
}
}
}