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.catalina.util;
18
19 import java.io.Serializable;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.LinkedHashMap;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.tomcat.util.res.StringManager;
27
28 /**
29 * Implementation of <strong>java.util.Map</strong> that includes a
30 * <code>locked</code> property. This class can be used to safely expose
31 * Catalina internal parameter map objects to user classes without having
32 * to clone them in order to avoid modifications. When first created, a
33 * <code>ParmaeterMap</code> instance is not locked.
34 *
35 * @param <K> The type of Key
36 * @param <V> The type of Value
37 *
38 * @author Craig R. McClanahan
39 */
40 public final class ParameterMap<K,V> implements Map<K,V>, Serializable {
41
42 private static final long serialVersionUID = 2L;
43
44 private final Map<K,V> delegatedMap;
45
46 private final Map<K,V> unmodifiableDelegatedMap;
47
48
49 /**
50 * Construct a new, empty map with the default initial capacity and
51 * load factor.
52 */
53 public ParameterMap() {
54 delegatedMap = new LinkedHashMap<>();
55 unmodifiableDelegatedMap = Collections.unmodifiableMap(delegatedMap);
56 }
57
58
59 /**
60 * Construct a new, empty map with the specified initial capacity and
61 * default load factor.
62 *
63 * @param initialCapacity The initial capacity of this map
64 */
65 public ParameterMap(int initialCapacity) {
66 delegatedMap = new LinkedHashMap<>(initialCapacity);
67 unmodifiableDelegatedMap = Collections.unmodifiableMap(delegatedMap);
68 }
69
70
71 /**
72 * Construct a new, empty map with the specified initial capacity and
73 * load factor.
74 *
75 * @param initialCapacity The initial capacity of this map
76 * @param loadFactor The load factor of this map
77 */
78 public ParameterMap(int initialCapacity, float loadFactor) {
79 delegatedMap = new LinkedHashMap<>(initialCapacity, loadFactor);
80 unmodifiableDelegatedMap = Collections.unmodifiableMap(delegatedMap);
81 }
82
83
84 /**
85 * Construct a new map with the same mappings as the given map.
86 *
87 * @param map Map whose contents are duplicated in the new map
88 */
89 public ParameterMap(Map<K,V> map) {
90 delegatedMap = new LinkedHashMap<>(map);
91 unmodifiableDelegatedMap = Collections.unmodifiableMap(delegatedMap);
92 }
93
94
95 /**
96 * The current lock state of this parameter map.
97 */
98 private boolean locked = false;
99
100
101 /**
102 * @return the locked state of this parameter map.
103 */
104 public boolean isLocked() {
105 return locked;
106 }
107
108
109 /**
110 * Set the locked state of this parameter map.
111 *
112 * @param locked The new locked state
113 */
114 public void setLocked(boolean locked) {
115 this.locked = locked;
116 }
117
118
119 /**
120 * The string manager for this package.
121 */
122 private static final StringManager sm = StringManager.getManager("org.apache.catalina.util");
123
124
125 /**
126 * {@inheritDoc}
127 *
128 * @exception IllegalStateException if this map is currently locked
129 */
130 @Override
131 public void clear() {
132 checkLocked();
133 delegatedMap.clear();
134 }
135
136
137 /**
138 * {@inheritDoc}
139 *
140 * @exception IllegalStateException if this map is currently locked
141 */
142 @Override
143 public V put(K key, V value) {
144 checkLocked();
145 return delegatedMap.put(key, value);
146 }
147
148
149 /**
150 * {@inheritDoc}
151 *
152 * @exception IllegalStateException if this map is currently locked
153 */
154 @Override
155 public void putAll(Map<? extends K,? extends V> map) {
156 checkLocked();
157 delegatedMap.putAll(map);
158 }
159
160
161 /**
162 * {@inheritDoc}
163 *
164 * @exception IllegalStateException if this map is currently locked
165 */
166 @Override
167 public V remove(Object key) {
168 checkLocked();
169 return delegatedMap.remove(key);
170 }
171
172
173 private void checkLocked() {
174 if (locked) {
175 throw new IllegalStateException(sm.getString("parameterMap.locked"));
176 }
177 }
178
179
180 @Override
181 public int size() {
182 return delegatedMap.size();
183 }
184
185
186 @Override
187 public boolean isEmpty() {
188 return delegatedMap.isEmpty();
189 }
190
191
192 @Override
193 public boolean containsKey(Object key) {
194 return delegatedMap.containsKey(key);
195 }
196
197
198 @Override
199 public boolean containsValue(Object value) {
200 return delegatedMap.containsValue(value);
201 }
202
203
204 @Override
205 public V get(Object key) {
206 return delegatedMap.get(key);
207 }
208
209
210 /**
211 * {@inheritDoc}
212 * <p>
213 * Returns an <strong>unmodifiable</strong> {@link Set} view of the keys
214 * contained in this map if it is locked.
215 */
216 @Override
217 public Set<K> keySet() {
218 if (locked) {
219 return unmodifiableDelegatedMap.keySet();
220 }
221
222 return delegatedMap.keySet();
223 }
224
225
226 /**
227 * {@inheritDoc}
228 * <p>
229 * Returns an <strong>unmodifiable</strong> {@link Collection} view of the
230 * values contained in this map if it is locked.
231 */
232 @Override
233 public Collection<V> values() {
234 if (locked) {
235 return unmodifiableDelegatedMap.values();
236 }
237
238 return delegatedMap.values();
239 }
240
241
242 /**
243 * {@inheritDoc}
244 * <p>
245 * Returns an <strong>unmodifiable</strong> {@link Set} view of the mappings
246 * contained in this map if it is locked.
247 */
248 @Override
249 public Set<java.util.Map.Entry<K, V>> entrySet() {
250 if (locked) {
251 return unmodifiableDelegatedMap.entrySet();
252 }
253
254 return delegatedMap.entrySet();
255 }
256 }
257