private static void addActivities( Set<TransitionTarget> visited, List<TransitionTarget> targets, IActivity activity, TransitionOptions options, boolean forward, Stack<TransitionStep> steps) { ModelElementList<ITransition> transitions = forward ? activity.getOutTransitions() : activity.getInTransitions(); JoinSplitType jsType = forward ? activity.getSplitType() : activity.getJoinType(); if (JoinSplitType.And == jsType && transitions.size() > 1) { IActivity target = consume( activity, asList(transitions), CollectionUtils.<ITransition>newHashSet(), forward, options.areLoopsAllowed()); if (target != null) { addActivity(visited, targets, target, options, forward, steps); } } else { for (ITransition transition : transitions) { IActivity target = forward ? transition.getToActivity() : transition.getFromActivity(); jsType = forward ? target.getJoinType() : target.getSplitType(); if (JoinSplitType.And != jsType) { addActivity(visited, targets, target, options, forward, steps); } } } }
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; }