enhancement #ICU4Z3 优化 nodeid 不合法报错提示,增加错误引导

This commit is contained in:
gaibu
2025-08-21 22:29:56 +08:00
parent ddbddc28c9
commit 1d300131bb
4 changed files with 157 additions and 47 deletions

View File

@@ -31,6 +31,7 @@ import com.yomahub.liteflow.log.LFLoggerManager;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
import com.yomahub.liteflow.util.ElRegexUtil;
import com.yomahub.liteflow.util.QlExpressUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -66,53 +67,10 @@ public class LiteFlowChainELBuilder {
* 所以在这里做一个缓存等conditionList全部build完毕后再去一次性替换chain里面的conditionList
*/
private final List<Condition> conditionList;
/**
* EL解析引擎
*/
public final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();
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());
}
/**
* EL解析引擎
*/
private final static ExpressRunner EXPRESS_RUNNER = QlExpressUtils.getInstance();
public static LiteFlowChainELBuilder createChain() {
return new LiteFlowChainELBuilder();

View File

@@ -0,0 +1,31 @@
package com.yomahub.liteflow.exception;
/**
* node id不合法异常
*
* @author tangkc
* @since 2.13.2
*/
public class NodeIdUnIllegalException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 异常信息
*/
private String message;
public NodeIdUnIllegalException(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,94 @@
package com.yomahub.liteflow.util;
import com.ql.util.express.ExpressRunner;
import com.yomahub.liteflow.builder.el.operator.*;
import com.yomahub.liteflow.common.ChainConstant;
/**
* EL 工具类
*
* @author tangkc
* @since 2.13.2
*/
public class QlExpressUtils {
/**
* EL解析引擎
*/
private final static ExpressRunner EXPRESS_RUNNER = new ExpressRunner();
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());
}
/**
* 获取QLExpress的实例
*/
public static ExpressRunner getInstance() {
return EXPRESS_RUNNER;
}
/**
* 检查变量名是否符合 变量命名规则
*
* @param variableName 变量名
* @return 如果符合规范返回 true否则返回 false
*/
public static boolean checkVariableName(String variableName) {
if (variableName == null || variableName.isEmpty()) {
return false;
}
// 首字符必须是合法的 Java 标识符起始字符
if (!Character.isJavaIdentifierStart(variableName.charAt(0))) {
return false;
}
// 后续字符必须是合法的 Java 标识符部分
for (int i = 1; i < variableName.length(); i++) {
if (!Character.isJavaIdentifierPart(variableName.charAt(i))) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,27 @@
package com.yomahub.liteflow.test.utils;
import cn.hutool.core.lang.Assert;
import com.yomahub.liteflow.util.QlExpressUtils;
import org.junit.jupiter.api.Test;
/**
* EL 工具类测试
*
* @author tangkc
* @since 2.13.2
*/
public class QlExpressUtilsTest {
@Test
public void checkVariableNameTest(){
// 错误的
Assert.isFalse(QlExpressUtils.checkVariableName(""));
Assert.isFalse(QlExpressUtils.checkVariableName("11a"));
Assert.isFalse(QlExpressUtils.checkVariableName("a-a"));
// 正确的
Assert.isTrue(QlExpressUtils.checkVariableName("aa"));
Assert.isTrue(QlExpressUtils.checkVariableName("_aa"));
Assert.isTrue(QlExpressUtils.checkVariableName("$aa"));
Assert.isTrue(QlExpressUtils.checkVariableName("$a_a"));
}
}