feature #I6A2GL 增加迭代器表达式特性,用于迭代循环中的集合
This commit is contained in:
parent
429d8ed2d6
commit
cebfb2867e
|
@ -53,6 +53,10 @@ public class LiteFlowNodeBuilder {
|
|||
return new LiteFlowNodeBuilder(NodeTypeEnum.BREAK);
|
||||
}
|
||||
|
||||
public static LiteFlowNodeBuilder createIteratorNode() {
|
||||
return new LiteFlowNodeBuilder(NodeTypeEnum.ITERATOR);
|
||||
}
|
||||
|
||||
public static LiteFlowNodeBuilder createScriptNode() {
|
||||
return new LiteFlowNodeBuilder(NodeTypeEnum.SCRIPT);
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ public class LiteFlowChainELBuilder {
|
|||
EXPRESS_RUNNER.addFunction(ChainConstant.NODE, new NodeOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.FOR, new ForOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.WHILE, new WhileOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.ITERATOR, new IteratorOperator());
|
||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DO, Object.class, new DoOperator());
|
||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.BREAK, Object.class, new BreakOperator());
|
||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DATA, Object.class, new DataOperator());
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.yomahub.liteflow.builder.el.operator;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.ql.util.express.exception.QLException;
|
||||
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
|
||||
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.condition.IteratorCondition;
|
||||
|
||||
public class IteratorOperator extends BaseOperator<IteratorCondition> {
|
||||
@Override
|
||||
public IteratorCondition build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeEq(objects, 1);
|
||||
|
||||
Node node = OperatorHelper.convert(objects[0], Node.class);
|
||||
if (!ListUtil.toList(NodeTypeEnum.ITERATOR).contains(node.getType())) {
|
||||
throw new QLException("The parameter must be iterator-node item");
|
||||
}
|
||||
|
||||
IteratorCondition iteratorCondition = new IteratorCondition();
|
||||
iteratorCondition.setIteratorNode(node);
|
||||
|
||||
return iteratorCondition;
|
||||
}
|
||||
}
|
|
@ -63,6 +63,8 @@ public interface ChainConstant {
|
|||
|
||||
String DATA = "data";
|
||||
|
||||
String ITERATOR = "ITERATOR";
|
||||
|
||||
String MONITOR_BUS = "monitorBus";
|
||||
|
||||
String CURR_CHAIN_ID = "currChainId";
|
||||
|
|
|
@ -349,6 +349,10 @@ public abstract class NodeComponent{
|
|||
return this.refNodeTL.get().getLoopIndex();
|
||||
}
|
||||
|
||||
public <T> T getCurrLoopObj(){
|
||||
return this.refNodeTL.get().getCurrLoopObject();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void invoke(String chainId, Object param) throws Exception {
|
||||
FlowExecutorHolder.loadInstance().invoke(chainId, param, this.getSlotIndex());
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* ITERATOR迭代器循环组件抽象类
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.9.7
|
||||
*/
|
||||
public abstract class NodeIteratorComponent extends NodeComponent{
|
||||
|
||||
@Override
|
||||
public void process() throws Exception {
|
||||
Iterator<?> it = processIterator();
|
||||
Slot slot = this.getSlot();
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
slot.setIteratorResult(originalClass.getName(), it);
|
||||
}
|
||||
|
||||
public abstract Iterator<?> processIterator() throws Exception;
|
||||
}
|
|
@ -14,7 +14,9 @@ public enum ConditionTypeEnum {
|
|||
|
||||
TYPE_FOR("for", "for"),
|
||||
|
||||
TYPE_WHILE("while", "while")
|
||||
TYPE_WHILE("while", "while"),
|
||||
|
||||
TYPE_ITERATOR("iterator", "iterator")
|
||||
;
|
||||
private String type;
|
||||
private String name;
|
||||
|
|
|
@ -7,6 +7,9 @@ public enum LiteFlowMethodEnum {
|
|||
PROCESS_FOR("processFor", true),
|
||||
PROCESS_WHILE("processWhile", true),
|
||||
PROCESS_BREAK("processBreak", true),
|
||||
|
||||
PROCESS_ITERATOR("processIterator", true),
|
||||
|
||||
IS_ACCESS("isAccess", false),
|
||||
|
||||
IS_END("isEnd", false),
|
||||
|
|
|
@ -35,6 +35,8 @@ public enum NodeTypeEnum {
|
|||
|
||||
BREAK("break", "循环跳出", false, NodeBreakComponent.class),
|
||||
|
||||
ITERATOR("iterator", "循环迭代", false, NodeIteratorComponent.class),
|
||||
|
||||
SCRIPT("script", "脚本", true, ScriptCommonComponent.class),
|
||||
|
||||
SWITCH_SCRIPT("switch_script", "选择脚本", true, ScriptSwitchComponent.class),
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.yomahub.liteflow.exception;
|
||||
|
||||
/**
|
||||
* 没有节点异常
|
||||
* @author Yun
|
||||
*/
|
||||
public class NoIteratorNodeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public NoIteratorNodeException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
|
@ -56,6 +56,8 @@ public class Node implements Executable,Cloneable{
|
|||
|
||||
private TransmittableThreadLocal<Integer> loopIndexTL = new TransmittableThreadLocal<>();
|
||||
|
||||
private TransmittableThreadLocal<Object> currLoopObject = new TransmittableThreadLocal<>();
|
||||
|
||||
public Node(){
|
||||
|
||||
}
|
||||
|
@ -241,4 +243,16 @@ public class Node implements Executable,Cloneable{
|
|||
public void removeLoopIndex(){
|
||||
this.loopIndexTL.remove();
|
||||
}
|
||||
|
||||
public void setCurrLoopObject(Object obj){
|
||||
this.currLoopObject.set(obj);
|
||||
}
|
||||
|
||||
public <T> T getCurrLoopObject(){
|
||||
return (T)this.currLoopObject.get();
|
||||
}
|
||||
|
||||
public void removeCurrLoopObject(){
|
||||
this.currLoopObject.remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public class ForCondition extends LoopCondition{
|
|||
//如果break组件不为空,则去执行
|
||||
if (ObjectUtil.isNotNull(breakNode)){
|
||||
breakNode.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakNode, i);
|
||||
breakNode.execute(slotIndex);
|
||||
Class<?> originalBreakClass = LiteFlowProxyUtil.getUserClass(this.breakNode.getInstance().getClass());
|
||||
boolean isBreak = slot.getBreakResult(originalBreakClass.getName());
|
||||
|
@ -64,10 +65,6 @@ public class ForCondition extends LoopCondition{
|
|||
return ConditionTypeEnum.TYPE_FOR;
|
||||
}
|
||||
|
||||
public Executable getDoExecutor() {
|
||||
return this.getExecutableList().get(0);
|
||||
}
|
||||
|
||||
public Node getForNode() {
|
||||
return forNode;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.exception.NoIteratorNodeException;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class IteratorCondition extends LoopCondition{
|
||||
|
||||
private Node iteratorNode;
|
||||
|
||||
@Override
|
||||
public void execute(Integer slotIndex) throws Exception {
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
if (ObjectUtil.isNull(iteratorNode)){
|
||||
String errorInfo = StrUtil.format("[{}]:no iterator-node found", slot.getRequestId());
|
||||
throw new NoIteratorNodeException(errorInfo);
|
||||
}
|
||||
|
||||
//执行Iterator组件
|
||||
iteratorNode.setCurrChainId(this.getCurrChainId());
|
||||
iteratorNode.execute(slotIndex);
|
||||
|
||||
//这里可能会有spring代理过的bean,所以拿到user原始的class
|
||||
Class<?> originalForCountClass = LiteFlowProxyUtil.getUserClass(this.iteratorNode.getInstance().getClass());
|
||||
//获得迭代器
|
||||
Iterator<?> it = slot.getIteratorResult(originalForCountClass.getName());
|
||||
|
||||
//获得要循环的可执行对象
|
||||
Executable executableItem = this.getDoExecutor();
|
||||
|
||||
int index = 0;
|
||||
while(it.hasNext()){
|
||||
Object itObj = it.next();
|
||||
|
||||
executableItem.setCurrChainId(this.getCurrChainId());
|
||||
//设置循环index
|
||||
setLoopIndex(executableItem, index);
|
||||
//设置循环迭代器对象
|
||||
setCurrLoopObject(executableItem, itObj);
|
||||
//执行可执行对象
|
||||
executableItem.execute(slotIndex);
|
||||
//如果break组件不为空,则去执行
|
||||
if (ObjectUtil.isNotNull(breakNode)){
|
||||
breakNode.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakNode, index);
|
||||
setCurrLoopObject(breakNode, itObj);
|
||||
breakNode.execute(slotIndex);
|
||||
Class<?> originalBreakClass = LiteFlowProxyUtil.getUserClass(this.breakNode.getInstance().getClass());
|
||||
boolean isBreak = slot.getBreakResult(originalBreakClass.getName());
|
||||
if (isBreak){
|
||||
break;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionTypeEnum getConditionType() {
|
||||
return ConditionTypeEnum.TYPE_ITERATOR;
|
||||
}
|
||||
|
||||
public Node getIteratorNode() {
|
||||
return iteratorNode;
|
||||
}
|
||||
|
||||
public void setIteratorNode(Node iteratorNode) {
|
||||
this.iteratorNode = iteratorNode;
|
||||
}
|
||||
}
|
|
@ -32,4 +32,18 @@ public abstract class LoopCondition extends Condition {
|
|||
((Node)executableItem).setLoopIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setCurrLoopObject(Executable executableItem, Object obj){
|
||||
if (executableItem instanceof Chain){
|
||||
((Chain)executableItem).getConditionList().forEach(condition -> setCurrLoopObject(condition, obj));
|
||||
}else if(executableItem instanceof Condition){
|
||||
((Condition)executableItem).getExecutableList().forEach(executable -> setCurrLoopObject(executable, obj));
|
||||
}else if(executableItem instanceof Node){
|
||||
((Node)executableItem).setCurrLoopObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
protected Executable getDoExecutor() {
|
||||
return this.getExecutableList().get(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,12 @@ public class WhileCondition extends LoopCondition{
|
|||
int index = 0;
|
||||
while(getWhileResult(slotIndex)){
|
||||
executableItem.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(executableItem, index++);
|
||||
setLoopIndex(executableItem, index);
|
||||
executableItem.execute(slotIndex);
|
||||
//如果break组件不为空,则去执行
|
||||
if (ObjectUtil.isNotNull(breakNode)){
|
||||
breakNode.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakNode, index);
|
||||
breakNode.execute(slotIndex);
|
||||
Class<?> originalBreakClass = LiteFlowProxyUtil.getUserClass(this.breakNode.getInstance().getClass());
|
||||
boolean isBreak = slot.getBreakResult(originalBreakClass.getName());
|
||||
|
@ -47,22 +48,19 @@ public class WhileCondition extends LoopCondition{
|
|||
break;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getWhileResult(Integer slotIndex) throws Exception{
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
//执行while组件
|
||||
whileNode.setCurrChainName(this.getCurrChainName());
|
||||
whileNode.setCurrChainId(this.getCurrChainId());
|
||||
whileNode.execute(slotIndex);
|
||||
Class<?> originalWhileClass = LiteFlowProxyUtil.getUserClass(this.whileNode.getInstance().getClass());
|
||||
return slot.getWhileResult(originalWhileClass.getName());
|
||||
}
|
||||
|
||||
public Executable getDoExecutor() {
|
||||
return this.getExecutableList().get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionTypeEnum getConditionType() {
|
||||
return ConditionTypeEnum.TYPE_WHILE;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.yomahub.liteflow.test.iterator;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
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;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* springboot环境最普通的例子测试
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.6.4
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(value = "classpath:/iterator/application.properties")
|
||||
@SpringBootTest(classes = IteratorELDeclMultiSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({"com.yomahub.liteflow.test.iterator.cmp"})
|
||||
public class IteratorELDeclMultiSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
//最简单的情况
|
||||
@Test
|
||||
public void testIt1() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("123", str);
|
||||
}
|
||||
|
||||
//迭代器带break
|
||||
@Test
|
||||
public void testIt2() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("12", str);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import com.yomahub.liteflow.test.base.cmp.TestDomain;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@LiteflowComponent
|
||||
public class CmpConfig {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "a")
|
||||
public void processA(NodeComponent bindCmp) {
|
||||
String key = "test";
|
||||
DefaultContext context = bindCmp.getFirstContextBean();
|
||||
if (!context.hasData(key)){
|
||||
context.setData(key, bindCmp.getCurrLoopObj());
|
||||
}else{
|
||||
String str = context.getData(key);
|
||||
str += bindCmp.getCurrLoopObj();
|
||||
context.setData(key, str);
|
||||
}
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_BREAK, nodeId = "b", nodeType = NodeTypeEnum.BREAK)
|
||||
public boolean processB(NodeComponent bindCmp) {
|
||||
return bindCmp.getLoopIndex() == 1;
|
||||
}
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_ITERATOR, nodeId = "it", nodeType = NodeTypeEnum.ITERATOR)
|
||||
public Iterator<?> processIT(NodeComponent bindCmp) {
|
||||
List<String> list = bindCmp.getRequestData();
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=iterator/flow.xml
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
ITERATOR(it).DO(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
ITERATOR(it).DO(a).BREAK(b);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,57 @@
|
|||
package com.yomahub.liteflow.test.iterator;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
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;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* springboot环境最普通的例子测试
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.6.4
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(value = "classpath:/iterator/application.properties")
|
||||
@SpringBootTest(classes = IteratorELDeclSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({"com.yomahub.liteflow.test.iterator.cmp"})
|
||||
public class IteratorELDeclSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
//最简单的情况
|
||||
@Test
|
||||
public void testIt1() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("123", str);
|
||||
}
|
||||
|
||||
//迭代器带break
|
||||
@Test
|
||||
public void testIt2() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("12", str);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a")
|
||||
@LiteflowCmpDefine(NodeTypeEnum.COMMON)
|
||||
public class ACmp{
|
||||
|
||||
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)
|
||||
public void process(NodeComponent bindCmp) {
|
||||
String key = "test";
|
||||
DefaultContext context = bindCmp.getFirstContextBean();
|
||||
if (!context.hasData(key)){
|
||||
context.setData(key, bindCmp.getCurrLoopObj());
|
||||
}else{
|
||||
String str = context.getData(key);
|
||||
str += bindCmp.getCurrLoopObj();
|
||||
context.setData(key, str);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("b")
|
||||
@LiteflowCmpDefine(NodeTypeEnum.BREAK)
|
||||
public class BCmp{
|
||||
|
||||
@LiteflowMethod(LiteFlowMethodEnum.PROCESS_BREAK)
|
||||
public boolean processBreak(NodeComponent bindCmp) throws Exception {
|
||||
return bindCmp.getLoopIndex() == 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("it")
|
||||
@LiteflowCmpDefine(NodeTypeEnum.ITERATOR)
|
||||
public class ITCmp{
|
||||
@LiteflowMethod(LiteFlowMethodEnum.PROCESS_ITERATOR)
|
||||
public Iterator<?> processIterator(NodeComponent bindCmp) throws Exception {
|
||||
List<String> list = bindCmp.getRequestData();
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=iterator/flow.xml
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
ITERATOR(it).DO(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
ITERATOR(it).DO(a).BREAK(b);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,48 @@
|
|||
package com.yomahub.liteflow.test.iterator;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.core.FlowExecutorHolder;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.property.LiteflowConfig;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class IteratorTest extends BaseTest{
|
||||
|
||||
private static FlowExecutor flowExecutor;
|
||||
|
||||
@BeforeClass
|
||||
public static void init(){
|
||||
LiteflowConfig config = new LiteflowConfig();
|
||||
config.setRuleSource("iterator/flow.xml");
|
||||
flowExecutor = FlowExecutorHolder.loadInstance(config);
|
||||
}
|
||||
|
||||
//最简单的情况
|
||||
@Test
|
||||
public void testIt1() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("123", str);
|
||||
}
|
||||
|
||||
//迭代器带break
|
||||
@Test
|
||||
public void testIt2() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("12", str);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
|
||||
public class ACmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
String key = "test";
|
||||
DefaultContext context = this.getFirstContextBean();
|
||||
if (!context.hasData(key)){
|
||||
context.setData(key, this.getCurrLoopObj());
|
||||
}else{
|
||||
String str = context.getData(key);
|
||||
str += this.getCurrLoopObj();
|
||||
context.setData(key, str);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
|
||||
public class BCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
return this.getLoopIndex() == 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class ITCmp extends NodeIteratorComponent {
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = this.getRequestData();
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<nodes>
|
||||
<node id="a" class="com.yomahub.liteflow.test.iterator.cmp.ACmp"/>
|
||||
<node id="b" class="com.yomahub.liteflow.test.iterator.cmp.BCmp"/>
|
||||
<node id="it" class="com.yomahub.liteflow.test.iterator.cmp.ITCmp"/>
|
||||
</nodes>
|
||||
|
||||
<chain name="chain1">
|
||||
ITERATOR(it).DO(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
ITERATOR(it).DO(a).BREAK(b);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,55 @@
|
|||
package com.yomahub.liteflow.test.iterator;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
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;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* springboot环境EL常规的例子测试
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(value = "classpath:/iterator/application.properties")
|
||||
@SpringBootTest(classes = IteratorELSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({"com.yomahub.liteflow.test.iterator.cmp"})
|
||||
public class IteratorELSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
//最简单的情况
|
||||
@Test
|
||||
public void testIt1() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("123", str);
|
||||
}
|
||||
|
||||
//迭代器带break
|
||||
@Test
|
||||
public void testIt2() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("12", str);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a")
|
||||
public class ACmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
String key = "test";
|
||||
DefaultContext context = this.getFirstContextBean();
|
||||
if (!context.hasData(key)){
|
||||
context.setData(key, this.getCurrLoopObj());
|
||||
}else{
|
||||
String str = context.getData(key);
|
||||
str += this.getCurrLoopObj();
|
||||
context.setData(key, str);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("b")
|
||||
public class BCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
return this.getLoopIndex() == 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("it")
|
||||
public class ITCmp extends NodeIteratorComponent {
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = this.getRequestData();
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=iterator/flow.xml
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
ITERATOR(it).DO(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
ITERATOR(it).DO(a).BREAK(b);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,45 @@
|
|||
package com.yomahub.liteflow.test.iterator;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:/iterator/application.xml")
|
||||
public class IteratorELSpringTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
//最简单的情况
|
||||
@Test
|
||||
public void testIt1() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("123", str);
|
||||
}
|
||||
|
||||
//迭代器带break
|
||||
@Test
|
||||
public void testIt2() throws Exception{
|
||||
List<String> list = ListUtil.toList("1","2","3");
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", list);
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
DefaultContext context = response.getFirstContextBean();
|
||||
String str = context.getData("test");
|
||||
Assert.assertEquals("12", str);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.slot.DefaultContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("a")
|
||||
public class ACmp extends NodeComponent {
|
||||
|
||||
@Override
|
||||
public void process() {
|
||||
String key = "test";
|
||||
DefaultContext context = this.getFirstContextBean();
|
||||
if (!context.hasData(key)){
|
||||
context.setData(key, this.getCurrLoopObj());
|
||||
}else{
|
||||
String str = context.getData(key);
|
||||
str += this.getCurrLoopObj();
|
||||
context.setData(key, str);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("b")
|
||||
public class BCmp extends NodeBreakComponent {
|
||||
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
return this.getLoopIndex() == 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.yomahub.liteflow.test.iterator.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIteratorComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component("it")
|
||||
public class ITCmp extends NodeIteratorComponent {
|
||||
@Override
|
||||
public Iterator<?> processIterator() throws Exception {
|
||||
List<String> list = this.getRequestData();
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
|
||||
|
||||
<context:component-scan base-package="com.yomahub.liteflow.test.iterator.cmp" />
|
||||
|
||||
<bean id="springAware" class="com.yomahub.liteflow.spi.spring.SpringAware"/>
|
||||
|
||||
<bean class="com.yomahub.liteflow.spring.ComponentScanner"/>
|
||||
|
||||
<bean id="liteflowConfig" class="com.yomahub.liteflow.property.LiteflowConfig">
|
||||
<property name="ruleSource" value="iterator/flow.xml"/>
|
||||
</bean>
|
||||
|
||||
<bean id="flowExecutor" class="com.yomahub.liteflow.core.FlowExecutor">
|
||||
<constructor-arg name="liteflowConfig" ref="liteflowConfig"/>
|
||||
</bean>
|
||||
</beans>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
ITERATOR(it).DO(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
ITERATOR(it).DO(a).BREAK(b);
|
||||
</chain>
|
||||
</flow>
|
Loading…
Reference in New Issue