View Javadoc
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 }