private static BPMNDiagram removeConnectedGateways(BPMNDiagram diagram) { List<Gateway> XOR = getXORGateways(diagram); Iterator<Flow> iterator = diagram.getFlows().iterator(); while (iterator.hasNext()) { Flow flow = iterator.next(); if (XOR.contains(flow.getSource()) && XOR.contains(flow.getTarget()) && isSplit(diagram, flow.getSource()) && isSplit(diagram, flow.getTarget())) { if (!flow.getSource().equals(flow.getTarget())) { List<Flow> flows = getOutgoingFlows(diagram, flow.getTarget()); for (Flow flow1 : flows) { diagram.addFlow(flow.getSource(), flow1.getTarget(), ""); } diagram.removeGateway((Gateway) flow.getTarget()); XOR = getXORGateways(diagram); } else { diagram.removeEdge(flow); } iterator = diagram.getFlows().iterator(); } } return diagram; }
private static BPMNDiagram mergeActivitiesAfterXOR(BPMNDiagram diagram) { boolean repeat = true; loops: while (repeat) { repeat = false; List<Gateway> gateways = getXORGateways(diagram); for (Gateway gateway : gateways) { List<Activity> activities = getOutgoingActivities(diagram, gateway); for (int i = 0; i < activities.size(); i++) { String label = activities.get(i).getLabel(); for (int j = i + 1; j < activities.size(); j++) { if (activities.get(j).getLabel().equals(label)) { diagram = mergeActivitiesAfterXOR(diagram, gateway, activities.get(i), activities.get(j)); diagram = separateSplitFromJoin(diagram); diagram = removeXORtoAND(diagram); diagram = removeConnectedGateways(diagram); diagram = BPMNSimplifier.removeGatewaysUseless(diagram, diagram.getGateways()); repeat = true; continue loops; } } } } } return diagram; }
public static BPMNDiagram mergeDiagram(BPMNDiagram diagram) { diagram = separateSplitFromJoin(diagram); diagram = removeXORtoAND(diagram); diagram = removeConnectedGateways(diagram); int curr = diagram.getNodes().size() + diagram.getFlows().size(); int size = 0; while (size != curr) { mergeActivitiesAfterXOR(diagram); mergeActivitiesBeforeXOR(diagram); size = curr; curr = diagram.getNodes().size() + diagram.getFlows().size(); } return diagram; }
private static List<Gateway> getANDGateways(BPMNDiagram diagram) { List<Gateway> gateways = new ArrayList<Gateway>(); for (Gateway gateway : diagram.getGateways()) { if (gateway.getGatewayType().equals(Gateway.GatewayType.PARALLEL)) { gateways.add(gateway); } } return gateways; }
private static List<Flow> getOutgoingFlows(BPMNDiagram diagram, BPMNNode bpmnNode) { List<Flow> flows = new ArrayList<Flow>(); for (Flow flow : diagram.getFlows()) { if (flow.getSource().equals(bpmnNode)) { flows.add(flow); } } return flows; }
private static List<Activity> getOutgoingActivities(BPMNDiagram diagram, BPMNNode bpmnNode) { List<Activity> flows = new ArrayList<Activity>(); for (Flow flow : diagram.getFlows()) { if (flow.getSource().equals(bpmnNode) && flow.getTarget() instanceof Activity) { flows.add((Activity) flow.getTarget()); } } return flows; }
private static List<BPMNNode> getIncomingNodes(BPMNDiagram diagram, BPMNNode bpmnNode) { List<BPMNNode> flows = new ArrayList<BPMNNode>(); for (Flow flow : diagram.getFlows()) { if (flow.getTarget().equals(bpmnNode)) { flows.add(flow.getSource()); } } return flows; }
private static BPMNDiagram removeXORtoAND(BPMNDiagram diagram) { List<Gateway> XOR = getXORGateways(diagram); List<Gateway> AND = getANDGateways(diagram); for (Gateway gateway1 : XOR) { for (Gateway gateway2 : AND) { List<Flow> flows = new ArrayList<Flow>(); for (Flow flow : diagram.getFlows()) { if (flow.getSource().equals(gateway1) && flow.getTarget().equals(gateway2)) { flows.add(flow); } } if (flows.size() > 1) { for (int i = 1; i < flows.size(); i++) { diagram.removeEdge(flows.get(i)); } } } } return diagram; }
private static BPMNDiagram separateSplitFromJoin(BPMNDiagram diagram) { Iterator<Gateway> iterator = getXORGateways(diagram).iterator(); while (iterator.hasNext()) { Gateway gateway = iterator.next(); if (isSplit(diagram, gateway) && isJoin(diagram, gateway)) { List<BPMNNode> incoming = getIncomingNodes(diagram, gateway); List<BPMNNode> outgoing = getOutgoingNodes(diagram, gateway); Gateway split = diagram.addGateway("", Gateway.GatewayType.DATABASED); Gateway join = diagram.addGateway("", Gateway.GatewayType.DATABASED); for (BPMNNode node : incoming) { diagram.addFlow(node, join, ""); } for (BPMNNode node : outgoing) { diagram.addFlow(split, node, ""); } diagram.addFlow(join, split, ""); diagram.removeGateway(gateway); iterator = getXORGateways(diagram).iterator(); } } return diagram; }
private static BPMNDiagram mergeActivitiesAfterXOR( BPMNDiagram diagram, Gateway gateway, Activity activity1, Activity activity2) { List<Flow> outgoingFlows1 = getOutgoingFlows(diagram, activity1); List<Flow> outgoingFlows2 = getOutgoingFlows(diagram, activity2); List<Flow> outgoingFlows3 = getOutgoingFlows(diagram, gateway); List<Flow> incomingFlows = getIncomingFlows(diagram, gateway); String label = activity1.getLabel(); Activity activity = diagram.addActivity(label, false, false, false, false, false); Set<BPMNNode> outgoingNodes1 = new UnifiedSet<BPMNNode>(); for (Flow flow : outgoingFlows1) { outgoingNodes1.add(flow.getTarget()); } for (Flow flow : outgoingFlows2) { outgoingNodes1.add(flow.getTarget()); } if (outgoingNodes1.size() > 1) { Gateway gateway1 = diagram.addGateway("", Gateway.GatewayType.DATABASED); Set<BPMNNode> outgoingNodes = new UnifiedSet<BPMNNode>(); for (Flow flow : outgoingFlows1) { if (!outgoingNodes.contains(flow.getTarget())) { outgoingNodes.add(flow.getTarget()); diagram.addFlow(gateway1, flow.getTarget(), ""); } } for (Flow flow : outgoingFlows2) { if (!outgoingNodes.contains(flow.getTarget())) { outgoingNodes.add(flow.getTarget()); diagram.addFlow(gateway1, flow.getTarget(), ""); } } diagram.addFlow(activity, gateway1, ""); } else if (outgoingNodes1.size() > 0) { diagram.addFlow(activity, outgoingNodes1.toArray(new BPMNNode[1])[0], ""); } diagram.removeActivity(activity1); diagram.removeActivity(activity2); if (outgoingFlows3.size() == 2) { for (Flow flow : incomingFlows) { diagram.addFlow(flow.getSource(), activity, ""); } diagram.removeGateway(gateway); } else { diagram.addFlow(gateway, activity, ""); } // if(outgoingNodes.size() == 1) { // BPMNNode node = outgoingNodes.toArray(new BPMNNode[1])[0]; // if(node instanceof Gateway) { // Gateway gateway2 = (Gateway) node; // if(gateway2.getGatewayType().equals(Gateway.GatewayType.DATABASED)) { // List<BPMNNode> list = new ArrayList<BPMNNode>(); // for(Flow flow: diagram.getFlows()) { // if(flow.getSource().equals(gateway2)) { // list.add(flow.getTarget()); // } // } // for(BPMNNode node1 : list) { // diagram.addFlow(activity, node1, ""); // } // diagram.removeGateway(gateway1); // diagram.removeGateway(gateway2); // } // } // } // } return diagram; }
public static void main(String[] args) throws Exception { System.out.println("This is the stand alone version of the BPMNMiner algorithm proposed in:"); System.out.println(); System.out.println("R. Conforti, M. Dumas, L. García-Bañuelos, and M. La Rosa."); System.out.println( "BPMN Miner: Automated discovery of BPMN process models with hierarchical structure."); System.out.println("Information Systems, 56, pp 284-303, 2016."); System.out.println(); System.out.println("For more info contact me at [email protected]"); System.out.println("or visit my website www.raffaeleconforti.com"); Scanner console = new Scanner(System.in); System.out.println("Input file:"); String name = console.nextLine(); while (name.endsWith(" ")) { name = name.substring(0, name.length() - 1); } XFactory factory = new XFactoryMemoryImpl(); XLog log = LogImporter.importFromFile(factory, name); UIPluginContext fakeContext = new FakePluginContext(); BPMNMinerCommandLine plugin = new BPMNMinerCommandLine(); BPMNDiagram diagram = plugin.mineBPMNModel(fakeContext, log); System.out.println("Do you want to structure the diagram? (y/n)"); String token = null; boolean structure = true; while (token == null) { token = console.nextLine(); if (token.equalsIgnoreCase("y")) { structure = true; } else if (token.equalsIgnoreCase("n")) { structure = false; } else { token = null; System.out.println("Accepted input Y or N"); System.out.println("Do you want to structure the diagram? (y/n)"); } } for (Activity activity : diagram.getActivities()) { if (activity.getLabel().endsWith("+complete")) { activity .getAttributeMap() .put( "ProM_Vis_attr_label", activity.getLabel().substring(0, activity.getLabel().indexOf("+complete"))); } } if (structure) { StructuringService ss = new StructuringService(); diagram = ss.structureDiagram(diagram); } if (name.endsWith(".xes")) name = name.substring(0, name.length() - 4); else if (name.endsWith(".xes.gz")) name = name.substring(0, name.length() - 7); else if (name.endsWith(".mxml")) name = name.substring(0, name.length() - 5); else if (name.endsWith(".mxml.gz")) name = name.substring(0, name.length() - 8); System.out.println("Output file: " + name + ".bpmn"); UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); UIContext context = new UIContext(); UIPluginContext uiPluginContext = context.getMainPluginContext(); BpmnDefinitions.BpmnDefinitionsBuilder definitionsBuilder = new BpmnDefinitions.BpmnDefinitionsBuilder(uiPluginContext, diagram); BpmnDefinitions definitions = new BpmnDefinitions("definitions", definitionsBuilder); StringBuilder sb = new StringBuilder(); sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\"\n " + "xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\"\n " + "xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\"\n " + "xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\"\n " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n " + "targetNamespace=\"http://www.omg.org/bpmn20\"\n " + "xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\">"); sb.append(definitions.exportElements()); sb.append("</definitions>"); FileWriter fileWriter = new FileWriter(new File(name + ".bpmn")); fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); }