private static IActivity consumeXor( IActivity startActivity, LinkedList<ITransition> unconsumed, HashSet<ITransition> visited, boolean forward, boolean supportsLoops, ModelElementList<ITransition> transitions) { IActivity result = null; for (ITransition out : transitions) { if (visited.contains(out)) // loop { if (!supportsLoops) { return null; } } else { LinkedList<ITransition> unconsumedClone = (LinkedList<ITransition>) unconsumed.clone(); HashSet<ITransition> visitedClone = (HashSet<ITransition>) visited.clone(); visitedClone.add(out); unconsumedClone.add(out); IActivity next = consume(startActivity, unconsumedClone, visitedClone, forward, supportsLoops); if (next == null) { return null; } else if (result == null) { result = next; } else if (result != next) { return null; } } } return result; }
private static LinkedList<ITransition> asList(ModelElementList<ITransition> transitions) { LinkedList<ITransition> unconsumed = CollectionUtils.newLinkedList(); for (ITransition transition : transitions) { unconsumed.add(transition); } return unconsumed; }
private static IActivity consume( IActivity startActivity, LinkedList<ITransition> unconsumed, HashSet<ITransition> visited, boolean forward, boolean supportsLoops) { int unchanged = 0; while (!unconsumed.isEmpty()) { ITransition transition = unconsumed.element(); IActivity target = forward ? transition.getToActivity() : transition.getFromActivity(); if (startActivity == target) { // unsupported loop break; } JoinSplitType inJsType = forward ? target.getJoinType() : target.getSplitType(); if (JoinSplitType.And == inJsType) { List<ITransition> pending = CollectionUtils.newList(); ModelElementList<ITransition> transitions = forward ? target.getInTransitions() : target.getOutTransitions(); for (ITransition incoming : transitions) { if (unconsumed.remove(incoming)) { pending.add(incoming); } } if (pending.size() == transitions.size()) // all incoming transitions consumed { if (unconsumed.isEmpty()) { return target; } } else { if (!unconsumed .isEmpty()) // unable to consume all transitions, but there are more branches, put // them all back to the end { unconsumed.addAll(pending); unchanged++; } if (unchanged == unconsumed.size()) { return null; } continue; } } else { unconsumed.remove(transition); } unchanged = 0; ModelElementList<ITransition> transitions = forward ? target.getOutTransitions() : target.getInTransitions(); if (transitions.isEmpty()) { return null; } JoinSplitType outJsType = forward ? target.getSplitType() : target.getJoinType(); if (JoinSplitType.Xor == outJsType && transitions.size() > 1) { return consumeXor(startActivity, unconsumed, visited, forward, supportsLoops, transitions); } else { for (ITransition out : transitions) { if (visited.contains(out)) // loop { if (!supportsLoops) { return null; } } else { visited.add(out); unconsumed.add(out); } } } } return null; }