/** * Creates a spanning tree in spanningTree corresponding to the input process * and lists transitions that are not in the spanning tree. * Use a Deep First Search Algorithm for that. * Transitions that are not in the spanning tree can be: * - transitions that creates a second path between two nodes (e.g. split/join) * - transitions that creates loops * @param inProcess input process * @param spanningTree process where the corresponding spanning tree will be created * @return list of transitions of input process that are not in the spanning tree. */ private static List<Transition> createSpanningTree(XpdlProcess inProcess, ProcessDefinitionImpl spanningTree) { Node inNode = inProcess.getInitial(); NodeImpl outNode = spanningTree.createNode(inNode.getName()); // Create a spanning tree in outProcess and list transitions that are not in the spanning tree. // Use a Deep First Search Algorithm for that. return processNode(inNode, outNode, spanningTree); }
/** * Deep first search algorithm that creates spanning tree * (see {@link IterationDetection#createSpanningTree(ProcessDefinitionImpl, ProcessDefinitionImpl)} * @param inNode node of the input process currently processed * @param outNode corresponding node in the spanning tree * @param outProcess spanning tree * @return list of unprocessed transitions during the DFS */ private static List<Transition> processNode(Node inNode, NodeImpl outNode, ProcessDefinitionImpl outProcess) { List<Transition> nonProcessedTransitions = new ArrayList<Transition>(); if (inNode.hasOutgoingTransitions()) { for (Transition t : inNode.getOutgoingTransitions()) { NodeImpl destNode = (NodeImpl) t.getDestination(); String destName = destNode.getName(); if (!outProcess.hasNode(destName)) { // create node NodeImpl newNode = outProcess.createNode(destName); outNode.createOutgoingTransition(newNode, t.getName()); nonProcessedTransitions.addAll(processNode(t.getDestination(), newNode, outProcess)); } else { // node already in the spanning tree, the transition is not in the spanning tree. nonProcessedTransitions.add(t); } } } return nonProcessedTransitions; }