From 1d300131bb1cd15b61ee7abbc72fad9c1025f55c Mon Sep 17 00:00:00 2001 From: gaibu <1016771049@qq.com> Date: Thu, 21 Aug 2025 22:29:56 +0800 Subject: [PATCH] =?UTF-8?q?enhancement=20#ICU4Z3=20=E4=BC=98=E5=8C=96=20no?= =?UTF-8?q?deid=20=E4=B8=8D=E5=90=88=E6=B3=95=E6=8A=A5=E9=94=99=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=94=99=E8=AF=AF=E5=BC=95?= =?UTF-8?q?=E5=AF=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/el/LiteFlowChainELBuilder.java | 52 +--------- .../exception/NodeIdUnIllegalException.java | 31 ++++++ .../yomahub/liteflow/util/QlExpressUtils.java | 94 +++++++++++++++++++ .../test/utils/QlExpressUtilsTest.java | 27 ++++++ 4 files changed, 157 insertions(+), 47 deletions(-) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/exception/NodeIdUnIllegalException.java create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/util/QlExpressUtils.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/utils/QlExpressUtilsTest.java 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 7ce55ea09..4ce4ce0c8 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 @@ -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 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(); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NodeIdUnIllegalException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NodeIdUnIllegalException.java new file mode 100644 index 000000000..820aa03fa --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/NodeIdUnIllegalException.java @@ -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; + } + +} 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 new file mode 100644 index 000000000..a840e91cb --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/util/QlExpressUtils.java @@ -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; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/utils/QlExpressUtilsTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/utils/QlExpressUtilsTest.java new file mode 100644 index 000000000..047c1d4ec --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/utils/QlExpressUtilsTest.java @@ -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")); + } +}