Mercurial Hosting > luan
comparison src/org/eclipse/jetty/util/MultiMap.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
801:6a21393191c1 | 802:3428c60d7cfc |
---|---|
1 // | |
2 // ======================================================================== | |
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. | |
4 // ------------------------------------------------------------------------ | |
5 // All rights reserved. This program and the accompanying materials | |
6 // are made available under the terms of the Eclipse Public License v1.0 | |
7 // and Apache License v2.0 which accompanies this distribution. | |
8 // | |
9 // The Eclipse Public License is available at | |
10 // http://www.eclipse.org/legal/epl-v10.html | |
11 // | |
12 // The Apache License v2.0 is available at | |
13 // http://www.opensource.org/licenses/apache2.0.php | |
14 // | |
15 // You may elect to redistribute this code under either of these licenses. | |
16 // ======================================================================== | |
17 // | |
18 | |
19 package org.eclipse.jetty.util; | |
20 | |
21 import java.io.Serializable; | |
22 import java.util.Arrays; | |
23 import java.util.Collection; | |
24 import java.util.HashMap; | |
25 import java.util.List; | |
26 import java.util.Map; | |
27 import java.util.Set; | |
28 import java.util.concurrent.ConcurrentHashMap; | |
29 import java.util.concurrent.ConcurrentMap; | |
30 | |
31 /* ------------------------------------------------------------ */ | |
32 /** A multi valued Map. | |
33 * This Map specializes HashMap and provides methods | |
34 * that operate on multi valued items. | |
35 * <P> | |
36 * Implemented as a map of LazyList values | |
37 * @param <K> The key type of the map. | |
38 * | |
39 * @see LazyList | |
40 * | |
41 */ | |
42 public class MultiMap<K> implements ConcurrentMap<K,Object>, Serializable | |
43 { | |
44 private static final long serialVersionUID = -6878723138353851005L; | |
45 Map<K,Object> _map; | |
46 ConcurrentMap<K, Object> _cmap; | |
47 | |
48 public MultiMap() | |
49 { | |
50 _map=new HashMap<K, Object>(); | |
51 } | |
52 | |
53 public MultiMap(Map<K,Object> map) | |
54 { | |
55 if (map instanceof ConcurrentMap) | |
56 _map=_cmap=new ConcurrentHashMap<K, Object>(map); | |
57 else | |
58 _map=new HashMap<K, Object>(map); | |
59 } | |
60 | |
61 public MultiMap(MultiMap<K> map) | |
62 { | |
63 if (map._cmap!=null) | |
64 _map=_cmap=new ConcurrentHashMap<K, Object>(map._cmap); | |
65 else | |
66 _map=new HashMap<K,Object>(map._map); | |
67 } | |
68 | |
69 public MultiMap(int capacity) | |
70 { | |
71 _map=new HashMap<K, Object>(capacity); | |
72 } | |
73 | |
74 public MultiMap(boolean concurrent) | |
75 { | |
76 if (concurrent) | |
77 _map=_cmap=new ConcurrentHashMap<K, Object>(); | |
78 else | |
79 _map=new HashMap<K, Object>(); | |
80 } | |
81 | |
82 | |
83 /* ------------------------------------------------------------ */ | |
84 /** Get multiple values. | |
85 * Single valued entries are converted to singleton lists. | |
86 * @param name The entry key. | |
87 * @return Unmodifieable List of values. | |
88 */ | |
89 public List getValues(Object name) | |
90 { | |
91 return LazyList.getList(_map.get(name),true); | |
92 } | |
93 | |
94 /* ------------------------------------------------------------ */ | |
95 /** Get a value from a multiple value. | |
96 * If the value is not a multivalue, then index 0 retrieves the | |
97 * value or null. | |
98 * @param name The entry key. | |
99 * @param i Index of element to get. | |
100 * @return Unmodifieable List of values. | |
101 */ | |
102 public Object getValue(Object name,int i) | |
103 { | |
104 Object l=_map.get(name); | |
105 if (i==0 && LazyList.size(l)==0) | |
106 return null; | |
107 return LazyList.get(l,i); | |
108 } | |
109 | |
110 | |
111 /* ------------------------------------------------------------ */ | |
112 /** Get value as String. | |
113 * Single valued items are converted to a String with the toString() | |
114 * Object method. Multi valued entries are converted to a comma separated | |
115 * List. No quoting of commas within values is performed. | |
116 * @param name The entry key. | |
117 * @return String value. | |
118 */ | |
119 public String getString(Object name) | |
120 { | |
121 Object l=_map.get(name); | |
122 switch(LazyList.size(l)) | |
123 { | |
124 case 0: | |
125 return null; | |
126 case 1: | |
127 Object o=LazyList.get(l,0); | |
128 return o==null?null:o.toString(); | |
129 default: | |
130 { | |
131 StringBuilder values=new StringBuilder(128); | |
132 for (int i=0; i<LazyList.size(l); i++) | |
133 { | |
134 Object e=LazyList.get(l,i); | |
135 if (e!=null) | |
136 { | |
137 if (values.length()>0) | |
138 values.append(','); | |
139 values.append(e.toString()); | |
140 } | |
141 } | |
142 return values.toString(); | |
143 } | |
144 } | |
145 } | |
146 | |
147 /* ------------------------------------------------------------ */ | |
148 public Object get(Object name) | |
149 { | |
150 Object l=_map.get(name); | |
151 switch(LazyList.size(l)) | |
152 { | |
153 case 0: | |
154 return null; | |
155 case 1: | |
156 Object o=LazyList.get(l,0); | |
157 return o; | |
158 default: | |
159 return LazyList.getList(l,true); | |
160 } | |
161 } | |
162 | |
163 /* ------------------------------------------------------------ */ | |
164 /** Put and entry into the map. | |
165 * @param name The entry key. | |
166 * @param value The entry value. | |
167 * @return The previous value or null. | |
168 */ | |
169 public Object put(K name, Object value) | |
170 { | |
171 return _map.put(name,LazyList.add(null,value)); | |
172 } | |
173 | |
174 /* ------------------------------------------------------------ */ | |
175 /** Put multi valued entry. | |
176 * @param name The entry key. | |
177 * @param values The List of multiple values. | |
178 * @return The previous value or null. | |
179 */ | |
180 public Object putValues(K name, List<? extends Object> values) | |
181 { | |
182 return _map.put(name,values); | |
183 } | |
184 | |
185 /* ------------------------------------------------------------ */ | |
186 /** Put multi valued entry. | |
187 * @param name The entry key. | |
188 * @param values The String array of multiple values. | |
189 * @return The previous value or null. | |
190 */ | |
191 public Object putValues(K name, String... values) | |
192 { | |
193 Object list=null; | |
194 for (int i=0;i<values.length;i++) | |
195 list=LazyList.add(list,values[i]); | |
196 return _map.put(name,list); | |
197 } | |
198 | |
199 | |
200 /* ------------------------------------------------------------ */ | |
201 /** Add value to multi valued entry. | |
202 * If the entry is single valued, it is converted to the first | |
203 * value of a multi valued entry. | |
204 * @param name The entry key. | |
205 * @param value The entry value. | |
206 */ | |
207 public void add(K name, Object value) | |
208 { | |
209 Object lo = _map.get(name); | |
210 Object ln = LazyList.add(lo,value); | |
211 if (lo!=ln) | |
212 _map.put(name,ln); | |
213 } | |
214 | |
215 /* ------------------------------------------------------------ */ | |
216 /** Add values to multi valued entry. | |
217 * If the entry is single valued, it is converted to the first | |
218 * value of a multi valued entry. | |
219 * @param name The entry key. | |
220 * @param values The List of multiple values. | |
221 */ | |
222 public void addValues(K name, List<? extends Object> values) | |
223 { | |
224 Object lo = _map.get(name); | |
225 Object ln = LazyList.addCollection(lo,values); | |
226 if (lo!=ln) | |
227 _map.put(name,ln); | |
228 } | |
229 | |
230 /* ------------------------------------------------------------ */ | |
231 /** Add values to multi valued entry. | |
232 * If the entry is single valued, it is converted to the first | |
233 * value of a multi valued entry. | |
234 * @param name The entry key. | |
235 * @param values The String array of multiple values. | |
236 */ | |
237 public void addValues(K name, String[] values) | |
238 { | |
239 Object lo = _map.get(name); | |
240 Object ln = LazyList.addCollection(lo,Arrays.asList(values)); | |
241 if (lo!=ln) | |
242 _map.put(name,ln); | |
243 } | |
244 | |
245 /* ------------------------------------------------------------ */ | |
246 /** Remove value. | |
247 * @param name The entry key. | |
248 * @param value The entry value. | |
249 * @return true if it was removed. | |
250 */ | |
251 public boolean removeValue(K name,Object value) | |
252 { | |
253 Object lo = _map.get(name); | |
254 Object ln=lo; | |
255 int s=LazyList.size(lo); | |
256 if (s>0) | |
257 { | |
258 ln=LazyList.remove(lo,value); | |
259 if (ln==null) | |
260 _map.remove(name); | |
261 else | |
262 _map.put(name, ln); | |
263 } | |
264 return LazyList.size(ln)!=s; | |
265 } | |
266 | |
267 | |
268 /* ------------------------------------------------------------ */ | |
269 /** Put all contents of map. | |
270 * @param m Map | |
271 */ | |
272 public void putAll(Map<? extends K, ? extends Object> m) | |
273 { | |
274 boolean multi = (m instanceof MultiMap); | |
275 | |
276 if (multi) | |
277 { | |
278 for (Map.Entry<? extends K, ? extends Object> entry : m.entrySet()) | |
279 { | |
280 _map.put(entry.getKey(),LazyList.clone(entry.getValue())); | |
281 } | |
282 } | |
283 else | |
284 { | |
285 _map.putAll(m); | |
286 } | |
287 } | |
288 | |
289 /* ------------------------------------------------------------ */ | |
290 /** | |
291 * @return Map of String arrays | |
292 */ | |
293 public Map<K,String[]> toStringArrayMap() | |
294 { | |
295 HashMap<K,String[]> map = new HashMap<K,String[]>(_map.size()*3/2) | |
296 { | |
297 public String toString() | |
298 { | |
299 StringBuilder b=new StringBuilder(); | |
300 b.append('{'); | |
301 for (K k:keySet()) | |
302 { | |
303 if(b.length()>1) | |
304 b.append(','); | |
305 b.append(k); | |
306 b.append('='); | |
307 b.append(Arrays.asList(get(k))); | |
308 } | |
309 | |
310 b.append('}'); | |
311 return b.toString(); | |
312 } | |
313 }; | |
314 | |
315 for(Map.Entry<K,Object> entry: _map.entrySet()) | |
316 { | |
317 String[] a = LazyList.toStringArray(entry.getValue()); | |
318 map.put(entry.getKey(),a); | |
319 } | |
320 return map; | |
321 } | |
322 | |
323 @Override | |
324 public String toString() | |
325 { | |
326 return _cmap==null?_map.toString():_cmap.toString(); | |
327 } | |
328 | |
329 public void clear() | |
330 { | |
331 _map.clear(); | |
332 } | |
333 | |
334 public boolean containsKey(Object key) | |
335 { | |
336 return _map.containsKey(key); | |
337 } | |
338 | |
339 public boolean containsValue(Object value) | |
340 { | |
341 return _map.containsValue(value); | |
342 } | |
343 | |
344 public Set<Entry<K, Object>> entrySet() | |
345 { | |
346 return _map.entrySet(); | |
347 } | |
348 | |
349 @Override | |
350 public boolean equals(Object o) | |
351 { | |
352 return _map.equals(o); | |
353 } | |
354 | |
355 @Override | |
356 public int hashCode() | |
357 { | |
358 return _map.hashCode(); | |
359 } | |
360 | |
361 public boolean isEmpty() | |
362 { | |
363 return _map.isEmpty(); | |
364 } | |
365 | |
366 public Set<K> keySet() | |
367 { | |
368 return _map.keySet(); | |
369 } | |
370 | |
371 public Object remove(Object key) | |
372 { | |
373 return _map.remove(key); | |
374 } | |
375 | |
376 public int size() | |
377 { | |
378 return _map.size(); | |
379 } | |
380 | |
381 public Collection<Object> values() | |
382 { | |
383 return _map.values(); | |
384 } | |
385 | |
386 | |
387 | |
388 public Object putIfAbsent(K key, Object value) | |
389 { | |
390 if (_cmap==null) | |
391 throw new UnsupportedOperationException(); | |
392 return _cmap.putIfAbsent(key,value); | |
393 } | |
394 | |
395 public boolean remove(Object key, Object value) | |
396 { | |
397 if (_cmap==null) | |
398 throw new UnsupportedOperationException(); | |
399 return _cmap.remove(key,value); | |
400 } | |
401 | |
402 public boolean replace(K key, Object oldValue, Object newValue) | |
403 { | |
404 if (_cmap==null) | |
405 throw new UnsupportedOperationException(); | |
406 return _cmap.replace(key,oldValue,newValue); | |
407 } | |
408 | |
409 public Object replace(K key, Object value) | |
410 { | |
411 if (_cmap==null) | |
412 throw new UnsupportedOperationException(); | |
413 return _cmap.replace(key,value); | |
414 } | |
415 } |