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