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.model;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 /**
23 * An abstract base class for state elements in SCXML that can be transitioned out from, such as State or Parallel.
24 */
25 public abstract class TransitionalState extends EnterableState {
26
27 /**
28 * A list of outgoing Transitions from this state, by document order.
29 */
30 private List<Transition> transitions;
31
32 /**
33 * Optional property holding the data model for this state.
34 */
35 private Datamodel datamodel;
36
37 /**
38 * List of history states owned by a given state (applies to non-leaf
39 * states).
40 */
41 private List<History> history;
42
43 /**
44 * The Invoke children, each which defines an external process that should
45 * be invoked, immediately after the onentry executable content,
46 * and the transitions become candidates after the invoked
47 * process has completed its execution.
48 * May occur 0 or more times.
49 */
50 private List<Invoke> invokes;
51
52 /**
53 * The set of EnterableState children contained in this TransitionalState
54 */
55 private List<EnterableState> children;
56
57 public TransitionalState() {
58 super();
59 transitions = new ArrayList<Transition>();
60 history = new ArrayList<History>();
61 children = new ArrayList<EnterableState>();
62 invokes = new ArrayList<Invoke>();
63 }
64
65 /**
66 * Update TransitionTarget descendants their ancestors
67 */
68 protected void updateDescendantsAncestors() {
69 super.updateDescendantsAncestors();
70 for (History h : history) {
71 // reset ancestors
72 h.updateDescendantsAncestors();
73 }
74 for (TransitionTarget child : children) {
75 child.updateDescendantsAncestors();
76 }
77 }
78
79 /**
80 * Get the TransitionalState (State or Parallel) parent.
81 *
82 * @return Returns the parent.
83 */
84 @Override
85 public TransitionalState getParent() {
86 return (TransitionalState)super.getParent();
87 }
88
89 /**
90 * Set the TransitionalState parent
91 *
92 * @param parent The parent to set.
93 */
94 public final void setParent(final TransitionalState parent) {
95 super.setParent(parent);
96 }
97
98 /**
99 * Get the ancestor of this TransitionalState at specified level
100 * @param level the level of the ancestor to return, zero being top
101 * @return the ancestor at specified level
102 */
103 @Override
104 public TransitionalState getAncestor(int level) {
105 return (TransitionalState)super.getAncestor(level);
106 }
107
108 /**
109 * Get the list of all outgoing transitions from this state, that
110 * will be candidates for being fired on the given event.
111 *
112 * @param event The event
113 * @return List Returns the candidate transitions for given event
114 */
115 public final List<Transition> getTransitionsList(final String event) {
116 List<Transition> matchingTransitions = null; // since we returned null upto v0.6
117 for (Transition t : transitions) {
118 if ((event == null && t.getEvent() == null)
119 || (event != null && event.equals(t.getEvent()))) {
120 if (matchingTransitions == null) {
121 matchingTransitions = new ArrayList<Transition>();
122 }
123 matchingTransitions.add(t);
124 }
125 }
126 return matchingTransitions;
127 }
128
129 /**
130 * Add a transition to the map of all outgoing transitions for
131 * this state.
132 *
133 * @param transition
134 * The transitions to set.
135 */
136 public final void addTransition(final Transition transition) {
137 transitions.add(transition);
138 transition.setParent(this);
139 }
140
141 /**
142 * Get the outgoing transitions for this state as a java.util.List.
143 *
144 * @return List Returns the transitions list.
145 */
146 public final List<Transition> getTransitionsList() {
147 return transitions;
148 }
149
150 /**
151 * Get the data model for this transition target.
152 *
153 * @return Returns the data model.
154 */
155 public final Datamodel getDatamodel() {
156 return datamodel;
157 }
158
159 /**
160 * Set the data model for this transition target.
161 *
162 * @param datamodel The Datamodel to set.
163 */
164 public final void setDatamodel(final Datamodel datamodel) {
165 this.datamodel = datamodel;
166 }
167
168 /**
169 * @param h History pseudo state
170 *
171 * @since 0.7
172 */
173 public final void addHistory(final History h) {
174 history.add(h);
175 h.setParent(this);
176 }
177
178 /**
179 * Does this state have a history pseudo state.
180 *
181 * @return boolean true if a given state contains at least one
182 * history pseudo state
183 *
184 * @since 0.7
185 */
186 public final boolean hasHistory() {
187 return (!history.isEmpty());
188 }
189
190 /**
191 * Get the list of history pseudo states for this state.
192 *
193 * @return a list of all history pseudo states contained by a given state
194 * (can be empty)
195 * @see #hasHistory()
196 *
197 * @since 0.7
198 */
199 public final List<History> getHistory() {
200 return history;
201 }
202
203 /**
204 * Get the Invoke children (may be empty).
205 *
206 * @return Invoke Returns the invoke.
207 */
208 public final List<Invoke> getInvokes() {
209 return invokes;
210 }
211
212 /**
213 * Set the Invoke child.
214 *
215 * @param invoke
216 * The invoke to set.
217 */
218 public final void addInvoke(final Invoke invoke) {
219 this.invokes.add(invoke);
220 invoke.setParentEnterableState(this);
221 }
222
223 /**
224 * Get the set of child transition targets (may be empty).
225 *
226 * @return Returns the children.
227 *
228 * @since 0.7
229 */
230 public final List<EnterableState> getChildren() {
231 return children;
232 }
233
234 /**
235 * Add a child.
236 *
237 * @param es A child enterable state.
238 *
239 * @since 0.7
240 */
241 protected void addChild(final EnterableState es) {
242 children.add(es);
243 es.setParent(this);
244 }
245 }