View Javadoc
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.env;
18  
19  import java.io.Serializable;
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.commons.scxml2.Context;
26  import org.apache.commons.scxml2.SCXMLSystemContext;
27  
28  /**
29   * Simple Context wrapping a map of variables.
30   *
31   */
32  public class SimpleContext implements Context, Serializable {
33  
34      /** Serial version UID. */
35      private static final long serialVersionUID = 1L;
36      /** Implementation independent log category. */
37      private static final Log DEFAULT_LOG = LogFactory.getLog(Context.class);
38      private Log log = DEFAULT_LOG;
39      /** The parent Context to this Context. */
40      private Context parent;
41      /** The Map of variables and their values in this Context. */
42      private Map<String, Object> vars;
43  
44      protected final SCXMLSystemContext systemContext;
45  
46      /**
47       * Constructor.
48       *
49       */
50      public SimpleContext() {
51          this(null, null);
52      }
53  
54      /**
55       * Constructor.
56       *
57       * @param parent A parent Context, can be null
58       */
59      public SimpleContext(final Context parent) {
60          this(parent, null);
61      }
62  
63      /**
64       * Constructor.
65       *
66       * @param parent A parent Context, can be null
67       * @param initialVars A pre-populated initial variables map
68       */
69      public SimpleContext(final Context parent, final Map<String, Object> initialVars) {
70          this.parent = parent;
71          this.systemContext = parent instanceof SCXMLSystemContext ?
72                  (SCXMLSystemContext) parent : parent != null ? parent.getSystemContext() : null;
73          if (initialVars == null) {
74              setVars(new HashMap<String, Object>());
75          } else {
76              setVars(this.vars = initialVars);
77          }
78      }
79  
80      /**
81       * Assigns a new value to an existing variable or creates a new one.
82       * The method searches the chain of parent Contexts for variable
83       * existence.
84       *
85       * @param name The variable name
86       * @param value The variable value
87       * @see org.apache.commons.scxml2.Context#set(String, Object)
88       */
89      public void set(final String name, final Object value) {
90          if (getVars().containsKey(name)) { //first try to override local
91              setLocal(name, value);
92          } else if (parent != null && parent.has(name)) { //then check for global
93              parent.set(name, value);
94          } else { //otherwise create a new local variable
95              setLocal(name, value);
96          }
97      }
98  
99      /**
100      * Get the value of this variable; delegating to parent.
101      *
102      * @param name The variable name
103      * @return Object The variable value
104      * @see org.apache.commons.scxml2.Context#get(java.lang.String)
105      */
106     public Object get(final String name) {
107         Object localValue = getVars().get(name);
108         if (localValue != null) {
109             return localValue;
110         } else if (parent != null) {
111             return parent.get(name);
112         } else {
113             return null;
114         }
115     }
116 
117     /**
118      * Check if this variable exists, delegating to parent.
119      *
120      * @param name The variable name
121      * @return boolean true if this variable exists
122      * @see org.apache.commons.scxml2.Context#has(java.lang.String)
123      */
124     public boolean has(final String name) {
125         return (hasLocal(name) || (parent != null && parent.has(name)));
126     }
127 
128     /**
129      * Check if this variable exists, only checking this Context
130      *
131      * @param name The variable name
132      * @return boolean true if this variable exists
133      * @see org.apache.commons.scxml2.Context#hasLocal(java.lang.String)
134      */
135     public boolean hasLocal(final String name) {
136         return (getVars().containsKey(name));
137     }
138 
139     /**
140      * Clear this Context.
141      *
142      * @see org.apache.commons.scxml2.Context#reset()
143      */
144     public void reset() {
145         getVars().clear();
146     }
147 
148     /**
149      * Get the parent Context, may be null.
150      *
151      * @return Context The parent Context
152      * @see org.apache.commons.scxml2.Context#getParent()
153      */
154     public Context getParent() {
155         return parent;
156     }
157 
158     /**
159      * Get the SCXMLSystemContext for this Context, should not be null unless this is the root Context
160      *
161      * @return The SCXMLSystemContext in a chained Context environment
162      */
163     public final SCXMLSystemContext getSystemContext() {
164         return systemContext;
165     }
166 
167     /**
168      * Assigns a new value to an existing variable or creates a new one.
169      * The method allows to shaddow a variable of the same name up the
170      * Context chain.
171      *
172      * @param name The variable name
173      * @param value The variable value
174      * @see org.apache.commons.scxml2.Context#setLocal(String, Object)
175      */
176     public void setLocal(final String name, final Object value) {
177         getVars().put(name, value);
178         if (log.isDebugEnabled()) {
179             log.debug(name + " = " + String.valueOf(value));
180         }
181     }
182 
183     /**
184      * Set the variables map.
185      *
186      * @param vars The new Map of variables.
187      */
188     protected void setVars(final Map<String, Object> vars) {
189         this.vars = vars;
190     }
191 
192     /**
193      * Get the Map of all local variables in this Context.
194      *
195      * @return Returns the vars.
196      */
197     public Map<String, Object> getVars() {
198         return vars;
199     }
200 
201     /**
202      * Set the log used by this <code>Context</code> instance.
203      *
204      * @param log The new log.
205      */
206     protected void setLog(final Log log) {
207         this.log = log;
208     }
209 
210     /**
211      * Get the log used by this <code>Context</code> instance.
212      *
213      * @return Log The log being used.
214      */
215     protected Log getLog() {
216         return log;
217     }
218 
219 }
220