diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java index 7c025be6a..8559c6d8b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/LiteFlowChainELBuilder.java @@ -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 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; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/AndOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/AndOperator.java new file mode 100644 index 000000000..73b68f6f4 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/AndOperator.java @@ -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 { + @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; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/BreakOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/BreakOperator.java index 39f695863..bc8479216 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/BreakOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/BreakOperator.java @@ -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 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; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DoOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DoOperator.java index f7780c199..edc4c2380 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DoOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/DoOperator.java @@ -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; /** diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ElifOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ElifOperator.java index 95075c901..825daaa22 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ElifOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ElifOperator.java @@ -25,17 +25,15 @@ public class ElifOperator extends BaseOperator { 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的地方。 diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IdOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IdOperator.java index 625417498..3420f10f6 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IdOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IdOperator.java @@ -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 diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IfOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IfOperator.java index b40ced37e..ddf6d4b9b 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IfOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IfOperator.java @@ -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 { 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 = new IfCondition(); - ifCondition.setIfNode(ifNode); + ifCondition.setIfItem(ifItem); ifCondition.setTrueCaseExecutableItem(trueCaseExecutableItem); ifCondition.setFalseCaseExecutableItem(falseCaseExecutableItem); return ifCondition; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NodeOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NodeOperator.java index 8a4fd5768..825b6a758 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NodeOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NodeOperator.java @@ -20,7 +20,7 @@ public class NodeOperator extends BaseOperator { @Override public Node build(Object[] objects) throws Exception { - OperatorHelper.checkObjectSizeNeqOne(objects); + OperatorHelper.checkObjectSizeEqOne(objects); String nodeId = OperatorHelper.convert(objects[0], String.class); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NotOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NotOperator.java new file mode 100644 index 000000000..cbe58ab85 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/NotOperator.java @@ -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 { + @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; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/OrOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/OrOperator.java new file mode 100644 index 000000000..ffe0a91ae --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/OrOperator.java @@ -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 { + @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; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/SwitchOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/SwitchOperator.java index becb615b5..aa1d4c199 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/SwitchOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/SwitchOperator.java @@ -18,7 +18,7 @@ public class SwitchOperator extends BaseOperator { @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())) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/WhileOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/WhileOperator.java index 515138692..a2b5c26c6 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/WhileOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/WhileOperator.java @@ -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 { @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; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/BaseOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/BaseOperator.java index b51a8fc23..b0a02eea9 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/BaseOperator.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/BaseOperator.java @@ -16,8 +16,7 @@ public abstract class BaseOperator 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) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java index 0ad20c8bc..ad8dbabde 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/base/OperatorHelper.java @@ -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"); + } + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java b/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java index f55cdf044..0cdbdce99 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java @@ -75,4 +75,10 @@ public interface ChainConstant { String CATCH = "CATCH"; + String AND = "AND"; + + String OR = "OR"; + + String NOT = "NOT"; + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeBreakComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeBreakComponent.java index dc5cb150e..8cf265c21 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeBreakComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeBreakComponent.java @@ -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()); + } + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java index 6aa694178..c08917738 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeComponent.java @@ -377,4 +377,7 @@ public abstract class NodeComponent { return FlowExecutorHolder.loadInstance().invoke2RespInAsync(chainId, param, this.getSlotIndex()); } + public T getItemResultMetaValue(Integer slotIndex){ + return null; + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeForComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeForComponent.java index 2f530d315..7728c7b82 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeForComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeForComponent.java @@ -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()); + } + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIfComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIfComponent.java index f08ae828f..0c8a46546 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIfComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIfComponent.java @@ -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()); + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java index 2b49dec5e..77379e34a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeIteratorComponent.java @@ -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()); + } + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeSwitchComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeSwitchComponent.java index d94caa2e0..047df1685 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeSwitchComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeSwitchComponent.java @@ -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()); + } + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeWhileComponent.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeWhileComponent.java index f04c05fe3..e96c13ed3 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeWhileComponent.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/NodeWhileComponent.java @@ -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()); + } + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java index 4ae613e8e..18976a270 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/enums/ConditionTypeEnum.java @@ -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; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/AndOrConditionException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/AndOrConditionException.java new file mode 100644 index 000000000..ae4688bed --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/AndOrConditionException.java @@ -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; + } + +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index 5fd7eca64..8ceb605be 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -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; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/Condition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Condition.java similarity index 95% rename from liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/Condition.java rename to liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Condition.java index 12e822aef..fad92399f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/Condition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Condition.java @@ -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() { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Executable.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Executable.java index 25746476f..6f14d41ab 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Executable.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Executable.java @@ -40,4 +40,8 @@ public interface Executable { } + default T getItemResultMetaValue(Integer slotIndex){ + return null; + } + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java index 2ac0eac4f..a69e38097 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Node.java @@ -275,4 +275,8 @@ public class Node implements Executable, Cloneable { this.language = language; } + @Override + public T getItemResultMetaValue(Integer slotIndex) { + return instance.getItemResultMetaValue(slotIndex); + } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/AndOrCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/AndOrCondition.java new file mode 100644 index 000000000..61a65df54 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/AndOrCondition.java @@ -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 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 getItem(){ + return this.getExecutableList(ConditionKey.AND_OR_ITEM_KEY); + } + + public BooleanConditionTypeEnum getBooleanConditionType() { + return booleanConditionType; + } + + public void setBooleanConditionType(BooleanConditionTypeEnum booleanConditionType) { + this.booleanConditionType = booleanConditionType; + } +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/BooleanConditionTypeEnum.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/BooleanConditionTypeEnum.java new file mode 100644 index 000000000..3e7edc5d0 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/BooleanConditionTypeEnum.java @@ -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 +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/CatchCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/CatchCondition.java index 70fab7d49..690d47e14 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/CatchCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/CatchCondition.java @@ -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; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ConditionKey.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ConditionKey.java index 185b1b3f0..3ede0d0a9 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ConditionKey.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ConditionKey.java @@ -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"; + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/FinallyCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/FinallyCondition.java index adf69062f..3bfe63d0a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/FinallyCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/FinallyCondition.java @@ -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; /** diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java index 1abd75a15..5bfd827ba 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ForCondition.java @@ -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; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IfCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IfCondition.java index e2593fed5..c4a594cbf 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IfCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IfCondition.java @@ -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); } - } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java index efd25f1f2..1d1e15d1f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/IteratorCondition.java @@ -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; } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java index 1b4053942..7ad2609c4 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/LoopCondition.java @@ -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); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/NotCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/NotCondition.java new file mode 100644 index 000000000..a4b22614a --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/NotCondition.java @@ -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); + } + +} diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/PreCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/PreCondition.java index 37187f059..5fe897440 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/PreCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/PreCondition.java @@ -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; /** diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java index ef41197d0..ba64e9846 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/SwitchCondition.java @@ -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)) { diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ThenCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ThenCondition.java index 439915c77..5f41b9aec 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ThenCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/ThenCondition.java @@ -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; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java index 0feb87a2f..9a7372a39 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhenCondition.java @@ -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; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java index 060d51b4e..441066f8f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/condition/WhileCondition.java @@ -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); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/parallel/ParallelSupplier.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/parallel/ParallelSupplier.java index 6493d3837..2713adb51 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/parallel/ParallelSupplier.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/parallel/ParallelSupplier.java @@ -17,20 +17,20 @@ public class ParallelSupplier implements Supplier { 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()); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java b/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java index 19c90e3e0..91ced72d7 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/slot/Slot.java @@ -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); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/BooleanOptELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/BooleanOptELSpringbootTest.java new file mode 100644 index 000000000..1ef6d921f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/BooleanOptELSpringbootTest.java @@ -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()); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/ACmp.java new file mode 100644 index 000000000..df0b4321e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/ACmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.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!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/BCmp.java new file mode 100644 index 000000000..503f441b9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.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!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/BK.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/BK.java new file mode 100644 index 000000000..54353a351 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/BK.java @@ -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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/W1.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/W1.java new file mode 100644 index 000000000..24e4d686d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/W1.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/W2.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/W2.java new file mode 100644 index 000000000..07007d85d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/W2.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X1.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X1.java new file mode 100644 index 000000000..afa69979e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X1.java @@ -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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X2.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X2.java new file mode 100644 index 000000000..266c7457a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X2.java @@ -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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X3.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X3.java new file mode 100644 index 000000000..dea18a14d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X3.java @@ -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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X4.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X4.java new file mode 100644 index 000000000..1de35a3b3 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/booleanOpt/cmp/X4.java @@ -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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java index 2ffdd06e2..fd4f8a04e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/monitorFile/MonitorFileELSpringbootTest.java @@ -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); diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/booleanOpt/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/booleanOpt/application.properties new file mode 100644 index 000000000..5ab0104bc --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/booleanOpt/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=booleanOpt/flow.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/booleanOpt/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/booleanOpt/flow.xml new file mode 100644 index 000000000..8898e2455 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/booleanOpt/flow.xml @@ -0,0 +1,28 @@ + + + + + IF(AND(x1, x2, x3), a, b); + + + + IF(OR(x1, x2, x3), a, b); + + + + IF(AND(x1, x2, NOT(x3)), a, b); + + + + IF( + OR( + AND(x1, x3), NOT(OR(x3, x4)) + ), + a, b + ); + + + + WHILE(AND(w1, NOT(w2))).DO(a).BREAK(bk); + + \ No newline at end of file