1 package org.apache.velocity;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import org.apache.velocity.context.AbstractContext;
26 import org.apache.velocity.context.Context;
27
28 /**
29 * General purpose implemention of the application Context
30 * interface for general application use. This class should
31 * be used in place of the original Context class.
32 *
33 * This implementation uses a HashMap (@see java.util.HashMap )
34 * for data storage.
35 *
36 * This context implementation cannot be shared between threads
37 * without those threads synchronizing access between them, as
38 * the HashMap is not synchronized, nor are some of the fundamentals
39 * of AbstractContext. If you need to share a Context between
40 * threads with simultaneous access for some reason, please create
41 * your own and extend the interface Context
42 *
43 * @see org.apache.velocity.context.Context
44 *
45 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
46 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
47 * @author <a href="mailto:fedor.karpelevitch@home.com">Fedor Karpelevitch</a>
48 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
49 * @version $Id: VelocityContext.java 463298 2006-10-12 16:10:32Z henning $
50 */
51 public class VelocityContext extends AbstractContext implements Cloneable
52 {
53 /**
54 * Version Id for serializable
55 */
56 private static final long serialVersionUID = 9033846851064645037L;
57
58 /**
59 * Storage for key/value pairs.
60 */
61 private Map context = null;
62
63 /**
64 * Creates a new instance (with no inner context).
65 */
66 public VelocityContext()
67 {
68 this(null, null);
69 }
70
71 /**
72 * Creates a new instance with the provided storage (and no inner
73 * context).
74 * @param context
75 */
76 public VelocityContext(Map context)
77 {
78 this(context, null);
79 }
80
81 /**
82 * Chaining constructor, used when you want to
83 * wrap a context in another. The inner context
84 * will be 'read only' - put() calls to the
85 * wrapping context will only effect the outermost
86 * context
87 *
88 * @param innerContext The <code>Context</code> implementation to
89 * wrap.
90 */
91 public VelocityContext( Context innerContext )
92 {
93 this(null, innerContext);
94 }
95
96 /**
97 * Initializes internal storage (never to <code>null</code>), and
98 * inner context.
99 *
100 * @param context Internal storage, or <code>null</code> to
101 * create default storage.
102 * @param innerContext Inner context.
103 */
104 public VelocityContext(Map context, Context innerContext)
105 {
106 super(innerContext);
107 this.context = (context == null ? new HashMap() : context);
108 }
109
110 /**
111 * retrieves value for key from internal
112 * storage
113 *
114 * @param key name of value to get
115 * @return value as object
116 */
117 public Object internalGet( String key )
118 {
119 return context.get( key );
120 }
121
122 /**
123 * stores the value for key to internal
124 * storage
125 *
126 * @param key name of value to store
127 * @param value value to store
128 * @return previous value of key as Object
129 */
130 public Object internalPut( String key, Object value )
131 {
132 return context.put( key, value );
133 }
134
135 /**
136 * determines if there is a value for the
137 * given key
138 *
139 * @param key name of value to check
140 * @return true if non-null value in store
141 */
142 public boolean internalContainsKey(Object key)
143 {
144 return context.containsKey( key );
145 }
146
147 /**
148 * returns array of keys
149 *
150 * @return keys as []
151 */
152 public Object[] internalGetKeys()
153 {
154 return context.keySet().toArray();
155 }
156
157 /**
158 * remove a key/value pair from the
159 * internal storage
160 *
161 * @param key name of value to remove
162 * @return value removed
163 */
164 public Object internalRemove(Object key)
165 {
166 return context.remove( key );
167 }
168
169 /**
170 * Clones this context object.
171 *
172 * @return A deep copy of this <code>Context</code>.
173 */
174 public Object clone()
175 {
176 VelocityContext clone = null;
177 try
178 {
179 clone = (VelocityContext) super.clone();
180 clone.context = new HashMap(context);
181 }
182 catch (CloneNotSupportedException ignored)
183 {
184 }
185 return clone;
186 }
187 }