1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.util;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.ObjectOutputStream;
24 import java.io.ObjectStreamException;
25 import java.io.Serializable;
26 import java.lang.reflect.Array;
27 import java.util.AbstractQueue;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.ConcurrentModificationException;
32 import java.util.EnumSet;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.ListIterator;
38 import java.util.Map;
39 import java.util.NoSuchElementException;
40 import java.util.Queue;
41 import java.util.RandomAccess;
42 import java.util.Set;
43 import java.util.concurrent.atomic.AtomicReference;
44
45 import org.apache.myfaces.trinidad.component.CompositeIterator;
46 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
47
48
49
50
51 public final class CollectionUtils
52 {
53 private CollectionUtils()
54 {
55
56 }
57
58
59
60
61
62
63
64 public static <T> ArrayList<T> arrayList(Iterator<T> iterator)
65 {
66 ArrayList<T> arrayList = new ArrayList<T>();
67
68 while (iterator.hasNext())
69 arrayList.add(iterator.next());
70
71 return arrayList;
72 }
73
74
75
76
77
78
79
80 public static <T> T[] toArray(Iterator<? extends T> iterator, Class<T> type)
81 {
82 if (iterator.hasNext())
83 {
84 Collection arrayList = arrayList(iterator);
85 T[] outArray = (T[])Array.newInstance(type, arrayList.size());
86
87 return (T[])arrayList.toArray(outArray);
88 }
89 else
90 {
91
92 return (T[])Array.newInstance(type, 0);
93 }
94 }
95
96
97
98
99
100 public static <T> Queue<T> emptyQueue()
101 {
102 return (Queue<T>)_EMPTY_QUEUE;
103 }
104
105
106
107
108
109 public static <T> Iterator<T> emptyIterator()
110 {
111 return (Iterator<T>)_EMPTY_ITERATOR;
112 }
113
114
115
116
117
118 public static <T> ListIterator<T> emptyListIterator()
119 {
120 return (ListIterator<T>)_EMPTY_LIST_ITERATOR;
121 }
122
123
124
125
126
127
128
129
130
131 public static <K,V> Iterator<V> subsetValueIterator(Map<? extends K, ? extends V> map,
132 Collection<? extends K> allowedKeys)
133 {
134 if (map.isEmpty() || allowedKeys.isEmpty())
135 {
136 return emptyIterator();
137 }
138 else
139 {
140 return new SubsetValueIterator<K,V>(map, allowedKeys.iterator());
141 }
142 }
143
144
145
146
147
148
149
150
151
152
153
154 public static <K,V> Iterator<V> subsetValueIterator(Map<? extends K, ? extends V> map,
155 Iterator<? extends K> allowedKeys)
156 {
157 if (map.isEmpty() || !allowedKeys.hasNext())
158 {
159 return emptyIterator();
160 }
161 else
162 {
163 return new SubsetValueIterator<K,V>(map, allowedKeys);
164 }
165 }
166
167
168
169
170 private static class SubsetValueIterator<K,V> implements Iterator<V>
171 {
172 public SubsetValueIterator(Map<? extends K, ? extends V> sourceMap,
173 Iterator<? extends K> allowedkeys)
174 {
175 if ((sourceMap == null) || (allowedkeys == null))
176 throw new NullPointerException();
177
178 _sourceMap = sourceMap;
179 _allowedkeys = allowedkeys;
180 }
181
182 @Override
183 public boolean hasNext()
184 {
185 return (_getKey() != null);
186 }
187
188 @Override
189 public V next()
190 {
191 K key = _getKey();
192
193 if (key == null)
194 throw new NoSuchElementException();
195
196
197 _calcNext = true;
198
199 return _sourceMap.get(key);
200 }
201
202 @Override
203 public void remove()
204 {
205
206 if (_nextValidKey == null)
207 throw new IllegalStateException();
208
209 try
210 {
211 _sourceMap.remove(_nextValidKey);
212 }
213 finally
214 {
215 _nextValidKey = null;
216 _calcNext = true;
217 }
218 }
219
220 private K _getKey()
221 {
222 if ((_nextValidKey == null) || _calcNext)
223 {
224 _nextValidKey = _getNextContainedKey();
225 _calcNext = false;
226 }
227
228 return _nextValidKey;
229 }
230
231 private K _getNextContainedKey()
232 {
233 while (_allowedkeys.hasNext())
234 {
235 K nextKey = _allowedkeys.next();
236
237 if (_sourceMap.containsKey(nextKey))
238 {
239 return nextKey;
240 }
241 }
242
243 return null;
244 }
245
246 private final Map<? extends K, ? extends V> _sourceMap;
247 private final Iterator<? extends K> _allowedkeys;
248 private K _nextValidKey;
249 private boolean _calcNext = true;
250 }
251
252
253
254
255
256
257
258
259
260 public static <T> Set<T> asSet(T... a)
261 {
262 return _asSet(a, false);
263 }
264
265
266
267
268
269
270
271
272 public static <T> Set<T> asUnmodifiableSet(T... a)
273 {
274 return _asSet(a, true);
275 }
276
277
278
279
280
281
282
283
284 public static <E extends Enum<E>> Set<E> unmodifiableCopyOfEnumSet(Set<E> s)
285 {
286 Class<? extends Set> copyClass = s.getClass();
287
288 if ((_EMPTY_SET == copyClass) || (_SINGLETON_SET == copyClass))
289 {
290
291 return s;
292 }
293 else
294 {
295 return Collections.unmodifiableSet(EnumSet.copyOf(s));
296 }
297 }
298
299 private static <T> Set<T> _asSet(T[] a, boolean makeImmutable)
300 {
301 int count = (a != null) ? a.length : 0;
302
303 Set<T> outSet;
304
305 if (count == 0)
306 {
307 outSet = Collections.emptySet();
308 }
309 else
310 {
311 if (count == 1)
312 {
313 outSet = Collections.singleton(a[0]);
314 }
315 else
316 {
317
318
319 int initialSize = (int)Math.ceil(count / .75d);
320
321 outSet = new HashSet<T>(initialSize, .75f);
322
323 for (int i = 0; i < count ; i++)
324 {
325 outSet.add(a[i]);
326 }
327
328 if (makeImmutable)
329 {
330 outSet = Collections.unmodifiableSet(outSet);
331 }
332 }
333 }
334
335 return outSet;
336 }
337
338
339
340
341
342
343
344
345
346
347
348
349
350 public static <T> Set<T> compositeSet(Set<T> primarySet, Set<T> secondarySet)
351 {
352 if ((primarySet instanceof Serializable) && (secondarySet instanceof Serializable))
353 return new SerializableFixedCompositeSet<T>(primarySet, secondarySet);
354 else
355 return new FixedCompositeSet<T>(primarySet, secondarySet);
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374 public static <T> Set<T> overlappingCompositeSet(Set<T> primarySet, Set<T> secondarySet)
375 {
376 if ((primarySet instanceof Serializable) && (secondarySet instanceof Serializable))
377 return new SerializableLenientFixedCompositeSet<T>(primarySet, secondarySet);
378 else
379 return new LenientFixedCompositeSet<T>(primarySet, secondarySet);
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398 public static <T> Collection<T> getSerializableCollection(Collection<T> c)
399 {
400 if (c instanceof Serializable)
401 return c;
402 else
403 return new SerializableCollection<T>(c);
404 }
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431 public static <T> List<T> newSerializableList(List<T> l)
432 {
433 if (l instanceof RandomAccess)
434 {
435 return new SerializableRandomAccessList<T>(l);
436 }
437 else
438 {
439 return new SerializableList<T>(l);
440 }
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469 public static <T> List<T> getSerializableList(List<T> l)
470 {
471
472
473 if ((l instanceof Serializable) &&
474 !_CHECKED_LIST.isInstance(l) &&
475 !_UNMODIFIABLE_LIST.isInstance(l) &&
476 !_SYNCHRONIZED_LIST.isInstance(l))
477 return l;
478 else
479 {
480 return newSerializableList(l);
481 }
482 }
483
484
485
486
487
488
489
490 public interface MapMutationHooks<K, V>
491 {
492
493
494
495
496
497
498 public void writeNotify(Map<K,V> map, K key, V value);
499
500
501
502
503
504
505 public void removeNotify(Map<K,V> map, Object key);
506
507
508
509
510
511 public void clearNotify(Map<K,V> map);
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525 public static <K,V> Map<K, V> newMutationHookedMap(Map<K, V> map, MapMutationHooks<K, V> hooks)
526 {
527 if (map == null)
528 throw new NullPointerException();
529
530 if (hooks == null)
531 throw new NullPointerException();
532
533 if (map instanceof Serializable)
534 return new SerializableExternalAccessHookMap<K, V>(map, hooks);
535 else
536 return new ExternalAccessHookMap<K, V>(map, hooks);
537 }
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 public static <K,V> Map<K, V> getCheckedSerializationMap(Map<K, V> map)
553 {
554 return getCheckedSerializationMap(map, true);
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572 public static <K,V> Map<K, V> getCheckedSerializationMap(
573 Map<K, V> map,
574 boolean requireSerializable)
575 {
576 if (map instanceof CheckedSerializationMap)
577 return map;
578 else
579 return new CheckedSerializationMap<K,V>(map, requireSerializable);
580 }
581
582
583
584
585
586
587
588 public static <E> int getUnionSize(
589 Collection<? extends E> firstCollection,
590 Collection<? extends E> secondCollection)
591 {
592 int firstSize = (firstCollection != null)
593 ? firstCollection.size()
594 : 0;
595
596 int secondSize = (secondCollection != null)
597 ? secondCollection.size()
598 : 0;
599
600 if (firstSize == 0)
601 return secondSize;
602
603 if (secondSize == 0)
604 return firstSize;
605
606
607 int size;
608 Collection<? extends E> iteratingCollection;
609 Collection<? extends E> baseCollection;
610
611 if (firstSize >= secondSize)
612 {
613 baseCollection = firstCollection;
614 iteratingCollection = secondCollection;
615 size = firstSize;
616 }
617 else
618 {
619 baseCollection = secondCollection;
620 iteratingCollection = firstCollection;
621 size = secondSize;
622 }
623
624 for (E currValue : iteratingCollection)
625 {
626 if (!baseCollection.contains(currValue))
627 {
628 size++;
629 }
630 }
631
632 return size;
633 }
634
635
636 protected static <T> T[] copyOf(T[] original, int newLength)
637 {
638 return (T[]) copyOf(original, newLength, original.getClass());
639 }
640
641 protected static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType)
642 {
643 T[] copy = ((Object)newType == (Object)Object[].class)
644 ? (T[]) new Object[newLength]
645 : (T[]) Array.newInstance(newType.getComponentType(), newLength);
646 System.arraycopy(original, 0, copy, 0,
647 Math.min(original.length, newLength));
648 return copy;
649 }
650
651 protected abstract static class DelegatingCollection<E> implements Collection<E>
652 {
653 protected abstract Collection<E> getDelegate();
654
655 public int size()
656 {
657 return getDelegate().size();
658 }
659
660 public boolean isEmpty()
661 {
662 return getDelegate().isEmpty();
663 }
664
665 public boolean contains(Object o)
666 {
667 return getDelegate().contains(o);
668 }
669
670 public Iterator<E> iterator()
671 {
672 return getDelegate().iterator();
673 }
674
675 public Object[] toArray()
676 {
677 return getDelegate().toArray();
678 }
679
680 public <T> T[] toArray(T[] a)
681 {
682 return getDelegate().toArray(a);
683 }
684
685 public boolean add(E e)
686 {
687 return getDelegate().add(e);
688 }
689
690 public boolean remove(Object o)
691 {
692 return getDelegate().remove(0);
693 }
694
695 public boolean containsAll(Collection<?> c)
696 {
697 return getDelegate().containsAll(c);
698 }
699
700 public boolean addAll(Collection<? extends E> c)
701 {
702 return getDelegate().addAll(c);
703 }
704
705 public boolean removeAll(Collection<?> c)
706 {
707 return getDelegate().removeAll(c);
708 }
709
710 public boolean retainAll(Collection<?> c)
711 {
712 return getDelegate().retainAll(c);
713 }
714
715 public void clear()
716 {
717 getDelegate().clear();
718 }
719
720
721
722
723
724
725 public boolean equals(Object o)
726 {
727 return (o == this) || getDelegate().equals(o);
728 }
729
730 public int hashCode()
731 {
732 return getDelegate().hashCode();
733 }
734
735 public String toString()
736 {
737 return getDelegate().toString();
738 }
739 }
740
741
742
743
744
745 protected abstract static class CompositeCollection<E> implements Collection<E>
746 {
747 protected abstract Collection<E> getPrimaryDelegate();
748 protected abstract Collection<E> getSecondaryDelegate();
749
750 public int size()
751 {
752 return getPrimaryDelegate().size() + getSecondaryDelegate().size();
753 }
754
755 public boolean isEmpty()
756 {
757 return getPrimaryDelegate().isEmpty() && getSecondaryDelegate().isEmpty();
758 }
759
760 public boolean contains(Object o)
761 {
762 return getPrimaryDelegate().contains(o) || getSecondaryDelegate().contains(o);
763 }
764
765 public Iterator<E> iterator()
766 {
767 return new CompositeIterator<E>(getPrimaryDelegate().iterator(),
768 getSecondaryDelegate().iterator());
769 }
770
771 public Object[] toArray()
772 {
773 int size = size();
774
775 Object[] out = new Object[size];
776
777 int i = 0;
778 for (Object currObject : this)
779 {
780 out[i] = currObject;
781
782 i++;
783
784 if (i == size)
785 break;
786 }
787
788 return out;
789 }
790
791 public <T> T[] toArray(T[] outArray)
792 {
793 int collectionSize = size();
794 int arraySize = outArray.length;
795
796
797 if (collectionSize > arraySize)
798 {
799 outArray = (T[])Array.newInstance(outArray.getClass().getComponentType(),
800 collectionSize);
801 }
802
803 Iterator<E> iterator = this.iterator();
804
805 for (int i = 0; i < collectionSize; i++)
806 {
807 if (!iterator.hasNext())
808 break;
809
810 outArray[i] = (T)iterator.next();
811 }
812
813 return outArray;
814 }
815
816 public boolean add(E e)
817 {
818 boolean modified = getPrimaryDelegate().add(e);
819
820 if (modified)
821 {
822
823
824 modified = !getSecondaryDelegate().remove(e);
825 }
826
827 return modified;
828 }
829
830 public boolean remove(Object o)
831 {
832 boolean removed = getPrimaryDelegate().remove(0);
833
834 if (!removed)
835 removed = getSecondaryDelegate().remove(0);
836
837 return removed;
838 }
839
840 public boolean containsAll(Collection<?> c)
841 {
842
843
844 Set<Object> intersection = new HashSet<Object>(getPrimaryDelegate());
845 intersection.retainAll(c);
846
847 if (intersection.size() == c.size())
848 {
849
850 return true;
851 }
852 else
853 {
854
855
856 Set<Object> remainder = new HashSet<Object>(c);
857 remainder.removeAll(intersection);
858
859 return getSecondaryDelegate().containsAll(remainder);
860 }
861 }
862
863 public boolean addAll(Collection<? extends E> c)
864 {
865
866 boolean changed = !containsAll(c);
867
868
869 getSecondaryDelegate().removeAll(c);
870 getPrimaryDelegate().addAll(c);
871
872 return changed;
873 }
874
875 public boolean removeAll(Collection<?> c)
876 {
877 return getPrimaryDelegate().removeAll(c) || getSecondaryDelegate().removeAll(c);
878 }
879
880 public boolean retainAll(Collection<?> c)
881 {
882 return getPrimaryDelegate().retainAll(c) || getSecondaryDelegate().retainAll(c);
883 }
884
885 public void clear()
886 {
887 getPrimaryDelegate().clear();
888 getSecondaryDelegate().clear();
889 }
890
891 @Override
892 public String toString()
893 {
894 return super.toString() +
895 "[primary:" +
896 getPrimaryDelegate() +
897 ", secondary:" +
898 getSecondaryDelegate() +
899 "]";
900 }
901 }
902
903
904
905
906
907 private static class RemovingIterator<E> implements Iterator<E>
908 {
909 public RemovingIterator(Iterator<E> baseIterator, Collection<E> disjointCollection)
910 {
911 _baseIterator = baseIterator;
912 _disjointCollection = disjointCollection;
913 }
914
915 public boolean hasNext()
916 {
917 return _baseIterator.hasNext();
918 }
919
920 public E next()
921 {
922 _last = _baseIterator.next();
923
924 return _last;
925 }
926
927 public void remove()
928 {
929 _baseIterator.remove();
930
931
932
933
934 _disjointCollection.remove(_last);
935 _last = null;
936 }
937
938 private final Iterator<E> _baseIterator;
939 private final Collection<E> _disjointCollection;
940 private E _last;
941 }
942
943
944
945
946
947
948 private static class DisjointIterator<E> implements Iterator<E>
949 {
950 public DisjointIterator(Collection<E> checkedCollection, Collection<E> disjointCollection)
951 {
952 _checkedCollection = checkedCollection;
953 _disjointIterator = disjointCollection.iterator();
954 }
955
956 public boolean hasNext()
957 {
958 if (_nextHolder == null)
959 {
960 do
961 {
962 if (_disjointIterator.hasNext())
963 {
964 E next = _disjointIterator.next();
965
966 if (!_checkedCollection.contains(next))
967 {
968
969 _nextHolder = new AtomicReference<E>(next);
970 break;
971 }
972 }
973 else
974 {
975 return false;
976 }
977 }
978 while (true);
979 }
980
981 return true;
982 }
983
984 public E next()
985 {
986
987 if (hasNext())
988 {
989 E value = _nextHolder.get();
990
991
992 _nextHolder = null;
993 return value;
994 }
995 else
996 {
997 throw new NoSuchElementException();
998 }
999 }
1000
1001 public void remove()
1002 {
1003
1004
1005
1006
1007
1008
1009
1010 if (_nextHolder == null)
1011 _disjointIterator.remove();
1012 else
1013 throw new IllegalStateException();
1014 }
1015
1016 private final Collection<E> _checkedCollection;
1017 private final Iterator<E> _disjointIterator;
1018 private AtomicReference<E> _nextHolder;
1019 }
1020
1021
1022
1023
1024
1025 protected abstract static class CompositeSet<E> extends CompositeCollection<E> implements Set<E>
1026 {
1027 @Override
1028 protected abstract Set<E> getPrimaryDelegate();
1029
1030 @Override
1031 protected abstract Set<E> getSecondaryDelegate();
1032
1033
1034
1035
1036 @Override
1037 public boolean equals(Object o)
1038 {
1039 if (o == this)
1040 return true;
1041 else if (!(o instanceof Set))
1042 return false;
1043 else
1044 {
1045 Collection other = (Collection) o;
1046
1047 if (other.size() != size())
1048 {
1049 return false;
1050 }
1051 else
1052 {
1053
1054
1055 try
1056 {
1057 return containsAll(other);
1058 }
1059 catch(NullPointerException npe)
1060 {
1061
1062 return false;
1063 }
1064 catch(ClassCastException npe)
1065 {
1066
1067 return false;
1068 }
1069 }
1070 }
1071 }
1072
1073
1074
1075
1076 @Override
1077 public int hashCode()
1078 {
1079
1080 return getPrimaryDelegate().hashCode() + getSecondaryDelegate().hashCode();
1081 }
1082 }
1083
1084
1085
1086
1087 private static class FixedCompositeSet<E> extends CompositeSet<E>
1088 {
1089 FixedCompositeSet(Set<E> primarySet, Set<E> secondarySet)
1090 {
1091 if (primarySet == null)
1092 throw new NullPointerException();
1093
1094 if (secondarySet == null)
1095 throw new NullPointerException();
1096
1097 assert Collections.disjoint(primarySet, secondarySet) : "Composed Sets not disjoint";
1098
1099 _primarySet = primarySet;
1100 _secondarySet = secondarySet;
1101 }
1102
1103 @Override
1104 protected Set<E> getPrimaryDelegate()
1105 {
1106 return _primarySet;
1107 }
1108
1109 @Override
1110 protected Set<E> getSecondaryDelegate()
1111 {
1112 return _secondarySet;
1113 }
1114
1115 private final Set<E> _primarySet;
1116 private final Set<E> _secondarySet;
1117 }
1118
1119
1120
1121
1122
1123 private static final class SerializableFixedCompositeSet<E> extends FixedCompositeSet<E>
1124 implements Serializable
1125 {
1126 SerializableFixedCompositeSet(Set<E> primarySet, Set<E> secondarySet)
1127 {
1128 super(primarySet, secondarySet);
1129 }
1130
1131 private static final long serialVersionUID = 0L;
1132 }
1133
1134
1135
1136
1137
1138 protected abstract static class LenientCompositeSet<E> extends CompositeSet<E>
1139 {
1140 @Override
1141 public int size()
1142 {
1143 return CollectionUtils.getUnionSize(getPrimaryDelegate(), getSecondaryDelegate());
1144 }
1145
1146 @Override
1147 public Iterator<E> iterator()
1148 {
1149
1150
1151
1152 Set<E> primaryDelegate = getPrimaryDelegate();
1153 Set<E> secondaryDelegate = getSecondaryDelegate();
1154
1155 if (primaryDelegate.size() >= secondaryDelegate.size())
1156 {
1157 return new CompositeIterator<E>(
1158 new RemovingIterator<E>(primaryDelegate.iterator(), secondaryDelegate),
1159 new DisjointIterator<E>(primaryDelegate, secondaryDelegate));
1160 }
1161 else
1162 {
1163 return new CompositeIterator<E>(
1164 new RemovingIterator<E>(secondaryDelegate.iterator(), primaryDelegate),
1165 new DisjointIterator<E>(secondaryDelegate, primaryDelegate));
1166 }
1167 }
1168
1169 @Override
1170 public boolean add(E e)
1171 {
1172 boolean modified = getPrimaryDelegate().add(e);
1173
1174 if (modified)
1175 {
1176
1177
1178
1179 modified = !getSecondaryDelegate().contains(e);
1180 }
1181
1182 return modified;
1183 }
1184
1185 @Override
1186 public boolean remove(Object o)
1187 {
1188
1189
1190 boolean removed = getPrimaryDelegate().remove(0);
1191 removed |= getSecondaryDelegate().remove(0);
1192
1193 return removed;
1194 }
1195
1196 @Override
1197 public boolean addAll(Collection<? extends E> c)
1198 {
1199
1200 boolean changed = !containsAll(c);
1201
1202
1203
1204 getPrimaryDelegate().addAll(c);
1205
1206 return changed;
1207 }
1208
1209
1210
1211
1212 @Override
1213 public int hashCode()
1214 {
1215
1216
1217
1218
1219
1220 Set<E> primaryDelegate = getPrimaryDelegate();
1221 Set<E> secondaryDelegate = getSecondaryDelegate();
1222
1223 int hashCode;
1224 Iterator<E> disjointElements;
1225
1226 if (primaryDelegate.size() >= secondaryDelegate.size())
1227 {
1228 hashCode = primaryDelegate.hashCode();
1229 disjointElements = new DisjointIterator<E>(primaryDelegate, secondaryDelegate);
1230 }
1231 else
1232 {
1233 hashCode = secondaryDelegate.hashCode();
1234 disjointElements = new DisjointIterator<E>(secondaryDelegate, primaryDelegate);
1235 }
1236
1237 while (disjointElements.hasNext())
1238 {
1239 E currElement = disjointElements.next();
1240
1241 if (currElement != null)
1242 hashCode += currElement.hashCode();
1243 }
1244
1245 return hashCode;
1246 }
1247 }
1248
1249
1250
1251
1252 private static class LenientFixedCompositeSet<E> extends LenientCompositeSet<E>
1253 {
1254 LenientFixedCompositeSet(Set<E> primarySet, Set<E> secondarySet)
1255 {
1256 if (primarySet == null)
1257 throw new NullPointerException();
1258
1259 if (secondarySet == null)
1260 throw new NullPointerException();
1261
1262 _primarySet = primarySet;
1263 _secondarySet = secondarySet;
1264 }
1265
1266 @Override
1267 protected Set<E> getPrimaryDelegate()
1268 {
1269 return _primarySet;
1270 }
1271
1272 @Override
1273 protected Set<E> getSecondaryDelegate()
1274 {
1275 return _secondarySet;
1276 }
1277
1278 private final Set<E> _primarySet;
1279 private final Set<E> _secondarySet;
1280 }
1281
1282
1283
1284
1285
1286 private static final class SerializableLenientFixedCompositeSet<E> extends
1287 LenientFixedCompositeSet<E> implements Serializable
1288 {
1289 SerializableLenientFixedCompositeSet(Set<E> primarySet, Set<E> secondarySet)
1290 {
1291 super(primarySet, secondarySet);
1292 }
1293
1294 private static final long serialVersionUID = 0L;
1295 }
1296
1297
1298 private static class SerializableCollection<E> extends DelegatingCollection<E>
1299 implements Serializable
1300 {
1301 SerializableCollection(Collection<E> delegate)
1302 {
1303
1304
1305 if (delegate == null)
1306 throw new NullPointerException();
1307
1308 _delegate = delegate;
1309 }
1310
1311 protected Collection<E> getDelegate()
1312 {
1313 return _delegate;
1314 }
1315
1316 protected Object writeReplace() throws ObjectStreamException
1317 {
1318
1319 return new ArrayList(_delegate);
1320 }
1321
1322 private static final long serialVersionUID = 0L;
1323
1324 private final transient Collection<E> _delegate;
1325 }
1326
1327
1328 private static class SerializableList<E> extends SerializableCollection<E> implements List<E>
1329 {
1330 SerializableList(List<E> delegate)
1331 {
1332 super(delegate);
1333 _delegate = delegate;
1334 }
1335
1336 public void add(int index, E element)
1337 {
1338 _delegate.add(index, element);
1339 }
1340
1341 public E remove(int index)
1342 {
1343 return _delegate.remove(index);
1344 }
1345
1346 public boolean addAll(int index, Collection<? extends E> c)
1347 {
1348 return _delegate.addAll(index, c);
1349 }
1350
1351 public E get(int index)
1352 {
1353 return _delegate.get(index);
1354 }
1355
1356 public E set(int index, E element)
1357 {
1358 return _delegate.set(index, element);
1359 }
1360
1361 public int indexOf(Object o)
1362 {
1363 return _delegate.indexOf(o);
1364 }
1365
1366 public int lastIndexOf(Object o)
1367 {
1368 return _delegate.lastIndexOf(o);
1369 }
1370
1371 public ListIterator<E> listIterator()
1372 {
1373 return _delegate.listIterator();
1374 }
1375
1376 public ListIterator<E> listIterator(int index)
1377 {
1378 return _delegate.listIterator(index);
1379 }
1380
1381 public List<E> subList(int fromIndex, int toIndex)
1382 {
1383 return CollectionUtils.getSerializableList(_delegate.subList(fromIndex, toIndex));
1384 }
1385
1386 private static final long serialVersionUID = 0L;
1387
1388 private final transient List<E> _delegate;
1389 }
1390
1391 private static class SerializableRandomAccessList<E> extends SerializableList<E> implements RandomAccess
1392 {
1393 SerializableRandomAccessList(List<E> delegate)
1394 {
1395 super(delegate);
1396 }
1397
1398 private static final long serialVersionUID = 0L;
1399 }
1400
1401 protected static abstract class DelegatingMap<K,V> implements Map<K,V>
1402 {
1403 protected abstract Map<K,V> getDelegate();
1404
1405 public int size()
1406 {
1407 return getDelegate().size();
1408 }
1409
1410 public boolean isEmpty()
1411 {
1412 return getDelegate().isEmpty();
1413 }
1414
1415 public boolean containsKey(Object key)
1416 {
1417 return getDelegate().containsKey(key);
1418 }
1419
1420 public boolean containsValue(Object value)
1421 {
1422 return getDelegate().containsValue(value);
1423 }
1424
1425 public V get(Object key)
1426 {
1427 return getDelegate().get(key);
1428 }
1429
1430
1431
1432 public V put(K key, V value)
1433 {
1434 return getDelegate().put(key, value);
1435 }
1436
1437 public V remove(Object key)
1438 {
1439 return getDelegate().remove(key);
1440 }
1441
1442
1443
1444 public void putAll(Map<? extends K, ? extends V> m)
1445 {
1446 getDelegate().putAll(m);
1447 }
1448
1449 public void clear()
1450 {
1451 getDelegate().clear();
1452 }
1453
1454
1455
1456 public Set<K> keySet()
1457 {
1458 return getDelegate().keySet();
1459 }
1460
1461 public Collection<V> values()
1462 {
1463 return getDelegate().values();
1464 }
1465
1466 public Set<Map.Entry<K, V>> entrySet()
1467 {
1468 return getDelegate().entrySet();
1469 }
1470
1471
1472
1473 public boolean equals(Object o)
1474 {
1475 return getDelegate().equals(o);
1476 }
1477
1478 public int hashCode()
1479 {
1480 return getDelegate().hashCode();
1481 }
1482 }
1483
1484 protected static abstract class DelegatingEntry<K,V> implements Map.Entry<K,V>
1485 {
1486 protected abstract Map.Entry<K,V> getDelegate();
1487
1488 public K getKey()
1489 {
1490 return getDelegate().getKey();
1491 }
1492
1493 public V getValue()
1494 {
1495 return getDelegate().getValue();
1496 }
1497
1498 public V setValue(V value)
1499 {
1500 return getDelegate().setValue(value);
1501 }
1502
1503 public boolean equals(Object o)
1504 {
1505 return getDelegate().equals(o);
1506 }
1507
1508 public int hashCode()
1509 {
1510 return getDelegate().hashCode();
1511 }
1512 }
1513
1514 protected static abstract class AccessHookMap<K,V> extends DelegatingMap<K, V>
1515 {
1516 protected abstract void writeNotify(K key, V value);
1517
1518 protected abstract void removeNotify(Object key);
1519
1520 protected abstract void clearNotify();
1521
1522 @Override
1523 public V put(K key, V value)
1524 {
1525 writeNotify(key, value);
1526
1527 return super.put(key, value);
1528 }
1529
1530 @Override
1531 public V remove(Object key)
1532 {
1533 removeNotify(key);
1534
1535 return super.remove(key);
1536 }
1537
1538 @Override
1539 public void putAll(Map<? extends K, ? extends V> m)
1540 {
1541 for (Map.Entry<? extends K, ? extends V> entry : m.entrySet())
1542 {
1543 K key = entry.getKey();
1544 V value = entry.getValue();
1545
1546 writeNotify(key, value);
1547 super.put(key, value);
1548 }
1549 }
1550
1551 @Override
1552 public void clear()
1553 {
1554 clearNotify();
1555 super.clear();
1556 }
1557
1558 public Set<Map.Entry<K, V>> entrySet()
1559 {
1560 return new MutationHookedEntrySet<K, V>(this);
1561 }
1562
1563
1564
1565 private static class MutationHookedEntrySet<K, V> extends DelegatingCollection<Entry<K,V>>
1566 implements Set<Entry<K, V>>
1567 {
1568 private MutationHookedEntrySet(AccessHookMap<K, V> accessHookMap)
1569 {
1570 if (accessHookMap == null)
1571 throw new NullPointerException();
1572
1573 _accessHookMap = accessHookMap;
1574 _delegate = accessHookMap.getDelegate().entrySet();
1575 }
1576
1577 protected Set<Entry<K, V>> getDelegate()
1578 {
1579 return _delegate;
1580 }
1581
1582 public Iterator<Entry<K,V>> iterator()
1583 {
1584 return new MutationHookedEntrySetIterator<K, V>(super.iterator(), _accessHookMap);
1585 }
1586
1587 public Object[] toArray()
1588 {
1589 Object[] delegateEntries = super.toArray();
1590
1591 int entryCount = delegateEntries.length;
1592
1593
1594
1595 Object[] entries =
1596 (delegateEntries.getClass().getComponentType().isAssignableFrom(Entry.class))
1597 ? delegateEntries
1598 : new Entry[entryCount];
1599
1600 for (int i = 0; i < entryCount; i++)
1601 entries[i] = new MutationHookedEntry((Entry<K,V>)delegateEntries[i], _accessHookMap);
1602
1603 return entries;
1604 }
1605
1606 public <T> T[] toArray(T[] a)
1607 {
1608 int inputSize = a.length;
1609
1610
1611
1612
1613 T[] outTypeArray = (inputSize == 0)
1614 ? a
1615 : CollectionUtils.copyOf(a, 0);
1616
1617 Object[] delegateEntries = super.toArray(outTypeArray);
1618
1619
1620 int entryCount = delegateEntries.length;
1621
1622 for (int i = 0; i < entryCount; i++)
1623 delegateEntries[i] = new MutationHookedEntry<K, V>((Entry<K,V>)delegateEntries[i],
1624 _accessHookMap);
1625
1626
1627 if (entryCount > inputSize)
1628 return (T[])delegateEntries;
1629
1630
1631 System.arraycopy(delegateEntries, 0, a, 0, entryCount);
1632
1633
1634 if (inputSize > entryCount)
1635 a[entryCount] = null;
1636
1637 return a;
1638 }
1639
1640
1641 private static final class MutationHookedEntrySetIterator<K, V> implements Iterator<Entry<K,V>>
1642 {
1643 private MutationHookedEntrySetIterator(Iterator<Entry<K, V>> delegate,
1644 AccessHookMap<K, V> accessHookMap)
1645 {
1646 _delegate = delegate;
1647 _accessHookMap = accessHookMap;
1648 }
1649
1650 public boolean hasNext()
1651 {
1652 return _delegate.hasNext();
1653 }
1654
1655 public Map.Entry<K,V> next()
1656 {
1657 Map.Entry<K,V> nextEntry = _delegate.next();
1658
1659
1660 _currKey = nextEntry.getKey();
1661
1662
1663 return new MutationHookedEntry<K,V>(nextEntry, _accessHookMap);
1664 }
1665
1666 public void remove()
1667 {
1668 if (_currKey == _NO_KEY)
1669 throw new IllegalStateException();
1670
1671
1672 _accessHookMap.removeNotify(_currKey);
1673
1674
1675 _delegate.remove();
1676
1677
1678 _currKey = _NO_KEY;
1679 }
1680
1681 private static final Object _NO_KEY = new Object();
1682
1683
1684
1685 private volatile Object _currKey = _NO_KEY;
1686
1687 private final Iterator<Entry<K, V>> _delegate;
1688 private final AccessHookMap<K, V> _accessHookMap;
1689 }
1690
1691
1692 private static class MutationHookedEntry<K, V> extends DelegatingEntry<K, V>
1693 {
1694 private MutationHookedEntry(Entry<K, V> delegate, AccessHookMap<K, V> accessHookMap)
1695 {
1696 if (delegate == null)
1697 throw new NullPointerException();
1698
1699 _delegate = delegate;
1700 _accessHookMap = accessHookMap;
1701 }
1702
1703 protected Entry<K, V> getDelegate()
1704 {
1705 return _delegate;
1706 }
1707
1708 public V setValue(V value)
1709 {
1710 _accessHookMap.writeNotify(getKey(), value);
1711 return super.setValue(value);
1712 }
1713
1714 private final Entry<K, V> _delegate;
1715 private final AccessHookMap<K, V> _accessHookMap;
1716 }
1717
1718 private final AccessHookMap<K, V> _accessHookMap;
1719 private final Set<Entry<K, V>> _delegate;
1720 }
1721 }
1722
1723 protected static class ExternalAccessHookMap<K,V> extends AccessHookMap<K, V>
1724 {
1725 protected ExternalAccessHookMap(Map<K, V> delegate, MapMutationHooks<K, V> mutationHooks)
1726 {
1727 if (delegate == null)
1728 throw new NullPointerException("delegate is null");
1729
1730 if (mutationHooks == null)
1731 throw new NullPointerException("accessHooks is null");
1732
1733 _delegate = delegate;
1734 _mutationHooks = mutationHooks;
1735 }
1736
1737 protected final Map<K, V> getDelegate()
1738 {
1739 return _delegate;
1740 }
1741
1742 protected final void writeNotify(K key, V value)
1743 {
1744 _mutationHooks.writeNotify(this, key, value);
1745 }
1746
1747 protected final void removeNotify(Object key)
1748 {
1749 _mutationHooks.removeNotify(this, key);
1750 }
1751
1752 protected final void clearNotify()
1753 {
1754 _mutationHooks.clearNotify(this);
1755 }
1756
1757 private static final long serialVersionUID = 1L;
1758
1759 private final Map<K, V> _delegate;
1760 private final MapMutationHooks<K, V> _mutationHooks;
1761 }
1762
1763 private static final class SerializableExternalAccessHookMap<K, V>
1764 extends ExternalAccessHookMap<K, V>
1765 implements Serializable
1766 {
1767 private SerializableExternalAccessHookMap(
1768 Map<K, V> delegate,
1769 MapMutationHooks<K, V> mutationHooks)
1770 {
1771 super(delegate, mutationHooks);
1772
1773 if (!(delegate instanceof Serializable))
1774 throw new IllegalArgumentException("Delegate must be Serializable");
1775
1776 if (!(mutationHooks instanceof Serializable))
1777 throw new IllegalArgumentException("mutation hooka must be Serializable");
1778 }
1779
1780 private static final long serialVersionUID = 1L;
1781 }
1782
1783
1784
1785 private final static class CheckedSerializationMap<K, V> extends AccessHookMap<K,V>
1786 implements Serializable
1787 {
1788
1789
1790
1791
1792
1793 public CheckedSerializationMap(
1794 Map<K, V> delegate,
1795 boolean requireSerializable)
1796 {
1797 if (delegate == null)
1798 throw new NullPointerException();
1799
1800 _delegate = delegate;
1801 _requireSerializable = requireSerializable;
1802 }
1803
1804 protected Map<K, V> getDelegate()
1805 {
1806 return _delegate;
1807 }
1808
1809 protected void writeNotify(K key, V value)
1810 {
1811
1812 if (!(key instanceof String))
1813 {
1814 if (key instanceof Serializable)
1815 {
1816
1817 try
1818 {
1819 new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(key);
1820 }
1821 catch (IOException e)
1822 {
1823 throw new IllegalArgumentException(_LOG.getMessage("FAILED_SERIALIZATION_PROPERTY_KEY",
1824 new Object[]{key, this}),
1825 e);
1826 }
1827 }
1828 else
1829 {
1830 if (_requireSerializable)
1831 {
1832 throw new ClassCastException(_LOG.getMessage("UNSERIALIZABLE_PROPERTY_KEY",
1833 new Object[]{key, this}));
1834 }
1835 }
1836 }
1837
1838 if (value instanceof Serializable)
1839 {
1840
1841 try
1842 {
1843 new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(value);
1844 }
1845 catch (IOException e)
1846 {
1847 throw new IllegalArgumentException(_LOG.getMessage("FAILED_SERIALIZATION_PROPERTY_VALUE",
1848 new Object[]{value, key, this}),
1849 e);
1850 }
1851 }
1852 else if (value != null)
1853 {
1854 if (_requireSerializable)
1855 {
1856 throw new ClassCastException(_LOG.getMessage("UNSERIALIZABLE_PROPERTY_VALUE",
1857 new Object[]{value, key, this}));
1858 }
1859 }
1860 }
1861
1862 protected void removeNotify(Object key)
1863 {
1864
1865 }
1866
1867 protected void clearNotify()
1868 {
1869
1870 }
1871
1872 @Override
1873 public void putAll(Map<? extends K, ? extends V> m)
1874 {
1875
1876 Object[] keys = m.keySet().toArray();
1877 Object[] values = m.values().toArray();
1878
1879 int keyCount = keys.length;
1880
1881
1882 if (keyCount != values.length)
1883 throw new ConcurrentModificationException();
1884
1885
1886 for (int k = 0; k < keyCount; k++)
1887 {
1888 writeNotify((K)keys[k], (V)values[k]);
1889 }
1890
1891
1892
1893 Map<K, V> delegate = getDelegate();
1894
1895 for (int k = 0; k < keyCount; k++)
1896 {
1897 delegate.put((K)keys[k], (V)values[k]);
1898 }
1899 }
1900
1901 private static final long serialVersionUID = 1L;
1902
1903 private final Map<K, V> _delegate;
1904 private final boolean _requireSerializable;
1905 }
1906
1907 private static class EmptyIterator implements Iterator
1908 {
1909 public boolean hasNext()
1910 {
1911 return false;
1912 }
1913
1914 public Object next()
1915 {
1916 throw new NoSuchElementException();
1917 }
1918
1919 public void remove()
1920 {
1921 throw new UnsupportedOperationException();
1922 }
1923 }
1924
1925 private static final class EmptyListIterator extends EmptyIterator implements ListIterator
1926 {
1927 public boolean hasPrevious()
1928 {
1929 return false;
1930 }
1931
1932 public Object previous()
1933 {
1934 throw new NoSuchElementException();
1935 }
1936
1937 public int nextIndex()
1938 {
1939 return 0;
1940 }
1941
1942 public int previousIndex()
1943 {
1944 return -1;
1945 }
1946
1947 public void set(Object e)
1948 {
1949 throw new UnsupportedOperationException();
1950 }
1951
1952 public void add(Object e)
1953 {
1954 throw new UnsupportedOperationException();
1955 }
1956 }
1957
1958 private static final class EmptyQueue extends AbstractQueue implements Serializable
1959 {
1960 public Iterator iterator()
1961 {
1962 return _EMPTY_ITERATOR;
1963 }
1964
1965 public int size()
1966 {
1967 return 0;
1968 }
1969
1970 @Override
1971 public boolean isEmpty()
1972 {
1973 return true;
1974 }
1975
1976 @Override
1977 public boolean contains(Object o)
1978 {
1979 return false;
1980 }
1981
1982 public boolean offer(Object e)
1983 {
1984 throw new UnsupportedOperationException();
1985 }
1986
1987 public Object poll()
1988 {
1989 return null;
1990 }
1991
1992 public Object peek()
1993 {
1994 return null;
1995 }
1996
1997 private Object readResolve()
1998 {
1999 return _EMPTY_QUEUE;
2000 }
2001
2002 private static final long serialVersionUID = 0L;
2003 }
2004
2005
2006
2007
2008
2009 private static final Class<? extends List> _CHECKED_LIST;
2010 private static final Class<? extends List> _UNMODIFIABLE_LIST;
2011 private static final Class<? extends List> _SYNCHRONIZED_LIST;
2012 private static final Class<? extends Set> _EMPTY_SET = Collections.emptySet().getClass();
2013 private static final Class<? extends Set> _SINGLETON_SET = Collections.singleton(null).getClass();
2014 private static final Queue _EMPTY_QUEUE = new EmptyQueue();
2015 private static final Iterator _EMPTY_ITERATOR = new EmptyIterator();
2016 private static final Iterator _EMPTY_LIST_ITERATOR = new EmptyListIterator();
2017
2018
2019 static
2020 {
2021
2022
2023 LinkedList<Object> dummyList = new LinkedList<Object>();
2024
2025 _CHECKED_LIST = Collections.checkedList(dummyList, Object.class).getClass();
2026 _UNMODIFIABLE_LIST = Collections.unmodifiableList(dummyList).getClass();
2027 _SYNCHRONIZED_LIST = Collections.synchronizedList(dummyList).getClass();
2028 }
2029
2030 private static final TrinidadLogger _LOG =
2031 TrinidadLogger.createTrinidadLogger(CollectionUtils.class);
2032
2033 }