    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.io.Serializable;
    020    import java.util.HashMap;
    021    import java.util.LinkedHashMap;
    022    import java.util.Map;
    023
    024    import org.apache.commons.scxml.SCXMLHelper;
    025
    026    /**
    027     * The class in this SCXML object model that corresponds to the
    028     * <scxml> root element, and serves as the "document
    029     * root".
    030     *
    031     */
    032    public class SCXML implements Serializable, NamespacePrefixesHolder {
    033
    034        /**
    035         * Serial version UID.
    036         */
    037        private static final long serialVersionUID = 2L;
    038
    039        /**
    040         * The SCXML XMLNS.
    041         */
    042        public static final String XMLNS = "http://www.w3.org/2005/07/scxml";
    043
    044        /**
    045         * The xmlns attribute on the root <smxml> element.
    046         * This must match XMLNS above.
    047         */
    048        private String xmlns;
    049
    050        /**
    051         * The SCXML version of this document.
    052         */
    053        private String version;
    054
    055        /**
    056         * The initial TransitionTarget for the SCXML executor.
    057         */
    058        private TransitionTarget initialTarget;
    059
    060        /**
    061         * The initial transition target ID (used by XML Digester only).
    062         */
    063        private String initial;
    064
    065        /**
    066         * Optional property holding the data model for this SCXML document.
    067         * This gets merged with the root context and potentially hides any
    068         * (namesake) variables in the root context.
    069         */
    070        private Datamodel datamodel;
    071
    072        /**
    073         * The immediate child targets of this SCXML document root.
    074         */
    075        private Map children;
    076
    077        /**
    078         * A global map of all States and Parallels associated with this
    079         * state machine, keyed by their id.
    080         */
    081        private Map targets;
    082
    083        /**
    084         * The XML namespaces defined on the SCXML document root node,
    085         * preserved primarily for serialization.
    086         */
    087        private Map namespaces;
    088
    089        /**
    090         * Indicates whether the legacy parser
    091         * ({@link org.apache.commons.scxml.io.SCXMLDigester}) was used.
    092         */
    093        private boolean legacy = false;
    094
    095        /**
    096         * Constructor.
    097         */
    098        public SCXML() {
    099            this.children = new LinkedHashMap();
    100            this.targets = new HashMap();
    101        }
    102
    103        /**
    104         * Get the initial State.
    105         *
    106         * @return State Returns the initialstate.
    107         *
    108         * @deprecated Use getInitialTarget() instead. Returns <code>null</code>
    109         *             if the initial target is a Parallel.
    110         */
    111        public final State getInitialState() {
    112            if (initialTarget != null && initialTarget instanceof State) {
    113                return (State) initialTarget;
    114            }
    115            return null;
    116        }
    117
    118        /**
    119         * Set the initial State.
    120         *
    121         * @param initialState The initialstate to set.
    122         *
    123         * @deprecated Use setInitialTarget(TransitionTarget) instead.
    124         */
    125        public final void setInitialState(final State initialState) {
    126            this.initialTarget = initialState;
    127        }
    128
    129        /**
    130         * Get the initial TransitionTarget.
    131         *
    132         * @return Returns the initial target for this state machine.
    133         *
    134         * @since 0.7
    135         */
    136        public final TransitionTarget getInitialTarget() {
    137            return initialTarget;
    138        }
    139
    140        /**
    141         * Set the initial TransitionTarget.
    142         *
    143         * @param initialTarget The initial target to set.
    144         *
    145         * @since 0.7
    146         */
    147        public final void setInitialTarget(final TransitionTarget initialTarget) {
    148            this.initialTarget = initialTarget;
    149        }
    150
    151        /**
    152         * Get the data model placed at document root.
    153         *
    154         * @return Returns the data model.
    155         */
    156        public final Datamodel getDatamodel() {
    157            return datamodel;
    158        }
    159
    160        /**
    161         * Set the data model at document root.
    162         *
    163         * @param datamodel The Datamodel to set.
    164         */
    165        public final void setDatamodel(final Datamodel datamodel) {
    166            this.datamodel = datamodel;
    167        }
    168
    169        /**
    170         * Get the children states.
    171         *
    172         * @return Map Returns map of the child states.
    173         *
    174         * @deprecated Use getChildren() instead.
    175         */
    176        public final Map getStates() {
    177            return children;
    178        }
    179
    180        /**
    181         * Add a child state.
    182         *
    183         * @param state The state to be added to the states Map.
    184         *
    185         * @deprecated Use addChild(TransitionTarget) instead.
    186         */
    187        public final void addState(final State state) {
    188            children.put(state.getId(), state);
    189        }
    190
    191        /**
    192         * Get the immediate child targets of the SCXML root.
    193         *
    194         * @return Map Returns map of the child targets.
    195         *
    196         * @since 0.7
    197         */
    198        public final Map getChildren() {
    199            return children;
    200        }
    201
    202        /**
    203         * Add an immediate child target of the SCXML root.
    204         *
    205         * @param tt The transition target to be added to the states Map.
    206         *
    207         * @since 0.7
    208         */
    209        public final void addChild(final TransitionTarget tt) {
    210            children.put(tt.getId(), tt);
    211        }
    212
    213        /**
    214         * Get the targets map, which is a Map of all States and Parallels
    215         * associated with this state machine, keyed by their id.
    216         *
    217         * @return Map Returns the targets.
    218         */
    219        public final Map getTargets() {
    220            return targets;
    221        }
    222
    223        /**
    224         * Add a target to this SCXML document.
    225         *
    226         * @param target The target to be added to the targets Map.
    227         */
    228        public final void addTarget(final TransitionTarget target) {
    229            String id = target.getId();
    230            if (!SCXMLHelper.isStringEmpty(id)) {
    231                // Target is not anonymous, so makes sense to map it
    232                targets.put(id, target);
    233            }
    234        }
    235
    236        /**
    237         * Get the SCXML document version.
    238         *
    239         * @return Returns the version.
    240         */
    241        public final String getVersion() {
    242            return version;
    243        }
    244
    245        /**
    246         * Set the SCXML document version.
    247         *
    248         * @param version The version to set.
    249         */
    250        public final void setVersion(final String version) {
    251            this.version = version;
    252        }
    253
    254        /**
    255         * Get the xmlns of this SCXML document.
    256         *
    257         * @return Returns the xmlns.
    258         */
    259        public final String getXmlns() {
    260            return xmlns;
    261        }
    262
    263        /**
    264         * Set the xmlns of this SCXML document.
    265         *
    266         * @param xmlns The xmlns to set.
    267         */
    268        public final void setXmlns(final String xmlns) {
    269            this.xmlns = xmlns;
    270        }
    271
    272        /**
    273         * Get the namespace definitions specified on the SCXML element.
    274         * May be <code>null</code>.
    275         *
    276         * @return The namespace definitions specified on the SCXML element,
    277         *         may be <code>null</code>.
    278         */
    279        public final Map getNamespaces() {
    280            return namespaces;
    281        }
    282
    283        /**
    284         * Set the namespace definitions specified on the SCXML element.
    285         *
    286         * @param namespaces The namespace definitions specified on the
    287         *                   SCXML element.
    288         */
    289        public final void setNamespaces(final Map namespaces) {
    290            this.namespaces = namespaces;
    291        }
    292
    293        /**
    294         * Get the ID of the initial state.
    295         *
    296         * @return String Returns the initial state ID (used by XML Digester only).
    297         * @see #getInitialTarget()
    298         * @deprecated Use {@link #getInitial()} instead.
    299         */
    300        public final String getInitialstate() {
    301            return initial;
    302        }
    303
    304        /**
    305         * Set the ID of the initial state.
    306         *
    307         * @param initialstate The initial state ID (used by XML Digester only).
    308         * @see #setInitialTarget(TransitionTarget)
    309         * @deprecated Use {@link #setInitial(String)} instead.
    310         */
    311        public final void setInitialstate(final String initialstate) {
    312            this.initial = initialstate;
    313        }
    314
    315        /**
    316         * Get the ID of the initial transition target.
    317         *
    318         * @return String Returns the initial transition target ID
    319         *     (used by XML Digester only).
    320         * @see #getInitialTarget()
    321         */
    322        public final String getInitial() {
    323            return initial;
    324        }
    325
    326        /**
    327         * Set the ID of the initial transition target.
    328         *
    329         * @param initial The initial transition target ID
    330         *     (used by XML Digester only).
    331         * @see #setInitialTarget(TransitionTarget)
    332         */
    333        public final void setInitial(final String initial) {
    334            this.initial = initial;
    335        }
    336
    337        /**
    338         * Whether the legacy parser was used.
    339         *
    340         * @return True, if legacy parser was used.
    341         *
    342         * @since 0.9
    343         * @deprecated Will be removed in v1.0
    344         */
    345        public final boolean isLegacy() {
    346            return legacy;
    347        }
    348
    349        /**
    350         * Set whether the legacy parser was used.
    351         *
    352         * @param legacy True, if legacy parser was used.
    353         *
    354         * @since 0.9
    355         * @deprecated Will be removed in v1.0
    356         */
    357        public final void setLegacy(final boolean legacy) {
    358            this.legacy = legacy;
    359        }
    360
    361    }
    362