feature #I9H6GN 支持 kotlin 脚本语言
This commit is contained in:
parent
252c81dd15
commit
33f05eb7cc
|
@ -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;
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>liteflow-script-plugin</artifactId>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>liteflow-script-kotlin</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-core</artifactId>
|
||||
<version>${revision}</version>
|
||||
<optional>true</optional>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-scripting-jsr223</artifactId>
|
||||
<version>1.9.23</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
# Kotlin的实现
|
||||
com.yomahub.liteflow.script.kotlin.KotlinScriptExecutor
|
|
@ -23,6 +23,7 @@
|
|||
<module>liteflow-script-lua</module>
|
||||
<module>liteflow-script-aviator</module>
|
||||
<module>liteflow-script-java</module>
|
||||
<module>liteflow-script-kotlin</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>liteflow-testcase-el</artifactId>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>liteflow-testcase-el-script-kotlin-springboot</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-spring-boot-starter</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yomahub</groupId>
|
||||
<artifactId>liteflow-script-kotlin</artifactId>
|
||||
<version>2.12.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=common/flow.xml
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="s1" type="script" language="kotlin">
|
||||
<![CDATA[
|
||||
import com.yomahub.liteflow.slot.DefaultContext
|
||||
|
||||
fun sum(a: Int, b: Int) = a + b
|
||||
var a = 2
|
||||
var b = 3
|
||||
val defaultContext = bindings["defaultContext"] as DefaultContext
|
||||
defaultContext.setData("s1", sum(a, b))
|
||||
println("Hello Kotlin!")
|
||||
]]>
|
||||
</node>
|
||||
<node id="s2" type="for_script" language="kotlin">
|
||||
<![CDATA[
|
||||
import com.yomahub.liteflow.slot.DefaultContext
|
||||
|
||||
fun getCount(): Int {
|
||||
val ctx = bindings["defaultContext"] as DefaultContext
|
||||
var n1 = ctx.getData("k1") as Int;
|
||||
var n2 = ctx.getData("k2") as Int;
|
||||
return n1 + n2;
|
||||
}
|
||||
getCount()
|
||||
]]>
|
||||
</node>
|
||||
<node id="s3" type="boolean_script" language="kotlin">
|
||||
<![CDATA[
|
||||
fun getBoolean1() = 2 > 1
|
||||
getBoolean1()
|
||||
]]>
|
||||
</node>
|
||||
<node id="s4" type="boolean_script" language="kotlin">
|
||||
<![CDATA[
|
||||
fun getBoolean2() = 2 < 1
|
||||
getBoolean2()
|
||||
]]>
|
||||
</node>
|
||||
<node id="s5" type="switch_script" language="kotlin">
|
||||
<![CDATA[
|
||||
import com.yomahub.liteflow.slot.DefaultContext
|
||||
|
||||
fun getId(ctx: DefaultContext) : String {
|
||||
return ctx.getData("id") as String
|
||||
}
|
||||
getId(bindings["defaultContext"] as DefaultContext)
|
||||
]]>
|
||||
</node>
|
||||
</nodes>
|
||||
|
||||
<chain name="chain1">
|
||||
THEN(a, b, c, s1);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
FOR(s2).DO(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
IF(s3, b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
IF(s4, b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
SWITCH(s5).TO(a, b, c);
|
||||
</chain>
|
||||
</flow>
|
|
@ -39,6 +39,7 @@
|
|||
<module>liteflow-testcase-el-script-java-springboot</module>
|
||||
<module>liteflow-testcase-el-builder</module>
|
||||
<module>liteflow-testcase-el-routechain</module>
|
||||
<module>liteflow-testcase-el-script-kotlin-springboot</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
|
|
Loading…
Reference in New Issue