UNPKG

pm4js

Version:

Process Mining for Javascript

131 lines (116 loc) 4.43 kB
class WfNetToBpmnConverter { static uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } static nodeUuid() { let uuid = WfNetToBpmnConverter.uuidv4(); return "id"+uuid.replace(/-/g, ""); } static apply(acceptingPetriNet) { let bpmnGraph = new BpmnGraph(WfNetToBpmnConverter.nodeUuid()); let enteringDictio = {}; let exitingDictio = {}; for (let placeId in acceptingPetriNet.net.places) { let place = acceptingPetriNet.net.places[placeId]; let node = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); node.type = "exclusiveGateway"; enteringDictio[place] = node; exitingDictio[place] = node; } for (let transId in acceptingPetriNet.net.transitions) { let trans = acceptingPetriNet.net.transitions[transId]; if (trans.label == null) { let node = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); if (Object.keys(trans.inArcs).length > 1 || Object.keys(trans.outArcs).length > 1) { node.type = "parallelGateway"; } else { node.type = "exclusiveGateway"; } enteringDictio[trans] = node; exitingDictio[trans] = node; } else { let enteringNode = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); let exitingNode = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); let task = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); if (Object.keys(trans.inArcs).length > 1) { enteringNode.type = "parallelGateway"; } else { enteringNode.type = "exclusiveGateway"; } if (Object.keys(trans.outArcs).length > 1) { exitingNode.type = "parallelGateway"; } else { exitingNode.type = "exclusiveGateway"; } task.type = "task"; task.name = trans.label; let edge = bpmnGraph.addEdge(WfNetToBpmnConverter.nodeUuid()); edge.setSource(enteringNode); edge.setTarget(task); edge = bpmnGraph.addEdge(WfNetToBpmnConverter.nodeUuid()); edge.setSource(task); edge.setTarget(exitingNode); enteringDictio[trans] = enteringNode; exitingDictio[trans] = exitingNode; } } for (let arcId in acceptingPetriNet.net.arcs) { let arc = acceptingPetriNet.net.arcs[arcId]; let edge = bpmnGraph.addEdge(WfNetToBpmnConverter.nodeUuid()); edge.setSource(exitingDictio[arc.source]); edge.setTarget(enteringDictio[arc.target]); } let startNode = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); let endNode = bpmnGraph.addNode(WfNetToBpmnConverter.nodeUuid()); startNode.type = "startEvent"; endNode.type = "endEvent"; for (let placeId in acceptingPetriNet.im.tokens) { let place = acceptingPetriNet.net.places[placeId]; let edge = bpmnGraph.addEdge(WfNetToBpmnConverter.nodeUuid()); edge.setSource(startNode); edge.setTarget(enteringDictio[place]); } for (let placeId in acceptingPetriNet.fm.tokens) { let place = acceptingPetriNet.net.places[placeId]; let edge = bpmnGraph.addEdge(WfNetToBpmnConverter.nodeUuid()); edge.setSource(exitingDictio[place]); edge.setTarget(endNode); } // reduction let changed = true; while (changed) { changed = false; let nodes = Object.keys(bpmnGraph.nodes); for (let nodeId of nodes) { let node = bpmnGraph.nodes[nodeId]; if (node.type == "exclusiveGateway" && Object.keys(node.incoming).length == 1 && Object.keys(node.outgoing).length == 1) { let leftNode = bpmnGraph.edges[Object.keys(node.incoming)[0]].source; let rightNode = bpmnGraph.edges[Object.keys(node.outgoing)[0]].target; bpmnGraph.removeNode(node.id); let newEdge = bpmnGraph.addEdge(WfNetToBpmnConverter.nodeUuid()); newEdge.setSource(leftNode); newEdge.setTarget(rightNode); changed = true; } } } Pm4JS.registerObject(bpmnGraph, "BPMN graph (converted from accepting Petri net)"); return bpmnGraph; } } try { module.exports = {WfNetToBpmnConverter: WfNetToBpmnConverter}; global.WfNetToBpmnConverter = WfNetToBpmnConverter; } catch (err) { //console.log(err); // not in Node } Pm4JS.registerAlgorithm("WfNetToBpmnConverter", "apply", ["AcceptingPetriNet"], "BpmnGraph", "Convert WF-NET to BPMN graph", "Alessandro Berti");