From e55dbb42e12a86826aea13d80ff2dce2c998474c Mon Sep 17 00:00:00 2001 From: zy <953725892@qq.com> Date: Mon, 18 Sep 2023 20:37:25 +0800 Subject: [PATCH] =?UTF-8?q?feat=20#I7SVZF=20=E5=AE=9E=E7=8E=B0XML=E4=B8=AD?= =?UTF-8?q?Chain=E7=9A=84=E6=8A=BD=E8=B1=A1=E7=BB=A7=E6=89=BF=E5=85=B3?= =?UTF-8?q?=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/common/ChainConstant.java | 4 + .../liteflow/parser/helper/ParserHelper.java | 83 ++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java b/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java index 7379f26ea..a550a5c41 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/common/ChainConstant.java @@ -84,4 +84,8 @@ public interface ChainConstant { String MAX_WAIT_SECONDS = "maxWaitSeconds"; + String ABSTRACT = "abstract"; + + String EXTENDS = "extends"; + } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java index eb239f76f..afc7b2cc1 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/parser/helper/ParserHelper.java @@ -15,6 +15,7 @@ import org.dom4j.Element; import java.util.*; import java.util.function.Consumer; +import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.yomahub.liteflow.common.ChainConstant.*; @@ -127,6 +128,10 @@ public class ParserHelper { public static void parseChainDocument(List documentList, Set chainNameSet, Consumer parseOneChainConsumer) { + //用于存放抽象chain的map + Map abstratChainMap = new HashMap<>(); + //用于存放已经解析过的实现chain + Set implChainSet = new HashSet<>(); // 先在元数据里放上chain // 先放有一个好处,可以在parse的时候先映射到FlowBus的chainMap,然后再去解析 // 这样就不用去像之前的版本那样回归调用 @@ -147,6 +152,9 @@ public class ParserHelper { } FlowBus.addChain(chainName); + if(e.attributeValue(ABSTRACT) != null && e.attributeValue(ABSTRACT).equals("true")){ + abstratChainMap.put(chainName,e); + } }); }); // 清空 @@ -156,7 +164,22 @@ public class ParserHelper { for (Document document : documentList) { Element rootElement = document.getRootElement(); List chainList = rootElement.elements(CHAIN); - chainList.forEach(parseOneChainConsumer); + //先对继承自抽象Chain的chain进行字符串替换 + chainList.stream() + .filter(e -> e.attributeValue(EXTENDS)!=null) + .forEach(e->{ + String baseChainId = e.attributeValue(EXTENDS); + if(abstratChainMap.containsKey(baseChainId)) { + Element baseChain = abstratChainMap.get(baseChainId); + parseImplChain(baseChain,e,abstratChainMap,implChainSet); + }else{ + throw new ChainNotFoundException(String.format("[abstract chain not found] chainName=%s", baseChainId)); + } + }); + //对所有非抽象chain进行解析 + chainList.stream() + .filter(e -> e.attributeValue(ABSTRACT)==null || e.attributeValue(ABSTRACT).equals("false")) + .forEach(parseOneChainConsumer); } } @@ -265,11 +288,45 @@ public class ParserHelper { } } + /** + * 解析一个继承自baseChain的implChain + * @param baseChain 父Chain + * @param implChain 实现Chain + * @param abstractChainMap 所有的抽象Chain + * @param implChainSet 已经解析过的实现Chain + */ + private static void parseImplChain(Element baseChain,Element implChain,Map abstractChainMap,Set implChainSet) { + //如果已经解析过了,就不再解析 + if(implChainSet.contains(implChain)) return; + //如果baseChainId也是继承自其他的chain,需要递归解析 + if(baseChain.attributeValue(EXTENDS)!=null){ + String pBaseChainId = baseChain.attributeValue(EXTENDS); + if(abstractChainMap.containsKey(pBaseChainId)) { + Element pBaseChain = abstractChainMap.get(pBaseChainId); + parseImplChain(pBaseChain, baseChain, abstractChainMap, implChainSet); + }else{ + throw new ChainNotFoundException(String.format("[abstract chain not found] chainName=%s", pBaseChainId)); + } + } + //否则根据baseChainId解析implChainId + String implChainEl = implChain.getText(); + String baseChainEl = baseChain.getText(); + //替换baseChainId中的implChainId + // 使用正则表达式匹配占位符并替换 + String parsedEl = RegexUtil.replaceAbstractChain(baseChainEl,implChainEl); + implChain.setText(parsedEl); + implChainSet.add(implChain); + } + private static class RegexUtil { // java 注释的正则表达式 private static final String REGEX_COMMENT = "(?