ソースを参照

feature #I5RV4W 加强脚本和java之间的互动

everywhere.z 2 年 前
コミット
979c4ea070

+ 7 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptBreakComponent.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.core;
 
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.script.ScriptExecutorFactory;
 
 /**
@@ -10,7 +11,12 @@ import com.yomahub.liteflow.script.ScriptExecutorFactory;
 public class ScriptBreakComponent extends NodeBreakComponent implements ScriptComponent{
     @Override
     public boolean processBreak() throws Exception {
-        return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(this.getCurrChainName(), getNodeId(), getSlotIndex());
+        ScriptExecuteWrap wrap = new ScriptExecuteWrap();
+        wrap.setCurrChainName(this.getCurrChainName());
+        wrap.setNodeId(this.getNodeId());
+        wrap.setSlotIndex(this.getSlotIndex());
+        wrap.setCmpData(this.getCmpData(Object.class));
+        return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap);
     }
 
     @Override

+ 7 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptCommonComponent.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.core;
 
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.script.ScriptExecutorFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -15,7 +16,12 @@ public class ScriptCommonComponent extends NodeComponent implements ScriptCompon
 
     @Override
     public void process() throws Exception {
-        ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(this.getCurrChainName(), getNodeId(), getSlotIndex());
+        ScriptExecuteWrap wrap = new ScriptExecuteWrap();
+        wrap.setCurrChainName(this.getCurrChainName());
+        wrap.setNodeId(this.getNodeId());
+        wrap.setSlotIndex(this.getSlotIndex());
+        wrap.setCmpData(this.getCmpData(Object.class));
+        ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap);
     }
 
     @Override

+ 7 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptForComponent.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.core;
 
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.script.ScriptExecutorFactory;
 
 /**
@@ -10,7 +11,12 @@ import com.yomahub.liteflow.script.ScriptExecutorFactory;
 public class ScriptForComponent extends NodeForComponent implements ScriptComponent{
     @Override
     public int processFor() throws Exception {
-        return (int) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(this.getCurrChainName(), getNodeId(), getSlotIndex());
+        ScriptExecuteWrap wrap = new ScriptExecuteWrap();
+        wrap.setCurrChainName(this.getCurrChainName());
+        wrap.setNodeId(this.getNodeId());
+        wrap.setSlotIndex(this.getSlotIndex());
+        wrap.setCmpData(this.getCmpData(Object.class));
+        return (int) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap);
     }
 
     @Override

+ 7 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptIfComponent.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.core;
 
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.script.ScriptExecutorFactory;
 
 /**
@@ -10,7 +11,12 @@ import com.yomahub.liteflow.script.ScriptExecutorFactory;
 public class ScriptIfComponent extends NodeIfComponent implements ScriptComponent{
     @Override
     public boolean processIf() throws Exception {
-        return (boolean)ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(this.getCurrChainName(), getNodeId(), getSlotIndex());
+        ScriptExecuteWrap wrap = new ScriptExecuteWrap();
+        wrap.setCurrChainName(this.getCurrChainName());
+        wrap.setNodeId(this.getNodeId());
+        wrap.setSlotIndex(this.getSlotIndex());
+        wrap.setCmpData(this.getCmpData(Object.class));
+        return (boolean)ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap);
     }
 
     @Override

+ 7 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptSwitchComponent.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.core;
 
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.script.ScriptExecutorFactory;
 
 /**
@@ -11,7 +12,12 @@ public class ScriptSwitchComponent extends NodeSwitchComponent implements Script
 
     @Override
     public String processSwitch() throws Exception {
-        return (String)ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(this.getCurrChainName(), getNodeId(), getSlotIndex());
+        ScriptExecuteWrap wrap = new ScriptExecuteWrap();
+        wrap.setCurrChainName(this.getCurrChainName());
+        wrap.setNodeId(this.getNodeId());
+        wrap.setSlotIndex(this.getSlotIndex());
+        wrap.setCmpData(this.getCmpData(Object.class));
+        return (String)ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap);
     }
 
     @Override

+ 7 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptWhileComponent.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.core;
 
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.script.ScriptExecutorFactory;
 
 /**
@@ -11,7 +12,12 @@ public class ScriptWhileComponent extends NodeWhileComponent implements ScriptCo
 
     @Override
     public boolean processWhile() throws Exception {
-        return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(this.getCurrChainName(), getNodeId(), getSlotIndex());
+        ScriptExecuteWrap wrap = new ScriptExecuteWrap();
+        wrap.setCurrChainName(this.getCurrChainName());
+        wrap.setNodeId(this.getNodeId());
+        wrap.setSlotIndex(this.getSlotIndex());
+        wrap.setCmpData(this.getCmpData(Object.class));
+        return (boolean) ScriptExecutorFactory.loadInstance().getScriptExecutor().execute(wrap);
     }
 
     @Override

+ 59 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecuteWrap.java

@@ -0,0 +1,59 @@
+package com.yomahub.liteflow.script;
+
+/**
+ * script执行前的包装元参数
+ * @author Bryan.Zhang
+ * @since 2.9.0
+ */
+public class ScriptExecuteWrap {
+
+    private int slotIndex;
+
+    private String currChainName;
+
+    private String nodeId;
+
+    private String tag;
+
+    private Object cmpData;
+
+    public int getSlotIndex() {
+        return slotIndex;
+    }
+
+    public void setSlotIndex(int slotIndex) {
+        this.slotIndex = slotIndex;
+    }
+
+    public String getCurrChainName() {
+        return currChainName;
+    }
+
+    public void setCurrChainName(String currChainName) {
+        this.currChainName = currChainName;
+    }
+
+    public String getNodeId() {
+        return nodeId;
+    }
+
+    public void setNodeId(String nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    public String getTag() {
+        return tag;
+    }
+
+    public void setTag(String tag) {
+        this.tag = tag;
+    }
+
+    public Object getCmpData() {
+        return cmpData;
+    }
+
+    public void setCmpData(Object cmpData) {
+        this.cmpData = cmpData;
+    }
+}

+ 1 - 1
liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecutor.java

@@ -11,7 +11,7 @@ public interface ScriptExecutor {
 
     void load(String nodeId, String script);
 
-    Object execute(String currChainName, String nodeId, int slotIndex);
+    Object execute(ScriptExecuteWrap wrap);
 
     void cleanCache();
 }

+ 19 - 11
liteflow-script-plugin/liteflow-script-groovy/src/main/java/com/yomahub/liteflow/script/groovy/GroovyScriptExecutor.java

@@ -1,8 +1,10 @@
 package com.yomahub.liteflow.script.groovy;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.yomahub.liteflow.script.ScriptBeanManager;
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.slot.DataBus;
 import com.yomahub.liteflow.slot.Slot;
 import com.yomahub.liteflow.script.ScriptExecutor;
@@ -49,42 +51,48 @@ public class GroovyScriptExecutor implements ScriptExecutor {
     }
 
     @Override
-    public Object execute(String currChainName, String nodeId, int slotIndex) {
+    public Object execute(ScriptExecuteWrap wrap) {
         try{
-            if (!compiledScriptMap.containsKey(nodeId)){
-                String errorMsg = StrUtil.format("script for node[{}] is not loaded", nodeId);
+            if (!compiledScriptMap.containsKey(wrap.getNodeId())){
+                String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
                 throw new ScriptLoadException(errorMsg);
             }
 
-            CompiledScript compiledScript = compiledScriptMap.get(nodeId);
+            CompiledScript compiledScript = compiledScriptMap.get(wrap.getNodeId());
             Bindings bindings = new SimpleBindings();
 
             //往脚本语言绑定表里循环增加绑定上下文的key
             //key的规则为自定义上下文的simpleName
             //比如你的自定义上下文为AbcContext,那么key就为:abcContext
             //这里不统一放一个map的原因是考虑到有些用户会调用上下文里的方法,而不是参数,所以脚本语言的绑定表里也是放多个上下文
-            DataBus.getContextBeanList(slotIndex).forEach(o -> {
+            DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(o -> {
                 String key = StrUtil.lowerFirst(o.getClass().getSimpleName());
                 bindings.put(key, o);
             });
 
-            //放入主Chain的流程参数
-            Slot slot = DataBus.getSlot(slotIndex);
-            bindings.put("requestData", slot.getRequestData());
+            //把wrap对象转换成元数据map
+            Map<String, Object> metaMap = BeanUtil.beanToMap(wrap);
+
+            //在元数据里放入主Chain的流程参数
+            Slot slot = DataBus.getSlot(wrap.getSlotIndex());
+            metaMap.put("requestData", slot.getRequestData());
 
             //如果有隐式流程,则放入隐式流程的流程参数
-            Object subRequestData = slot.getChainReqData(currChainName);
+            Object subRequestData = slot.getChainReqData(wrap.getCurrChainName());
             if (ObjectUtil.isNotNull(subRequestData)){
-                bindings.put("subRequestData", subRequestData);
+                metaMap.put("subRequestData", subRequestData);
             }
 
+            //往脚本上下文里放入元数据
+            bindings.put("_meta", metaMap);
+
             //放入用户自己定义的bean
             bindings.putAll(ScriptBeanManager.getScriptBeanMap());
 
             return compiledScript.eval(bindings);
         }catch (Exception e){
             log.error(e.getMessage(), e);
-            String errorMsg = StrUtil.format("script execute error for node[{}]", nodeId);
+            String errorMsg = StrUtil.format("script execute error for node[{}]", wrap.getNodeId());
             throw new ScriptExecuteException(errorMsg);
         }
     }

+ 20 - 12
liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java

@@ -1,5 +1,6 @@
 package com.yomahub.liteflow.script.qlexpress;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
@@ -8,6 +9,7 @@ import com.ql.util.express.ExpressLoader;
 import com.ql.util.express.ExpressRunner;
 import com.ql.util.express.InstructionSet;
 import com.yomahub.liteflow.script.ScriptBeanManager;
+import com.yomahub.liteflow.script.ScriptExecuteWrap;
 import com.yomahub.liteflow.slot.DataBus;
 import com.yomahub.liteflow.slot.Slot;
 import com.yomahub.liteflow.script.ScriptExecutor;
@@ -52,36 +54,42 @@ public class QLExpressScriptExecutor implements ScriptExecutor {
     }
 
     @Override
-    public Object execute(String currChainName, String nodeId, int slotIndex) {
+    public Object execute(ScriptExecuteWrap wrap) {
         List<String> errorList = new ArrayList<>();
         try{
-            if (!compiledScriptMap.containsKey(nodeId)){
-                String errorMsg = StrUtil.format("script for node[{}] is not loaded", nodeId);
+            if (!compiledScriptMap.containsKey(wrap.getNodeId())){
+                String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
                 throw new ScriptLoadException(errorMsg);
             }
 
-            InstructionSet instructionSet = compiledScriptMap.get(nodeId);
+            InstructionSet instructionSet = compiledScriptMap.get(wrap.getNodeId());
             DefaultContext<String, Object> context = new DefaultContext<>();
 
             //往脚本语言绑定表里循环增加绑定上下文的key
             //key的规则为自定义上下文的simpleName
             //比如你的自定义上下文为AbcContext,那么key就为:abcContext
             //这里不统一放一个map的原因是考虑到有些用户会调用上下文里的方法,而不是参数,所以脚本语言的绑定表里也是放多个上下文
-            DataBus.getContextBeanList(slotIndex).forEach(o -> {
+            DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(o -> {
                 String key = StrUtil.lowerFirst(o.getClass().getSimpleName());
                 context.put(key, o);
             });
 
-            //放入主Chain的流程参数
-            Slot slot = DataBus.getSlot(slotIndex);
-            context.put("requestData", slot.getRequestData());
+            //把wrap对象转换成元数据map
+            Map<String, Object> metaMap = BeanUtil.beanToMap(wrap);
 
-            //如果有隐试流程,则放入隐式流程的流程参数
-            Object subRequestData = slot.getChainReqData(currChainName);
+            //在元数据里放入主Chain的流程参数
+            Slot slot = DataBus.getSlot(wrap.getSlotIndex());
+            metaMap.put("requestData", slot.getRequestData());
+
+            //如果有隐式流程,则放入隐式流程的流程参数
+            Object subRequestData = slot.getChainReqData(wrap.getCurrChainName());
             if (ObjectUtil.isNotNull(subRequestData)){
-                context.put("subRequestData", subRequestData);
+                metaMap.put("subRequestData", subRequestData);
             }
 
+            //往脚本上下文里放入元数据
+            context.putAll(metaMap);
+
             //放入用户自己定义的bean
             context.putAll(ScriptBeanManager.getScriptBeanMap());
 
@@ -90,7 +98,7 @@ public class QLExpressScriptExecutor implements ScriptExecutor {
             for (String scriptErrorMsg : errorList){
                 log.error("\n{}", scriptErrorMsg);
             }
-            String errorMsg = StrUtil.format("script execute error for node[{}]", nodeId);
+            String errorMsg = StrUtil.format("script execute error for node[{}]", wrap.getNodeId());
             throw new ScriptExecuteException(errorMsg);
         }
     }

+ 1 - 1
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/xml-script/flow.el.xml

@@ -33,7 +33,7 @@
             <![CDATA[
                 def a=30;
                 def b=2;
-                defaultContext.setData("s4","s4:" + requestData);
+                defaultContext.setData("s4","s4:" + _meta.requestData);
             ]]>
         </node>
     </nodes>