diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java index 364d546ee..c6fe31637 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/ScriptComponent.java @@ -43,6 +43,7 @@ public interface ScriptComponent { wrap.setCmpData(cmp.getCmpData(Map.class)); wrap.setLoopIndex(cmp.getLoopIndex()); wrap.setLoopObject(cmp.getCurrLoopObj()); + wrap.setCmp(cmp); return wrap; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecuteWrap.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecuteWrap.java index e1287e837..f47ce541f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecuteWrap.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptExecuteWrap.java @@ -1,5 +1,7 @@ package com.yomahub.liteflow.script; +import com.yomahub.liteflow.core.NodeComponent; + /** * script执行前的包装元参数 * @@ -8,19 +10,21 @@ package com.yomahub.liteflow.script; */ public class ScriptExecuteWrap { - private int slotIndex; + public int slotIndex; - private String currChainId; + public String currChainId; - private String nodeId; + public String nodeId; - private String tag; + public String tag; - private Object cmpData; + public Object cmpData; - private Integer loopIndex; + public Integer loopIndex; - private Object loopObject; + public Object loopObject; + + public NodeComponent cmp; public int getSlotIndex() { return slotIndex; @@ -93,4 +97,12 @@ public class ScriptExecuteWrap { public void setLoopObject(Object loopObject) { this.loopObject = loopObject; } + + public NodeComponent getCmp() { + return cmp; + } + + public void setCmp(NodeComponent cmp) { + this.cmp = cmp; + } } diff --git a/liteflow-core/src/main/resources/dtd/liteflow.dtd b/liteflow-core/src/main/resources/dtd/liteflow.dtd index a0eb6004c..e7935c461 100644 --- a/liteflow-core/src/main/resources/dtd/liteflow.dtd +++ b/liteflow-core/src/main/resources/dtd/liteflow.dtd @@ -11,7 +11,7 @@ type (script|if_script|switch_script|while_script|for_script|break_script) #IMPLIED class CDATA #IMPLIED file CDATA #IMPLIED - language (qlexpress|groovy|js|python|lua|aviator) #IMPLIED + language (qlexpress|groovy|js|python|lua|aviator|java) #IMPLIED > com.yomahub liteflow-core ${revision} - provided org.codehaus.janino diff --git a/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java b/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java index 800c57e40..0133203f9 100644 --- a/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java +++ b/liteflow-script-plugin/liteflow-script-java/src/main/java/com/yomahub/liteflow/script/java/JavaExecutor.java @@ -1,38 +1,51 @@ package com.yomahub.liteflow.script.java; +import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.enums.ScriptTypeEnum; import com.yomahub.liteflow.script.ScriptExecuteWrap; import com.yomahub.liteflow.script.ScriptExecutor; +import com.yomahub.liteflow.script.exception.ScriptLoadException; +import com.yomahub.liteflow.util.CopyOnWriteHashMap; import org.codehaus.commons.compiler.CompilerFactoryFactory; import org.codehaus.commons.compiler.IScriptEvaluator; +import java.util.Map; public class JavaExecutor extends ScriptExecutor { + + private final Map compiledScriptMap = new CopyOnWriteHashMap<>(); + @Override public void load(String nodeId, String script) { - // 创建Janino脚本Evaluator - /*IScriptEvaluator se = CompilerFactoryFactory.getDefaultCompilerFactory().newScriptEvaluator(); - // 返回值类型指定为Object以支持不同脚本 - se.setReturnType(Object.class); - // 指定Janino脚本里的变量名及类型,为通用起见,只设置一个Object类型的变量 - se.setParameters(new String[] { JANINO_SCRIPT_PARAMETER_NAME }, new Class[] { Object.class }); - // 编译 - se.cook(script); - // 缓存编译过的Evaluator - compiledScriptMap.put(nodeId, se);*/ + try{ + IScriptEvaluator se = CompilerFactoryFactory.getDefaultCompilerFactory(this.getClass().getClassLoader()).newScriptEvaluator(); + se.setReturnType(Object.class); + se.setParameters(new String[] {"_meta"}, new Class[] {ScriptExecuteWrap.class}); + se.cook(script); + compiledScriptMap.put(nodeId, se); + }catch (Exception e){ + String errorMsg = StrUtil.format("script loading error for node[{}],error msg:{}", nodeId, e.getMessage()); + throw new ScriptLoadException(errorMsg); + } + } @Override public Object executeScript(ScriptExecuteWrap wrap) throws Exception { - return null; + if (!compiledScriptMap.containsKey(wrap.getNodeId())) { + String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId()); + throw new ScriptLoadException(errorMsg); + } + IScriptEvaluator se = compiledScriptMap.get(wrap.getNodeId()); + return se.evaluate(wrap); } @Override public void cleanCache() { - + compiledScriptMap.clear(); } @Override public ScriptTypeEnum scriptType() { - return null; + return ScriptTypeEnum.JAVA; } } diff --git a/liteflow-script-plugin/liteflow-script-java/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor b/liteflow-script-plugin/liteflow-script-java/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor new file mode 100644 index 000000000..792fff1c0 --- /dev/null +++ b/liteflow-script-plugin/liteflow-script-java/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor @@ -0,0 +1,2 @@ +# Java的实现 +com.yomahub.liteflow.script.java.JavaExecutor \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/pom.xml b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/pom.xml new file mode 100644 index 000000000..2b450a298 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + liteflow-testcase-el + com.yomahub + ${revision} + ../pom.xml + + + liteflow-testcase-el-script-java-springboot + + + + com.yomahub + liteflow-spring-boot-starter + ${revision} + + + com.yomahub + liteflow-script-java + ${revision} + test + + + org.springframework.boot + spring-boot-starter-test + + + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java new file mode 100644 index 000000000..df1e70c4c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/BaseTest.java @@ -0,0 +1,23 @@ +package com.yomahub.liteflow.test; + +import com.yomahub.liteflow.core.FlowInitHook; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.property.LiteflowConfigGetter; +import com.yomahub.liteflow.spi.holder.SpiFactoryCleaner; +import com.yomahub.liteflow.spring.ComponentScanner; +import com.yomahub.liteflow.thread.ExecutorHelper; +import org.junit.jupiter.api.AfterAll; + +public class BaseTest { + + @AfterAll + public static void cleanScanCache() { + ComponentScanner.cleanCache(); + FlowBus.cleanCache(); + ExecutorHelper.loadInstance().clearExecutorServiceMap(); + SpiFactoryCleaner.clean(); + LiteflowConfigGetter.clean(); + FlowInitHook.cleanHook(); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/ScriptJavaCommonELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/ScriptJavaCommonELTest.java new file mode 100644 index 000000000..10d7ae843 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/ScriptJavaCommonELTest.java @@ -0,0 +1,36 @@ +package com.yomahub.liteflow.test.script.java.common; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import javax.annotation.Resource; + +@ExtendWith(SpringExtension.class) +@TestPropertySource(value = "classpath:/common/application.properties") +@SpringBootTest(classes = ScriptJavaCommonELTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.script.java.common.cmp" }) +public class ScriptJavaCommonELTest { + + @Resource + private FlowExecutor flowExecutor; + + // 测试普通脚本节点 + @Test + public void testCommon1() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + DefaultContext context = response.getFirstContextBean(); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals(6, (int)context.getData("s1")); + Assertions.assertEquals("hello,jack", context.getData("hi")); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/ACmp.java new file mode 100644 index 000000000..0a838cda4 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/ACmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.script.java.common.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/BCmp.java new file mode 100644 index 000000000..83ddeaede --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.script.java.common.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/CCmp.java new file mode 100644 index 000000000..b2ef97f4f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/CCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.script.java.common.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; + +@LiteflowComponent("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/DCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/DCmp.java new file mode 100644 index 000000000..1f40e2fc9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/DCmp.java @@ -0,0 +1,24 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.script.java.common.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.slot.DefaultContext; + +@LiteflowComponent("d") +public class DCmp extends NodeComponent { + + @Override + public void process() { + DefaultContext context = this.getFirstContextBean(); + context.setData("count", 198); + System.out.println("DCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/TestDomain.java b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/TestDomain.java new file mode 100644 index 000000000..7925310ff --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/java/com/yomahub/liteflow/test/script/java/common/cmp/TestDomain.java @@ -0,0 +1,11 @@ +package com.yomahub.liteflow.test.script.java.common.cmp; + +import org.springframework.stereotype.Component; + +@Component +public class TestDomain { + + public String sayHello(String name){ + return "hello," + name; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/resources/common/application.properties b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/resources/common/application.properties new file mode 100644 index 000000000..4c9c216b6 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/resources/common/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=common/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/resources/common/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/resources/common/flow.xml new file mode 100644 index 000000000..a64ec0c2d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-java-springboot/src/test/resources/common/flow.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + THEN(a, b, c, s1); + + \ No newline at end of file diff --git a/liteflow-testcase-el/pom.xml b/liteflow-testcase-el/pom.xml index e824294a0..3aacdd528 100644 --- a/liteflow-testcase-el/pom.xml +++ b/liteflow-testcase-el/pom.xml @@ -36,6 +36,7 @@ liteflow-testcase-el-script-multi-language-springboot liteflow-testcase-el-script-aviator-springboot liteflow-testcase-el-sql-springboot-dynamic + liteflow-testcase-el-script-java-springboot