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