aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main/java/org/apache/velocity/VelocityContext.java
blob: 9b4a6e4a5cd22f60796747bbb73fff168634ef67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package org.apache.velocity;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.velocity.context.AbstractContext;
import org.apache.velocity.context.Context;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 *  General purpose implementation of the application Context
 *  interface for general application use.  This class should
 *  be used in place of the original Context class.
 *
 *  This implementation uses a HashMap  (@see java.util.HashMap )
 *  for data storage.
 *
 *  This context implementation cannot be shared between threads
 *  without those threads synchronizing access between them, as
 *  the HashMap is not synchronized, nor are some of the fundamentals
 *  of AbstractContext.  If you need to share a Context between
 *  threads with simultaneous access for some reason, please create
 *  your own and extend the interface Context
 *
 *  @see org.apache.velocity.context.Context
 *
 *  @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
 *  @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
 *  @author <a href="mailto:fedor.karpelevitch@home.com">Fedor Karpelevitch</a>
 *  @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 *  @version $Id$
 */
public class VelocityContext
    extends AbstractContext
    implements Cloneable, Serializable
{
    /**
     * Version Id for serializable
     */
    private static final long serialVersionUID = 9033846851064645037L;

    /**
     *  Storage for key/value pairs.
     */
    private Map<String, Object> context = null;

    /**
     *  Creates a new instance (with no inner context).
     */
    public VelocityContext()
    {
        this(null, null);
    }

    /**
     *  Creates a new instance with the provided storage (and no inner
     *  context).
     * @param context
     */
    public VelocityContext(Map<String, Object> context)
    {
        this(context, null);
    }

    /**
     *  Chaining constructor, used when you want to
     *  wrap a context in another.  The inner context
     *  will be 'read only' - put() calls to the
     *  wrapping context will only effect the outermost
     *  context
     *
     *  @param innerContext The <code>Context</code> implementation to
     *  wrap.
     */
    public VelocityContext( Context innerContext )
    {
        this(null, innerContext);
    }

    /**
     *  Initializes internal storage (never to <code>null</code>), and
     *  inner context.
     *
     *  @param context Internal storage, or <code>null</code> to
     *  create default storage.
     *  @param innerContext Inner context.
     */
    public VelocityContext(Map<String, Object> context, Context innerContext)
    {
        super(innerContext);
        this.context = (context == null ? new HashMap<>() : context);
    }

    /**
     *  retrieves value for key from internal
     *  storage
     *
     *  @param key name of value to get
     *  @return value as object
     */
    @Override
    public Object internalGet(String key )
    {
        return context.get( key );
    }

    /**
     *  stores the value for key to internal
     *  storage
     *
     *  @param key name of value to store
     *  @param value value to store
     *  @return previous value of key as Object
     */
    @Override
    public Object internalPut(String key, Object value )
    {
        return context.put( key, value );
    }

    /**
     *  determines if there is a value for the
     *  given key
     *
     *  @param key name of value to check
     *  @return true if non-null value in store
     */
    @Override
    public  boolean internalContainsKey(String key)
    {
        return context.containsKey( key );
    }

    /**
     *  returns array of keys
     *
     *  @return keys as []
     */
    @Override
    public  String[] internalGetKeys()
    {
        return context.keySet().toArray(new String[context.size()]);
    }

    /**
     *  remove a key/value pair from the
     *  internal storage
     *
     *  @param key name of value to remove
     *  @return value removed
     */
    @Override
    public  Object internalRemove(String key)
    {
        return context.remove( key );
    }

    /**
     * Clones this context object.
     *
     * @return A shallow copy of this <code>Context</code>.
     */
    @Override
    public Object clone()
    {
        VelocityContext clone = null;
        try
        {
            clone = (VelocityContext) super.clone();
            clone.context = new HashMap<>(context);
        }
        catch (CloneNotSupportedException ignored)
        {
        }
        return clone;
    }
}