diff --git a/build.gradle b/build.gradle index 4d4e867cb2..689c86d122 100644 --- a/build.gradle +++ b/build.gradle @@ -408,6 +408,7 @@ project('spring-integration-scripting') { testCompile project(":spring-integration-test") testCompile("org.jruby:jruby:1.6.3") testCompile("org.codehaus.groovy:groovy-all:1.7.5") + testCompile("org.python:jython-standalone:2.5.2") } } diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/ScriptExecutor.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/ScriptExecutor.java index 7d260cbd18..9530901b09 100644 --- a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/ScriptExecutor.java +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/ScriptExecutor.java @@ -35,5 +35,6 @@ public interface ScriptExecutor { * @param variables -bind variable * @return */ - public abstract Object executeScript(ScriptSource scriptSource,Map variables); + public abstract Object executeScript(ScriptSource scriptSource,Map variables); + } \ No newline at end of file diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/config/jsr223/ScriptParser.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/config/jsr223/ScriptParser.java index dd04bcc637..f5fde7a4e6 100644 --- a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/config/jsr223/ScriptParser.java +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/config/jsr223/ScriptParser.java @@ -19,7 +19,7 @@ package org.springframework.integration.scripting.config.jsr223; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.integration.scripting.config.AbstractScriptParser; -import org.springframework.integration.scripting.jsr223.DefaultScriptExecutor; +import org.springframework.integration.scripting.jsr223.ScriptExecutorFactory; import org.springframework.util.Assert; import org.w3c.dom.Element; @@ -47,7 +47,7 @@ public class ScriptParser extends AbstractScriptParser { protected void postProcess(BeanDefinitionBuilder builder, Element element, ParserContext parserContext){ String language = element.getAttribute(LANGUAGE_ATTRIBUTE); Assert.hasLength(language, "Attribute " + LANGUAGE_ATTRIBUTE + " is required"); - builder.addConstructorArgValue(new DefaultScriptExecutor(language)); + builder.addConstructorArgValue(ScriptExecutorFactory.getScriptExecutor(language)); } diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/AbstractScriptExecutor.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/AbstractScriptExecutor.java new file mode 100644 index 0000000000..e07a4afe67 --- /dev/null +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/AbstractScriptExecutor.java @@ -0,0 +1,103 @@ +/* + * 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.scripting.jsr223; + +import java.io.IOException; +import java.util.Date; +import java.util.Map; +import java.util.Map.Entry; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.integration.scripting.ScriptExecutor; +import org.springframework.scripting.ScriptSource; +import org.springframework.util.Assert; + +/** + * Base Class for {@link ScriptExecutor} + * + * @author David Turanski + * @author Mark Fisher + * @since 2.1 + */ +abstract class AbstractScriptExecutor implements ScriptExecutor { + + protected final Log logger = LogFactory.getLog(this.getClass()); + + protected final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); + + protected final String language; + + public AbstractScriptExecutor(String language) { + Assert.hasText(language, "language must not be empty"); + this.language = language; + if (logger.isDebugEnabled()) { + logger.debug("using script engine : " + scriptEngineManager.getEngineByName(language).getFactory().getEngineName()); + for (String name:scriptEngineManager.getEngineByName(language).getFactory().getNames()){ + logger.debug("name=" + name); + } + } + } + + + public Object executeScript(ScriptSource scriptSource) { + return this.executeScript(scriptSource, null); + } + + public Object executeScript(ScriptSource scriptSource, Map variables) { + Object result = null; + ScriptEngine scriptEngine = this.scriptEngineManager.getEngineByName(this.language); + try { + if (variables != null) { + for (Entry entry : variables.entrySet()) { + scriptEngine.put(entry.getKey(), entry.getValue()); + } + } + String script = scriptSource.getScriptAsString(); + Date start = new Date(); + if (logger.isDebugEnabled()) { + logger.debug("executing script: " + script); + } + + result = scriptEngine.eval(script); + + result = postProcess(result, scriptEngine, script); + + if (logger.isDebugEnabled()) { + logger.debug("script executed in " + (new Date().getTime() - start.getTime()) + " ms"); + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + catch (ScriptException e) { + throw new RuntimeException(e); + } + return result; + } + + + /** + * Subclasses may implement this to provide any special handling required + * @param result + * @param scriptEngine + * @param script + * @return modified result + */ + protected abstract Object postProcess(Object result, ScriptEngine scriptEngine, String script); + +} diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/DefaultScriptExecutor.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/DefaultScriptExecutor.java index ce23ce3f77..6cd18542b3 100644 --- a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/DefaultScriptExecutor.java +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/DefaultScriptExecutor.java @@ -12,88 +12,36 @@ */ package org.springframework.integration.scripting.jsr223; -import java.io.IOException; -import java.util.Date; -import java.util.Map; -import java.util.Map.Entry; - import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.integration.scripting.ScriptExecutor; -import org.springframework.scripting.ScriptSource; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; /** - * Executes JSR223 scripts + * Default implementation of the {@link ScriptExecutor} * * @author David Turanski * @author Mark Fisher * @since 2.1 */ -public class DefaultScriptExecutor implements ScriptExecutor { - - private static final Log logger = LogFactory.getLog(DefaultScriptExecutor.class); - - static { - if (ClassUtils.isPresent("org.jruby.embed.jsr223.JRubyEngine", System.class.getClassLoader())) { - System.setProperty("org.jruby.embed.localvariable.behavior", "transient"); - System.setProperty("org.jruby.embed.localcontext.scope", "threadsafe"); - } - } - - - private final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); - - private final String language; - - + class DefaultScriptExecutor extends AbstractScriptExecutor { /** - * Create a DefaultScriptExceutor for the specified language name (JSR233 alias). + * Create a DefaultScriptExceutor for the specified language name (JSR233 + * alias). */ public DefaultScriptExecutor(String language) { - Assert.hasText(language, "language must not be empty"); - this.language = language; - if (logger.isDebugEnabled()) { - logger.debug("using script engine : " + scriptEngineManager.getEngineByName(language).getFactory().getEngineName()); - } + super(language); } - - public Object executeScript(ScriptSource scriptSource) { - return this.executeScript(scriptSource, null); - } - - public Object executeScript(ScriptSource scriptSource, Map variables) { - Object result = null; - ScriptEngine scriptEngine = this.scriptEngineManager.getEngineByName(this.language); - try { - if (variables != null) { - for (Entry entry : variables.entrySet()) { - scriptEngine.put(entry.getKey(), entry.getValue()); - } - } - String script = scriptSource.getScriptAsString(); - Date start = new Date(); - if (logger.isDebugEnabled()) { - logger.debug("executing script: " + script); - } - result = scriptEngine.eval(script); - if (logger.isDebugEnabled()) { - logger.debug("script executed in " + (new Date().getTime() - start.getTime()) + " ms"); - } - } - catch (IOException e) { - throw new RuntimeException(e); - } - catch (ScriptException e) { - throw new RuntimeException(e); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.integration.scripting.jsr223.AbstractScriptExecutor + * #postProcess(java.lang.Object, javax.script.ScriptEngine, + * java.lang.String) + */ + @Override + protected Object postProcess(Object result, ScriptEngine scriptEngine, String script) { return result; } diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/PythonScriptExecutor.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/PythonScriptExecutor.java new file mode 100644 index 0000000000..f4c3bc820a --- /dev/null +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/PythonScriptExecutor.java @@ -0,0 +1,59 @@ +/* + * 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.scripting.jsr223; + +import javax.script.ScriptEngine; + +import org.springframework.integration.scripting.ScriptExecutor; + +/** + * A {@link ScriptExecutor} that implements special handling required for Python to emulate behavior similar to other JSR223 scripting languages. + *

+ * Script evaluation using the Jython implementation results in a null return value for normal variable expressions such as + * x=2. As a work around, it is necessary to get the value of 'x' explicitly following the script evaluation. This class performs + * simple parsing on the last line of the script to obtain the variable name, if any, and return its value. + * + * @author David Turanski + * @since 2.1 + * + */ + class PythonScriptExecutor extends AbstractScriptExecutor { + /** + * @param language + */ + public PythonScriptExecutor() { + super("python"); + } + + /* (non-Javadoc) + * @see org.springframework.integration.scripting.jsr223.AbstractScriptExecutor#postProcess(java.lang.Object, javax.script.ScriptEngine, java.lang.String) + */ + @Override + protected Object postProcess(Object result, ScriptEngine scriptEngine, String script) { + Object newResult= result; + if (newResult == null) { + String returnVariableName = PythonVariableParser.parseReturnVariable(script); + newResult = scriptEngine.get(returnVariableName); + } + return newResult; + } + + public static class PythonVariableParser { + public static String parseReturnVariable(String script){ + String[] lines = script.trim().split("\n"); + String lastLine = lines[lines.length -1]; + String[] tokens = lastLine.split("="); + return tokens[0].trim(); + } + } +} diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/RubyScriptExecutor.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/RubyScriptExecutor.java new file mode 100644 index 0000000000..8e7efb799e --- /dev/null +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/RubyScriptExecutor.java @@ -0,0 +1,35 @@ +/* + * 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.scripting.jsr223; + +import org.springframework.util.ClassUtils; + + +/** + * @author David Turanski + * @since 2.1 + * + */ + class RubyScriptExecutor extends DefaultScriptExecutor { + + static { + if (ClassUtils.isPresent("org.jruby.embed.jsr223.JRubyEngine", System.class.getClassLoader())) { + System.setProperty("org.jruby.embed.localvariable.behavior", "transient"); + System.setProperty("org.jruby.embed.localcontext.scope", "threadsafe"); + } + } + + public RubyScriptExecutor() { + super("ruby"); + } +} diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutingMessageProcessor.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutingMessageProcessor.java index ccb12ade69..b20be7cf6c 100644 --- a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutingMessageProcessor.java +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutingMessageProcessor.java @@ -28,7 +28,7 @@ import org.springframework.util.Assert; */ public class ScriptExecutingMessageProcessor extends AbstractScriptExecutingMessageProcessor { - private final DefaultScriptExecutor scriptExecutor; + private final ScriptExecutor scriptExecutor; private volatile ScriptSource scriptSource; @@ -37,7 +37,7 @@ public class ScriptExecutingMessageProcessor extends AbstractScriptExecutingMess * @param scriptSource * @param scriptExecutor */ - public ScriptExecutingMessageProcessor(ScriptSource scriptSource, DefaultScriptExecutor scriptExecutor) { + public ScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptExecutor scriptExecutor) { super(); this.scriptSource = scriptSource; this.scriptExecutor = scriptExecutor; @@ -48,7 +48,7 @@ public class ScriptExecutingMessageProcessor extends AbstractScriptExecutingMess * @param scriptSource * @param scriptExecutor */ - public ScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptVariableGenerator scriptVariableGenerator,DefaultScriptExecutor scriptExecutor) { + public ScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptVariableGenerator scriptVariableGenerator, ScriptExecutor scriptExecutor) { super(scriptVariableGenerator); this.scriptSource = scriptSource; this.scriptExecutor = scriptExecutor; @@ -60,7 +60,7 @@ public class ScriptExecutingMessageProcessor extends AbstractScriptExecutingMess * @param scriptExecutor * @param variables */ - public ScriptExecutingMessageProcessor(ScriptSource scriptSource,DefaultScriptExecutor scriptExecutor,Map variables ) { + public ScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptExecutor scriptExecutor,Map variables ) { super(new DefaultScriptVariableGenerator(variables)); this.scriptSource = scriptSource; this.scriptExecutor = scriptExecutor; diff --git a/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutorFactory.java b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutorFactory.java new file mode 100644 index 0000000000..9759907438 --- /dev/null +++ b/spring-integration-scripting/src/main/java/org/springframework/integration/scripting/jsr223/ScriptExecutorFactory.java @@ -0,0 +1,33 @@ +/* + * 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.scripting.jsr223; + +import org.springframework.integration.scripting.ScriptExecutor; + +/** + * @author David Turanski + * @since 2.1 + */ +public class ScriptExecutorFactory { + + private ScriptExecutorFactory(){}; + public static ScriptExecutor getScriptExecutor(String language) { + if (language.equalsIgnoreCase("python") || language.equalsIgnoreCase("jython")){ + return new PythonScriptExecutor(); + } + else if (language.equalsIgnoreCase("ruby") || language.equalsIgnoreCase("jruby")) { + return new RubyScriptExecutor(); + } + return new DefaultScriptExecutor(language); + } +} diff --git a/spring-integration-scripting/src/main/resources/org/springframework/integration/scripting/config/spring-integration-scripting-2.1.xsd b/spring-integration-scripting/src/main/resources/org/springframework/integration/scripting/config/spring-integration-scripting-2.1.xsd index c231e310a6..9c530d2e63 100644 --- a/spring-integration-scripting/src/main/resources/org/springframework/integration/scripting/config/spring-integration-scripting-2.1.xsd +++ b/spring-integration-scripting/src/main/resources/org/springframework/integration/scripting/config/spring-integration-scripting-2.1.xsd @@ -26,6 +26,13 @@ + + + + The script variable to return as a result of the evaluation (Optional). + + + diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223RouterTests.js b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223RouterTests.js index 05feab9deb..dd4081c82e 100644 --- a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223RouterTests.js +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223RouterTests.js @@ -1,5 +1,4 @@ - -function route(max){ - return payload.length > max ? "longStrings" : "shortStrings"; +function route(max) { + return payload.length > max ? "longStrings" : "shortStrings"; } route(maxLen); diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests-context.xml b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests-context.xml index 9a276a2bcb..6949921b6a 100644 --- a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests-context.xml +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests-context.xml @@ -11,8 +11,8 @@ + lang="python" + location="org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.py"> diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.java b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.java index a31110522e..b080e35570 100644 --- a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.java +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.java @@ -21,7 +21,6 @@ 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.HashMap; import java.util.Map; @@ -43,27 +42,25 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Mark Fisher * @author Oleg Zhurakousky + * @author David Turanski * @since 2.0 */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) public class Jsr223ServiceActivatorTests { - + @Autowired private MessageChannel referencedScriptInput; @Autowired private MessageChannel inlineScriptInput; - + @Autowired private MessageChannel withScriptVariableGenerator; - - - @Test - public void referencedScriptAndCustomiser() throws Exception{ - + public void referencedScript() throws Exception { + QueueChannel replyChannel = new QueueChannel(); replyChannel.setBeanName("returnAddress"); for (int i = 1; i <= 3; i++) { @@ -75,20 +72,21 @@ public class Jsr223ServiceActivatorTests { String value2 = (String) replyChannel.receive(0).getPayload(); String value3 = (String) replyChannel.receive(0).getPayload(); System.out.println(value1 + "\n" + value2 + "\n" + value3); - assertTrue(value1.startsWith("ruby-test-1-foo - bar")); - assertTrue(value2.startsWith("ruby-test-2-foo - bar")); - assertTrue(value3.startsWith("ruby-test-3-foo - bar")); - // because we are using 'prototype bean the suffix date will be different + assertTrue(value1.startsWith("python-test-1-foo - bar")); + assertTrue(value2.startsWith("python-test-2-foo - bar")); + assertTrue(value3.startsWith("python-test-3-foo - bar")); + // because 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 withScriptVariableGenerator() throws Exception{ - + public void withScriptVariableGenerator() throws Exception { + QueueChannel replyChannel = new QueueChannel(); replyChannel.setBeanName("returnAddress"); for (int i = 1; i <= 3; i++) { @@ -102,17 +100,18 @@ public class Jsr223ServiceActivatorTests { assertTrue(value1.startsWith("ruby-test-1-foo - bar")); assertTrue(value2.startsWith("ruby-test-2-foo - bar")); assertTrue(value3.startsWith("ruby-test-3-foo - bar")); - // because we are using 'prototype bean the suffix date will be different + // because 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{ - + public void inlineScript() throws Exception { + QueueChannel replyChannel = new QueueChannel(); replyChannel.setBeanName("returnAddress"); for (int i = 1; i <= 3; i++) { @@ -123,21 +122,21 @@ public class Jsr223ServiceActivatorTests { assertEquals("inline-test-2", replyChannel.receive(0).getPayload()); assertEquals("inline-test-3", replyChannel.receive(0).getPayload()); assertNull(replyChannel.receive(0)); - + } - - @Test(expected=BeanDefinitionParsingException.class) - public void inlineScriptAndVariables() throws Exception{ + + @Test(expected = BeanDefinitionParsingException.class) + public void inlineScriptAndVariables() throws Exception { new ClassPathXmlApplicationContext("Jsr223ServiceActivatorTests-fail-context.xml", this.getClass()); } - - @Test(expected=BeanDefinitionParsingException.class) - public void variablesAndScriptVariableGenerator() throws Exception{ - new ClassPathXmlApplicationContext("Jsr223ServiceActivatorTests-fail-withgenerator-context.xml", this.getClass()); + + @Test(expected = BeanDefinitionParsingException.class) + public void variablesAndScriptVariableGenerator() throws Exception { + new ClassPathXmlApplicationContext("Jsr223ServiceActivatorTests-fail-withgenerator-context.xml", + this.getClass()); } - - public static class SampleScriptVariSource implements ScriptVariableGenerator{ + public static class SampleScriptVariSource implements ScriptVariableGenerator { public Map generateScriptVariables(Message message) { Map variables = new HashMap(); variables.put("foo", "foo"); diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.py b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.py new file mode 100644 index 0000000000..41aced873d --- /dev/null +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.py @@ -0,0 +1 @@ +"python-%s-%s - %s - %s" %(payload,foo,bar,date) \ No newline at end of file diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutingMessageProcessorTests.java b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutingMessageProcessorTests.java index 906a117ae7..691fb30d60 100644 --- a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutingMessageProcessorTests.java +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutingMessageProcessorTests.java @@ -22,8 +22,7 @@ import org.junit.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.integration.Message; import org.springframework.integration.message.GenericMessage; -import org.springframework.integration.scripting.jsr223.ScriptExecutingMessageProcessor; -import org.springframework.integration.scripting.jsr223.DefaultScriptExecutor; +import org.springframework.integration.scripting.ScriptExecutor; import org.springframework.scripting.ScriptSource; import org.springframework.scripting.support.ResourceScriptSource; @@ -32,10 +31,10 @@ import org.springframework.scripting.support.ResourceScriptSource; * */ public class Jsr223ScriptExecutingMessageProcessorTests { - DefaultScriptExecutor executor; + ScriptExecutor executor; @Before public void setUp() { - executor = new DefaultScriptExecutor("jruby"); + executor = ScriptExecutorFactory.getScriptExecutor("jruby"); } @Test public void testExecuteWithVariables(){ diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutorTests.java b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutorTests.java index ebab3f91d1..b61bebb198 100644 --- a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutorTests.java +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/Jsr223ScriptExecutorTests.java @@ -31,7 +31,7 @@ import org.springframework.scripting.support.StaticScriptSource; public class Jsr223ScriptExecutorTests { @Test public void test(){ - ScriptExecutor executor = new DefaultScriptExecutor("jruby"); + ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("jruby"); executor.executeScript(new StaticScriptSource("puts 'hello, world'")); executor.executeScript(new StaticScriptSource("puts 'hello, again'")); @@ -54,8 +54,17 @@ public class Jsr223ScriptExecutorTests { } @Test public void testJs(){ - ScriptExecutor executor = new DefaultScriptExecutor("js"); + ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("js"); Object obj = executor.executeScript(new StaticScriptSource("function js(){ return 'js';} js();")); assertEquals("js",obj.toString()); } + + @Test public void testPython() { + ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("python"); + Object obj = executor.executeScript(new StaticScriptSource("x=2") ); + assertEquals(2,obj); + + obj = executor.executeScript(new StaticScriptSource("def foo(y):\n\tx=y\n\treturn y\nz=foo(2)") ); + assertEquals(2,obj); + } } diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/PythonScriptExecutorTests.java b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/PythonScriptExecutorTests.java new file mode 100644 index 0000000000..4c9689aee1 --- /dev/null +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/PythonScriptExecutorTests.java @@ -0,0 +1,78 @@ +/* + * 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.scripting.jsr223; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.python.core.PyTuple; +import org.springframework.core.io.ClassPathResource; +import org.springframework.integration.scripting.ScriptExecutor; +import org.springframework.scripting.ScriptSource; +import org.springframework.scripting.support.ResourceScriptSource; +import org.springframework.scripting.support.StaticScriptSource; + +/** + * @author David Turanski + * + */ +public class PythonScriptExecutorTests { + ScriptExecutor executor; + @Before + public void init() { + executor = new PythonScriptExecutor(); + } + @Test + public void testLiteral() { + Object obj = executor.executeScript(new StaticScriptSource("3+4") ); + assertEquals(7,obj); + + obj = executor.executeScript(new StaticScriptSource("'hello,world'") ); + assertEquals("hello,world",obj); + } + + @Test + + public void test1() { + Object obj = executor.executeScript(new StaticScriptSource("x=2") ); + assertEquals(2,obj); + } + + @Test + public void test2() { + Object obj = executor.executeScript(new StaticScriptSource("def foo(y):\n\tx=y\n\treturn y\nz=foo(2)") ); + assertEquals(2,obj); + } + + @Test + public void test3() { + ScriptSource source = + new ResourceScriptSource(new ClassPathResource("/org/springframework/integration/scripting/jsr223/test3.py")); + Object obj = executor.executeScript(source); + System.out.println(obj); + PyTuple tuple = (PyTuple) obj; + assertEquals(1, tuple.get(0)); + } + + @Test + public void testEmbeddedVariable() { + Map variables = new HashMap(); + variables.put("scope", "world"); + Object obj = executor.executeScript(new StaticScriptSource("\"hello, %s\"% scope"),variables); + assertEquals("hello, world",obj); + } +} diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/PythonVariableParserTests.java b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/PythonVariableParserTests.java new file mode 100644 index 0000000000..64c183467c --- /dev/null +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/PythonVariableParserTests.java @@ -0,0 +1,49 @@ +/* + * 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.scripting.jsr223; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; +import org.springframework.core.io.ClassPathResource; +import org.springframework.scripting.ScriptSource; +import org.springframework.scripting.support.ResourceScriptSource; + +/** + * @author David Turanski + * + */ +public class PythonVariableParserTests { + + @Test + public void testBasic() throws IOException { + String var = PythonScriptExecutor.PythonVariableParser.parseReturnVariable("x=2"); + assertEquals("x",var); + + var = PythonScriptExecutor.PythonVariableParser.parseReturnVariable("\n\n\nx = 2\n\n\n"); + assertEquals("x",var); + + var = PythonScriptExecutor.PythonVariableParser.parseReturnVariable("\n\n\nx\n\n\n"); + } + + + @Test + public void test2() throws IOException { + ScriptSource source = + new ResourceScriptSource(new ClassPathResource("/org/springframework/integration/scripting/jsr223/test2.py")); + String var = PythonScriptExecutor.PythonVariableParser.parseReturnVariable(source.getScriptAsString()); + assertEquals("bar",var); + } +} diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/test2.py b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/test2.py new file mode 100644 index 0000000000..c38d4755ff --- /dev/null +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/test2.py @@ -0,0 +1,5 @@ +def foo(y): + x=y + return x + +bar = foo(7) diff --git a/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/test3.py b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/test3.py new file mode 100644 index 0000000000..3e4527109b --- /dev/null +++ b/spring-integration-scripting/src/test/java/org/springframework/integration/scripting/jsr223/test3.py @@ -0,0 +1,6 @@ +def foo(): + return(1,2,3) + + +(x,y,z) = foo() +result = (x,y,z) diff --git a/spring-integration-scripting/src/test/resources/log4j.xml b/spring-integration-scripting/src/test/resources/log4j.xml index a87914ff1e..575d062f62 100644 --- a/spring-integration-scripting/src/test/resources/log4j.xml +++ b/spring-integration-scripting/src/test/resources/log4j.xml @@ -12,10 +12,10 @@ - + - +