package no.hal.scxml.generator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.scxml.SCInstance; import org.apache.commons.scxml.SCXMLExecutor; import org.apache.commons.scxml.SCXMLExpressionException; import org.apache.commons.scxml.model.TransitionTarget; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.edit.provider.IDisposable; import org.eclipse.emf.js4emf.ecore.internal.EmfContext; public class ScriptEventHandler extends AdapterImpl { private Log log = LogFactory.getLog(ScriptEventHandler.class); private TransitionTarget scxmlState; private String script; public ScriptEventHandler(TransitionTarget scxmlState, String script) { this.scxmlState = scxmlState; this.script = script; } public String getScxmlStateId() { return scxmlState.getId(); } public String getScript() { return script; } public String getScriptEventId() { return getScxmlStateId() + "#" + script + ";"; } private ScriptEventManager scriptEventManager; public void activateScriptHandler(ScriptEventManager scriptEventManager) { this.scriptEventManager = scriptEventManager; if (log.isDebugEnabled()) { debug("Activating event condition for " + getScript() + " (" + this + ")"); } checkEventCondition(); } private Notifier dependencies = null; private void disposeDependencies() { if (isActive()) { Notifier notifier = dependencies; dependencies = null; if (notifier instanceof IDisposable) { ((IDisposable)notifier).dispose(); } notifier.eAdapters().remove(this); } } public void deactivateScriptHandler() { disposeDependencies(); if (log.isDebugEnabled()) { debug("Deactivating event condition for " + getScript() + " (" + this + ")"); } scriptEventManager = null; } private SCInstance getScInstance() { return scriptEventManager.getScInstance(); } private SCXMLExecutor getExecutor() { return getScInstance().getExecutor(); } private void debug(String message) { if (log.isDebugEnabled()) { log.debug(getScxmlStateId() + ": " + message + " (" + this + ")"); } } private void checkEventCondition() { disposeDependencies(); if (log.isDebugEnabled()) { debug("Checking event condition for " + getScript()); } EmfContext.startAddingDependencies(); Object result = null; try { result = getExecutor().getEvaluator().evalCond(getScInstance().getContext(scxmlState), script); } catch (SCXMLExpressionException e) { } dependencies = EmfContext.stopAddingDependencies(); if (isActive()) { dependencies.eAdapters().add(this); } if (log.isDebugEnabled()) { debug("Event condition result for " + getScript() + ": " + result); } if (Boolean.TRUE.equals(result)) { if (log.isDebugEnabled()) { debug("Sending event " + getScriptEventId()); } scriptEventManager.sendScriptEvent(this); } } private boolean isActive() { return (dependencies != null); } private boolean isRelevantNotification(Notification notification) { return notification.getEventType() != Notification.REMOVING_ADAPTER; } public void notifyChanged(Notification notification) { if (isActive() && isRelevantNotification(notification)) { checkEventCondition(); } } }