1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.util;
20
21 import java.util.AbstractMap;
22 import java.util.AbstractSet;
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public final class SubKeyMap<V> extends AbstractMap<String, V>
45 {
46 public SubKeyMap(Map<String, Object> base, String prefix)
47 {
48 if (base == null)
49 {
50 throw new NullPointerException();
51 }
52 if (prefix == null)
53 {
54 throw new NullPointerException();
55 }
56
57
58 if (base instanceof SubKeyMap)
59 {
60 _base = ((SubKeyMap) base)._base;
61 _prefix = ((SubKeyMap) base)._prefix + prefix;
62 }
63 else
64 {
65 _base = base;
66 _prefix = prefix;
67 }
68 _keyBuffer = new StringBuilder(32);
69 }
70
71 @Override
72 public boolean isEmpty()
73 {
74 return entrySet().isEmpty();
75 }
76
77 @Override
78 public V get(Object key)
79 {
80 key = _getBaseKey(key);
81 return (V) _base.get(key);
82 }
83
84 @Override
85 public V put(String key, V value)
86 {
87 key = _getBaseKey(key);
88 return (V) _base.put(key, value);
89 }
90
91 @Override
92 public V remove(Object key)
93 {
94 key = _getBaseKey(key);
95 return (V) _base.remove(key);
96 }
97
98 @Override
99 public boolean containsKey(Object key)
100 {
101 if (!(key instanceof String))
102 {
103 return false;
104 }
105
106 return _base.containsKey(_getBaseKey(key));
107 }
108
109 @Override
110 public Set<Map.Entry<String, V>> entrySet()
111 {
112 if (_entrySet == null)
113 {
114 _entrySet = new Entries<V>();
115 }
116 return _entrySet;
117 }
118
119 private String _getBaseKey(Object key)
120 {
121 if (key == null)
122 {
123 throw new NullPointerException();
124 }
125
126
127 _keyBuffer.setLength(0);
128 _keyBuffer.append(_prefix);
129 _keyBuffer.append((String) key);
130 return _keyBuffer.toString();
131 }
132
133 private List<String> _gatherKeys()
134 {
135 List<String> list = new ArrayList<String>();
136 for (String key : _base.keySet())
137 {
138 if (key != null && key.startsWith(_prefix))
139 {
140 list.add(key);
141 }
142 }
143
144 return list;
145 }
146
147
148
149
150 private class Entries<V> extends AbstractSet<Map.Entry<String, V>>
151 {
152 public Entries()
153 {
154 }
155
156 @Override
157 public Iterator<Map.Entry<String, V>> iterator()
158 {
159
160
161
162
163 List<String> keyList = _gatherKeys();
164 return new EntryIterator<V>(keyList.iterator());
165 }
166
167 @Override
168 public int size()
169 {
170 int size = 0;
171 for (String key : _base.keySet())
172 {
173 if (key != null && key.startsWith(_prefix))
174 {
175 size++;
176 }
177 }
178
179 return size;
180 }
181
182 @Override
183 public boolean isEmpty()
184 {
185 Iterator<String> keys = _base.keySet().iterator();
186 while (keys.hasNext())
187 {
188 String key = keys.next();
189
190
191 if (key != null && key.startsWith(_prefix))
192 {
193 return false;
194 }
195 }
196
197 return true;
198 }
199
200 @Override
201 public void clear()
202 {
203 Iterator<String> keys = _base.keySet().iterator();
204 while (keys.hasNext())
205 {
206 String key = keys.next();
207 if (key != null && key.startsWith(_prefix))
208 {
209 keys.remove();
210 }
211 }
212 }
213 }
214
215 private class EntryIterator<V> implements Iterator<Map.Entry<String, V>>
216 {
217 public EntryIterator(Iterator<String> iterator)
218 {
219 _iterator = iterator;
220 }
221
222 public boolean hasNext()
223 {
224 return _iterator.hasNext();
225 }
226
227 public Map.Entry<String, V> next()
228 {
229 String baseKey = _iterator.next();
230 _currentKey = baseKey;
231 return new Entry<V>(baseKey);
232 }
233
234 public void remove()
235 {
236 if (_currentKey == null)
237 {
238 throw new IllegalStateException();
239 }
240
241 _base.remove(_currentKey);
242
243 _currentKey = null;
244 }
245
246 private Iterator<String> _iterator;
247 private String _currentKey;
248 }
249
250 private class Entry<V> implements Map.Entry<String, V>
251 {
252 public Entry(String baseKey)
253 {
254 _baseKey = baseKey;
255 }
256
257 public String getKey()
258 {
259 if (_key == null)
260 {
261 _key = _baseKey.substring(_prefix.length());
262 }
263 return _key;
264 }
265
266 public V getValue()
267 {
268 return (V) _base.get(_baseKey);
269 }
270
271 public V setValue(V value)
272 {
273 return (V) _base.put(_baseKey, value);
274 }
275
276 @SuppressWarnings("unchecked")
277 @Override
278 public boolean equals(Object o)
279 {
280 if (!(o instanceof Map.Entry))
281 {
282 return false;
283 }
284 Map.Entry<String, V> e = (Map.Entry<String, V>) o;
285 return _equals(getKey(), e.getKey())
286 && _equals(getValue(), e.getValue());
287 }
288
289 @Override
290 public int hashCode()
291 {
292 Object key = getKey();
293 Object value = getValue();
294 return ((key == null) ? 0 : key.hashCode())
295 ^ ((value == null) ? 0 : value.hashCode());
296 }
297
298 private String _baseKey;
299 private String _key;
300 }
301
302 static private boolean _equals(Object a, Object b)
303 {
304 if (a == null)
305 {
306 return b == null;
307 }
308 return a.equals(b);
309 }
310
311 private final Map<String, Object> _base;
312 private final String _prefix;
313 private Set<Map.Entry<String, V>> _entrySet;
314 private StringBuilder _keyBuffer;
315
316 }