From e9b85bca18d7289e228404c3ef7cae0ad69f262e Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 27 Jan 2011 16:46:59 -0500 Subject: [PATCH] INT-1727 added namespace support for script-variable-source --- .../groovy/DefaultScriptVariableSource.java | 6 +- .../groovy/config/GroovyScriptParser.java | 57 +++++++++++-------- .../config/spring-integration-groovy-2.0.xsd | 23 +++++++- .../GroovyServiceActivatorTests-context.xml | 9 +++ ...ActivatorTests-fail-withsource-context.xml | 21 +++++++ .../config/GroovyServiceActivatorTests.java | 42 ++++++++++++++ 6 files changed, 129 insertions(+), 29 deletions(-) create mode 100644 spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-fail-withsource-context.xml diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java index c41a7d090c..292d37e12c 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/DefaultScriptVariableSource.java @@ -22,6 +22,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.integration.Message; import org.springframework.util.CollectionUtils; @@ -58,8 +59,9 @@ public class DefaultScriptVariableSource implements BeanFactoryAware, ScriptVari if (!CollectionUtils.isEmpty(variableMap)){ for (String variableName : variableMap.keySet()) { Object variableValue = variableMap.get(variableName); - if (variableValue == null){ - scriptVariables.put(variableName, this.beanFactory.getBean(variableName)); + if (variableValue instanceof RuntimeBeanReference){ + String beanName = ((RuntimeBeanReference)variableValue).getBeanName(); + scriptVariables.put(variableName, this.beanFactory.getBean(beanName)); } else { scriptVariables.put(variableName, variableValue); diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java index 9eabd8e5ad..2ce25e2ecb 100644 --- a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java +++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java @@ -22,6 +22,7 @@ import java.util.Map; import org.w3c.dom.Element; +import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; @@ -66,6 +67,13 @@ public class GroovyScriptParser extends AbstractSingleBeanDefinitionParser { return; } + String scriptVariableSourceName = element.getAttribute("script-variable-source"); + + if (StringUtils.hasText(scriptVariableSourceName) && variableElements.size() > 0){ + parserContext.getReaderContext().error("'script-variable-source' and 'variable' sub-element are mutualy exclusive. Must use one or the other.", element); + return; + } + if (StringUtils.hasText(scriptLocation)){ builder.addConstructorArgValue(this.resolveScriptLocation(element, parserContext.getReaderContext(), scriptLocation)); } @@ -73,33 +81,34 @@ public class GroovyScriptParser extends AbstractSingleBeanDefinitionParser { builder.addConstructorArgValue(new StaticScriptSource(scriptText, "groovy.lang.Script")); } - BeanDefinitionBuilder scriptVariableSource = - BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.groovy.DefaultScriptVariableSource"); - String name = - BeanDefinitionReaderUtils.registerWithGeneratedName(scriptVariableSource.getBeanDefinition(), parserContext.getRegistry()); - builder.addConstructorArgReference(name); - - Map variableMap = new HashMap(); - for (Element childElement : variableElements) { - String variableName = childElement.getAttribute("name"); - String variableValue = childElement.getAttribute("value"); - String variableRef = childElement.getAttribute("ref"); - if (StringUtils.hasText(variableValue) && StringUtils.hasText(variableRef)){ - parserContext.getReaderContext().error("Exactly one of the 'ref' attribute or 'value' attribute, " + - " is required for element " + - IntegrationNamespaceUtils.createElementDescription(element) + ".", element); + if (!StringUtils.hasText(scriptVariableSourceName)){ + BeanDefinitionBuilder scriptVariableSourceBuilder = + BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.groovy.DefaultScriptVariableSource"); + + Map variableMap = new HashMap(); + for (Element childElement : variableElements) { + String variableName = childElement.getAttribute("name"); + String variableValue = childElement.getAttribute("value"); + String variableRef = childElement.getAttribute("ref"); + if (!(StringUtils.hasText(variableValue) ^ StringUtils.hasText(variableRef))) { + parserContext.getReaderContext().error("Exactly one of the 'ref' attribute or 'value' attribute, " + + " is required for element " + + IntegrationNamespaceUtils.createElementDescription(element) + ".", element); + } + if (StringUtils.hasText(variableValue)){ + variableMap.put(variableName, variableValue); + } + else { + variableMap.put(variableName, new RuntimeBeanReference(variableRef)); + } } - if (StringUtils.hasText(variableValue)){ - variableMap.put(variableName, variableValue); - } - else { - // 'null' means that the value will be retrieved from the AC - variableMap.put(variableName, null); + if (!CollectionUtils.isEmpty(variableMap)){ + scriptVariableSourceBuilder.addConstructorArgValue(variableMap); } + scriptVariableSourceName = + BeanDefinitionReaderUtils.registerWithGeneratedName(scriptVariableSourceBuilder.getBeanDefinition(), parserContext.getRegistry()); } - if (!CollectionUtils.isEmpty(variableMap)){ - scriptVariableSource.addConstructorArgValue(variableMap); - } + builder.addConstructorArgReference(scriptVariableSourceName); } private Object resolveScriptLocation(Element element, XmlReaderContext readerContext, String scriptLocation) { diff --git a/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd b/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd index 5f02754019..2e4aebb05b 100644 --- a/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd +++ b/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd @@ -17,24 +17,30 @@ + + + Allows you to define custom Groovy variable bindings. The use of this sub-element is mutually + exclusive with 'script-variable-source' attribute + + - Name of the groovy binding variable + Name of the Groovy binding variable - Value of the groovy binding variable + Value of the Groovy binding variable - Value of the groovy binding variable pointing to a bean reference + Value of the Groovy binding variable pointing to a bean reference @@ -53,6 +59,17 @@ + + + + Reference to the ScriptVariableSource bean. This attribute is mutually + exclusive with 'variable' sub-element + + + + + + diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-context.xml b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-context.xml index 2b11a9b6ae..e82fc89553 100644 --- a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-context.xml +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-context.xml @@ -17,6 +17,15 @@ + + + + + + + diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-fail-withsource-context.xml b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-fail-withsource-context.xml new file mode 100644 index 0000000000..d33efb809c --- /dev/null +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-fail-withsource-context.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java index 8f844e391d..98c8ca06a8 100644 --- a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java +++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java @@ -21,6 +21,9 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import java.util.Date; +import java.util.Map; + import org.junit.Test; import org.junit.runner.RunWith; @@ -30,6 +33,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.groovy.DefaultScriptVariableSource; import org.springframework.integration.support.MessageBuilder; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -47,6 +51,9 @@ public class GroovyServiceActivatorTests { @Autowired private MessageChannel inlineScriptInput; + + @Autowired + private MessageChannel withScriptVariableSource; @Test @@ -71,6 +78,29 @@ public class GroovyServiceActivatorTests { assertNull(replyChannel.receive(0)); } + + @Test + public void withScriptVariableSource() throws Exception{ + QueueChannel replyChannel = new QueueChannel(); + replyChannel.setBeanName("returnAddress"); + for (int i = 1; i <= 3; i++) { + Message message = MessageBuilder.withPayload("test-" + i).setReplyChannel(replyChannel).build(); + this.withScriptVariableSource.send(message); + Thread.sleep(1000); + } + String value1 = (String) replyChannel.receive(0).getPayload(); + String value2 = (String) replyChannel.receive(0).getPayload(); + String value3 = (String) replyChannel.receive(0).getPayload(); + assertTrue(value1.startsWith("groovy-test-1-foo - bar")); + assertTrue(value2.startsWith("groovy-test-2-foo - bar")); + assertTrue(value3.startsWith("groovy-test-3-foo - bar")); + // becouse we are using 'prototype bean the suffix date will be different + + assertFalse(value1.substring(26).equals(value2.substring(26))); + assertFalse(value2.substring(26).equals(value3.substring(26))); + + assertNull(replyChannel.receive(0)); + } @Test public void inlineScript() throws Exception{ @@ -90,5 +120,17 @@ public class GroovyServiceActivatorTests { public void inlineScriptAndVariables() throws Exception{ new ClassPathXmlApplicationContext("GroovyServiceActivatorTests-fail-context.xml", this.getClass()); } + + @Test(expected=BeanDefinitionParsingException.class) + public void variablesAndScriptVariableSource() throws Exception{ + new ClassPathXmlApplicationContext("GroovyServiceActivatorTests-fail-withsource-context.xml", this.getClass()); + } + public static class SampleScriptVariSource extends DefaultScriptVariableSource{ + protected void doResolveScriptVariables(Map variables){ + variables.put("foo", "foo"); + variables.put("bar", "bar"); + variables.put("date", new Date()); + } + } }