!105 对于el表达式里的未定义的子表达式和未注册的node进行编译时检查

Merge pull request !105 from 与或非/issues/I5Q3SS
This commit is contained in:
铂赛东
2022-09-17 15:09:52 +00:00
committed by Gitee
4 changed files with 188 additions and 133 deletions

View File

@@ -6,21 +6,22 @@ import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.builder.el.operator.*;
import com.yomahub.liteflow.exception.DataNofFoundException;
import com.yomahub.liteflow.exception.ELParseException;
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.Executable;
import com.yomahub.liteflow.flow.element.condition.Condition;
import com.yomahub.liteflow.flow.element.condition.FinallyCondition;
import com.yomahub.liteflow.flow.element.condition.PreCondition;
import com.yomahub.liteflow.flow.element.condition.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Chain基于代码形式的组装器
* EL表达式规则专属组装器
*
* @author Bryan.Zhang
* @since 2.8.0
*/
@@ -41,7 +42,7 @@ public class LiteFlowChainELBuilder {
private final List<Condition> finallyConditionList;
//EL解析引擎
private final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();;
private final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();
static {
//初始化QLExpress的Runner
@@ -86,13 +87,13 @@ public class LiteFlowChainELBuilder {
}
public LiteFlowChainELBuilder setEL(String elStr) {
if (StrUtil.isBlank(elStr)){
if (StrUtil.isBlank(elStr)) {
String errMsg = StrUtil.format("no conditionList in this chain[{}]", chain.getChainName());
throw new FlowSystemException(errMsg);
}
List<String> errorList = new ArrayList<>();
try{
try {
DefaultContext<String, Object> context = new DefaultContext<>();
//这里一定要先放chain再放node因为node优先于chain所以当重名时node会覆盖掉chain
@@ -111,8 +112,8 @@ public class LiteFlowChainELBuilder {
//为什么只寻找第一层,而不往下寻找了呢?
//因为这是一个规范如果在后面的层级中出现pre和finally语义上也不好理解所以pre和finally只能定义在第一层
//如果硬是要在后面定义,则执行的时候会忽略,相关代码已做了判断
for (Executable executable : condition.getExecutableList()){
if (executable instanceof PreCondition){
for (Executable executable : condition.getExecutableList()) {
if (executable instanceof PreCondition) {
this.preConditionList.add((PreCondition) executable);
} else if (executable instanceof FinallyCondition) {
this.finallyConditionList.add((FinallyCondition) executable);
@@ -122,9 +123,13 @@ public class LiteFlowChainELBuilder {
//把主要的condition加入
this.conditionList.add(condition);
return this;
}catch (QLException e){
} catch (QLException e) {
// EL 底层会包装异常,这里是曲线处理
if (Objects.equals(e.getCause().getMessage(), DataNofFoundException.MSG)) {
throw new ELParseException(String.format("[node/chain is not exist or node/chain not register]elStr=%s", elStr));
}
throw new ELParseException(e.getCause().getMessage());
}catch (Exception e){
} catch (Exception e) {
throw new ELParseException(e.getMessage());
}
}

View File

@@ -12,23 +12,25 @@ import com.yomahub.liteflow.exception.ELParseException;
*/
public abstract class BaseOperator extends Operator {
@Override
public Object executeInner(Object[] objects) throws Exception {
try {
return buildCondition(objects);
} catch (QLException e) {
throw e;
} catch (Exception e) {
throw new ELParseException("errors occurred in EL parsing");
}
}
@Override
public Object executeInner(Object[] objects) throws Exception {
try {
// 检查 node 和 chain 是否已经注册
OperatorHelper.checkNodeAndChainExist(objects);
return buildCondition(objects);
} catch (QLException e) {
throw e;
} catch (Exception e) {
throw new ELParseException("errors occurred in EL parsing");
}
}
/**
* 构建 EL 条件
*
* @param objects objects
* @return Condition
* @throws Exception Exception
*/
public abstract Object buildCondition(Object[] objects) throws Exception;
/**
* 构建 EL 条件
*
* @param objects objects
* @return Condition
* @throws Exception Exception
*/
public abstract Object buildCondition(Object[] objects) throws Exception;
}

View File

@@ -1,6 +1,9 @@
package com.yomahub.liteflow.builder.el.operator.base;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.exception.DataNofFoundException;
import java.util.Objects;
/**
* Operator 常用工具类
@@ -9,121 +12,134 @@ import com.ql.util.express.exception.QLException;
*/
public class OperatorHelper {
/**
* 检查参数数量不等于1
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeNeqOne(Object[] objects) throws QLException {
checkObjectSizeNeq(objects, 1);
}
/**
* 检查参数数量不等于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");
}
}
/**
* 检查参数数量,不等于 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
* @throws QLException QLException
*/
public static void checkObjectSizeGtZero(Object[] objects) throws QLException {
if (objects.length == 0) {
throw new QLException("parameter is empty");
}
}
/**
* 检查参数数量,大于 0
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeGtZero(Object[] objects) throws QLException {
if (objects.length == 0) {
throw new QLException("parameter is empty");
}
}
/**
* 检查参数数量,大于 2
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeGtTwo(Object[] objects) throws QLException {
checkObjectSizeGtZero(objects);
if (objects.length <= 1) {
throw new QLException("parameter error");
}
}
/**
* 检查参数数量,大于 2
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeGtTwo(Object[] objects) throws QLException {
checkObjectSizeGtZero(objects);
if (objects.length <= 1) {
throw new QLException("parameter error");
}
}
/**
* 检查参数数量,等于 2
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeEqTwo(Object[] objects) throws QLException {
checkObjectSizeEq(objects, 2);
}
/**
* 检查参数数量,等于 2
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeEqTwo(Object[] objects) throws QLException {
checkObjectSizeEq(objects, 2);
}
/**
* 检查参数数量,等于 3
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeEqThree(Object[] objects) throws QLException {
checkObjectSizeEq(objects, 3);
}
/**
* 检查参数数量,等于 3
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkObjectSizeEqThree(Object[] objects) throws QLException {
checkObjectSizeEq(objects, 3);
}
/**
* 检查参数数量,等于 size
*
* @param objects objects
* @param size 参数数量
* @throws QLException QLException
*/
public static void checkObjectSizeEq(Object[] objects, int size) throws QLException {
checkObjectSizeGtZero(objects);
/**
* 检查参数数量,等于 size
*
* @param objects objects
* @param size 参数数量
* @throws QLException QLException
*/
public static void checkObjectSizeEq(Object[] objects, int size) throws QLException {
checkObjectSizeGtZero(objects);
if (objects.length != size) {
throw new QLException("parameter error");
}
}
if (objects.length != size) {
throw new QLException("parameter error");
}
}
/**
* 检查参数数量,等于 size1 或 size2
*
* @param objects objects
* @param size1 参数数量1
* @param size2 参数数量2
* @throws QLException QLException
*/
public static void checkObjectSizeEq(Object[] objects, int size1, int size2) throws QLException {
checkObjectSizeGtZero(objects);
/**
* 检查参数数量,等于 size1 或 size2
*
* @param objects objects
* @param size1 参数数量1
* @param size2 参数数量2
* @throws QLException QLException
*/
public static void checkObjectSizeEq(Object[] objects, int size1, int size2) throws QLException {
checkObjectSizeGtZero(objects);
if (objects.length != size1 && objects.length != size2) {
throw new QLException("parameter error");
}
}
if (objects.length != size1 && objects.length != size2) {
throw new QLException("parameter error");
}
}
/**
* 转换 object 为指定的类型
*
* @param object object
* @param tClass 指定类型
* @param <T> 返回类型
* @return T
* @throws QLException QLException
*/
public static <T> T convert(Object object, Class<T> tClass) throws QLException {
if (tClass.isInstance(object)) {
return (T) object;
}
/**
* 转换 object 为指定的类型
*
* @param object object
* @param tClass 指定类型
* @param <T> 返回类型
* @return T
* @throws QLException QLException
*/
public static <T> T convert(Object object, Class<T> tClass) throws QLException {
if (tClass.isInstance(object)) {
return (T) object;
}
throw new QLException("The caller must be " + tClass.getName() + " item");
}
throw new QLException("The caller must be " + tClass.getName() + " item");
}
/**
* 检查 node 和 chain 是否已经注册
*
* @param objects objects
* @throws QLException QLException
*/
public static void checkNodeAndChainExist(Object[] objects) throws QLException {
for (Object object : objects) {
if (Objects.isNull(object)) {
throw new QLException(DataNofFoundException.MSG);
}
}
}
}

View File

@@ -0,0 +1,32 @@
package com.yomahub.liteflow.exception;
/**
* @author tangkc
*/
public class DataNofFoundException extends RuntimeException {
public static final String MSG = "DataNofFoundException";
private static final long serialVersionUID = 1L;
/**
* 异常信息
*/
private String message;
public DataNofFoundException() {
this.message = MSG;
}
public DataNofFoundException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}