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 }