enhancement #ID8XF9 对QLExpress4的支持

This commit is contained in:
everywhere.z
2025-11-28 19:40:05 +08:00
parent ad9906584a
commit e0c6f39a01
5 changed files with 28 additions and 34 deletions

View File

@@ -1,7 +1,6 @@
package com.yomahub.liteflow.builder.el;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -15,7 +14,7 @@ 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;
import com.yomahub.liteflow.enums.ParseModeEnum;
@@ -37,9 +36,9 @@ import com.yomahub.liteflow.util.ElRegexUtil;
import com.yomahub.liteflow.util.QlExpressUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
@@ -73,7 +72,7 @@ public class LiteFlowChainELBuilder {
/**
* EL解析引擎
*/
private final static Express4Runner EXPRESS_RUNNER = QlExpressUtils.getInstance();
private final static Express4Runner EXPRESS_RUNNER = QlExpressUtils.getELExpressRunner();
public static LiteFlowChainELBuilder createChain() {
return new LiteFlowChainELBuilder();
@@ -290,25 +289,15 @@ 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;
}
String[] outAttrNames = parseResult.getOutAttrNames();
if (ArrayUtil.isEmpty(outAttrNames)) {
// 使用 QLExpress4 的 getOutVarNames 方法获取脚本中使用的所有外部变量
Set<String> outVarNames = EXPRESS_RUNNER.getOutVarNames(elStr);
if (CollUtil.isEmpty(outVarNames)) {
return msg;
}
List<String> chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true);
List<String> nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true);
for (String attrName : outAttrNames) {
for (String attrName : outVarNames) {
if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) {
msg = String.format(
"[%s] is not exist or [%s] is not registered, you need to define a node or chain with id [%s] and register it \n EL: ",
@@ -332,13 +321,12 @@ public class LiteFlowChainELBuilder {
// 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a")
int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName));
if (nodeIndex != -1) {
// 需要加上 "EL: " 的长度 4再加上 node(" 长度 6再加上 "^" 的长度 1indexOf 从 0
// 需要加上 "EL: " 的长度 4再加上 "node("" 长度 6再加上 "^" 的长度 1indexOf 从 0
// 开始,所以还需要加 1
return msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true);
}
}
}
*/
} catch (Exception ex) {
// ignore
}
@@ -373,12 +361,8 @@ public class LiteFlowChainELBuilder {
// 只有当PARSE_ONE_ON_FIRST_EXEC时才会执行这个方法
// 那么会有一种级联的情况这个EL中含有其他的chain如果这时候不先解析其他chain就到导致诸如循环场景无法设置index或者obj的情况
// 所以这里要判断表达式里有没有其他的chain如果有进行先行解析
// TODO: QLExpress4 暂时没有 getOutVarNames 方法,这里先注释掉级联解析逻辑
// 等待 QLExpress4 提供相应的 API 后再恢复
/*
String[] itemArray = EXPRESS_RUNNER.getOutVarNames(chain.getEl());
Arrays.stream(itemArray).forEach(item -> {
Set<String> itemSet = EXPRESS_RUNNER.getOutVarNames(chain.getEl());
itemSet.stream().forEach(item -> {
if (FlowBus.containChain(item) && !chain.getChainId().equals(item)) {
Chain itemChain = FlowBus.getChain(item);
if (!itemChain.isCompiled()){
@@ -386,7 +370,6 @@ public class LiteFlowChainELBuilder {
}
}
});
*/
// 解析el成为一个Condition
// 为什么这里只是一个Condition而不是一个List<Condition>呢

View File

@@ -28,7 +28,7 @@ import java.util.stream.IntStream;
*/
public class LiteflowContextRegexMatcher {
private static final Express4Runner expressRunner = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
private static final Express4Runner expressRunner = QlExpressUtils.getContextSearchExpressRunner();
public static Object searchContext(List<Tuple> contextList, String regPattern){
// 把上下文数据转换成map形式的key为别名value为上下文

View File

@@ -2,6 +2,7 @@ package com.yomahub.liteflow.util;
import com.alibaba.qlexpress4.Express4Runner;
import com.alibaba.qlexpress4.InitOptions;
import com.alibaba.qlexpress4.security.QLSecurityStrategy;
import com.yomahub.liteflow.builder.el.operator.*;
import com.yomahub.liteflow.common.ChainConstant;
@@ -18,6 +19,11 @@ public class QlExpressUtils {
*/
private final static Express4Runner EXPRESS_RUNNER = new Express4Runner(InitOptions.DEFAULT_OPTIONS);
/**
* 上下文搜索解析引擎
*/
private final static Express4Runner CONTEXT_SEARCH_EXPRESS_RUNNER = new Express4Runner(InitOptions.builder().securityStrategy(QLSecurityStrategy.open()).build());
static {
// 初始化QLExpress的Runner
EXPRESS_RUNNER.addVarArgsFunction(ChainConstant.THEN, new ThenOperator());
@@ -63,10 +69,17 @@ public class QlExpressUtils {
/**
* 获取QLExpress的实例
*/
public static Express4Runner getInstance() {
public static Express4Runner getELExpressRunner() {
return EXPRESS_RUNNER;
}
/**
* 获取上下文搜索的QLExpress实例
*/
public static Express4Runner getContextSearchExpressRunner() {
return CONTEXT_SEARCH_EXPRESS_RUNNER;
}
/**
* 检查变量名是否符合 变量命名规则
*