优化Operator中的值转换问题,增加了所有的Node的copy机制

This commit is contained in:
everywhere.z
2022-09-29 18:31:59 +08:00
parent 5b3ad32eba
commit 73512044d0
21 changed files with 79 additions and 161 deletions

View File

@@ -54,15 +54,17 @@ public class LiteFlowChainELBuilder {
EXPRESS_RUNNER.addFunction("IF", new IfOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("ELSE", Object.class, new ElseOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("ELIF", Object.class, new ElifOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("TO", Object.class, new ToOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("to", Object.class, new ToOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("tag", Object.class, new TagOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("any", Object.class, new AnyOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("id", Object.class, new IdOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("ignoreError", Object.class, new IgnoreErrorOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("threadPool", Object.class, new ThreadPoolOperator());
EXPRESS_RUNNER.addFunction("NODE", new NodeOperator());
EXPRESS_RUNNER.addFunction("node", new NodeOperator());
EXPRESS_RUNNER.addFunction("FOR", new ForOperator());
EXPRESS_RUNNER.addFunction("WHILE", new WhileOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("DO", Object.class, new DoOperator());
EXPRESS_RUNNER.addFunctionAndClassMethod("BREAK", Object.class, new BreakOperator());
}

View File

@@ -19,13 +19,8 @@ public class AnyOperator extends BaseOperator<WhenCondition> {
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
if (objects[1] instanceof Boolean) {
// any
whenCondition.setAny(Boolean.parseBoolean(objects[1].toString().toLowerCase()));
} else {
throw new QLException("the parameter must be boolean type");
}
Boolean any = OperatorHelper.convert(objects[1], Boolean.class);
whenCondition.setAny(any);
return whenCondition;
}
}

View File

@@ -25,29 +25,16 @@ public class BreakOperator extends BaseOperator<LoopCondition> {
public LoopCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
//由于BREAK关键字有可能用在FOR后面也有可能用于WHILE后面所以这里要进行判断
LoopCondition condition;
if (objects[0] instanceof ForCondition){
//获得caller也就是ForCondition
condition = OperatorHelper.convert(objects[0], ForCondition.class);
}else if(objects[0] instanceof WhileCondition){
//获得caller也就是WhileCondition
condition = OperatorHelper.convert(objects[0], WhileCondition.class);
}else{
throw new QLException("The caller must be ForCondition or WhileCondition item");
}
//DO关键字有可能用在FOR后面也有可能用于WHILE后面所以这里要进行判断是不是这两种类型的超类LoopCondition
String errorMsg = "The caller must be ForCondition or WhileCondition item";
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
//获得需要执行的可执行表达式
if (objects[1] instanceof Node){
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");
}
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 item");
throw new QLException("The parameter must be node-break item");
}
return condition;
}

View File

@@ -24,26 +24,13 @@ public class DoOperator extends BaseOperator<LoopCondition> {
public LoopCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEqTwo(objects);
//由于DO关键字有可能用在FOR后面也有可能用于WHILE后面所以这里要进行判断
LoopCondition condition;
if (objects[0] instanceof ForCondition){
//获得caller也就是ForCondition
condition = OperatorHelper.convert(objects[0], ForCondition.class);
}else if(objects[0] instanceof WhileCondition){
//获得caller也就是WhileCondition
condition = OperatorHelper.convert(objects[0], WhileCondition.class);
}else{
throw new QLException("The caller must be ForCondition or WhileCondition item");
}
//DO关键字有可能用在FOR后面也有可能用于WHILE后面所以这里要进行判断是不是这两种类型的超类LoopCondition
String errorMsg = "The caller must be ForCondition or WhileCondition item";
LoopCondition condition = OperatorHelper.convert(objects[0], LoopCondition.class, errorMsg);
//获得需要执行的可执行表达式
if (objects[1] instanceof Executable){
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
condition.setExecutableList(ListUtil.toList(doExecutableItem));
}else{
throw new QLException("The parameter must be Executable item");
}
Executable doExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
condition.setExecutableList(ListUtil.toList(doExecutableItem));
return condition;
}

View File

@@ -25,19 +25,13 @@ public class ElifOperator extends BaseOperator<IfCondition> {
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
//解析第一个参数
Node ifNode;
if (objects[1] instanceof Node) {
ifNode = (Node) objects[1];
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
throw new QLException("The first parameter must be If item");
}
} else {
throw new QLException("The first parameter must be Node item");
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 trueCaseExecutableItem = (Executable) objects[2];
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
//构建一个内部的IfCondition
IfCondition ifConditionItem = new IfCondition();

View File

@@ -20,7 +20,7 @@ public class ElseOperator extends BaseOperator<IfCondition> {
IfCondition ifCondition = OperatorHelper.convert(objects[0], IfCondition.class);
Executable elseExecutableItem = (Executable) objects[1];
Executable elseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
// 因为当中可能会有多个ELIF所以并不知道这个ELSE前面有没有ELIF
// 每一次拿到的caller总是最开始大的if需要遍历到没有falseCaseExecutable的地方。

View File

@@ -20,11 +20,7 @@ public class FinallyOperator extends BaseOperator<FinallyCondition> {
FinallyCondition finallyCondition = new FinallyCondition();
for (Object obj : objects) {
if (obj instanceof Executable) {
finallyCondition.addExecutable((Executable) obj);
} else {
throw new QLException("parameter must be executable item!");
}
finallyCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
}
return finallyCondition;
}

View File

@@ -22,12 +22,12 @@ public class ForOperator extends BaseOperator<ForCondition> {
Node node;
if (objects[0] instanceof Node) {
node = (Node) objects[0];
node = OperatorHelper.convert(objects[0], Node.class);
if (!ListUtil.toList(NodeTypeEnum.FOR, NodeTypeEnum.FOR_SCRIPT).contains(node.getType())) {
throw new QLException("The parameter must be for-node item");
}
}else if(objects[0] instanceof Integer){
Integer forCount = (Integer) objects[0];
Integer forCount = OperatorHelper.convert(objects[0], Integer.class);
node = new Node();
node.setInstance(new NodeForComponent() {
@Override

View File

@@ -23,13 +23,9 @@ public class IdOperator extends BaseOperator<Condition> {
Condition condition = OperatorHelper.convert(objects[0], Condition.class);
if (objects[1] instanceof String) {
// id
condition.setId(objects[1].toString());
} else {
LOG.error("the parameter must be String type!");
throw new QLException("the parameter must be String type");
}
String id = OperatorHelper.convert(objects[1], String.class);
condition.setId(id);
return condition;
}

View File

@@ -22,24 +22,18 @@ public class IfOperator extends BaseOperator<IfCondition> {
OperatorHelper.checkObjectSizeEq(objects, 2, 3);
//解析第一个参数
Node ifNode;
if (objects[0] instanceof Node) {
ifNode = (Node) objects[0];
if (!ListUtil.toList(NodeTypeEnum.IF, NodeTypeEnum.IF_SCRIPT).contains(ifNode.getType())) {
throw new QLException("The first parameter must be If item");
}
} else {
throw new QLException("The first parameter must be Node item");
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 trueCaseExecutableItem = (Executable) objects[1];
Executable trueCaseExecutableItem = OperatorHelper.convert(objects[1], Executable.class);
//解析第三个参数,如果有的话
Executable falseCaseExecutableItem = null;
if (objects.length == 3) {
falseCaseExecutableItem = (Executable) objects[2];
falseCaseExecutableItem = OperatorHelper.convert(objects[2], Executable.class);
}
IfCondition ifCondition = new IfCondition();

View File

@@ -19,12 +19,8 @@ public class IgnoreErrorOperator extends BaseOperator<WhenCondition> {
WhenCondition condition = OperatorHelper.convert(objects[0], WhenCondition.class);
if (objects[1] instanceof Boolean) {
// ignoreError
condition.setErrorResume(Boolean.parseBoolean(objects[1].toString().toLowerCase()));
} else {
throw new QLException("The parameter must be boolean type");
}
Boolean ignoreError = OperatorHelper.convert(objects[1], Boolean.class);
condition.setErrorResume(ignoreError);
return condition;
}

View File

@@ -22,12 +22,7 @@ public class NodeOperator extends BaseOperator<Node> {
public Node build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeNeqOne(objects);
String nodeId;
if (objects[0] instanceof String) {
nodeId = (String) objects[0];
} else {
throw new QLException("The value must be Node item!");
}
String nodeId = OperatorHelper.convert(objects[0], String.class);
if (FlowBus.containNode(nodeId)) {
return FlowBus.getNode(nodeId);

View File

@@ -20,11 +20,7 @@ public class PreOperator extends BaseOperator<PreCondition> {
PreCondition preCondition = new PreCondition();
for (Object obj : objects) {
if (obj instanceof Executable) {
preCondition.addExecutable((Executable) obj);
} else {
throw new QLException("parameter must be executable item");
}
preCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
}
return preCondition;
}

View File

@@ -20,14 +20,8 @@ public class SwitchOperator extends BaseOperator<SwitchCondition> {
public SwitchCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeNeqOne(objects);
Node switchNode;
if (objects[0] instanceof Node) {
switchNode = (Node) objects[0];
if (!ListUtil.toList(NodeTypeEnum.SWITCH, NodeTypeEnum.SWITCH_SCRIPT).contains(switchNode.getType())) {
throw new QLException("The caller must be Switch item");
}
} else {
Node switchNode = OperatorHelper.convert(objects[0], Node.class);
if (!ListUtil.toList(NodeTypeEnum.SWITCH, NodeTypeEnum.SWITCH_SCRIPT).contains(switchNode.getType())) {
throw new QLException("The caller must be Switch item");
}

View File

@@ -20,21 +20,10 @@ public class TagOperator extends BaseOperator<Node> {
Node node = OperatorHelper.convert(objects[0], Node.class);
String tag ;
if (objects[1] instanceof String) {
tag = objects[1].toString();
} else {
throw new QLException("the parameter must be String type");
}
String tag = OperatorHelper.convert(objects[1], String.class);
//这里为什么要clone一个呢
//因为tag是跟着chain走的。而在el上下文里的放的都是同一个node如果多个同样的node tag不同则这里必须copy
Node copyNode = FlowBus.copyNode(node.getId());
if (null == copyNode){
throw new QLException("The Node must be not null");
}
copyNode.setTag(tag);
node.setTag(tag);
return copyNode;
return node;
}
}

View File

@@ -20,11 +20,7 @@ public class ThenOperator extends BaseOperator<ThenCondition> {
ThenCondition thenCondition = new ThenCondition();
for (Object obj : objects) {
if (obj instanceof Executable) {
thenCondition.addExecutable((Executable) obj);
} else {
throw new QLException("parameter must be executable item");
}
thenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
}
return thenCondition;
}

View File

@@ -19,12 +19,7 @@ public class ThreadPoolOperator extends BaseOperator<WhenCondition> {
WhenCondition whenCondition = OperatorHelper.convert(objects[0], WhenCondition.class);
if (objects[1] instanceof String) {
// threadPoolClazz
whenCondition.setThreadExecutorClass(objects[1].toString());
} else {
throw new QLException("the parameter must be String type");
}
whenCondition.setThreadExecutorClass(OperatorHelper.convert(objects[1], String.class));
return whenCondition;
}

View File

@@ -21,12 +21,8 @@ public class ToOperator extends BaseOperator<SwitchCondition> {
SwitchCondition switchCondition = OperatorHelper.convert(objects[0], SwitchCondition.class);
for (int i = 1; i < objects.length; i++) {
if (objects[i] instanceof Executable) {
Executable target = (Executable) objects[i];
switchCondition.addTargetItem(target);
} else {
throw new QLException("The parameter must be Executable item");
}
Executable target = OperatorHelper.convert(objects[i], Executable.class);
switchCondition.addTargetItem(target);
}
return switchCondition;
}

View File

@@ -19,11 +19,7 @@ public class WhenOperator extends BaseOperator<WhenCondition> {
WhenCondition whenCondition = new WhenCondition();
for (Object obj : objects) {
if (obj instanceof Executable) {
whenCondition.addExecutable((Executable) obj);
} else {
throw new QLException("parameter must be executable item");
}
whenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
}
return whenCondition;
}

View File

@@ -19,14 +19,9 @@ public class WhileOperator extends BaseOperator<WhileCondition> {
public WhileCondition build(Object[] objects) throws Exception {
OperatorHelper.checkObjectSizeEq(objects, 1);
Node node;
if (objects[0] instanceof Node){
node = (Node) objects[0];
if (!ListUtil.toList(NodeTypeEnum.WHILE, NodeTypeEnum.WHILE_SCRIPT).contains(node.getType())) {
throw new QLException("The parameter must be while-node item");
}
}else{
throw new QLException("The parameter must be Node item");
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");
}
WhileCondition whileCondition = new WhileCondition();

View File

@@ -1,7 +1,10 @@
package com.yomahub.liteflow.builder.el.operator.base;
import cn.hutool.core.util.StrUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.exception.DataNofFoundException;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.element.Node;
import java.util.Objects;
@@ -114,19 +117,35 @@ public class OperatorHelper {
/**
* 转换 object 为指定的类型
*
* @param object object
* @param tClass 指定类型
* @param <T> 返回类型
* @return T
* @throws QLException QLException
* 如果是Node类型的则进行copy
* 为什么要进行copy呢因为原先的Node都是存放在FlowBus的NodeMap中的。有些属性在EL中不是全局的属于当前这个chain的。
* 所以要进行copy动作
*/
public static <T> T convert(Object object, Class<T> tClass) throws QLException {
if (tClass.isInstance(object)) {
return (T) object;
public static <T> T convert(Object object, Class<T> clazz) throws QLException {
String errorMsg = StrUtil.format("The parameter must be {} item", clazz.getSimpleName());
return convert(object, clazz, errorMsg);
}
/**
* 转换 object 为指定的类型,自定义错误信息
* 如果是Node类型的则进行copy
*/
public static <T> T convert(Object object, Class<T> clazz, String errorMsg) throws QLException {
try{
if (clazz.isAssignableFrom(object.getClass())) {
if(clazz.equals(Node.class)){
Node node = (Node) object;
return (T) node.copy();
}else{
return (T) object;
}
}
}catch (Exception e){
throw new QLException("An error occurred while copying an object");
}
throw new QLException("The parameter must be " + tClass.getName() + " item");
throw new QLException(errorMsg);
}
/**