enhancement #I95XTD python脚本无法写return脚本

This commit is contained in:
everywhere.z
2024-03-28 14:52:12 +08:00
parent d03849b62d
commit 8a2d189374
3 changed files with 105 additions and 24 deletions

View File

@@ -24,5 +24,4 @@
<artifactId>jython-standalone</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -3,39 +3,120 @@ package com.yomahub.liteflow.script.python;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor;
import java.util.Arrays;
import java.util.List;
import com.yomahub.liteflow.script.ScriptExecuteWrap;
import com.yomahub.liteflow.script.ScriptExecutor;
import com.yomahub.liteflow.script.exception.ScriptLoadException;
import org.python.core.PyCode;
import org.python.core.PyObject;
import org.python.core.PySystemState;
import org.python.util.PythonInterpreter;
import java.util.*;
import java.util.stream.Collectors;
/**
* Python脚本语言的执行器实现
*
* @author Bryan.Zhang
* @since 2.9.5
* @since 2.12.0
*/
public class PythonScriptExecutor extends JSR223ScriptExecutor {
public class PythonScriptExecutor extends ScriptExecutor {
@Override
public ScriptTypeEnum scriptType() {
return ScriptTypeEnum.PYTHON;
}
private PythonInterpreter pythonInterpreter;
@Override
protected String convertScript(String script) {
String[] lineArray = script.split("\\n");
List<String> noBlankLineList = Arrays.stream(lineArray)
.filter(s -> !StrUtil.isBlank(s))
.collect(Collectors.toList());
private final String RESULT_KEY = "result";
// 用第一行的缩进的空格数作为整个代码的缩进量
String blankStr = ReUtil.getGroup0("^[ ]*", noBlankLineList.get(0));
private final Map<String, PyCode> compiledScriptMap = new HashMap<>();
// 重新构建脚本
StringBuilder scriptSB = new StringBuilder();
noBlankLineList.forEach(s -> scriptSB.append(StrUtil.format("{}\n", s.replaceFirst(blankStr, StrUtil.EMPTY))));
return scriptSB.toString();
}
@Override
public ScriptExecutor init(){
PySystemState systemState = new PySystemState();
systemState.setdefaultencoding("UTF-8");
this.pythonInterpreter = new PythonInterpreter(null, systemState);
return this;
}
@Override
public void load(String nodeId, String script) {
try {
PyCode pyCode = (PyCode) compile(script);
compiledScriptMap.put(nodeId, pyCode);
}
catch (Exception e) {
String errorMsg = StrUtil.format("script loading error for node[{}],error msg:{}", nodeId, e.getMessage());
throw new ScriptLoadException(errorMsg);
}
}
@Override
public void unLoad(String nodeId) {
compiledScriptMap.remove(nodeId);
}
@Override
public List<String> getNodeIds() {
return new ArrayList<>(compiledScriptMap.keySet());
}
@Override
public Object executeScript(ScriptExecuteWrap wrap) throws Exception {
if (!compiledScriptMap.containsKey(wrap.getNodeId())) {
String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
throw new ScriptLoadException(errorMsg);
}
PyCode compiledScript = compiledScriptMap.get(wrap.getNodeId());
bindParam(wrap, pythonInterpreter::set, pythonInterpreter::set);
pythonInterpreter.exec(compiledScript);
PyObject result = pythonInterpreter.get(RESULT_KEY);
if (result == null){
return null;
}
pythonInterpreter.cleanup();
switch (wrap.getCmp().getType()){
case BOOLEAN_SCRIPT:
return result.__tojava__(Boolean.class);
case FOR_SCRIPT:
return result.__tojava__(Integer.class);
default:
return result.__tojava__(Object.class);
}
}
@Override
public void cleanCache() {
compiledScriptMap.clear();
}
@Override
public ScriptTypeEnum scriptType() {
return ScriptTypeEnum.PYTHON;
}
@Override
public Object compile(String script) throws Exception {
return pythonInterpreter.compile(convertScript(script));
}
private String convertScript(String script) {
String[] lineArray = script.split("\\n");
List<String> noBlankLineList = Arrays.stream(lineArray)
.filter(s -> !StrUtil.isBlank(s))
.collect(Collectors.toList());
// 用第一行的缩进的空格数作为整个代码的缩进量
String blankStr = ReUtil.getGroup0("^[ ]*", noBlankLineList.get(0));
// 重新构建脚本
StringBuilder scriptSB = new StringBuilder();
noBlankLineList.forEach(s -> scriptSB.append(StrUtil.format("{}\n", s.replaceFirst(blankStr, StrUtil.EMPTY))));
return scriptSB.toString().replace("return", RESULT_KEY + "=");
}
}

View File

@@ -39,8 +39,9 @@ public class ScriptPythonCommonELTest extends BaseTest {
DefaultContext context = response.getFirstContextBean();
Assertions.assertTrue(response.isSuccess());
Assertions.assertEquals(Integer.valueOf(30), context.getData("s1"));
Assertions.assertEquals("杰克", context.getData("name"));
Assertions.assertEquals("jack", context.getData("name"));
Assertions.assertEquals("hi,jack", context.getData("td"));
Assertions.assertEquals("中文",context.getData("s2"));
}
@Test