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