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 */ 017package org.apache.commons.scxml2.model; 018 019import java.io.Serializable; 020import java.util.ArrayList; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025/** 026 * The class in this SCXML object model that corresponds to the 027 * <scxml> root element, and serves as the "document 028 * root". 029 * 030 */ 031public class SCXML implements Serializable, Observable, 032 NamespacePrefixesHolder { 033 034 /** 035 * Serial version UID. 036 */ 037 private static final long serialVersionUID = 2L; 038 039 /** 040 * The SCXML XMLNS. 041 */ 042 @SuppressWarnings("unused") 043 public static final String XMLNS = "http://www.w3.org/2005/07/scxml"; 044 045 /** 046 * Reserved prefix for auto generated TransitionTarget id values 047 */ 048 public static final String GENERATED_TT_ID_PREFIX = "_generated_tt_id_"; 049 050 /** 051 * The predefined observableId with value 0 (zero) for this SCXML state machine 052 */ 053 private static final Integer SCXML_OBSERVABLE_ID = 0; 054 055 /** 056 * The xmlns attribute on the root <smxml> element. 057 * This must match XMLNS above. 058 */ 059 private String xmlns; 060 061 /** 062 * The SCXML version of this document. 063 */ 064 private String version; 065 066 /** 067 * The initial Transition for the SCXML executor. 068 */ 069 private SimpleTransition initialTransition; 070 071 /** 072 * The initial transition target ID 073 */ 074 private String initial; 075 076 /** 077 * The name for this state machine. 078 */ 079 private String name; 080 081 /** 082 * The profile in use. 083 */ 084 private String profile; 085 086 /** 087 * The exmode for this document. 088 */ 089 private String exmode; 090 091 092 /** 093 * The datamodel name as specified as "datamodel" attribute on this document 094 */ 095 private String datamodelName; 096 097 /** 098 * Optional property holding the data model for this SCXML document. 099 * 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