feature #I6RF8Y EL表达式里支持并或非操作符
This commit is contained in:
parent
44c8920ab7
commit
d62611e90b
|
@ -16,7 +16,7 @@ import com.yomahub.liteflow.exception.FlowSystemException;
|
|||
import com.yomahub.liteflow.flow.FlowBus;
|
||||
import com.yomahub.liteflow.flow.element.Chain;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.condition.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -37,9 +37,9 @@ public class LiteFlowChainELBuilder {
|
|||
private Chain chain;
|
||||
|
||||
/**
|
||||
* //这是主体的Condition //声明这个变量,而不是用chain.getConditionList的目的,是为了辅助平滑加载
|
||||
* //虽然FlowBus里面的map都是CopyOnWrite类型的,但是在buildCondition的时候,为了平滑加载,所以不能事先把chain.getConditionList给设为空List
|
||||
* //所以在这里做一个缓存,等conditionList全部build完毕后,再去一次性替换chain里面的conditionList
|
||||
* 这是主体的Condition //声明这个变量,而不是用chain.getConditionList的目的,是为了辅助平滑加载
|
||||
* 虽然FlowBus里面的map都是CopyOnWrite类型的,但是在buildCondition的时候,为了平滑加载,所以不能事先把chain.getConditionList给设为空List
|
||||
* 所以在这里做一个缓存,等conditionList全部build完毕后,再去一次性替换chain里面的conditionList
|
||||
*/
|
||||
private final List<Condition> conditionList;
|
||||
|
||||
|
@ -62,6 +62,9 @@ public class LiteFlowChainELBuilder {
|
|||
EXPRESS_RUNNER.addFunction(ChainConstant.WHILE, new WhileOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.ITERATOR, new IteratorOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.CATCH, new CatchOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.AND, new AndOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.OR, new OrOperator());
|
||||
EXPRESS_RUNNER.addFunction(ChainConstant.NOT, new NotOperator());
|
||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ELSE, Object.class, new ElseOperator());
|
||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ELIF, Object.class, new ElifOperator());
|
||||
EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TO, Object.class, new ToOperator());
|
||||
|
@ -139,18 +142,6 @@ public class LiteFlowChainELBuilder {
|
|||
// 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样
|
||||
Condition condition = (Condition) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true);
|
||||
|
||||
// 从condition的第一层嵌套结构里拿出Pre和Finally节点
|
||||
// 为什么只寻找第一层,而不往下寻找了呢?
|
||||
// 因为这是一个规范,如果在后面的层级中出现pre和finally,语义上也不好理解,所以pre和finally只能定义在第一层
|
||||
// 如果硬是要在后面定义,则执行的时候会忽略,相关代码已做了判断
|
||||
/*
|
||||
* for (Executable executable : condition.getExecutableList()) { if
|
||||
* (executable instanceof PreCondition) {
|
||||
* this.preConditionList.add((PreCondition) executable); } else if (executable
|
||||
* instanceof FinallyCondition) {
|
||||
* this.finallyConditionList.add((FinallyCondition) executable); } }
|
||||
*/
|
||||
|
||||
// 把主要的condition加入
|
||||
this.conditionList.add(condition);
|
||||
return this;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.yomahub.liteflow.builder.el.operator;
|
||||
|
||||
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
|
||||
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.BooleanConditionTypeEnum;
|
||||
|
||||
/**
|
||||
* EL表达式中AND关键字的操作
|
||||
* 主要用于适用于产生布尔类型结果的表达式中,比如IF(AND(a,b)),WHILE(AND(a,b))
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.10.2
|
||||
*/
|
||||
public class AndOperator extends BaseOperator<AndOrCondition> {
|
||||
@Override
|
||||
public AndOrCondition build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeGtTwo(objects);
|
||||
|
||||
AndOrCondition andOrCondition = new AndOrCondition();
|
||||
andOrCondition.setBooleanConditionType(BooleanConditionTypeEnum.AND);
|
||||
|
||||
for (Object object : objects){
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(object);
|
||||
|
||||
Executable item = OperatorHelper.convert(object, Executable.class);
|
||||
andOrCondition.addItem(item);
|
||||
}
|
||||
|
||||
return andOrCondition;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ 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.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
|
||||
|
||||
|
@ -25,13 +26,9 @@ public class BreakOperator extends BaseOperator<LoopCondition> {
|
|||
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
|
||||
|
||||
// 获得需要执行的可执行表达式
|
||||
Node breakNode = OperatorHelper.convert(objects[1], Node.class);
|
||||
if (ListUtil.toList(NodeTypeEnum.BREAK, NodeTypeEnum.BREAK_SCRIPT).contains(breakNode.getType())) {
|
||||
condition.setBreakNode(breakNode);
|
||||
}
|
||||
else {
|
||||
throw new QLException("The parameter must be node-break item");
|
||||
}
|
||||
Executable breakItem = OperatorHelper.convert(objects[1], Node.class);
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(breakItem);
|
||||
condition.setBreakItem(breakItem);
|
||||
return condition;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
|
|||
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.condition.CatchCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.condition.LoopCondition;
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,17 +25,15 @@ public class ElifOperator extends BaseOperator<IfCondition> {
|
|||
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
|
||||
|
||||
// 解析第一个参数
|
||||
Node ifNode = OperatorHelper.convert(objects[1], Node.class);
|
||||
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
|
||||
throw new QLException("The first parameter must be If item");
|
||||
}
|
||||
Executable ifItem = OperatorHelper.convert(objects[1], Node.class);
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(ifItem);
|
||||
|
||||
// 解析第二个参数
|
||||
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
|
||||
|
||||
// 构建一个内部的IfCondition
|
||||
IfCondition ifConditionItem = new IfCondition();
|
||||
ifConditionItem.setIfNode(ifNode);
|
||||
ifConditionItem.setIfItem(ifItem);
|
||||
ifConditionItem.setTrueCaseExecutableItem(trueCaseExecutableItem);
|
||||
|
||||
// 因为可能会有多个ELIF,所以每一次拿到的caller总是最开始大的if,需要遍历到没有falseCaseExecutable的地方。
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.yomahub.liteflow.builder.el.operator;
|
|||
|
||||
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
|
||||
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
||||
import com.yomahub.liteflow.flow.element.condition.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
|
||||
/**
|
||||
* EL规则中的id的操作符,只有condition可加id
|
||||
|
|
|
@ -7,7 +7,9 @@ import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
|||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.IfCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.NotCondition;
|
||||
|
||||
/**
|
||||
* EL规则中的IF的操作符
|
||||
|
@ -22,10 +24,8 @@ public class IfOperator extends BaseOperator<IfCondition> {
|
|||
OperatorHelper.checkObjectSizeEq(objects, 2, 3);
|
||||
|
||||
// 解析第一个参数
|
||||
Node ifNode = OperatorHelper.convert(objects[0], Node.class);
|
||||
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
|
||||
throw new QLException("The first parameter must be If item");
|
||||
}
|
||||
Executable ifItem = OperatorHelper.convert(objects[0], Executable.class);
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(ifItem);
|
||||
|
||||
// 解析第二个参数
|
||||
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
|
||||
|
@ -37,7 +37,7 @@ public class IfOperator extends BaseOperator<IfCondition> {
|
|||
}
|
||||
|
||||
IfCondition ifCondition = new IfCondition();
|
||||
ifCondition.setIfNode(ifNode);
|
||||
ifCondition.setIfItem(ifItem);
|
||||
ifCondition.setTrueCaseExecutableItem(trueCaseExecutableItem);
|
||||
ifCondition.setFalseCaseExecutableItem(falseCaseExecutableItem);
|
||||
return ifCondition;
|
||||
|
|
|
@ -20,7 +20,7 @@ public class NodeOperator extends BaseOperator<Node> {
|
|||
|
||||
@Override
|
||||
public Node build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeNeqOne(objects);
|
||||
OperatorHelper.checkObjectSizeEqOne(objects);
|
||||
|
||||
String nodeId = OperatorHelper.convert(objects[0], String.class);
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.yomahub.liteflow.builder.el.operator;
|
||||
|
||||
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
|
||||
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.BooleanConditionTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.condition.NotCondition;
|
||||
|
||||
/**
|
||||
* EL表达式中NOT关键字的操作,表示非的操作
|
||||
* 主要用于适用于产生布尔类型结果的表达式中,比如IF(NOT(a)),WHILE(NOT(a))
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.10.2
|
||||
*/
|
||||
public class NotOperator extends BaseOperator<NotCondition> {
|
||||
@Override
|
||||
public NotCondition build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeEqOne(objects);
|
||||
|
||||
Object object = objects[0];
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(object);
|
||||
Executable item = OperatorHelper.convert(object, Executable.class);
|
||||
|
||||
NotCondition notCondition = new NotCondition();
|
||||
notCondition.setItem(item);
|
||||
|
||||
return notCondition;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.yomahub.liteflow.builder.el.operator;
|
||||
|
||||
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
|
||||
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.BooleanConditionTypeEnum;
|
||||
|
||||
/**
|
||||
* EL表达式中OR关键字的操作
|
||||
* 主要用于适用于产生布尔类型结果的表达式中,比如IF(OR(a,b)),WHILE(OR(a,b))
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.10.2
|
||||
*/
|
||||
public class OrOperator extends BaseOperator<AndOrCondition> {
|
||||
@Override
|
||||
public AndOrCondition build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeGtTwo(objects);
|
||||
|
||||
AndOrCondition andOrCondition = new AndOrCondition();
|
||||
andOrCondition.setBooleanConditionType(BooleanConditionTypeEnum.OR);
|
||||
|
||||
for (Object object : objects){
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(object);
|
||||
|
||||
Executable item = OperatorHelper.convert(object, Executable.class);
|
||||
andOrCondition.addItem(item);
|
||||
}
|
||||
|
||||
return andOrCondition;
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ public class SwitchOperator extends BaseOperator<SwitchCondition> {
|
|||
|
||||
@Override
|
||||
public SwitchCondition build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeNeqOne(objects);
|
||||
OperatorHelper.checkObjectSizeEqOne(objects);
|
||||
|
||||
Node switchNode = OperatorHelper.convert(objects[0], Node.class);
|
||||
if (!ListUtil.toList(NodeTypeEnum.SWITCH, NodeTypeEnum.SWITCH_SCRIPT).contains(switchNode.getType())) {
|
||||
|
|
|
@ -5,6 +5,7 @@ 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.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.condition.WhileCondition;
|
||||
|
||||
|
@ -18,15 +19,13 @@ public class WhileOperator extends BaseOperator<WhileCondition> {
|
|||
|
||||
@Override
|
||||
public WhileCondition build(Object[] objects) throws Exception {
|
||||
OperatorHelper.checkObjectSizeEq(objects, 1);
|
||||
OperatorHelper.checkObjectSizeEqOne(objects);
|
||||
|
||||
Node node = OperatorHelper.convert(objects[0], Node.class);
|
||||
if (!ListUtil.toList(NodeTypeEnum.WHILE, NodeTypeEnum.WHILE_SCRIPT).contains(node.getType())) {
|
||||
throw new QLException("The parameter must be while-node item");
|
||||
}
|
||||
Executable whileItem = OperatorHelper.convert(objects[0], Executable.class);
|
||||
OperatorHelper.checkObjectMustBeBooleanItem(whileItem);
|
||||
|
||||
WhileCondition whileCondition = new WhileCondition();
|
||||
whileCondition.setWhileNode(node);
|
||||
whileCondition.setWhileItem(whileItem);
|
||||
return whileCondition;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ public abstract class BaseOperator<T extends Executable> extends Operator {
|
|||
@Override
|
||||
public T executeInner(Object[] objects) throws Exception {
|
||||
try {
|
||||
// 检查 node 和 chain 是否已经注册
|
||||
OperatorHelper.checkNodeAndChainExist(objects);
|
||||
OperatorHelper.checkItemNotNull(objects);
|
||||
return build(objects);
|
||||
}
|
||||
catch (QLException e) {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package com.yomahub.liteflow.builder.el.operator.base;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ql.util.express.exception.QLException;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.DataNotFoundException;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.flow.element.condition.AndOrCondition;
|
||||
import com.yomahub.liteflow.flow.element.condition.NotCondition;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -15,28 +19,6 @@ import java.util.Objects;
|
|||
*/
|
||||
public class OperatorHelper {
|
||||
|
||||
/**
|
||||
* 检查参数数量,不等于1
|
||||
* @param objects objects
|
||||
* @throws QLException QLException
|
||||
*/
|
||||
public static void checkObjectSizeNeqOne(Object[] objects) throws QLException {
|
||||
checkObjectSizeNeq(objects, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查参数数量,不等于 size
|
||||
* @param objects objects
|
||||
* @param size 参数数量
|
||||
* @throws QLException QLException
|
||||
*/
|
||||
public static void checkObjectSizeNeq(Object[] objects, int size) throws QLException {
|
||||
checkObjectSizeGtZero(objects);
|
||||
if (objects.length != size) {
|
||||
throw new QLException("parameter error");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查参数数量,大于 0
|
||||
* @param objects objects
|
||||
|
@ -60,6 +42,15 @@ public class OperatorHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查参数数量,等于 1
|
||||
* @param objects objects
|
||||
* @throws QLException QLException
|
||||
*/
|
||||
public static void checkObjectSizeEqOne(Object[] objects) throws QLException {
|
||||
checkObjectSizeEq(objects, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查参数数量,等于 2
|
||||
* @param objects objects
|
||||
|
@ -138,12 +129,7 @@ public class OperatorHelper {
|
|||
throw new QLException(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 node 和 chain 是否已经注册
|
||||
* @param objects objects
|
||||
* @throws QLException QLException
|
||||
*/
|
||||
public static void checkNodeAndChainExist(Object[] objects) throws QLException {
|
||||
public static void checkItemNotNull(Object[] objects) throws QLException {
|
||||
for (Object object : objects) {
|
||||
if (Objects.isNull(object)) {
|
||||
throw new QLException(DataNotFoundException.MSG);
|
||||
|
@ -151,4 +137,17 @@ public class OperatorHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所谓Boolean item,指的是那些最终的结果值为布尔类型的Item
|
||||
* 布尔类型的items有,if,while,break类型的Node,以及AndOrCondition以及NotCondition
|
||||
*/
|
||||
public static void checkObjectMustBeBooleanItem(Object object) throws Exception{
|
||||
if (!(object instanceof Node && ListUtil.toList(
|
||||
NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT,
|
||||
NodeTypeEnum.WHILE, NodeTypeEnum.WHILE_SCRIPT,
|
||||
NodeTypeEnum.BREAK, NodeTypeEnum.BREAK_SCRIPT).contains(((Node) object).getType())
|
||||
|| object instanceof AndOrCondition || object instanceof NotCondition)) {
|
||||
throw new QLException("The first parameter must be boolean type Node or boolean type condition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,4 +75,10 @@ public interface ChainConstant {
|
|||
|
||||
String CATCH = "CATCH";
|
||||
|
||||
String AND = "AND";
|
||||
|
||||
String OR = "OR";
|
||||
|
||||
String NOT = "NOT";
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
|
@ -21,4 +22,11 @@ public abstract class NodeBreakComponent extends NodeComponent {
|
|||
|
||||
public abstract boolean processBreak() throws Exception;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Boolean getItemResultMetaValue(Integer slotIndex) {
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return DataBus.getSlot(slotIndex).getBreakResult(originalClass.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -377,4 +377,7 @@ public abstract class NodeComponent {
|
|||
return FlowExecutorHolder.loadInstance().invoke2RespInAsync(chainId, param, this.getSlotIndex());
|
||||
}
|
||||
|
||||
public <T> T getItemResultMetaValue(Integer slotIndex){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
|
@ -21,4 +22,11 @@ public abstract class NodeForComponent extends NodeComponent {
|
|||
|
||||
public abstract int processFor() throws Exception;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Integer getItemResultMetaValue(Integer slotIndex) {
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return DataBus.getSlot(slotIndex).getForResult(originalClass.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
/**
|
||||
|
@ -19,4 +20,10 @@ public abstract class NodeIfComponent extends NodeComponent {
|
|||
|
||||
public abstract boolean processIf() throws Exception;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Boolean getItemResultMetaValue(Integer slotIndex) {
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return DataBus.getSlot(slotIndex).getIfResult(originalClass.getName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
|
@ -23,4 +24,11 @@ public abstract class NodeIteratorComponent extends NodeComponent {
|
|||
|
||||
public abstract Iterator<?> processIterator() throws Exception;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<?> getItemResultMetaValue(Integer slotIndex) {
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return DataBus.getSlot(slotIndex).getIteratorResult(originalClass.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
/**
|
||||
|
@ -26,4 +27,11 @@ public abstract class NodeSwitchComponent extends NodeComponent {
|
|||
// 用以返回路由节点的beanId
|
||||
public abstract String processSwitch() throws Exception;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public String getItemResultMetaValue(Integer slotIndex) {
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return DataBus.getSlot(slotIndex).getSwitchResult(originalClass.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.yomahub.liteflow.core;
|
||||
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
|
||||
|
||||
|
@ -21,4 +22,11 @@ public abstract class NodeWhileComponent extends NodeComponent {
|
|||
|
||||
public abstract boolean processWhile() throws Exception;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Boolean getItemResultMetaValue(Integer slotIndex) {
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getClass());
|
||||
return DataBus.getSlot(slotIndex).getWhileResult(originalClass.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,9 +5,17 @@ package com.yomahub.liteflow.enums;
|
|||
*/
|
||||
public enum ConditionTypeEnum {
|
||||
|
||||
TYPE_THEN("then", "then"), TYPE_WHEN("when", "when"), TYPE_SWITCH("switch", "switch"),
|
||||
TYPE_THEN("then", "then"),
|
||||
|
||||
TYPE_IF("if", "if"), TYPE_PRE("pre", "pre"), TYPE_FINALLY("finally", "finally"),
|
||||
TYPE_WHEN("when", "when"),
|
||||
|
||||
TYPE_SWITCH("switch", "switch"),
|
||||
|
||||
TYPE_IF("if", "if"),
|
||||
|
||||
TYPE_PRE("pre", "pre"),
|
||||
|
||||
TYPE_FINALLY("finally", "finally"),
|
||||
|
||||
TYPE_FOR("for", "for"),
|
||||
|
||||
|
@ -15,7 +23,11 @@ public enum ConditionTypeEnum {
|
|||
|
||||
TYPE_ITERATOR("iterator", "iterator"),
|
||||
|
||||
TYPE_CATCH("catch", "catch");
|
||||
TYPE_CATCH("catch", "catch"),
|
||||
|
||||
TYPE_AND_OR_OPT("and_or_opt", "and_or_opt"),
|
||||
|
||||
TYPE_NOT_OPT("not_opt", "not_opt");
|
||||
|
||||
private String type;
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package com.yomahub.liteflow.exception;
|
||||
|
||||
public class AndOrConditionException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 异常信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public AndOrConditionException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,6 @@ import com.yomahub.liteflow.slot.DataBus;
|
|||
import com.yomahub.liteflow.slot.Slot;
|
||||
import com.yomahub.liteflow.enums.ExecuteTypeEnum;
|
||||
import com.yomahub.liteflow.exception.FlowSystemException;
|
||||
import com.yomahub.liteflow.flow.element.condition.Condition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.flow.element.condition;
|
||||
package com.yomahub.liteflow.flow.element;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
|
@ -14,6 +14,7 @@ import com.yomahub.liteflow.enums.ExecuteTypeEnum;
|
|||
import com.yomahub.liteflow.exception.ChainEndException;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.condition.ConditionKey;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
|
||||
|
@ -65,7 +66,7 @@ public abstract class Condition implements Executable {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void executeCondition(Integer slotIndex) throws Exception;
|
||||
public abstract void executeCondition(Integer slotIndex) throws Exception;
|
||||
|
||||
@Override
|
||||
public ExecuteTypeEnum getExecuteType() {
|
|
@ -40,4 +40,8 @@ public interface Executable {
|
|||
|
||||
}
|
||||
|
||||
default <T> T getItemResultMetaValue(Integer slotIndex){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -275,4 +275,8 @@ public class Node implements Executable, Cloneable {
|
|||
this.language = language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getItemResultMetaValue(Integer slotIndex) {
|
||||
return instance.getItemResultMetaValue(slotIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.exception.AndOrConditionException;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
import java.util.List;
|
||||
|
||||
public class AndOrCondition extends Condition {
|
||||
|
||||
private BooleanConditionTypeEnum booleanConditionType;
|
||||
|
||||
@Override
|
||||
public void executeCondition(Integer slotIndex) throws Exception {
|
||||
List<Executable> itemList = this.getItem();
|
||||
|
||||
|
||||
if (CollUtil.isEmpty(itemList)){
|
||||
throw new AndOrConditionException("boolean item list is null");
|
||||
}
|
||||
|
||||
boolean[] booleanArray = new boolean[itemList.size()];
|
||||
|
||||
for (int i = 0; i < itemList.size(); i++) {
|
||||
Executable item = itemList.get(i);
|
||||
item.setCurrChainId(this.getCurrChainId());
|
||||
item.execute(slotIndex);
|
||||
booleanArray[i] = item.getItemResultMetaValue(slotIndex);
|
||||
}
|
||||
|
||||
BooleanConditionTypeEnum booleanConditionType = this.getBooleanConditionType();
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
|
||||
String resultKey = StrUtil.format("{}_{}",this.getClass().getName(),this.hashCode());
|
||||
switch (booleanConditionType) {
|
||||
case AND:
|
||||
slot.setAndOrResult(resultKey, BooleanUtil.and(booleanArray));
|
||||
break;
|
||||
case OR:
|
||||
slot.setAndOrResult(resultKey, BooleanUtil.or(booleanArray));
|
||||
break;
|
||||
default:
|
||||
throw new AndOrConditionException("condition type must be 'AND' or 'OR'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Boolean getItemResultMetaValue(Integer slotIndex) {
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
String resultKey = StrUtil.format("{}_{}",this.getClass().getName(),this.hashCode());
|
||||
return slot.getAndOrResult(resultKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionTypeEnum getConditionType() {
|
||||
return ConditionTypeEnum.TYPE_AND_OR_OPT;
|
||||
}
|
||||
|
||||
public void addItem(Executable item){
|
||||
this.addExecutable(ConditionKey.AND_OR_ITEM_KEY, item);
|
||||
}
|
||||
|
||||
public List<Executable> getItem(){
|
||||
return this.getExecutableList(ConditionKey.AND_OR_ITEM_KEY);
|
||||
}
|
||||
|
||||
public BooleanConditionTypeEnum getBooleanConditionType() {
|
||||
return booleanConditionType;
|
||||
}
|
||||
|
||||
public void setBooleanConditionType(BooleanConditionTypeEnum booleanConditionType) {
|
||||
this.booleanConditionType = booleanConditionType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
/**
|
||||
* 结果为Boolean类型的类型
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.10.2
|
||||
*/
|
||||
public enum BooleanConditionTypeEnum {
|
||||
|
||||
AND,
|
||||
OR,
|
||||
NOT
|
||||
}
|
|
@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.exception.CatchErrorException;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
|
|
|
@ -32,4 +32,8 @@ public interface ConditionKey {
|
|||
|
||||
String CATCH_KEY = "CATCH_KEY";
|
||||
|
||||
String AND_OR_ITEM_KEY = "AND_OR_ITEM";
|
||||
|
||||
String NOT_ITEM_KEY = "NOT_ITEM_KEY";
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,16 +36,14 @@ public class ForCondition extends LoopCondition {
|
|||
forNode.setCurrChainId(this.getCurrChainId());
|
||||
forNode.execute(slotIndex);
|
||||
|
||||
// 这里可能会有spring代理过的bean,所以拿到user原始的class
|
||||
Class<?> originalForCountClass = LiteFlowProxyUtil.getUserClass(forNode.getInstance().getClass());
|
||||
// 获得循环次数
|
||||
int forCount = slot.getForResult(originalForCountClass.getName());
|
||||
int forCount = forNode.getItemResultMetaValue(slotIndex);
|
||||
|
||||
// 获得要循环的可执行对象
|
||||
Executable executableItem = this.getDoExecutor();
|
||||
|
||||
// 获取Break节点
|
||||
Node breakNode = this.getBreakNode();
|
||||
Executable breakItem = this.getBreakItem();
|
||||
|
||||
// 循环执行
|
||||
for (int i = 0; i < forCount; i++) {
|
||||
|
@ -54,12 +52,11 @@ public class ForCondition extends LoopCondition {
|
|||
setLoopIndex(executableItem, i);
|
||||
executableItem.execute(slotIndex);
|
||||
// 如果break组件不为空,则去执行
|
||||
if (ObjectUtil.isNotNull(breakNode)) {
|
||||
breakNode.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakNode, i);
|
||||
breakNode.execute(slotIndex);
|
||||
Class<?> originalBreakClass = LiteFlowProxyUtil.getUserClass(breakNode.getInstance().getClass());
|
||||
boolean isBreak = slot.getBreakResult(originalBreakClass.getName());
|
||||
if (ObjectUtil.isNotNull(breakItem)) {
|
||||
breakItem.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakItem, i);
|
||||
breakItem.execute(slotIndex);
|
||||
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
|
||||
if (isBreak) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
|
|||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.*;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
|
@ -22,66 +23,62 @@ public class IfCondition extends Condition {
|
|||
|
||||
@Override
|
||||
public void executeCondition(Integer slotIndex) throws Exception {
|
||||
if (ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(getIfNode().getType())) {
|
||||
// 先去判断isAccess方法,如果isAccess方法都返回false,整个IF表达式不执行
|
||||
if (!this.getIfNode().isAccess(slotIndex)) {
|
||||
return;
|
||||
Executable ifItem = this.getIfItem();
|
||||
|
||||
// 先去判断isAccess方法,如果isAccess方法都返回false,整个IF表达式不执行
|
||||
if (!ifItem.isAccess(slotIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 先执行IF节点
|
||||
ifItem.setCurrChainId(this.getCurrChainId());
|
||||
ifItem.execute(slotIndex);
|
||||
|
||||
// 拿到If执行过的结果
|
||||
boolean ifResult = ifItem.getItemResultMetaValue(slotIndex);
|
||||
|
||||
Executable trueCaseExecutableItem = this.getTrueCaseExecutableItem();
|
||||
Executable falseCaseExecutableItem = this.getFalseCaseExecutableItem();
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
|
||||
if (ifResult) {
|
||||
// trueCaseExecutableItem这个不能为空,否则执行什么呢
|
||||
if (ObjectUtil.isNull(trueCaseExecutableItem)) {
|
||||
String errorInfo = StrUtil.format("[{}]:no if-true node found for the component[{}]",
|
||||
slot.getRequestId(), ifItem.getExecuteId());
|
||||
throw new NoIfTrueNodeException(errorInfo);
|
||||
}
|
||||
|
||||
// 先执行IF节点
|
||||
this.getIfNode().setCurrChainId(this.getCurrChainId());
|
||||
this.getIfNode().execute(slotIndex);
|
||||
// trueCaseExecutableItem 不能为前置或者后置组件
|
||||
if (trueCaseExecutableItem instanceof PreCondition
|
||||
|| trueCaseExecutableItem instanceof FinallyCondition) {
|
||||
String errorInfo = StrUtil.format(
|
||||
"[{}]:if component[{}] error, if true node cannot be pre or finally", slot.getRequestId(),
|
||||
ifItem.getExecuteId());
|
||||
throw new IfTargetCannotBePreOrFinallyException(errorInfo);
|
||||
}
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
// 这里可能会有spring代理过的bean,所以拿到user原始的class
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(this.getIfNode().getInstance().getClass());
|
||||
// 拿到If执行过的结果
|
||||
boolean ifResult = slot.getIfResult(originalClass.getName());
|
||||
|
||||
Executable trueCaseExecutableItem = this.getTrueCaseExecutableItem();
|
||||
Executable falseCaseExecutableItem = this.getFalseCaseExecutableItem();
|
||||
|
||||
if (ifResult) {
|
||||
// trueCaseExecutableItem这个不能为空,否则执行什么呢
|
||||
if (ObjectUtil.isNull(trueCaseExecutableItem)) {
|
||||
String errorInfo = StrUtil.format("[{}]:no if-true node found for the component[{}]",
|
||||
slot.getRequestId(), this.getIfNode().getInstance().getDisplayName());
|
||||
throw new NoIfTrueNodeException(errorInfo);
|
||||
}
|
||||
|
||||
// trueCaseExecutableItem 不能为前置或者后置组件
|
||||
if (trueCaseExecutableItem instanceof PreCondition
|
||||
|| trueCaseExecutableItem instanceof FinallyCondition) {
|
||||
// 执行trueCaseExecutableItem
|
||||
trueCaseExecutableItem.setCurrChainId(this.getCurrChainId());
|
||||
trueCaseExecutableItem.execute(slotIndex);
|
||||
}
|
||||
else {
|
||||
// falseCaseExecutableItem可以为null,但是不为null时就执行否的情况
|
||||
if (ObjectUtil.isNotNull(falseCaseExecutableItem)) {
|
||||
// falseCaseExecutableItem 不能为前置或者后置组件
|
||||
if (falseCaseExecutableItem instanceof PreCondition
|
||||
|| falseCaseExecutableItem instanceof FinallyCondition) {
|
||||
String errorInfo = StrUtil.format(
|
||||
"[{}]:if component[{}] error, if true node cannot be pre or finally", slot.getRequestId(),
|
||||
this.getIfNode().getInstance().getDisplayName());
|
||||
"[{}]:if component[{}] error, if true node cannot be pre or finally",
|
||||
slot.getRequestId(), ifItem.getExecuteId());
|
||||
throw new IfTargetCannotBePreOrFinallyException(errorInfo);
|
||||
}
|
||||
|
||||
// 执行trueCaseExecutableItem
|
||||
trueCaseExecutableItem.setCurrChainId(this.getCurrChainId());
|
||||
trueCaseExecutableItem.execute(slotIndex);
|
||||
// 执行falseCaseExecutableItem
|
||||
falseCaseExecutableItem.setCurrChainId(this.getCurrChainId());
|
||||
falseCaseExecutableItem.execute(slotIndex);
|
||||
}
|
||||
else {
|
||||
// falseCaseExecutableItem可以为null,但是不为null时就执行否的情况
|
||||
if (ObjectUtil.isNotNull(falseCaseExecutableItem)) {
|
||||
// falseCaseExecutableItem 不能为前置或者后置组件
|
||||
if (falseCaseExecutableItem instanceof PreCondition
|
||||
|| falseCaseExecutableItem instanceof FinallyCondition) {
|
||||
String errorInfo = StrUtil.format(
|
||||
"[{}]:if component[{}] error, if true node cannot be pre or finally",
|
||||
slot.getRequestId(), this.getIfNode().getInstance().getDisplayName());
|
||||
throw new IfTargetCannotBePreOrFinallyException(errorInfo);
|
||||
}
|
||||
|
||||
// 执行falseCaseExecutableItem
|
||||
falseCaseExecutableItem.setCurrChainId(this.getCurrChainId());
|
||||
falseCaseExecutableItem.execute(slotIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IfTypeErrorException("if instance must be NodeIfComponent");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,12 +103,11 @@ public class IfCondition extends Condition {
|
|||
this.addExecutable(ConditionKey.IF_FALSE_CASE_KEY, falseCaseExecutableItem);
|
||||
}
|
||||
|
||||
public void setIfNode(Node ifNode) {
|
||||
public void setIfItem(Executable ifNode) {
|
||||
this.addExecutable(ConditionKey.IF_KEY, ifNode);
|
||||
}
|
||||
|
||||
public Node getIfNode() {
|
||||
return (Node) this.getExecutableOne(ConditionKey.IF_KEY);
|
||||
public Executable getIfItem() {
|
||||
return this.getExecutableOne(ConditionKey.IF_KEY);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public class IteratorCondition extends LoopCondition {
|
|||
}
|
||||
|
||||
// 先去判断isAccess方法,如果isAccess方法都返回false,整个ITERATOR表达式不执行
|
||||
if (!this.getIteratorNode().isAccess(slotIndex)) {
|
||||
if (!iteratorNode.isAccess(slotIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -33,16 +33,13 @@ public class IteratorCondition extends LoopCondition {
|
|||
iteratorNode.setCurrChainId(this.getCurrChainId());
|
||||
iteratorNode.execute(slotIndex);
|
||||
|
||||
// 这里可能会有spring代理过的bean,所以拿到user原始的class
|
||||
Class<?> originalForCountClass = LiteFlowProxyUtil.getUserClass(iteratorNode.getInstance().getClass());
|
||||
// 获得迭代器
|
||||
Iterator<?> it = slot.getIteratorResult(originalForCountClass.getName());
|
||||
Iterator<?> it = iteratorNode.getItemResultMetaValue(slotIndex);
|
||||
|
||||
// 获得要循环的可执行对象
|
||||
Executable executableItem = this.getDoExecutor();
|
||||
|
||||
// 获取Break节点
|
||||
Node breakNode = this.getBreakNode();
|
||||
Executable breakItem = this.getBreakItem();
|
||||
|
||||
int index = 0;
|
||||
while (it.hasNext()) {
|
||||
|
@ -56,13 +53,12 @@ public class IteratorCondition extends LoopCondition {
|
|||
// 执行可执行对象
|
||||
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(breakNode.getInstance().getClass());
|
||||
boolean isBreak = slot.getBreakResult(originalBreakClass.getName());
|
||||
if (ObjectUtil.isNotNull(breakItem)) {
|
||||
breakItem.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakItem, index);
|
||||
setCurrLoopObject(breakItem, itObj);
|
||||
breakItem.execute(slotIndex);
|
||||
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
|
||||
if (isBreak) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import com.yomahub.liteflow.flow.element.Chain;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 循环Condition的抽象类 主要继承对象有ForCondition和WhileCondition
|
||||
*
|
||||
|
@ -16,11 +13,11 @@ import java.util.function.Consumer;
|
|||
*/
|
||||
public abstract class LoopCondition extends Condition {
|
||||
|
||||
protected Node getBreakNode() {
|
||||
return (Node) this.getExecutableOne(ConditionKey.BREAK_KEY);
|
||||
protected Executable getBreakItem() {
|
||||
return this.getExecutableOne(ConditionKey.BREAK_KEY);
|
||||
}
|
||||
|
||||
public void setBreakNode(Node breakNode) {
|
||||
public void setBreakItem(Executable breakNode) {
|
||||
this.addExecutable(ConditionKey.BREAK_KEY, breakNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
|
||||
public class NotCondition extends Condition {
|
||||
|
||||
@Override
|
||||
public void executeCondition(Integer slotIndex) throws Exception {
|
||||
Executable item = this.getItem();
|
||||
|
||||
item.setCurrChainId(this.getCurrChainId());
|
||||
item.execute(slotIndex);
|
||||
boolean flag = item.getItemResultMetaValue(slotIndex);
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
|
||||
String resultKey = StrUtil.format("{}_{}",this.getClass().getName(),this.hashCode());
|
||||
slot.setAndOrResult(resultKey, !flag);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Boolean getItemResultMetaValue(Integer slotIndex) {
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
String resultKey = StrUtil.format("{}_{}",this.getClass().getName(),this.hashCode());
|
||||
return slot.getAndOrResult(resultKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConditionTypeEnum getConditionType() {
|
||||
return ConditionTypeEnum.TYPE_NOT_OPT;
|
||||
}
|
||||
|
||||
public void setItem(Executable item){
|
||||
this.addExecutable(ConditionKey.NOT_ITEM_KEY, item);
|
||||
}
|
||||
|
||||
public Executable getItem(){
|
||||
return this.getExecutableOne(ConditionKey.NOT_ITEM_KEY);
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
package com.yomahub.liteflow.flow.element.condition;
|
||||
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,13 +8,13 @@ import com.yomahub.liteflow.enums.NodeTypeEnum;
|
|||
import com.yomahub.liteflow.exception.NoSwitchTargetNodeException;
|
||||
import com.yomahub.liteflow.exception.SwitchTargetCannotBePreOrFinallyException;
|
||||
import com.yomahub.liteflow.exception.SwitchTypeErrorException;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -46,11 +46,10 @@ public class SwitchCondition extends Condition {
|
|||
switchNode.setCurrChainId(this.getCurrChainId());
|
||||
switchNode.execute(slotIndex);
|
||||
|
||||
// 根据switch节点执行出来的结果选择
|
||||
// 拿到switch节点的结果
|
||||
String targetId = switchNode.getItemResultMetaValue(slotIndex);
|
||||
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
// 这里可能会有spring代理过的bean,所以拿到user原始的class
|
||||
Class<?> originalClass = LiteFlowProxyUtil.getUserClass(switchNode.getInstance().getClass());
|
||||
String targetId = slot.getSwitchResult(originalClass.getName());
|
||||
|
||||
Executable targetExecutor = null;
|
||||
if (StrUtil.isNotBlank(targetId)) {
|
||||
|
|
|
@ -9,6 +9,7 @@ package com.yomahub.liteflow.flow.element.condition;
|
|||
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.exception.ChainEndException;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.element.Executable;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.slot.Slot;
|
||||
|
|
|
@ -11,6 +11,7 @@ import cn.hutool.core.util.StrUtil;
|
|||
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.exception.WhenExecuteException;
|
||||
import com.yomahub.liteflow.flow.element.Condition;
|
||||
import com.yomahub.liteflow.flow.parallel.CompletableFutureTimeout;
|
||||
import com.yomahub.liteflow.flow.parallel.ParallelSupplier;
|
||||
import com.yomahub.liteflow.flow.parallel.WhenFutureObj;
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
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.NoWhileNodeException;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 循环条件Condition
|
||||
|
@ -20,15 +15,10 @@ public class WhileCondition extends LoopCondition {
|
|||
|
||||
@Override
|
||||
public void executeCondition(Integer slotIndex) throws Exception {
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
Node whileNode = this.getWhileNode();
|
||||
if (ObjectUtil.isNull(whileNode)) {
|
||||
String errorInfo = StrUtil.format("[{}]:no while-node found", slot.getRequestId());
|
||||
throw new NoWhileNodeException(errorInfo);
|
||||
}
|
||||
Executable whileItem = this.getWhileItem();
|
||||
|
||||
// 先去判断isAccess方法,如果isAccess方法都返回false,整个WHILE表达式不执行
|
||||
if (!this.getWhileNode().isAccess(slotIndex)) {
|
||||
if (!whileItem.isAccess(slotIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -36,7 +26,7 @@ public class WhileCondition extends LoopCondition {
|
|||
Executable executableItem = this.getDoExecutor();
|
||||
|
||||
// 获取Break节点
|
||||
Node breakNode = this.getBreakNode();
|
||||
Executable breakItem = this.getBreakItem();
|
||||
|
||||
// 循环执行
|
||||
int index = 0;
|
||||
|
@ -45,12 +35,11 @@ public class WhileCondition extends LoopCondition {
|
|||
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(breakNode.getInstance().getClass());
|
||||
boolean isBreak = slot.getBreakResult(originalBreakClass.getName());
|
||||
if (ObjectUtil.isNotNull(breakItem)) {
|
||||
breakItem.setCurrChainId(this.getCurrChainId());
|
||||
setLoopIndex(breakItem, index);
|
||||
breakItem.execute(slotIndex);
|
||||
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
|
||||
if (isBreak) {
|
||||
break;
|
||||
}
|
||||
|
@ -60,13 +49,12 @@ public class WhileCondition extends LoopCondition {
|
|||
}
|
||||
|
||||
private boolean getWhileResult(Integer slotIndex) throws Exception {
|
||||
Slot slot = DataBus.getSlot(slotIndex);
|
||||
Node whileNode = this.getWhileNode();
|
||||
Executable whileItem = this.getWhileItem();
|
||||
// 执行while组件
|
||||
whileNode.setCurrChainId(this.getCurrChainId());
|
||||
whileNode.execute(slotIndex);
|
||||
Class<?> originalWhileClass = LiteFlowProxyUtil.getUserClass(whileNode.getInstance().getClass());
|
||||
return slot.getWhileResult(originalWhileClass.getName());
|
||||
whileItem.setCurrChainId(this.getCurrChainId());
|
||||
whileItem.execute(slotIndex);
|
||||
|
||||
return whileItem.getItemResultMetaValue(slotIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,12 +62,12 @@ public class WhileCondition extends LoopCondition {
|
|||
return ConditionTypeEnum.TYPE_WHILE;
|
||||
}
|
||||
|
||||
public Node getWhileNode() {
|
||||
return (Node) this.getExecutableOne(ConditionKey.WHILE_KEY);
|
||||
public Executable getWhileItem() {
|
||||
return this.getExecutableOne(ConditionKey.WHILE_KEY);
|
||||
}
|
||||
|
||||
public void setWhileNode(Node whileNode) {
|
||||
this.addExecutable(ConditionKey.WHILE_KEY, whileNode);
|
||||
public void setWhileItem(Executable whileItem) {
|
||||
this.addExecutable(ConditionKey.WHILE_KEY, whileItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,20 +17,20 @@ public class ParallelSupplier implements Supplier<WhenFutureObj> {
|
|||
|
||||
private final Executable executableItem;
|
||||
|
||||
private final String currChainName;
|
||||
private final String currChainId;
|
||||
|
||||
private final Integer slotIndex;
|
||||
|
||||
public ParallelSupplier(Executable executableItem, String currChainName, Integer slotIndex) {
|
||||
public ParallelSupplier(Executable executableItem, String currChainId, Integer slotIndex) {
|
||||
this.executableItem = executableItem;
|
||||
this.currChainName = currChainName;
|
||||
this.currChainId = currChainId;
|
||||
this.slotIndex = slotIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WhenFutureObj get() {
|
||||
try {
|
||||
executableItem.setCurrChainId(currChainName);
|
||||
executableItem.setCurrChainId(currChainId);
|
||||
executableItem.execute(slotIndex);
|
||||
return WhenFutureObj.success(executableItem.getExecuteId());
|
||||
}
|
||||
|
|
|
@ -50,6 +50,10 @@ public class Slot {
|
|||
|
||||
private static final String IF_NODE_PREFIX = "_if_";
|
||||
|
||||
private static final String AND_OR_PREFIX = "_and_or_";
|
||||
|
||||
private static final String NOT_PREFIX = "_not_";
|
||||
|
||||
private static final String FOR_PREFIX = "_for_";
|
||||
|
||||
private static final String WHILE_PREFIX = "_while_";
|
||||
|
@ -233,6 +237,22 @@ public class Slot {
|
|||
return getThreadMetaData(IF_NODE_PREFIX + key);
|
||||
}
|
||||
|
||||
public void setAndOrResult(String key, boolean result) {
|
||||
putThreadMetaDataMap(AND_OR_PREFIX + key, result);
|
||||
}
|
||||
|
||||
public boolean getAndOrResult(String key) {
|
||||
return getThreadMetaData(AND_OR_PREFIX + key);
|
||||
}
|
||||
|
||||
public void setNotResult(String key, boolean result) {
|
||||
putThreadMetaDataMap(NOT_PREFIX + key, result);
|
||||
}
|
||||
|
||||
public boolean getNotResult(String key) {
|
||||
return getThreadMetaData(NOT_PREFIX + key);
|
||||
}
|
||||
|
||||
public void setForResult(String key, int forCount) {
|
||||
putThreadMetaDataMap(FOR_PREFIX + key, forCount);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.yomahub.liteflow.test.booleanOpt;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
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;
|
||||
|
||||
/**
|
||||
* springboot环境EL常规的例子测试
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@TestPropertySource(value = "classpath:/booleanOpt/application.properties")
|
||||
@SpringBootTest(classes = BooleanOptELSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({ "com.yomahub.liteflow.test.booleanOpt.cmp" })
|
||||
public class BooleanOptELSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// IF情况下AND
|
||||
@Test
|
||||
public void testBooleanOpt1() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
Assert.assertEquals("x1==>x2==>x3==>b", response.getExecuteStepStr());
|
||||
}
|
||||
|
||||
// IF情况下OR
|
||||
@Test
|
||||
public void testBooleanOpt2() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
Assert.assertEquals("x1==>x2==>x3==>a", response.getExecuteStepStr());
|
||||
}
|
||||
|
||||
// IF情况下AND+NOT
|
||||
@Test
|
||||
public void testBooleanOpt3() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
Assert.assertEquals("x1==>x2==>x3==>a", response.getExecuteStepStr());
|
||||
}
|
||||
|
||||
// IF情况下AND+OR+NOT混合复杂
|
||||
@Test
|
||||
public void testBooleanOpt4() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
Assert.assertEquals("x1==>x3==>x3==>x4==>a", response.getExecuteStepStr());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanOpt5() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
|
||||
Assert.assertTrue(response.isSuccess());
|
||||
Assert.assertEquals("w1==>w2==>a==>bk==>w1==>w2==>a==>bk==>w1==>w2==>a==>bk==>w1==>w2==>a==>bk", 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.booleanOpt.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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -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.booleanOpt.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!");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.yomahub.liteflow.test.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeBreakComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("bk")
|
||||
public class BK extends NodeBreakComponent {
|
||||
@Override
|
||||
public boolean processBreak() throws Exception {
|
||||
int index = this.getLoopIndex();
|
||||
return index > 2;
|
||||
}
|
||||
}
|
|
@ -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.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("w1")
|
||||
public class W1 extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -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.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeWhileComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("w2")
|
||||
public class W2 extends NodeWhileComponent {
|
||||
|
||||
@Override
|
||||
public boolean processWhile() throws Exception {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.yomahub.liteflow.test.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x1")
|
||||
public class X1 extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.yomahub.liteflow.test.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x2")
|
||||
public class X2 extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.yomahub.liteflow.test.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x3")
|
||||
public class X3 extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.yomahub.liteflow.test.booleanOpt.cmp;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeIfComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("x4")
|
||||
public class X4 extends NodeIfComponent {
|
||||
@Override
|
||||
public boolean processIf() throws Exception {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ public class MonitorFileELSpringbootTest extends BaseTest {
|
|||
|
||||
@Test
|
||||
public void testMonitor() throws Exception {
|
||||
String absolutePath = new ClassPathResource("classpath:/monitorFile/flow.el.xml").getAbsolutePath();
|
||||
String absolutePath = new ClassPathResource("classpath:/monitorFile/flow.xml").getAbsolutePath();
|
||||
String content = FileUtil.readUtf8String(absolutePath);
|
||||
String newContent = content.replace("THEN(a, b, c);", "THEN(a, c, b);");
|
||||
FileUtil.writeString(newContent, new File(absolutePath), CharsetUtil.CHARSET_UTF_8);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=booleanOpt/flow.xml
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
IF(AND(x1, x2, x3), a, b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
IF(OR(x1, x2, x3), a, b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
IF(AND(x1, x2, NOT(x3)), a, b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
IF(
|
||||
OR(
|
||||
AND(x1, x3), NOT(OR(x3, x4))
|
||||
),
|
||||
a, b
|
||||
);
|
||||
</chain>
|
||||
|
||||
<chain name="chain5">
|
||||
WHILE(AND(w1, NOT(w2))).DO(a).BREAK(bk);
|
||||
</chain>
|
||||
</flow>
|
Loading…
Reference in New Issue