From 33f05eb7cc23de57fb8ab7fac65d47b186488692 Mon Sep 17 00:00:00 2001 From: Dale Lee <1658850308@qq.com> Date: Thu, 2 May 2024 15:33:16 +0800 Subject: [PATCH] =?UTF-8?q?feature=20#I9H6GN=20=E6=94=AF=E6=8C=81=20kotlin?= =?UTF-8?q?=20=E8=84=9A=E6=9C=AC=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/enums/ScriptTypeEnum.java | 3 +- .../liteflow-script-kotlin/pom.xml | 29 ++++++ .../script/kotlin/KotlinScriptExecutor.java | 15 +++ ...com.yomahub.liteflow.script.ScriptExecutor | 2 + liteflow-script-plugin/pom.xml | 1 + .../pom.xml | 32 +++++++ .../liteflow/test/script/BaseTest.java | 24 +++++ .../liteflow/test/script/kotlin/T2.java | 93 +++++++++++++++++++ .../test/script/kotlin/TestKotlin.java | 49 ++++++++++ .../LiteFlowKotlinScriptCommonELTest.java | 68 ++++++++++++++ .../test/script/kotlin/common/cmp/ACmp.java | 21 +++++ .../test/script/kotlin/common/cmp/BCmp.java | 21 +++++ .../test/script/kotlin/common/cmp/CCmp.java | 21 +++++ .../resources/common/application.properties | 1 + .../src/test/resources/common/flow.xml | 72 ++++++++++++++ liteflow-testcase-el/pom.xml | 1 + 16 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 liteflow-script-plugin/liteflow-script-kotlin/pom.xml create mode 100644 liteflow-script-plugin/liteflow-script-kotlin/src/main/java/com/yomahub/liteflow/script/kotlin/KotlinScriptExecutor.java create mode 100644 liteflow-script-plugin/liteflow-script-kotlin/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/pom.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/BaseTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/T2.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/TestKotlin.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/LiteFlowKotlinScriptCommonELTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/resources/common/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/resources/common/flow.xml diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java index f350b4169..c9a62570a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ScriptTypeEnum.java @@ -8,7 +8,8 @@ public enum ScriptTypeEnum { PYTHON("python", "python"), LUA("luaj", "lua"), AVIATOR("AviatorScript", "aviator"), - JAVA("java", "java"); + JAVA("java", "java"), + KOTLIN("kotlin", "kotlin"); private String engineName; diff --git a/liteflow-script-plugin/liteflow-script-kotlin/pom.xml b/liteflow-script-plugin/liteflow-script-kotlin/pom.xml new file mode 100644 index 000000000..c89e6d796 --- /dev/null +++ b/liteflow-script-plugin/liteflow-script-kotlin/pom.xml @@ -0,0 +1,29 @@ + + + + liteflow-script-plugin + com.yomahub + ${revision} + ../pom.xml + + 4.0.0 + + liteflow-script-kotlin + + + + com.yomahub + liteflow-core + ${revision} + true + provided + + + org.jetbrains.kotlin + kotlin-scripting-jsr223 + 1.9.23 + + + \ No newline at end of file diff --git a/liteflow-script-plugin/liteflow-script-kotlin/src/main/java/com/yomahub/liteflow/script/kotlin/KotlinScriptExecutor.java b/liteflow-script-plugin/liteflow-script-kotlin/src/main/java/com/yomahub/liteflow/script/kotlin/KotlinScriptExecutor.java new file mode 100644 index 000000000..acdc490d0 --- /dev/null +++ b/liteflow-script-plugin/liteflow-script-kotlin/src/main/java/com/yomahub/liteflow/script/kotlin/KotlinScriptExecutor.java @@ -0,0 +1,15 @@ +package com.yomahub.liteflow.script.kotlin; + +import com.yomahub.liteflow.enums.ScriptTypeEnum; +import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor; + +/** + * Kotlin脚本执行器 + * @author DaleLee + */ +public class KotlinScriptExecutor extends JSR223ScriptExecutor { + @Override + public ScriptTypeEnum scriptType() { + return ScriptTypeEnum.KOTLIN; + } +} diff --git a/liteflow-script-plugin/liteflow-script-kotlin/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor b/liteflow-script-plugin/liteflow-script-kotlin/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor new file mode 100644 index 000000000..ccce7e1fb --- /dev/null +++ b/liteflow-script-plugin/liteflow-script-kotlin/src/main/resources/META-INF/services/com.yomahub.liteflow.script.ScriptExecutor @@ -0,0 +1,2 @@ +# Kotlin的实现 +com.yomahub.liteflow.script.kotlin.KotlinScriptExecutor \ No newline at end of file diff --git a/liteflow-script-plugin/pom.xml b/liteflow-script-plugin/pom.xml index 2c43fa16c..a188cd04b 100644 --- a/liteflow-script-plugin/pom.xml +++ b/liteflow-script-plugin/pom.xml @@ -23,6 +23,7 @@ liteflow-script-lua liteflow-script-aviator liteflow-script-java + liteflow-script-kotlin \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/pom.xml b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/pom.xml new file mode 100644 index 000000000..e76dca32f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/pom.xml @@ -0,0 +1,32 @@ + + + + liteflow-testcase-el + com.yomahub + ${revision} + ../pom.xml + + 4.0.0 + + liteflow-testcase-el-script-kotlin-springboot + + + + com.yomahub + liteflow-spring-boot-starter + ${revision} + + + com.yomahub + liteflow-script-kotlin + 2.12.0 + test + + + org.springframework.boot + spring-boot-starter-test + + + diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/BaseTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/BaseTest.java new file mode 100644 index 000000000..6cb71ce88 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/BaseTest.java @@ -0,0 +1,24 @@ +package com.yomahub.liteflow.test.script; + +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(); + FlowBus.clearStat(); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/T2.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/T2.java new file mode 100644 index 000000000..564cb33a3 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/T2.java @@ -0,0 +1,93 @@ +package com.yomahub.liteflow.test.script.kotlin; + +import com.yomahub.liteflow.slot.DefaultContext; +import org.junit.jupiter.api.Test; + +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleBindings; + +public class T2 { + @Test + public void test1() throws ScriptException { + // 初始化 ScriptEngineManager 和 Kotlin 脚本引擎 + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("kotlin"); + + if (engine == null) { + throw new IllegalStateException("Kotlin script engine not found"); + } + + // 假设我们有以下Kotlin脚本,它期望一个名为'message'的外部参数 + String script = "fun greet(name: String) {\n" + + " println(\"Hello, $name!\")\n" + + " }\n" + + " println(bindings[\"message\"])"; + + + // 编译脚本为CompiledScript对象 + Compilable compilable = (Compilable) engine; + CompiledScript compiledScript = compilable.compile(script); + + // 准备脚本上下文,用于传递外部参数 + Bindings bindings = engine.createBindings(); + // 设置外部参数 + bindings.put("message", "User"); + + // 使用相同的上下文多次执行已编译的脚本 + for (int i = 0; i < 2; i++) { + compiledScript.eval(bindings); + } +// engine.put("message","User"); +// engine.eval(script); + //engine.eval(script,bindings); + } + + @Test + public void test2() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("kotlin"); + String script = "" + + "var defaultContext = bindings[\"defaultContext\"]\n" + + "println(defaultContext.getData(\"key\"))"; + // 编译脚本为CompiledScript对象 + Compilable compilable = (Compilable) engine; + CompiledScript compiledScript = compilable.compile(script); + + // 准备脚本上下文,用于传递外部参数 + Bindings bindings = new SimpleBindings(); + DefaultContext context = new DefaultContext(); + context.setData("key", "value"); + // 设置外部参数 + bindings.put("defaultContext", context); + compiledScript.eval(bindings); + } + + @Test + public void test3() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("kotlin"); + String script = + "fun getNum() = 15\n" + + "getNum()"; + + // 编译脚本为CompiledScript对象 + Compilable compilable = (Compilable) engine; + CompiledScript compiledScript = compilable.compile(script); + + // 准备脚本上下文,用于传递外部参数 +// Bindings bindings = new SimpleBindings(); +// DefaultContext context = new DefaultContext(); +// context.setData("key", "value"); +// // 设置外部参数 +// bindings.put("defaultContext", context); + /* Object res = compiledScript.eval(); + System.out.println(res);*/ + Object eval = engine.eval(script); + System.out.println(eval); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/TestKotlin.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/TestKotlin.java new file mode 100644 index 000000000..7ddd0a878 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/TestKotlin.java @@ -0,0 +1,49 @@ +package com.yomahub.liteflow.test.script.kotlin; + +import com.yomahub.liteflow.enums.ScriptTypeEnum; + +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +public class TestKotlin { + public static void main(String[] args) throws ScriptException, NoSuchMethodException { + // 获取脚本引擎管理器 + ScriptEngineManager manager = new ScriptEngineManager(); + + // 获取Kotlin脚本引擎 + ScriptEngine engine = manager.getEngineByName(ScriptTypeEnum.KOTLIN.getEngineName()); // ".kts" 是Kotlin脚本文件的扩展名 + + // 检查是否找到了Kotlin脚本引擎 + if (engine == null) { + System.out.println("No Kotlin script engine found."); + return; + } + + System.out.println(engine instanceof Compilable); + + // 定义一个Kotlin脚本 + String script = "println(\"Hello, Kotlin JSR 223!\")"; + + Compilable compilable = (Compilable) engine; + CompiledScript compile = compilable.compile(script); + compile.eval(); + + + // 编译并执行脚本 + engine.eval(script); + + // 如果ScriptEngine也实现了Invocable接口,我们可以调用脚本中的函数 +// if (engine instanceof Invocable) { +// Invocable inv = (Invocable) engine; +// +// // 调用脚本中的greet函数 +// String greeting = (String) inv.invokeFunction("greet", "World"); +// System.out.println(greeting); // 输出: Hello, World! +// } else { +// System.out.println("The script engine does not support Invocable interface."); +// } + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/LiteFlowKotlinScriptCommonELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/LiteFlowKotlinScriptCommonELTest.java new file mode 100644 index 000000000..49629ce31 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/LiteFlowKotlinScriptCommonELTest.java @@ -0,0 +1,68 @@ +package com.yomahub.liteflow.test.script.kotlin.common; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.script.BaseTest; +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 = LiteFlowKotlinScriptCommonELTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.script.kotlin.common.cmp"}) +public class LiteFlowKotlinScriptCommonELTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testCommon1() { + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + DefaultContext context = response.getFirstContextBean(); + Assertions.assertEquals(Integer.valueOf(5), context.getData("s1")); + } + + @Test + public void testFor1() { + DefaultContext context = new DefaultContext(); + context.setData("k1", 1); + context.setData("k2", 2); + LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg", context); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("s2==>a==>a==>a",response.getExecuteStepStr()); + } + + @Test + public void testIf1() { + LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("s3==>b",response.getExecuteStepStr()); + } + + @Test + public void testIf2() { + LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("s4",response.getExecuteStepStr()); + } + + @Test + public void testSwitch1() { + DefaultContext context = new DefaultContext(); + context.setData("id", "c"); + LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg", context); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("s5==>c",response.getExecuteStepStr()); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/ACmp.java new file mode 100644 index 000000000..895686f17 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/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.kotlin.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-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/BCmp.java new file mode 100644 index 000000000..1c4eb6496 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/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.kotlin.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-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/common/cmp/CCmp.java new file mode 100644 index 000000000..661e979a0 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/java/com/yomahub/liteflow/test/script/kotlin/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.kotlin.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-kotlin-springboot/src/test/resources/common/application.properties b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/resources/common/application.properties new file mode 100644 index 000000000..4c9c216b6 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-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-kotlin-springboot/src/test/resources/common/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/resources/common/flow.xml new file mode 100644 index 000000000..35db6f006 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-script-kotlin-springboot/src/test/resources/common/flow.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + 1 + getBoolean1() + ]]> + + + + + + + + + + + THEN(a, b, c, s1); + + + + FOR(s2).DO(a); + + + + IF(s3, b); + + + + IF(s4, b); + + + + SWITCH(s5).TO(a, b, c); + + \ No newline at end of file diff --git a/liteflow-testcase-el/pom.xml b/liteflow-testcase-el/pom.xml index 7323492cf..7c3ba26e0 100644 --- a/liteflow-testcase-el/pom.xml +++ b/liteflow-testcase-el/pom.xml @@ -39,6 +39,7 @@ liteflow-testcase-el-script-java-springboot liteflow-testcase-el-builder liteflow-testcase-el-routechain + liteflow-testcase-el-script-kotlin-springboot