View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.scxml2;
18  
19  import java.util.Set;
20  
21  import org.apache.commons.scxml2.model.EnterableState;
22  import org.apache.commons.scxml2.model.ModelException;
23  import org.apache.commons.scxml2.model.SCXML;
24  
25  /**
26   * <p>The purpose of this interface is to separate the the
27   * <a href="http://www.w3.org/TR/2014/CR-scxml-20140313/#AlgorithmforSCXMLInterpretation">
28   *     W3C SCXML Algorithm for SCXML Interpretation</a>
29   * from the <code>SCXMLExecutor</code> and therefore make it pluggable.</p>
30   * <p>
31   * From an SCXML execution POV, there are only three entry points needed into the Algorithm, namely:
32   * <ul>
33   *     <li>Performing the initialization of the state machine and completing a first macro step,
34   *     see: {@link #firstStep(SCXMLExecutionContext)}. The state machine thereafter should be ready
35   *     for processing external events (or be terminated already)</li>
36   *     <li>Processing a single external event and completing the macro step for it, after which the
37   *     state machine should be ready for processing another external event (if any), or be terminated already.
38   *     See: {@link #nextStep(SCXMLExecutionContext, TriggerEvent)}.
39   *     </li>
40   *     <li>Finally, if the state machine terminated ({@link SCXMLExecutionContext#isRunning()} == false), after either
41   *     of the above steps, finalize the state machine by performing the final step.
42   *     See: {@link #finalStep(SCXMLExecutionContext)}.
43   *     </li>
44   * </ul>
45   * </p>
46   * <p>After a state machine has been terminated you can re-initialize the execution context, and start again.</p>
47   * <p>
48   * Except for the loading of the SCXML document and (re)initializing the {@link SCXMLExecutionContext}, the above steps
49   * represent the <b>interpret</b>,<b>mainEventLoop</b> and <b>exitInterpreter</b> entry points specified in Algorithm
50   * for SCXML Interpretation, but more practically and logically broken into separate steps so that the blocking wait
51   * for external events can be handled externally.
52   * </p>
53   * <p>
54   *  These three entry points are the only interface methods used by the SCXMLExecutor. It is up to the
55   *  specific SCXMLSemantics implementation to provide the concrete handling for these according to the Algorithm in
56   *  the SCXML specification (or possibly something else/different).
57   * </p>
58   * <p>
59   * The default {@link org.apache.commons.scxml2.semantics.SCXMLSemanticsImpl} provides an implementation of the
60   * specification, and can easily be overridden/customized as a whole or only on specific parts of the Algorithm
61   * implementation.
62   * </p>
63   * <p>
64   * Note that both the {@link #firstStep(SCXMLExecutionContext)} and {@link #nextStep(SCXMLExecutionContext, TriggerEvent)}
65   * first run to completion for any internal events raised before returning, as expected and required by the SCXML
66   * specification, so it is currently not possible to 'manage' internal event processing externally.
67   * </p>
68   *
69   * <p>Specific semantics can be created by subclassing
70   * <code>org.apache.commons.scxml2.semantics.SCXMLSemanticsImpl</code>.</p>
71   */
72  public interface SCXMLSemantics {
73  
74      /**
75       * Optional post processing immediately following SCXMLReader. May be used
76       * for removing pseudo-states etc.
77       *
78       * @param input  SCXML state machine
79       * @param errRep ErrorReporter callback
80       * @return normalized SCXML state machine, pseudo states are removed, etc.
81       */
82      SCXML normalizeStateMachine(final SCXML input, final ErrorReporter errRep);
83  
84      /**
85       * First step in the execution of an SCXML state machine.
86       * <p>
87       * In the default implementation, this will first (re)initialize the state machine instance, destroying any existing
88       * state!
89       * </p>
90       * <p>
91       * The first step is corresponding to the Algorithm for SCXML processing from the interpret() procedure to the
92       * mainLoop() procedure up to the blocking wait for an external event.
93       * </p>
94       * <p>
95       * This step should complete the SCXML initial execution and a subsequent macroStep to stabilize the state machine
96       * again before returning.
97       * </p>
98       * <p>
99       * If the state machine no longer is running after all this, first the {@link #finalStep(SCXMLExecutionContext)}
100      * should be called for cleanup before returning.
101      * </p>
102      * @param exctx The execution context for this step
103      * @throws ModelException if the state machine instance failed to initialize or a SCXML model error occurred during
104      * the execution.
105      */
106     void firstStep(final SCXMLExecutionContext exctx) throws ModelException;
107 
108     /**
109      * Next step in the execution of an SCXML state machine.
110      * <p>
111      * The next step is corresponding to the Algorithm for SCXML processing mainEventLoop() procedure after receiving an
112      * external event, up to the blocking wait for another external event.
113      * </p>
114      * <p>
115      * If the state machine isn't {@link SCXMLExecutionContext#isRunning()} (any more), this method should do nothing.
116      * </p>
117      * <p>
118      * If the provided event is a {@link TriggerEvent#CANCEL_EVENT}, the state machine should stop running.
119      * </p>
120      * <p>
121      * Otherwise, the event must be set in the {@link SCXMLSystemContext} and processing of the event then should start,
122      * and if the event leads to any transitions a microStep for this event should be performed, followed up by a
123      * macroStep to stabilize the state machine again before returning.
124      * </p>
125      * <p>
126      * If the state machine no longer is running after all this, first the {@link #finalStep(SCXMLExecutionContext)}
127      * should be called for cleanup before returning.
128      * </p>
129      * @param exctx The execution context for this step
130      * @param event The event to process
131      * @throws ModelException if a SCXML model error occurred during the execution.
132      */
133     void nextStep(final SCXMLExecutionContext exctx, final TriggerEvent event) throws ModelException;
134 
135     /**
136      * The final step in the execution of an SCXML state machine.
137      * <p>
138      * This final step is corresponding to the Algorithm for SCXML processing exitInterpreter() procedure, after the
139      * state machine stopped running.
140      * </p>
141      * <p>
142      * If the state machine still is {@link SCXMLExecutionContext#isRunning()} invoking this method should simply
143      * do nothing.
144      * </p>
145      * <p>
146      * This final step should first exit all remaining active states and cancel any active invokers, before handling
147      * the possible donedata element for the last final state.
148      * </p>
149      * <p>
150      *  <em>NOTE: the current implementation does not yet provide final donedata handling.</em>
151      * </p>
152      * @param exctx The execution context for this step
153      * @throws ModelException if a SCXML model error occurred during the execution.
154      */
155     void finalStep(final SCXMLExecutionContext exctx) throws ModelException;
156 
157     /**
158      * Checks whether a given set of states is a legal Harel State Table
159      * configuration (with the respect to the definition of the OR and AND
160      * states).
161      * <p>
162      * When {@link SCXMLExecutionContext#isCheckLegalConfiguration()} is true (default) the SCXMLSemantics implementation
163      * <em>should</em> invoke this method before executing a step, and throw a ModelException if a non-legal
164      * configuration is encountered.
165      * </p>
166      * <p>
167      * This method is also first invoked when manually initializing the status of a state machine through
168      * {@link SCXMLExecutor#setConfiguration(java.util.Set}.
169      * </p>
170      * @param states a set of states
171      * @param errRep ErrorReporter to report detailed error info if needed
172      * @return true if a given state configuration is legal, false otherwise
173      */
174     public boolean isLegalConfiguration(final Set<EnterableState> states, final ErrorReporter errRep);
175 }