Pārlūkot izejas kodu

!147 feat #I64L3Q 增加 @ScriptMethod 注解
Merge pull request !147 from 与或非/issues/I64L3Q

铂赛东 2 gadi atpakaļ
vecāks
revīzija
4adbe86fa6
35 mainītis faili ar 848 papildinājumiem un 6 dzēšanām
  1. 25 0
      liteflow-core/src/main/java/com/yomahub/liteflow/script/annotation/ScriptMethod.java
  2. 98 0
      liteflow-core/src/main/java/com/yomahub/liteflow/script/proxy/ScriptMethodProxy.java
  3. 41 6
      liteflow-spring/src/main/java/com/yomahub/liteflow/spring/ComponentScanner.java
  4. 44 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/LiteFlowScriptScripMethodJsELTest.java
  5. 29 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/bean/DemoBean1.java
  6. 11 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/bean/DemoBean2.java
  7. 20 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/cmp/ACmp.java
  8. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/cmp/BCmp.java
  9. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/cmp/CCmp.java
  10. 1 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/resources/scriptmethod/application.properties
  11. 27 0
      liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/resources/scriptmethod/flow.xml
  12. 43 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/LiteFlowScriptScriptMethodGroovyELTest.java
  13. 25 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/bean/DemoBean1.java
  14. 11 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/bean/DemoBean2.java
  15. 20 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/cmp/ACmp.java
  16. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/cmp/BCmp.java
  17. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/cmp/CCmp.java
  18. 1 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptmethod/application.properties
  19. 27 0
      liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptmethod/flow.xml
  20. 44 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/LiteFlowScriptScriptMethodJsELTest.java
  21. 28 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/bean/DemoBean1.java
  22. 11 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/bean/DemoBean2.java
  23. 20 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/cmp/ACmp.java
  24. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/cmp/BCmp.java
  25. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/cmp/CCmp.java
  26. 1 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/scriptmethod/application.properties
  27. 27 0
      liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/scriptmethod/flow.xml
  28. 44 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/LiteFlowScriptScriptMethodQLExpressELTest.java
  29. 23 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/bean/DemoBean1.java
  30. 11 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/bean/DemoBean2.java
  31. 20 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/cmp/ACmp.java
  32. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/cmp/BCmp.java
  33. 21 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/cmp/CCmp.java
  34. 1 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/resources/scriptmethod/application.properties
  35. 27 0
      liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/resources/scriptmethod/flow.xml

+ 25 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/script/annotation/ScriptMethod.java

@@ -0,0 +1,25 @@
+package com.yomahub.liteflow.script.annotation;
+
+import com.yomahub.liteflow.annotation.AliasFor;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 用于标注在Script中可使用的java 方法
+ *
+ * @author tangkc
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface ScriptMethod {
+
+    @AliasFor("name")
+    String value() default "";
+}

+ 98 - 0
liteflow-core/src/main/java/com/yomahub/liteflow/script/proxy/ScriptMethodProxy.java

@@ -0,0 +1,98 @@
+package com.yomahub.liteflow.script.proxy;
+
+import cn.hutool.core.util.ClassUtil;
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.exception.LiteFlowException;
+import com.yomahub.liteflow.exception.ScriptBeanMethodInvokeException;
+import com.yomahub.liteflow.util.LiteFlowProxyUtil;
+import com.yomahub.liteflow.util.SerialsUtil;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.implementation.InvocationHandlerAdapter;
+import net.bytebuddy.matcher.ElementMatchers;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * 脚本方法代理
+ */
+public class ScriptMethodProxy {
+    /**
+     * 被代理的 bean
+     */
+    private final Object bean;
+
+    /**
+     * 原始的类
+     */
+    private final Class<?> orignalClass;
+
+    private final List<Method> scriptMethods;
+
+    public ScriptMethodProxy(Object bean, Class<?> orignalClass, List<Method> scriptMethods) {
+        this.bean = bean;
+        this.orignalClass = orignalClass;
+        this.scriptMethods = scriptMethods;
+    }
+
+    public Object getProxyScriptMethod() {
+
+        try {
+            return new ByteBuddy().subclass(orignalClass)
+                    .name(buildClassName()) // 设置生成的类名
+                    .method(ElementMatchers.any())
+                    .intercept(InvocationHandlerAdapter.of(new AopInvocationHandler(bean, scriptMethods)))
+                    .annotateType(orignalClass.getAnnotations())
+                    .make()
+                    .load(ScriptBeanProxy.class.getClassLoader())
+                    .getLoaded()
+                    .newInstance();
+        } catch (Exception e) {
+            throw new LiteFlowException(e);
+        }
+    }
+
+    private String buildClassName() {
+        return StrUtil.format("{}.ByteBuddy${}",
+                ClassUtil.getPackage(orignalClass),
+                SerialsUtil.generateShortUUID());
+    }
+
+    public static class AopInvocationHandler implements InvocationHandler {
+        private final Object bean;
+
+        private final Class<?> clazz;
+
+        private final Set<Method> methodSet;
+
+        public AopInvocationHandler(Object bean, List<Method> methods) {
+            this.bean = bean;
+            this.clazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
+            this.methodSet = new HashSet<>(methods);
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            Optional<Method> invokeMethodOp = Arrays.stream(clazz.getMethods())
+                    .filter(method::equals)
+                    .findFirst();
+
+            if (!invokeMethodOp.isPresent()) {
+                String errorMsg = StrUtil.format("cannot find method[{}]", clazz.getName(), method.getName());
+                throw new ScriptBeanMethodInvokeException(errorMsg);
+            }
+
+            if (!methodSet.contains(method)) {
+                String errorMsg = StrUtil.format("script method[{}.{}] cannot be executed", clazz.getName(), method.getName());
+                throw new ScriptBeanMethodInvokeException(errorMsg);
+            }
+
+            return invokeMethodOp.get().invoke(bean, args);
+        }
+    }
+}

+ 41 - 6
liteflow-spring/src/main/java/com/yomahub/liteflow/spring/ComponentScanner.java

@@ -8,15 +8,19 @@
  */
 package com.yomahub.liteflow.spring;
 
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.yomahub.liteflow.annotation.util.AnnoUtil;
 import com.yomahub.liteflow.aop.ICmpAroundAspect;
 import com.yomahub.liteflow.core.NodeComponent;
 import com.yomahub.liteflow.property.LiteflowConfig;
-import com.yomahub.liteflow.script.annotation.ScriptBean;
 import com.yomahub.liteflow.script.ScriptBeanManager;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
+import com.yomahub.liteflow.script.annotation.ScriptMethod;
 import com.yomahub.liteflow.script.proxy.ScriptBeanProxy;
+import com.yomahub.liteflow.script.proxy.ScriptMethodProxy;
 import com.yomahub.liteflow.util.LOGOPrinter;
 import com.yomahub.liteflow.util.LiteFlowProxyUtil;
 import org.slf4j.Logger;
@@ -24,12 +28,16 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 
+import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 组件扫描类,只要是NodeComponent的实现类,都可以被这个扫描器扫到
+ *
  * @author Bryan.Zhang
  */
 public class ComponentScanner implements BeanPostProcessor {
@@ -48,7 +56,7 @@ public class ComponentScanner implements BeanPostProcessor {
 
     public ComponentScanner(LiteflowConfig liteflowConfig) {
         this.liteflowConfig = liteflowConfig;
-        if(liteflowConfig.getPrintBanner()){
+        if (liteflowConfig.getPrintBanner()) {
             // 打印liteflow的LOGO
             LOGOPrinter.print();
         }
@@ -66,7 +74,7 @@ public class ComponentScanner implements BeanPostProcessor {
 
         //判断是不是声明式组件
         //如果是,就缓存到类属性的map中
-        if (LiteFlowProxyUtil.isDeclareCmp(bean.getClass())){
+        if (LiteFlowProxyUtil.isDeclareCmp(bean.getClass())) {
             LOG.info("proxy component[{}] has been found", beanName);
             List<NodeComponent> nodeComponents = LiteFlowProxyUtil.proxy2NodeComponent(bean, beanName);
             nodeComponents.forEach(
@@ -77,7 +85,7 @@ public class ComponentScanner implements BeanPostProcessor {
                     }
             );
             // 只有注解支持单bean多Node,所以一个直接返回
-            if (nodeComponents.size() == 1){
+            if (nodeComponents.size() == 1) {
                 return nodeComponents.get(0);
             }
             return bean;
@@ -98,11 +106,38 @@ public class ComponentScanner implements BeanPostProcessor {
             return cmpAroundAspect;
         }
 
-        //扫描@ScriptBean修饰的类
+        // 扫描@ScriptBean修饰的类
         ScriptBean scriptBean = AnnoUtil.getAnnotation(clazz, ScriptBean.class);
-        if (ObjectUtil.isNotNull(scriptBean)){
+        if (ObjectUtil.isNotNull(scriptBean)) {
             ScriptBeanProxy proxy = new ScriptBeanProxy(bean, clazz, scriptBean);
             ScriptBeanManager.addScriptBean(scriptBean.value(), proxy.getProxyScriptBean());
+            return bean;
+        }
+
+        // 扫描@ScriptMethod修饰的类
+        List<Method> scriptMethods = Arrays.stream(clazz.getMethods())
+                .filter(method -> {
+                    ScriptMethod scriptMethod = AnnoUtil.getAnnotation(method, ScriptMethod.class);
+                    return ObjectUtil.isNotNull(scriptMethod) && StrUtil.isNotEmpty(scriptMethod.value());
+                })
+                .collect(Collectors.toList());
+        if (CollUtil.isNotEmpty(scriptMethods)) {
+            Map<String, List<Method>> scriptMethodsGroupByValue = CollStreamUtil.groupBy(scriptMethods, method -> {
+                ScriptMethod scriptMethod = AnnoUtil.getAnnotation(method, ScriptMethod.class);
+                return scriptMethod.value();
+            }, Collectors.toList());
+
+
+            for (Map.Entry<String, List<Method>> entry : scriptMethodsGroupByValue.entrySet()) {
+                String key = entry.getKey();
+                List<Method> methods = entry.getValue();
+                ScriptMethodProxy proxy = new ScriptMethodProxy(bean, clazz, methods);
+
+                ScriptBeanManager.addScriptBean(key, proxy.getProxyScriptMethod());
+
+            }
+
+            return bean;
         }
 
         return bean;

+ 44 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/LiteFlowScriptScripMethodJsELTest.java

@@ -0,0 +1,44 @@
+package com.yomahub.liteflow.test.script.graaljs.scriptmethod;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/scriptmethod/application.properties")
+@SpringBootTest(classes = LiteFlowScriptScripMethodJsELTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.script.graaljs.scriptmethod.cmp", "com.yomahub.liteflow.test.script.graaljs.scriptmethod.bean"})
+public class LiteFlowScriptScripMethodJsELTest extends BaseTest {
+
+    @Resource
+    private FlowExecutor flowExecutor;
+
+    @Test
+    public void testScriptBean1() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello", context.getData("demo"));
+    }
+
+    @Test
+    public void testScriptBean2() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello,kobekobe", context.getData("demo"));
+    }
+
+}

+ 29 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/bean/DemoBean1.java

@@ -0,0 +1,29 @@
+package com.yomahub.liteflow.test.script.graaljs.scriptmethod.bean;
+
+import com.yomahub.liteflow.script.annotation.ScriptMethod;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+public class DemoBean1 {
+
+    @Resource
+    private DemoBean2 demoBean2;
+
+    @ScriptMethod("demo1")
+    public String getDemoStr1() {
+        return "hello";
+    }
+
+    @ScriptMethod("demo")
+    public String getDemoStr2(String name) {
+        return demoBean2.getDemoStr2(name);
+    }
+
+    @ScriptMethod("demo")
+    public String getDemoStr2(String name1, String name2) {
+        return demoBean2.getDemoStr2(name1 + name2);
+    }
+
+}

+ 11 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/bean/DemoBean2.java

@@ -0,0 +1,11 @@
+package com.yomahub.liteflow.test.script.graaljs.scriptmethod.bean;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DemoBean2 {
+
+    public String getDemoStr2(String name){
+        return "hello,"+name;
+    }
+}

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/cmp/ACmp.java

@@ -0,0 +1,20 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.graaljs.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("a")
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ACmp executed!");
+	}
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/cmp/BCmp.java

@@ -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.graaljs.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("b")
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptmethod/cmp/CCmp.java

@@ -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.graaljs.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("c")
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/resources/scriptmethod/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=scriptmethod/flow.xml

+ 27 - 0
liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/resources/scriptmethod/flow.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+
+    <nodes>
+        <node id="d" type="script" language="js">
+            <![CDATA[
+                var str = demo1.getDemoStr1();
+                defaultContext.setData("demo", str);
+            ]]>
+        </node>
+
+        <node id="e" type="script" language="js">
+            <![CDATA[
+                var str = demo.getDemoStr2("kobe","kobe");
+                defaultContext.setData("demo", str);
+            ]]>
+        </node>
+    </nodes>
+
+    <chain name="chain1">
+        THEN(a,b,c,d);
+    </chain>
+
+    <chain name="chain2">
+        THEN(a,b,c,e);
+    </chain>
+</flow>

+ 43 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/LiteFlowScriptScriptMethodGroovyELTest.java

@@ -0,0 +1,43 @@
+package com.yomahub.liteflow.test.script.groovy.scriptmethod;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/scriptmethod/application.properties")
+@SpringBootTest(classes = LiteFlowScriptScriptMethodGroovyELTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.script.groovy.scriptmethod.cmp","com.yomahub.liteflow.test.script.groovy.scriptmethod.bean"})
+public class LiteFlowScriptScriptMethodGroovyELTest extends BaseTest {
+
+    @Resource
+    private FlowExecutor flowExecutor;
+
+    @Test
+    public void testScriptBean1() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello", context.getData("demo"));
+    }
+
+    @Test
+    public void testScriptBean2() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello,kobe", context.getData("demo"));
+    }
+}

+ 25 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/bean/DemoBean1.java

@@ -0,0 +1,25 @@
+package com.yomahub.liteflow.test.script.groovy.scriptmethod.bean;
+
+import com.yomahub.liteflow.script.annotation.ScriptMethod;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+public class DemoBean1 {
+
+    @Resource
+    private DemoBean2 demoBean2;
+
+
+    @ScriptMethod("demo")
+    public String getDemoStr1() {
+        return "hello";
+    }
+
+    @ScriptMethod("demo2")
+    public String getDemoStr2(String name) {
+        return demoBean2.getDemoStr2(name);
+    }
+
+}

+ 11 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/bean/DemoBean2.java

@@ -0,0 +1,11 @@
+package com.yomahub.liteflow.test.script.groovy.scriptmethod.bean;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DemoBean2 {
+
+    public String getDemoStr2(String name){
+        return "hello,"+name;
+    }
+}

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/cmp/ACmp.java

@@ -0,0 +1,20 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.groovy.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("a")
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ACmp executed!");
+	}
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/cmp/BCmp.java

@@ -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.groovy.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("b")
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptmethod/cmp/CCmp.java

@@ -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.groovy.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("c")
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptmethod/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=scriptmethod/flow.xml

+ 27 - 0
liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptmethod/flow.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+
+    <nodes>
+        <node id="d" type="script" language="groovy">
+            <![CDATA[
+                def str = demo.getDemoStr1()
+                defaultContext.setData("demo", str)
+            ]]>
+        </node>
+
+        <node id="e" type="script" language="groovy">
+            <![CDATA[
+                def str = demo2.getDemoStr2("kobe")
+                defaultContext.setData("demo", str)
+            ]]>
+        </node>
+    </nodes>
+
+    <chain name="chain1">
+        THEN(a,b,c,d);
+    </chain>
+
+    <chain name="chain2">
+        THEN(a,b,c,e);
+    </chain>
+</flow>

+ 44 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/LiteFlowScriptScriptMethodJsELTest.java

@@ -0,0 +1,44 @@
+package com.yomahub.liteflow.test.script.javascript.scriptmethod;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/scriptmethod/application.properties")
+@SpringBootTest(classes = LiteFlowScriptScriptMethodJsELTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.script.javascript.scriptmethod.cmp","com.yomahub.liteflow.test.script.javascript.scriptmethod.bean"})
+public class LiteFlowScriptScriptMethodJsELTest extends BaseTest {
+
+    @Resource
+    private FlowExecutor flowExecutor;
+
+    @Test
+    public void testScriptBean1() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello", context.getData("demo"));
+    }
+
+    @Test
+    public void testScriptBean2() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello,kobe", context.getData("demo"));
+    }
+
+}

+ 28 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/bean/DemoBean1.java

@@ -0,0 +1,28 @@
+package com.yomahub.liteflow.test.script.javascript.scriptmethod.bean;
+
+import com.yomahub.liteflow.script.annotation.ScriptMethod;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+public class DemoBean1 {
+
+    @Resource
+    private DemoBean2 demoBean2;
+
+    @ScriptMethod("demo")
+    public String getDemoStr1() {
+        return "hello";
+    }
+
+    @ScriptMethod("demo2")
+    public String getDemoStr2(String name) {
+        return demoBean2.getDemoStr2(name);
+    }
+
+    @ScriptMethod("demo3")
+    public String getDemoStr3(String name, String name2) {
+        return demoBean2.getDemoStr2(name) + name2;
+    }
+}

+ 11 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/bean/DemoBean2.java

@@ -0,0 +1,11 @@
+package com.yomahub.liteflow.test.script.javascript.scriptmethod.bean;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DemoBean2 {
+
+    public String getDemoStr2(String name){
+        return "hello,"+name;
+    }
+}

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/cmp/ACmp.java

@@ -0,0 +1,20 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.javascript.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("a")
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ACmp executed!");
+	}
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/cmp/BCmp.java

@@ -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.javascript.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("b")
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptmethod/cmp/CCmp.java

@@ -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.javascript.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("c")
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/scriptmethod/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=scriptmethod/flow.xml

+ 27 - 0
liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/resources/scriptmethod/flow.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+
+    <nodes>
+        <node id="d" type="script" language="js">
+            <![CDATA[
+                var str = demo.getDemoStr1();
+                defaultContext.setData("demo", str);
+            ]]>
+        </node>
+
+        <node id="e" type="script" language="js">
+            <![CDATA[
+                var str = demo2.getDemoStr2("kobe");
+                defaultContext.setData("demo", str);
+            ]]>
+        </node>
+    </nodes>
+
+    <chain name="chain1">
+        THEN(a,b,c,d);
+    </chain>
+
+    <chain name="chain2">
+        THEN(a,b,c,e);
+    </chain>
+</flow>

+ 44 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/LiteFlowScriptScriptMethodQLExpressELTest.java

@@ -0,0 +1,44 @@
+package com.yomahub.liteflow.test.script.qlexpress.scriptmethod;
+
+import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.flow.LiteflowResponse;
+import com.yomahub.liteflow.slot.DefaultContext;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+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.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+
+@RunWith(SpringRunner.class)
+@TestPropertySource(value = "classpath:/scriptmethod/application.properties")
+@SpringBootTest(classes = LiteFlowScriptScriptMethodQLExpressELTest.class)
+@EnableAutoConfiguration
+@ComponentScan({"com.yomahub.liteflow.test.script.qlexpress.scriptmethod.cmp","com.yomahub.liteflow.test.script.qlexpress.scriptmethod.bean"})
+public class LiteFlowScriptScriptMethodQLExpressELTest extends BaseTest {
+
+    @Resource
+    private FlowExecutor flowExecutor;
+
+    @Test
+    public void testScriptBean1() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello", context.getData("demo"));
+    }
+
+    @Test
+    public void testScriptBean2() throws Exception{
+        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+        Assert.assertTrue(response.isSuccess());
+        DefaultContext context = response.getFirstContextBean();
+        Assert.assertEquals("hello,kobe", context.getData("demo"));
+    }
+
+}

+ 23 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/bean/DemoBean1.java

@@ -0,0 +1,23 @@
+package com.yomahub.liteflow.test.script.qlexpress.scriptmethod.bean;
+
+import com.yomahub.liteflow.script.annotation.ScriptMethod;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+public class DemoBean1 {
+
+    @Resource
+    private DemoBean2 demoBean2;
+
+    @ScriptMethod("demo")
+    public String getDemoStr1(){
+        return "hello";
+    }
+
+    @ScriptMethod("demo2")
+    public String getDemoStr2(String name){
+        return demoBean2.getDemoStr2(name);
+    }
+}

+ 11 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/bean/DemoBean2.java

@@ -0,0 +1,11 @@
+package com.yomahub.liteflow.test.script.qlexpress.scriptmethod.bean;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class DemoBean2 {
+
+    public String getDemoStr2(String name){
+        return "hello,"+name;
+    }
+}

+ 20 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/cmp/ACmp.java

@@ -0,0 +1,20 @@
+/**
+ * <p>Title: liteflow</p>
+ * <p>Description: 轻量级的组件式流程框架</p>
+ * @author Bryan.Zhang
+ * @email weenyc31@163.com
+ * @Date 2020/4/1
+ */
+package com.yomahub.liteflow.test.script.qlexpress.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("a")
+public class ACmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("ACmp executed!");
+	}
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/cmp/BCmp.java

@@ -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.qlexpress.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("b")
+public class BCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("BCmp executed!");
+	}
+
+}

+ 21 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptmethod/cmp/CCmp.java

@@ -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.qlexpress.scriptmethod.cmp;
+
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.stereotype.Component;
+
+@Component("c")
+public class CCmp extends NodeComponent {
+
+	@Override
+	public void process() {
+		System.out.println("CCmp executed!");
+	}
+
+}

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/resources/scriptmethod/application.properties

@@ -0,0 +1 @@
+liteflow.rule-source=scriptmethod/flow.xml

+ 27 - 0
liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/resources/scriptmethod/flow.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<flow>
+
+    <nodes>
+        <node id="d" type="script">
+            <![CDATA[
+                str = demo.getDemoStr1();
+                defaultContext.setData("demo", str);
+            ]]>
+        </node>
+
+        <node id="e" type="script">
+            <![CDATA[
+                str = demo2.getDemoStr2("kobe");
+                defaultContext.setData("demo", str);
+            ]]>
+        </node>
+    </nodes>
+
+    <chain name="chain1">
+        THEN(a,b,c,d)
+    </chain>
+
+    <chain name="chain2">
+        THEN(a,b,c,e)
+    </chain>
+</flow>