1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.danube.http.util;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23
24
25
26
27
28
29
30
31
32 public class MultiStringHashMap implements MultiStringMap {
33
34
35 protected Map<String, Object> map;
36
37
38
39
40 public MultiStringHashMap() {
41 map = new HashMap<String, Object>();
42 }
43
44
45
46
47
48 public MultiStringHashMap(int initialCapacity) {
49 map = new HashMap<String, Object>(initialCapacity);
50 }
51
52
53
54
55
56
57 public MultiStringHashMap(int initialCapacity, float loadFactor) {
58 map = new HashMap<String, Object>(initialCapacity, loadFactor);
59 }
60
61
62
63
64
65
66
67
68
69
70
71
72
73 @SuppressWarnings("unchecked")
74 public void add(String id, String value) {
75 Object old = map.get(id);
76 if (old == null) {
77 map.put(id, value);
78 } else if (old instanceof String) {
79 ArrayList<String> list = new ArrayList<String>();
80 list.add((String)old);
81 list.add(value);
82 } else if (old instanceof List) {
83 ((List<String>)old).add(value);
84 } else {
85 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
86 }
87 }
88
89
90
91
92
93
94
95
96
97 public void addAll(String id, String[] values) {
98 addAll(id, Arrays.asList(values));
99 }
100
101
102
103
104
105
106
107
108
109
110 @SuppressWarnings("unchecked")
111 public void addAll(String id, Collection<String> values) {
112 Object old = map.get(id);
113 if (old == null) {
114 ArrayList<String> list = new ArrayList<String>();
115 list.addAll(values);
116 map.put(id, list);
117 } else if (old instanceof String) {
118 ArrayList<String> list = new ArrayList<String>();
119 list.add((String)old);
120 list.addAll(values);
121 map.put(id, list);
122 } else if (old instanceof List) {
123 ((List<String>)old).addAll(values);
124 } else {
125 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
126 }
127 }
128
129
130
131
132
133
134 public void putOnly(String id, String value) {
135 map.put(id, value);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150 public void putAll(String id, String[] values) {
151 if (values.length > 1) {
152 putAll(id, Arrays.asList(values));
153 } else if (values.length == 1) {
154 putOnly(id, values[0]);
155 } else {
156 removeAll(id);
157 }
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 public void putAll(String id, Collection<String> values) {
178 ArrayList<String> list = null;
179 if (values instanceof ArrayList) {
180 list = (ArrayList<String>)values;
181 map.put(id, values);
182 } else {
183 list = new ArrayList<String>();
184 list.addAll(values);
185 map.put(id, values);
186 }
187 int size = list.size();
188 if (size == 0) {
189 removeAll(id);
190 } else if (size == 1) {
191 putOnly(id, (String)list.get(0));
192 } else {
193 map.put(id, list);
194 }
195 }
196
197
198
199
200
201 @SuppressWarnings("unchecked")
202 public Collection<String> removeAll(String id) {
203 Object old = map.remove(id);
204 if (old instanceof String) {
205 String[] res = new String[1];
206 res[0] = (String)old;
207 return Collections.unmodifiableList(Arrays.asList(res));
208 } else if (old instanceof List) {
209 return Collections.unmodifiableList((List<String>)old);
210 } else if (old == null) {
211 return null;
212 } else {
213 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228 @SuppressWarnings("unchecked")
229 public String removeFirst(String id) {
230 Object old = map.get(id);
231 if (old instanceof String) {
232 return (String)map.remove(id);
233 } else if (old instanceof List) {
234 List<String> list = (List<String>)old;
235 String oldString = list.remove(0);
236 if (list.size() == 1) {
237 map.put(id, list.get(0));
238 }
239 return oldString;
240 } else {
241 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
242 }
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257 @SuppressWarnings("unchecked")
258 public String remove(String id, int index) {
259 Object old = map.get(id);
260 if (old instanceof String) {
261 if (index == 0) {
262 return (String)map.remove(id);
263 } else {
264 throw new IndexOutOfBoundsException("Has one element but index is " + index);
265 }
266 } else if (old instanceof List) {
267 List<String> list = (List<String>)old;
268 String oldString = list.remove(index);
269 if (list.size() == 1) {
270 map.put(id, list.get(0));
271 }
272 return oldString;
273 } else {
274 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
275 }
276 }
277
278
279
280
281
282
283 public boolean containsKey(String id) {
284 return map.containsKey(id);
285 }
286
287
288
289
290
291
292 @SuppressWarnings("unchecked")
293 public int getEntrySize(String id) {
294 Object old = map.get(id);
295 if (old instanceof String) {
296 return 1;
297 } else if (old instanceof List) {
298 List<String> list = (List<String>)old;
299 return list.size();
300 } else if (old == null) {
301 return 0;
302 } else {
303 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
304 }
305 }
306
307
308
309
310
311
312
313 @SuppressWarnings("unchecked")
314 public String getOnly(String id) {
315 Object old = map.get(id);
316 if (old instanceof String) {
317 return (String)map.get(id);
318 } else if (old instanceof List) {
319 List<String> list = (List<String>)old;
320 int size = list.size();
321 if (size == 0) {
322 return null;
323 } else if (size == 1) {
324 return list.get(0);
325 } else {
326
327 throw new IllegalStateException("Asked key has more then one element");
328 }
329 } else if (old == null) {
330 return null;
331 } else {
332 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
333 }
334 }
335
336
337
338
339
340
341
342 @SuppressWarnings("unchecked")
343 public String getFirst(String id) {
344 Object old = map.get(id);
345 if (old instanceof String) {
346 return (String)map.get(id);
347 } else if (old instanceof List) {
348 List<String> list = (List<String>)old;
349 int size = list.size();
350 if (size == 0) {
351 return null;
352 } else {
353 return list.get(0);
354 }
355 } else if (old == null) {
356 return null;
357 } else {
358 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
359 }
360 }
361
362
363
364
365
366
367
368 @SuppressWarnings("unchecked")
369 public String[] getAsArray(String id) {
370 Object old = map.get(id);
371 if (old == null) {
372 return new String[0];
373 } else if (old instanceof String) {
374 return new String[]{(String)old};
375 } else if (old instanceof List) {
376 List<String> list = (List<String>)old;
377 String[] res = new String[list.size()];
378 res = list.toArray(res);
379 return res;
380 } else {
381 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
382 }
383 }
384
385
386
387
388
389
390
391 @SuppressWarnings("unchecked")
392 public List<String> getAsList(String id) {
393 Object old = map.get(id);
394 if (old == null) {
395 return Collections.emptyList();
396 } else if (old instanceof String) {
397 return Arrays.asList((String)old);
398 } else if (old instanceof List) {
399 return (List<String>)old;
400 } else {
401 throw new IllegalStateException("Found wrong type as the maps value; " + old.getClass());
402 }
403 }
404
405
406
407
408 public void clear() {
409 map.clear();
410 }
411
412
413
414
415
416 public Set<String> keySet() {
417 return map.keySet();
418 }
419
420
421
422
423
424
425 public Map<String, Object> getAsMap() {
426 return map;
427 }
428
429
430
431
432
433
434 @SuppressWarnings("unchecked")
435 public Collection<Map.Entry<String, String>> getAllEntries() {
436 ArrayList<Map.Entry<String, String>> all = new ArrayList<Map.Entry<String, String>>();
437
438 for (Map.Entry<String, Object> entry : map.entrySet()) {
439 Object obj = entry.getValue();
440 if (obj instanceof String) {
441 InternalMapEntry<String, String> newEntry = new InternalMapEntry<String, String>(entry.getKey(), (String)entry.getValue());
442 all.add(newEntry);
443
444 } else if (obj instanceof List) {
445 List<String> list = (List<String>)obj;
446 String key = entry.getKey();
447 for (String element : list) {
448 InternalMapEntry<String, String> newEntry = new InternalMapEntry<String, String>(key, element);
449 all.add(newEntry);
450 }
451 } else {
452 throw new IllegalStateException("Found wrong type as the maps value; " + obj.getClass());
453 }
454 }
455
456 return (Collection<Map.Entry<String, String>>)all;
457 }
458
459
460
461
462
463 public int size() {
464 return map.size();
465 }
466
467
468
469
470 protected class InternalMapEntry<K, V> implements Map.Entry<K, V> {
471
472
473 protected K key;
474
475 protected V value;
476
477
478
479
480
481
482 public InternalMapEntry(K key, V value) {
483 this.key = key;
484 this.value = value;
485 }
486
487
488
489
490
491 public K getKey() {
492 return key;
493 }
494
495
496
497
498
499 public V getValue() {
500 return value;
501 }
502
503
504
505
506
507
508 public V setValue(V value) {
509 V old = this.value;
510 this.value = value;
511 return old;
512 }
513
514 }
515
516 }