1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.util;
15
16 import java.io.Serializable;
17 import java.util.Arrays;
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
26
27
28
29
30
31
32
33
34
35
36
37
38 public class MultiMap<K> implements ConcurrentMap<K,Object>, Serializable
39 {
40 private static final long serialVersionUID = -6878723138353851005L;
41 Map<K,Object> _map;
42 ConcurrentMap<K, Object> _cmap;
43
44 public MultiMap()
45 {
46 _map=new HashMap<K, Object>();
47 }
48
49 public MultiMap(Map map)
50 {
51 if (map instanceof ConcurrentMap)
52 _map=_cmap=new ConcurrentHashMap<K, Object>(map);
53 else
54 _map=new HashMap<K, Object>(map);
55 }
56
57 public MultiMap(MultiMap<K> map)
58 {
59 if (map._cmap!=null)
60 _map=_cmap=new ConcurrentHashMap<K, Object>(map._cmap);
61 else
62 _map=new HashMap<K,Object>(map._map);
63 }
64
65 public MultiMap(int capacity)
66 {
67 _map=new HashMap<K, Object>(capacity);
68 }
69
70 public MultiMap(boolean concurrent)
71 {
72 if (concurrent)
73 _map=_cmap=new ConcurrentHashMap<K, Object>();
74 else
75 _map=new HashMap<K, Object>();
76 }
77
78
79
80
81
82
83
84
85 public List<Object> getValues(Object name)
86 {
87 return LazyList.getList(_map.get(name),true);
88 }
89
90
91
92
93
94
95
96
97
98 public Object getValue(Object name,int i)
99 {
100 Object l=_map.get(name);
101 if (i==0 && LazyList.size(l)==0)
102 return null;
103 return LazyList.get(l,i);
104 }
105
106
107
108
109
110
111
112
113
114
115 public String getString(Object name)
116 {
117 Object l=_map.get(name);
118 switch(LazyList.size(l))
119 {
120 case 0:
121 return null;
122 case 1:
123 Object o=LazyList.get(l,0);
124 return o==null?null:o.toString();
125 default:
126 {
127 StringBuilder values=new StringBuilder(128);
128 for (int i=0; i<LazyList.size(l); i++)
129 {
130 Object e=LazyList.get(l,i);
131 if (e!=null)
132 {
133 if (values.length()>0)
134 values.append(',');
135 values.append(e.toString());
136 }
137 }
138 return values.toString();
139 }
140 }
141 }
142
143
144 public Object get(Object name)
145 {
146 Object l=_map.get(name);
147 switch(LazyList.size(l))
148 {
149 case 0:
150 return null;
151 case 1:
152 Object o=LazyList.get(l,0);
153 return o;
154 default:
155 return LazyList.getList(l,true);
156 }
157 }
158
159
160
161
162
163
164
165 public Object put(K name, Object value)
166 {
167 return _map.put(name,LazyList.add(null,value));
168 }
169
170
171
172
173
174
175
176 public Object putValues(K name, List values)
177 {
178 return _map.put(name,values);
179 }
180
181
182
183
184
185
186
187 public Object putValues(K name, String[] values)
188 {
189 Object list=null;
190 for (int i=0;i<values.length;i++)
191 list=LazyList.add(list,values[i]);
192 return put(name,list);
193 }
194
195
196
197
198
199
200
201
202
203 public void add(K name, Object value)
204 {
205 Object lo = _map.get(name);
206 Object ln = LazyList.add(lo,value);
207 if (lo!=ln)
208 _map.put(name,ln);
209 }
210
211
212
213
214
215
216
217
218 public void addValues(K name, List values)
219 {
220 Object lo = _map.get(name);
221 Object ln = LazyList.addCollection(lo,values);
222 if (lo!=ln)
223 _map.put(name,ln);
224 }
225
226
227
228
229
230
231
232
233 public void addValues(K name, String[] values)
234 {
235 Object lo = _map.get(name);
236 Object ln = LazyList.addCollection(lo,Arrays.asList(values));
237 if (lo!=ln)
238 _map.put(name,ln);
239 }
240
241
242
243
244
245
246
247 public boolean removeValue(K name,Object value)
248 {
249 Object lo = _map.get(name);
250 Object ln=lo;
251 int s=LazyList.size(lo);
252 if (s>0)
253 {
254 ln=LazyList.remove(lo,value);
255 if (ln==null)
256 _map.remove(name);
257 else
258 _map.put(name, ln);
259 }
260 return LazyList.size(ln)!=s;
261 }
262
263
264
265
266
267 public void putAll(Map m)
268 {
269 Iterator i = m.entrySet().iterator();
270 boolean multi=m instanceof MultiMap;
271 while(i.hasNext())
272 {
273 Map.Entry entry = (Map.Entry)i.next();
274 if (multi)
275 _map.put((K)(entry.getKey()),LazyList.clone(entry.getValue()));
276 else
277 put((K)(entry.getKey()),entry.getValue());
278 }
279 }
280
281
282
283
284
285 public Map toStringArrayMap()
286 {
287 HashMap map = new HashMap(_map.size()*3/2);
288
289 Iterator i = _map.entrySet().iterator();
290 while(i.hasNext())
291 {
292 Map.Entry entry = (Map.Entry)i.next();
293 Object l = entry.getValue();
294 String[] a = LazyList.toStringArray(l);
295
296
297
298 map.put(entry.getKey(),a);
299 }
300 return map;
301 }
302
303 @Override
304 public String toString()
305 {
306 return _cmap==null?_map.toString():_cmap.toString();
307 }
308
309 public void clear()
310 {
311 _map.clear();
312 }
313
314 public boolean containsKey(Object key)
315 {
316 return _map.containsKey(key);
317 }
318
319 public boolean containsValue(Object value)
320 {
321 return _map.containsValue(value);
322 }
323
324 public Set<Entry<K, Object>> entrySet()
325 {
326 return _map.entrySet();
327 }
328
329 @Override
330 public boolean equals(Object o)
331 {
332 return _map.equals(o);
333 }
334
335 @Override
336 public int hashCode()
337 {
338 return _map.hashCode();
339 }
340
341 public boolean isEmpty()
342 {
343 return _map.isEmpty();
344 }
345
346 public Set<K> keySet()
347 {
348 return _map.keySet();
349 }
350
351 public Object remove(Object key)
352 {
353 return _map.remove(key);
354 }
355
356 public int size()
357 {
358 return _map.size();
359 }
360
361 public Collection<Object> values()
362 {
363 return _map.values();
364 }
365
366
367
368 public Object putIfAbsent(K key, Object value)
369 {
370 if (_cmap==null)
371 throw new UnsupportedOperationException();
372 return _cmap.putIfAbsent(key,value);
373 }
374
375 public boolean remove(Object key, Object value)
376 {
377 if (_cmap==null)
378 throw new UnsupportedOperationException();
379 return _cmap.remove(key,value);
380 }
381
382 public boolean replace(K key, Object oldValue, Object newValue)
383 {
384 if (_cmap==null)
385 throw new UnsupportedOperationException();
386 return _cmap.replace(key,oldValue,newValue);
387 }
388
389 public Object replace(K key, Object value)
390 {
391 if (_cmap==null)
392 throw new UnsupportedOperationException();
393 return _cmap.replace(key,value);
394 }
395 }