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