mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 20:22:07 +08:00
enhancement #I95XTD python脚本无法写return脚本
This commit is contained in:
@@ -24,5 +24,4 @@
|
||||
<artifactId>jython-standalone</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -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 + "=");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user