mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-24 01:18:09 +08:00
Merge branch 'dev' of https://gitee.com/dromara/liteFlow
# Conflicts: # liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java
This commit is contained in:
@@ -16,170 +16,171 @@ import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 节点类型枚举
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public enum NodeTypeEnum {
|
||||
|
||||
COMMON("common","普通", false, NodeComponent.class),
|
||||
COMMON("common", "普通", false, NodeComponent.class),
|
||||
|
||||
SWITCH("switch", "选择", false, NodeSwitchComponent.class),
|
||||
SWITCH("switch", "选择", false, NodeSwitchComponent.class),
|
||||
|
||||
IF("if", "条件", false, NodeIfComponent.class),
|
||||
IF("if", "条件", false, NodeIfComponent.class),
|
||||
|
||||
FOR("for","循环次数", false, NodeForComponent.class),
|
||||
FOR("for", "循环次数", false, NodeForComponent.class),
|
||||
|
||||
WHILE("while", "循环条件", false, NodeWhileComponent.class),
|
||||
WHILE("while", "循环条件", false, NodeWhileComponent.class),
|
||||
|
||||
BREAK("break", "循环跳出", false, NodeBreakComponent.class),
|
||||
SCRIPT("script","脚本", true, ScriptCommonComponent.class),
|
||||
BREAK("break", "循环跳出", false, NodeBreakComponent.class),
|
||||
|
||||
SWITCH_SCRIPT("switch_script", "选择脚本", true, ScriptSwitchComponent.class),
|
||||
SCRIPT("script", "脚本", true, ScriptCommonComponent.class),
|
||||
|
||||
IF_SCRIPT("if_script", "条件脚本", true, ScriptIfComponent.class),
|
||||
SWITCH_SCRIPT("switch_script", "选择脚本", true, ScriptSwitchComponent.class),
|
||||
|
||||
FOR_SCRIPT("for_script", "循环次数脚本", true, ScriptForComponent.class),
|
||||
IF_SCRIPT("if_script", "条件脚本", true, ScriptIfComponent.class),
|
||||
|
||||
WHILE_SCRIPT("while_script", "循环条件脚本", true, ScriptWhileComponent.class),
|
||||
FOR_SCRIPT("for_script", "循环次数脚本", true, ScriptForComponent.class),
|
||||
|
||||
BREAK_SCRIPT("break_script", "循环跳出脚本", true, ScriptBreakComponent.class)
|
||||
;
|
||||
WHILE_SCRIPT("while_script", "循环条件脚本", true, ScriptWhileComponent.class),
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(NodeTypeEnum.class);
|
||||
BREAK_SCRIPT("break_script", "循环跳出脚本", true, ScriptBreakComponent.class);
|
||||
|
||||
private String code;
|
||||
private String name;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(NodeTypeEnum.class);
|
||||
|
||||
private boolean isScript;
|
||||
private String code;
|
||||
private String name;
|
||||
|
||||
private Class<? extends NodeComponent> mappingClazz;
|
||||
private boolean isScript;
|
||||
|
||||
NodeTypeEnum(String code, String name, boolean isScript, Class<? extends NodeComponent> mappingClazz) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.isScript = isScript;
|
||||
this.mappingClazz = mappingClazz;
|
||||
}
|
||||
private Class<? extends NodeComponent> mappingClazz;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
NodeTypeEnum(String code, String name, boolean isScript, Class<? extends NodeComponent> mappingClazz) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.isScript = isScript;
|
||||
this.mappingClazz = mappingClazz;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isScript() {
|
||||
return isScript;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setScript(boolean script) {
|
||||
isScript = script;
|
||||
}
|
||||
public boolean isScript() {
|
||||
return isScript;
|
||||
}
|
||||
|
||||
public Class<? extends NodeComponent> getMappingClazz() {
|
||||
return mappingClazz;
|
||||
}
|
||||
public void setScript(boolean script) {
|
||||
isScript = script;
|
||||
}
|
||||
|
||||
public void setMappingClazz(Class<? extends NodeComponent> mappingClazz) {
|
||||
this.mappingClazz = mappingClazz;
|
||||
}
|
||||
public Class<? extends NodeComponent> getMappingClazz() {
|
||||
return mappingClazz;
|
||||
}
|
||||
|
||||
public static NodeTypeEnum getEnumByCode(String code) {
|
||||
for (NodeTypeEnum e : NodeTypeEnum.values()) {
|
||||
if (e.getCode().equals(code)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void setMappingClazz(Class<? extends NodeComponent> mappingClazz) {
|
||||
this.mappingClazz = mappingClazz;
|
||||
}
|
||||
|
||||
public static NodeTypeEnum guessTypeBySuperClazz(Class<?> clazz){
|
||||
Class<?> superClazz = clazz;
|
||||
while(true){
|
||||
superClazz = superClazz.getSuperclass();
|
||||
if (superClazz.getPackage().getName().startsWith("com.yomahub.liteflow.core")){
|
||||
break;
|
||||
}
|
||||
if(superClazz.equals(Object.class)){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static NodeTypeEnum getEnumByCode(String code) {
|
||||
for (NodeTypeEnum e : NodeTypeEnum.values()) {
|
||||
if (e.getCode().equals(code)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
for (NodeTypeEnum e : NodeTypeEnum.values()) {
|
||||
if (e.getMappingClazz().equals(superClazz)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static NodeTypeEnum guessTypeBySuperClazz(Class<?> clazz) {
|
||||
Class<?> superClazz = clazz;
|
||||
while (true) {
|
||||
superClazz = superClazz.getSuperclass();
|
||||
if (superClazz.getPackage().getName().startsWith("com.yomahub.liteflow.core")) {
|
||||
break;
|
||||
}
|
||||
if (superClazz.equals(Object.class)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static NodeTypeEnum guessType(Class<?> clazz){
|
||||
NodeTypeEnum nodeType = guessTypeBySuperClazz(clazz);
|
||||
if (nodeType == null){
|
||||
//尝试从类声明处进行推断
|
||||
LiteflowCmpDefine liteflowCmpDefine = clazz.getAnnotation(LiteflowCmpDefine.class);
|
||||
if (liteflowCmpDefine != null){
|
||||
//类声明方式中@LiteflowMethod是无需设置nodeId的
|
||||
//但是如果设置了,那么核心逻辑其实是取类上定义的id的
|
||||
//这种可以运行,但是理解起来不大好理解,所以给出提示,建议不要这么做
|
||||
boolean mixDefined = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
||||
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
||||
if (liteflowMethod != null){
|
||||
return StrUtil.isNotBlank(liteflowMethod.nodeId());
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
for (NodeTypeEnum e : NodeTypeEnum.values()) {
|
||||
if (e.getMappingClazz().equals(superClazz)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mixDefined){
|
||||
LOG.warn("[[[WARNING!!!]]]The @liteflowMethod in the class[{}] defined by @liteflowCmpDefine should not configure the nodeId again!",
|
||||
clazz.getName());
|
||||
}
|
||||
public static NodeTypeEnum guessType(Class<?> clazz) {
|
||||
NodeTypeEnum nodeType = guessTypeBySuperClazz(clazz);
|
||||
if (nodeType == null) {
|
||||
//尝试从类声明处进行推断
|
||||
LiteflowCmpDefine liteflowCmpDefine = clazz.getAnnotation(LiteflowCmpDefine.class);
|
||||
if (liteflowCmpDefine != null) {
|
||||
//类声明方式中@LiteflowMethod是无需设置nodeId的
|
||||
//但是如果设置了,那么核心逻辑其实是取类上定义的id的
|
||||
//这种可以运行,但是理解起来不大好理解,所以给出提示,建议不要这么做
|
||||
boolean mixDefined = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
||||
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
||||
if (liteflowMethod != null) {
|
||||
return StrUtil.isNotBlank(liteflowMethod.nodeId());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (mixDefined) {
|
||||
LOG.warn("[[[WARNING!!!]]]The @liteflowMethod in the class[{}] defined by @liteflowCmpDefine should not configure the nodeId again!",
|
||||
clazz.getName());
|
||||
}
|
||||
|
||||
|
||||
//在返回之前,还要对方法级别的@LiteflowMethod进行检查,如果存在方法上的类型与类上的不一致时,给予警告信息
|
||||
AtomicReference<Method> differenceTypeMethod = new AtomicReference<>();
|
||||
boolean hasDifferenceNodeType = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
||||
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
||||
if (liteflowMethod != null){
|
||||
if (!liteflowMethod.nodeType().equals(liteflowCmpDefine.value())){
|
||||
differenceTypeMethod.set(method);
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
//在返回之前,还要对方法级别的@LiteflowMethod进行检查,如果存在方法上的类型与类上的不一致时,给予警告信息
|
||||
AtomicReference<Method> differenceTypeMethod = new AtomicReference<>();
|
||||
boolean hasDifferenceNodeType = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
|
||||
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
|
||||
if (liteflowMethod != null) {
|
||||
if (!liteflowMethod.nodeType().equals(liteflowCmpDefine.value())) {
|
||||
differenceTypeMethod.set(method);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
//表示存在不一样的类型
|
||||
if (hasDifferenceNodeType){
|
||||
LOG.warn("[[[WARNING!!!]]]The nodeType in @liteflowCmpDefine declared on the class[{}] does not match the nodeType in @liteflowMethod declared on the method[{}]!",
|
||||
clazz.getName(), differenceTypeMethod.get().getName());
|
||||
}
|
||||
//表示存在不一样的类型
|
||||
if (hasDifferenceNodeType) {
|
||||
LOG.warn("[[[WARNING!!!]]]The nodeType in @liteflowCmpDefine declared on the class[{}] does not match the nodeType in @liteflowMethod declared on the method[{}]!",
|
||||
clazz.getName(), differenceTypeMethod.get().getName());
|
||||
}
|
||||
|
||||
return liteflowCmpDefine.value();
|
||||
}
|
||||
return liteflowCmpDefine.value();
|
||||
}
|
||||
|
||||
//再尝试声明式组件这部分的推断
|
||||
LiteflowMethod liteflowMethod = Arrays.stream(clazz.getDeclaredMethods()).map(
|
||||
method -> AnnotationUtil.getAnnotation(method, LiteflowMethod.class)
|
||||
).filter(Objects::nonNull).filter(lfMethod -> lfMethod.value().isMainMethod()).findFirst().orElse(null);
|
||||
//再尝试声明式组件这部分的推断
|
||||
LiteflowMethod liteflowMethod = Arrays.stream(clazz.getDeclaredMethods()).map(
|
||||
method -> AnnotationUtil.getAnnotation(method, LiteflowMethod.class)
|
||||
).filter(Objects::nonNull).filter(lfMethod -> lfMethod.value().isMainMethod()).findFirst().orElse(null);
|
||||
|
||||
if (liteflowMethod != null) {
|
||||
nodeType = liteflowMethod.nodeType();
|
||||
}
|
||||
}
|
||||
return nodeType;
|
||||
}
|
||||
if (liteflowMethod != null) {
|
||||
nodeType = liteflowMethod.nodeType();
|
||||
}
|
||||
}
|
||||
return nodeType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ public abstract class BaseJsonFlowParser implements FlowParser {
|
||||
JsonNode flowJsonNode = JsonUtil.parseObject(content);
|
||||
jsonObjectList.add(flowJsonNode);
|
||||
}
|
||||
ParserHelper.parseJsonNode(jsonObjectList, CHAIN_NAME_SET, this::parseOneChain);
|
||||
ParserHelper.parseNodeJson(jsonObjectList);
|
||||
ParserHelper.parseChainJson(jsonObjectList, CHAIN_NAME_SET, this::parseOneChain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,8 +36,8 @@ public abstract class BaseXmlFlowParser implements FlowParser {
|
||||
documentList.add(document);
|
||||
}
|
||||
|
||||
Consumer<Element> parseOneChainConsumer = this::parseOneChain;
|
||||
ParserHelper.parseDocument(documentList, CHAIN_NAME_SET, parseOneChainConsumer);
|
||||
ParserHelper.parseNodeDocument(documentList);
|
||||
ParserHelper.parseChainDocument(documentList, CHAIN_NAME_SET, this::parseOneChain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,8 @@ public abstract class BaseYmlFlowParser implements FlowParser {
|
||||
}
|
||||
|
||||
Consumer<JsonNode> parseOneChainConsumer = this::parseOneChain;
|
||||
ParserHelper.parseJsonNode(jsonObjectList, CHAIN_NAME_SET,parseOneChainConsumer);
|
||||
ParserHelper.parseNodeJson(jsonObjectList);
|
||||
ParserHelper.parseChainJson(jsonObjectList, CHAIN_NAME_SET, parseOneChainConsumer);
|
||||
}
|
||||
|
||||
protected JsonNode convertToJson(String yamlString) {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.yomahub.liteflow.parser.helper;
|
||||
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.yomahub.liteflow.annotation.*;
|
||||
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
|
||||
import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
|
||||
import com.yomahub.liteflow.builder.prop.NodePropBean;
|
||||
@@ -87,35 +85,13 @@ public class ParserHelper {
|
||||
|
||||
/**
|
||||
* xml 形式的主要解析过程
|
||||
*
|
||||
* @param documentList documentList
|
||||
* @param chainNameSet 用于去重
|
||||
* @param parseOneChainConsumer parseOneChain 函数
|
||||
*/
|
||||
public static void parseDocument(List<Document> documentList, Set<String> chainNameSet, Consumer<Element> parseOneChainConsumer) {
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
documentList.forEach(document -> {
|
||||
// 解析chain节点
|
||||
List<Element> chainList = document.getRootElement().elements(CHAIN);
|
||||
|
||||
//先在元数据里放上chain
|
||||
chainList.forEach(e -> {
|
||||
//校验加载的 chainName 是否有重复的
|
||||
//TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
});
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
/**
|
||||
* xml 形式的主要解析过程
|
||||
* @param documentList documentList
|
||||
*/
|
||||
public static void parseNodeDocument(List<Document> documentList) {
|
||||
for (Document document : documentList) {
|
||||
Element rootElement = document.getRootElement();
|
||||
Element nodesElement = rootElement.element(NODES);
|
||||
@@ -143,38 +119,67 @@ public class ParserHelper {
|
||||
ParserHelper.buildNode(nodePropBean);
|
||||
}
|
||||
}
|
||||
|
||||
//解析每一个chain
|
||||
List<Element> chainList = rootElement.elements(CHAIN);
|
||||
chainList.forEach(parseOneChainConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseJsonNode(List<JsonNode> flowJsonObjectList, Set<String> chainNameSet, Consumer<JsonNode> parseOneChainConsumer) {
|
||||
|
||||
public static void parseDocument(List<Document> documentList, Set<String> chainNameSet, Consumer<Element> parseOneChainConsumer) {
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
flowJsonObjectList.forEach(jsonObject -> {
|
||||
documentList.forEach(document -> {
|
||||
// 解析chain节点
|
||||
Iterator<JsonNode> iterator = jsonObject.get(FLOW).get(CHAIN).elements();
|
||||
List<Element> chainList = document.getRootElement().elements(CHAIN);
|
||||
|
||||
//先在元数据里放上chain
|
||||
while (iterator.hasNext()) {
|
||||
JsonNode innerJsonObject = iterator.next();
|
||||
chainList.forEach(e -> {
|
||||
//校验加载的 chainName 是否有重复的
|
||||
// TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
//String chainName = innerJsonObject.get(NAME).textValue();
|
||||
String chainName = Optional.ofNullable(innerJsonObject.get(ID)).orElse(innerJsonObject.get(NAME)).textValue();
|
||||
//TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
}
|
||||
});
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
}
|
||||
|
||||
public static void parseChainDocument(List<Document> documentList, Set<String> chainNameSet, Consumer<Element> parseOneChainConsumer){
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
documentList.forEach(document -> {
|
||||
// 解析chain节点
|
||||
List<Element> chainList = document.getRootElement().elements(CHAIN);
|
||||
|
||||
//先在元数据里放上chain
|
||||
chainList.forEach(e -> {
|
||||
//校验加载的 chainName 是否有重复的
|
||||
//TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
});
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
//解析每一个chain
|
||||
for (Document document : documentList) {
|
||||
Element rootElement = document.getRootElement();
|
||||
List<Element> chainList = rootElement.elements(CHAIN);
|
||||
chainList.forEach(parseOneChainConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseNodeJson(List<JsonNode> flowJsonObjectList) {
|
||||
for (JsonNode flowJsonNode : flowJsonObjectList) {
|
||||
// 当存在<nodes>节点定义时,解析node节点
|
||||
if (flowJsonNode.get(FLOW).has(NODES)) {
|
||||
@@ -201,7 +206,61 @@ public class ParserHelper {
|
||||
ParserHelper.buildNode(nodePropBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseJsonNode(List<JsonNode> flowJsonObjectList, Set<String> chainNameSet, Consumer<JsonNode> parseOneChainConsumer) {
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
flowJsonObjectList.forEach(jsonObject -> {
|
||||
// 解析chain节点
|
||||
Iterator<JsonNode> iterator = jsonObject.get(FLOW).get(CHAIN).elements();
|
||||
//先在元数据里放上chain
|
||||
while (iterator.hasNext()) {
|
||||
JsonNode innerJsonObject = iterator.next();
|
||||
//校验加载的 chainName 是否有重复的
|
||||
// TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
//String chainName = innerJsonObject.get(NAME).textValue();
|
||||
String chainName = Optional.ofNullable(innerJsonObject.get(ID)).orElse(innerJsonObject.get(NAME)).textValue();
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
}
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
}
|
||||
|
||||
public static void parseChainJson(List<JsonNode> flowJsonObjectList, Set<String> chainNameSet, Consumer<JsonNode> parseOneChainConsumer){
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
flowJsonObjectList.forEach(jsonObject -> {
|
||||
// 解析chain节点
|
||||
Iterator<JsonNode> iterator = jsonObject.get(FLOW).get(CHAIN).elements();
|
||||
//先在元数据里放上chain
|
||||
while (iterator.hasNext()) {
|
||||
JsonNode innerJsonObject = iterator.next();
|
||||
//校验加载的 chainName 是否有重复的
|
||||
// TODO 这里是否有个问题,当混合格式加载的时候,2个同名的Chain在不同的文件里,就不行了
|
||||
String chainName = Optional.ofNullable(innerJsonObject.get(ID)).orElse(innerJsonObject.get(NAME)).textValue();
|
||||
if (!chainNameSet.add(chainName)) {
|
||||
throw new ChainDuplicateException(String.format("[chain name duplicate] chainName=%s", chainName));
|
||||
}
|
||||
|
||||
FlowBus.addChain(chainName);
|
||||
}
|
||||
});
|
||||
// 清空
|
||||
chainNameSet.clear();
|
||||
|
||||
for (JsonNode flowJsonNode : flowJsonObjectList) {
|
||||
//解析每一个chain
|
||||
Iterator<JsonNode> chainIterator = flowJsonNode.get(FLOW).get(CHAIN).elements();
|
||||
while (chainIterator.hasNext()) {
|
||||
@@ -218,9 +277,9 @@ public class ParserHelper {
|
||||
*/
|
||||
public static void parseOneChainEl(JsonNode chainNode) {
|
||||
//构建chainBuilder
|
||||
String chainName = Optional.ofNullable(chainNode.get(ID)).orElse(chainNode.get(NAME)).textValue();
|
||||
String chainId = Optional.ofNullable(chainNode.get(ID)).orElse(chainNode.get(NAME)).textValue();
|
||||
String el = chainNode.get(VALUE).textValue();
|
||||
LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainName(chainName);
|
||||
LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainId(chainId);
|
||||
chainELBuilder.setEL(el).build();
|
||||
}
|
||||
|
||||
@@ -231,10 +290,10 @@ public class ParserHelper {
|
||||
*/
|
||||
public static void parseOneChainEl(Element e) {
|
||||
//构建chainBuilder
|
||||
String chainName = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
||||
String chainId = Optional.ofNullable(e.attributeValue(ID)).orElse(e.attributeValue(NAME));
|
||||
String text = e.getText();
|
||||
String el = RegexUtil.removeComments(text);
|
||||
LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainName(chainName);
|
||||
LiteFlowChainELBuilder chainELBuilder = LiteFlowChainELBuilder.createChain().setChainId(chainId);
|
||||
chainELBuilder.setEL(el).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
language (groovy|js) #IMPLIED
|
||||
>
|
||||
<!ATTLIST chain
|
||||
name CDATA #REQUIRED>
|
||||
name CDATA>
|
||||
Reference in New Issue
Block a user