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.io.Serializable; 20 import java.util.ArrayList; 21 import java.util.HashMap; 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 * <scxml> root element, and serves as the "document 28 * root". 29 * 30 */ 31 public class SCXML implements Serializable, Observable, 32 NamespacePrefixesHolder { 33 34 /** 35 * Serial version UID. 36 */ 37 private static final long serialVersionUID = 2L; 38 39 /** 40 * The SCXML XMLNS. 41 */ 42 @SuppressWarnings("unused") 43 public static final String XMLNS = "http://www.w3.org/2005/07/scxml"; 44 45 /** 46 * Reserved prefix for auto generated TransitionTarget id values 47 */ 48 public static final String GENERATED_TT_ID_PREFIX = "_generated_tt_id_"; 49 50 /** 51 * The predefined observableId with value 0 (zero) for this SCXML state machine 52 */ 53 private static final Integer SCXML_OBSERVABLE_ID = 0; 54 55 /** 56 * The xmlns attribute on the root <smxml> element. 57 * This must match XMLNS above. 58 */ 59 private String xmlns; 60 61 /** 62 * The SCXML version of this document. 63 */ 64 private String version; 65 66 /** 67 * The initial Transition for the SCXML executor. 68 */ 69 private SimpleTransition initialTransition; 70 71 /** 72 * The initial transition target ID 73 */ 74 private String initial; 75 76 /** 77 * The name for this state machine. 78 */ 79 private String name; 80 81 /** 82 * The profile in use. 83 */ 84 private String profile; 85 86 /** 87 * The exmode for this document. 88 */ 89 private String exmode; 90 91 92 /** 93 * The datamodel name as specified as "datamodel" attribute on this document 94 */ 95 private String datamodelName; 96 97 /** 98 * Optional property holding the data model for this SCXML document. 99 * This gets merged with the root context and potentially hides any 100 * (namesake) variables in the root context. 101 */ 102 private Datamodel datamodel; 103 104 /** 105 * Optional property holding the initial script for this SCXML document. 106 */ 107 private Script globalScript; 108 109 /** 110 * The immediate child targets of this SCXML document root. 111 */ 112 private List<EnterableState> children; 113 114 /** 115 * A global map of all States and Parallels associated with this 116 * state machine, keyed by their id. 117 */ 118 private Map<String, TransitionTarget> targets; 119 120 /** 121 * The XML namespaces defined on the SCXML document root node, 122 * preserved primarily for serialization. 123 */ 124 private Map<String, String> namespaces; 125 126 /** 127 * The next auto-generated transition target unique id value 128 * @see #generateTransitionTargetId() 129 */ 130 private long ttNextId; 131 132 /** 133 * Constructor. 134 */ 135 public SCXML() { 136 this.children = new ArrayList<EnterableState>(); 137 this.targets = new HashMap<String, TransitionTarget>(); 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 public final Integer getObservableId() { 144 return SCXML_OBSERVABLE_ID; 145 } 146 147 /** 148 * Simple unique TransitionTarget id value generation 149 * @return a unique TransitionTarget id for this SCXML instance 150 */ 151 public final String generateTransitionTargetId() { 152 return GENERATED_TT_ID_PREFIX +ttNextId++; 153 } 154 155 public final Script getGlobalScript() { 156 return globalScript; 157 } 158 159 public final void setGlobalScript(Script script) { 160 this.globalScript = script; 161 } 162 163 /** 164 * Get the initial Transition. 165 * 166 * @return Returns the initial transition for this state machine. 167 * 168 * @since 2.0 169 */ 170 public final SimpleTransition getInitialTransition() { 171 return initialTransition; 172 } 173 174 /** 175 * Set the initial Transition. 176 * <p>Note: the initial transition can/may not have executable content!</p> 177 * 178 * @param initialTransition The initial transition to set. 179 * 180 * @since 2.0 181 */ 182 public final void setInitialTransition(final SimpleTransition initialTransition) { 183 this.initialTransition = initialTransition; 184 } 185 186 /** 187 * Get the data model placed at document root. 188 * 189 * @return Returns the data model. 190 */ 191 public final Datamodel getDatamodel() { 192 return datamodel; 193 } 194 195 /** 196 * Set the data model at document root. 197 * 198 * @param datamodel The Datamodel to set. 199 */ 200 public final void setDatamodel(final Datamodel datamodel) { 201 this.datamodel = datamodel; 202 } 203 204 /** 205 * Get the immediate child targets of the SCXML root. 206 * 207 * @return List Returns list of the child targets. 208 * 209 * @since 0.7 210 */ 211 public final List<EnterableState> getChildren() { 212 return children; 213 } 214 215 /** 216 * Get the first immediate child of the SCXML root. Return null if there's no child. 217 * 218 * @return Returns the first immediate child of the SCXML root. Return null if there's no child. 219 * 220 * @since 2.0 221 */ 222 public final EnterableState getFirstChild() { 223 if (!children.isEmpty()) { 224 return children.get(0); 225 } 226 return null; 227 } 228 229 /** 230 * Add an immediate child of the SCXML root. 231 * 232 * @param es The child to be added. 233 * 234 * @since 0.7 235 */ 236 public final void addChild(final EnterableState es) { 237 children.add(es); 238 } 239 240 /** 241 * Get the targets map, which is a Map of all States and Parallels 242 * associated with this state machine, keyed by their id. 243 * 244 * @return Map Returns the targets. 245 */ 246 public final Map<String, TransitionTarget> getTargets() { 247 return targets; 248 } 249 250 /** 251 * Add a target to this SCXML document. 252 * 253 * @param target The target to be added to the targets Map. 254 */ 255 public final void addTarget(final TransitionTarget target) { 256 targets.put(target.getId(), target); 257 } 258 259 /** 260 * Get the SCXML document version. 261 * 262 * @return Returns the version. 263 */ 264 public final String getVersion() { 265 return version; 266 } 267 268 /** 269 * Set the SCXML document version. 270 * 271 * @param version The version to set. 272 */ 273 public final void setVersion(final String version) { 274 this.version = version; 275 } 276 277 /** 278 * Get the xmlns of this SCXML document. 279 * 280 * @return Returns the xmlns. 281 */ 282 public final String getXmlns() { 283 return xmlns; 284 } 285 286 /** 287 * Set the xmlns of this SCXML document. 288 * 289 * @param xmlns The xmlns to set. 290 */ 291 public final void setXmlns(final String xmlns) { 292 this.xmlns = xmlns; 293 } 294 295 /** 296 * Get the namespace definitions specified on the SCXML element. 297 * May be <code>null</code>. 298 * 299 * @return The namespace definitions specified on the SCXML element, 300 * may be <code>null</code>. 301 */ 302 public final Map<String, String> getNamespaces() { 303 return namespaces; 304 } 305 306 /** 307 * Set the namespace definitions specified on the SCXML element. 308 * 309 * @param namespaces The namespace definitions specified on the 310 * SCXML element. 311 */ 312 public final void setNamespaces(final Map<String, String> namespaces) { 313 this.namespaces = namespaces; 314 } 315 316 /** 317 * Get the the initial transition target. 318 * 319 * @return String Returns the initial transition target ID 320 * @see #getInitialTransition() 321 */ 322 public final String getInitial() { 323 return initial; 324 } 325 326 /** 327 * Set the initial transition target. 328 * 329 * @param initial The initial transition target 330 * @see #setInitialTransition(SimpleTransition) 331 */ 332 public final void setInitial(final String initial) { 333 this.initial = initial; 334 } 335 336 /** 337 * Get the name for this state machine. 338 * 339 * @return The name for this state machine. 340 */ 341 public String getName() { 342 return name; 343 } 344 345 /** 346 * Set the name for this state machine. 347 * 348 * @param name The name for this state machine. 349 */ 350 public void setName(String name) { 351 this.name = name; 352 } 353 354 /** 355 * Get the profile in use for this state machine. 356 * 357 * @return The profile in use. 358 */ 359 public String getProfile() { 360 return profile; 361 } 362 363 /** 364 * Set the profile in use for this state machine. 365 * 366 * @param profile The profile to be used. 367 */ 368 public void setProfile(String profile) { 369 this.profile = profile; 370 } 371 372 /** 373 * Get the exmode in use for this state machine. 374 * 375 * @return The exmode in use. 376 */ 377 public String getExmode() { 378 return exmode; 379 } 380 381 /** 382 * Set the exmode to be used for this state machine. 383 * 384 * @param exmode The exmode to be used. 385 */ 386 public void setExmode(String exmode) { 387 this.exmode = exmode; 388 } 389 390 /** 391 * Get the datamodel name as specified as attribute on this document 392 * @return The datamodel name of this document 393 */ 394 public String getDatamodelName() { 395 return datamodelName; 396 } 397 398 /** 399 * Sets the datamodel name as specified as attribute on this document 400 * @param datamodelName The datamodel name 401 */ 402 public void setDatamodelName(final String datamodelName) { 403 this.datamodelName = datamodelName; 404 } 405 } 406