* 1. SCXML elemnt (top) should reach count exactly 1. We essentially
* summarize up the hierarchy tree starting with a given set of
* states = active configuration.
*/
boolean legalConfig = true; // let's be optimists
Map counts = new IdentityHashMap();
Set scxmlCount = new HashSet();
for (Iterator i = states.iterator(); i.hasNext();) {
TransitionTarget tt = (TransitionTarget) i.next();
TransitionTarget parent = null;
while ((parent = tt.getParent()) != null) {
HashSet cnt = (HashSet) counts.get(parent);
if (cnt == null) {
cnt = new HashSet();
counts.put(parent, cnt);
}
cnt.add(tt);
tt = parent;
}
//top-level contribution
scxmlCount.add(tt);
}
//Validate counts:
for (Iterator i = counts.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
TransitionTarget tt = (TransitionTarget) entry.getKey();
Set count = (Set) entry.getValue();
if (tt instanceof Parallel) {
Parallel p = (Parallel) tt;
if (count.size() < p.getStates().size()) {
errRep.onError(ErrorReporter.ILLEGAL_CONFIG,
"Not all AND states active for parallel "
+ p.getId(), entry);
legalConfig = false;
}
} else {
if (count.size() > 1) {
errRep.onError(ErrorReporter.ILLEGAL_CONFIG,
"Multiple OR states active for state "
+ tt.getId(), entry);
legalConfig = false;
}
}
count.clear(); //cleanup
}
if (scxmlCount.size() > 1) {
errRep.onError(ErrorReporter.ILLEGAL_CONFIG,
"Multiple top-level OR states active!", scxmlCount);
}
//cleanup
scxmlCount.clear();
counts.clear();
return legalConfig;
}