1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import java.util.AbstractMap;
22 import java.util.AbstractSet;
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.NoSuchElementException;
27 import java.util.Set;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 class _ArrayMap<K, V> extends AbstractMap<K, V> implements Cloneable
66 {
67
68
69
70 public _ArrayMap()
71 {
72 this(0, 1);
73 }
74
75
76
77
78
79 public _ArrayMap(int size)
80 {
81 this(size, 1);
82 }
83
84
85
86
87
88
89
90 public _ArrayMap(int size, int increment)
91 {
92 if ((increment < 1) || (size < 0))
93 {
94 throw new IllegalArgumentException();
95 }
96
97 if (size > 0)
98 {
99 _array = new Object[2 * size];
100 }
101
102 _increment = increment;
103 }
104
105
106
107
108 @SuppressWarnings("unchecked")
109 public K getKey(int index)
110 {
111 if ((index < 0) || (index >= size()))
112 {
113 throw new IndexOutOfBoundsException();
114 }
115 return (K) _array[index * 2];
116 }
117
118
119
120
121 @SuppressWarnings("unchecked")
122 public V getValue(int index)
123 {
124 if ((index < 0) || (index >= size()))
125 {
126 throw new IndexOutOfBoundsException();
127 }
128 return (V) _array[index * 2 + 1];
129 }
130
131
132
133
134
135 static public Object get(Object[] array, Object key)
136 {
137 Object o = getByIdentity(array, key);
138 if (o != null)
139 {
140 return o;
141 }
142
143 return getByEquality(array, key);
144 }
145
146
147
148
149
150 static public Object getByIdentity(Object[] array, Object key)
151 {
152 if (array != null)
153 {
154 int length = array.length;
155 for (int i = 0; i < length; i += 2)
156 {
157 if (array[i] == key)
158 {
159 return array[i + 1];
160 }
161 }
162 }
163
164 return null;
165 }
166
167
168
169
170
171 static public Object getByEquality(Object[] array, Object key)
172 {
173 if (array != null)
174 {
175 int length = array.length;
176
177 for (int i = 0; i < length; i += 2)
178 {
179 Object targetKey = array[i];
180 if (targetKey == null)
181 {
182 return null;
183 }
184 else if (targetKey.equals(key))
185 {
186 return array[i + 1];
187 }
188 }
189 }
190
191 return null;
192 }
193
194
195
196
197
198 static public Object[] put(Object[] array, Object key, Object value)
199 {
200 if (array != null)
201 {
202 int length = array.length;
203
204 for (int i = 0; i < length; i += 2)
205 {
206 Object curKey = array[i];
207
208 if (((curKey != null) && (curKey.equals(key)))
209 || (curKey == key))
210 {
211 array[i + 1] = value;
212 return array;
213 }
214 }
215 }
216
217 return _addToArray(array, key, value, 1);
218 }
219
220
221
222
223
224 static public Object[] remove(Object[] array, Object key)
225 {
226 return remove(array, key, true);
227 }
228
229
230
231
232
233 static public Object[] remove(Object[] array, Object key, boolean reallocate)
234 {
235 if (array != null)
236 {
237 int length = array.length;
238
239 for (int i = 0; i < length; i += 2)
240 {
241 Object curKey = array[i];
242
243 if (((curKey != null) && curKey.equals(key)) || (curKey == key))
244 {
245 Object[] newArray = array;
246
247 if (reallocate)
248 {
249 newArray = new Object[length - 2];
250 System.arraycopy(array, 0, newArray, 0, i);
251 }
252
253 System.arraycopy(array, i + 2, newArray, i, length - i - 2);
254
255 if (!reallocate)
256 {
257 array[length - 1] = null;
258 array[length - 2] = null;
259 }
260
261 return newArray;
262 }
263 }
264 }
265
266 return array;
267 }
268
269
270
271
272 @Override
273 public int size()
274 {
275 return _size;
276 }
277
278 @Override
279 public boolean containsValue(Object value)
280 {
281 int entryCount = size() * 2;
282 for (int i = 0; i < entryCount; i += 2)
283 {
284 if (_equals(value, _array[i + 1]))
285 {
286 return true;
287 }
288 }
289
290 return false;
291 }
292
293 @Override
294 public boolean containsKey(Object key)
295 {
296 int entryCount = size() * 2;
297 for (int i = 0; i < entryCount; i += 2)
298 {
299 if (_equals(key, _array[i]))
300 {
301 return true;
302 }
303 }
304
305 return false;
306 }
307
308
309
310
311
312
313 @SuppressWarnings("unchecked")
314 public Iterator<K> keys()
315 {
316 int size = _size;
317
318 if (size == 0)
319 {
320 return null;
321 }
322 ArrayList<K> keyList = new ArrayList<K>();
323 int i = (size - 1) * 2;
324 while (i >= 0)
325 {
326 keyList.add((K) _array[i]);
327 i = i - 2;
328 }
329 return keyList.iterator();
330 }
331
332
333
334
335 public static Iterator<Object> getKeys(Object[] array)
336 {
337 if (array == null)
338 {
339 return null;
340 }
341 ArrayList<Object> keyList = new ArrayList<Object>();
342 int i = array.length - 2;
343 while (i >= 0)
344 {
345 keyList.add(array[i]);
346 i = i - 2;
347 }
348 return keyList.iterator();
349 }
350
351
352
353
354 public static Iterator<Object> getValues(Object[] array)
355 {
356 if (array == null)
357 {
358 return null;
359 }
360 ArrayList<Object> valueList = new ArrayList<Object>();
361 int i = array.length - 1;
362 while (i >= 0)
363 {
364 valueList.add(array[i]);
365 i = i - 2;
366 }
367 return valueList.iterator();
368 }
369
370
371
372
373 @SuppressWarnings("unchecked")
374 @Override
375 public Object clone()
376 {
377 try
378 {
379 _ArrayMap<K, V> am = (_ArrayMap<K, V>) super.clone();
380
381 am._array = _array.clone();
382 am._size = _size;
383 am._increment = _increment;
384 return am;
385 }
386 catch (CloneNotSupportedException cnse)
387 {
388
389 return null;
390 }
391 }
392
393 @Override
394 public Set<Map.Entry<K, V>> entrySet()
395 {
396 if (_entrySet == null)
397 {
398 _entrySet = new AbstractSet<Map.Entry<K, V>>()
399 {
400 @Override
401 public int size()
402 {
403 return _ArrayMap.this.size();
404 }
405
406 @Override
407 public Iterator<Map.Entry<K, V>> iterator()
408 {
409 return new Iterator<Map.Entry<K, V>>()
410 {
411 public boolean hasNext()
412 {
413 return (_index < _ArrayMap.this.size());
414 }
415
416 public void remove()
417 {
418
419
420
421 if ((_index == 0) || _removed)
422 {
423 throw new IllegalStateException();
424 }
425
426 _removed = true;
427
428 int size = _ArrayMap.this.size();
429 Object[] array = _ArrayMap.this._array;
430 if (size > _index)
431 {
432 System.arraycopy(array, _index * 2, array,
433 (_index - 1) * 2, (size - _index) * 2);
434 }
435
436
437 array[size * 2 - 2] = null;
438 array[size * 2 - 1] = null;
439
440 _ArrayMap.this._size = size - 1;
441
442
443 _index = _index - 1;
444 }
445
446 public Map.Entry<K, V> next()
447 {
448 if (!hasNext())
449 {
450 throw new NoSuchElementException();
451 }
452
453 final int index = _index;
454 _removed = false;
455 _index = index + 1;
456
457 return new Map.Entry<K, V>()
458 {
459 public K getKey()
460 {
461 return _ArrayMap.this.getKey(index);
462 }
463
464 public V getValue()
465 {
466 return _ArrayMap.this.getValue(index);
467 }
468
469 public V setValue(V value)
470 {
471 V oldValue = getValue();
472 _ArrayMap.this._array[index * 2 + 1] = value;
473 return oldValue;
474 }
475
476 @SuppressWarnings("unchecked")
477 @Override
478 public boolean equals(Object o)
479 {
480 if (!(o instanceof Map.Entry))
481 {
482 return false;
483 }
484 Map.Entry<K, V> e = (Map.Entry<K, V>) o;
485 return _equals(getKey(), e.getKey())
486 && _equals(getValue(), e.getValue());
487 }
488
489 @Override
490 public int hashCode()
491 {
492 Object key = getKey();
493 Object value = getValue();
494 return ((key == null) ? 0 : key.hashCode())
495 ^ ((value == null) ? 0 : value
496 .hashCode());
497 }
498 };
499 }
500
501 private int _index;
502 private boolean _removed;
503 };
504 }
505 };
506 }
507
508 return _entrySet;
509 }
510
511 @SuppressWarnings("unchecked")
512 @Override
513 public V get(Object key)
514 {
515 return (V) getByEquality(_array, key);
516
517 }
518
519 @SuppressWarnings("unchecked")
520 public V getByIdentity(Object key)
521 {
522 return (V) getByIdentity(_array, key);
523 }
524
525 @SuppressWarnings("unchecked")
526 @Override
527 public V put(K key, V value)
528 {
529 if (value == null)
530 {
531 return remove(key);
532 }
533
534 Object[] array = _array;
535
536
537
538 Object o = getByEquality(array, key);
539
540 if (o == null)
541 {
542 int size = _size * 2;
543 if ((array != null) && (size < array.length))
544 {
545 array[size] = key;
546 array[size + 1] = value;
547 }
548 else
549 {
550 _array = _addToArray(array, key, value, _increment);
551 }
552
553 _size = _size + 1;
554 }
555 else
556 {
557
558
559
560 _array = put(array, key, value);
561 }
562
563 return (V) o;
564 }
565
566 @SuppressWarnings("unchecked")
567 @Override
568 public V remove(Object key)
569 {
570 Object[] array = _array;
571 Object o = get(array, key);
572 if (o != null)
573 {
574 remove(array, key, false);
575 _size = _size - 1;
576 }
577
578 return (V) o;
579 }
580
581
582
583
584 @Override
585 public void clear()
586 {
587 int size = _size;
588 if (size > 0)
589 {
590 size = size * 2;
591 for (int i = 0; i < size; i++)
592 {
593 _array[i] = null;
594 }
595
596 _size = 0;
597 }
598 }
599
600
601
602
603
604 private static Object[] _addToArray(Object[] array, Object key,
605 Object value, int increment)
606 {
607 Object[] newArray = null;
608 if (array != null)
609 {
610 int length = array.length;
611 newArray = new Object[length + (2 * increment)];
612 System.arraycopy(array, 0, newArray, 2, length);
613 }
614 else
615 {
616 newArray = new Object[2 * increment];
617 }
618
619 newArray[0] = key;
620 newArray[1] = value;
621 return newArray;
622 }
623
624 private static boolean _equals(Object a, Object b)
625 {
626 if (a == null)
627 {
628 return b == null;
629 }
630 return a.equals(b);
631 }
632
633 private Object[] _array;
634 private int _size;
635 private int _increment;
636 private Set<Map.Entry<K, V>> _entrySet;
637 }