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 }