mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 20:22:07 +08:00
feature #I4GS07 代码动态组件装配的特性
enhancement #I4QWJK 重构parser逻辑,解决的代码冗余问题 feature #I4QWH7 支持循环依赖 enhancement #I4CNO1 不使用spring无法使用
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
package com.yomahub.liteflow.builder;
|
||||
|
||||
import com.yomahub.liteflow.entity.flow.Chain;
|
||||
import com.yomahub.liteflow.entity.flow.Condition;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.yomahub.liteflow.entity.flow.*;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.flow.FlowBus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Chain基于代码形式的组装器
|
||||
@@ -13,7 +15,7 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class LiteFlowChainBuilder {
|
||||
|
||||
private final Chain chain;
|
||||
private Chain chain;
|
||||
|
||||
public static LiteFlowChainBuilder createChain(){
|
||||
return new LiteFlowChainBuilder();
|
||||
@@ -21,20 +23,61 @@ public class LiteFlowChainBuilder {
|
||||
|
||||
public LiteFlowChainBuilder(){
|
||||
chain = new Chain();
|
||||
chain.setConditionList(new ArrayList<>());
|
||||
}
|
||||
|
||||
public LiteFlowChainBuilder setChainName(String chainName){
|
||||
this.chain.setChainName(chainName);
|
||||
if (FlowBus.containChain(chainName)){
|
||||
this.chain = FlowBus.getChain(chainName);
|
||||
}else{
|
||||
this.chain.setChainName(chainName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowChainBuilder setCondition(Condition condition){
|
||||
this.chain.getConditionList().add(condition);
|
||||
//这里把condition组装进conditionList,
|
||||
buildConditions(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build(){
|
||||
FlowBus.addChain(this.chain);
|
||||
}
|
||||
|
||||
private void buildConditions(Condition condition) {
|
||||
//这里进行合并逻辑
|
||||
//对于then来说,相邻的2个then会合并成一个condition
|
||||
//对于when来说,相同组的when会合并成一个condition,不同组的when还是会拆开
|
||||
if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_PRE)) {
|
||||
this.chain.getConditionList().add(new PreCondition(condition));
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_THEN)) {
|
||||
if (this.chain.getConditionList().size() >= 1 &&
|
||||
CollectionUtil.getLast(this.chain.getConditionList()) instanceof ThenCondition) {
|
||||
CollectionUtil.getLast(this.chain.getConditionList()).getNodeList().addAll(condition.getNodeList());
|
||||
} else {
|
||||
this.chain.getConditionList().add(new ThenCondition(condition));
|
||||
}
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_WHEN)) {
|
||||
if (this.chain.getConditionList().size() > 1 &&
|
||||
CollectionUtil.getLast(this.chain.getConditionList()) instanceof WhenCondition &&
|
||||
CollectionUtil.getLast(this.chain.getConditionList()).getGroup().equals(condition.getGroup())) {
|
||||
CollectionUtil.getLast(this.chain.getConditionList()).getNodeList().addAll(condition.getNodeList());
|
||||
} else {
|
||||
this.chain.getConditionList().add(new WhenCondition(condition));
|
||||
}
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY)) {
|
||||
this.chain.getConditionList().add(new FinallyCondition(condition));
|
||||
}
|
||||
|
||||
//每一次build之后,对conditionList进行排序,pre最前面,finally最后
|
||||
//这里为什么要排序,因为在声明的时候,哪怕有人不把pre放最前,finally放最后,但最终也要确保是正确的顺序
|
||||
CollectionUtil.sort(this.chain.getConditionList(), (o1, o2) -> {
|
||||
if (o1.getConditionType().equals(ConditionTypeEnum.TYPE_PRE) || o2.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY)){
|
||||
return -1;
|
||||
} else if (o2.getConditionType().equals(ConditionTypeEnum.TYPE_PRE) || o1.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY)){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ public class LiteFlowConditionBuilder {
|
||||
|
||||
protected Condition condition;
|
||||
|
||||
public static LiteFlowConditionBuilder createCondition(ConditionTypeEnum conditionType){
|
||||
return new LiteFlowConditionBuilder(conditionType);
|
||||
}
|
||||
|
||||
public static LiteFlowConditionBuilder createThenCondition(){
|
||||
return new LiteFlowConditionBuilder(ConditionTypeEnum.TYPE_THEN);
|
||||
}
|
||||
@@ -40,7 +44,7 @@ public class LiteFlowConditionBuilder {
|
||||
|
||||
public LiteFlowConditionBuilder(ConditionTypeEnum conditionType){
|
||||
this.condition = new Condition();
|
||||
this.condition.setConditionType(conditionType.getType());
|
||||
this.condition.setConditionType(conditionType);
|
||||
this.condition.setNodeList(new ArrayList<>());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.yomahub.liteflow.builder;
|
||||
|
||||
import com.yomahub.liteflow.entity.flow.Chain;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.entity.flow.Node;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.NodeBuildException;
|
||||
import com.yomahub.liteflow.flow.FlowBus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LiteFlowNodeBuilder {
|
||||
|
||||
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final Node node;
|
||||
|
||||
public static LiteFlowNodeBuilder createNode(){
|
||||
public static LiteFlowNodeBuilder createNode() {
|
||||
return new LiteFlowNodeBuilder();
|
||||
}
|
||||
|
||||
@@ -16,19 +23,52 @@ public class LiteFlowNodeBuilder {
|
||||
this.node = new Node();
|
||||
}
|
||||
|
||||
public LiteFlowNodeBuilder setId(String nodeId){
|
||||
public LiteFlowNodeBuilder setId(String nodeId) {
|
||||
this.node.setId(nodeId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowNodeBuilder setName(String name){
|
||||
public LiteFlowNodeBuilder setName(String name) {
|
||||
this.node.setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowNodeBuilder setType(NodeTypeEnum type){
|
||||
public LiteFlowNodeBuilder setClazz(String clazz) {
|
||||
this.node.setClazz(clazz);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowNodeBuilder setType(NodeTypeEnum type) {
|
||||
this.node.setType(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowNodeBuilder setScript(String script) {
|
||||
this.node.setScript(script);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowNodeBuilder setFile(String filePath) {
|
||||
if (StrUtil.isBlank(filePath)){
|
||||
return this;
|
||||
}
|
||||
String script = ResourceUtil.readUtf8Str(StrUtil.format("classpath: {}", filePath));
|
||||
return setScript(script);
|
||||
}
|
||||
|
||||
public void build() {
|
||||
try {
|
||||
if (this.node.getType().equals(NodeTypeEnum.COMMON)) {
|
||||
FlowBus.addCommonNode(this.node.getId(), this.node.getName(), this.node.getClazz());
|
||||
} else if (this.node.getType().equals(NodeTypeEnum.SCRIPT)){
|
||||
FlowBus.addCommonScriptNode(this.node.getId(), this.node.getName(), this.node.getScript());
|
||||
} else if (this.node.getType().equals(NodeTypeEnum.COND_SCRIPT)){
|
||||
FlowBus.addCondScriptNode(this.node.getId(), this.node.getName(), this.node.getScript());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errMsg = StrUtil.format("An exception occurred while building the node[{}]", this.node.getId());
|
||||
LOG.error(errMsg, e);
|
||||
throw new NodeBuildException(errMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.yomahub.liteflow.builder;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
|
||||
/**
|
||||
@@ -14,18 +16,36 @@ public class LiteFlowWhenConditionBuilder extends LiteFlowConditionBuilder{
|
||||
super(conditionType);
|
||||
}
|
||||
|
||||
public LiteFlowConditionBuilder setErrorResume(boolean errorResume){
|
||||
public LiteFlowWhenConditionBuilder setErrorResume(boolean errorResume){
|
||||
this.condition.setErrorResume(errorResume);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowConditionBuilder setGroup(String group){
|
||||
this.condition.setGroup(group);
|
||||
public LiteFlowWhenConditionBuilder setErrorResume(String errorResume){
|
||||
if (StrUtil.isBlank(errorResume)){
|
||||
return this;
|
||||
}
|
||||
return setErrorResume(Boolean.parseBoolean(errorResume));
|
||||
}
|
||||
|
||||
public LiteFlowWhenConditionBuilder setGroup(String group){
|
||||
if (StrUtil.isBlank(group)){
|
||||
this.condition.setGroup(LocalDefaultFlowConstant.DEFAULT);
|
||||
}else{
|
||||
this.condition.setGroup(group);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowConditionBuilder setAny(boolean any){
|
||||
public LiteFlowWhenConditionBuilder setAny(boolean any){
|
||||
this.condition.setAny(any);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiteFlowWhenConditionBuilder setAny(String any){
|
||||
if (StrUtil.isBlank(any)){
|
||||
return this;
|
||||
}
|
||||
return setAny(Boolean.parseBoolean(any));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,12 +40,14 @@ public class Chain implements Executable {
|
||||
|
||||
private String chainName;
|
||||
|
||||
private List<Condition> conditionList;
|
||||
|
||||
public Chain(){
|
||||
private List<Condition> conditionList = new ArrayList<>();
|
||||
|
||||
public Chain(String chainName){
|
||||
this.chainName = chainName;
|
||||
}
|
||||
|
||||
public Chain(){}
|
||||
|
||||
public Chain(String chainName, List<Condition> conditionList) {
|
||||
this.chainName = chainName;
|
||||
this.conditionList = conditionList;
|
||||
@@ -94,7 +96,7 @@ public class Chain implements Executable {
|
||||
public void executeFinally(Integer slotIndex) throws Exception {
|
||||
//先把finally的节点过滤出来
|
||||
List<Condition> finallyConditionList = conditionList.stream().filter(condition ->
|
||||
condition.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())).collect(Collectors.toList());
|
||||
condition.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY)).collect(Collectors.toList());
|
||||
for (Condition finallyCondition : finallyConditionList){
|
||||
for(Executable executableItem : finallyCondition.getNodeList()){
|
||||
executableItem.execute(slotIndex);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package com.yomahub.liteflow.entity.flow;
|
||||
|
||||
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -18,7 +19,7 @@ import java.util.List;
|
||||
public class Condition {
|
||||
|
||||
//condition 类型 参数:ConditionTypeEnum 包含:then when
|
||||
private String conditionType;
|
||||
private ConditionTypeEnum conditionType;
|
||||
|
||||
private List<Executable> nodeList;
|
||||
|
||||
@@ -61,11 +62,11 @@ public class Condition {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getConditionType() {
|
||||
public ConditionTypeEnum getConditionType() {
|
||||
return conditionType;
|
||||
}
|
||||
|
||||
public void setConditionType(String conditionType) {
|
||||
public void setConditionType(ConditionTypeEnum conditionType) {
|
||||
this.conditionType = conditionType;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public class Node implements Executable,Cloneable{
|
||||
|
||||
private String name;
|
||||
|
||||
private String tag;
|
||||
private String clazz;
|
||||
|
||||
private NodeTypeEnum type;
|
||||
|
||||
@@ -45,6 +45,8 @@ public class Node implements Executable,Cloneable{
|
||||
|
||||
private NodeComponent instance;
|
||||
|
||||
private String tag;
|
||||
|
||||
private final Map<String, Executable> condNodeMap = new HashMap<>();
|
||||
|
||||
public Node(){
|
||||
@@ -56,6 +58,7 @@ public class Node implements Executable,Cloneable{
|
||||
this.name = instance.getName();
|
||||
this.instance = instance;
|
||||
this.type = instance.getType();
|
||||
this.clazz = instance.getClass().getName();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -204,4 +207,12 @@ public class Node implements Executable,Cloneable{
|
||||
public void setScript(String script) {
|
||||
this.script = script;
|
||||
}
|
||||
|
||||
public String getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public void setClazz(String clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,4 +29,13 @@ public enum ConditionTypeEnum {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static ConditionTypeEnum getEnumByCode(String code) {
|
||||
for (ConditionTypeEnum e : ConditionTypeEnum.values()) {
|
||||
if (e.getType().equals(code)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yomahub.liteflow.exception;
|
||||
|
||||
|
||||
public class EmptyConditionValueException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 异常信息 */
|
||||
private String message;
|
||||
|
||||
public EmptyConditionValueException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yomahub.liteflow.exception;
|
||||
|
||||
|
||||
public class NodeBuildException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 异常信息 */
|
||||
private String message;
|
||||
|
||||
public NodeBuildException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yomahub.liteflow.exception;
|
||||
|
||||
|
||||
public class NotSupportConditionException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 异常信息 */
|
||||
private String message;
|
||||
|
||||
public NotSupportConditionException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.yomahub.liteflow.core.ScriptComponent;
|
||||
import com.yomahub.liteflow.core.ScriptCondComponent;
|
||||
import com.yomahub.liteflow.entity.data.DataBus;
|
||||
import com.yomahub.liteflow.entity.flow.Chain;
|
||||
import com.yomahub.liteflow.entity.flow.Condition;
|
||||
import com.yomahub.liteflow.entity.flow.Node;
|
||||
import com.yomahub.liteflow.enums.FlowParserTypeEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
@@ -38,6 +39,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.SerializationUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -60,7 +62,11 @@ public class FlowBus {
|
||||
}
|
||||
|
||||
public static void addChain(Chain chain) {
|
||||
chainMap.put(chain.getChainName(), chain);
|
||||
if (chainMap.containsKey(chain.getChainName()) && CollectionUtil.isEmpty(chain.getConditionList())){
|
||||
chainMap.get(chain.getChainName()).setConditionList(chain.getConditionList());
|
||||
}else{
|
||||
chainMap.put(chain.getChainName(), chain);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean containChain(String chainId) {
|
||||
|
||||
@@ -27,43 +27,6 @@ public abstract class FlowParser {
|
||||
|
||||
public abstract void parse(List<String> contentList) throws Exception;
|
||||
|
||||
protected void buildConditions(List<Condition> conditionList, Condition condition) {
|
||||
//这里进行合并逻辑
|
||||
//对于then来说,相邻的2个then会合并成一个condition
|
||||
//对于when来说,相同组的when会合并成一个condition,不同组的when还是会拆开
|
||||
if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_PRE.getType())) {
|
||||
conditionList.add(new PreCondition(condition));
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_THEN.getType())) {
|
||||
if (conditionList.size() >= 1 &&
|
||||
CollectionUtil.getLast(conditionList) instanceof ThenCondition) {
|
||||
CollectionUtil.getLast(conditionList).getNodeList().addAll(condition.getNodeList());
|
||||
} else {
|
||||
conditionList.add(new ThenCondition(condition));
|
||||
}
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_WHEN.getType())) {
|
||||
if (conditionList.size() > 1 &&
|
||||
CollectionUtil.getLast(conditionList) instanceof WhenCondition &&
|
||||
CollectionUtil.getLast(conditionList).getGroup().equals(condition.getGroup())) {
|
||||
CollectionUtil.getLast(conditionList).getNodeList().addAll(condition.getNodeList());
|
||||
} else {
|
||||
conditionList.add(new WhenCondition(condition));
|
||||
}
|
||||
} else if (condition.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())) {
|
||||
conditionList.add(new FinallyCondition(condition));
|
||||
}
|
||||
|
||||
//每一次build之后,对conditionList进行排序,pre最前面,finally最后
|
||||
//这里为什么要排序,因为在声明的时候,哪怕有人不把pre放最前,finally放最后,但最终也要确保是正确的顺序
|
||||
CollectionUtil.sort(conditionList, (o1, o2) -> {
|
||||
if (o1.getConditionType().equals(ConditionTypeEnum.TYPE_PRE.getType()) || o2.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())){
|
||||
return -1;
|
||||
} else if (o2.getConditionType().equals(ConditionTypeEnum.TYPE_PRE.getType()) || o1.getConditionType().equals(ConditionTypeEnum.TYPE_FINALLY.getType())){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置的ruleSource查找匹配的资源
|
||||
*/
|
||||
|
||||
@@ -8,18 +8,26 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
|
||||
import com.yomahub.liteflow.builder.LiteFlowConditionBuilder;
|
||||
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
|
||||
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.entity.flow.*;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.EmptyConditionValueException;
|
||||
import com.yomahub.liteflow.exception.ExecutableItemNotFoundException;
|
||||
import com.yomahub.liteflow.exception.NodeTypeNotSupportException;
|
||||
import com.yomahub.liteflow.exception.NotSupportConditionException;
|
||||
import com.yomahub.liteflow.flow.FlowBus;
|
||||
import com.yomahub.liteflow.spring.ComponentScanner;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Json格式解析器
|
||||
@@ -53,171 +61,120 @@ public abstract class JsonFlowParser extends FlowParser {
|
||||
|
||||
//json格式,解析过程
|
||||
public void parseJsonObject(List<JSONObject> flowJsonObjectList) throws Exception {
|
||||
try {
|
||||
for (Map.Entry<String, NodeComponent> componentEntry : ComponentScanner.nodeComponentMap.entrySet()) {
|
||||
if (!FlowBus.containNode(componentEntry.getKey())) {
|
||||
FlowBus.addSpringScanNode(componentEntry.getKey(), componentEntry.getValue());
|
||||
}
|
||||
for (Map.Entry<String, NodeComponent> componentEntry : ComponentScanner.nodeComponentMap.entrySet()) {
|
||||
if (!FlowBus.containNode(componentEntry.getKey())) {
|
||||
FlowBus.addSpringScanNode(componentEntry.getKey(), componentEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
for (JSONObject flowJsonObject : flowJsonObjectList) {
|
||||
// 当存在<nodes>节点定义时,解析node节点
|
||||
if (flowJsonObject.getJSONObject("flow").containsKey("nodes")){
|
||||
JSONArray nodeArrayList = flowJsonObject.getJSONObject("flow").getJSONObject("nodes").getJSONArray("node");
|
||||
String id, name, clazz, script, type, file;
|
||||
for (int i = 0; i < nodeArrayList.size(); i++) {
|
||||
JSONObject nodeObject = nodeArrayList.getJSONObject(i);
|
||||
id = nodeObject.getString("id");
|
||||
name = nodeObject.getString("name");
|
||||
clazz = nodeObject.getString("class");
|
||||
type = nodeObject.getString("type");
|
||||
file = nodeObject.getString("file");
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
flowJsonObjectList.forEach(jsonObject -> {
|
||||
// 解析chain节点
|
||||
JSONArray chainArray = jsonObject.getJSONObject("flow").getJSONArray("chain");
|
||||
|
||||
//初始化type
|
||||
if (StrUtil.isBlank(type)){
|
||||
type = NodeTypeEnum.COMMON.getCode();
|
||||
}
|
||||
NodeTypeEnum nodeTypeEnum = NodeTypeEnum.getEnumByCode(type);
|
||||
if (ObjectUtil.isNull(nodeTypeEnum)){
|
||||
throw new NodeTypeNotSupportException(StrUtil.format("type [{}] is not support", type));
|
||||
}
|
||||
//先在元数据里放上chain
|
||||
chainArray.forEach(o -> {
|
||||
JSONObject innerJsonObject = (JSONObject)o;
|
||||
FlowBus.addChain(new Chain(innerJsonObject.getString("name")));
|
||||
});
|
||||
});
|
||||
|
||||
//这里区分是普通java节点还是脚本节点
|
||||
//如果是脚本节点,又区分是普通脚本节点,还是条件脚本节点
|
||||
if (nodeTypeEnum.equals(NodeTypeEnum.COMMON) && StrUtil.isNotBlank(clazz)){
|
||||
FlowBus.addCommonNode(id, name, clazz);
|
||||
}else if(nodeTypeEnum.equals(NodeTypeEnum.SCRIPT) || nodeTypeEnum.equals(NodeTypeEnum.COND_SCRIPT)){
|
||||
//如果file字段不为空,则优先从file里面读取脚本文本
|
||||
if (StrUtil.isNotBlank(file)){
|
||||
script = ResourceUtil.readUtf8Str(StrUtil.format("classpath: {}", file));
|
||||
}else{
|
||||
script = nodeObject.getString("value");
|
||||
}
|
||||
for (JSONObject flowJsonObject : flowJsonObjectList) {
|
||||
// 当存在<nodes>节点定义时,解析node节点
|
||||
if (flowJsonObject.getJSONObject("flow").containsKey("nodes")){
|
||||
JSONArray nodeArrayList = flowJsonObject.getJSONObject("flow").getJSONObject("nodes").getJSONArray("node");
|
||||
String id, name, clazz, script, type, file;
|
||||
for (int i = 0; i < nodeArrayList.size(); i++) {
|
||||
JSONObject nodeObject = nodeArrayList.getJSONObject(i);
|
||||
id = nodeObject.getString("id");
|
||||
name = nodeObject.getString("name");
|
||||
clazz = nodeObject.getString("class");
|
||||
type = nodeObject.getString("type");
|
||||
script = nodeObject.getString("value");
|
||||
file = nodeObject.getString("file");
|
||||
|
||||
//根据节点类型把脚本添加到元数据里
|
||||
if (nodeTypeEnum.equals(NodeTypeEnum.SCRIPT)){
|
||||
FlowBus.addCommonScriptNode(id, name, script);
|
||||
}else {
|
||||
FlowBus.addCondScriptNode(id, name, script);
|
||||
}
|
||||
}
|
||||
//初始化type
|
||||
if (StrUtil.isBlank(type)){
|
||||
type = NodeTypeEnum.COMMON.getCode();
|
||||
}
|
||||
}
|
||||
|
||||
// 解析chain节点
|
||||
JSONArray chainArray = flowJsonObject.getJSONObject("flow").getJSONArray("chain");
|
||||
for (int i = 0; i < chainArray.size(); i++) {
|
||||
JSONObject jsonObject = chainArray.getJSONObject(i);
|
||||
parseOneChain(jsonObject, flowJsonObjectList);
|
||||
//检查nodeType是不是规定的类型
|
||||
NodeTypeEnum nodeTypeEnum = NodeTypeEnum.getEnumByCode(type);
|
||||
if (ObjectUtil.isNull(nodeTypeEnum)){
|
||||
throw new NodeTypeNotSupportException(StrUtil.format("type [{}] is not support", type));
|
||||
}
|
||||
|
||||
//进行node的build过程
|
||||
LiteFlowNodeBuilder.createNode().setId(id)
|
||||
.setName(name)
|
||||
.setClazz(clazz)
|
||||
.setType(nodeTypeEnum)
|
||||
.setScript(script)
|
||||
.setFile(file)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("JsonFlowParser parser exception", e);
|
||||
throw e;
|
||||
|
||||
//解析每一个chain
|
||||
JSONArray chainArray = flowJsonObject.getJSONObject("flow").getJSONArray("chain");
|
||||
chainArray.forEach(o -> {
|
||||
JSONObject jsonObject = (JSONObject)o;
|
||||
parseOneChain(jsonObject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析一个chain的过程
|
||||
*/
|
||||
private void parseOneChain(JSONObject chainObject, List<JSONObject> flowJsonObjectList) throws Exception {
|
||||
String condArrayStr;
|
||||
String[] condArray;
|
||||
List<Executable> chainNodeList;
|
||||
List<Condition> conditionList = new ArrayList<>();
|
||||
private void parseOneChain(JSONObject chainObject){
|
||||
String condValueStr;
|
||||
ConditionTypeEnum conditionType;
|
||||
String group;
|
||||
String errorResume;
|
||||
Condition condition;
|
||||
String any;
|
||||
|
||||
//构建chainBuilder
|
||||
String chainName = chainObject.getString("name");
|
||||
JSONArray conditionArray = chainObject.getJSONArray("condition");
|
||||
for (Object o : conditionArray) {
|
||||
LiteFlowChainBuilder chainBuilder = LiteFlowChainBuilder.createChain().setChainName(chainName);
|
||||
|
||||
for (Object o : chainObject.getJSONArray("condition")) {
|
||||
JSONObject condObject = (JSONObject) o;
|
||||
String condType = condObject.getString("type");
|
||||
condArrayStr = condObject.getString("value");
|
||||
group = condObject.getString("group");
|
||||
conditionType = ConditionTypeEnum.getEnumByCode(condObject.getString("type"));
|
||||
condValueStr = condObject.getString("value");
|
||||
errorResume = condObject.getString("errorResume");
|
||||
group = condObject.getString("group");
|
||||
any = condObject.getString("any");
|
||||
if (StrUtil.isBlank(condType) || StrUtil.isBlank(condArrayStr)) {
|
||||
continue;
|
||||
}
|
||||
if (StrUtil.isBlank(group)) {
|
||||
group = LocalDefaultFlowConstant.DEFAULT;
|
||||
}
|
||||
if (StrUtil.isBlank(errorResume)) {
|
||||
errorResume = Boolean.FALSE.toString();
|
||||
}
|
||||
if (StrUtil.isBlank(any)){
|
||||
any = Boolean.FALSE.toString();
|
||||
}
|
||||
condition = new Condition();
|
||||
chainNodeList = new ArrayList<>();
|
||||
condArray = condArrayStr.split(",");
|
||||
RegexEntity regexEntity;
|
||||
String itemExpression;
|
||||
RegexNodeEntity item;
|
||||
//这里解析的规则,优先按照node去解析,再按照chain去解析
|
||||
for (int i = 0; i < condArray.length; i++) {
|
||||
itemExpression = condArray[i].trim();
|
||||
regexEntity = RegexEntity.parse(itemExpression);
|
||||
item = regexEntity.getItem();
|
||||
if (FlowBus.containNode(item.getId())) {
|
||||
Node node = FlowBus.copyNode(item.getId());
|
||||
node.setTag(regexEntity.getItem().getTag());
|
||||
chainNodeList.add(node);
|
||||
//这里判断是不是条件节点,条件节点会含有realItem,也就是括号里的node
|
||||
if (regexEntity.getRealItemArray() != null) {
|
||||
for (RegexNodeEntity realItem : regexEntity.getRealItemArray()) {
|
||||
if (FlowBus.containNode(realItem.getId())) {
|
||||
Node condNode = FlowBus.copyNode(realItem.getId());
|
||||
condNode.setTag(realItem.getTag());
|
||||
node.setCondNode(condNode.getId(), condNode);
|
||||
} else if (hasChain(flowJsonObjectList, realItem.getId())) {
|
||||
Chain chain = FlowBus.getChain(realItem.getId());
|
||||
node.setCondNode(chain.getChainName(), chain);
|
||||
} else{
|
||||
String errorMsg = StrUtil.format("executable node[{}] is not found!", realItem.getId());
|
||||
throw new ExecutableItemNotFoundException(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (hasChain(flowJsonObjectList, item.getId())) {
|
||||
Chain chain = FlowBus.getChain(item.getId());
|
||||
chainNodeList.add(chain);
|
||||
} else {
|
||||
String errorMsg = StrUtil.format("executable node[{}] is not found!", regexEntity.getItem().getId());
|
||||
throw new ExecutableItemNotFoundException(errorMsg);
|
||||
}
|
||||
}
|
||||
condition.setErrorResume(Boolean.parseBoolean(errorResume));
|
||||
condition.setGroup(group);
|
||||
condition.setAny(any.equals(Boolean.TRUE.toString()));
|
||||
condition.setConditionType(condType);
|
||||
condition.setNodeList(chainNodeList);
|
||||
|
||||
//这里把condition组装进conditionList,根据参数有些condition要和conditionList里面的某些进行合并操作
|
||||
super.buildConditions(conditionList, condition);
|
||||
}
|
||||
FlowBus.addChain(new Chain(chainName, conditionList));
|
||||
}
|
||||
if (ObjectUtil.isNull(conditionType)){
|
||||
throw new NotSupportConditionException("ConditionType is not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断在这个FlowBus元数据里是否含有这个chain
|
||||
* 因为chain和node都是可执行器,在一个规则文件上,有可能是node,有可能是chain
|
||||
*/
|
||||
private boolean hasChain(List<JSONObject> flowJsonObjectList, String chainName) throws Exception {
|
||||
for (JSONObject jsonObject : flowJsonObjectList) {
|
||||
JSONArray chainArray = jsonObject.getJSONObject("flow").getJSONArray("chain");
|
||||
for (int i = 0; i < chainArray.size(); i++) {
|
||||
JSONObject chainObject = chainArray.getJSONObject(i);
|
||||
if (chainObject.getString("name").equals(chainName) && !FlowBus.containChain(chainName)) {
|
||||
parseOneChain(chainObject, flowJsonObjectList);
|
||||
return true;
|
||||
} else if (FlowBus.containChain(chainName)) {
|
||||
return true;
|
||||
}
|
||||
if (StrUtil.isBlank(condValueStr)) {
|
||||
throw new EmptyConditionValueException("Condition value cannot be empty");
|
||||
}
|
||||
|
||||
|
||||
//如果是when类型的话,有特殊化参数要设置,只针对于when的
|
||||
if (conditionType.equals(ConditionTypeEnum.TYPE_WHEN)){
|
||||
chainBuilder.setCondition(
|
||||
LiteFlowConditionBuilder.createWhenCondition()
|
||||
.setErrorResume(errorResume)
|
||||
.setGroup(group)
|
||||
.setAny(any)
|
||||
.setValue(condValueStr)
|
||||
.build()
|
||||
).build();
|
||||
}else{
|
||||
chainBuilder.setCondition(
|
||||
LiteFlowConditionBuilder.createCondition(conditionType)
|
||||
.setValue(condValueStr)
|
||||
.build()
|
||||
).build();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,18 @@ import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.builder.LiteFlowChainBuilder;
|
||||
import com.yomahub.liteflow.builder.LiteFlowConditionBuilder;
|
||||
import com.yomahub.liteflow.builder.LiteFlowNodeBuilder;
|
||||
import com.yomahub.liteflow.common.LocalDefaultFlowConstant;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.entity.flow.Chain;
|
||||
import com.yomahub.liteflow.entity.flow.Condition;
|
||||
import com.yomahub.liteflow.entity.flow.Executable;
|
||||
import com.yomahub.liteflow.entity.flow.Node;
|
||||
import com.yomahub.liteflow.enums.ConditionTypeEnum;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.CyclicDependencyException;
|
||||
import com.yomahub.liteflow.exception.ExecutableItemNotFoundException;
|
||||
import com.yomahub.liteflow.exception.NodeTypeNotSupportException;
|
||||
import com.yomahub.liteflow.exception.ParseException;
|
||||
import com.yomahub.liteflow.exception.*;
|
||||
import com.yomahub.liteflow.flow.FlowBus;
|
||||
import com.yomahub.liteflow.spring.ComponentScanner;
|
||||
import org.dom4j.Document;
|
||||
@@ -28,10 +29,10 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* xml形式的解析器
|
||||
*
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public abstract class XmlFlowParser extends FlowParser {
|
||||
@@ -63,6 +64,18 @@ public abstract class XmlFlowParser extends FlowParser {
|
||||
}
|
||||
}
|
||||
|
||||
//先在元数据里放上chain
|
||||
//先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析
|
||||
//这样就不用去像之前的版本那样回归调用
|
||||
//同时也解决了不能循环依赖的问题
|
||||
documentList.forEach(document -> {
|
||||
// 解析chain节点
|
||||
List<Element> chainList = document.getRootElement().elements("chain");
|
||||
|
||||
//先在元数据里放上chain
|
||||
chainList.forEach(e -> FlowBus.addChain(new Chain(e.attributeValue("name"))));
|
||||
});
|
||||
|
||||
for (Document document : documentList) {
|
||||
Element rootElement = document.getRootElement();
|
||||
Element nodesElement = rootElement.element("nodes");
|
||||
@@ -75,152 +88,84 @@ public abstract class XmlFlowParser extends FlowParser {
|
||||
name = e.attributeValue("name");
|
||||
clazz = e.attributeValue("class");
|
||||
type = e.attributeValue("type");
|
||||
script = e.getTextTrim();
|
||||
file = e.attributeValue("file");
|
||||
|
||||
//初始化type
|
||||
if (StrUtil.isBlank(type)){
|
||||
type = NodeTypeEnum.COMMON.getCode();
|
||||
}
|
||||
|
||||
//检查nodeType是不是规定的类型
|
||||
NodeTypeEnum nodeTypeEnum = NodeTypeEnum.getEnumByCode(type);
|
||||
if (ObjectUtil.isNull(nodeTypeEnum)){
|
||||
throw new NodeTypeNotSupportException(StrUtil.format("type [{}] is not support", type));
|
||||
}
|
||||
|
||||
//这里区分是普通java节点还是脚本节点
|
||||
//如果是脚本节点,又区分是普通脚本节点,还是条件脚本节点
|
||||
if (nodeTypeEnum.equals(NodeTypeEnum.COMMON) && StrUtil.isNotBlank(clazz)){
|
||||
FlowBus.addCommonNode(id, name, clazz);
|
||||
}else if(nodeTypeEnum.equals(NodeTypeEnum.SCRIPT) || nodeTypeEnum.equals(NodeTypeEnum.COND_SCRIPT)){
|
||||
//如果file字段不为空,则优先从file里面读取脚本文本
|
||||
if (StrUtil.isNotBlank(file)){
|
||||
script = ResourceUtil.readUtf8Str(StrUtil.format("classpath: {}", file));
|
||||
}else{
|
||||
script = e.getTextTrim();
|
||||
}
|
||||
|
||||
//根据节点类型把脚本添加到元数据里
|
||||
if (nodeTypeEnum.equals(NodeTypeEnum.SCRIPT)){
|
||||
FlowBus.addCommonScriptNode(id, name, script);
|
||||
}else {
|
||||
FlowBus.addCondScriptNode(id, name, script);
|
||||
}
|
||||
}
|
||||
//进行node的build过程
|
||||
LiteFlowNodeBuilder.createNode().setId(id)
|
||||
.setName(name)
|
||||
.setClazz(clazz)
|
||||
.setType(nodeTypeEnum)
|
||||
.setScript(script)
|
||||
.setFile(file)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// 解析chain节点
|
||||
//解析每一个chain
|
||||
List<Element> chainList = rootElement.elements("chain");
|
||||
for (Element e : chainList) {
|
||||
parseOneChain(e, documentList);
|
||||
}
|
||||
chainList.forEach(this::parseOneChain);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析一个chain的过程
|
||||
*/
|
||||
private void parseOneChain(Element e, List<Document> documentList) throws Exception {
|
||||
String condArrayStr;
|
||||
String[] condArray;
|
||||
private void parseOneChain(Element e) {
|
||||
String condValueStr;
|
||||
String group;
|
||||
String errorResume;
|
||||
String any;
|
||||
Condition condition;
|
||||
Element condE;
|
||||
List<Executable> chainNodeList;
|
||||
List<Condition> conditionList = new ArrayList<>();
|
||||
ConditionTypeEnum conditionType;
|
||||
|
||||
//构建chainBuilder
|
||||
String chainName = e.attributeValue("name");
|
||||
LiteFlowChainBuilder chainBuilder = LiteFlowChainBuilder.createChain().setChainName(chainName);
|
||||
|
||||
for (Iterator<Element> it = e.elementIterator(); it.hasNext(); ) {
|
||||
condE = it.next();
|
||||
condArrayStr = condE.attributeValue("value");
|
||||
Element condE = it.next();
|
||||
conditionType = ConditionTypeEnum.getEnumByCode(condE.getName());
|
||||
condValueStr = condE.attributeValue("value");
|
||||
errorResume = condE.attributeValue("errorResume");
|
||||
group = condE.attributeValue("group");
|
||||
any = condE.attributeValue("any");
|
||||
if (StrUtil.isBlank(condArrayStr)) {
|
||||
continue;
|
||||
}
|
||||
if (StrUtil.isBlank(group)) {
|
||||
group = LocalDefaultFlowConstant.DEFAULT;
|
||||
}
|
||||
if (StrUtil.isBlank(errorResume)) {
|
||||
errorResume = Boolean.FALSE.toString();
|
||||
}
|
||||
if (StrUtil.isBlank(any)){
|
||||
any = Boolean.FALSE.toString();
|
||||
}
|
||||
condition = new Condition();
|
||||
chainNodeList = new ArrayList<>();
|
||||
condArray = condArrayStr.split(",");
|
||||
RegexEntity regexEntity;
|
||||
String itemExpression;
|
||||
RegexNodeEntity item;
|
||||
//这里解析的规则,优先按照node去解析,再按照chain去解析
|
||||
for (String s : condArray) {
|
||||
itemExpression = s.trim();
|
||||
regexEntity = RegexEntity.parse(itemExpression);
|
||||
item = regexEntity.getItem();
|
||||
if (FlowBus.containNode(item.getId())) {
|
||||
Node node = FlowBus.copyNode(item.getId());
|
||||
node.setTag(regexEntity.getItem().getTag());
|
||||
chainNodeList.add(node);
|
||||
//这里判断是不是条件节点,条件节点会含有realItem,也就是括号里的node
|
||||
if (regexEntity.getRealItemArray() != null) {
|
||||
for (RegexNodeEntity realItem : regexEntity.getRealItemArray()) {
|
||||
if (FlowBus.containNode(realItem.getId())) {
|
||||
Node condNode = FlowBus.copyNode(realItem.getId());
|
||||
condNode.setTag(realItem.getTag());
|
||||
node.setCondNode(condNode.getId(), condNode);
|
||||
} else if (hasChain(documentList, realItem.getId())) {
|
||||
Chain chain = FlowBus.getChain(realItem.getId());
|
||||
node.setCondNode(chain.getChainName(), chain);
|
||||
} else{
|
||||
String errorMsg = StrUtil.format("executable node[{}] is not found!", realItem.getId());
|
||||
throw new ExecutableItemNotFoundException(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (hasChain(documentList, item.getId())) {
|
||||
Chain chain = FlowBus.getChain(item.getId());
|
||||
chainNodeList.add(chain);
|
||||
} else {
|
||||
String errorMsg = StrUtil.format("executable node[{}] is not found!", regexEntity.getItem().getId());
|
||||
throw new ExecutableItemNotFoundException(errorMsg);
|
||||
}
|
||||
}
|
||||
condition.setErrorResume(Boolean.parseBoolean(errorResume));
|
||||
condition.setGroup(group);
|
||||
condition.setAny(any.equals(Boolean.TRUE.toString()));
|
||||
condition.setConditionType(condE.getName());
|
||||
condition.setNodeList(chainNodeList);
|
||||
|
||||
//这里把condition组装进conditionList,根据参数有些condition要和conditionList里面的某些进行合并操作
|
||||
super.buildConditions(conditionList, condition);
|
||||
}
|
||||
FlowBus.addChain(new Chain(chainName, conditionList));
|
||||
}
|
||||
|
||||
//判断在这个FlowBus元数据里是否含有这个chain
|
||||
//因为chain和node都是可执行器,在一个规则文件上,有可能是node,有可能是chain
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean hasChain(List<Document> documentList, String chainName) throws Exception {
|
||||
try{
|
||||
for (Document document : documentList) {
|
||||
List<Element> chainList = document.getRootElement().elements("chain");
|
||||
for (Element ce : chainList) {
|
||||
String ceName = ce.attributeValue("name");
|
||||
if (ceName.equals(chainName)) {
|
||||
if (!FlowBus.containChain(chainName)) {
|
||||
parseOneChain(ce, documentList);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (ObjectUtil.isNull(conditionType)){
|
||||
throw new NotSupportConditionException("ConditionType is not supported");
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(condValueStr)) {
|
||||
throw new EmptyConditionValueException("Condition value cannot be empty");
|
||||
}
|
||||
|
||||
//如果是when类型的话,有特殊化参数要设置,只针对于when的
|
||||
if (conditionType.equals(ConditionTypeEnum.TYPE_WHEN)){
|
||||
chainBuilder.setCondition(
|
||||
LiteFlowConditionBuilder.createWhenCondition()
|
||||
.setErrorResume(errorResume)
|
||||
.setGroup(group)
|
||||
.setAny(any)
|
||||
.setValue(condValueStr)
|
||||
.build()
|
||||
).build();
|
||||
}else{
|
||||
chainBuilder.setCondition(
|
||||
LiteFlowConditionBuilder.createCondition(conditionType)
|
||||
.setValue(condValueStr)
|
||||
.build()
|
||||
).build();
|
||||
}
|
||||
return false;
|
||||
}catch (StackOverflowError e){
|
||||
LOG.error("a cyclic dependency occurs in chain", e);
|
||||
throw new CyclicDependencyException("a cyclic dependency occurs in chain");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user