in src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java [476:511]
public void finalStep(final SCXMLExecutionContext exctx) throws ModelException {
if (exctx.isRunning()) {
return;
}
final ArrayList<EnterableState> configuration = new ArrayList<>(exctx.getScInstance().getStateConfiguration().getActiveStates());
configuration.sort(DocumentOrder.reverseDocumentOrderComparator);
for (final EnterableState es : configuration) {
for (final OnExit onexit : es.getOnExits()) {
executeContent(exctx, onexit);
}
if (es instanceof TransitionalState) {
// check if invokers are active in this state
for (final Invoke inv : ((TransitionalState)es).getInvokes()) {
exctx.cancelInvoker(inv);
}
}
exctx.getNotificationRegistry().fireOnExit(es, es);
exctx.getNotificationRegistry().fireOnExit(exctx.getStateMachine(), es);
if (es instanceof Final && es.getParent() == null) {
final Object donedata = ((Final)es).processDoneData(exctx);
exctx.getScInstance().getGlobalContext().getSystemContext().getPlatformVariables().put(SCXMLSystemContext.FINAL_DONE_DATA_KEY, donedata);
if (exctx.getSCXMLExecutor().getParentSCXMLIOProcessor() != null) {
final ParentSCXMLIOProcessor ioProcessor = exctx.getSCXMLExecutor().getParentSCXMLIOProcessor();
if (!ioProcessor.isClosed()) {
ioProcessor.addEvent(
new EventBuilder("done.invoke."+ioProcessor.getInvokeId(), TriggerEvent.SIGNAL_EVENT)
.invokeId(ioProcessor.getInvokeId()).data(donedata).build());
ioProcessor.close();
}
}
}
else {
exctx.getScInstance().getStateConfiguration().exitState(es);
}
}
}