in src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java [610:663]
public void removeConflictingTransitions(final SCXMLExecutionContext exctx, final Step step,
final List<Transition> enabledTransitions) {
final LinkedHashSet<Transition> filteredTransitions = new LinkedHashSet<>();
final LinkedHashSet<Transition> preemptedTransitions = new LinkedHashSet<>();
final Map<Transition, Set<EnterableState>> exitSets = new HashMap<>();
final Set<EnterableState> configuration = exctx.getScInstance().getStateConfiguration().getActiveStates();
enabledTransitions.sort(DocumentOrder.documentOrderComparator);
for (final Transition t1 : enabledTransitions) {
boolean t1Preempted = false;
Set<EnterableState> t1ExitSet = exitSets.get(t1);
for (final Transition t2 : filteredTransitions) {
if (t1ExitSet == null) {
t1ExitSet = new HashSet<>();
computeExitSet(t1, t1ExitSet, configuration);
exitSets.put(t1, t1ExitSet);
}
Set<EnterableState> t2ExitSet = exitSets.get(t2);
if (t2ExitSet == null) {
t2ExitSet = new HashSet<>();
computeExitSet(t2, t2ExitSet, configuration);
exitSets.put(t2, t2ExitSet);
}
final Set<EnterableState> smaller = t1ExitSet.size() < t2ExitSet.size() ? t1ExitSet : t2ExitSet;
final Set<EnterableState> larger = smaller == t1ExitSet ? t2ExitSet : t1ExitSet;
boolean hasIntersection = false;
for (final EnterableState s1 : smaller) {
hasIntersection = larger.contains(s1);
if (hasIntersection) {
break;
}
}
if (hasIntersection) {
if (!t1.getParent().isDescendantOf(t2.getParent())) {
t1Preempted = true;
break;
}
preemptedTransitions.add(t2);
}
}
if (t1Preempted) {
exitSets.remove(t1);
}
else {
for (final Transition preempted : preemptedTransitions) {
filteredTransitions.remove(preempted);
exitSets.remove(preempted);
}
filteredTransitions.add(t1);
}
}
step.getTransitList().addAll(filteredTransitions);
}