1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml.model;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.LinkedHashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 /***
26 * The class in this SCXML object model that corresponds to the
27 * <state> SCXML element.
28 *
29 */
30 public class State extends TransitionTarget {
31
32 /***
33 * Serial version UID.
34 */
35 private static final long serialVersionUID = 2L;
36
37 /***
38 * The Map containing immediate children of this State, keyed by
39 * their IDs. Incompatible with the parallel or invoke property.
40 */
41 private Map children;
42
43 /***
44 * The Parallel child, which defines a set of parallel substates.
45 * May occur 0 or 1 times. Incompatible with the state or invoke property.
46 */
47 private Parallel parallel;
48
49 /***
50 * The Invoke child, which defines an external process that should
51 * be invoked, immediately after the onentry executable content,
52 * and the transitions become candidates after the invoked
53 * process has completed its execution.
54 * May occur 0 or 1 times. Incompatible with the state or parallel
55 * property.
56 */
57 private Invoke invoke;
58
59 /***
60 * Boolean property indicating whether this is a final state or not.
61 * Default value is false . Final states may not have substates or
62 * outgoing transitions.
63 */
64 private boolean isFinal;
65
66 /***
67 * A child which identifies initial state for state machines that
68 * have substates.
69 */
70 private Initial initial;
71
72 /***
73 * A list of outgoing Transitions from this state, by document order.
74 */
75 private List transitions;
76
77 /***
78 * Applies to composite states only. If one of its final children is
79 * active, its parent is marked done. This property is reset upon
80 * re-entry.
81 *
82 * @deprecated Will be removed in v1.0
83 */
84 private boolean done = false;
85
86 /***
87 * Constructor.
88 */
89 public State() {
90 this.children = new LinkedHashMap();
91 this.transitions = new ArrayList();
92 }
93
94 /***
95 * Is this state a "final" state.
96 *
97 * @return boolean Returns the isFinal.
98 * @deprecated Use {@link #isFinal()} instead
99 */
100 public final boolean getIsFinal() {
101 return isFinal;
102 }
103
104 /***
105 * Set whether this is a "final" state.
106 *
107 * @param isFinal
108 * The isFinal to set.
109 * @deprecated Use {@link #setFinal(boolean)} instead
110 */
111 public final void setIsFinal(final boolean isFinal) {
112 this.isFinal = isFinal;
113 }
114
115 /***
116 * Is this state a "final" state.
117 *
118 * @return boolean Returns the isFinal.
119 *
120 * @since 0.7
121 */
122 public final boolean isFinal() {
123 return isFinal;
124 }
125
126 /***
127 * Set whether this is a "final" state.
128 *
129 * @param isFinal
130 * The isFinal to set.
131 *
132 * @since 0.7
133 */
134 public final void setFinal(final boolean isFinal) {
135 this.isFinal = isFinal;
136 }
137
138 /***
139 * Get the Parallel child (may be null).
140 *
141 * @return Parallel Returns the parallel.
142 *
143 * @deprecated <parallel> no longer needs an enclosing
144 * <state> element.
145 */
146 public final Parallel getParallel() {
147 return parallel;
148 }
149
150 /***
151 * Set the Parallel child.
152 *
153 * @param parallel
154 * The parallel to set.
155 *
156 * @deprecated <parallel> no longer needs an enclosing
157 * <state> element.
158 */
159 public final void setParallel(final Parallel parallel) {
160 this.parallel = parallel;
161 }
162
163 /***
164 * Get the Invoke child (may be null).
165 *
166 * @return Invoke Returns the invoke.
167 */
168 public final Invoke getInvoke() {
169 return invoke;
170 }
171
172 /***
173 * Set the Invoke child.
174 *
175 * @param invoke
176 * The invoke to set.
177 */
178 public final void setInvoke(final Invoke invoke) {
179 this.invoke = invoke;
180 }
181
182 /***
183 * Get the initial state.
184 *
185 * @return Initial Returns the initial state.
186 */
187 public final Initial getInitial() {
188 return initial;
189 }
190
191 /***
192 * Set the initial state.
193 *
194 * @param target
195 * The target to set.
196 */
197 public final void setInitial(final Initial target) {
198 this.initial = target;
199 target.setParent(this);
200 }
201
202 /***
203 * Get the map of all outgoing transitions from this state.
204 *
205 * @return Map Returns the transitions Map.
206 * @deprecated Use {@link #getTransitionsList()} instead
207 */
208 public final Map getTransitions() {
209 Map transitionsMap = new HashMap();
210 for (int i = 0; i < transitions.size(); i++) {
211 Transition transition = (Transition) transitions.get(i);
212 String event = transition.getEvent();
213 if (!transitionsMap.containsKey(event)) {
214 List eventTransitions = new ArrayList();
215 eventTransitions.add(transition);
216 transitionsMap.put(event, eventTransitions);
217 } else {
218 ((List) transitionsMap.get(event)).add(transition);
219 }
220 }
221 return transitionsMap;
222 }
223
224 /***
225 * Get the list of all outgoing transitions from this state, that
226 * will be candidates for being fired on the given event.
227 *
228 * @param event The event
229 * @return List Returns the candidate transitions for given event
230 */
231 public final List getTransitionsList(final String event) {
232 List matchingTransitions = null;
233 for (int i = 0; i < transitions.size(); i++) {
234 Transition t = (Transition) transitions.get(i);
235 if ((event == null && t.getEvent() == null)
236 || (event != null && event.equals(t.getEvent()))) {
237 if (matchingTransitions == null) {
238 matchingTransitions = new ArrayList();
239 }
240 matchingTransitions.add(t);
241 }
242 }
243 return matchingTransitions;
244 }
245
246 /***
247 * Add a transition to the map of all outgoing transitions for
248 * this state.
249 *
250 * @param transition
251 * The transitions to set.
252 */
253 public final void addTransition(final Transition transition) {
254 transitions.add(transition);
255 transition.setParent(this);
256 }
257
258 /***
259 * Get the map of child states (may be empty).
260 *
261 * @return Map Returns the children.
262 */
263 public final Map getChildren() {
264 return children;
265 }
266
267 /***
268 * Add a child state.
269 *
270 * @param state
271 * a child state
272 *
273 * @deprecated Use {@link #addChild(TransitionTarget)} instead.
274 */
275 public final void addChild(final State state) {
276 this.children.put(state.getId(), state);
277 state.setParent(this);
278 }
279
280 /***
281 * Add a child transition target.
282 *
283 * @param tt
284 * a child transition target
285 *
286 * @since 0.7
287 */
288 public final void addChild(final TransitionTarget tt) {
289 this.children.put(tt.getId(), tt);
290 tt.setParent(this);
291 }
292
293 /***
294 * Get the outgoing transitions for this state as a java.util.List.
295 *
296 * @return List Returns the transitions list.
297 */
298 public final List getTransitionsList() {
299 return transitions;
300 }
301
302 /***
303 * Check whether this is a simple (leaf) state (UML terminology).
304 *
305 * @return true if this is a simple state, otherwise false
306 */
307 public final boolean isSimple() {
308 if (parallel == null && children.isEmpty()) {
309 return true;
310 }
311 return false;
312 }
313
314 /***
315 * Check whether this is a composite state (UML terminology).
316 *
317 * @return true if this is a composite state, otherwise false
318 */
319 public final boolean isComposite() {
320 if (parallel == null && children.isEmpty()) {
321 return false;
322 }
323 return true;
324 }
325
326 /***
327 * Checks whether it is a region state (directly nested to parallel - UML
328 * terminology).
329 *
330 * @return true if this is a region state, otherwise false
331 * @see Parallel
332 */
333 public final boolean isRegion() {
334 if (getParent() instanceof Parallel) {
335 return true;
336 }
337 return false;
338 }
339
340 /***
341 * Checks whether it is a orthogonal state, that is, it owns a parallel
342 * (UML terminology).
343 *
344 * @return true if this is a orthogonal state, otherwise false
345 * @deprecated <parallel> now represents an orthogonal state, rather
346 * than denoting that the enclosing state is orthogonal, as
347 * it did in previous SCXML WDs.
348 */
349 public final boolean isOrthogonal() {
350 if (parallel != null) {
351 return true;
352 }
353 return false;
354 }
355
356 /***
357 * In case this is a parallel state, check if one its final states
358 * is active.
359 *
360 * @return Returns the done.
361 * @deprecated Will be removed in v1.0, in favor of
362 * <code>SCInstance#isDone(TransitionTarget)</code>
363 */
364 public final boolean isDone() {
365 return done;
366 }
367
368 /***
369 * Update the done property, which is set if this is a parallel state,
370 * and one its final states is active.
371 *
372 * @param done The done to set.
373 * @deprecated Will be removed in v1.0, in favor of
374 * <code>SCInstance#setDone(TransitionTarget)</code>
375 */
376 public final void setDone(final boolean done) {
377 this.done = done;
378 }
379 }
380