    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.env;
    018
    019    import java.io.Serializable;
    020    import java.util.HashMap;
    021    import java.util.Map;
    022
    023    import org.apache.commons.logging.Log;
    024    import org.apache.commons.logging.LogFactory;
    025    import org.apache.commons.scxml.Context;
    026
    027    /**
    028     * Simple Context wrapping a map of variables.
    029     *
    030     */
    031    public class SimpleContext implements Context, Serializable {
    032
    033        /** Serial version UID. */
    034        private static final long serialVersionUID = 1L;
    035        /** Implementation independent log category. */
    036        private Log log = LogFactory.getLog(Context.class);
    037        /** The parent Context to this Context. */
    038        private Context parent;
    039        /** The Map of variables and their values in this Context. */
    040        private Map vars;
    041
    042        /**
    043         * Constructor.
    044         *
    045         */
    046        public SimpleContext() {
    047            this(null, null);
    048        }
    049
    050        /**
    051         * Constructor.
    052         *
    053         * @param parent A parent Context, can be null
    054         */
    055        public SimpleContext(final Context parent) {
    056            this(parent, null);
    057        }
    058        /**
    059         * Constructor.
    060         *
    061         * @param initialVars A pre-populated initial variables map
    062         */
    063        public SimpleContext(final Map initialVars) {
    064            this(null, initialVars);
    065        }
    066
    067        /**
    068         * Constructor.
    069         *
    070         * @param parent A parent Context, can be null
    071         * @param initialVars A pre-populated initial variables map
    072         */
    073        public SimpleContext(final Context parent, final Map initialVars) {
    074            this.parent = parent;
    075            if (initialVars == null) {
    076                this.vars = new HashMap();
    077            } else {
    078                this.vars = initialVars;
    079            }
    080        }
    081
    082        /**
    083         * Assigns a new value to an existing variable or creates a new one.
    084         * The method searches the chain of parent Contexts for variable
    085         * existence.
    086         *
    087         * @param name The variable name
    088         * @param value The variable value
    089         * @see org.apache.commons.scxml.Context#set(String, Object)
    090         */
    091        public void set(final String name, final Object value) {
    092            if (vars.containsKey(name)) { //first try to override local
    093                setLocal(name, value);
    094            } else if (parent != null && parent.has(name)) { //then check for global
    095                parent.set(name, value);
    096            } else { //otherwise create a new local variable
    097                setLocal(name, value);
    098            }
    099        }
    100
    101        /**
    102         * Get the value of this variable; delegating to parent.
    103         *
    104         * @param name The variable name
    105         * @return Object The variable value
    106         * @see org.apache.commons.scxml.Context#get(java.lang.String)
    107         */
    108        public Object get(final String name) {
    109            if (vars.containsKey(name)) {
    110                return vars.get(name);
    111            } else if (parent != null) {
    112                return parent.get(name);
    113            } else {
    114                return null;
    115            }
    116        }
    117
    118        /**
    119         * Check if this variable exists, delegating to parent.
    120         *
    121         * @param name The variable name
    122         * @return boolean true if this variable exists
    123         * @see org.apache.commons.scxml.Context#has(java.lang.String)
    124         */
    125        public boolean has(final String name) {
    126            if (vars.containsKey(name)) {
    127                return true;
    128            } else if (parent != null && parent.has(name)) {
    129                return true;
    130            }
    131            return false;
    132        }
    133
    134        /**
    135         * Clear this Context.
    136         *
    137         * @see org.apache.commons.scxml.Context#reset()
    138         */
    139        public void reset() {
    140            vars.clear();
    141        }
    142
    143        /**
    144         * Get the parent Context, may be null.
    145         *
    146         * @return Context The parent Context
    147         * @see org.apache.commons.scxml.Context#getParent()
    148         */
    149        public Context getParent() {
    150            return parent;
    151        }
    152
    153        /**
    154         * Assigns a new value to an existing variable or creates a new one.
    155         * The method allows to shaddow a variable of the same name up the
    156         * Context chain.
    157         *
    158         * @param name The variable name
    159         * @param value The variable value
    160         * @see org.apache.commons.scxml.Context#setLocal(String, Object)
    161         */
    162        public void setLocal(final String name, final Object value) {
    163            vars.put(name, value);
    164            if (log.isDebugEnabled() && !name.equals("_ALL_STATES")) {
    165                log.debug(name + " = " + String.valueOf(value));
    166            }
    167        }
    168
    169        /**
    170         * Set the variables map.
    171         *
    172         * @param vars The new Map of variables.
    173         */
    174        protected void setVars(final Map vars) {
    175            this.vars = vars;
    176        }
    177
    178        /**
    179         * Get the Map of all local variables in this Context.
    180         *
    181         * @return Returns the vars.
    182         */
    183        public Map getVars() {
    184            return vars;
    185        }
    186
    187        /**
    188         * Set the log used by this <code>Context</code> instance.
    189         *
    190         * @param log The new log.
    191         */
    192        protected void setLog(final Log log) {
    193            this.log = log;
    194        }
    195
    196        /**
    197         * Get the log used by this <code>Context</code> instance.
    198         *
    199         * @return Log The log being used.
    200         */
    201        protected Log getLog() {
    202            return log;
    203        }
    204
    205    }
    206