INT-2177 - Added python support and related refactoring

This commit is contained in:
David Turanski
2011-10-14 09:57:21 -04:00
committed by Mark Fisher
parent 1d80d34225
commit a0e7b3cd78
21 changed files with 449 additions and 117 deletions

View File

@@ -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")
}
}

View File

@@ -35,5 +35,6 @@ public interface ScriptExecutor {
* @param variables -bind variable
* @return
*/
public abstract Object executeScript(ScriptSource scriptSource,Map<String,Object> variables);
public abstract Object executeScript(ScriptSource scriptSource,Map<String,Object> variables);
}

View File

@@ -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));
}

View File

@@ -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<String, Object> variables) {
Object result = null;
ScriptEngine scriptEngine = this.scriptEngineManager.getEngineByName(this.language);
try {
if (variables != null) {
for (Entry<String, Object> 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);
}

View File

@@ -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<String, Object> variables) {
Object result = null;
ScriptEngine scriptEngine = this.scriptEngineManager.getEngineByName(this.language);
try {
if (variables != null) {
for (Entry<String, Object> 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;
}

View File

@@ -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.
* <p>
* Script evaluation using the Jython implementation results in a <code>null</code> return value for normal variable expressions such as
* <code>x=2</code>. 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();
}
}
}

View File

@@ -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");
}
}

View File

@@ -28,7 +28,7 @@ import org.springframework.util.Assert;
*/
public class ScriptExecutingMessageProcessor extends AbstractScriptExecutingMessageProcessor<Object> {
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<String,Object> variables ) {
public ScriptExecutingMessageProcessor(ScriptSource scriptSource, ScriptExecutor scriptExecutor,Map<String,Object> variables ) {
super(new DefaultScriptVariableGenerator(variables));
this.scriptSource = scriptSource;
this.scriptExecutor = scriptExecutor;

View File

@@ -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);
}
}

View File

@@ -26,6 +26,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="return" use="optional">
<xsd:annotation>
<xsd:documentation>
The script variable to return as a result of the evaluation (Optional).
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

View File

@@ -1,5 +1,4 @@
function route(max){
return payload.length > max ? "longStrings" : "shortStrings";
function route(max) {
return payload.length > max ? "longStrings" : "shortStrings";
}
route(maxLen);

View File

@@ -11,8 +11,8 @@
<service-activator input-channel="referencedScriptInput">
<script:script
lang="ruby"
location="org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.rb">
lang="python"
location="org/springframework/integration/scripting/config/jsr223/Jsr223ServiceActivatorTests.py">
<script:variable name="foo" value="foo"/>
<script:variable name="bar" value="bar"/>
<script:variable name="date" ref="date"/>

View File

@@ -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<String, Object> generateScriptVariables(Message<?> message) {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("foo", "foo");

View File

@@ -0,0 +1 @@
"python-%s-%s - %s - %s" %(payload,foo,bar,date)

View File

@@ -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(){

View File

@@ -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);
}
}

View File

@@ -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<String,Object> variables = new HashMap<String,Object>();
variables.put("scope", "world");
Object obj = executor.executeScript(new StaticScriptSource("\"hello, %s\"% scope"),variables);
assertEquals("hello, world",obj);
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,5 @@
def foo(y):
x=y
return x
bar = foo(7)

View File

@@ -0,0 +1,6 @@
def foo():
return(1,2,3)
(x,y,z) = foo()
result = (x,y,z)

View File

@@ -12,10 +12,10 @@
<!-- Loggers -->
<logger name="org.springframework">
<level value="info" />
<level value="warn" />
</logger>
<logger name="org.springframework.integration.jsr223">
<logger name="org.springframework.integration.scripting.jsr223">
<level value="info" />
</logger>