netflix-conductor-json-tree 的java实现
发表于:2022-11-09 11:51:39 分类:JAVA 阅读:491次
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author ERSREDMA * @date created at 10:14 2022/11/9 */ public class ProcessModelReader { private final Map<String, List<Map<String,Object>>> source; private List<Map<String,Object>> nodes; private List<Map<String,Object>> edges; private NodeInfo startNode; private NodeInfo endNode; private ModelResult modelResult; private Map<String,NodeInfo> nodeMap = new HashMap<>(); public ProcessModelReader(Map<String, List<Map<String,Object>>> source) { this.source = source; this.nodes = source.get("nodes"); this.edges = source.get("edges"); } public static void main(String[] args) { String json = "{\"nodes\":[{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"endNode\",\"shape\":\"end-node\",\"size\":\"48*48\",\"color\":\"#1890FF\",\"label\":\"结束\",\"name\":\"end\",\"x\":1103.015625,\"y\":299,\"id\":\"88786c7d\",\"index\":3,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"end\",\"childProcess\":\"666\",\"taskActions\":[\"see\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"node\",\"shape\":\"rect-node\",\"size\":\"112*48\",\"label\":\"用户任务6\",\"name\":\"regular\",\"color\":\"#1890FF\",\"x\":632.515625,\"y\":183,\"id\":\"c5fdac2c\",\"index\":8,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"renwu6\",\"childProcess\":\"666\",\"userId\":\"985842828292653056\",\"taskActions\":[\"countersign\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"node\",\"shape\":\"rect-node\",\"size\":\"112*48\",\"label\":\"用户任务5\",\"name\":\"regular\",\"color\":\"#1890FF\",\"x\":443.515625,\"y\":420.5,\"id\":\"88d39d4f\",\"index\":11,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"renwu5\",\"childProcess\":\"666\",\"userId\":\"985842828292653056\",\"taskActions\":[\"see\",\"return\",\"countersign\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"node\",\"shape\":\"rect-node\",\"size\":\"112*48\",\"label\":\"测试\",\"name\":\"regular\",\"color\":\"#1890FF\",\"x\":231.015625,\"y\":282.5,\"id\":\"050c5e9c\",\"index\":12,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"renwu1\",\"childProcess\":\"666\",\"userId\":\"985842828292653056\",\"taskActions\":[\"see\",\"return\",\"countersign\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"startNode\",\"shape\":\"start-node\",\"size\":\"48*48\",\"color\":\"#1890FF\",\"label\":\"开始\",\"name\":\"start\",\"x\":46.212056145280656,\"y\":288.5,\"id\":\"d2ee386d\",\"index\":13,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"start\",\"childProcess\":\"666\",\"taskActions\":[\"see\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"shape\":\"flow-rhombus\",\"nodetype\":\"only-node\",\"size\":\"112*48\",\"color\":\"#1890FF\",\"label\":\"分支\",\"name\":\"regular\",\"x\":442.015625,\"y\":288.5,\"id\":\"e5afc5d0\",\"index\":14,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"fenzhi\",\"childProcess\":\"666\",\"taskActions\":[\"see\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"node\",\"shape\":\"rect-node\",\"size\":\"112*48\",\"label\":\"用户任务3\",\"name\":\"regular\",\"color\":\"#1890FF\",\"x\":644.0002745462446,\"y\":420.5,\"id\":\"40cf04ba\",\"index\":15,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"renwu3\",\"childProcess\":\"666\",\"userId\":\"985842828292653056\",\"taskActions\":[\"see\",\"return\",\"revoke\",\"countersign\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"node\",\"shape\":\"rect-node\",\"size\":\"112*48\",\"label\":\"指定节点回退\",\"name\":\"regular\",\"color\":\"#1890FF\",\"x\":891.9542231849778,\"y\":420.5,\"id\":\"f38e9dec\",\"index\":16,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"renweu6\",\"childProcess\":\"666\",\"userId\":\"985842828292653056\",\"taskActions\":[\"return\",\"returnbycode\"]},{\"v-05d465ce\":\"\",\"type\":\"node\",\"nodetype\":\"node\",\"shape\":\"rect-node\",\"size\":\"112*48\",\"label\":\"用户任务9\",\"name\":\"regular\",\"color\":\"#1890FF\",\"x\":828.015625,\"y\":183,\"id\":\"8e92e886\",\"index\":17,\"style\":{\"fill\":\"#fff\",\"stroke\":\"#000\"},\"code\":\"renwu4\",\"childProcess\":\"666\",\"taskActions\":[\"revoke\",\"termination\"],\"userId\":\"985842828292653056\"}],\"edges\":[{\"source\":\"d2ee386d\",\"sourceAnchor\":1,\"target\":\"050c5e9c\",\"targetAnchor\":3,\"id\":\"0485d1c3\",\"index\":0,\"shape\":\"flow-polyline\"},{\"source\":\"050c5e9c\",\"sourceAnchor\":1,\"target\":\"e5afc5d0\",\"targetAnchor\":3,\"id\":\"bad54296\",\"index\":1,\"shape\":\"flow-polyline\"},{\"source\":\"c5fdac2c\",\"sourceAnchor\":1,\"target\":\"8e92e886\",\"targetAnchor\":3,\"id\":\"53199848\",\"index\":2,\"shape\":\"flow-polyline\"},{\"source\":\"8e92e886\",\"sourceAnchor\":1,\"target\":\"88786c7d\",\"targetAnchor\":3,\"id\":\"7739f5e7\",\"index\":4,\"shape\":\"flow-polyline\"},{\"source\":\"f38e9dec\",\"sourceAnchor\":1,\"target\":\"88786c7d\",\"targetAnchor\":2,\"id\":\"3f48bc4a\",\"index\":5,\"shape\":\"flow-polyline\"},{\"source\":\"40cf04ba\",\"sourceAnchor\":1,\"target\":\"f38e9dec\",\"targetAnchor\":3,\"id\":\"4bdd67e5\",\"index\":6,\"shape\":\"flow-polyline\"},{\"source\":\"e5afc5d0\",\"sourceAnchor\":1,\"target\":\"c5fdac2c\",\"targetAnchor\":3,\"id\":\"54c81c81\",\"index\":7,\"shape\":\"flow-polyline\",\"label\":\"修改\",\"expression\":\"subProces==0\"},{\"source\":\"e5afc5d0\",\"sourceAnchor\":2,\"target\":\"88d39d4f\",\"targetAnchor\":0,\"id\":\"725da4b5\",\"index\":9,\"shape\":\"flow-polyline\",\"label\":\"不修改\",\"expression\":\"subProces==1\"},{\"source\":\"88d39d4f\",\"sourceAnchor\":1,\"target\":\"40cf04ba\",\"targetAnchor\":3,\"id\":\"7d2319b2\",\"index\":10,\"shape\":\"flow-polyline\"}]}"; ObjectMapper mapper = new ObjectMapper(); Map<String, List<Map<String,Object>>> data; try { data = mapper.readValue(json, Map.class); } catch (Exception e) { throw new RuntimeException("解析模型失败:" + e.getMessage()); } ProcessModelReader processModelReader = new ProcessModelReader(data); ModelResult result = processModelReader.createdModelResult(); System.out.println(result); } public ModelResult createdModelResult(){ initNodeMap(); findStartAndEnd(); ModelResult result = new ModelResult(); this.modelResult = result; result.setLabel(startNode.label); result.setSteps(new ArrayList<>()); for (EdgeInfo item : startNode.out) { if (item.target.out.size() == 1) { // 服务节点 serviceNodeHandle(item.target, result.steps); }else if (item.target.out.size() > 1) { // 条件节点 result.steps.add(conditionNodeHandle(item.target)); } } return result; } public void initNodeMap(){ for (Map<String, Object> edge : edges) { String sourceNodeId = edge.get("source").toString(); // 源节点ID String targetNodeId = edge.get("target").toString(); // 目标节点ID NodeInfo sourceNode = nodeMap.get(sourceNodeId); if(sourceNode==null){ sourceNode = NodeInfo.create(sourceNodeId, this); nodeMap.put(sourceNodeId,sourceNode); } NodeInfo targetNode = nodeMap.get(targetNodeId); if(targetNode==null){ targetNode = NodeInfo.create(targetNodeId, this); nodeMap.put(targetNodeId,targetNode); } EdgeInfo edgeOut = new EdgeInfo(); edgeOut.setEdge(edge); edgeOut.setTarget(targetNode); sourceNode.out.add(edgeOut); EdgeInfo edgeIn = new EdgeInfo(); edgeIn.setEdge(edge); edgeIn.setSource(sourceNode); targetNode.in.add(edgeIn); } } public void findStartAndEnd(){ for (NodeInfo value : nodeMap.values()) { if(value.in.size()==0){ this.startNode = value; }else if(value.out.size()==0){ this.endNode = value; } } } private void serviceNodeHandle(NodeInfo node, List<NodeResult> context) { NodeResult res = new NodeResult(); res.setLabel(node.getLabel()); res.setType("service"); context.add(res); NodeInfo nextNode = node.out.get(0).target; // 服务节点 if (nextNode.out.size() == 1) { serviceNodeHandle(nextNode, context); } // 条件节点 if (nextNode.out.size() > 1) { context.add(conditionNodeHandle(nextNode)); } } private NodeResult conditionNodeHandle(NodeInfo node) { NodeResult res = new NodeResult(); res.setLabel(node.getLabel()); res.setType("condition"); Map<String,List<NodeResult>> decisionCases= new HashMap<>(); res.setDecisionCases(decisionCases); for (int i = 0; i < node.out.size(); i++) { EdgeInfo next = node.out.get(i); List<NodeResult> value = new ArrayList<>(); decisionCases.put(next.edge.get("label").toString(), value); if(next.target.out.size()==1){ serviceNodeHandle(next.target,value); } if(next.target.out.size()>1){ value.add(conditionNodeHandle(next.target)); } } return res; } public static class NodeInfo{ private String id; private String label; private List<EdgeInfo> out; private List<EdgeInfo> in; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public List<EdgeInfo> getOut() { return out; } public void setOut(List<EdgeInfo> out) { this.out = out; } public List<EdgeInfo> getIn() { return in; } public void setIn(List<EdgeInfo> in) { this.in = in; } public static NodeInfo create(String id, ProcessModelReader reader){ for (Map<String, Object> node : reader.nodes) { String nodeId = node.get("id").toString(); if(id.equals(nodeId)){ NodeInfo find = new NodeInfo(); find.setId(id); find.setLabel(node.get("label").toString()); find.setIn(new ArrayList<>()); find.setOut(new ArrayList<>()); return find; } } throw new RuntimeException("未找到指定ID为"+id+"的元素"); } } public static class EdgeInfo{ private Map<String,Object> edge; private NodeInfo source; private NodeInfo target; public Map<String, Object> getEdge() { return edge; } public void setEdge(Map<String, Object> edge) { this.edge = edge; } public NodeInfo getSource() { return source; } public void setSource(NodeInfo source) { this.source = source; } public NodeInfo getTarget() { return target; } public void setTarget(NodeInfo target) { this.target = target; } } public static class NodeResult{ private String label; private String type; private Map<String,List<NodeResult>> decisionCases; public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getType() { return type; } public void setType(String type) { this.type = type; } public Map<String, List<NodeResult>> getDecisionCases() { return decisionCases; } public void setDecisionCases(Map<String, List<NodeResult>> decisionCases) { this.decisionCases = decisionCases; } @Override public String toString() { ObjectMapper mapper = new ObjectMapper(); try { return mapper.writeValueAsString(this); } catch (JsonProcessingException e) { e.printStackTrace(); } return ""; } } public static class ModelResult{ private String label; private List<NodeResult> steps; private Map<String,Object> outputParams; public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public List<NodeResult> getSteps() { return steps; } public void setSteps(List<NodeResult> steps) { this.steps = steps; } public Map<String, Object> getOutputParams() { return outputParams; } public void setOutputParams(Map<String, Object> outputParams) { this.outputParams = outputParams; } @Override public String toString() { ObjectMapper mapper = new ObjectMapper(); try { return mapper.writeValueAsString(this); } catch (JsonProcessingException e) { e.printStackTrace(); } return ""; } } }
关键词:bpm,model