001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.scxml2; 018 019import java.util.Set; 020 021import org.apache.commons.scxml2.model.EnterableState; 022import org.apache.commons.scxml2.model.ModelException; 023import org.apache.commons.scxml2.model.SCXML; 024 025/** 026 * <p>The purpose of this interface is to separate the the 027 * <a href="http://www.w3.org/TR/2014/CR-scxml-20140313/#AlgorithmforSCXMLInterpretation"> 028 * W3C SCXML Algorithm for SCXML Interpretation</a> 029 * from the <code>SCXMLExecutor</code> and therefore make it pluggable.</p> 030 * <p> 031 * From an SCXML execution POV, there are only three entry points needed into the Algorithm, namely: 032 * <ul> 033 * <li>Performing the initialization of the state machine and completing a first macro step, 034 * see: {@link #firstStep(SCXMLExecutionContext)}. The state machine thereafter should be ready 035 * for processing external events (or be terminated already)</li> 036 * <li>Processing a single external event and completing the macro step for it, after which the 037 * state machine should be ready for processing another external event (if any), or be terminated already. 038 * See: {@link #nextStep(SCXMLExecutionContext, TriggerEvent)}. 039 * </li> 040 * <li>Finally, if the state machine terminated ({@link SCXMLExecutionContext#isRunning()} == false), after either 041 * of the above steps, finalize the state machine by performing the final step. 042 * See: {@link #finalStep(SCXMLExecutionContext)}. 043 * </li> 044 * </ul> 045 * </p> 046 * <p>After a state machine has been terminated you can re-initialize the execution context, and start again.</p> 047 * <p> 048 * Except for the loading of the SCXML document and (re)initializing the {@link SCXMLExecutionContext}, the above steps 049 * represent the <b>interpret</b>,<b>mainEventLoop</b> and <b>exitInterpreter</b> entry points specified in Algorithm 050 * for SCXML Interpretation, but more practically and logically broken into separate steps so that the blocking wait 051 * for external events can be handled externally. 052 * </p> 053 * <p> 054 * These three entry points are the only interface methods used by the SCXMLExecutor. It is up to the 055 * specific SCXMLSemantics implementation to provide the concrete handling for these according to the Algorithm in 056 * the SCXML specification (or possibly something else/different). 057 * </p> 058 * <p> 059 * The default {@link org.apache.commons.scxml2.semantics.SCXMLSemanticsImpl} provides an implementation of the 060 * specification, and can easily be overridden/customized as a whole or only on specific parts of the Algorithm 061 * implementation. 062 * </p> 063 * <p> 064 * Note that both the {@link #firstStep(SCXMLExecutionContext)} and {@link #nextStep(SCXMLExecutionContext, TriggerEvent)} 065 * first run to completion for any internal events raised before returning, as expected and required by the SCXML 066 * specification, so it is currently not possible to 'manage' internal event processing externally. 067 * </p> 068 * 069 * <p>Specific semantics can be created by subclassing 070 * <code>org.apache.commons.scxml2.semantics.SCXMLSemanticsImpl</code>.</p> 071 */ 072public interface SCXMLSemantics { 073 074 /** 075 * Optional post processing immediately following SCXMLReader. May be used 076 * for removing pseudo-states etc. 077 * 078 * @param input SCXML state machine 079 * @param errRep ErrorReporter callback 080 * @return normalized SCXML state machine, pseudo states are removed, etc. 081 */ 082 SCXML normalizeStateMachine(final SCXML input, final ErrorReporter errRep); 083 084 /** 085 * First step in the execution of an SCXML state machine. 086 * <p> 087 * In the default implementation, this will first (re)initialize the state machine instance, destroying any existing 088 * state! 089 * </p> 090 * <p> 091 * The first step is corresponding to the Algorithm for SCXML processing from the interpret() procedure to the 092 * mainLoop() procedure up to the blocking wait for an external event. 093 * </p> 094 * <p> 095 * This step should complete the SCXML initial execution and a subsequent macroStep to stabilize the state machine 096 * again before returning. 097 * </p> 098 * <p> 099 * 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}