From b60525a2595c6548c91be9981c86b39fcff7614e Mon Sep 17 00:00:00 2001 From: David Turanski Date: Fri, 24 Jun 2011 13:47:49 -0400 Subject: [PATCH] INT-1927 allow sub-elements of other than tested with --- .../xml/GlobalChannelInterceptorParser.java | 85 +++++++++++++------ .../config/xml/GlobalWireTapParser.java | 3 +- .../config/xml/spring-integration-2.0.xsd | 4 +- ...nnelInterceptorSubElementTests-context.xml | 23 +++++ ...obalChannelInterceptorSubElementTests.java | 60 +++++++++++++ .../GlobalChannelInterceptorTests.java | 37 +++++--- 6 files changed, 171 insertions(+), 41 deletions(-) create mode 100644 spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests-context.xml create mode 100644 spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests.java diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java index 5b7c74f2af..81f14bbd0f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalChannelInterceptorParser.java @@ -16,6 +16,8 @@ package org.springframework.integration.config.xml; +import java.util.List; + import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; @@ -25,6 +27,7 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; /** @@ -35,9 +38,11 @@ import org.w3c.dom.Element; * @author David Turanski * @since 2.0 */ -public class GlobalChannelInterceptorParser extends AbstractBeanDefinitionParser { +public class GlobalChannelInterceptorParser extends + AbstractBeanDefinitionParser { - private static final String BASE_PACKAGE = IntegrationNamespaceUtils.BASE_PACKAGE + ".channel.interceptor."; + private static final String BASE_PACKAGE = IntegrationNamespaceUtils.BASE_PACKAGE + + ".channel.interceptor."; private static final String CHANNEL_NAME_PATTERN_ATTRIBUTE = "pattern"; @@ -45,50 +50,82 @@ public class GlobalChannelInterceptorParser extends AbstractBeanDefinitionParser private static final String GLOBAL_POST_PROCESSOR_CLASSNAME = "GlobalChannelInterceptorBeanPostProcessor"; - private final ManagedList globalInterceptors = new ManagedList(); private volatile boolean postProcessorCreated; + int ICOUNT = 0; - protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { + protected AbstractBeanDefinition parseInternal(Element element, + ParserContext parserContext) { this.createAndRegisterGlobalPostProcessorIfNecessary(parserContext); - BeanDefinitionBuilder globalChannelInterceptorBuilder = - BeanDefinitionBuilder.genericBeanDefinition(BASE_PACKAGE + "GlobalChannelInterceptorWrapper"); - - globalChannelInterceptorBuilder.addConstructorArgValue(getBeanDefinitionBuilderConstructorValue(element, parserContext)); + BeanDefinitionBuilder globalChannelInterceptorBuilder = BeanDefinitionBuilder + .genericBeanDefinition(BASE_PACKAGE + + "GlobalChannelInterceptorWrapper"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(globalChannelInterceptorBuilder, element, "order"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(globalChannelInterceptorBuilder, element, CHANNEL_NAME_PATTERN_ATTRIBUTE, "patterns"); + Object childBeanDefinition = getBeanDefinitionBuilderConstructorValue( + element, parserContext, globalChannelInterceptorBuilder); + globalChannelInterceptorBuilder + .addConstructorArgValue(childBeanDefinition); + + IntegrationNamespaceUtils.setValueIfAttributeDefined( + globalChannelInterceptorBuilder, element, "order"); + IntegrationNamespaceUtils.setValueIfAttributeDefined( + globalChannelInterceptorBuilder, element, + CHANNEL_NAME_PATTERN_ATTRIBUTE, "patterns"); String beanName = BeanDefinitionReaderUtils.generateBeanName( - globalChannelInterceptorBuilder.getBeanDefinition(), parserContext.getRegistry()); - parserContext.registerBeanComponent(new BeanComponentDefinition(globalChannelInterceptorBuilder.getBeanDefinition(), beanName)); + globalChannelInterceptorBuilder.getBeanDefinition(), + parserContext.getRegistry()); + parserContext.registerBeanComponent(new BeanComponentDefinition( + globalChannelInterceptorBuilder.getBeanDefinition(), beanName)); this.globalInterceptors.add(new RuntimeBeanReference(beanName)); return null; } - private void createAndRegisterGlobalPostProcessorIfNecessary(ParserContext parserContext) { + private void createAndRegisterGlobalPostProcessorIfNecessary( + ParserContext parserContext) { if (!this.postProcessorCreated) { - BeanDefinitionBuilder postProcessorBuilder = BeanDefinitionBuilder.genericBeanDefinition( - BASE_PACKAGE + GLOBAL_POST_PROCESSOR_CLASSNAME); - postProcessorBuilder.addConstructorArgValue(this.globalInterceptors); + BeanDefinitionBuilder postProcessorBuilder = BeanDefinitionBuilder + .genericBeanDefinition(BASE_PACKAGE + + GLOBAL_POST_PROCESSOR_CLASSNAME); + postProcessorBuilder + .addConstructorArgValue(this.globalInterceptors); BeanDefinition beanDef = postProcessorBuilder.getBeanDefinition(); - String beanName = BeanDefinitionReaderUtils.generateBeanName( + String beanName = BeanDefinitionReaderUtils.generateBeanName( beanDef, parserContext.getRegistry()); - parserContext.registerBeanComponent(new BeanComponentDefinition(beanDef, beanName)); + parserContext.registerBeanComponent(new BeanComponentDefinition( + beanDef, beanName)); this.postProcessorCreated = true; } } - - protected Object getBeanDefinitionBuilderConstructorValue(Element element, ParserContext parserContext){ - BeanComponentDefinition interceptorBeanDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext); + + protected Object getBeanDefinitionBuilderConstructorValue(Element element, + ParserContext parserContext, BeanDefinitionBuilder parentBuilder) { + BeanComponentDefinition interceptorBeanDefinition = IntegrationNamespaceUtils + .parseInnerHandlerDefinition(element, parserContext); if (interceptorBeanDefinition != null) { return interceptorBeanDefinition; - } - else { - String beanName = element.getAttribute(REF_ATTRIBUTE); + } else { + String beanName = null; + if (element.hasAttribute(REF_ATTRIBUTE)) { + beanName = element.getAttribute(REF_ATTRIBUTE); + + } else { + List els = DomUtils.getChildElements(element); + if (els.isEmpty()) { + parserContext.getReaderContext().error("child BeanDefinition must not be null", element); + } else { + Element child = els.get(0); + if ("wire-tap".equals(child.getLocalName())){ + beanName = new WireTapParser().parse(child, parserContext); + }else { + BeanDefinition beanDef = parserContext.getDelegate().parseCustomElement(child); + beanName = BeanDefinitionReaderUtils.generateBeanName(beanDef, parserContext.getRegistry()); + } + } + } return new RuntimeBeanReference(beanName); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalWireTapParser.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalWireTapParser.java index 7141f90c4e..668e50c3d4 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalWireTapParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/GlobalWireTapParser.java @@ -13,6 +13,7 @@ package org.springframework.integration.config.xml; import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; @@ -24,7 +25,7 @@ import org.w3c.dom.Element; */ public class GlobalWireTapParser extends GlobalChannelInterceptorParser { @Override - protected Object getBeanDefinitionBuilderConstructorValue(Element element, ParserContext parserContext){ + protected Object getBeanDefinitionBuilderConstructorValue(Element element, ParserContext parserContext, BeanDefinitionBuilder parentBuilder){ String wireTapBeanName = new WireTapParser().parse(element, parserContext); return new RuntimeBeanReference(wireTapBeanName); } diff --git a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd index 2975db1e1e..045f72526d 100644 --- a/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd +++ b/spring-integration-core/src/main/resources/org/springframework/integration/config/xml/spring-integration-2.0.xsd @@ -2853,9 +2853,7 @@ Name of the header whose value will be used to route messages - - - + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests-context.xml new file mode 100644 index 0000000000..56f50cd251 --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests-context.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests.java b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests.java new file mode 100644 index 0000000000..ae9cd45cdc --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorSubElementTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2002-2011 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.channel.interceptor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationContext; +import org.springframework.integration.Message; +import org.springframework.integration.MessageChannel; +import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.message.GenericMessage; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author David Turanski + * @since 2.0 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class GlobalChannelInterceptorSubElementTests { + @Autowired + ApplicationContext applicationContext; + + + @Autowired + @Qualifier("inputA") + MessageChannel inputA; + + @Autowired + @Qualifier("wiretap") + PollableChannel wiretapChannel; + + @Test + public void testWiretapSubElement(){ + inputA.send(new GenericMessage("hello")); + Message result = wiretapChannel.receive(100); + assertNotNull(result); + assertEquals("hello",result.getPayload()); + } +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java index 122a1379b8..8002338a8e 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/interceptor/GlobalChannelInterceptorTests.java @@ -16,6 +16,9 @@ package org.springframework.integration.channel.interceptor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -24,30 +27,36 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.Assert; import org.junit.Test; - +import org.junit.runner.RunWith; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.Ordered; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; -import org.springframework.integration.channel.AbstractMessageChannel; import org.springframework.integration.channel.ChannelInterceptor; +import org.springframework.integration.core.PollableChannel; +import org.springframework.integration.message.GenericMessage; import org.springframework.integration.test.util.TestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Oleg Zhurakousky - * @author Dave Turanski + * @author David Turanski * @since 2.0 */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration public class GlobalChannelInterceptorTests { - + @Autowired + ApplicationContext applicationContext; + @Test public void validateGlobalInterceptor() throws Exception{ - ApplicationContext applicationContext = new ClassPathXmlApplicationContext( - "GlobalChannelInterceptorTests-context.xml", GlobalChannelInterceptorTests.class); - Map channels = applicationContext.getBeansOfType(MessageChannel.class); + Map channels = applicationContext.getBeansOfType(MessageChannel.class); for (String channelName : channels.keySet()) { MessageChannel channel = channels.get(channelName); if (channelName.equals("nullChannel")){ @@ -107,12 +116,14 @@ public class GlobalChannelInterceptorTests { } } + + @Autowired + @Qualifier("inpuC") + MessageChannel inpuCchannel; @Test public void testWildCardPatternMatch() { - ApplicationContext applicationContext = new ClassPathXmlApplicationContext( - "GlobalChannelInterceptorTests-context.xml", GlobalChannelInterceptorTests.class); - AbstractMessageChannel channel = applicationContext.getBean("inpuC", AbstractMessageChannel.class); - List interceptorList = TestUtils.getPropertyValue(channel, "interceptors.interceptors", List.class); + + List interceptorList = TestUtils.getPropertyValue(inpuCchannel, "interceptors.interceptors", List.class); List interceptorNames = new ArrayList(); for (Object interceptor : interceptorList) { interceptorNames.add(interceptor.toString()); @@ -121,7 +132,7 @@ public class GlobalChannelInterceptorTests { Assert.assertTrue(interceptorNames.contains("interceptor-eleven")); } - + public static class SampleInterceptor implements ChannelInterceptor { private String testIdentifier;