diff --git a/spring-integration-groovy/.classpath b/spring-integration-groovy/.classpath
new file mode 100644
index 0000000000..f42fb64cfa
--- /dev/null
+++ b/spring-integration-groovy/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/.project b/spring-integration-groovy/.project
new file mode 100644
index 0000000000..b9917d438b
--- /dev/null
+++ b/spring-integration-groovy/.project
@@ -0,0 +1,29 @@
+
+
+ spring-integration-groovy
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.springframework.ide.eclipse.core.springbuilder
+
+
+
+
+ org.maven.ide.eclipse.maven2Builder
+
+
+
+
+
+ org.maven.ide.eclipse.maven2Nature
+ org.springframework.ide.eclipse.core.springnature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/spring-integration-groovy/.settings/org.eclipse.jdt.core.prefs b/spring-integration-groovy/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..c307b02b01
--- /dev/null
+++ b/spring-integration-groovy/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,6 @@
+#Wed Jul 14 06:20:12 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/spring-integration-groovy/.settings/org.maven.ide.eclipse.prefs b/spring-integration-groovy/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000000..105311c8dd
--- /dev/null
+++ b/spring-integration-groovy/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,9 @@
+#Wed Jul 14 06:19:35 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/spring-integration-groovy/.springBeans b/spring-integration-groovy/.springBeans
new file mode 100644
index 0000000000..dbe284d518
--- /dev/null
+++ b/spring-integration-groovy/.springBeans
@@ -0,0 +1,13 @@
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/pom.xml b/spring-integration-groovy/pom.xml
new file mode 100644
index 0000000000..200415533e
--- /dev/null
+++ b/spring-integration-groovy/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ org.springframework.integration
+ spring-integration-parent
+ 2.0.0.BUILD-SNAPSHOT
+
+ org.springframework.integration
+ spring-integration-groovy
+ jar
+ Spring Integration Groovy Support
+
+
+ org.codehaus.groovy
+ groovy-all
+ 1.7.3
+
+
+ org.springframework.integration
+ spring-integration-core
+ ${project.version}
+
+
+ org.springframework
+ spring-context-support
+ ${org.springframework.version}
+
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+ test
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+ com.springsource.bundlor
+ com.springsource.bundlor.maven
+
+
+
+
diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java
new file mode 100644
index 0000000000..9eda0fa6b2
--- /dev/null
+++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2010 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.groovy;
+
+import groovy.lang.Binding;
+import groovy.lang.GString;
+import groovy.lang.GroovyObject;
+import groovy.lang.Script;
+
+import org.springframework.integration.core.Message;
+import org.springframework.integration.handler.AbstractScriptExecutingMessageProcessor;
+import org.springframework.scripting.ScriptSource;
+import org.springframework.scripting.groovy.GroovyObjectCustomizer;
+import org.springframework.scripting.groovy.GroovyScriptFactory;
+import org.springframework.util.Assert;
+
+/**
+ * @author Dave Syer
+ * @author Mark Fisher
+ * @since 2.0
+ */
+public class GroovyScriptExecutingMessageProcessor extends AbstractScriptExecutingMessageProcessor {
+
+ private final GroovyScriptFactory scriptFactory;
+
+ private final MessageContextBindingCustomizer customizer = new MessageContextBindingCustomizer();
+
+
+ public GroovyScriptExecutingMessageProcessor(ScriptSource scriptSource) {
+ super(scriptSource);
+ this.scriptFactory = new GroovyScriptFactory(this.getClass().getSimpleName(), this.customizer);
+ }
+
+
+ @Override
+ protected Object executeScript(ScriptSource scriptSource, Message> message) throws Exception {
+ synchronized (this) {
+ this.customizer.setMessage(message);
+ Object result = this.scriptFactory.getScriptedObject(scriptSource, null);
+ return (result instanceof GString) ? result.toString() : result;
+ }
+ }
+
+
+ private static class MessageContextBindingCustomizer implements GroovyObjectCustomizer {
+
+ private volatile Message> message;
+
+ public void setMessage(Message> message) {
+ this.message = message;
+ }
+
+ public void customize(GroovyObject goo) {
+ Assert.state(goo instanceof Script, "Expected a Script");
+ if (this.message != null) {
+ Binding binding = ((Script) goo).getBinding();
+ binding.setVariable("payload", this.message.getPayload());
+ binding.setVariable("headers", this.message.getHeaders());
+ }
+ }
+ }
+
+}
diff --git a/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyNamespaceHandler.java b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyNamespaceHandler.java
new file mode 100644
index 0000000000..6ba09f2db3
--- /dev/null
+++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyNamespaceHandler.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+public class GroovyNamespaceHandler extends AbstractIntegrationNamespaceHandler {
+
+ public void init() {
+ this.registerBeanDefinitionParser("script", new GroovyScriptParser());
+ }
+
+}
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
new file mode 100644
index 0000000000..8f811ba512
--- /dev/null
+++ b/spring-integration-groovy/src/main/java/org/springframework/integration/groovy/config/GroovyScriptParser.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.beans.factory.xml.XmlReaderContext;
+import org.springframework.scripting.support.StaticScriptSource;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+public class GroovyScriptParser extends AbstractSingleBeanDefinitionParser {
+
+ private static final String LOCATION_ATTRIBUTE = "location";
+
+
+ @Override
+ protected String getBeanClassName(Element element) {
+ return "org.springframework.integration.groovy.GroovyScriptExecutingMessageProcessor";
+ }
+
+ @Override
+ protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ builder.addConstructorArgValue(this.resolveScriptSource(element, parserContext.getReaderContext()));
+ }
+
+ private Object resolveScriptSource(Element element, XmlReaderContext readerContext) {
+ boolean hasScriptLocation = element.hasAttribute(LOCATION_ATTRIBUTE);
+ String scriptText = DomUtils.getTextValue(element);
+ if (!(hasScriptLocation ^ StringUtils.hasText(scriptText))) {
+ readerContext.error("Either the 'location' attribute or inline script text must be provided, but not both.", element);
+ return null;
+ }
+ else if (hasScriptLocation) {
+ BeanDefinitionBuilder resourceScriptSourceBuilder =
+ BeanDefinitionBuilder.genericBeanDefinition("org.springframework.scripting.support.ResourceScriptSource");
+ resourceScriptSourceBuilder.addConstructorArgValue(element.getAttribute(LOCATION_ATTRIBUTE));
+ return resourceScriptSourceBuilder.getBeanDefinition();
+ }
+ return new StaticScriptSource(scriptText, "groovy.lang.Script");
+ }
+
+}
diff --git a/spring-integration-groovy/src/main/resources/META-INF/spring.handlers b/spring-integration-groovy/src/main/resources/META-INF/spring.handlers
new file mode 100644
index 0000000000..c48911e4db
--- /dev/null
+++ b/spring-integration-groovy/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@
+http\://www.springframework.org/schema/integration/groovy=org.springframework.integration.groovy.config.GroovyNamespaceHandler
diff --git a/spring-integration-groovy/src/main/resources/META-INF/spring.schemas b/spring-integration-groovy/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 0000000000..45e7980e12
--- /dev/null
+++ b/spring-integration-groovy/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1,2 @@
+http\://www.springframework.org/schema/integration/groovy/spring-integration-groovy-2.0.xsd=org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd
+http\://www.springframework.org/schema/integration/groovy/spring-integration-groovy.xsd=org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd
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
new file mode 100644
index 0000000000..1898d8a6b6
--- /dev/null
+++ b/spring-integration-groovy/src/main/resources/org/springframework/integration/groovy/config/spring-integration-groovy-2.0.xsd
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+ Configures an inner bean that will generate a Groovy Script.
+
+
+
+
+
+
+
+
+ Resource location path for the Script. Either this or an inline script
+ as body text should be provided, but not both.
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyExpressionTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyExpressionTests.java
new file mode 100644
index 0000000000..db9f2abc65
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyExpressionTests.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2002-2010 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.groovy;
+
+import static org.junit.Assert.assertEquals;
+
+import groovy.lang.GroovyObject;
+import groovy.lang.Script;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.Executors;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.scripting.groovy.GroovyObjectCustomizer;
+import org.springframework.scripting.groovy.GroovyScriptFactory;
+import org.springframework.scripting.support.ResourceScriptSource;
+import org.springframework.util.Assert;
+
+/**
+ * @author Dave Syer
+ */
+public class GroovyExpressionTests {
+
+ private static Log logger = LogFactory.getLog(GroovyExpressionTests.class);
+
+ @Before
+ public void setLogLevel() {
+ LogManager.getLogger(getClass()).setLevel(Level.DEBUG);
+ }
+
+ @After
+ public void resetLogLevel() {
+ LogManager.getLogger(getClass()).setLevel(Level.INFO);
+ }
+
+ @Test
+ public void testScriptFactoryCustomizer() throws Exception {
+ Customizer customizer = new Customizer(Collections.singletonMap("name", (Object) "foo"));
+ GroovyScriptFactory factory = new GroovyScriptFactory("Groovy Script", customizer);
+ ResourceScriptSource scriptSource = new ResourceScriptSource(new NamedByteArrayResource("\"name=${name}\"".getBytes(), "InlineScript"));
+ Object scriptedObject = factory.getScriptedObject(scriptSource, null);
+ assertEquals("name=foo", scriptedObject.toString());
+ customizer.setMap(Collections.singletonMap("name", (Object) "bar"));
+ scriptedObject = factory.getScriptedObject(scriptSource, null);
+ assertEquals("name=bar", scriptedObject.toString());
+ }
+
+ @Test
+ public void testScriptFactoryCustomizerThreadSafety() throws Exception {
+ final Customizer customizer = new Customizer(Collections.singletonMap("name", (Object) "foo"));
+ final GroovyScriptFactory factory = new GroovyScriptFactory("Groovy Script", customizer);
+ final ResourceScriptSource scriptSource = new ResourceScriptSource(new NamedByteArrayResource(
+ "\"name=${name}\"".getBytes(), "InlineScript"));
+ Object scriptedObject = factory.getScriptedObject(scriptSource, null);
+ assertEquals("name=foo", scriptedObject.toString());
+ CompletionService completionService = new ExecutorCompletionService(Executors.newFixedThreadPool(10));
+ for (int i = 0; i < 100; i++) {
+ final String name = "bar" + i;
+ completionService.submit(new Callable() {
+ public String call() throws Exception {
+ Object scriptedObject;
+ synchronized (customizer) {
+ customizer.setMap(Collections.singletonMap("name", (Object) name));
+ scriptedObject = factory.getScriptedObject(scriptSource, null);
+ }
+ String result = scriptedObject.toString();
+ logger.debug("Result=" + result + " with name=" + name);
+ if (!("name=" + name).equals(result)) {
+ throw new IllegalStateException("Wrong value (" + result + ") for: " + name);
+ }
+ return name;
+ }
+ });
+ }
+ Set set = new HashSet();
+ for (int i = 0; i < 100; i++) {
+ set.add(completionService.take().get());
+ }
+ assertEquals(100, set.size());
+ }
+
+ @Test
+ public void testScriptFactoryCustomizerStatic() throws Exception {
+ final Customizer customizer = new Customizer(Collections.singletonMap("name", (Object) "foo"));
+ final GroovyScriptFactory factory = new GroovyScriptFactory("Groovy Script", customizer);
+ final ResourceScriptSource scriptSource = new ResourceScriptSource(new NamedByteArrayResource(
+ "\"name=${name}\"".getBytes(), "InlineScript"));
+ Object scriptedObject = factory.getScriptedObject(scriptSource, null);
+ assertEquals("name=foo", scriptedObject.toString());
+ CompletionService completionService = new ExecutorCompletionService(Executors.newFixedThreadPool(10));
+ for (int i = 0; i < 100; i++) {
+ final String name = "bar" + i;
+ completionService.submit(new Callable() {
+ public String call() throws Exception {
+ Object scriptedObject = factory.getScriptedObject(scriptSource, null);
+ String result = scriptedObject.toString();
+ logger.debug("Result=" + result + " with name=" + name);
+ if (!("name=foo").equals(result)) {
+ throw new IllegalStateException("Wrong value (" + result + ") for: " + name);
+ }
+ return name;
+ }
+ });
+ }
+ Set set = new HashSet();
+ for (int i = 0; i < 100; i++) {
+ set.add(completionService.take().get());
+ }
+ assertEquals(100, set.size());
+ }
+
+ @Test
+ public void testScriptFactoryCustomizerThreadSafetyWithNewScript() throws Exception {
+ final Customizer customizer = new Customizer(Collections.singletonMap("name", (Object) "foo"));
+ final GroovyScriptFactory factory = new GroovyScriptFactory("Groovy Script", customizer);
+ CompletionService completionService = new ExecutorCompletionService(Executors.newFixedThreadPool(5));
+ for (int i = 0; i < 100; i++) {
+ final String name = "Bar" + i;
+ completionService.submit(new Callable() {
+ public String call() throws Exception {
+ Object scriptedObject;
+ synchronized (customizer) {
+ customizer.setMap(Collections.singletonMap("name", (Object) name));
+ ResourceScriptSource scriptSource = new ResourceScriptSource(new NamedByteArrayResource(
+ "\"name=${name}\"".getBytes(), "InlineScript" + name));
+ scriptedObject = factory.getScriptedObject(scriptSource, null);
+ }
+ String result = scriptedObject.toString();
+ logger.debug("Result=" + result + " with name=" + name);
+ if (!("name=" + name).equals(result)) {
+ throw new IllegalStateException("Wrong value (" + result + ") for: " + name);
+ }
+ return name;
+ }
+ });
+ }
+ Set set = new HashSet();
+ for (int i = 0; i < 100; i++) {
+ set.add(completionService.take().get());
+ }
+ assertEquals(100, set.size());
+ }
+
+
+ private static class Customizer implements GroovyObjectCustomizer {
+
+ private Map map = new HashMap();
+
+ public Customizer(Map map) {
+ super();
+ this.map.putAll(map);
+ }
+
+ public void customize(GroovyObject goo) {
+ Assert.state(goo instanceof Script, "Expected a Script");
+ for (Map.Entry entry : map.entrySet()) {
+ ((Script) goo).getBinding().setVariable(entry.getKey(), entry.getValue());
+ }
+ }
+
+ public void setMap(Map map) {
+ this.map.clear();
+ this.map.putAll(map);
+ }
+ }
+
+
+ private static class NamedByteArrayResource extends ByteArrayResource {
+
+ private final String fileName;
+
+ public NamedByteArrayResource(byte[] bytes, String fileName) {
+ super(bytes);
+ this.fileName = fileName;
+ }
+
+ @Override
+ public String getFilename() throws IllegalStateException {
+ return fileName;
+ }
+
+ }
+
+}
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java
new file mode 100644
index 0000000000..86633732fe
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessorTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2010 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.groovy;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Test;
+
+import org.springframework.core.io.AbstractResource;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.handler.MessageProcessor;
+import org.springframework.integration.message.MessageBuilder;
+import org.springframework.scripting.ScriptSource;
+import org.springframework.scripting.support.ResourceScriptSource;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+public class GroovyScriptExecutingMessageProcessorTests {
+
+ @Test
+ public void simpleTest() throws Exception {
+ String script = "return \"payload is $payload, header is $headers.testHeader\"";
+ Message> message = MessageBuilder.withPayload("foo").setHeader("testHeader", "bar").build();
+ TestResource resource = new TestResource(script, "simpleTest");
+ ScriptSource scriptSource = new ResourceScriptSource(resource);
+ MessageProcessor processor = new GroovyScriptExecutingMessageProcessor(scriptSource);
+ Object result = processor.processMessage(message);
+ assertEquals("payload is foo, header is bar", result.toString());
+ }
+
+
+ private static class TestResource extends AbstractResource {
+
+ private final String scriptString;
+
+ private final String filename;
+
+ private TestResource(String scriptString, String filename) {
+ this.scriptString = scriptString;
+ this.filename = filename;
+ }
+
+ public String getDescription() {
+ return "test";
+ }
+
+ @Override
+ public String getFilename() {
+ return this.filename;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(scriptString.getBytes("UTF-8"));
+ }
+ }
+
+}
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests-context.xml b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests-context.xml
new file mode 100644
index 0000000000..697f86f85a
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests-context.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests.groovy b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests.groovy
new file mode 100644
index 0000000000..3896defe15
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests.groovy
@@ -0,0 +1 @@
+return headers.type == 'good'
\ No newline at end of file
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests.java
new file mode 100644
index 0000000000..29a657e70e
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyFilterTests.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.message.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class GroovyFilterTests {
+
+ @Autowired
+ private MessageChannel referencedScriptInput;
+
+ @Autowired
+ private MessageChannel inlineScriptInput;
+
+
+ @Test
+ public void referencedScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ Message> message1 = MessageBuilder.withPayload("test-1")
+ .setReplyChannel(replyChannel)
+ .setHeader("type", "bad")
+ .build();
+ Message> message2 = MessageBuilder.withPayload("test-2")
+ .setReplyChannel(replyChannel)
+ .setHeader("type", "good")
+ .build();
+ this.referencedScriptInput.send(message1);
+ this.referencedScriptInput.send(message2);
+ assertEquals("test-2", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+ @Test
+ public void inlineScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ Message> message1 = MessageBuilder.withPayload("bad").setReplyChannel(replyChannel).build();
+ Message> message2 = MessageBuilder.withPayload("good").setReplyChannel(replyChannel).build();
+ this.inlineScriptInput.send(message1);
+ this.inlineScriptInput.send(message2);
+ Message> received = replyChannel.receive(0);
+ assertNotNull(received);
+ assertEquals("good", received.getPayload());
+ assertEquals(message2, received);
+ assertNull(replyChannel.receive(0));
+ }
+
+}
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests-context.xml b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests-context.xml
new file mode 100644
index 0000000000..2531b258d0
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests-context.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5 ? 'longStrings' : 'shortStrings'
+ ]]>
+
+
+
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests.groovy b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests.groovy
new file mode 100644
index 0000000000..a78de43119
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests.groovy
@@ -0,0 +1 @@
+return payload.length() > 3 ? 'longStrings' : 'shortStrings'
\ No newline at end of file
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests.java
new file mode 100644
index 0000000000..248e0b748b
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyRouterTests.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.channel.PollableChannel;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.message.StringMessage;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class GroovyRouterTests {
+
+ @Autowired
+ private MessageChannel referencedScriptInput;
+
+ @Autowired
+ private MessageChannel inlineScriptInput;
+
+ @Autowired
+ private PollableChannel longStrings;
+
+ @Autowired
+ private PollableChannel shortStrings;
+
+
+ @Test
+ public void referencedScript() { // long is > 3
+ Message> message1 = new StringMessage("aardvark");
+ Message> message2 = new StringMessage("bear");
+ Message> message3 = new StringMessage("cat");
+ Message> message4 = new StringMessage("dog");
+ Message> message5 = new StringMessage("elephant");
+ this.referencedScriptInput.send(message1);
+ this.referencedScriptInput.send(message2);
+ this.referencedScriptInput.send(message3);
+ this.referencedScriptInput.send(message4);
+ this.referencedScriptInput.send(message5);
+ assertEquals("cat", shortStrings.receive(0).getPayload());
+ assertEquals("dog", shortStrings.receive(0).getPayload());
+ assertEquals("aardvark", longStrings.receive(0).getPayload());
+ assertEquals("bear", longStrings.receive(0).getPayload());
+ assertEquals("elephant", longStrings.receive(0).getPayload());
+ assertNull(shortStrings.receive(0));
+ assertNull(longStrings.receive(0));
+ }
+
+ @Test
+ public void inlineScript() { // long is > 5
+ Message> message1 = new StringMessage("aardvark");
+ Message> message2 = new StringMessage("bear");
+ Message> message3 = new StringMessage("cat");
+ Message> message4 = new StringMessage("dog");
+ Message> message5 = new StringMessage("elephant");
+ this.inlineScriptInput.send(message1);
+ this.inlineScriptInput.send(message2);
+ this.inlineScriptInput.send(message3);
+ this.inlineScriptInput.send(message4);
+ this.inlineScriptInput.send(message5);
+ assertEquals("bear", shortStrings.receive(0).getPayload());
+ assertEquals("cat", shortStrings.receive(0).getPayload());
+ assertEquals("dog", shortStrings.receive(0).getPayload());
+ assertEquals("aardvark", longStrings.receive(0).getPayload());
+ assertEquals("elephant", longStrings.receive(0).getPayload());
+ assertNull(shortStrings.receive(0));
+ assertNull(longStrings.receive(0));
+ }
+
+}
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
new file mode 100644
index 0000000000..94001f2757
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests-context.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.groovy b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.groovy
new file mode 100644
index 0000000000..96fa19d96a
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.groovy
@@ -0,0 +1 @@
+return "groovy-$payload"
\ No newline at end of file
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
new file mode 100644
index 0000000000..3047f8729b
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyServiceActivatorTests.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.message.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class GroovyServiceActivatorTests {
+
+ @Autowired
+ private MessageChannel referencedScriptInput;
+
+ @Autowired
+ private MessageChannel inlineScriptInput;
+
+
+ @Test
+ public void referencedScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ for (int i = 1; i <= 3; i++) {
+ Message> message = MessageBuilder.withPayload("test-" + i).setReplyChannel(replyChannel).build();
+ this.referencedScriptInput.send(message);
+ }
+ assertEquals("groovy-test-1", replyChannel.receive(0).getPayload());
+ assertEquals("groovy-test-2", replyChannel.receive(0).getPayload());
+ assertEquals("groovy-test-3", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+ @Test
+ public void inlineScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ for (int i = 1; i <= 3; i++) {
+ Message> message = MessageBuilder.withPayload("test-" + i).setReplyChannel(replyChannel).build();
+ this.inlineScriptInput.send(message);
+ }
+ assertEquals("inline-test-1", replyChannel.receive(0).getPayload());
+ assertEquals("inline-test-2", replyChannel.receive(0).getPayload());
+ assertEquals("inline-test-3", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+}
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests-context.xml b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests-context.xml
new file mode 100644
index 0000000000..a05ebe66a8
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests-context.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests.groovy b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests.groovy
new file mode 100644
index 0000000000..9189295ee4
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests.groovy
@@ -0,0 +1 @@
+return payload.split(',')
\ No newline at end of file
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests.java
new file mode 100644
index 0000000000..14ee9dd7e7
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovySplitterTests.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.message.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class GroovySplitterTests {
+
+ @Autowired
+ private MessageChannel referencedScriptInput;
+
+ @Autowired
+ private MessageChannel inlineScriptInput;
+
+
+ @Test
+ public void referencedScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ Message> message = MessageBuilder.withPayload("x,y,z").setReplyChannel(replyChannel).build();
+ this.referencedScriptInput.send(message);
+ assertEquals("x", replyChannel.receive(0).getPayload());
+ assertEquals("y", replyChannel.receive(0).getPayload());
+ assertEquals("z", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+ @Test
+ public void inlineScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ Message> message = MessageBuilder.withPayload("a b c").setReplyChannel(replyChannel).build();
+ this.inlineScriptInput.send(message);
+ assertEquals("a", replyChannel.receive(0).getPayload());
+ assertEquals("b", replyChannel.receive(0).getPayload());
+ assertEquals("c", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+}
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests-context.xml b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests-context.xml
new file mode 100644
index 0000000000..818dfc6bc2
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests-context.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests.groovy b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests.groovy
new file mode 100644
index 0000000000..96fa19d96a
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests.groovy
@@ -0,0 +1 @@
+return "groovy-$payload"
\ No newline at end of file
diff --git a/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests.java b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests.java
new file mode 100644
index 0000000000..96d1c31e78
--- /dev/null
+++ b/spring-integration-groovy/src/test/java/org/springframework/integration/groovy/config/GroovyTransformerTests.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2002-2010 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.groovy.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.core.Message;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.message.MessageBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ * @since 2.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class GroovyTransformerTests {
+
+ @Autowired
+ private MessageChannel referencedScriptInput;
+
+ @Autowired
+ private MessageChannel inlineScriptInput;
+
+
+ @Test
+ public void referencedScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ for (int i = 1; i <= 3; i++) {
+ Message> message = MessageBuilder.withPayload("test-" + i).setReplyChannel(replyChannel).build();
+ this.referencedScriptInput.send(message);
+ }
+ assertEquals("groovy-test-1", replyChannel.receive(0).getPayload());
+ assertEquals("groovy-test-2", replyChannel.receive(0).getPayload());
+ assertEquals("groovy-test-3", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+ @Test
+ public void inlineScript() {
+ QueueChannel replyChannel = new QueueChannel();
+ replyChannel.setBeanName("returnAddress");
+ for (int i = 1; i <= 3; i++) {
+ Message> message = MessageBuilder.withPayload("test-" + i).setReplyChannel(replyChannel).build();
+ this.inlineScriptInput.send(message);
+ }
+ assertEquals("inline-test-1", replyChannel.receive(0).getPayload());
+ assertEquals("inline-test-2", replyChannel.receive(0).getPayload());
+ assertEquals("inline-test-3", replyChannel.receive(0).getPayload());
+ assertNull(replyChannel.receive(0));
+ }
+
+}
diff --git a/spring-integration-groovy/template.mf b/spring-integration-groovy/template.mf
new file mode 100644
index 0000000000..7cb50fcb05
--- /dev/null
+++ b/spring-integration-groovy/template.mf
@@ -0,0 +1,9 @@
+Bundle-SymbolicName: org.springframework.integration.groovy
+Bundle-Name: Spring Integration Groovy Support
+Bundle-Vendor: SpringSource
+Bundle-ManifestVersion: 2
+Import-Template:
+ org.apache.commons.logging;version="[1.1.1, 2.0.0)",
+ org.springframework.integration.*;version="[2.0.0, 2.0.1)",
+ org.springframework.*;version="[3.0.0, 4.0.0)",
+ groovy.*;version="[1.7.3, 2.0.0)"