GH-9507: Migrate Python support to GraalVM Polyglot
Fixes: #9507 Issue link: https://github.com/spring-projects/spring-integration/issues/9507 * Deprecate `PythonScriptExecutor` in favor of `PolyglotScriptExecutor` with a `python` as language * Add handling for `PolyglotWrapper` return type of the script evaluation * Rework `DeriveLanguageFromExtensionTests.testParseLanguage()` to the `@ParameterizedTest`
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2024 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.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.integration.scripting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.graalvm.polyglot.Context;
|
||||
@@ -36,7 +38,7 @@ public class PolyglotScriptExecutor implements ScriptExecutor {
|
||||
|
||||
private final String language;
|
||||
|
||||
private Context.Builder contextBuilder;
|
||||
private final Context.Builder contextBuilder;
|
||||
|
||||
/**
|
||||
* Construct an executor based on the provided language id.
|
||||
@@ -67,11 +69,28 @@ public class PolyglotScriptExecutor implements ScriptExecutor {
|
||||
Value bindings = context.getBindings(this.language);
|
||||
variables.forEach(bindings::putMember);
|
||||
}
|
||||
return context.eval(this.language, scriptSource.getScriptAsString()).as(Object.class);
|
||||
String scriptAsString = scriptSource.getScriptAsString();
|
||||
Object result = context.eval(this.language, scriptAsString).as(Object.class);
|
||||
// We have to copy all the expected PolyglotWrapper instances before context is closed.
|
||||
if (result instanceof Map<?, ?> map) {
|
||||
String returnVariable = parseReturnVariable(scriptAsString);
|
||||
result = map.get(returnVariable);
|
||||
}
|
||||
if (result instanceof List<?> list) {
|
||||
result = new ArrayList<>(list);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ScriptingException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,9 +32,14 @@ import javax.script.ScriptEngine;
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @deprecated in favor of {@link org.springframework.integration.scripting.PolyglotScriptExecutor}
|
||||
* with a {@code python} language argument.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "6.4")
|
||||
public class PythonScriptExecutor extends AbstractScriptExecutor {
|
||||
|
||||
public PythonScriptExecutor() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -35,7 +35,7 @@ public final class ScriptExecutorFactory {
|
||||
|
||||
public static ScriptExecutor getScriptExecutor(String language) {
|
||||
if (language.equalsIgnoreCase("python") || language.equalsIgnoreCase("jython")) {
|
||||
return new PythonScriptExecutor();
|
||||
return new PolyglotScriptExecutor("python");
|
||||
}
|
||||
else if (language.equalsIgnoreCase("ruby") || language.equalsIgnoreCase("jruby")) {
|
||||
return new RubyScriptExecutor();
|
||||
@@ -56,11 +56,16 @@ public final class ScriptExecutorFactory {
|
||||
int index = scriptLocation.lastIndexOf('.') + 1;
|
||||
Assert.state(index > 0, () -> "Unable to determine language for script '" + scriptLocation + "'");
|
||||
String extension = scriptLocation.substring(index);
|
||||
if (extension.equals("kts")) {
|
||||
return "kotlin";
|
||||
}
|
||||
else if (extension.equals("js")) {
|
||||
return "js";
|
||||
switch (extension) {
|
||||
case "kts" -> {
|
||||
return "kotlin";
|
||||
}
|
||||
case "js" -> {
|
||||
return "js";
|
||||
}
|
||||
case "py" -> {
|
||||
return "python";
|
||||
}
|
||||
}
|
||||
ScriptEngineManager engineManager = new ScriptEngineManager();
|
||||
ScriptEngine engine = engineManager.getEngineByExtension(extension);
|
||||
|
||||
Reference in New Issue
Block a user