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.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   * &lt;state&gt; 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 &quot;final&quot; 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 &quot;final&quot; 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 &quot;final&quot; 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 &quot;final&quot; 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 &lt;parallel&gt; no longer needs an enclosing
    144      *             &lt;state&gt; 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 &lt;parallel&gt; no longer needs an enclosing
    157      *             &lt;state&gt; 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; // since we returned null upto v0.6
    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 &lt;parallel&gt; 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