001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.scxml.model; 018 019 import java.util.LinkedHashMap; 020 import java.util.Map; 021 022 /** 023 * The class in this SCXML object model that corresponds to the 024 * <state> SCXML element. 025 * 026 */ 027 public class State extends TransitionTarget { 028 029 /** 030 * Serial version UID. 031 */ 032 private static final long serialVersionUID = 2L; 033 034 /** 035 * The Map containing immediate children of this State, keyed by 036 * their IDs. Incompatible with the parallel or invoke property. 037 */ 038 private Map children; 039 040 /** 041 * The Parallel child, which defines a set of parallel substates. 042 * May occur 0 or 1 times. Incompatible with the state or invoke property. 043 */ 044 private Parallel parallel; 045 046 /** 047 * The Invoke child, which defines an external process that should 048 * be invoked, immediately after the onentry executable content, 049 * and the transitions become candidates after the invoked 050 * process has completed its execution. 051 * May occur 0 or 1 times. Incompatible with the state or parallel 052 * property. 053 */ 054 private Invoke invoke; 055 056 /** 057 * Boolean property indicating whether this is a final state or not. 058 * Default value is false . Final states may not have substates or 059 * outgoing transitions. 060 */ 061 private boolean isFinal; 062 063 /** 064 * A child which identifies initial state for state machines that 065 * have substates. 066 */ 067 private Initial initial; 068 069 /** 070 * Applies to composite states only. If one of its final children is 071 * active, its parent is marked done. This property is reset upon 072 * re-entry. 073 * 074 * @deprecated Will be removed in v1.0 075 */ 076 private boolean done = false; 077 078 /** 079 * Constructor. 080 */ 081 public State() { 082 this.children = new LinkedHashMap(); 083 } 084 085 /** 086 * Is this state a "final" state. 087 * 088 * @return boolean Returns the isFinal. 089 * @deprecated Use {@link #isFinal()} instead 090 */ 091 public final boolean getIsFinal() { 092 return isFinal; 093 } 094 095 /** 096 * Set whether this is a "final" state. 097 * 098 * @param isFinal 099 * The isFinal to set. 100 * @deprecated Use {@link #setFinal(boolean)} instead 101 */ 102 public final void setIsFinal(final boolean isFinal) { 103 this.isFinal = isFinal; 104 } 105 106 /** 107 * Is this state a "final" state. 108 * 109 * @return boolean Returns the isFinal. 110 * 111 * @since 0.7 112 */ 113 public final boolean isFinal() { 114 return isFinal; 115 } 116 117 /** 118 * Set whether this is a "final" state. 119 * 120 * @param isFinal 121 * The isFinal to set. 122 * 123 * @since 0.7 124 */ 125 public final void setFinal(final boolean isFinal) { 126 this.isFinal = isFinal; 127 } 128 129 /** 130 * Get the Parallel child (may be null). 131 * 132 * @return Parallel Returns the parallel. 133 * 134 * @deprecated <parallel> no longer needs an enclosing 135 * <state> element. 136 */ 137 public final Parallel getParallel() { 138 return parallel; 139 } 140 141 /** 142 * Set the Parallel child. 143 * 144 * @param parallel 145 * The parallel to set. 146 * 147 * @deprecated <parallel> no longer needs an enclosing 148 * <state> element. 149 */ 150 public final void setParallel(final Parallel parallel) { 151 this.parallel = parallel; 152 } 153 154 /** 155 * Get the Invoke child (may be null). 156 * 157 * @return Invoke Returns the invoke. 158 */ 159 public final Invoke getInvoke() { 160 return invoke; 161 } 162 163 /** 164 * Set the Invoke child. 165 * 166 * @param invoke 167 * The invoke to set. 168 */ 169 public final void setInvoke(final Invoke invoke) { 170 this.invoke = invoke; 171 } 172 173 /** 174 * Get the initial state. 175 * 176 * @return Initial Returns the initial state. 177 */ 178 public final Initial getInitial() { 179 return initial; 180 } 181 182 /** 183 * Set the initial state. 184 * 185 * @param target 186 * The target to set. 187 */ 188 public final void setInitial(final Initial target) { 189 this.initial = target; 190 target.setParent(this); 191 } 192 193 /** 194 * Get the initial state's ID. 195 * 196 * @return The initial state's string ID. 197 */ 198 public final String getFirst() { 199 if (initial != null) { 200 return initial.getTransition().getNext(); 201 } 202 return null; 203 } 204 205 /** 206 * Set the initial state by its ID string. 207 * 208 * @param target 209 * The initial target's ID to set. 210 */ 211 public final void setFirst(final String target) { 212 Transition t = new Transition(); 213 t.setNext(target); 214 Initial ini = new Initial(); 215 ini.setTransition(t); 216 ini.setParent(this); 217 this.initial = ini; 218 } 219 220 /** 221 * Get the map of child states (may be empty). 222 * 223 * @return Map Returns the children. 224 */ 225 public final Map getChildren() { 226 return children; 227 } 228 229 /** 230 * Add a child state. 231 * 232 * @param state 233 * a child state 234 * 235 * @deprecated Use {@link #addChild(TransitionTarget)} instead. 236 */ 237 public final void addChild(final State state) { 238 this.children.put(state.getId(), state); 239 state.setParent(this); 240 } 241 242 /** 243 * Add a child transition target. 244 * 245 * @param tt 246 * a child transition target 247 * 248 * @since 0.7 249 */ 250 public final void addChild(final TransitionTarget tt) { 251 this.children.put(tt.getId(), tt); 252 tt.setParent(this); 253 } 254 255 /** 256 * Check whether this is a simple (leaf) state (UML terminology). 257 * 258 * @return true if this is a simple state, otherwise false 259 */ 260 public final boolean isSimple() { 261 if (parallel == null && children.isEmpty()) { 262 return true; 263 } 264 return false; 265 } 266 267 /** 268 * Check whether this is a composite state (UML terminology). 269 * 270 * @return true if this is a composite state, otherwise false 271 */ 272 public final boolean isComposite() { 273 if (parallel == null && children.isEmpty()) { 274 return false; 275 } 276 return true; 277 } 278 279 /** 280 * Checks whether it is a region state (directly nested to parallel - UML 281 * terminology). 282 * 283 * @return true if this is a region state, otherwise false 284 * @see Parallel 285 */ 286 public final boolean isRegion() { 287 if (getParent() instanceof Parallel) { 288 return true; 289 } 290 return false; 291 } 292 293 /** 294 * Checks whether it is a orthogonal state, that is, it owns a parallel 295 * (UML terminology). 296 * 297 * @return true if this is a orthogonal state, otherwise false 298 * @deprecated <parallel> now represents an orthogonal state, rather 299 * than denoting that the enclosing state is orthogonal, as 300 * it did in previous SCXML WDs. 301 */ 302 public final boolean isOrthogonal() { 303 if (parallel != null) { 304 return true; 305 } 306 return false; 307 } 308 309 /** 310 * In case this is a parallel state, check if one its final states 311 * is active. 312 * 313 * @return Returns the done. 314 * @deprecated Will be removed in v1.0, in favor of 315 * <code>SCInstance#isDone(TransitionTarget)</code> 316 */ 317 public final boolean isDone() { 318 return done; 319 } 320 321 /** 322 * Update the done property, which is set if this is a parallel state, 323 * and one its final states is active. 324 * 325 * @param done The done to set. 326 * @deprecated Will be removed in v1.0, in favor of 327 * <code>SCInstance#setDone(TransitionTarget)</code> 328 */ 329 public final void setDone(final boolean done) { 330 this.done = done; 331 } 332 } 333