1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml2.env;
18
19 import java.io.IOException;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.net.URL;
23
24 import javax.xml.stream.XMLStreamException;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.commons.scxml2.Context;
29 import org.apache.commons.scxml2.Evaluator;
30 import org.apache.commons.scxml2.SCXMLExecutor;
31 import org.apache.commons.scxml2.SCXMLListener;
32 import org.apache.commons.scxml2.TriggerEvent;
33 import org.apache.commons.scxml2.env.jexl.JexlContext;
34 import org.apache.commons.scxml2.env.jexl.JexlEvaluator;
35 import org.apache.commons.scxml2.io.SCXMLReader;
36 import org.apache.commons.scxml2.model.EnterableState;
37 import org.apache.commons.scxml2.model.ModelException;
38 import org.apache.commons.scxml2.model.SCXML;
39 import org.apache.commons.scxml2.model.Transition;
40 import org.apache.commons.scxml2.model.TransitionTarget;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public abstract class AbstractStateMachine {
67
68
69
70
71 private SCXML stateMachine;
72
73
74
75
76 private SCXMLExecutor engine;
77
78
79
80
81 private Log log;
82
83
84
85
86
87 private static final Class<?>[] SIGNATURE = new Class[0];
88
89
90
91
92
93 private static final Object[] PARAMETERS = new Object[0];
94
95
96
97
98
99
100
101
102 public AbstractStateMachine(final URL scxmlDocument) throws ModelException {
103
104 this(scxmlDocument, new JexlContext(), new JexlEvaluator());
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public AbstractStateMachine(final URL scxmlDocument,
120 final Context rootCtx, final Evaluator evaluator) throws ModelException {
121 log = LogFactory.getLog(this.getClass());
122 try {
123 stateMachine = SCXMLReader.read(scxmlDocument);
124 } catch (IOException ioe) {
125 logError(ioe);
126 } catch (XMLStreamException xse) {
127 logError(xse);
128 } catch (ModelException me) {
129 logError(me);
130 }
131 initialize(stateMachine, rootCtx, evaluator);
132 }
133
134
135
136
137
138
139
140
141
142
143 public AbstractStateMachine(final SCXML stateMachine) throws ModelException {
144
145 this(stateMachine, new JexlContext(), new JexlEvaluator());
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 public AbstractStateMachine(final SCXML stateMachine,
163 final Context rootCtx, final Evaluator evaluator) throws ModelException {
164 log = LogFactory.getLog(this.getClass());
165 initialize(stateMachine, rootCtx, evaluator);
166 }
167
168
169
170
171
172
173
174
175 private void initialize(final SCXML stateMachine,
176 final Context rootCtx, final Evaluator evaluator) throws ModelException {
177 engine = new SCXMLExecutor(evaluator, new SimpleDispatcher(),
178 new SimpleErrorReporter());
179 engine.setStateMachine(stateMachine);
180 engine.setRootContext(rootCtx);
181 engine.addListener(stateMachine, new EntryListener());
182 try {
183 engine.go();
184 } catch (ModelException me) {
185 logError(me);
186 }
187 }
188
189
190
191
192
193
194
195
196 public boolean fireEvent(final String event) {
197 TriggerEvent[] evts = {new TriggerEvent(event,
198 TriggerEvent.SIGNAL_EVENT)};
199 try {
200 engine.triggerEvents(evts);
201 } catch (ModelException me) {
202 logError(me);
203 }
204 return engine.getStatus().isFinal();
205 }
206
207
208
209
210
211
212
213 public SCXMLExecutor getEngine() {
214 return engine;
215 }
216
217
218
219
220
221
222 public Log getLog() {
223 return log;
224 }
225
226
227
228
229
230
231 public void setLog(final Log log) {
232 this.log = log;
233 }
234
235
236
237
238
239
240
241 public boolean invoke(final String methodName) {
242 Class<?> clas = this.getClass();
243 try {
244 Method method = clas.getDeclaredMethod(methodName, SIGNATURE);
245 method.invoke(this, PARAMETERS);
246 } catch (SecurityException se) {
247 logError(se);
248 return false;
249 } catch (NoSuchMethodException nsme) {
250 logError(nsme);
251 return false;
252 } catch (IllegalArgumentException iae) {
253 logError(iae);
254 return false;
255 } catch (IllegalAccessException iae) {
256 logError(iae);
257 return false;
258 } catch (InvocationTargetException ite) {
259 logError(ite);
260 return false;
261 }
262 return true;
263 }
264
265
266
267
268
269
270 public boolean resetMachine() {
271 try {
272 engine.reset();
273 } catch (ModelException me) {
274 logError(me);
275 return false;
276 }
277 return true;
278 }
279
280
281
282
283
284
285 protected void logError(final Exception exception) {
286 if (log.isErrorEnabled()) {
287 log.error(exception.getMessage(), exception);
288 }
289 }
290
291
292
293
294
295 protected class EntryListener implements SCXMLListener {
296
297
298
299
300 public void onEntry(final EnterableState entered) {
301 invoke(entered.getId());
302 }
303
304
305
306
307
308
309
310
311
312 public void onTransition(final TransitionTarget from,
313 final TransitionTarget to, final Transition transition, final String event) {
314
315 }
316
317
318
319
320
321
322 public void onExit(final EnterableState exited) {
323
324 }
325
326 }
327
328 }
329