netflix-conductor-json-tree 的java实现-查看文章

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


验证码: