diff --git a/.gitignore b/.gitignore
index 1f56396cc..aacc4f0ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -80,4 +80,5 @@ atlassian-ide-plugin.xml
/logs
*/logs
-.flattened-pom.xml
\ No newline at end of file
+.flattened-pom.xml
+/.vscode/settings.json
diff --git a/liteflow-core/pom.xml b/liteflow-core/pom.xml
index d650fa682..63fc7d6ba 100644
--- a/liteflow-core/pom.xml
+++ b/liteflow-core/pom.xml
@@ -54,7 +54,7 @@
com.alibaba
- QLExpress
+ qlexpress4
commons-beanutils
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 426315c8b..16b4ae264 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
@@ -8,10 +8,13 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.ql.util.express.DefaultContext;
-import com.ql.util.express.ExpressRunner;
-import com.ql.util.express.InstructionSet;
-import com.ql.util.express.exception.QLException;
+import com.alibaba.qlexpress4.Express4Runner;
+import com.alibaba.qlexpress4.QLOptions;
+import com.alibaba.qlexpress4.QLResult;
+import com.alibaba.qlexpress4.exception.QLException;
+
+import java.util.HashMap;
+import java.util.Map;
import com.yomahub.liteflow.builder.el.operator.*;
import com.yomahub.liteflow.common.ChainConstant;
import com.yomahub.liteflow.common.entity.ValidationResp;
@@ -70,7 +73,7 @@ public class LiteFlowChainELBuilder {
/**
* EL解析引擎
*/
- private final static ExpressRunner EXPRESS_RUNNER = QlExpressUtils.getInstance();
+ private final static Express4Runner EXPRESS_RUNNER = QlExpressUtils.getInstance();
public static LiteFlowChainELBuilder createChain() {
return new LiteFlowChainELBuilder();
@@ -131,15 +134,17 @@ public class LiteFlowChainELBuilder {
String msg = buildDataNotFoundExceptionMsg(routeEl);
throw new ELParseException(msg);
}else if (ObjectUtil.isNotNull(e.getCause())){
- throw new ELParseException(e.getCause().getMessage());
+ String causeMsg = e.getCause().getMessage();
+ throw new ELParseException(StrUtil.isNotBlank(causeMsg) ? causeMsg : e.getMessage());
}else{
- throw new ELParseException(e.getMessage());
+ throw new ELParseException(StrUtil.isNotBlank(e.getMessage()) ? e.getMessage() : "Unknown EL parse error");
}
}catch (RouteELInvalidException e){
throw e;
}catch (Exception e) {
String errMsg = StrUtil.format("parse el fail in this chain[{}];\r\n", chain.getChainId());
- throw new ELParseException(errMsg + e.getMessage());
+ String exMsg = e.getMessage();
+ throw new ELParseException(errMsg + (StrUtil.isNotBlank(exMsg) ? exMsg : e.getClass().getSimpleName()));
}
}
@@ -166,7 +171,7 @@ public class LiteFlowChainELBuilder {
Condition condition = compile(elStr, errorList, true);
if (Objects.isNull(condition)){
- throw new QLException(StrUtil.format("parse el fail,el:[{}]", elStr));
+ throw new ELParseException(StrUtil.format("parse el fail,el:[{}]", elStr));
}
if (liteflowConfig.getEnableNodeInstanceId()) {
@@ -183,13 +188,15 @@ public class LiteFlowChainELBuilder {
String msg = buildDataNotFoundExceptionMsg(elStr);
throw new ELParseException(msg);
}else if (ObjectUtil.isNotNull(e.getCause())){
- throw new ELParseException(e.getCause().getMessage());
+ String causeMsg = e.getCause().getMessage();
+ throw new ELParseException(StrUtil.isNotBlank(causeMsg) ? causeMsg : e.getMessage());
}else{
- throw new ELParseException(e.getMessage());
+ throw new ELParseException(StrUtil.isNotBlank(e.getMessage()) ? e.getMessage() : "Unknown EL parse error");
}
} catch (Exception e) {
String errMsg = StrUtil.format("parse el fail in this chain[{}];\r\n", chain.getChainId());
- throw new ELParseException(errMsg + e.getMessage());
+ String exMsg = e.getMessage();
+ throw new ELParseException(errMsg + (StrUtil.isNotBlank(exMsg) ? exMsg : e.getClass().getSimpleName()));
}
}
@@ -283,6 +290,12 @@ public class LiteFlowChainELBuilder {
String msg = String.format("[node/chain is not exist or node/chain not register]\n EL: %s",
StrUtil.trim(elStr));
try {
+ // QLExpress4 暂时不支持 getInstructionSetFromLocalCache 方法
+ // 这里简化处理,直接返回基本错误信息
+ // TODO: 等待 QLExpress4 提供相应的 API 后再完善此功能
+ return msg;
+
+ /* 旧版本的代码,等待 QLExpress4 支持后再启用
InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr);
if (parseResult == null) {
return msg;
@@ -325,6 +338,7 @@ public class LiteFlowChainELBuilder {
}
}
}
+ */
} catch (Exception ex) {
// ignore
}
@@ -342,9 +356,8 @@ public class LiteFlowChainELBuilder {
return;
}
- List errorList = new ArrayList<>();
try {
- DefaultContext context = new DefaultContext<>();
+ Map context = new HashMap<>();
// 这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain
// 往上下文里放入所有的chain,是的el表达式可以直接引用到chain
@@ -361,6 +374,9 @@ public class LiteFlowChainELBuilder {
// 那么会有一种级联的情况:这个EL中含有其他的chain,如果这时候不先解析其他chain,就到导致诸如循环场景无法设置index或者obj的情况
// 所以这里要判断表达式里有没有其他的chain,如果有,进行先行解析
+ // TODO: QLExpress4 暂时没有 getOutVarNames 方法,这里先注释掉级联解析逻辑
+ // 等待 QLExpress4 提供相应的 API 后再恢复
+ /*
String[] itemArray = EXPRESS_RUNNER.getOutVarNames(chain.getEl());
Arrays.stream(itemArray).forEach(item -> {
if (FlowBus.containChain(item) && !chain.getChainId().equals(item)) {
@@ -370,14 +386,16 @@ public class LiteFlowChainELBuilder {
}
}
});
+ */
// 解析el成为一个Condition
// 为什么这里只是一个Condition,而不是一个List呢
// 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样
- Condition condition = (Condition) EXPRESS_RUNNER.execute(chain.getEl(), context, errorList, true, true);
+ QLResult expressResult = EXPRESS_RUNNER.execute(chain.getEl(), context, QLOptions.DEFAULT_OPTIONS);
+ Condition condition = (Condition) expressResult.getResult();
if (Objects.isNull(condition)){
- throw new QLException(StrUtil.format("parse el fail,el:[{}]", chain.getEl()));
+ throw new ELParseException(StrUtil.format("parse el fail,el:[{}]", chain.getEl()));
}
// 设置实例id
@@ -400,19 +418,21 @@ public class LiteFlowChainELBuilder {
String msg = buildDataNotFoundExceptionMsg(chain.getEl());
throw new ELParseException(msg);
}else if (ObjectUtil.isNotNull(e.getCause())){
- throw new ELParseException(e.getCause().getMessage());
+ String causeMsg = e.getCause().getMessage();
+ throw new ELParseException(StrUtil.isNotBlank(causeMsg) ? causeMsg : e.getMessage());
}else{
- throw new ELParseException(e.getMessage());
+ throw new ELParseException(StrUtil.isNotBlank(e.getMessage()) ? e.getMessage() : "Unknown EL parse error");
}
} catch (Exception e) {
String errMsg = StrUtil.format("parse el fail in this chain[{}];\r\n", chain.getChainId());
- throw new ELParseException(errMsg + e.getMessage());
+ String exMsg = e.getMessage();
+ throw new ELParseException(errMsg + (StrUtil.isNotBlank(exMsg) ? exMsg : e.getClass().getSimpleName()));
}
}
@SuppressWarnings("unchecked")
private T compile(String elStr, List errorList, boolean putChain2Context) throws Exception{
- DefaultContext context = new DefaultContext<>();
+ Map context = new HashMap<>();
if (putChain2Context){
// 这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain
@@ -432,7 +452,8 @@ public class LiteFlowChainELBuilder {
// 为什么这里只是一个Condition,而不是一个List呢
// 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样
- return (T) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true);
+ QLResult expressResult = EXPRESS_RUNNER.execute(elStr, context, QLOptions.DEFAULT_OPTIONS);
+ return (T) expressResult.getResult();
}
}
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 c6b3a5f4a..98e840c5d 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
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.builder.el.operator;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
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;
@@ -41,7 +41,7 @@ public class DoOperator extends BaseOperator {
}
else {
String errorMsg = "The caller must be LoopCondition or CatchCondition item";
- throw new QLException(errorMsg);
+ throw new ELParseException(errorMsg);
}
}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/FinallyOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/FinallyOperator.java
index b759b6cac..fc5f3cc0a 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/FinallyOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/FinallyOperator.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.builder.el.operator;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
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;
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ForOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ForOperator.java
index a5abc57f0..393986a9b 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ForOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ForOperator.java
@@ -3,7 +3,7 @@ package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.core.NodeComponent;
@@ -46,7 +46,7 @@ public class ForOperator extends BaseOperator {
node.setId(nodeForComponent.getNodeId());
}
else {
- throw new QLException("The parameter must be Node item");
+ throw new ELParseException("The parameter must be Node item");
}
ForCondition forCondition = new ForCondition();
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java
index b140dce46..dfb36fa4e 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IgnoreErrorOperator.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.builder.el.operator;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
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.WhenCondition;
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java
index 0d29a7f07..f35ecb5a8 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/IteratorOperator.java
@@ -1,7 +1,7 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.NodeTypeEnum;
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/MaxWaitTimeOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/MaxWaitTimeOperator.java
index 6ca3fd3ec..37d586f3a 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/MaxWaitTimeOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/MaxWaitTimeOperator.java
@@ -2,7 +2,7 @@ package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrFormatter;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
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;
@@ -42,7 +42,7 @@ public abstract class MaxWaitTimeOperator extends BaseOperator {
} else if (executable instanceof FinallyCondition) {
// FINALLY,报错
String errorMsg = StrFormatter.format("The caller [{}] cannot use the keyword \"{}'\"", executable.toString(), operatorName());
- throw new QLException(errorMsg);
+ throw new ELParseException(errorMsg);
} else if (containsFinally(executable)) {
// 处理 THEN 中的 FINALLY
ThenCondition thenCondition = OperatorHelper.convert(executable, ThenCondition.class);
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/PercentageOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/PercentageOperator.java
index 0bb172f3a..100d127bc 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/PercentageOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/PercentageOperator.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.builder.el.operator;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.ParallelStrategyEnum;
@@ -24,7 +24,7 @@ public class PercentageOperator extends BaseOperator {
Double percentage = OperatorHelper.convert2Double(objects[1]);
if (percentage > 1 || percentage < 0) {
- throw new QLException("The percentage must be between 0 and 1.");
+ throw new ELParseException("The percentage must be between 0 and 1.");
}
whenCondition.setParallelStrategy(ParallelStrategyEnum.PERCENTAGE);
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 c1d0ad3d9..693368663 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
@@ -1,7 +1,7 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.enums.NodeTypeEnum;
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/TagOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/TagOperator.java
index 2d61e59b3..451328e89 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/TagOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/TagOperator.java
@@ -1,7 +1,7 @@
package com.yomahub.liteflow.builder.el.operator;
import cn.hutool.core.collection.ListUtil;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.builder.el.operator.base.BaseOperator;
import com.yomahub.liteflow.builder.el.operator.base.OperatorHelper;
import com.yomahub.liteflow.flow.FlowBus;
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ThreadPoolOperator.java b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ThreadPoolOperator.java
index 69f444fcb..963e1233f 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ThreadPoolOperator.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/builder/el/operator/ThreadPoolOperator.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.builder.el.operator;
-import com.ql.util.express.exception.QLException;
+import com.yomahub.liteflow.exception.ELParseException;
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;
@@ -37,7 +37,7 @@ public class ThreadPoolOperator extends BaseOperator {
return condition;
} else {
String errorMsg = "The caller must be WhenCondition or LoopCondition item";
- throw new QLException(errorMsg);
+ throw new ELParseException(errorMsg);
}
}
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 b0a02eea9..f61db65dc 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
@@ -1,23 +1,23 @@
package com.yomahub.liteflow.builder.el.operator.base;
-import com.ql.util.express.Operator;
-import com.ql.util.express.exception.QLException;
+import com.alibaba.qlexpress4.api.QLFunctionalVarargs;
+import com.alibaba.qlexpress4.exception.QLException;
import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.flow.element.Executable;
/**
- * BaseOperator 为了强化 executeInner 方法,会捕获抛出的 QLException 错误,输出友好的错误提示
+ * BaseOperator 为了强化 call 方法,会捕获抛出的 QLException 错误,输出友好的错误提示
*
* @author gaibu
* @since 2.8.6
*/
-public abstract class BaseOperator extends Operator {
+public abstract class BaseOperator implements QLFunctionalVarargs {
@Override
- public T executeInner(Object[] objects) throws Exception {
+ public T call(Object... parameters) {
try {
- OperatorHelper.checkItemNotNull(objects);
- return build(objects);
+ OperatorHelper.checkItemNotNull(parameters);
+ return build(parameters);
}
catch (QLException e) {
throw 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 31107a9d9..d1d9bf41f 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
@@ -2,11 +2,11 @@ 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.ConditionTypeEnum;
import com.yomahub.liteflow.enums.ExecuteableTypeEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.exception.DataNotFoundException;
+import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
@@ -25,50 +25,50 @@ public class OperatorHelper {
/**
* 检查参数数量,大于 0
* @param objects objects
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeGtZero(Object[] objects) throws QLException {
+ public static void checkObjectSizeGtZero(Object[] objects) throws ELParseException {
if (objects.length == 0) {
- throw new QLException("parameter is empty");
+ throw new ELParseException("parameter is empty");
}
}
/**
* 检查参数数量,大于等于 2
* @param objects objects
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeGteTwo(Object[] objects) throws QLException {
+ public static void checkObjectSizeGteTwo(Object[] objects) throws ELParseException {
checkObjectSizeGtZero(objects);
if (objects.length < 2) {
- throw new QLException("parameter size error");
+ throw new ELParseException("parameter size error");
}
}
/**
* 检查参数数量,等于 1
* @param objects objects
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeEqOne(Object[] objects) throws QLException {
+ public static void checkObjectSizeEqOne(Object[] objects) throws ELParseException {
checkObjectSizeEq(objects, 1);
}
/**
* 检查参数数量,等于 2
* @param objects objects
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeEqTwo(Object[] objects) throws QLException {
+ public static void checkObjectSizeEqTwo(Object[] objects) throws ELParseException {
checkObjectSizeEq(objects, 2);
}
/**
* 检查参数数量,等于 3
* @param objects objects
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeEqThree(Object[] objects) throws QLException {
+ public static void checkObjectSizeEqThree(Object[] objects) throws ELParseException {
checkObjectSizeEq(objects, 3);
}
@@ -76,13 +76,13 @@ public class OperatorHelper {
* 检查参数数量,等于 size
* @param objects objects
* @param size 参数数量
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeEq(Object[] objects, int size) throws QLException {
+ public static void checkObjectSizeEq(Object[] objects, int size) throws ELParseException {
checkObjectSizeGtZero(objects);
if (objects.length != size) {
- throw new QLException("parameter size error");
+ throw new ELParseException("parameter size error");
}
}
@@ -91,13 +91,13 @@ public class OperatorHelper {
* @param objects objects
* @param size1 参数数量1
* @param size2 参数数量2
- * @throws QLException QLException
+ * @throws ELParseException ELParseException
*/
- public static void checkObjectSizeEq(Object[] objects, int size1, int size2) throws QLException {
+ public static void checkObjectSizeEq(Object[] objects, int size1, int size2) throws ELParseException {
checkObjectSizeGtZero(objects);
if (objects.length != size1 && objects.length != size2) {
- throw new QLException("parameter size error");
+ throw new ELParseException("parameter size error");
}
}
@@ -105,12 +105,12 @@ public class OperatorHelper {
* 转换 object 为指定的类型 如果是Node类型的则进行copy
* 为什么要进行copy呢?因为原先的Node都是存放在FlowBus的NodeMap中的。有些属性在EL中不是全局的,属于当前这个chain的。 所以要进行copy动作
*/
- public static T convert(Object object, Class clazz) throws QLException {
+ public static T convert(Object object, Class clazz) throws ELParseException {
String errorMsg = StrUtil.format("The parameter must be {} item", clazz.getSimpleName());
return convert(object, clazz, errorMsg);
}
- public static Double convert2Double(Object object) throws QLException {
+ public static Double convert2Double(Object object) throws ELParseException {
if (object instanceof Number) {
// 对 float 特别处理,避免精度问题
if (object instanceof Float) {
@@ -119,14 +119,14 @@ public class OperatorHelper {
}
return ((Number) object).doubleValue();
}
- throw new QLException(StrUtil.format("Unsupported type: {}, it must be numeric type.", object.getClass().getName()));
+ throw new ELParseException(StrUtil.format("Unsupported type: {}, it must be numeric type.", object.getClass().getName()));
}
/**
* 转换 object 为指定的类型,自定义错误信息 如果是Node类型的则进行copy
*/
@SuppressWarnings("unchecked")
- public static T convert(Object object, Class clazz, String errorMsg) throws QLException {
+ public static T convert(Object object, Class clazz, String errorMsg) throws ELParseException {
try {
if (clazz.isAssignableFrom(object.getClass())) {
if (object instanceof Node) {
@@ -139,16 +139,16 @@ public class OperatorHelper {
}
}
catch (Exception e) {
- throw new QLException("An error occurred while copying an object");
+ throw new ELParseException("An error occurred while copying an object");
}
- throw new QLException(errorMsg);
+ throw new ELParseException(errorMsg);
}
- public static void checkItemNotNull(Object[] objects) throws QLException {
+ public static void checkItemNotNull(Object[] objects) throws ELParseException {
for (Object object : objects) {
if (Objects.isNull(object)) {
- throw new QLException(DataNotFoundException.MSG);
+ throw new ELParseException(DataNotFoundException.MSG);
}
}
}
@@ -159,13 +159,13 @@ public class OperatorHelper {
*/
public static void checkObjMustBeCommonTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
- throw new QLException("The parameter must be Executable item.");
+ throw new ELParseException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteableTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.COMMON, NodeTypeEnum.SCRIPT, NodeTypeEnum.FALLBACK).contains(node.getType())){
- throw new QLException(StrUtil.format("The node[{}] must be a common type component", node.getId()));
+ throw new ELParseException(StrUtil.format("The node[{}] must be a common type component", node.getId()));
}
}
}
@@ -178,7 +178,7 @@ public class OperatorHelper {
*/
public static void checkObjMustBeBooleanTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
- throw new QLException("The parameter must be Executable item.");
+ throw new ELParseException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteableTypeEnum.NODE)){
@@ -186,21 +186,21 @@ public class OperatorHelper {
if (!ListUtil.toList(NodeTypeEnum.BOOLEAN,
NodeTypeEnum.BOOLEAN_SCRIPT,
NodeTypeEnum.FALLBACK).contains(node.getType())){
- throw new QLException(StrUtil.format("The node[{}] must be boolean type Node.", node.getId()));
+ throw new ELParseException(StrUtil.format("The node[{}] must be boolean type Node.", node.getId()));
}
}else if(item.getExecuteType().equals(ExecuteableTypeEnum.CONDITION)){
Condition condition = (Condition) item;
if (!ListUtil.toList(ConditionTypeEnum.TYPE_AND_OR_OPT, ConditionTypeEnum.TYPE_NOT_OPT).contains(condition.getConditionType())){
- throw new QLException(StrUtil.format("The condition[{}] must be boolean type Condition.", condition.getId()));
+ throw new ELParseException(StrUtil.format("The condition[{}] must be boolean type Condition.", condition.getId()));
}
}else{
- throw new QLException("The parameter error.");
+ throw new ELParseException("The parameter error.");
}
}
public static void checkObjMustBeForTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
- throw new QLException("The parameter must be Executable item.");
+ throw new ELParseException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteableTypeEnum.NODE)){
@@ -208,32 +208,32 @@ public class OperatorHelper {
if (!ListUtil.toList(NodeTypeEnum.FOR,
NodeTypeEnum.FOR_SCRIPT,
NodeTypeEnum.FALLBACK).contains(node.getType())){
- throw new QLException(StrUtil.format("The node[{}] must be For type Node.", node.getId()));
+ throw new ELParseException(StrUtil.format("The node[{}] must be For type Node.", node.getId()));
}
}else{
- throw new QLException("The parameter error.");
+ throw new ELParseException("The parameter error.");
}
}
public static void checkObjMustBeIteratorTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
- throw new QLException("The parameter must be Executable item.");
+ throw new ELParseException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteableTypeEnum.NODE)){
Node node = (Node) item;
if (!ListUtil.toList(NodeTypeEnum.ITERATOR,
NodeTypeEnum.FALLBACK).contains(node.getType())){
- throw new QLException(StrUtil.format("The node[{}] must be Iterator type Node.", node.getId()));
+ throw new ELParseException(StrUtil.format("The node[{}] must be Iterator type Node.", node.getId()));
}
}else{
- throw new QLException("The parameter error.");
+ throw new ELParseException("The parameter error.");
}
}
public static void checkObjMustBeSwitchTypeItem(Object object) throws Exception{
if (!(object instanceof Executable)){
- throw new QLException("The parameter must be Executable item.");
+ throw new ELParseException("The parameter must be Executable item.");
}
Executable item = (Executable) object;
if (item.getExecuteType().equals(ExecuteableTypeEnum.NODE)){
@@ -241,10 +241,10 @@ public class OperatorHelper {
if (!ListUtil.toList(NodeTypeEnum.SWITCH,
NodeTypeEnum.SWITCH_SCRIPT,
NodeTypeEnum.FALLBACK).contains(node.getType())){
- throw new QLException(StrUtil.format("The node[{}] must be Switch type Node.", node.getId()));
+ throw new ELParseException(StrUtil.format("The node[{}] must be Switch type Node.", node.getId()));
}
}else{
- throw new QLException("The parameter error.");
+ throw new ELParseException("The parameter error.");
}
}
}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java
index 905d89847..8104ec8ea 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/proxy/DeclComponentProxy.java
@@ -6,9 +6,9 @@ import cn.hutool.core.lang.Tuple;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
-import com.ql.util.express.DefaultContext;
-import com.ql.util.express.ExpressRunner;
-import com.ql.util.express.InstructionSet;
+import com.alibaba.qlexpress4.Express4Runner;
+import com.alibaba.qlexpress4.QLResult;
+import com.alibaba.qlexpress4.QLOptions;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.annotation.LiteflowRetry;
import com.yomahub.liteflow.core.NodeComponent;
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/BaseNodeInstanceIdManageSpi.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/BaseNodeInstanceIdManageSpi.java
index b18ef6467..38415a34c 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/BaseNodeInstanceIdManageSpi.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/BaseNodeInstanceIdManageSpi.java
@@ -1,13 +1,13 @@
package com.yomahub.liteflow.flow.instanceId;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.entity.InstanceInfoDto;
import com.yomahub.liteflow.util.JsonUtil;
-import org.apache.commons.lang.StringUtils;
import java.util.*;
@@ -26,7 +26,7 @@ public abstract class BaseNodeInstanceIdManageSpi implements NodeInstanceIdManag
*/
@Override
public Node getNodeByIdAndInstanceId(String chainId, String instanceId) {
- if (StringUtils.isBlank(chainId) || StringUtils.isBlank(instanceId)) {
+ if (StrUtil.isBlank(chainId) || StrUtil.isBlank(instanceId)) {
return null;
}
Chain chain = FlowBus.getChain(chainId);
@@ -45,7 +45,7 @@ public abstract class BaseNodeInstanceIdManageSpi implements NodeInstanceIdManag
*/
@Override
public Node getNodeByIdAndIndex(String chainId, String nodeId, Integer index) {
- if (StringUtils.isBlank(chainId) || index == null) {
+ if (StrUtil.isBlank(chainId) || index == null) {
return null;
}
Chain chain = FlowBus.getChain(chainId);
@@ -64,7 +64,7 @@ public abstract class BaseNodeInstanceIdManageSpi implements NodeInstanceIdManag
*/
@Override
public List getNodeInstanceIds(String chainId, String nodeId) {
- if (StringUtils.isBlank(chainId) || StringUtils.isBlank(nodeId)) {
+ if (StrUtil.isBlank(chainId) || StrUtil.isBlank(nodeId)) {
return Collections.emptyList();
}
// 第一行为elMd5 第二行为实例id json格式信息
@@ -133,7 +133,7 @@ public abstract class BaseNodeInstanceIdManageSpi implements NodeInstanceIdManag
*/
@Override
public int getNodeLocationById(String chainId, String instanceId) {
- if (StringUtils.isBlank(chainId) || StringUtils.isBlank(instanceId)) {
+ if (StrUtil.isBlank(chainId) || StrUtil.isBlank(instanceId)) {
return -1;
}
// 第一行为elMd5 第二行为实例id json格式信息
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/DefaultNodeInstanceIdManageSpiImpl.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/DefaultNodeInstanceIdManageSpiImpl.java
index cc94e8185..da8ed5dca 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/DefaultNodeInstanceIdManageSpiImpl.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/instanceId/DefaultNodeInstanceIdManageSpiImpl.java
@@ -3,9 +3,9 @@ package com.yomahub.liteflow.flow.instanceId;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.flow.entity.InstanceInfoDto;
import com.yomahub.liteflow.util.JsonUtil;
-import org.apache.commons.lang.StringUtils;
import java.io.File;
import java.util.*;
@@ -23,7 +23,7 @@ public class DefaultNodeInstanceIdManageSpiImpl extends BaseNodeInstanceIdManage
@Override
public List readInstanceIdFile(String chainId) {
- if (StringUtils.isBlank(chainId)) {
+ if (StrUtil.isBlank(chainId)) {
return Collections.emptyList();
}
@@ -36,7 +36,7 @@ public class DefaultNodeInstanceIdManageSpiImpl extends BaseNodeInstanceIdManage
@Override
public void writeInstanceIdFile(List instanceIdList, String elMd5, String chainId) {
- if (StringUtils.isBlank(chainId) || CollUtil.isEmpty(instanceIdList)) {
+ if (StrUtil.isBlank(chainId) || CollUtil.isEmpty(instanceIdList)) {
return;
}
File nodeDir = new File(basePath + chainId);
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteflowContextRegexMatcher.java b/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteflowContextRegexMatcher.java
index a626caecd..605bf011e 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteflowContextRegexMatcher.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteflowContextRegexMatcher.java
@@ -4,12 +4,14 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Tuple;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
-import com.ql.util.express.DefaultContext;
-import com.ql.util.express.ExpressRunner;
-import com.ql.util.express.InstructionSet;
+import com.alibaba.qlexpress4.Express4Runner;
+import com.alibaba.qlexpress4.QLResult;
+import com.alibaba.qlexpress4.InitOptions;
+import com.alibaba.qlexpress4.QLOptions;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -26,7 +28,7 @@ import java.util.stream.IntStream;
*/
public class LiteflowContextRegexMatcher {
- private static final ExpressRunner expressRunner = new ExpressRunner();
+ private static final Express4Runner expressRunner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
public static Object searchContext(List contextList, String regPattern){
// 把上下文数据转换成map形式的,key为别名,value为上下文
@@ -34,16 +36,14 @@ public class LiteflowContextRegexMatcher {
Collectors.toMap(tuple -> tuple.get(0), tuple -> tuple.get(1))
);
- List errorList = new ArrayList<>();
-
Object result = null;
// 根据表达式去上下文里搜索相匹配的数据
for(Map.Entry entry : contextMap.entrySet()){
try{
- InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache(entry.getKey() + "." + regPattern);
- DefaultContext context = new DefaultContext<>();
+ Map context = new HashMap<>();
context.put(entry.getKey(), entry.getValue());
- result = expressRunner.execute(instructionSet, context, errorList, false, false);
+ QLResult expressResult = expressRunner.execute(entry.getKey() + "." + regPattern, context, QLOptions.DEFAULT_OPTIONS);
+ result = expressResult.getResult();
if (result != null){
break;
}
@@ -53,10 +53,10 @@ public class LiteflowContextRegexMatcher {
if (result == null){
try{
// 如果没有搜到,那么尝试推断表达式是指定的上下文,按照指定上下文的方式去再获取
- InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache("contextMap." + regPattern);
- DefaultContext context = new DefaultContext<>();
+ Map context = new HashMap<>();
context.put("contextMap", contextMap);
- result = expressRunner.execute(instructionSet, context, errorList, false, false);
+ QLResult expressResult = expressRunner.execute("contextMap." + regPattern, context, QLOptions.DEFAULT_OPTIONS);
+ result = expressResult.getResult();
}catch (Exception ignore){}
}
@@ -69,8 +69,6 @@ public class LiteflowContextRegexMatcher {
Collectors.toMap(tuple -> tuple.get(0), tuple -> tuple.get(1))
);
- List errorList = new ArrayList<>();
-
boolean flag = false;
String argStr = IntStream.range(0, args.length).mapToObj(
@@ -83,11 +81,10 @@ public class LiteflowContextRegexMatcher {
for(Map.Entry entry : contextMap.entrySet()){
try{
- InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache(StrUtil.format("{}.{}({})", entry.getKey(), methodExpress, argStr));
- DefaultContext context = new DefaultContext<>();
+ Map context = new HashMap<>();
context.put(entry.getKey(), entry.getValue());
tupleList.forEach(tuple -> context.put(tuple.getA(), args[tuple.getB()]));
- expressRunner.execute(instructionSet, context, errorList, false, false);
+ expressRunner.execute(StrUtil.format("{}.{}({})", entry.getKey(), methodExpress, argStr), context, QLOptions.DEFAULT_OPTIONS);
flag = true;
break;
}catch (Exception ignore){}
@@ -97,11 +94,10 @@ public class LiteflowContextRegexMatcher {
if (BooleanUtil.isFalse(flag)){
try{
// 如果没有搜到,那么尝试推断表达式是指定的上下文,按照指定上下文的方式去再获取
- InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache(StrUtil.format("contextMap.{}({})", methodExpress, argStr));
- DefaultContext context = new DefaultContext<>();
+ Map context = new HashMap<>();
context.put("contextMap", contextMap);
tupleList.forEach(tuple -> context.put(tuple.getA(), args[tuple.getB()]));
- expressRunner.execute(instructionSet, context, errorList, false, false);
+ expressRunner.execute(StrUtil.format("contextMap.{}({})", methodExpress, argStr), context, QLOptions.DEFAULT_OPTIONS);
}catch (Exception ignore){}
}
}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/util/QlExpressUtils.java b/liteflow-core/src/main/java/com/yomahub/liteflow/util/QlExpressUtils.java
index 0dac32a61..05a14d8fe 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/util/QlExpressUtils.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/util/QlExpressUtils.java
@@ -1,6 +1,7 @@
package com.yomahub.liteflow.util;
-import com.ql.util.express.ExpressRunner;
+import com.alibaba.qlexpress4.Express4Runner;
+import com.alibaba.qlexpress4.InitOptions;
import com.yomahub.liteflow.builder.el.operator.*;
import com.yomahub.liteflow.common.ChainConstant;
@@ -15,54 +16,54 @@ public class QlExpressUtils {
/**
* EL解析引擎
*/
- private final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();
+ private final static Express4Runner EXPRESS_RUNNER = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
static {
// 初始化QLExpress的Runner
- EXPRESS_RUNNER.addFunction(ChainConstant.THEN, new ThenOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.WHEN, new WhenOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.SER, new ThenOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.PAR, new WhenOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.SWITCH, new SwitchOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.PRE, new PreOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.FINALLY, new FinallyOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.IF, new IfOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.NODE.toUpperCase(), new NodeOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.NODE, new NodeOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.FOR, new ForOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.WHILE, new WhileOperator());
- EXPRESS_RUNNER.addFunction(ChainConstant.ITERATOR, new IteratorOperator());
- EXPRESS_RUNNER.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());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TO.toLowerCase(), Object.class, new ToOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DEFAULT, Object.class, new DefaultOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.TAG, Object.class, new TagOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ANY, Object.class, new AnyOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.MUST, Object.class, new MustOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.PERCENTAGE, Object.class, new PercentageOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.ID, Object.class, new IdOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.IGNORE_ERROR, Object.class, new IgnoreErrorOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.THREAD_POOL, Object.class, new ThreadPoolOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DO, Object.class, new DoOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.BREAK, Object.class, new BreakOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.DATA, Object.class, new DataOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.MAX_WAIT_SECONDS, Object.class, new MaxWaitSecondsOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.MAX_WAIT_MILLISECONDS, Object.class, new MaxWaitMillisecondsOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.PARALLEL, Object.class, new ParallelOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.RETRY, Object.class, new RetryOperator());
- EXPRESS_RUNNER.addFunctionAndClassMethod(ChainConstant.BIND, Object.class, new BindOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.THEN, new ThenOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.WHEN, new WhenOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.SER, new ThenOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.PAR, new WhenOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.SWITCH, new SwitchOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.PRE, new PreOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.FINALLY, new FinallyOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.IF, new IfOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.NODE.toUpperCase(), new NodeOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.NODE, new NodeOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.FOR, new ForOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.WHILE, new WhileOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.ITERATOR, new IteratorOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.CATCH, new CatchOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.AND, new AndOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.OR, new OrOperator());
+ EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.NOT, new NotOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.ELSE, Object.class, new ElseOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.ELIF, Object.class, new ElifOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.TO, Object.class, new ToOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.TO.toLowerCase(), Object.class, new ToOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.DEFAULT, Object.class, new DefaultOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.TAG, Object.class, new TagOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.ANY, Object.class, new AnyOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.MUST, Object.class, new MustOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.PERCENTAGE, Object.class, new PercentageOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.ID, Object.class, new IdOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.IGNORE_ERROR, Object.class, new IgnoreErrorOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.THREAD_POOL, Object.class, new ThreadPoolOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.DO, Object.class, new DoOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.BREAK, Object.class, new BreakOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.DATA, Object.class, new DataOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.MAX_WAIT_SECONDS, Object.class, new MaxWaitSecondsOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.MAX_WAIT_MILLISECONDS, Object.class, new MaxWaitMillisecondsOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.PARALLEL, Object.class, new ParallelOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.RETRY, Object.class, new RetryOperator());
+ EXPRESS_RUNNER.addExtendFunction(ChainConstant.BIND, Object.class, new BindOperator());
}
/**
* 获取QLExpress的实例
*/
- public static ExpressRunner getInstance() {
+ public static Express4Runner getInstance() {
return EXPRESS_RUNNER;
}
diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/impl/InstanceIdRead.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/impl/InstanceIdRead.java
index 3aa48f3f4..866898819 100644
--- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/impl/InstanceIdRead.java
+++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/impl/InstanceIdRead.java
@@ -7,7 +7,6 @@ import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
import com.yomahub.liteflow.parser.sql.read.AbstractSqlRead;
import com.yomahub.liteflow.parser.sql.read.vo.InstanceIdVO;
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
-import org.apache.commons.lang.StringUtils;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -59,7 +58,7 @@ public class InstanceIdRead extends AbstractSqlRead {
String instanceIdApplicationNameField = super.config.getInstanceIdApplicationNameField();
String applicationName = super.config.getApplicationName();
- if (StringUtils.isEmpty(chainId)) {
+ if (StrUtil.isEmpty(chainId)) {
throw new IllegalArgumentException("You did not define the chainId");
}
return StrUtil.format(SqlReadConstant.SQL_PATTERN_WITH_CHAIN_ID, tableName, instanceIdApplicationNameField
diff --git a/liteflow-script-plugin/liteflow-script-qlexpress/pom.xml b/liteflow-script-plugin/liteflow-script-qlexpress/pom.xml
index 7580d4316..2708be582 100644
--- a/liteflow-script-plugin/liteflow-script-qlexpress/pom.xml
+++ b/liteflow-script-plugin/liteflow-script-qlexpress/pom.xml
@@ -23,7 +23,7 @@
com.alibaba
- QLExpress
+ qlexpress4
\ No newline at end of file
diff --git a/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java b/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java
index 66a86beac..1961e590f 100644
--- a/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java
+++ b/liteflow-script-plugin/liteflow-script-qlexpress/src/main/java/com/yomahub/liteflow/script/qlexpress/QLExpressScriptExecutor.java
@@ -2,10 +2,10 @@ package com.yomahub.liteflow.script.qlexpress;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
-import com.ql.util.express.DefaultContext;
-import com.ql.util.express.ExpressLoader;
-import com.ql.util.express.ExpressRunner;
-import com.ql.util.express.InstructionSet;
+import com.alibaba.qlexpress4.Express4Runner;
+import com.alibaba.qlexpress4.QLResult;
+import com.alibaba.qlexpress4.InitOptions;
+import com.alibaba.qlexpress4.QLOptions;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.script.ScriptExecuteWrap;
import com.yomahub.liteflow.script.ScriptExecutor;
@@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory;
import javax.script.ScriptException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -30,13 +31,13 @@ public class QLExpressScriptExecutor extends ScriptExecutor {
private final Logger log = LoggerFactory.getLogger(this.getClass());
- private ExpressRunner expressRunner;
+ private Express4Runner expressRunner;
- private final Map compiledScriptMap = new CopyOnWriteHashMap<>();
+ private final Map compiledScriptMap = new CopyOnWriteHashMap<>();
@Override
public ScriptExecutor init() {
- expressRunner = new ExpressRunner(true, false);
+ expressRunner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
//如果有生命周期则执行相应生命周期实现
super.lifeCycle(expressRunner);
return this;
@@ -45,7 +46,8 @@ public class QLExpressScriptExecutor extends ScriptExecutor {
@Override
public void load(String nodeId, String script) {
try {
- compiledScriptMap.put(nodeId, (InstructionSet) compile(script));
+ // QLExpress4 不需要预编译,直接存储脚本内容
+ compiledScriptMap.put(nodeId, script);
}
catch (Exception e) {
String errorMsg = StrUtil.format("script loading error for node[{}],error msg:{}", nodeId, e.getMessage());
@@ -65,24 +67,21 @@ public class QLExpressScriptExecutor extends ScriptExecutor {
@Override
public Object executeScript(ScriptExecuteWrap wrap) throws Exception {
- List errorList = new ArrayList<>();
try {
if (!compiledScriptMap.containsKey(wrap.getNodeId())) {
String errorMsg = StrUtil.format("script for node[{}] is not loaded", wrap.getNodeId());
throw new ScriptLoadException(errorMsg);
}
- InstructionSet instructionSet = compiledScriptMap.get(wrap.getNodeId());
- DefaultContext context = new DefaultContext<>();
+ String script = compiledScriptMap.get(wrap.getNodeId());
+ Map context = new HashMap<>();
bindParam(wrap, context::put, context::putIfAbsent);
- return expressRunner.execute(instructionSet, context, errorList, true, false);
+ QLResult expressResult = expressRunner.execute(script, context, QLOptions.DEFAULT_OPTIONS);
+ return expressResult.getResult();
}
catch (Exception e) {
- for (String scriptErrorMsg : errorList) {
- log.error("\n{}", scriptErrorMsg);
- }
throw e;
}
}
@@ -90,8 +89,10 @@ public class QLExpressScriptExecutor extends ScriptExecutor {
@Override
public void cleanCache() {
compiledScriptMap.clear();
- expressRunner.clearExpressCache();
- ReflectUtil.setFieldValue(expressRunner, "loader", new ExpressLoader(expressRunner));
+ // QLExpress4 没有 clearExpressCache 方法,重新初始化 runner
+ expressRunner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
+ //如果有生命周期则执行相应生命周期实现
+ super.lifeCycle(expressRunner);
}
@Override
@@ -101,7 +102,8 @@ public class QLExpressScriptExecutor extends ScriptExecutor {
@Override
public Object compile(String script) throws Exception {
- return expressRunner.getInstructionSetFromLocalCache(script);
+ // QLExpress4 不支持预编译,返回 null
+ return null;
}
}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/base/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/base/flow.el.xml
index aab117311..5bed8ab83 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/base/flow.el.xml
+++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/base/flow.el.xml
@@ -2,53 +2,7 @@
- THEN(a,b,b,a);
+ THEN(a,b,b,a,SWITCH(e).TO(d,b))
-
- THEN(
- a,b,
- SWITCH(e).to(d,f)
- );
-
-
-
- THEN(
- a,
- WHEN(
- c,
- SWITCH(g).to(b, d, THEN(h,i).id("then_1001"))
- )
- );
-
-
-
- THEN(
- a,b,
- WHEN(
- THEN(c, WHEN(j,k)),
- d,
- THEN(h, i)
- ),
- SWITCH(x).to(
- m,
- n,
- WHEN(q, THEN(p, r)).id("w01")
- ),
- z
- );
-
-
-
- t1 = THEN(c, WHEN(j,k));
- w1 = WHEN(q, THEN(p, r)).id("w01");
- t2 = THEN(h, i);
-
- THEN(
- a,b,
- WHEN(t1, d, t2 ),
- SWITCH(x).to(m, n, w1),
- z
- );
-
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 55a54b112..822e38718 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,7 +58,7 @@
0.10
0.7.3
1.4.4
- 3.3.4
+ 4.0.5
3.0.25
22.0.0
1.17.7
@@ -227,7 +227,7 @@
com.alibaba
- QLExpress
+ qlexpress4
${qlexpress.version}