All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jbpt.pm.ProcessModel Maven / Gradle / Ivy

Go to download

The jBPT code library is a compendium of technologies that support research on design, execution, and evaluation of business processes.

There is a newer version: 0.3.1
Show newest version
package org.jbpt.pm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jbpt.algo.graph.DirectedGraphAlgorithms;
import org.jbpt.algo.graph.GraphAlgorithms;
import org.jbpt.graph.abs.AbstractDirectedGraph;
import org.jbpt.hypergraph.abs.IVertex;
import org.jbpt.hypergraph.abs.Vertex;
import org.jbpt.petri.PetriNet;
import org.jbpt.petri.Place;
import org.jbpt.petri.Transition;


/**
 * Basic process model implementation
 * 
 * @author Artem Polyvyanyy, Tobias Hoppe, Cindy F?hnrich, Andreas Meyer
 */
public class ProcessModel extends AbstractDirectedGraph, FlowNode> implements IProcessModel, FlowNode, NonFlowNode> {

	private DirectedGraphAlgorithms, FlowNode> directedGraphAlgorithms = new DirectedGraphAlgorithms, FlowNode>();
	
	private GraphAlgorithms, FlowNode> graphAlgorithms = new GraphAlgorithms, FlowNode>();
	
	protected Set nonFlowNodes = new HashSet();

	/**
	 * Construct an empty process
	 */
	public ProcessModel() {
	}
	
	/**
	 * Construct an empty process with the given name
	 * @param name of the process
	 */
	public ProcessModel(String name) {
		setName(name);
	}

	@Override
	public ControlFlow addControlFlow(FlowNode from, FlowNode to) {
		return addControlFlow(from, to, 1f);
	}
	
	@Override
	public ControlFlow addControlFlow(FlowNode from, FlowNode to, float probability) {
		if (from == null || to == null) {
			return null;
		}
		from.setModel(this);
		to.setModel(this);
		
		Collection ss = new ArrayList();
		ss.add(from);
		Collection ts = new ArrayList();
		ts.add(to);
		
		if (!this.checkEdge(ss, ts)) return null;
		
		return new ControlFlow(this, from, to, probability);
	}
	
	@Override
	public ControlFlow addEdge(FlowNode from, FlowNode to) {
		return addControlFlow(from, to);
	}
	
	@Override
	public FlowNode addFlowNode(FlowNode obj) {
		obj.setModel(this);
		return super.addVertex(obj);
	}

	@Override
	@Deprecated
	public Gateway addGateway(Gateway gateway) {
		return (Gateway) this.addFlowNode(gateway);
	}

	@Override
	public NonFlowNode addNonFlowNode(NonFlowNode obj) {
		return (this.nonFlowNodes.add(obj)) ? obj : null;
	}

	/**
	 * Add activity to the process
	 * @param task {@link Activity} to add
	 * @return {@link Activity} that was added to the process, null upon failure
	 */
	@Deprecated
	public Activity addTask(Activity task) {
		return (Activity) this.addFlowNode(task);
	}
	
	@Override
	public ProcessModel clone(){
		ProcessModel clone = (ProcessModel) super.clone();
		
		// clear algorithm class
		clone.clearMembers();
		
		// workaround since abstract graph notifier is not cloned
		clone.removeVertices(clone.getVertices());
		clone.removeEdges(clone.getEdges());
		
		Map nodeCopies = new HashMap();
		
		for (FlowNode n : this.getVertices()) {
			FlowNode c = n.clone();
			clone.addFlowNode(c);
			nodeCopies.put(n, c);
		}
		
		for (ControlFlow f : this.getControlFlow()) {
			FlowNode from = nodeCopies.get(f.getSource());
			FlowNode to = nodeCopies.get(f.getTarget());
			clone.addControlFlow(from, to);
		}
		
		clone.nonFlowNodes = new HashSet();
		for (NonFlowNode node : this.nonFlowNodes){
			clone.nonFlowNodes.add((NonFlowNode) node.clone());
		}
		return clone;
	}
	
	@Override
	public boolean contains(Vertex modelElement){
		return this.vertices.containsKey(modelElement) || this.nonFlowNodes.contains(modelElement);
	}

	@Override
	public boolean containsAllTypes(Collection> classes) {
		if (classes == null) {
			return false;
		}
		for (Class clazz : classes) {
			boolean result = containsType(clazz);
			if (!result) {
				return false;
			}
		}
		return true;
	}
	
	@Override
	public boolean containsType(Class clazz) {
		if (clazz == null) {
			return false;
		}
		for (IVertex flowNode : this.vertices.keySet()) {
			if (clazz.isInstance(flowNode)) {
				return true;
			}
		}
		for (IVertex nonFlowNode : this.nonFlowNodes) {
			if (clazz.isInstance(nonFlowNode)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public Collection filter(Class clazz) {
		Collection result = new ArrayList();
		for (IVertex flowNode : this.vertices.keySet()){	
			if (clazz.isInstance(flowNode)){
				result.add((Vertex) flowNode);
			}
		}
		for (IVertex nonFlowNode : this.nonFlowNodes){
			if (clazz.isInstance(nonFlowNode)){
				result.add((Vertex) nonFlowNode);
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getActivities() {
		return (Collection) this.filter(Activity.class);
	}

	@Override
	public Collection> getControlFlow() {
		return this.getEdges();
	}

	@Override
	public Collection getDataNodes() {
		Collection dataNodes = new ArrayList();
		for (NonFlowNode node : this.nonFlowNodes){
			if (node instanceof DataNode){
				dataNodes.add((DataNode) node);
			}
		}
		return dataNodes;
	}

	@Override
	public Collection getEntries() {
		return (Collection) directedGraphAlgorithms.getSources(this);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getEvents() {
		return (Collection) this.filter(Event.class);
	}

	@Override
	public Collection getExits() {
		return (Collection) directedGraphAlgorithms.getSinks(this);
	}

	@Override
	public Collection getFlowNodes() {
		return (Collection) super.getVertices();
	}

	@Override
	public Collection getFlowNodes(NonFlowNode obj) {
		Set result = new HashSet();
		result.addAll(this.getInputFlowNodes(obj));
		result.addAll(this.getOutputFlowNodes(obj));
		return new ArrayList(result);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getGateways() {
		return (Collection) this.filter(Gateway.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getGateways(Class type) {
		return (Collection) this.filter(type);		
	}

	@Override
	public Collection> getIncomingControlFlow(FlowNode obj) {
		return super.getIncomingEdges(obj);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getInputFlowNodes(NonFlowNode obj) {
		Set result = new HashSet();
		//given node is part of this graph
		if (this.nonFlowNodes.contains(obj)){
			if (obj instanceof IDataNode){
				//31.07.2012 Temporary Remove
				//result.addAll((Collection) ((IDataNode) obj).getWritingFlowNodes());
				//result.addAll((Collection) ((IDataNode) obj).getUnspecifiedFlowNodes());
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getInputNonFlowNodes(FlowNode obj) {
		Set result = new HashSet();
		//31.07.2012 Temporary Remove
		//result.addAll((Collection) obj.getReadDocuments());
		//result.addAll((Collection) obj.getUnspecifiedDocuments());
		//result.addAll((Collection) obj.getResources());
		return result;
	}

	@Override
	public Collection getNonFlowNodes() {
		return new ArrayList(this.nonFlowNodes);
	}

	@Override
	public Collection getNonFlowNodes(FlowNode obj) {
		Set result = new HashSet();
		result.addAll(this.getInputNonFlowNodes(obj));
		result.addAll(this.getOutputNonFlowNodes(obj));
		return new ArrayList(result);
	}

	@Override
	public Collection> getOutgoingControlFlow(FlowNode obj) {
		return this.getOutgoingEdges(obj);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getOutputFlowNodes(NonFlowNode obj) {
		Set result = new HashSet();
		//given node part of this graph?
		//31.07.2012 Temporary Remove
		//		if (this.nonFlowNodes.contains(obj)){
//			if (obj instanceof IDataNode){
//				result.addAll((Collection) ((IDataNode) obj).getReadingFlowNodes());
//				result.addAll((Collection) ((IDataNode) obj).getUnspecifiedFlowNodes());
//			}
//		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection getOutputNonFlowNodes(FlowNode obj) {
		Set result = new HashSet();
		//31.07.2012 Temporary Remove
		//result.addAll((Collection) obj.getWriteDocuments());
		//result.addAll((Collection) obj.getUnspecifiedDocuments());
		//result.addAll((Collection) obj.getResources());
		return result;
	}

	@Override
	public boolean isConnected(){
		return graphAlgorithms.isConnected(this);
	}

	@Override
	public ControlFlow removeControlFlow(ControlFlow flow) {
		return this.removeEdge(flow)!=null ? flow : null;
	}
	
	@Override
	public Collection> removeControlFlows(Collection> flows) {
		return this.removeEdges(flows);
	}
	
	@Override
	public FlowNode removeFlowNode(FlowNode obj) {
		return super.removeVertex(obj);
	}

	@Override
	@Deprecated
	public Gateway removeGateway(Gateway gateway) {
		return (Gateway) this.removeFlowNode(gateway);
	}
	
	@Override
	public NonFlowNode removeNonFlowNode(NonFlowNode obj) {
		return this.nonFlowNodes.remove(obj) ? obj : null;
	}

	@Override
	@Deprecated
	public Activity removeTask(Activity task) {
		return (Activity) this.removeFlowNode(task);
	}
	
	@Override
	public String toDOT() {
		String result = "";
		if (this == null) {
			return result;
		}
		
		result += "digraph G {\n";
		result += "rankdir=LR \n"; //rankdir=LR for left to right graph; rankdir=TD for top to down graph
		
		for (Event e : this.getEvents()) {
			result += String.format("  n%s[shape=ellipse,label=\"%s\"];\n", e.getId().replace("-", ""), e.getName());
		}
		result+="\n";
		
		for (Activity a : this.getActivities()) {
			result += String.format("  n%s[shape=box,label=\"%s\"];\n", a.getId().replace("-", ""), a.getName());
		}
		result+="\n";
		
		for (Gateway g : this.getGateways(AndGateway.class)) {
			result += String.format("  n%s[shape=diamond,label=\"%s\"];\n", g.getId().replace("-", ""), "AND");
		}
		for (Gateway g : this.getGateways(XorGateway.class)) {
			result += String.format("  n%s[shape=diamond,label=\"%s\"];\n", g.getId().replace("-", ""), "XOR");
		}
		for (Gateway g : this.getGateways(OrGateway.class)) {
			result += String.format("  n%s[shape=diamond,label=\"%s\"];\n", g.getId().replace("-", ""), "OR");
		}
		for (Gateway g : this.getGateways(AlternativGateway.class))
			result += String.format("  n%s[shape=diamond,label=\"%s\"];\n", g.getId().replace("-", ""), "?");
		result+="\n";
		
		for (DataNode d : this.getDataNodes()) {
			result += String.format("  n%s[shape=note,label=\"%s\"];\n", d.getId().replace("-", ""), d.getName().concat(" [" + d.getState() + "]"));
		}
		result+="\n";
		
		for (ControlFlow cf: this.getControlFlow()) {
			if (cf.getLabel()!=null && cf.getLabel()!="")
				result += String.format("  n%s->n%s[label=\"%s\"];\n", cf.getSource().getId().replace("-", ""), cf.getTarget().getId().replace("-", ""), cf.getLabel());
			else
				result += String.format("  n%s->n%s;\n", cf.getSource().getId().replace("-", ""), cf.getTarget().getId().replace("-", ""));
		}
		result+="\n";
		
		for (Activity a : this.getActivities()) {
			for (IDataNode d : a.getReadDocuments()) {
				result += String.format("  n%s->n%s;\n", d.getId().replace("-", ""), a.getId().replace("-", ""));
			}
			for (IDataNode d : a.getWriteDocuments()) {
				result += String.format("  n%s->n%s;\n", a.getId().replace("-", ""), d.getId().replace("-", ""));
			}
		}
		result += "}";
		
		return result;
	}
	
	@Override
	public Collection getAllPredecessors(FlowNode fn) {
		Set result = new HashSet();
		
		Set temp = new HashSet();
		temp.addAll(getDirectPredecessors(fn));
		result.addAll(temp);
		while(!(temp.isEmpty())) {
			Set temp2 = new HashSet();
			for (FlowNode flowNode : temp) {
				temp2.addAll(getDirectPredecessors(flowNode));
			}
			temp = temp2;
			Set temp3 = new HashSet();
			for (FlowNode flowNode : temp) {
				if(!(result.contains(flowNode))) {
					result.add(flowNode);
				} else {
					temp3.add(flowNode);
				}
			}
			for (FlowNode flowNode : temp3) {
				temp.remove(flowNode);
			}
		}
		
		return result;
	}
	
	@Override
	public Collection getAllSuccessors(FlowNode fn) {
		Set result = new HashSet();
		
		Set temp = new HashSet();
		temp.addAll(getDirectSuccessors(fn));
		result.addAll(temp);
		while(!(temp.isEmpty())) {
			Set temp2 = new HashSet();
			for (FlowNode flowNode : temp) {
				temp2.addAll(getDirectSuccessors(flowNode));
			}
			temp = temp2;
			Set temp3 = new HashSet();
			for (FlowNode flowNode : temp) {
				if(!(result.contains(flowNode))) {
					result.add(flowNode);
				} else {
					temp3.add(flowNode);
				}
			}
			for (FlowNode flowNode : temp3) {
				temp.remove(flowNode);
			}
		}
		
		return result;
	}
	
	/**
	 * assumptions:
	 * single entry node - single start node
	 * start with (i) activity or (ii) event followed by activity or and/ xor gateway
	 * every activity has at most one incoming and at most one outgoing edge
	 * unique labeling of activities
	 * control flow nodes: start event, end event, activity, gateway
	 */
	@Override
	public PetriNet toPetriNet() {
		PetriNet pn = new PetriNet();
		List nodes1 = new ArrayList();
		List nodes2 = new ArrayList();
		List nodes3 = new ArrayList();
		
		for (FlowNode fn : this.getEntries()) {
			if(fn instanceof Activity) {
				pn.addFlow(new Place(), new Transition(fn.getName()));
				nodes1.add(fn);
			} else if(fn instanceof Event) {
				fn = this.getFirstDirectSuccessor(fn);
				if(fn instanceof Activity) {
					pn.addFlow(new Place(), new Transition(fn.getName()));
					nodes1.add(fn);
				} else if(fn instanceof AndGateway) {
					for (FlowNode flowNode : this.getDirectSuccessors(fn)) {
						pn.addFlow(new Place(), new Transition(flowNode.getName()));
						nodes1.add(flowNode);
					}
				} else if(fn instanceof XorGateway) {
					Place p = new Place();
					for (FlowNode flowNode : this.getDirectSuccessors(fn)) {
						pn.addFlow(p, new Transition(flowNode.getName()));
						nodes1.add(flowNode);
					}
				} else {
					//not possible
				}
			} else {
				//not possible
			}
		} //initial transition
		
		while(!(nodes1.isEmpty())) {
			for (FlowNode flowNode : nodes1) {
				if(flowNode instanceof Activity) {
					while(this.getFirstDirectSuccessor(flowNode) instanceof Activity) {
						for (Transition transition : pn.getSinkTransitions()) {
							if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
								Place p = new Place();
								pn.addFlow(transition, p);
								pn.addFlow(p, new Transition(this.getFirstDirectSuccessor(flowNode).getName()));
							}
						} 
						flowNode = this.getFirstDirectSuccessor(flowNode);
					}
					nodes2.add(flowNode);
				} else if(flowNode instanceof Gateway) {
					nodes2.add(flowNode);
				} else {
					//not possible
				}
			} //gateway reached for each path
			nodes1.clear();
			nodes1.addAll(nodes2);
			nodes2.clear();
			
			//handle gateways
			while(!(nodes1.isEmpty())) {
				FlowNode currentFlowNode = nodes1.get(0);
				for (FlowNode node : this.getDirectSuccessors(currentFlowNode)) {
					if(node instanceof Event) {
						break;
					}
					Gateway gw = (Gateway) node;
					
					for (FlowNode flowNode : nodes1) {
						for (FlowNode flowNode2 : this.getDirectSuccessors(flowNode)) {
							if(flowNode2.equals(gw)) {
								nodes2.add(flowNode);
							}
						}
					}
					if(this.getIncomingEdges(gw).size() == 1 && this.getOutgoingEdges(gw).size() > 1) { //split
						if(gw instanceof AndGateway) { //and split
							for (Transition transition : pn.getSinkTransitions()) {
								for (FlowNode flowNode : nodes2) {
									if(flowNode instanceof Activity) {
										if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
											for (FlowNode flowNode2 : this.getDirectSuccessors(gw)) {
												Place p = new Place();
												pn.addFlow(transition, p);
												if(flowNode2 instanceof Activity) {
													pn.addFlow(p, new Transition(flowNode2.getName()));
													nodes3.add(flowNode2);
												} else if(flowNode2 instanceof Gateway) {
													Transition t = new Transition();
													t.setDescription(flowNode2.getName());
													pn.addFlow(p, t);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												} else {
													//not possible
												}
											}
										}
									} else if(flowNode instanceof Gateway) {
										if(transition.getDescription().equalsIgnoreCase(node.getName())) {
											for (FlowNode flowNode2 : this.getDirectSuccessors(gw)) {
												Place p = new Place();
												pn.addFlow(transition, p);
												if(flowNode2 instanceof Activity) {
													pn.addFlow(p, new Transition(flowNode2.getName()));
													nodes3.add(flowNode2);
												} else if(flowNode2 instanceof Gateway) {
													Transition t = new Transition();
													t.setDescription(flowNode2.getName());
													pn.addFlow(p, t);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												} else {
													//not possible
												}
											}
											
										}
									} else {
										//not possible
									}
									
								}
							}
						} else if(gw instanceof XorGateway) { //xor split
							for (Transition transition : pn.getSinkTransitions()) {
								for (FlowNode flowNode : nodes2) {
									if(flowNode instanceof Activity) {
										if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
											Place p = new Place();
											for (FlowNode flowNode2 : this.getDirectSuccessors(gw)) {
												pn.addFlow(transition, p);
												if(flowNode2 instanceof Activity) {
													pn.addFlow(p, new Transition(flowNode2.getName()));
													nodes3.add(flowNode2);
												} else if(flowNode2 instanceof Gateway) {
													Transition t = new Transition();
													t.setDescription(flowNode2.getName());
													pn.addFlow(p, t);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												} else {
													//not possible
												}
											}
										}
									} else if(flowNode instanceof Gateway) {
										if(transition.getDescription().equalsIgnoreCase(node.getName())) {
											Place p = new Place();
											for (FlowNode flowNode2 : this.getDirectSuccessors(gw)) {
												pn.addFlow(transition, p);
												if(flowNode2 instanceof Activity) {
													pn.addFlow(p, new Transition(flowNode2.getName()));
													nodes3.add(flowNode2);
												} else if(flowNode2 instanceof Gateway) {
													Transition t = new Transition();
													t.setDescription(flowNode2.getName());
													pn.addFlow(p, t);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												} else {
													//not possible
												}
											}
											
										}
									} else {
										//not possible
									}
									
								}
							}
						} else {
							//not possible
						}
						
						 
					} else if(this.getIncomingEdges(gw).size() > 1 && this.getOutgoingEdges(gw).size() == 1) { //join
						if(nodes1.containsAll(this.getDirectPredecessors(gw))) {
							if(gw instanceof AndGateway) { //and join
								Transition t1 = new Transition(this.getFirstDirectSuccessor(gw).getName());
								Transition t2 = new Transition();
								t2.setDescription(gw.getName());
								for (Transition transition : pn.getSinkTransitions()) {
									if(this.getFirstDirectSuccessor(gw) instanceof Activity) {
										for (FlowNode flowNode : nodes2) {
											if(flowNode instanceof Activity) {
												if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
													Place p = new Place();
													pn.addFlow(transition, p);
													pn.addFlow(p, t1);
													if(!(nodes3.contains(getFirstDirectSuccessor(gw)))) {
														nodes3.add(getFirstDirectSuccessor(gw));
													}
												}
											} else if(flowNode instanceof Gateway) {
												for (FlowNode flowNode2 : this.getDirectSuccessors(flowNode)) {
													if (transition.getDescription().equalsIgnoreCase(flowNode2.getName())) {
														Place p = new Place();
														pn.addFlow(transition, p);
														pn.addFlow(p, t1);
														if(!(nodes3.contains(getFirstDirectSuccessor(gw)))) {
															nodes3.add(getFirstDirectSuccessor(gw));
														}
													}
												}
											}
										}
									} else if(this.getFirstDirectSuccessor(gw) instanceof Gateway) {
										for (FlowNode flowNode : nodes2) {
											if(flowNode instanceof Activity) {
												if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
													Place p = new Place();
													pn.addFlow(transition, p);
													pn.addFlow(p, t2);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												}
											} else if(flowNode instanceof Gateway) {
												if (transition.getDescription().equalsIgnoreCase(flowNode.getName())) {
													Place p = new Place();
													pn.addFlow(transition, p);
													pn.addFlow(p, t2);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												}
											}
										}
									}
								}
								for (FlowNode flowNode : nodes2) {
									nodes1.remove(flowNode);
								}
							} else if(gw instanceof XorGateway) { //xor join
								Transition t1 = new Transition(this.getFirstDirectSuccessor(gw).getName());
								Transition t2 = new Transition();
								t2.setDescription(gw.getName());
								Place p = new Place();
								for (Transition transition : pn.getSinkTransitions()) {
									if(this.getFirstDirectSuccessor(gw) instanceof Activity) {
										for (FlowNode flowNode : nodes2) {											
											if(flowNode instanceof Activity) {
												if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
													pn.addFlow(transition, p);
													pn.addFlow(p, t1);
													if(!(nodes3.contains(getFirstDirectSuccessor(gw)))) {
														nodes3.add(getFirstDirectSuccessor(gw));
													}
												}
											} else if(flowNode instanceof Gateway) {
												for (FlowNode flowNode2 : this.getDirectSuccessors(flowNode)) {
													if (transition.getDescription().equalsIgnoreCase(flowNode2.getName())) {
														pn.addFlow(transition, p);
														pn.addFlow(p, t1);
														if(!(nodes3.contains(getFirstDirectSuccessor(gw)))) {
															nodes3.add(getFirstDirectSuccessor(gw));
														}
													}
												}
											}
										}
									} else if(this.getFirstDirectSuccessor(gw) instanceof Gateway) {
										for (FlowNode flowNode : nodes2) {
											if(flowNode instanceof Activity) {
												if (transition.getName().equalsIgnoreCase(flowNode.getName())) {
													pn.addFlow(transition, p);
													pn.addFlow(p, t2);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												}
											} else if(flowNode instanceof Gateway) {
												if (transition.getDescription().equalsIgnoreCase(flowNode.getName())) {
													pn.addFlow(transition, p);
													pn.addFlow(p, t2);
													if(!(nodes3.contains(gw))) {
														nodes3.add(gw);
													}
												}
											}
										}
									}
								}
								for (FlowNode flowNode : nodes2) {
									nodes1.remove(flowNode);
								}
							}
						} else {
							nodes3.add(currentFlowNode);
						}
						
					} else if(this.getIncomingEdges(gw).size() > 1 && this.getOutgoingEdges(gw).size() > 1) { //split and join
						//TODO
					} else {
						//at most one inc and one out
					}
					nodes2.clear();
				}
				if(nodes1.contains(currentFlowNode)) {
					nodes1.remove(currentFlowNode);
				}				
			}
			nodes1.clear();
			nodes2.clear();
			nodes1.addAll(nodes3);
			nodes3.clear();
		}
		for (Transition t : pn.getSinkTransitions()) {
			pn.addFlow(t, new Place());
		}
		return pn;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy