You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by at...@apache.org on 2014/03/14 01:50:35 UTC
svn commit: r1577400 - in
/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2:
SCXMLExecutor.java SCXMLSemantics.java semantics/SCXMLSemanticsImpl.java
Author: ate
Date: Fri Mar 14 00:50:35 2014
New Revision: 1577400
URL: http://svn.apache.org/r1577400
Log:
SCXML-196
Modified:
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLSemantics.java
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java?rev=1577400&r1=1577399&r2=1577400&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java Fri Mar 14 00:50:35 2014
@@ -437,17 +437,12 @@ public class SCXMLExecutor implements Se
// CreateEmptyStatus
currentStatus = new Status();
Step step = new Step(null, currentStatus);
+ // execute initial script if defined
+ semantics.executeGlobalScript(step, stateMachine, eventdispatcher, errorReporter, scInstance);
// DetermineInitialStates
- semantics.determineInitialStates(stateMachine,
- step.getAfterStatus().getStates(),
- step.getEntryList(), errorReporter, scInstance);
- // execute initial script if defined configured as transition so as to not trigger events
- if (stateMachine.getInitialScript() != null) {
- step.getTransitList().add((Transition)stateMachine.getInitialScript().getParent());
- }
- // ExecuteActions
- semantics.executeActions(step, stateMachine, eventdispatcher,
- errorReporter, scInstance);
+ semantics.determineInitialStates(step, stateMachine, errorReporter, scInstance);
+ // enter initial states
+ semantics.enterStates(step, stateMachine, eventdispatcher, errorReporter, scInstance);
// AssignCurrentStatus
updateStatus(step);
// Execute Immediate Transitions
Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLSemantics.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLSemantics.java?rev=1577400&r1=1577399&r2=1577400&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLSemantics.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCXMLSemantics.java Fri Mar 14 00:50:35 2014
@@ -16,29 +16,18 @@
*/
package org.apache.commons.scxml2;
-import java.util.List;
-import java.util.Set;
-
import org.apache.commons.scxml2.model.ModelException;
import org.apache.commons.scxml2.model.SCXML;
-import org.apache.commons.scxml2.model.TransitionTarget;
/**
- * <p>The purpose of this interface is to separate the interpretation algorithm
+ * <p>The purpose of this interface is to separate the the
+ * <a href="http://www.w3.org/TR/2014/CR-scxml-20140313/#AlgorithmforSCXMLInterpretation">
+ * W3C SCXML Algorithm for SCXML Interpretation</a>
* from the <code>SCXMLExecutor</code> and therefore make it pluggable.</p>
*
* <p>Semantics agnostic utility functions and common operators as defined in
* UML can be found in the <code>SCXMLHelper</code> or attached directly to
- * the SCXML model elements. Some of the possible semantic interpretations
- * are, for example:</p>
- *
- * <ul>
- * <li>STATEMATE
- * <li>RHAPSODY
- * <li>ROOMCharts
- * <li>UML 1.5
- * <li>UML 2.0
- * </ul>
+ * the SCXML model elements.</p>
*
* <p>Specific semantics can be created by subclassing
* <code>org.apache.commons.scxml2.semantics.SCXMLSemanticsImpl</code>.</p>
@@ -57,15 +46,25 @@ public interface SCXMLSemantics {
*/
SCXML normalizeStateMachine(final SCXML input, final ErrorReporter errRep);
+ public void executeGlobalScript(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException;
+
+ public void exitStates(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException;
+
+ public void executeTransitionContent(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException;
+
+ public void enterStates(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException;
+
/**
* Determining the initial state(s) for this state machine.
*
- * @param input
+ * @param step
+ * provides target states and entry list to fill in [out]
+ * @param stateMachine
* SCXML state machine
- * @param states
- * a set of States to populate
- * @param entryList
- * a list of States and Parallels to enter
* @param errRep
* ErrorReporter callback
* @param scInstance
@@ -74,8 +73,7 @@ public interface SCXMLSemantics {
* @throws ModelException
* in case there is a fatal SCXML object model problem.
*/
- void determineInitialStates(final SCXML input, final Set<TransitionTarget> states,
- final List<TransitionTarget> entryList, final ErrorReporter errRep,
+ void determineInitialStates(final Step step, final SCXML stateMachine, final ErrorReporter errRep,
final SCInstance scInstance)
throws ModelException;
@@ -195,6 +193,5 @@ public interface SCXMLSemantics {
*/
void initiateInvokes(final Step step, final ErrorReporter errRep,
final SCInstance scInstance);
-
}
Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java?rev=1577400&r1=1577399&r2=1577400&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java Fri Mar 14 00:50:35 2014
@@ -46,6 +46,7 @@ import org.apache.commons.scxml2.Trigger
import org.apache.commons.scxml2.invoke.Invoker;
import org.apache.commons.scxml2.invoke.InvokerException;
import org.apache.commons.scxml2.model.Action;
+import org.apache.commons.scxml2.model.Executable;
import org.apache.commons.scxml2.model.Finalize;
import org.apache.commons.scxml2.model.History;
import org.apache.commons.scxml2.model.Initial;
@@ -185,6 +186,19 @@ public class SCXMLSemanticsImpl implemen
return false;
}
+ protected void executeContent(Executable exec, final EventDispatcher evtDispatcher, final ErrorReporter errRep,
+ final SCInstance scInstance, final Collection<TriggerEvent> internalEvents)
+ throws ModelException {
+
+ try {
+ for (Action action : exec.getActions()) {
+ action.execute(evtDispatcher, errRep, scInstance, appLog, internalEvents);
+ }
+ } catch (SCXMLExpressionException e) {
+ errRep.onError(ErrorConstants.EXPRESSION_ERROR, e.getMessage(), exec);
+ }
+ }
+
/**
* @param input
* SCXML state machine
@@ -193,86 +207,32 @@ public class SCXMLSemanticsImpl implemen
* ErrorReporter callback
*/
public SCXML normalizeStateMachine(final SCXML input,
- final ErrorReporter errRep) {
+ final ErrorReporter errRep) {
//it is a no-op for now
return input;
}
- /**
- * @param input
- * SCXML state machine [in]
- * @param targets
- * a set of initial targets to populate [out]
- * @param entryList
- * a list of States and Parallels to enter [out]
- * @param errRep
- * ErrorReporter callback [inout]
- * @param scInstance
- * The state chart instance [in]
- * @throws ModelException
- * in case there is a fatal SCXML object model problem.
- */
- public void determineInitialStates(final SCXML input, final Set<TransitionTarget> targets,
- final List<TransitionTarget> entryList, final ErrorReporter errRep,
- final SCInstance scInstance)
- throws ModelException {
- TransitionTarget tmp = input.getInitialTarget();
- if (tmp == null) {
- errRep.onError(ErrorConstants.NO_INITIAL,
- "SCXML initialstate is missing!", input);
- } else {
- targets.add(tmp);
- determineTargetStates(targets, errRep, scInstance);
- //set of ALL entered states (even if initialState is a jump-over)
- Set<TransitionTarget> onEntry = SCXMLHelper.getAncestorClosure(targets, null);
- // sort onEntry according state hierarchy
- TransitionTarget[] oen = onEntry.toArray(new TransitionTarget[onEntry.size()]);
- onEntry.clear();
- Arrays.sort(oen, getTTComparator());
- // we need to impose reverse order for the onEntry list
- List<TransitionTarget> entering = Arrays.asList(oen);
- Collections.reverse(entering);
- entryList.addAll(entering);
-
+ public void executeGlobalScript(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException {
+ if (stateMachine.getInitialScript() != null) {
+ try {
+ stateMachine.getInitialScript().execute(evtDispatcher, errRep, scInstance, appLog,
+ step.getAfterStatus().getEvents());
+ } catch (SCXMLExpressionException e) {
+ errRep.onError(ErrorConstants.EXPRESSION_ERROR, e.getMessage(), stateMachine);
+ }
}
}
- /**
- * Executes all OnExit/Transition/OnEntry transitional actions.
- *
- * @param step
- * provides EntryList, TransitList, ExitList gets
- * updated its AfterStatus/Events
- * @param stateMachine
- * state machine - SCXML instance
- * @param evtDispatcher
- * the event dispatcher - EventDispatcher instance
- * @param errRep
- * error reporter
- * @param scInstance
- * The state chart instance
- * @throws ModelException
- * in case there is a fatal SCXML object model problem.
- */
- public void executeActions(final Step step, final SCXML stateMachine,
- final EventDispatcher evtDispatcher,
- final ErrorReporter errRep, final SCInstance scInstance)
- throws ModelException {
+ public void exitStates(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException {
NotificationRegistry nr = scInstance.getNotificationRegistry();
Collection<TriggerEvent> internalEvents = step.getAfterStatus().getEvents();
Map<TransitionTarget, Invoker> invokers = scInstance.getInvokers();
// ExecutePhaseActions / OnExit
for (TransitionTarget tt : step.getExitList()) {
OnExit oe = tt.getOnExit();
- try {
- for (Action onExitAct : oe.getActions()) {
- onExitAct.execute(evtDispatcher,
- errRep, scInstance, appLog, internalEvents);
- }
- } catch (SCXMLExpressionException e) {
- errRep.onError(ErrorConstants.EXPRESSION_ERROR, e.getMessage(),
- oe);
- }
+ executeContent(oe, evtDispatcher, errRep, scInstance, internalEvents);
// check if invoke is active in this state
if (invokers.containsKey(tt)) {
Invoker toCancel = invokers.get(tt);
@@ -280,7 +240,7 @@ public class SCXMLSemanticsImpl implemen
toCancel.cancel();
} catch (InvokerException ie) {
TriggerEvent te = new TriggerEvent(tt.getId()
- + ".invoke.cancel.failed", TriggerEvent.ERROR_EVENT);
+ + ".invoke.cancel.failed", TriggerEvent.ERROR_EVENT);
internalEvents.add(te);
}
// done here, don't wait for cancel response
@@ -292,35 +252,29 @@ public class SCXMLSemanticsImpl implemen
TriggerEvent.CHANGE_EVENT);
internalEvents.add(te);
}
- // ExecutePhaseActions / Transitions
+ }
+
+ public void executeTransitionContent(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException {
+ NotificationRegistry nr = scInstance.getNotificationRegistry();
+ Collection<TriggerEvent> internalEvents = step.getAfterStatus().getEvents();
for (Transition t : step.getTransitList()) {
- try {
- for (Action transitAct : t.getActions()) {
- transitAct.execute(evtDispatcher,
- errRep, scInstance, appLog, internalEvents);
- }
- } catch (SCXMLExpressionException e) {
- errRep.onError(ErrorConstants.EXPRESSION_ERROR,
- e.getMessage(), t);
- }
+ executeContent(t, evtDispatcher, errRep, scInstance, internalEvents);
List<TransitionTarget> rtargets = t.getRuntimeTargets();
for (TransitionTarget tt : rtargets) {
nr.fireOnTransition(t, t.getParent(), tt, t);
nr.fireOnTransition(stateMachine, t.getParent(), tt, t);
}
}
- // ExecutePhaseActions / OnEntry
+ }
+
+ public void enterStates(final Step step, final SCXML stateMachine, final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance) throws ModelException {
+ NotificationRegistry nr = scInstance.getNotificationRegistry();
+ Collection<TriggerEvent> internalEvents = step.getAfterStatus().getEvents();
for (TransitionTarget tt : step.getEntryList()) {
OnEntry oe = tt.getOnEntry();
- try {
- for (Action onEntryAct : oe.getActions()) {
- onEntryAct.execute(evtDispatcher,
- errRep, scInstance, appLog, internalEvents);
- }
- } catch (SCXMLExpressionException e) {
- errRep.onError(ErrorConstants.EXPRESSION_ERROR, e.getMessage(),
- oe);
- }
+ executeContent(oe, evtDispatcher, errRep, scInstance, internalEvents);
nr.fireOnEntry(tt, tt);
nr.fireOnEntry(stateMachine, tt);
TriggerEvent te = new TriggerEvent(tt.getId() + ".entry",
@@ -330,17 +284,8 @@ public class SCXMLSemanticsImpl implemen
if (tt instanceof State) {
State ts = (State) tt;
Initial ini = ts.getInitial();
- if (ts.isComposite() && ini != null) {
- try {
- for (Action initialAct : ini.getTransition().
- getActions()) {
- initialAct.execute(evtDispatcher,
- errRep, scInstance, appLog, internalEvents);
- }
- } catch (SCXMLExpressionException e) {
- errRep.onError(ErrorConstants.EXPRESSION_ERROR,
- e.getMessage(), ini);
- }
+ if (ts.isComposite() && ini != null) { // TODO: use step.getDefaultEntrySet().contains(tt) instead
+ executeContent(ini.getTransition(), evtDispatcher, errRep, scInstance, internalEvents);
}
if (ts.isFinal()) {
State parent = (State) ts.getParent();
@@ -368,7 +313,7 @@ public class SCXMLSemanticsImpl implemen
}
if (finCount == pCount) {
te = new TriggerEvent(p.getId() + ".done",
- TriggerEvent.CHANGE_EVENT);
+ TriggerEvent.CHANGE_EVENT);
internalEvents.add(te);
scInstance.setDone(p, true);
}
@@ -379,6 +324,69 @@ public class SCXMLSemanticsImpl implemen
}
/**
+ * @param step
+ * provides target states and entry list to fill in [out]
+ * @param stateMachine
+ * SCXML state machine [in]
+ * @param errRep
+ * ErrorReporter callback [inout]
+ * @param scInstance
+ * The state chart instance [in]
+ * @throws org.apache.commons.scxml2.model.ModelException
+ * in case there is a fatal SCXML object model problem.
+ */
+ public void determineInitialStates(final Step step, final SCXML stateMachine, final ErrorReporter errRep,
+ final SCInstance scInstance)
+ throws ModelException {
+ TransitionTarget tmp = stateMachine.getInitialTarget();
+ if (tmp == null) {
+ errRep.onError(ErrorConstants.NO_INITIAL,
+ "SCXML initialstate is missing!", stateMachine);
+ } else {
+ Set<TransitionTarget> targets = step.getAfterStatus().getStates();
+ targets.add(tmp);
+ determineTargetStates(targets, errRep, scInstance);
+ //set of ALL entered states (even if initialState is a jump-over)
+ Set<TransitionTarget> onEntry = SCXMLHelper.getAncestorClosure(targets, null);
+ // sort onEntry according state hierarchy
+ TransitionTarget[] oen = onEntry.toArray(new TransitionTarget[onEntry.size()]);
+ onEntry.clear();
+ Arrays.sort(oen, getTTComparator());
+ // we need to impose reverse order for the onEntry list
+ List<TransitionTarget> entering = Arrays.asList(oen);
+ Collections.reverse(entering);
+ step.getEntryList().addAll(entering);
+
+ }
+ }
+
+ /**
+ * Executes all OnExit/Transition/OnEntry transitional actions.
+ *
+ * @param step
+ * provides EntryList, TransitList, ExitList gets
+ * updated its AfterStatus/Events
+ * @param stateMachine
+ * state machine - SCXML instance
+ * @param evtDispatcher
+ * the event dispatcher - EventDispatcher instance
+ * @param errRep
+ * error reporter
+ * @param scInstance
+ * The state chart instance
+ * @throws ModelException
+ * in case there is a fatal SCXML object model problem.
+ */
+ public void executeActions(final Step step, final SCXML stateMachine,
+ final EventDispatcher evtDispatcher,
+ final ErrorReporter errRep, final SCInstance scInstance)
+ throws ModelException {
+ exitStates(step, stateMachine, evtDispatcher, errRep, scInstance);
+ executeTransitionContent(step, stateMachine, evtDispatcher, errRep, scInstance);
+ enterStates(step, stateMachine, evtDispatcher, errRep, scInstance);
+ }
+
+ /**
* @param stateMachine
* a SM to traverse [in]
* @param step
@@ -447,15 +455,7 @@ public class SCXMLSemanticsImpl implemen
if (finalizeMatch(s.getId(), allEvents)) {
Finalize fn = s.getInvoke().getFinalize();
if (fn != null) {
- try {
- for (Action fnAct : fn.getActions()) {
- fnAct.execute(evtDispatcher, errRep, scInstance, appLog,
- step.getAfterStatus().getEvents());
- }
- } catch (SCXMLExpressionException e) {
- errRep.onError(ErrorConstants.EXPRESSION_ERROR,
- e.getMessage(), fn);
- }
+ executeContent(fn, evtDispatcher, errRep, scInstance, step.getAfterStatus().getEvents());
}
}
}