aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2015-01-19 12:46:40 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-01-19 12:46:40 +0000
commitaab56800fcb95e9b1a2d653588b14158080cc6b4 (patch)
tree7365392c3ea77742021cf187acfd465f9bb774ab
parent6fa98dbaae182b511fbeb331e08f5fb827715ea8 (diff)
parent84fb43aa6a1e752487f2624055ff26b1b6b7c043 (diff)
downloadandroid_external_guava-aab56800fcb95e9b1a2d653588b14158080cc6b4.tar.gz
android_external_guava-aab56800fcb95e9b1a2d653588b14158080cc6b4.tar.bz2
android_external_guava-aab56800fcb95e9b1a2d653588b14158080cc6b4.zip
am 84fb43aa: Merge "Revert "Upgraded Guava to unmodified v14.0.1""
* commit '84fb43aa6a1e752487f2624055ff26b1b6b7c043': Revert "Upgraded Guava to unmodified v14.0.1"
-rw-r--r--AUTHORS1
-rw-r--r--README2
-rw-r--r--guava-gwt/pom.xml109
-rw-r--r--guava-gwt/src-super/com/google/common/base/super/com/google/common/base/CharMatcher.java1244
-rw-r--r--guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Charsets.java52
-rw-r--r--guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Enums.java108
-rw-r--r--guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Predicates.java22
-rw-r--r--guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Splitter.java136
-rw-r--r--guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Stopwatch.java40
-rw-r--r--guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheBuilder.java741
-rw-r--r--guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheLoader.java50
-rw-r--r--guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LocalCache.java829
-rw-r--r--guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAddables.java28
-rw-r--r--guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAdder.java40
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractBiMap.java76
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultimap.java1259
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultiset.java117
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractSortedMultiset.java142
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayListMultimap.java6
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayTable.java817
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ContiguousSet.java142
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/DescendingMultiset.java140
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyContiguousSet.java5
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableList.java15
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableMap.java (renamed from guava-gwt/src/com/google/common/collect/ForwardingImmutableSet_CustomFieldSerializer.java)9
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSet.java7
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedMap.java42
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedSet.java2
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumBiMap.java15
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumHashBiMap.java13
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumMultiset.java17
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/FluentIterable.java508
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableList.java94
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableMap.java125
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableSet.java76
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/GenericMapMaker.java17
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashBiMap.java9
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashMultimap.java2
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList.java38
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java (renamed from guava-gwt/src/com/google/common/collect/RegularImmutableAsList_CustomFieldSerializer.java)28
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableBiMap.java23
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableCollection.java15
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumMap.java41
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumSet.java13
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableList.java102
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableListMultimap.java26
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMap.java200
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapEntrySet.java57
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapKeySet.java77
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapValues.java73
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMultimap.java280
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSet.java20
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSetMultimap.java85
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedAsList.java53
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedMap.java102
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedSet.java22
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterables.java146
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterators.java182
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultimap.java539
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultiset.java4
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedListMultimap.java452
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Lists.java1122
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/MapMaker.java28
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Maps.java919
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Multimaps.java834
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ObjectArrays.java15
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Platform.java42
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularContiguousSet.java52
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableList.java13
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableMap.java4
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSet.java2
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedMap.java31
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedSet.java4
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Sets.java420
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableList.java12
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableMap.java (renamed from guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableBiMap.java)31
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableSet.java23
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultiset.java57
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultisets.java93
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Synchronized.java67
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultimap.java42
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultiset.java1066
-rw-r--r--guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/UnmodifiableSortedMultiset.java112
-rw-r--r--guava-gwt/src-super/com/google/common/escape/super/com/google/common/escape/Platform.java (renamed from guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableBiMap.java)25
-rw-r--r--guava-gwt/src-super/com/google/common/io/super/com/google/common/io/BaseEncoding.java794
-rw-r--r--guava-gwt/src-super/com/google/common/io/super/com/google/common/io/GwtWorkarounds.java118
-rw-r--r--guava-gwt/src-super/com/google/common/math/super/com/google/common/math/BigIntegerMath.java268
-rw-r--r--guava-gwt/src-super/com/google/common/math/super/com/google/common/math/IntMath.java292
-rw-r--r--guava-gwt/src-super/com/google/common/math/super/com/google/common/math/LongMath.java300
-rw-r--r--guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Chars.java9
-rw-r--r--guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Ints.java20
-rw-r--r--guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Longs.java (renamed from guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Doubles.java)256
-rw-r--r--guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Shorts.java20
-rw-r--r--guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/UnsignedInteger.java312
-rw-r--r--guava-gwt/src-super/com/google/common/testing/super/com/google/common/testing/Platform.java (renamed from guava-testlib/blackhole-gwt/src-super/com/google/common/testing/super/com/google/common/testing/Platform.java)0
-rw-r--r--guava-gwt/src-super/java/nio/charset/Charset.gwt.xml4
-rw-r--r--guava-gwt/src-super/java/nio/charset/Charset.java101
-rw-r--r--guava-gwt/src-super/java/nio/charset/IllegalCharsetNameException.java35
-rw-r--r--guava-gwt/src-super/java/nio/charset/UnsupportedCharsetException.java35
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/Callable.java2
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentHashMap.java2
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentMap.java2
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/ExecutionException.java4
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/TimeUnit.java4
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicInteger.java2
-rw-r--r--guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicLong.java2
-rw-r--r--guava-gwt/src/com/google/common/ForceGuavaCompilation.gwt.xml15
-rw-r--r--guava-gwt/src/com/google/common/ForceGuavaCompilationEntryPoint.java29
-rw-r--r--guava-gwt/src/com/google/common/annotations/Annotations.gwt.xml3
-rw-r--r--guava-gwt/src/com/google/common/base/Absent_CustomFieldSerializer.java41
-rw-r--r--guava-gwt/src/com/google/common/base/Base.gwt.xml10
-rw-r--r--guava-gwt/src/com/google/common/base/GwtSerializationDependencies.java57
-rw-r--r--guava-gwt/src/com/google/common/base/PairwiseEquivalence_CustomFieldSerializer.java2
-rw-r--r--guava-gwt/src/com/google/common/base/Present_CustomFieldSerializer.java42
-rw-r--r--guava-gwt/src/com/google/common/cache/Cache.gwt.xml5
-rw-r--r--guava-gwt/src/com/google/common/collect/AllEqualOrdering_CustomFieldSerializer.java37
-rw-r--r--guava-gwt/src/com/google/common/collect/Collect.gwt.xml7
-rw-r--r--guava-gwt/src/com/google/common/collect/EmptyImmutableMap_CustomFieldSerializer.java (renamed from guava-gwt/src/com/google/common/collect/EmptyImmutableBiMap_CustomFieldSerializer.java)18
-rw-r--r--guava-gwt/src/com/google/common/collect/EmptyImmutableSortedMap_CustomFieldSerializer.java44
-rw-r--r--guava-gwt/src/com/google/common/collect/GwtPlatform.java57
-rw-r--r--guava-gwt/src/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java38
-rw-r--r--guava-gwt/src/com/google/common/collect/ImmutableBiMap_CustomFieldSerializer.java26
-rw-r--r--guava-gwt/src/com/google/common/collect/ImmutableEntry_CustomFieldSerializer.java2
-rw-r--r--guava-gwt/src/com/google/common/collect/ImmutableEnumMap_CustomFieldSerializer.java54
-rw-r--r--guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializer.java41
-rw-r--r--guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializerBase.java58
-rw-r--r--guava-gwt/src/com/google/common/collect/LexicographicalOrdering_CustomFieldSerializer.java3
-rw-r--r--guava-gwt/src/com/google/common/collect/LinkedHashMultimap_CustomFieldSerializer.java45
-rw-r--r--guava-gwt/src/com/google/common/collect/Multiset_CustomFieldSerializerBase.java15
-rw-r--r--guava-gwt/src/com/google/common/collect/RegularImmutableSortedMap_CustomFieldSerializer.java44
-rw-r--r--guava-gwt/src/com/google/common/collect/SingletonImmutableMap_CustomFieldSerializer.java (renamed from guava-gwt/src/com/google/common/collect/SingletonImmutableBiMap_CustomFieldSerializer.java)12
-rw-r--r--guava-gwt/src/com/google/common/io/Io.gwt.xml17
-rw-r--r--guava-gwt/src/com/google/common/math/Math.gwt.xml7
-rw-r--r--guava-gwt/src/com/google/common/net/Net.gwt.xml13
-rw-r--r--guava-gwt/src/com/google/common/primitives/Primitives.gwt.xml15
-rw-r--r--guava-gwt/src/com/google/common/primitives/UnsignedLong_CustomFieldSerializer.java39
-rw-r--r--guava-gwt/src/com/google/common/util/concurrent/Concurrent.gwt.xml9
-rw-r--r--guava-gwt/test/com/google/common/cache/TestModuleEntryPoint.java30
-rw-r--r--guava-gwt/test/com/google/common/cache/testModule.gwt.xml20
-rw-r--r--guava-gwt/test/com/google/common/collect/testModule.gwt.xml3
-rw-r--r--guava-gwt/test/com/google/common/io/TestModuleEntryPoint.java30
-rw-r--r--guava-gwt/test/com/google/common/io/testModule.gwt.xml18
-rw-r--r--guava-gwt/test/com/google/common/math/testModule.gwt.xml2
-rw-r--r--guava-gwt/test/com/google/common/net/TestPlatform.java (renamed from guava-tests/test/com/google/common/net/TestPlatform.java)0
-rw-r--r--guava-gwt/test/com/google/common/net/testModule.gwt.xml1
-rw-r--r--guava-gwt/test/com/google/common/primitives/testModule.gwt.xml2
-rw-r--r--guava-gwt/test/com/google/common/testing/TestModuleEntryPoint.java (renamed from guava-testlib/blackhole-gwt/test/com/google/common/testing/TestModuleEntryPoint.java)0
-rw-r--r--guava-gwt/test/com/google/common/testing/Testing.gwt.xml (renamed from guava-testlib/blackhole-gwt/src/com/google/common/testing/Testing.gwt.xml)11
-rw-r--r--guava-gwt/test/com/google/common/testing/testModule.gwt.xml (renamed from guava-testlib/blackhole-gwt/test/com/google/common/testing/testModule.gwt.xml)1
-rw-r--r--guava-gwt/test/com/google/common/util/concurrent/TestModuleEntryPoint.java30
-rw-r--r--guava-gwt/test/com/google/common/util/concurrent/testModule.gwt.xml17
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java387
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapInverseTester.java66
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapRemoveTester.java94
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetIteratorTester.java90
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetReadsTester.java141
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetWritesTester.java253
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/SetGenerators.java349
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/GwtPlatform.java38
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Helpers.java404
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Platform.java80
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddAllTester.java165
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddTester.java110
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionCreationTester.java58
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionIteratorTester.java126
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionToArrayTester.java187
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddAtIndexTester.java153
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddTester.java75
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListHashCodeTester.java41
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListListIteratorTester.java109
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSetTester.java136
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSubListTester.java324
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapCreationTester.java144
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutAllTester.java199
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutTester.java241
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/Platform.java74
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetAddTester.java54
-rw-r--r--guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetHashCodeTester.java63
-rw-r--r--guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/GwtPlatform.java40
-rw-r--r--guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/Testing.gwt.xml17
-rw-r--r--guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/google/Google.gwt.xml23
-rw-r--r--guava-testlib/pom.xml37
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTestSuiteBuilder.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTester.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java13
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java16
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AbstractTester.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/AnEnum.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/BaseComparable.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java69
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/ConcurrentMapInterfaceTest.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java401
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/DerivedComparable.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/DerivedGenerator.java35
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/DerivedTestIteratorGenerator.java8
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/ExampleIteratorTester.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java42
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/Helpers.java140
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/IteratorTester.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/ListIteratorTester.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java70
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java178
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/MinimalSet.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java180
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java6
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/OneSizeTestContainerGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/PerCollectionSizeTestSuiteBuilder.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/Platform.java28
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/SampleElements.java26
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java70
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java131
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java55
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestCharacterListGenerator.java66
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestCollectionGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestCollidingSetGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestContainerGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestEnumMapGenerator.java11
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestEnumSetGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestIntegerSetGenerator.java68
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestIntegerSortedSetGenerator.java44
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestIteratorGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestListGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestMapEntrySetGenerator.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestMapGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestQueueGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestSetGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestSortedMapGenerator.java59
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringCollectionGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringListGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringMapGenerator.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringQueueGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringSetGenerator.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringSortedMapGenerator.java69
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestStringSortedSetGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestSubjectGenerator.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestUnhashableCollectionGenerator.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestsForListsInJavaUtil.java13
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestsForMapsInJavaUtil.java126
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/TestsForSetsInJavaUtil.java82
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/UnhashableObject.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/WrongType.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/CollectionFeature.java24
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/ConflictingRequirementsException.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/Feature.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/ListFeature.java10
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/MapFeature.java17
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/SetFeature.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/TesterAnnotation.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/features/TesterRequirements.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/AbstractBiMapTester.java77
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/AbstractListMultimapTester.java54
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java166
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java65
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/BiMapClearTester.java79
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/BiMapGenerators.java88
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/BiMapInverseTester.java84
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/BiMapPutTester.java99
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/BiMapRemoveTester.java107
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java173
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java211
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/ListGenerators.java27
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutAllTester.java53
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutTester.java77
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/ListMultimapRemoveTester.java116
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/ListMultimapReplaceValuesTester.java48
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/ListMultimapTestSuiteBuilder.java100
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java159
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsEntryTester.java76
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsKeyTester.java90
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsValueTester.java66
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapGetTester.java122
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapPutIterableTester.java76
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapPutTester.java194
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveAllTester.java94
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveEntryTester.java187
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapReplaceValuesTester.java93
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapSizeTester.java91
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java600
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultisetIteratorTester.java31
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultisetReadsTester.java7
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultisetSerializationTester.java47
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java230
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/MultisetWritesTester.java54
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/Platform.java40
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SetGenerators.java136
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutAllTester.java55
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutTester.java59
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SetMultimapReplaceValuesTester.java49
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SetMultimapTestSuiteBuilder.java111
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SortedMapGenerators.java183
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java72
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapGetTester.java35
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapTestSuiteBuilder.java84
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestBiMapGenerator.java36
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestListMultimapGenerator.java31
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestMultimapGenerator.java45
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestSetMultimapGenerator.java31
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestStringBiMapGenerator.java92
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestStringListMultimapGenerator.java101
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/google/TestStringSetMultimapGenerator.java100
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/AbstractListIndexOfTester.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/AbstractListTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/AbstractQueueTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/AbstractSetTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddAllTester.java46
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddTester.java39
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionClearTester.java33
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsAllTester.java3
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionCreationTester.java7
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionEqualsTester.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionIsEmptyTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java12
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveAllTester.java50
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveTester.java19
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionRetainAllTester.java54
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationEqualTester.java40
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationTester.java41
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionSizeTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java6
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/CollectionToStringTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllAtIndexTester.java27
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllTester.java10
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListAddAtIndexTester.java23
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListAddTester.java6
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListCreationTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListEqualsTester.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListGetTester.java5
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListHashCodeTester.java10
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListIndexOfTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListLastIndexOfTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListListIteratorTester.java11
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAllTester.java6
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAtIndexTester.java20
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListRetainAllTester.java8
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListSetTester.java7
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListSubListTester.java40
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/ListToArrayTester.java8
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapClearTester.java58
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapContainsKeyTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapContainsValueTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapCreationTester.java21
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapEqualsTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapGetTester.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapHashCodeTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapIsEmptyTester.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapNavigationTester.java (renamed from guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java)31
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapPutAllTester.java64
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapPutTester.java60
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapRemoveTester.java50
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapSerializationTester.java37
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/MapSizeTester.java4
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/Platform.java15
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/QueueElementTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/QueueOfferTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/QueuePeekTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/QueuePollTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/QueueRemoveTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetAddAllTester.java10
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetAddTester.java7
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetCreationTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetEqualsTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetHashCodeTester.java9
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetNavigationTester.java (renamed from guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java)113
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SetRemoveTester.java2
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SortedMapNavigationTester.java101
-rw-r--r--guava-testlib/src/com/google/common/collect/testing/testers/SortedSetNavigationTester.java102
-rw-r--r--guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java380
-rw-r--r--guava-testlib/src/com/google/common/testing/ArbitraryInstances.java440
-rw-r--r--guava-testlib/src/com/google/common/testing/ClassSanityTester.java765
-rw-r--r--guava-testlib/src/com/google/common/testing/DummyProxy.java110
-rw-r--r--guava-testlib/src/com/google/common/testing/EqualsTester.java13
-rw-r--r--guava-testlib/src/com/google/common/testing/EquivalenceTester.java2
-rw-r--r--guava-testlib/src/com/google/common/testing/FakeTicker.java20
-rw-r--r--guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java214
-rw-r--r--guava-testlib/src/com/google/common/testing/FreshValueGenerator.java789
-rw-r--r--guava-testlib/src/com/google/common/testing/GcFinalization.java59
-rw-r--r--guava-testlib/src/com/google/common/testing/NullPointerTester.java422
-rw-r--r--guava-testlib/src/com/google/common/testing/RelationshipTester.java62
-rw-r--r--guava-testlib/src/com/google/common/testing/TearDown.java2
-rw-r--r--guava-testlib/src/com/google/common/testing/TearDownStack.java4
-rw-r--r--guava-testlib/src/com/google/common/testing/TestLogHandler.java8
-rw-r--r--guava-testlib/src/com/google/common/testing/package-info.java23
-rw-r--r--guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java117
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java83
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/HelpersTest.java33
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/IteratorTesterTest.java349
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java117
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/MinimalCollectionTest.java52
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/MinimalIterableTest.java106
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/MinimalSetTest.java47
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/OpenJdk6ListTests.java70
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/OpenJdk6MapTests.java57
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/OpenJdk6QueueTests.java50
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/OpenJdk6SetTests.java61
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/OpenJdk6Tests.java39
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/SafeTreeMapTest.java126
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/SafeTreeSetTest.java106
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/features/FeatureEnumTest.java108
-rw-r--r--guava-testlib/test/com/google/common/collect/testing/features/FeatureUtilTest.java284
-rw-r--r--guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java119
-rw-r--r--guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java381
-rw-r--r--guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java1164
-rw-r--r--guava-testlib/test/com/google/common/testing/FakeTickerTest.java167
-rw-r--r--guava-testlib/test/com/google/common/testing/FreshValueGeneratorTest.java742
-rw-r--r--guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java1221
-rw-r--r--guava-testlib/test/com/google/common/testing/PackageSanityTests.java23
-rw-r--r--guava-testlib/test/com/google/common/testing/RelationshipTesterTest.java40
-rw-r--r--guava-testlib/test/com/google/common/testing/anotherpackage/ForwardingWrapperTesterTest.java453
-rw-r--r--guava-testlib/test/com/google/common/testing/anotherpackage/SomeClassThatDoesNotUseNullable.java30
-rw-r--r--guava-testlib/test/com/google/common/util/concurrent/testing/TestingExecutorsTest.java85
-rw-r--r--guava-tests/benchmark/com/google/common/base/AsciiBenchmark.java114
-rw-r--r--guava-tests/benchmark/com/google/common/base/CharMatcherBenchmark.java2646
-rw-r--r--guava-tests/benchmark/com/google/common/base/JoinerBenchmark.java179
-rw-r--r--guava-tests/benchmark/com/google/common/base/ObjectsBenchmark.java85
-rw-r--r--guava-tests/benchmark/com/google/common/base/SplitterBenchmark.java63
-rw-r--r--guava-tests/benchmark/com/google/common/base/StopwatchBenchmark.java56
-rw-r--r--guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java116
-rw-r--r--guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java61
-rw-r--r--guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java66
-rw-r--r--guava-tests/benchmark/com/google/common/cache/LoadingCacheSingleThreadBenchmark.java111
-rw-r--r--guava-tests/benchmark/com/google/common/cache/MapMakerComparisonBenchmark.java96
-rw-r--r--guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java69
-rw-r--r--guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java528
-rw-r--r--guava-tests/benchmark/com/google/common/collect/HashMultisetAddPresentBenchmark.java61
-rw-r--r--guava-tests/benchmark/com/google/common/collect/ImmutableListCreationBenchmark.java92
-rw-r--r--guava-tests/benchmark/com/google/common/collect/ImmutableMapCreationBenchmark.java93
-rw-r--r--guava-tests/benchmark/com/google/common/collect/InternersBenchmark.java55
-rw-r--r--guava-tests/benchmark/com/google/common/collect/IteratorBenchmark.java145
-rw-r--r--guava-tests/benchmark/com/google/common/collect/MapBenchmark.java220
-rw-r--r--guava-tests/benchmark/com/google/common/collect/MapMakerSingleThreadBenchmark.java114
-rw-r--r--guava-tests/benchmark/com/google/common/collect/MinMaxPriorityQueueBenchmark.java154
-rw-r--r--guava-tests/benchmark/com/google/common/collect/MultisetIteratorBenchmark.java97
-rw-r--r--guava-tests/benchmark/com/google/common/collect/PowerSetBenchmark.java57
-rw-r--r--guava-tests/benchmark/com/google/common/collect/SetContainsBenchmark.java84
-rw-r--r--guava-tests/benchmark/com/google/common/collect/SetCreationBenchmark.java61
-rw-r--r--guava-tests/benchmark/com/google/common/collect/SetIterationBenchmark.java68
-rw-r--r--guava-tests/benchmark/com/google/common/hash/ChecksumBenchmark.java99
-rw-r--r--guava-tests/benchmark/com/google/common/hash/HashBenchmark.java92
-rw-r--r--guava-tests/benchmark/com/google/common/hash/HashFunctionBenchmark.java87
-rw-r--r--guava-tests/benchmark/com/google/common/hash/MessageDigestAlgorithmBenchmark.java111
-rw-r--r--guava-tests/benchmark/com/google/common/hash/MessageDigestCreationBenchmark.java60
-rw-r--r--guava-tests/benchmark/com/google/common/math/ApacheBenchmark.java249
-rw-r--r--guava-tests/benchmark/com/google/common/math/BigIntegerMathBenchmark.java119
-rw-r--r--guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java93
-rw-r--r--guava-tests/benchmark/com/google/common/math/DoubleMathBenchmark.java90
-rw-r--r--guava-tests/benchmark/com/google/common/math/DoubleMathRoundingBenchmark.java92
-rw-r--r--guava-tests/benchmark/com/google/common/math/IntMathBenchmark.java103
-rw-r--r--guava-tests/benchmark/com/google/common/math/IntMathRoundingBenchmark.java93
-rw-r--r--guava-tests/benchmark/com/google/common/math/LongMathBenchmark.java106
-rw-r--r--guava-tests/benchmark/com/google/common/math/LongMathRoundingBenchmark.java93
-rw-r--r--guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java106
-rw-r--r--guava-tests/benchmark/com/google/common/primitives/UnsignedLongsBenchmark.java138
-rw-r--r--guava-tests/benchmark/com/google/common/util/concurrent/CycleDetectingLockFactoryBenchmark.java92
-rw-r--r--guava-tests/benchmark/com/google/common/util/concurrent/MonitorBenchmark.java73
-rw-r--r--guava-tests/lib/libtruth-gwt.jarbin0 -> 18751 bytes
-rw-r--r--guava-tests/lib/libtruth.jarbin0 -> 26052 bytes
-rw-r--r--guava-tests/pom.xml71
-rw-r--r--guava-tests/test/com/google/common/base/BenchmarkHelpers.java84
-rw-r--r--guava-tests/test/com/google/common/base/CaseFormatTest.java20
-rw-r--r--guava-tests/test/com/google/common/base/CharMatcherTest.java222
-rw-r--r--guava-tests/test/com/google/common/base/CharsetsTest.java10
-rw-r--r--guava-tests/test/com/google/common/base/EnumsTest.java51
-rw-r--r--guava-tests/test/com/google/common/base/EquivalenceTest.java70
-rw-r--r--guava-tests/test/com/google/common/base/EquivalencesTest.java63
-rw-r--r--guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java245
-rw-r--r--guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java33
-rw-r--r--guava-tests/test/com/google/common/base/FunctionsTest.java25
-rw-r--r--guava-tests/test/com/google/common/base/JoinerTest.java31
-rw-r--r--guava-tests/test/com/google/common/base/ObjectsTest.java2
-rw-r--r--guava-tests/test/com/google/common/base/OptionalTest.java116
-rw-r--r--guava-tests/test/com/google/common/base/PackageSanityTests.java30
-rw-r--r--guava-tests/test/com/google/common/base/PreconditionsTest.java2
-rw-r--r--guava-tests/test/com/google/common/base/PredicatesTest.java25
-rw-r--r--guava-tests/test/com/google/common/base/SplitterTest.java235
-rw-r--r--guava-tests/test/com/google/common/base/StopwatchTest.java65
-rw-r--r--guava-tests/test/com/google/common/base/StringsTest.java2
-rw-r--r--guava-tests/test/com/google/common/base/SuppliersTest.java37
-rw-r--r--guava-tests/test/com/google/common/base/ThrowablesTest.java12
-rw-r--r--guava-tests/test/com/google/common/base/ToStringHelperTest.java107
-rw-r--r--guava-tests/test/com/google/common/cache/AbstractCacheTest.java14
-rw-r--r--guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java503
-rw-r--r--guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java539
-rw-r--r--guava-tests/test/com/google/common/cache/CacheBuilderTest.java18
-rw-r--r--guava-tests/test/com/google/common/cache/CacheEvictionTest.java36
-rw-r--r--guava-tests/test/com/google/common/cache/CacheExpirationTest.java54
-rw-r--r--guava-tests/test/com/google/common/cache/CacheLoadingTest.java124
-rw-r--r--guava-tests/test/com/google/common/cache/CacheManualTest.java4
-rw-r--r--guava-tests/test/com/google/common/cache/CacheReferencesTest.java6
-rw-r--r--guava-tests/test/com/google/common/cache/CacheTesting.java11
-rw-r--r--guava-tests/test/com/google/common/cache/EmptyCachesTest.java4
-rw-r--r--guava-tests/test/com/google/common/cache/LocalCacheTest.java112
-rw-r--r--guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java63
-rw-r--r--guava-tests/test/com/google/common/cache/PackageSanityTests.java36
-rw-r--r--guava-tests/test/com/google/common/cache/PopulatedCachesTest.java35
-rw-r--r--guava-tests/test/com/google/common/cache/RemovalNotificationTest.java41
-rw-r--r--guava-tests/test/com/google/common/cache/TestingCacheLoaders.java9
-rw-r--r--guava-tests/test/com/google/common/cache/TestingRemovalListeners.java6
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractBiMapTest.java550
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java115
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractCollectionTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java27
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java29
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractLinkedIteratorTest.java (renamed from guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java)22
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java68
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractMultimapTest.java98
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractMultisetTest.java9
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java71
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractTableReadTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java52
-rw-r--r--guava-tests/test/com/google/common/collect/ArrayTableTest.java29
-rw-r--r--guava-tests/test/com/google/common/collect/BenchmarkHelpers.java297
-rw-r--r--guava-tests/test/com/google/common/collect/BiMapCollectionTest.java74
-rw-r--r--guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java126
-rw-r--r--guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java63
-rw-r--r--guava-tests/test/com/google/common/collect/BstInOrderPathTest.java199
-rw-r--r--guava-tests/test/com/google/common/collect/BstMutationResultTest.java33
-rw-r--r--guava-tests/test/com/google/common/collect/BstNodeTest.java125
-rw-r--r--guava-tests/test/com/google/common/collect/BstOperationsTest.java544
-rw-r--r--guava-tests/test/com/google/common/collect/BstPathTest.java55
-rw-r--r--guava-tests/test/com/google/common/collect/BstRangeOpsTest.java397
-rw-r--r--guava-tests/test/com/google/common/collect/BstTesting.java188
-rw-r--r--guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java155
-rw-r--r--guava-tests/test/com/google/common/collect/Collections2Test.java413
-rw-r--r--guava-tests/test/com/google/common/collect/ComparisonChainTest.java24
-rw-r--r--guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java45
-rw-r--r--guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java111
-rw-r--r--guava-tests/test/com/google/common/collect/ConstraintsTest.java65
-rw-r--r--guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java110
-rw-r--r--guava-tests/test/com/google/common/collect/ContiguousSetTest.java303
-rw-r--r--guava-tests/test/com/google/common/collect/CountTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/DiscreteDomainsTest.java (renamed from guava-tests/test/com/google/common/collect/DiscreteDomainTest.java)9
-rw-r--r--guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java33
-rw-r--r--guava-tests/test/com/google/common/collect/EnumBiMapTest.java166
-rw-r--r--guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java115
-rw-r--r--guava-tests/test/com/google/common/collect/EnumMultisetTest.java70
-rw-r--r--guava-tests/test/com/google/common/collect/FauxveridesTest.java12
-rw-r--r--guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java446
-rw-r--r--guava-tests/test/com/google/common/collect/FluentIterableTest.java728
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java120
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingDequeTest.java225
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingListTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingMapTest.java40
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java4
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java380
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java255
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingQueueTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingSetTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java46
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingTestCase.java2
-rw-r--r--guava-tests/test/com/google/common/collect/GeneralRangeTest.java38
-rw-r--r--guava-tests/test/com/google/common/collect/HashBasedTableTest.java22
-rw-r--r--guava-tests/test/com/google/common/collect/HashBiMapTest.java86
-rw-r--r--guava-tests/test/com/google/common/collect/HashMultimapTest.java44
-rw-r--r--guava-tests/test/com/google/common/collect/HashMultisetTest.java48
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java102
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java40
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java80
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java82
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableListTest.java76
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableMapTest.java133
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java13
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java82
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java228
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java508
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java253
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java99
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSetTest.java103
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java166
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java179
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java258
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableTableTest.java61
-rw-r--r--guava-tests/test/com/google/common/collect/InternersTest.java18
-rw-r--r--guava-tests/test/com/google/common/collect/InverseBiMapTest.java (renamed from guava/src/com/google/common/collect/ForwardingImmutableMap.java)15
-rw-r--r--guava-tests/test/com/google/common/collect/IterablesTest.java83
-rw-r--r--guava-tests/test/com/google/common/collect/IteratorsTest.java96
-rw-r--r--guava-tests/test/com/google/common/collect/LenientSerializableTester.java9
-rw-r--r--guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java107
-rw-r--r--guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java57
-rw-r--r--guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java56
-rw-r--r--guava-tests/test/com/google/common/collect/ListsTest.java174
-rw-r--r--guava-tests/test/com/google/common/collect/MapConstraintsTest.java16
-rw-r--r--guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java43
-rw-r--r--guava-tests/test/com/google/common/collect/MapsCollectionTest.java639
-rw-r--r--guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/MapsTest.java1378
-rw-r--r--guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java10
-rw-r--r--guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java51
-rw-r--r--guava-tests/test/com/google/common/collect/MultimapCollectionTest.java978
-rw-r--r--guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java661
-rw-r--r--guava-tests/test/com/google/common/collect/MultimapsTest.java151
-rw-r--r--guava-tests/test/com/google/common/collect/MultisetCollectionTest.java (renamed from guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java)234
-rw-r--r--guava-tests/test/com/google/common/collect/MultisetsTest.java208
-rw-r--r--guava-tests/test/com/google/common/collect/NewCustomTableTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/ObjectArraysTest.java80
-rw-r--r--guava-tests/test/com/google/common/collect/OrderingTest.java291
-rw-r--r--guava-tests/test/com/google/common/collect/PackageSanityTests.java32
-rw-r--r--guava-tests/test/com/google/common/collect/QueuesTest.java11
-rw-r--r--guava-tests/test/com/google/common/collect/RangeNonGwtTest.java10
-rw-r--r--guava-tests/test/com/google/common/collect/RangeTest.java372
-rw-r--r--guava-tests/test/com/google/common/collect/RangesTest.java1
-rw-r--r--guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java17
-rw-r--r--guava-tests/test/com/google/common/collect/SetOperationsTest.java4
-rw-r--r--guava-tests/test/com/google/common/collect/SetsTest.java324
-rw-r--r--guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java13
-rw-r--r--guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java34
-rw-r--r--guava-tests/test/com/google/common/collect/SortedIterablesTest.java36
-rw-r--r--guava-tests/test/com/google/common/collect/SortedListsTest.java12
-rw-r--r--guava-tests/test/com/google/common/collect/SortedMapsTest.java222
-rw-r--r--guava-tests/test/com/google/common/collect/SpecialRandom.java55
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java78
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java14
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java392
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java268
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java177
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedSetTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/TableCollectionTest.java15
-rw-r--r--guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java51
-rw-r--r--guava-tests/test/com/google/common/collect/TransformedSetTest.java126
-rw-r--r--guava-tests/test/com/google/common/collect/TreeBasedTableTest.java155
-rw-r--r--guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java35
-rw-r--r--guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java553
-rw-r--r--guava-tests/test/com/google/common/collect/TreeMultisetTest.java143
-rw-r--r--guava-tests/test/com/google/common/collect/TreeRangeMapTest.java480
-rw-r--r--guava-tests/test/com/google/common/collect/TreeRangeSetTest.java570
-rw-r--r--guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java4
-rw-r--r--guava-tests/test/com/google/common/eventbus/EventBusTest.java58
-rw-r--r--guava-tests/test/com/google/common/eventbus/EventHandlerTest.java41
-rw-r--r--guava-tests/test/com/google/common/eventbus/PackageSanityTests.java51
-rw-r--r--guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java4
-rw-r--r--guava-tests/test/com/google/common/eventbus/StringCatcher.java10
-rw-r--r--guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java451
-rw-r--r--guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java57
-rw-r--r--guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java140
-rw-r--r--guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java69
-rw-r--r--guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java115
-rw-r--r--guava-tests/test/com/google/common/hash/BloomFilterTest.java241
-rw-r--r--guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java87
-rw-r--r--guava-tests/test/com/google/common/hash/FunnelsTest.java92
-rw-r--r--guava-tests/test/com/google/common/hash/HashCodesTest.java126
-rw-r--r--guava-tests/test/com/google/common/hash/HashFunctionsTest.java74
-rw-r--r--guava-tests/test/com/google/common/hash/HashTestUtils.java506
-rw-r--r--guava-tests/test/com/google/common/hash/HashingTest.java215
-rw-r--r--guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java73
-rw-r--r--guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java71
-rw-r--r--guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java39
-rw-r--r--guava-tests/test/com/google/common/hash/PackageSanityTests.java35
-rw-r--r--guava-tests/test/com/google/common/io/BaseEncodingTest.java431
-rw-r--r--guava-tests/test/com/google/common/io/ByteSinkTest.java117
-rw-r--r--guava-tests/test/com/google/common/io/ByteSinkTester.java125
-rw-r--r--guava-tests/test/com/google/common/io/ByteSourceTest.java215
-rw-r--r--guava-tests/test/com/google/common/io/ByteSourceTester.java187
-rw-r--r--guava-tests/test/com/google/common/io/ByteStreamsTest.java382
-rw-r--r--guava-tests/test/com/google/common/io/CharSinkTest.java128
-rw-r--r--guava-tests/test/com/google/common/io/CharSinkTester.java135
-rw-r--r--guava-tests/test/com/google/common/io/CharSourceTest.java145
-rw-r--r--guava-tests/test/com/google/common/io/CharSourceTester.java147
-rw-r--r--guava-tests/test/com/google/common/io/CharStreamsTest.java144
-rw-r--r--guava-tests/test/com/google/common/io/CloseablesTest.java72
-rw-r--r--guava-tests/test/com/google/common/io/CloserTest.java461
-rw-r--r--guava-tests/test/com/google/common/io/FlushablesTest.java112
-rw-r--r--guava-tests/test/com/google/common/io/PackageSanityTests.java36
-rw-r--r--guava-tests/test/com/google/common/io/RandomAmountInputStream.java6
-rw-r--r--guava-tests/test/com/google/common/io/ResourcesTest.java48
-rw-r--r--guava-tests/test/com/google/common/io/SourceSinkFactories.java378
-rw-r--r--guava-tests/test/com/google/common/io/SourceSinkFactory.java101
-rw-r--r--guava-tests/test/com/google/common/io/SourceSinkTester.java125
-rw-r--r--guava-tests/test/com/google/common/io/TestByteSink.java75
-rw-r--r--guava-tests/test/com/google/common/io/TestByteSource.java74
-rw-r--r--guava-tests/test/com/google/common/io/TestCharSink.java76
-rw-r--r--guava-tests/test/com/google/common/io/TestCharSource.java52
-rw-r--r--guava-tests/test/com/google/common/io/TestInputStream.java91
-rw-r--r--guava-tests/test/com/google/common/io/TestOption.java30
-rw-r--r--guava-tests/test/com/google/common/io/TestOutputStream.java83
-rw-r--r--guava-tests/test/com/google/common/io/TestReader.java46
-rw-r--r--guava-tests/test/com/google/common/io/TestStreamSupplier.java37
-rw-r--r--guava-tests/test/com/google/common/io/TestWriter.java63
-rw-r--r--guava-tests/test/com/google/common/math/BigIntegerMathTest.java96
-rw-r--r--guava-tests/test/com/google/common/math/DoubleMathTest.java145
-rw-r--r--guava-tests/test/com/google/common/math/DoubleUtilsTest.java66
-rw-r--r--guava-tests/test/com/google/common/math/IntMathTest.java145
-rw-r--r--guava-tests/test/com/google/common/math/LongMathTest.java178
-rw-r--r--guava-tests/test/com/google/common/math/MathBenchmarking.java79
-rw-r--r--guava-tests/test/com/google/common/math/MathPreconditionsTest.java268
-rw-r--r--guava-tests/test/com/google/common/math/MathTesting.java32
-rw-r--r--guava-tests/test/com/google/common/math/PackageSanityTests.java27
-rw-r--r--guava-tests/test/com/google/common/math/TestPlatform.java29
-rw-r--r--guava-tests/test/com/google/common/net/HostAndPortTest.java232
-rw-r--r--guava-tests/test/com/google/common/net/HostSpecifierTest.java2
-rw-r--r--guava-tests/test/com/google/common/net/HttpHeadersTest.java5
-rw-r--r--guava-tests/test/com/google/common/net/InetAddressesTest.java44
-rw-r--r--guava-tests/test/com/google/common/net/InternetDomainNameTest.java15
-rw-r--r--guava-tests/test/com/google/common/net/MediaTypeTest.java432
-rw-r--r--guava-tests/test/com/google/common/net/PackageSanityTests.java31
-rw-r--r--guava-tests/test/com/google/common/primitives/BooleansTest.java94
-rw-r--r--guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/BytesTest.java24
-rw-r--r--guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/CharsTest.java6
-rw-r--r--guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/DoublesTest.java136
-rw-r--r--guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/FloatsTest.java124
-rw-r--r--guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/IntsTest.java26
-rw-r--r--guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/LongsTest.java101
-rw-r--r--guava-tests/test/com/google/common/primitives/PackageSanityTests.java31
-rw-r--r--guava-tests/test/com/google/common/primitives/PrimitivesTest.java2
-rw-r--r--guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/ShortsTest.java26
-rw-r--r--guava-tests/test/com/google/common/primitives/SignedBytesTest.java8
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java98
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java144
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java134
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedLongTest.java127
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java198
-rw-r--r--guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java139
-rw-r--r--guava-tests/test/com/google/common/reflect/ClassPathTest.java374
-rw-r--r--guava-tests/test/com/google/common/reflect/ElementTest.java244
-rw-r--r--guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java186
-rw-r--r--guava-tests/test/com/google/common/reflect/InvokableTest.java536
-rw-r--r--guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java194
-rw-r--r--guava-tests/test/com/google/common/reflect/PackageSanityTests.java25
-rw-r--r--guava-tests/test/com/google/common/reflect/ParameterTest.java56
-rw-r--r--guava-tests/test/com/google/common/reflect/ReflectionTest.java92
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeParameterTest.java61
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeResolverTest.java216
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java547
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeTokenTest.java1517
-rw-r--r--guava-tests/test/com/google/common/reflect/TypesTest.java424
-rw-r--r--guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java19
-rw-r--r--guava-tests/test/com/google/common/reflect/test.txt1
-rw-r--r--guava-tests/test/com/google/common/testing/EqualsTesterTest.java (renamed from guava-testlib/test/com/google/common/testing/EqualsTesterTest.java)0
-rw-r--r--guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java (renamed from guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java)16
-rw-r--r--guava-tests/test/com/google/common/testing/FakeTickerTest.java74
-rw-r--r--guava-tests/test/com/google/common/testing/GcFinalizationTest.java (renamed from guava-testlib/test/com/google/common/testing/GcFinalizationTest.java)50
-rw-r--r--guava-tests/test/com/google/common/testing/NullPointerTesterTest.java601
-rw-r--r--guava-tests/test/com/google/common/testing/SerializableTesterTest.java (renamed from guava-testlib/test/com/google/common/testing/SerializableTesterTest.java)0
-rw-r--r--guava-tests/test/com/google/common/testing/TearDownStackTest.java (renamed from guava-testlib/test/com/google/common/testing/TearDownStackTest.java)2
-rw-r--r--guava-tests/test/com/google/common/testing/TestLogHandlerTest.java (renamed from guava-testlib/test/com/google/common/testing/TestLogHandlerTest.java)2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java85
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java32
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java218
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java95
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java550
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java1
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java25
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java581
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java64
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java90
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java44
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java74
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java53
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/FuturesTest.java693
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java20
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java11
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java9
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java240
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java27
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java363
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/StripedTest.java165
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java23
-rw-r--r--guava/pom.xml93
-rw-r--r--guava/src/com/google/common/annotations/Beta.java11
-rw-r--r--guava/src/com/google/common/annotations/GwtIncompatible.java6
-rw-r--r--guava/src/com/google/common/annotations/VisibleForTesting.java4
-rw-r--r--guava/src/com/google/common/base/Absent.java89
-rw-r--r--guava/src/com/google/common/base/Ascii.java87
-rw-r--r--guava/src/com/google/common/base/CaseFormat.java162
-rw-r--r--guava/src/com/google/common/base/CharMatcher.java800
-rw-r--r--guava/src/com/google/common/base/Charsets.java15
-rw-r--r--guava/src/com/google/common/base/Defaults.java5
-rw-r--r--guava/src/com/google/common/base/Enums.java46
-rw-r--r--guava/src/com/google/common/base/Equivalence.java74
-rw-r--r--guava/src/com/google/common/base/Equivalences.java97
-rw-r--r--guava/src/com/google/common/base/FinalizableReferenceQueue.java41
-rw-r--r--guava/src/com/google/common/base/Function.java8
-rw-r--r--guava/src/com/google/common/base/Functions.java17
-rw-r--r--guava/src/com/google/common/base/Joiner.java26
-rw-r--r--guava/src/com/google/common/base/Objects.java142
-rw-r--r--guava/src/com/google/common/base/Optional.java193
-rw-r--r--guava/src/com/google/common/base/Preconditions.java4
-rw-r--r--guava/src/com/google/common/base/Predicate.java6
-rw-r--r--guava/src/com/google/common/base/Predicates.java28
-rw-r--r--guava/src/com/google/common/base/Present.java92
-rw-r--r--guava/src/com/google/common/base/SmallCharMatcher.java155
-rw-r--r--guava/src/com/google/common/base/Splitter.java136
-rw-r--r--guava/src/com/google/common/base/Stopwatch.java49
-rw-r--r--guava/src/com/google/common/base/Strings.java3
-rw-r--r--guava/src/com/google/common/base/Suppliers.java78
-rw-r--r--guava/src/com/google/common/base/Throwables.java4
-rw-r--r--guava/src/com/google/common/base/Ticker.java7
-rw-r--r--guava/src/com/google/common/base/internal/Finalizer.java61
-rw-r--r--guava/src/com/google/common/base/package-info.java3
-rw-r--r--guava/src/com/google/common/cache/AbstractCache.java110
-rw-r--r--guava/src/com/google/common/cache/AbstractLoadingCache.java9
-rw-r--r--guava/src/com/google/common/cache/Cache.java82
-rw-r--r--guava/src/com/google/common/cache/CacheBuilder.java195
-rw-r--r--guava/src/com/google/common/cache/CacheBuilderSpec.java455
-rw-r--r--guava/src/com/google/common/cache/CacheLoader.java58
-rw-r--r--guava/src/com/google/common/cache/CacheStats.java7
-rw-r--r--guava/src/com/google/common/cache/ForwardingCache.java31
-rw-r--r--guava/src/com/google/common/cache/LoadingCache.java9
-rw-r--r--guava/src/com/google/common/cache/LocalCache.java369
-rw-r--r--guava/src/com/google/common/cache/LongAddable.java33
-rw-r--r--guava/src/com/google/common/cache/LongAddables.java75
-rw-r--r--guava/src/com/google/common/cache/LongAdder.java211
-rw-r--r--guava/src/com/google/common/cache/RemovalCause.java2
-rw-r--r--guava/src/com/google/common/cache/RemovalListener.java2
-rw-r--r--guava/src/com/google/common/cache/RemovalListeners.java4
-rw-r--r--guava/src/com/google/common/cache/RemovalNotification.java2
-rw-r--r--guava/src/com/google/common/cache/Striped64.java347
-rw-r--r--guava/src/com/google/common/cache/Weigher.java19
-rw-r--r--guava/src/com/google/common/cache/package-info.java4
-rw-r--r--guava/src/com/google/common/collect/AbstractBiMap.java76
-rw-r--r--guava/src/com/google/common/collect/AbstractLinkedIterator.java (renamed from guava/src/com/google/common/collect/AbstractSequentialIterator.java)19
-rw-r--r--guava/src/com/google/common/collect/AbstractListMultimap.java9
-rw-r--r--guava/src/com/google/common/collect/AbstractMapBasedMultimap.java1567
-rw-r--r--guava/src/com/google/common/collect/AbstractMapBasedMultiset.java116
-rw-r--r--guava/src/com/google/common/collect/AbstractMultimap.java1318
-rw-r--r--guava/src/com/google/common/collect/AbstractMultiset.java18
-rw-r--r--guava/src/com/google/common/collect/AbstractNavigableMap.java198
-rw-r--r--guava/src/com/google/common/collect/AbstractRangeSet.java123
-rw-r--r--guava/src/com/google/common/collect/AbstractSetMultimap.java10
-rw-r--r--guava/src/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java56
-rw-r--r--guava/src/com/google/common/collect/AbstractSortedMultiset.java38
-rw-r--r--guava/src/com/google/common/collect/AbstractSortedSetMultimap.java19
-rw-r--r--guava/src/com/google/common/collect/AllEqualOrdering.java66
-rw-r--r--guava/src/com/google/common/collect/ArrayListMultimap.java6
-rw-r--r--guava/src/com/google/common/collect/ArrayTable.java382
-rw-r--r--guava/src/com/google/common/collect/AsynchronousComputationException.java (renamed from guava-gwt/src/com/google/common/collect/ForwardingImmutableList_CustomFieldSerializer.java)20
-rw-r--r--guava/src/com/google/common/collect/BiMap.java4
-rw-r--r--guava/src/com/google/common/collect/BoundType.java19
-rw-r--r--guava/src/com/google/common/collect/BstAggregate.java41
-rw-r--r--guava/src/com/google/common/collect/BstBalancePolicy.java45
-rw-r--r--guava/src/com/google/common/collect/BstCountBasedBalancePolicies.java212
-rw-r--r--guava/src/com/google/common/collect/BstInOrderPath.java126
-rw-r--r--guava/src/com/google/common/collect/BstModificationResult.java74
-rw-r--r--guava/src/com/google/common/collect/BstModifier.java49
-rw-r--r--guava/src/com/google/common/collect/BstMutationResult.java156
-rw-r--r--guava/src/com/google/common/collect/BstMutationRule.java77
-rw-r--r--guava/src/com/google/common/collect/BstNode.java125
-rw-r--r--guava/src/com/google/common/collect/BstNodeFactory.java46
-rw-r--r--guava/src/com/google/common/collect/BstOperations.java228
-rw-r--r--guava/src/com/google/common/collect/BstPath.java74
-rw-r--r--guava/src/com/google/common/collect/BstPathFactory.java38
-rw-r--r--guava/src/com/google/common/collect/BstRangeOps.java175
-rw-r--r--guava/src/com/google/common/collect/BstSide.java40
-rw-r--r--guava/src/com/google/common/collect/CartesianList.java164
-rw-r--r--guava/src/com/google/common/collect/ClassToInstanceMap.java7
-rw-r--r--guava/src/com/google/common/collect/Collections2.java389
-rw-r--r--guava/src/com/google/common/collect/ComparatorOrdering.java12
-rw-r--r--guava/src/com/google/common/collect/ComparisonChain.java44
-rw-r--r--guava/src/com/google/common/collect/CompoundOrdering.java13
-rw-r--r--guava/src/com/google/common/collect/ComputationException.java4
-rw-r--r--guava/src/com/google/common/collect/ComputingConcurrentHashMap.java9
-rw-r--r--guava/src/com/google/common/collect/ConcurrentHashMultiset.java85
-rw-r--r--guava/src/com/google/common/collect/ContiguousSet.java72
-rw-r--r--guava/src/com/google/common/collect/Count.java4
-rw-r--r--guava/src/com/google/common/collect/Cut.java12
-rw-r--r--guava/src/com/google/common/collect/DescendingImmutableSortedMultiset.java49
-rw-r--r--guava/src/com/google/common/collect/DescendingImmutableSortedSet.java114
-rw-r--r--guava/src/com/google/common/collect/DescendingMultiset.java140
-rw-r--r--guava/src/com/google/common/collect/DiscreteDomain.java155
-rw-r--r--guava/src/com/google/common/collect/DiscreteDomains.java125
-rw-r--r--guava/src/com/google/common/collect/EmptyContiguousSet.java14
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableBiMap.java77
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableList.java52
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableMap.java95
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableMultiset.java67
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableSet.java22
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableSortedMap.java107
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableSortedMultiset.java73
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableSortedSet.java32
-rw-r--r--guava/src/com/google/common/collect/EmptyImmutableTable.java6
-rw-r--r--guava/src/com/google/common/collect/EnumBiMap.java15
-rw-r--r--guava/src/com/google/common/collect/EnumHashBiMap.java13
-rw-r--r--guava/src/com/google/common/collect/EnumMultiset.java17
-rw-r--r--guava/src/com/google/common/collect/FilteredEntryMultimap.java406
-rw-r--r--guava/src/com/google/common/collect/FilteredKeyMultimap.java228
-rw-r--r--guava/src/com/google/common/collect/FilteredMultimap.java40
-rw-r--r--guava/src/com/google/common/collect/FluentIterable.java531
-rw-r--r--guava/src/com/google/common/collect/ForwardingBlockingDeque.java123
-rw-r--r--guava/src/com/google/common/collect/ForwardingCollection.java29
-rw-r--r--guava/src/com/google/common/collect/ForwardingDeque.java129
-rw-r--r--guava/src/com/google/common/collect/ForwardingImmutableCollection.java30
-rw-r--r--guava/src/com/google/common/collect/ForwardingImmutableList.java29
-rw-r--r--guava/src/com/google/common/collect/ForwardingImmutableSet.java29
-rw-r--r--guava/src/com/google/common/collect/ForwardingList.java17
-rw-r--r--guava/src/com/google/common/collect/ForwardingMap.java29
-rw-r--r--guava/src/com/google/common/collect/ForwardingMapEntry.java4
-rw-r--r--guava/src/com/google/common/collect/ForwardingMultiset.java34
-rw-r--r--guava/src/com/google/common/collect/ForwardingNavigableMap.java397
-rw-r--r--guava/src/com/google/common/collect/ForwardingNavigableSet.java238
-rw-r--r--guava/src/com/google/common/collect/ForwardingQueue.java7
-rw-r--r--guava/src/com/google/common/collect/ForwardingSet.java21
-rw-r--r--guava/src/com/google/common/collect/ForwardingTable.java2
-rw-r--r--guava/src/com/google/common/collect/GeneralRange.java135
-rw-r--r--guava/src/com/google/common/collect/GenericMapMaker.java30
-rw-r--r--guava/src/com/google/common/collect/HashBasedTable.java6
-rw-r--r--guava/src/com/google/common/collect/HashBiMap.java636
-rw-r--r--guava/src/com/google/common/collect/HashMultimap.java2
-rw-r--r--guava/src/com/google/common/collect/Hashing.java39
-rw-r--r--guava/src/com/google/common/collect/ImmutableAsList.java39
-rw-r--r--guava/src/com/google/common/collect/ImmutableBiMap.java130
-rw-r--r--guava/src/com/google/common/collect/ImmutableClassToInstanceMap.java9
-rw-r--r--guava/src/com/google/common/collect/ImmutableCollection.java35
-rw-r--r--guava/src/com/google/common/collect/ImmutableEnumMap.java151
-rw-r--r--guava/src/com/google/common/collect/ImmutableEnumSet.java13
-rw-r--r--guava/src/com/google/common/collect/ImmutableList.java204
-rw-r--r--guava/src/com/google/common/collect/ImmutableListMultimap.java26
-rw-r--r--guava/src/com/google/common/collect/ImmutableMap.java158
-rw-r--r--guava/src/com/google/common/collect/ImmutableMapEntrySet.java76
-rw-r--r--guava/src/com/google/common/collect/ImmutableMapKeySet.java95
-rw-r--r--guava/src/com/google/common/collect/ImmutableMapValues.java91
-rw-r--r--guava/src/com/google/common/collect/ImmutableMultimap.java279
-rw-r--r--guava/src/com/google/common/collect/ImmutableMultiset.java92
-rw-r--r--guava/src/com/google/common/collect/ImmutableRangeMap.java299
-rw-r--r--guava/src/com/google/common/collect/ImmutableRangeSet.java608
-rw-r--r--guava/src/com/google/common/collect/ImmutableSet.java260
-rw-r--r--guava/src/com/google/common/collect/ImmutableSetMultimap.java85
-rw-r--r--guava/src/com/google/common/collect/ImmutableSortedAsList.java97
-rw-r--r--guava/src/com/google/common/collect/ImmutableSortedMap.java480
-rw-r--r--guava/src/com/google/common/collect/ImmutableSortedMultiset.java162
-rw-r--r--guava/src/com/google/common/collect/ImmutableSortedSet.java261
-rw-r--r--guava/src/com/google/common/collect/ImmutableTable.java36
-rw-r--r--guava/src/com/google/common/collect/Interners.java40
-rw-r--r--guava/src/com/google/common/collect/Iterables.java149
-rw-r--r--guava/src/com/google/common/collect/Iterators.java182
-rw-r--r--guava/src/com/google/common/collect/LinkedHashMultimap.java584
-rw-r--r--guava/src/com/google/common/collect/LinkedHashMultiset.java4
-rw-r--r--guava/src/com/google/common/collect/LinkedListMultimap.java456
-rw-r--r--guava/src/com/google/common/collect/ListMultimap.java7
-rw-r--r--guava/src/com/google/common/collect/Lists.java253
-rw-r--r--guava/src/com/google/common/collect/MapConstraints.java3
-rw-r--r--guava/src/com/google/common/collect/MapMaker.java147
-rw-r--r--guava/src/com/google/common/collect/MapMakerInternalMap.java171
-rw-r--r--guava/src/com/google/common/collect/Maps.java2126
-rw-r--r--guava/src/com/google/common/collect/MinMaxPriorityQueue.java7
-rw-r--r--guava/src/com/google/common/collect/Multimap.java157
-rw-r--r--guava/src/com/google/common/collect/Multimaps.java888
-rw-r--r--guava/src/com/google/common/collect/Multiset.java18
-rw-r--r--guava/src/com/google/common/collect/Multisets.java562
-rw-r--r--guava/src/com/google/common/collect/MutableClassToInstanceMap.java4
-rw-r--r--guava/src/com/google/common/collect/ObjectArrays.java23
-rw-r--r--guava/src/com/google/common/collect/Ordering.java718
-rw-r--r--guava/src/com/google/common/collect/PeekingIterator.java4
-rw-r--r--guava/src/com/google/common/collect/Platform.java67
-rw-r--r--guava/src/com/google/common/collect/Queues.java127
-rw-r--r--guava/src/com/google/common/collect/Range.java706
-rw-r--r--guava/src/com/google/common/collect/RangeMap.java134
-rw-r--r--guava/src/com/google/common/collect/RangeSet.java206
-rw-r--r--guava/src/com/google/common/collect/Ranges.java77
-rw-r--r--guava/src/com/google/common/collect/RegularContiguousSet.java69
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableAsList.java91
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableBiMap.java282
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableList.java68
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableMap.java138
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableMultiset.java57
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableSortedMap.java130
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableSortedMultiset.java205
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableSortedSet.java104
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableTable.java564
-rw-r--r--guava/src/com/google/common/collect/SetMultimap.java11
-rw-r--r--guava/src/com/google/common/collect/Sets.java851
-rw-r--r--guava/src/com/google/common/collect/SingletonImmutableBiMap.java96
-rw-r--r--guava/src/com/google/common/collect/SingletonImmutableList.java45
-rw-r--r--guava/src/com/google/common/collect/SingletonImmutableMap.java162
-rw-r--r--guava/src/com/google/common/collect/SingletonImmutableTable.java6
-rw-r--r--guava/src/com/google/common/collect/SortedIterables.java151
-rw-r--r--guava/src/com/google/common/collect/SortedLists.java12
-rw-r--r--guava/src/com/google/common/collect/SortedMapDifference.java2
-rw-r--r--guava/src/com/google/common/collect/SortedMaps.java374
-rw-r--r--guava/src/com/google/common/collect/SortedMultiset.java16
-rw-r--r--guava/src/com/google/common/collect/SortedMultisetBridge.java31
-rw-r--r--guava/src/com/google/common/collect/SortedMultisets.java183
-rw-r--r--guava/src/com/google/common/collect/SortedSetMultimap.java7
-rw-r--r--guava/src/com/google/common/collect/StandardTable.java132
-rw-r--r--guava/src/com/google/common/collect/Synchronized.java413
-rw-r--r--guava/src/com/google/common/collect/Table.java7
-rw-r--r--guava/src/com/google/common/collect/Tables.java8
-rw-r--r--guava/src/com/google/common/collect/TransformedImmutableList.java128
-rw-r--r--guava/src/com/google/common/collect/TransformedIterator.java55
-rw-r--r--guava/src/com/google/common/collect/TransformedListIterator.java71
-rw-r--r--guava/src/com/google/common/collect/TreeBasedTable.java4
-rw-r--r--guava/src/com/google/common/collect/TreeMultimap.java85
-rw-r--r--guava/src/com/google/common/collect/TreeMultiset.java1091
-rw-r--r--guava/src/com/google/common/collect/TreeRangeMap.java618
-rw-r--r--guava/src/com/google/common/collect/TreeRangeSet.java851
-rw-r--r--guava/src/com/google/common/collect/UnmodifiableIterator.java4
-rw-r--r--guava/src/com/google/common/collect/UnmodifiableListIterator.java6
-rw-r--r--guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java114
-rw-r--r--guava/src/com/google/common/collect/UsingToStringOrdering.java5
-rw-r--r--guava/src/com/google/common/collect/WellBehavedMap.java67
-rw-r--r--guava/src/com/google/common/collect/package-info.java10
-rw-r--r--guava/src/com/google/common/eventbus/AllowConcurrentEvents.java1
-rw-r--r--guava/src/com/google/common/eventbus/AnnotatedHandlerFinder.java93
-rw-r--r--guava/src/com/google/common/eventbus/AsyncEventBus.java19
-rw-r--r--guava/src/com/google/common/eventbus/DeadEvent.java6
-rw-r--r--guava/src/com/google/common/eventbus/EventBus.java184
-rw-r--r--guava/src/com/google/common/eventbus/EventHandler.java35
-rw-r--r--guava/src/com/google/common/eventbus/HandlerFindingStrategy.java2
-rw-r--r--guava/src/com/google/common/eventbus/Subscribe.java1
-rw-r--r--guava/src/com/google/common/eventbus/package-info.java18
-rw-r--r--guava/src/com/google/common/hash/AbstractByteHasher.java122
-rw-r--r--guava/src/com/google/common/hash/AbstractCompositeHashFunction.java33
-rw-r--r--guava/src/com/google/common/hash/AbstractHasher.java16
-rw-r--r--guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java64
-rw-r--r--guava/src/com/google/common/hash/AbstractStreamingHashFunction.java14
-rw-r--r--guava/src/com/google/common/hash/BloomFilter.java277
-rw-r--r--guava/src/com/google/common/hash/BloomFilterStrategies.java82
-rw-r--r--guava/src/com/google/common/hash/ChecksumHashFunction.java96
-rw-r--r--guava/src/com/google/common/hash/Funnel.java25
-rw-r--r--guava/src/com/google/common/hash/Funnels.java88
-rw-r--r--guava/src/com/google/common/hash/HashCode.java18
-rw-r--r--guava/src/com/google/common/hash/HashCodes.java92
-rw-r--r--guava/src/com/google/common/hash/HashFunction.java34
-rw-r--r--guava/src/com/google/common/hash/Hasher.java34
-rw-r--r--guava/src/com/google/common/hash/Hashing.java231
-rw-r--r--guava/src/com/google/common/hash/MessageDigestHashFunction.java193
-rw-r--r--guava/src/com/google/common/hash/Murmur3_128HashFunction.java103
-rw-r--r--guava/src/com/google/common/hash/Murmur3_32HashFunction.java159
-rw-r--r--guava/src/com/google/common/hash/Sink.java (renamed from guava/src/com/google/common/hash/PrimitiveSink.java)28
-rw-r--r--guava/src/com/google/common/hash/package-info.java4
-rw-r--r--guava/src/com/google/common/io/AppendableWriter.java14
-rw-r--r--guava/src/com/google/common/io/BaseEncoding.java882
-rw-r--r--guava/src/com/google/common/io/ByteArrayDataInput.java22
-rw-r--r--guava/src/com/google/common/io/ByteSink.java144
-rw-r--r--guava/src/com/google/common/io/ByteSource.java343
-rw-r--r--guava/src/com/google/common/io/ByteStreams.java466
-rw-r--r--guava/src/com/google/common/io/CharSink.java150
-rw-r--r--guava/src/com/google/common/io/CharSource.java192
-rw-r--r--guava/src/com/google/common/io/CharStreams.java332
-rw-r--r--guava/src/com/google/common/io/Closeables.java69
-rw-r--r--guava/src/com/google/common/io/Closer.java285
-rw-r--r--guava/src/com/google/common/io/CountingInputStream.java4
-rw-r--r--guava/src/com/google/common/io/CountingOutputStream.java4
-rw-r--r--guava/src/com/google/common/io/FileWriteMode.java28
-rw-r--r--guava/src/com/google/common/io/Files.java377
-rw-r--r--guava/src/com/google/common/io/GwtWorkarounds.java231
-rw-r--r--guava/src/com/google/common/io/LimitInputStream.java3
-rw-r--r--guava/src/com/google/common/io/LineBuffer.java3
-rw-r--r--guava/src/com/google/common/io/MultiInputStream.java8
-rw-r--r--guava/src/com/google/common/io/MultiReader.java4
-rw-r--r--guava/src/com/google/common/io/NullOutputStream.java6
-rw-r--r--guava/src/com/google/common/io/PatternFilenameFilter.java4
-rw-r--r--guava/src/com/google/common/io/Resources.java73
-rw-r--r--guava/src/com/google/common/io/package-info.java1
-rw-r--r--guava/src/com/google/common/math/BigIntegerMath.java118
-rw-r--r--guava/src/com/google/common/math/DoubleMath.java141
-rw-r--r--guava/src/com/google/common/math/DoubleUtils.java97
-rw-r--r--guava/src/com/google/common/math/IntMath.java113
-rw-r--r--guava/src/com/google/common/math/LongMath.java271
-rw-r--r--guava/src/com/google/common/math/MathPreconditions.java41
-rw-r--r--guava/src/com/google/common/math/package-info.java5
-rw-r--r--guava/src/com/google/common/net/HostAndPort.java13
-rw-r--r--guava/src/com/google/common/net/HttpHeaders.java2
-rw-r--r--guava/src/com/google/common/net/InetAddresses.java298
-rw-r--r--guava/src/com/google/common/net/InternetDomainName.java10
-rw-r--r--guava/src/com/google/common/net/MediaType.java703
-rw-r--r--guava/src/com/google/common/net/TldPatterns.java2349
-rw-r--r--guava/src/com/google/common/net/package-info.java1
-rw-r--r--guava/src/com/google/common/primitives/Booleans.java9
-rw-r--r--guava/src/com/google/common/primitives/Bytes.java20
-rw-r--r--guava/src/com/google/common/primitives/Chars.java9
-rw-r--r--guava/src/com/google/common/primitives/Doubles.java86
-rw-r--r--guava/src/com/google/common/primitives/Floats.java62
-rw-r--r--guava/src/com/google/common/primitives/Ints.java20
-rw-r--r--guava/src/com/google/common/primitives/Longs.java98
-rw-r--r--guava/src/com/google/common/primitives/ParseRequest.java57
-rw-r--r--guava/src/com/google/common/primitives/Shorts.java20
-rw-r--r--guava/src/com/google/common/primitives/SignedBytes.java4
-rw-r--r--guava/src/com/google/common/primitives/UnsignedBytes.java388
-rw-r--r--guava/src/com/google/common/primitives/UnsignedInteger.java161
-rw-r--r--guava/src/com/google/common/primitives/UnsignedInts.java82
-rw-r--r--guava/src/com/google/common/primitives/UnsignedLong.java153
-rw-r--r--guava/src/com/google/common/primitives/UnsignedLongs.java113
-rw-r--r--guava/src/com/google/common/primitives/generate.sh (renamed from guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Floats.java)352
-rw-r--r--guava/src/com/google/common/primitives/package-info.java8
-rw-r--r--guava/src/com/google/common/reflect/AbstractInvocationHandler.java112
-rw-r--r--guava/src/com/google/common/reflect/ClassPath.java379
-rw-r--r--guava/src/com/google/common/reflect/Element.java164
-rw-r--r--guava/src/com/google/common/reflect/ImmutableTypeToInstanceMap.java138
-rw-r--r--guava/src/com/google/common/reflect/Invokable.java286
-rw-r--r--guava/src/com/google/common/reflect/MutableTypeToInstanceMap.java89
-rw-r--r--guava/src/com/google/common/reflect/Parameter.java103
-rw-r--r--guava/src/com/google/common/reflect/Reflection.java98
-rw-r--r--guava/src/com/google/common/reflect/TypeCapture.java38
-rw-r--r--guava/src/com/google/common/reflect/TypeParameter.java67
-rw-r--r--guava/src/com/google/common/reflect/TypeResolver.java391
-rw-r--r--guava/src/com/google/common/reflect/TypeToInstanceMap.java92
-rw-r--r--guava/src/com/google/common/reflect/TypeToken.java1146
-rw-r--r--guava/src/com/google/common/reflect/Types.java504
-rw-r--r--guava/src/com/google/common/reflect/package-info.java23
-rw-r--r--guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java42
-rw-r--r--guava/src/com/google/common/util/concurrent/AbstractFuture.java65
-rw-r--r--guava/src/com/google/common/util/concurrent/AbstractIdleService.java40
-rw-r--r--guava/src/com/google/common/util/concurrent/AbstractListeningExecutorService.java89
-rw-r--r--guava/src/com/google/common/util/concurrent/AbstractScheduledService.java89
-rw-r--r--guava/src/com/google/common/util/concurrent/AbstractService.java457
-rw-r--r--guava/src/com/google/common/util/concurrent/AsyncFunction.java3
-rw-r--r--guava/src/com/google/common/util/concurrent/AtomicDouble.java12
-rw-r--r--guava/src/com/google/common/util/concurrent/AtomicDoubleArray.java4
-rw-r--r--guava/src/com/google/common/util/concurrent/AtomicLongMap.java20
-rw-r--r--guava/src/com/google/common/util/concurrent/Atomics.java3
-rw-r--r--guava/src/com/google/common/util/concurrent/CycleDetectingLockFactory.java1038
-rw-r--r--guava/src/com/google/common/util/concurrent/ExecutionError.java10
-rw-r--r--guava/src/com/google/common/util/concurrent/ExecutionList.java3
-rw-r--r--guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java6
-rw-r--r--guava/src/com/google/common/util/concurrent/ForwardingService.java23
-rw-r--r--guava/src/com/google/common/util/concurrent/FutureCallback.java3
-rw-r--r--guava/src/com/google/common/util/concurrent/FutureFallback.java48
-rw-r--r--guava/src/com/google/common/util/concurrent/Futures.java985
-rw-r--r--guava/src/com/google/common/util/concurrent/JdkFutureAdapters.java34
-rw-r--r--guava/src/com/google/common/util/concurrent/ListenableFuture.java38
-rw-r--r--guava/src/com/google/common/util/concurrent/ListenableFutureTask.java11
-rw-r--r--guava/src/com/google/common/util/concurrent/MoreExecutors.java299
-rw-r--r--guava/src/com/google/common/util/concurrent/RateLimiter.java690
-rw-r--r--guava/src/com/google/common/util/concurrent/Service.java202
-rw-r--r--guava/src/com/google/common/util/concurrent/ServiceManager.java724
-rw-r--r--guava/src/com/google/common/util/concurrent/Striped.java376
-rw-r--r--guava/src/com/google/common/util/concurrent/ThreadFactoryBuilder.java5
-rw-r--r--guava/src/com/google/common/util/concurrent/UncheckedExecutionException.java18
-rw-r--r--guava/src/com/google/common/util/concurrent/UncheckedTimeoutException.java8
-rw-r--r--guava/src/com/google/common/util/concurrent/Uninterruptibles.java12
-rw-r--r--guava/src/com/google/common/util/concurrent/package-info.java1
-rw-r--r--pom.xml34
1150 files changed, 28561 insertions, 115414 deletions
diff --git a/AUTHORS b/AUTHORS
index f8c86ec..5228f71 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,4 @@
Google Inc.
Colin Decker
-Emily Soldal
Louis Wasserman
Maginatics
diff --git a/README b/README
index 089d02d..69eee4f 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
Guava: Google Core Libraries for Java
=====================================
-Requires JDK 1.6 or higher (as of 12.0).
+Requires JDK 1.5 or higher.
Project page:
http://guava-libraries.googlecode.com
diff --git a/guava-gwt/pom.xml b/guava-gwt/pom.xml
index 6b44fac..f087b3d 100644
--- a/guava-gwt/pom.xml
+++ b/guava-gwt/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>com.google.guava</groupId>
<artifactId>guava-parent</artifactId>
- <version>14.0.1</version>
+ <version>11.0.2</version>
</parent>
<artifactId>guava-gwt</artifactId>
<name>Guava GWT compatible libs</name>
@@ -16,89 +16,53 @@
This project includes GWT-friendly sources.
</description>
- <properties>
- <gwt.version>2.5.0-rc1</gwt.version>
- </properties>
<dependencies>
- <!-- GWT requires a library's transitive dependencies to be present when compiling a project that uses that library, thanks to its full-program compilation, so we don't use scope=provided. -->
<dependency>
- <groupId>com.google.code.findbugs</groupId>
- <artifactId>jsr305</artifactId>
- <version>1.3.9</version>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${project.version}</version>
+ <classifier>sources</classifier>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
- <version>${gwt.version}</version>
+ <version>2.2.0</version>
+ <type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
- <version>${gwt.version}</version>
+ <version>2.2.0</version>
+ <type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.3.1</version>
- <configuration>
- <excludes>
- <exclude>**/ForceGuavaCompilation*</exclude>
- </excludes>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.1.2</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <phase>post-integration-test</phase>
- <goals><goal>jar</goal></goals>
- </execution>
- </executions>
- <configuration>
- <excludes>
- <exclude>**/ForceGuavaCompilation*</exclude>
- </excludes>
+ <source>1.5</source>
+ <target>1.5</target>
</configuration>
</plugin>
<plugin>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8</version>
- <executions>
- <execution>
- <id>attach-docs</id>
- <phase>post-integration-test</phase>
- <goals><goal>jar</goal></goals>
- </execution>
- </executions>
- </plugin>
- <!-- Disable "normal" testing, which doesn't work for GWT tests. -->
- <plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- <plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
@@ -111,6 +75,7 @@
<classifier>sources</classifier>
<overWrite>true</overWrite>
<excludeTransitive>true</excludeTransitive>
+ <includeScope>provided</includeScope>
<excludes>META-INF/MANIFEST.MF</excludes>
<outputDirectory>${project.build.directory}/guava-sources</outputDirectory>
<type>java-source</type>
@@ -118,16 +83,9 @@
</configuration>
</execution>
</executions>
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>${project.version}</version>
- <classifier>sources</classifier>
- </dependency>
- </dependencies>
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
@@ -151,27 +109,9 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>gwt-maven-plugin</artifactId>
- <version>${gwt.version}</version>
- <executions>
- <execution>
- <id>gwt-compile</id>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <module>com.google.common.ForceGuavaCompilation</module>
- <strict>true</strict>
- <validateOnly>true</validateOnly>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
<sourceDirectory>src</sourceDirectory>
- <testSourceDirectory>test</testSourceDirectory>
+ <testSourceDirectory>disabled</testSourceDirectory>
<resources>
<resource>
<directory>src</directory>
@@ -183,10 +123,5 @@
<directory>${project.build.directory}/guava-gwt-sources</directory>
</resource>
</resources>
- <testResources>
- <testResource>
- <directory>test</directory>
- </testResource>
- </testResources>
</build>
</project>
diff --git a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/CharMatcher.java b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/CharMatcher.java
deleted file mode 100644
index ed30766..0000000
--- a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/CharMatcher.java
+++ /dev/null
@@ -1,1244 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Arrays;
-
-import javax.annotation.CheckReturnValue;
-
-/**
- * Determines a true or false value for any Java {@code char} value, just as {@link Predicate} does
- * for any {@link Object}. Also offers basic text processing methods based on this function.
- * Implementations are strongly encouraged to be side-effect-free and immutable.
- *
- * <p>Throughout the documentation of this class, the phrase "matching character" is used to mean
- * "any character {@code c} for which {@code this.matches(c)} returns {@code true}".
- *
- * <p><b>Note:</b> This class deals only with {@code char} values; it does not understand
- * supplementary Unicode code points in the range {@code 0x10000} to {@code 0x10FFFF}. Such logical
- * characters are encoded into a {@code String} using surrogate pairs, and a {@code CharMatcher}
- * treats these just as two separate characters.
- *
- * <p>Example usages: <pre>
- * String trimmed = {@link #WHITESPACE WHITESPACE}.{@link #trimFrom trimFrom}(userInput);
- * if ({@link #ASCII ASCII}.{@link #matchesAllOf matchesAllOf}(s)) { ... }</pre>
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#CharMatcher">
- * {@code CharMatcher}</a>.
- *
- * @author Kevin Bourrillion
- * @since 1.0
- */
-@Beta // Possibly change from chars to code points; decide constants vs. methods
-@GwtCompatible(emulated = true)
-public abstract class CharMatcher implements Predicate<Character> {
- // Constants
- /**
- * Determines whether a character is a breaking whitespace (that is, a whitespace which can be
- * interpreted as a break between words for formatting purposes). See {@link #WHITESPACE} for a
- * discussion of that term.
- *
- * @since 2.0
- */
- public static final CharMatcher BREAKING_WHITESPACE = new CharMatcher() {
- @Override
- public boolean matches(char c) {
- switch (c) {
- case '\t':
- case '\n':
- case '\013':
- case '\f':
- case '\r':
- case ' ':
- case '\u0085':
- case '\u1680':
- case '\u2028':
- case '\u2029':
- case '\u205f':
- case '\u3000':
- return true;
- case '\u2007':
- return false;
- default:
- return c >= '\u2000' && c <= '\u200a';
- }
- }
-
- @Override
- public String toString() {
- return "CharMatcher.BREAKING_WHITESPACE";
- }
- };
-
- /**
- * Determines whether a character is ASCII, meaning that its code point is less than 128.
- */
- public static final CharMatcher ASCII = inRange('\0', '\u007f', "CharMatcher.ASCII");
-
- private static class RangesMatcher extends CharMatcher {
- private final char[] rangeStarts;
- private final char[] rangeEnds;
-
- RangesMatcher(String description, char[] rangeStarts, char[] rangeEnds) {
- super(description);
- this.rangeStarts = rangeStarts;
- this.rangeEnds = rangeEnds;
- checkArgument(rangeStarts.length == rangeEnds.length);
- for (int i = 0; i < rangeStarts.length; i++) {
- checkArgument(rangeStarts[i] <= rangeEnds[i]);
- if (i + 1 < rangeStarts.length) {
- checkArgument(rangeEnds[i] < rangeStarts[i + 1]);
- }
- }
- }
-
- @Override
- public boolean matches(char c) {
- int index = Arrays.binarySearch(rangeStarts, c);
- if (index >= 0) {
- return true;
- } else {
- index = ~index - 1;
- return index >= 0 && c <= rangeEnds[index];
- }
- }
- }
-
- // Must be in ascending order.
- private static final String ZEROES = "0\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66\u0be6"
- + "\u0c66\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810\u1946\u19d0\u1b50\u1bb0"
- + "\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10";
-
- private static final String NINES;
- static {
- StringBuilder builder = new StringBuilder(ZEROES.length());
- for (int i = 0; i < ZEROES.length(); i++) {
- builder.append((char) (ZEROES.charAt(i) + 9));
- }
- NINES = builder.toString();
- }
-
- /**
- * Determines whether a character is a digit according to
- * <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D">Unicode</a>.
- */
- public static final CharMatcher DIGIT = new RangesMatcher(
- "CharMatcher.DIGIT", ZEROES.toCharArray(), NINES.toCharArray());
-
- /**
- * Determines whether a character is a digit according to {@link Character#isDigit(char) Java's
- * definition}. If you only care to match ASCII digits, you can use {@code inRange('0', '9')}.
- */
- public static final CharMatcher JAVA_DIGIT = new CharMatcher("CharMatcher.JAVA_DIGIT") {
- @Override public boolean matches(char c) {
- return Character.isDigit(c);
- }
- };
-
- /**
- * Determines whether a character is a letter according to {@link Character#isLetter(char) Java's
- * definition}. If you only care to match letters of the Latin alphabet, you can use {@code
- * inRange('a', 'z').or(inRange('A', 'Z'))}.
- */
- public static final CharMatcher JAVA_LETTER = new CharMatcher("CharMatcher.JAVA_LETTER") {
- @Override public boolean matches(char c) {
- return Character.isLetter(c);
- }
- };
-
- /**
- * Determines whether a character is a letter or digit according to {@link
- * Character#isLetterOrDigit(char) Java's definition}.
- */
- public static final CharMatcher JAVA_LETTER_OR_DIGIT =
- new CharMatcher("CharMatcher.JAVA_LETTER_OR_DIGIT") {
- @Override public boolean matches(char c) {
- return Character.isLetterOrDigit(c);
- }
- };
-
- /**
- * Determines whether a character is upper case according to {@link Character#isUpperCase(char)
- * Java's definition}.
- */
- public static final CharMatcher JAVA_UPPER_CASE =
- new CharMatcher("CharMatcher.JAVA_UPPER_CASE") {
- @Override public boolean matches(char c) {
- return Character.isUpperCase(c);
- }
- };
-
- /**
- * Determines whether a character is lower case according to {@link Character#isLowerCase(char)
- * Java's definition}.
- */
- public static final CharMatcher JAVA_LOWER_CASE =
- new CharMatcher("CharMatcher.JAVA_LOWER_CASE") {
- @Override public boolean matches(char c) {
- return Character.isLowerCase(c);
- }
- };
-
- /**
- * Determines whether a character is an ISO control character as specified by {@link
- * Character#isISOControl(char)}.
- */
- public static final CharMatcher JAVA_ISO_CONTROL =
- inRange('\u0000', '\u001f')
- .or(inRange('\u007f', '\u009f'))
- .withToString("CharMatcher.JAVA_ISO_CONTROL");
-
- /**
- * Determines whether a character is invisible; that is, if its Unicode category is any of
- * SPACE_SEPARATOR, LINE_SEPARATOR, PARAGRAPH_SEPARATOR, CONTROL, FORMAT, SURROGATE, and
- * PRIVATE_USE according to ICU4J.
- */
- public static final CharMatcher INVISIBLE = new RangesMatcher("CharMatcher.INVISIBLE", (
- "\u0000\u007f\u00ad\u0600\u06dd\u070f\u1680\u180e\u2000\u2028\u205f\u206a\u3000\ud800\ufeff"
- + "\ufff9\ufffa").toCharArray(), (
- "\u0020\u00a0\u00ad\u0604\u06dd\u070f\u1680\u180e\u200f\u202f\u2064\u206f\u3000\uf8ff\ufeff"
- + "\ufff9\ufffb").toCharArray());
-
- private static String showCharacter(char c) {
- String hex = "0123456789ABCDEF";
- char[] tmp = {'\\', 'u', '\0', '\0', '\0', '\0'};
- for (int i = 0; i < 4; i++) {
- tmp[5 - i] = hex.charAt(c & 0xF);
- c >>= 4;
- }
- return String.copyValueOf(tmp);
-
- }
-
- /**
- * Determines whether a character is single-width (not double-width). When in doubt, this matcher
- * errs on the side of returning {@code false} (that is, it tends to assume a character is
- * double-width).
- *
- * <p><b>Note:</b> as the reference file evolves, we will modify this constant to keep it up to
- * date.
- */
- public static final CharMatcher SINGLE_WIDTH = new RangesMatcher("CharMatcher.SINGLE_WIDTH",
- "\u0000\u05be\u05d0\u05f3\u0600\u0750\u0e00\u1e00\u2100\ufb50\ufe70\uff61".toCharArray(),
- "\u04f9\u05be\u05ea\u05f4\u06ff\u077f\u0e7f\u20af\u213a\ufdff\ufeff\uffdc".toCharArray());
-
- /** Matches any character. */
- public static final CharMatcher ANY =
- new FastMatcher("CharMatcher.ANY") {
- @Override public boolean matches(char c) {
- return true;
- }
-
- @Override public int indexIn(CharSequence sequence) {
- return (sequence.length() == 0) ? -1 : 0;
- }
-
- @Override public int indexIn(CharSequence sequence, int start) {
- int length = sequence.length();
- Preconditions.checkPositionIndex(start, length);
- return (start == length) ? -1 : start;
- }
-
- @Override public int lastIndexIn(CharSequence sequence) {
- return sequence.length() - 1;
- }
-
- @Override public boolean matchesAllOf(CharSequence sequence) {
- checkNotNull(sequence);
- return true;
- }
-
- @Override public boolean matchesNoneOf(CharSequence sequence) {
- return sequence.length() == 0;
- }
-
- @Override public String removeFrom(CharSequence sequence) {
- checkNotNull(sequence);
- return "";
- }
-
- @Override public String replaceFrom(CharSequence sequence, char replacement) {
- char[] array = new char[sequence.length()];
- Arrays.fill(array, replacement);
- return new String(array);
- }
-
- @Override public String replaceFrom(CharSequence sequence, CharSequence replacement) {
- StringBuilder retval = new StringBuilder(sequence.length() * replacement.length());
- for (int i = 0; i < sequence.length(); i++) {
- retval.append(replacement);
- }
- return retval.toString();
- }
-
- @Override public String collapseFrom(CharSequence sequence, char replacement) {
- return (sequence.length() == 0) ? "" : String.valueOf(replacement);
- }
-
- @Override public String trimFrom(CharSequence sequence) {
- checkNotNull(sequence);
- return "";
- }
-
- @Override public int countIn(CharSequence sequence) {
- return sequence.length();
- }
-
- @Override public CharMatcher and(CharMatcher other) {
- return checkNotNull(other);
- }
-
- @Override public CharMatcher or(CharMatcher other) {
- checkNotNull(other);
- return this;
- }
-
- @Override public CharMatcher negate() {
- return NONE;
- }
- };
-
- /** Matches no characters. */
- public static final CharMatcher NONE =
- new FastMatcher("CharMatcher.NONE") {
- @Override public boolean matches(char c) {
- return false;
- }
-
- @Override public int indexIn(CharSequence sequence) {
- checkNotNull(sequence);
- return -1;
- }
-
- @Override public int indexIn(CharSequence sequence, int start) {
- int length = sequence.length();
- Preconditions.checkPositionIndex(start, length);
- return -1;
- }
-
- @Override public int lastIndexIn(CharSequence sequence) {
- checkNotNull(sequence);
- return -1;
- }
-
- @Override public boolean matchesAllOf(CharSequence sequence) {
- return sequence.length() == 0;
- }
-
- @Override public boolean matchesNoneOf(CharSequence sequence) {
- checkNotNull(sequence);
- return true;
- }
-
- @Override public String removeFrom(CharSequence sequence) {
- return sequence.toString();
- }
-
- @Override public String replaceFrom(CharSequence sequence, char replacement) {
- return sequence.toString();
- }
-
- @Override public String replaceFrom(CharSequence sequence, CharSequence replacement) {
- checkNotNull(replacement);
- return sequence.toString();
- }
-
- @Override public String collapseFrom(CharSequence sequence, char replacement) {
- return sequence.toString();
- }
-
- @Override public String trimFrom(CharSequence sequence) {
- return sequence.toString();
- }
-
- @Override
- public String trimLeadingFrom(CharSequence sequence) {
- return sequence.toString();
- }
-
- @Override
- public String trimTrailingFrom(CharSequence sequence) {
- return sequence.toString();
- }
-
- @Override public int countIn(CharSequence sequence) {
- checkNotNull(sequence);
- return 0;
- }
-
- @Override public CharMatcher and(CharMatcher other) {
- checkNotNull(other);
- return this;
- }
-
- @Override public CharMatcher or(CharMatcher other) {
- return checkNotNull(other);
- }
-
- @Override public CharMatcher negate() {
- return ANY;
- }
- };
-
- // Static factories
-
- /**
- * Returns a {@code char} matcher that matches only one specified character.
- */
- public static CharMatcher is(final char match) {
- String description = "CharMatcher.is('" + showCharacter(match) + "')";
- return new FastMatcher(description) {
- @Override public boolean matches(char c) {
- return c == match;
- }
-
- @Override public String replaceFrom(CharSequence sequence, char replacement) {
- return sequence.toString().replace(match, replacement);
- }
-
- @Override public CharMatcher and(CharMatcher other) {
- return other.matches(match) ? this : NONE;
- }
-
- @Override public CharMatcher or(CharMatcher other) {
- return other.matches(match) ? other : super.or(other);
- }
-
- @Override public CharMatcher negate() {
- return isNot(match);
- }
- };
- }
-
- /**
- * Returns a {@code char} matcher that matches any character except the one specified.
- *
- * <p>To negate another {@code CharMatcher}, use {@link #negate()}.
- */
- public static CharMatcher isNot(final char match) {
- String description = "CharMatcher.isNot(" + Integer.toHexString(match) + ")";
- return new FastMatcher(description) {
- @Override public boolean matches(char c) {
- return c != match;
- }
-
- @Override public CharMatcher and(CharMatcher other) {
- return other.matches(match) ? super.and(other) : other;
- }
-
- @Override public CharMatcher or(CharMatcher other) {
- return other.matches(match) ? ANY : this;
- }
-
- @Override public CharMatcher negate() {
- return is(match);
- }
- };
- }
-
- /**
- * Returns a {@code char} matcher that matches any character present in the given character
- * sequence.
- */
- public static CharMatcher anyOf(final CharSequence sequence) {
- switch (sequence.length()) {
- case 0:
- return NONE;
- case 1:
- return is(sequence.charAt(0));
- case 2:
- return isEither(sequence.charAt(0), sequence.charAt(1));
- default:
- // continue below to handle the general case
- }
- // TODO(user): is it potentially worth just going ahead and building a precomputed matcher?
- final char[] chars = sequence.toString().toCharArray();
- Arrays.sort(chars);
- StringBuilder description = new StringBuilder("CharMatcher.anyOf(\"");
- for (char c : chars) {
- description.append(showCharacter(c));
- }
- description.append("\")");
- return new CharMatcher(description.toString()) {
- @Override public boolean matches(char c) {
- return Arrays.binarySearch(chars, c) >= 0;
- }
- };
- }
-
- private static CharMatcher isEither(
- final char match1,
- final char match2) {
- String description = "CharMatcher.anyOf(\"" +
- showCharacter(match1) + showCharacter(match2) + "\")";
- return new FastMatcher(description) {
- @Override public boolean matches(char c) {
- return c == match1 || c == match2;
- }
- };
- }
-
- /**
- * Returns a {@code char} matcher that matches any character not present in the given character
- * sequence.
- */
- public static CharMatcher noneOf(CharSequence sequence) {
- return anyOf(sequence).negate();
- }
-
- /**
- * Returns a {@code char} matcher that matches any character in a given range (both endpoints are
- * inclusive). For example, to match any lowercase letter of the English alphabet, use {@code
- * CharMatcher.inRange('a', 'z')}.
- *
- * @throws IllegalArgumentException if {@code endInclusive < startInclusive}
- */
- public static CharMatcher inRange(final char startInclusive, final char endInclusive) {
- checkArgument(endInclusive >= startInclusive);
- String description = "CharMatcher.inRange('" +
- showCharacter(startInclusive) + "', '" +
- showCharacter(endInclusive) + "')";
- return inRange(startInclusive, endInclusive, description);
- }
-
- static CharMatcher inRange(final char startInclusive, final char endInclusive,
- String description) {
- return new FastMatcher(description) {
- @Override public boolean matches(char c) {
- return startInclusive <= c && c <= endInclusive;
- }
- };
- }
-
- /**
- * Returns a matcher with identical behavior to the given {@link Character}-based predicate, but
- * which operates on primitive {@code char} instances instead.
- */
- public static CharMatcher forPredicate(final Predicate<? super Character> predicate) {
- checkNotNull(predicate);
- if (predicate instanceof CharMatcher) {
- return (CharMatcher) predicate;
- }
- String description = "CharMatcher.forPredicate(" + predicate + ")";
- return new CharMatcher(description) {
- @Override public boolean matches(char c) {
- return predicate.apply(c);
- }
-
- @Override public boolean apply(Character character) {
- return predicate.apply(checkNotNull(character));
- }
- };
- }
-
- // State
- final String description;
-
- // Constructors
-
- /**
- * Sets the {@code toString()} from the given description.
- */
- CharMatcher(String description) {
- this.description = description;
- }
-
- /**
- * Constructor for use by subclasses. When subclassing, you may want to override
- * {@code toString()} to provide a useful description.
- */
- protected CharMatcher() {
- description = super.toString();
- }
-
- // Abstract methods
-
- /** Determines a true or false value for the given character. */
- public abstract boolean matches(char c);
-
- // Non-static factories
-
- /**
- * Returns a matcher that matches any character not matched by this matcher.
- */
- public CharMatcher negate() {
- return new NegatedMatcher(this);
- }
-
- private static class NegatedMatcher extends CharMatcher {
- final CharMatcher original;
-
- NegatedMatcher(String toString, CharMatcher original) {
- super(toString);
- this.original = original;
- }
-
- NegatedMatcher(CharMatcher original) {
- this(original + ".negate()", original);
- }
-
- @Override public boolean matches(char c) {
- return !original.matches(c);
- }
-
- @Override public boolean matchesAllOf(CharSequence sequence) {
- return original.matchesNoneOf(sequence);
- }
-
- @Override public boolean matchesNoneOf(CharSequence sequence) {
- return original.matchesAllOf(sequence);
- }
-
- @Override public int countIn(CharSequence sequence) {
- return sequence.length() - original.countIn(sequence);
- }
-
- @Override public CharMatcher negate() {
- return original;
- }
-
- @Override
- CharMatcher withToString(String description) {
- return new NegatedMatcher(description, original);
- }
- }
-
- /**
- * Returns a matcher that matches any character matched by both this matcher and {@code other}.
- */
- public CharMatcher and(CharMatcher other) {
- return new And(this, checkNotNull(other));
- }
-
- private static class And extends CharMatcher {
- final CharMatcher first;
- final CharMatcher second;
-
- And(CharMatcher a, CharMatcher b) {
- this(a, b, "CharMatcher.and(" + a + ", " + b + ")");
- }
-
- And(CharMatcher a, CharMatcher b, String description) {
- super(description);
- first = checkNotNull(a);
- second = checkNotNull(b);
- }
-
- @Override
- public boolean matches(char c) {
- return first.matches(c) && second.matches(c);
- }
-
- @Override
- CharMatcher withToString(String description) {
- return new And(first, second, description);
- }
- }
-
- /**
- * Returns a matcher that matches any character matched by either this matcher or {@code other}.
- */
- public CharMatcher or(CharMatcher other) {
- return new Or(this, checkNotNull(other));
- }
-
- private static class Or extends CharMatcher {
- final CharMatcher first;
- final CharMatcher second;
-
- Or(CharMatcher a, CharMatcher b, String description) {
- super(description);
- first = checkNotNull(a);
- second = checkNotNull(b);
- }
-
- Or(CharMatcher a, CharMatcher b) {
- this(a, b, "CharMatcher.or(" + a + ", " + b + ")");
- }
-
- @Override
- public boolean matches(char c) {
- return first.matches(c) || second.matches(c);
- }
-
- @Override
- CharMatcher withToString(String description) {
- return new Or(first, second, description);
- }
- }
-
- /**
- * Returns a {@code char} matcher functionally equivalent to this one, but which may be faster to
- * query than the original; your mileage may vary. Precomputation takes time and is likely to be
- * worthwhile only if the precomputed matcher is queried many thousands of times.
- *
- * <p>This method has no effect (returns {@code this}) when called in GWT: it's unclear whether a
- * precomputed matcher is faster, but it certainly consumes more memory, which doesn't seem like a
- * worthwhile tradeoff in a browser.
- */
- public CharMatcher precomputed() {
- return Platform.precomputeCharMatcher(this);
- }
-
- /**
- * Subclasses should provide a new CharMatcher with the same characteristics as {@code this},
- * but with their {@code toString} method overridden with the new description.
- *
- * <p>This is unsupported by default.
- */
- CharMatcher withToString(String description) {
- throw new UnsupportedOperationException();
- }
-
- private static final int DISTINCT_CHARS = Character.MAX_VALUE - Character.MIN_VALUE + 1;
-
- /**
- * A matcher for which precomputation will not yield any significant benefit.
- */
- abstract static class FastMatcher extends CharMatcher {
- FastMatcher() {
- super();
- }
-
- FastMatcher(String description) {
- super(description);
- }
-
- @Override
- public final CharMatcher precomputed() {
- return this;
- }
-
- @Override
- public CharMatcher negate() {
- return new NegatedFastMatcher(this);
- }
- }
-
- static final class NegatedFastMatcher extends NegatedMatcher {
- NegatedFastMatcher(CharMatcher original) {
- super(original);
- }
-
- NegatedFastMatcher(String toString, CharMatcher original) {
- super(toString, original);
- }
-
- @Override
- public final CharMatcher precomputed() {
- return this;
- }
-
- @Override
- CharMatcher withToString(String description) {
- return new NegatedFastMatcher(description, original);
- }
- }
-
- private static boolean isSmall(int totalCharacters, int tableLength) {
- return totalCharacters <= SmallCharMatcher.MAX_SIZE
- && tableLength > (totalCharacters * Character.SIZE);
- }
-
- // Text processing routines
-
- /**
- * Returns {@code true} if a character sequence contains at least one matching character.
- * Equivalent to {@code !matchesNoneOf(sequence)}.
- *
- * <p>The default implementation iterates over the sequence, invoking {@link #matches} for each
- * character, until this returns {@code true} or the end is reached.
- *
- * @param sequence the character sequence to examine, possibly empty
- * @return {@code true} if this matcher matches at least one character in the sequence
- * @since 8.0
- */
- public boolean matchesAnyOf(CharSequence sequence) {
- return !matchesNoneOf(sequence);
- }
-
- /**
- * Returns {@code true} if a character sequence contains only matching characters.
- *
- * <p>The default implementation iterates over the sequence, invoking {@link #matches} for each
- * character, until this returns {@code false} or the end is reached.
- *
- * @param sequence the character sequence to examine, possibly empty
- * @return {@code true} if this matcher matches every character in the sequence, including when
- * the sequence is empty
- */
- public boolean matchesAllOf(CharSequence sequence) {
- for (int i = sequence.length() - 1; i >= 0; i--) {
- if (!matches(sequence.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns {@code true} if a character sequence contains no matching characters. Equivalent to
- * {@code !matchesAnyOf(sequence)}.
- *
- * <p>The default implementation iterates over the sequence, invoking {@link #matches} for each
- * character, until this returns {@code false} or the end is reached.
- *
- * @param sequence the character sequence to examine, possibly empty
- * @return {@code true} if this matcher matches every character in the sequence, including when
- * the sequence is empty
- */
- public boolean matchesNoneOf(CharSequence sequence) {
- return indexIn(sequence) == -1;
- }
-
- /**
- * Returns the index of the first matching character in a character sequence, or {@code -1} if no
- * matching character is present.
- *
- * <p>The default implementation iterates over the sequence in forward order calling {@link
- * #matches} for each character.
- *
- * @param sequence the character sequence to examine from the beginning
- * @return an index, or {@code -1} if no character matches
- */
- public int indexIn(CharSequence sequence) {
- int length = sequence.length();
- for (int i = 0; i < length; i++) {
- if (matches(sequence.charAt(i))) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Returns the index of the first matching character in a character sequence, starting from a
- * given position, or {@code -1} if no character matches after that position.
- *
- * <p>The default implementation iterates over the sequence in forward order, beginning at {@code
- * start}, calling {@link #matches} for each character.
- *
- * @param sequence the character sequence to examine
- * @param start the first index to examine; must be nonnegative and no greater than {@code
- * sequence.length()}
- * @return the index of the first matching character, guaranteed to be no less than {@code start},
- * or {@code -1} if no character matches
- * @throws IndexOutOfBoundsException if start is negative or greater than {@code
- * sequence.length()}
- */
- public int indexIn(CharSequence sequence, int start) {
- int length = sequence.length();
- Preconditions.checkPositionIndex(start, length);
- for (int i = start; i < length; i++) {
- if (matches(sequence.charAt(i))) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Returns the index of the last matching character in a character sequence, or {@code -1} if no
- * matching character is present.
- *
- * <p>The default implementation iterates over the sequence in reverse order calling {@link
- * #matches} for each character.
- *
- * @param sequence the character sequence to examine from the end
- * @return an index, or {@code -1} if no character matches
- */
- public int lastIndexIn(CharSequence sequence) {
- for (int i = sequence.length() - 1; i >= 0; i--) {
- if (matches(sequence.charAt(i))) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Returns the number of matching characters found in a character sequence.
- */
- public int countIn(CharSequence sequence) {
- int count = 0;
- for (int i = 0; i < sequence.length(); i++) {
- if (matches(sequence.charAt(i))) {
- count++;
- }
- }
- return count;
- }
-
- /**
- * Returns a string containing all non-matching characters of a character sequence, in order. For
- * example: <pre> {@code
- *
- * CharMatcher.is('a').removeFrom("bazaar")}</pre>
- *
- * ... returns {@code "bzr"}.
- */
- @CheckReturnValue
- public String removeFrom(CharSequence sequence) {
- String string = sequence.toString();
- int pos = indexIn(string);
- if (pos == -1) {
- return string;
- }
-
- char[] chars = string.toCharArray();
- int spread = 1;
-
- // This unusual loop comes from extensive benchmarking
- OUT: while (true) {
- pos++;
- while (true) {
- if (pos == chars.length) {
- break OUT;
- }
- if (matches(chars[pos])) {
- break;
- }
- chars[pos - spread] = chars[pos];
- pos++;
- }
- spread++;
- }
- return new String(chars, 0, pos - spread);
- }
-
- /**
- * Returns a string containing all matching characters of a character sequence, in order. For
- * example: <pre> {@code
- *
- * CharMatcher.is('a').retainFrom("bazaar")}</pre>
- *
- * ... returns {@code "aaa"}.
- */
- @CheckReturnValue
- public String retainFrom(CharSequence sequence) {
- return negate().removeFrom(sequence);
- }
-
- /**
- * Returns a string copy of the input character sequence, with each character that matches this
- * matcher replaced by a given replacement character. For example: <pre> {@code
- *
- * CharMatcher.is('a').replaceFrom("radar", 'o')}</pre>
- *
- * ... returns {@code "rodor"}.
- *
- * <p>The default implementation uses {@link #indexIn(CharSequence)} to find the first matching
- * character, then iterates the remainder of the sequence calling {@link #matches(char)} for each
- * character.
- *
- * @param sequence the character sequence to replace matching characters in
- * @param replacement the character to append to the result string in place of each matching
- * character in {@code sequence}
- * @return the new string
- */
- @CheckReturnValue
- public String replaceFrom(CharSequence sequence, char replacement) {
- String string = sequence.toString();
- int pos = indexIn(string);
- if (pos == -1) {
- return string;
- }
- char[] chars = string.toCharArray();
- chars[pos] = replacement;
- for (int i = pos + 1; i < chars.length; i++) {
- if (matches(chars[i])) {
- chars[i] = replacement;
- }
- }
- return new String(chars);
- }
-
- /**
- * Returns a string copy of the input character sequence, with each character that matches this
- * matcher replaced by a given replacement sequence. For example: <pre> {@code
- *
- * CharMatcher.is('a').replaceFrom("yaha", "oo")}</pre>
- *
- * ... returns {@code "yoohoo"}.
- *
- * <p><b>Note:</b> If the replacement is a fixed string with only one character, you are better
- * off calling {@link #replaceFrom(CharSequence, char)} directly.
- *
- * @param sequence the character sequence to replace matching characters in
- * @param replacement the characters to append to the result string in place of each matching
- * character in {@code sequence}
- * @return the new string
- */
- @CheckReturnValue
- public String replaceFrom(CharSequence sequence, CharSequence replacement) {
- int replacementLen = replacement.length();
- if (replacementLen == 0) {
- return removeFrom(sequence);
- }
- if (replacementLen == 1) {
- return replaceFrom(sequence, replacement.charAt(0));
- }
-
- String string = sequence.toString();
- int pos = indexIn(string);
- if (pos == -1) {
- return string;
- }
-
- int len = string.length();
- StringBuilder buf = new StringBuilder((len * 3 / 2) + 16);
-
- int oldpos = 0;
- do {
- buf.append(string, oldpos, pos);
- buf.append(replacement);
- oldpos = pos + 1;
- pos = indexIn(string, oldpos);
- } while (pos != -1);
-
- buf.append(string, oldpos, len);
- return buf.toString();
- }
-
- /**
- * Returns a substring of the input character sequence that omits all characters this matcher
- * matches from the beginning and from the end of the string. For example: <pre> {@code
- *
- * CharMatcher.anyOf("ab").trimFrom("abacatbab")}</pre>
- *
- * ... returns {@code "cat"}.
- *
- * <p>Note that: <pre> {@code
- *
- * CharMatcher.inRange('\0', ' ').trimFrom(str)}</pre>
- *
- * ... is equivalent to {@link String#trim()}.
- */
- @CheckReturnValue
- public String trimFrom(CharSequence sequence) {
- int len = sequence.length();
- int first;
- int last;
-
- for (first = 0; first < len; first++) {
- if (!matches(sequence.charAt(first))) {
- break;
- }
- }
- for (last = len - 1; last > first; last--) {
- if (!matches(sequence.charAt(last))) {
- break;
- }
- }
-
- return sequence.subSequence(first, last + 1).toString();
- }
-
- /**
- * Returns a substring of the input character sequence that omits all characters this matcher
- * matches from the beginning of the string. For example: <pre> {@code
- *
- * CharMatcher.anyOf("ab").trimLeadingFrom("abacatbab")}</pre>
- *
- * ... returns {@code "catbab"}.
- */
- @CheckReturnValue
- public String trimLeadingFrom(CharSequence sequence) {
- int len = sequence.length();
- for (int first = 0; first < len; first++) {
- if (!matches(sequence.charAt(first))) {
- return sequence.subSequence(first, len).toString();
- }
- }
- return "";
- }
-
- /**
- * Returns a substring of the input character sequence that omits all characters this matcher
- * matches from the end of the string. For example: <pre> {@code
- *
- * CharMatcher.anyOf("ab").trimTrailingFrom("abacatbab")}</pre>
- *
- * ... returns {@code "abacat"}.
- */
- @CheckReturnValue
- public String trimTrailingFrom(CharSequence sequence) {
- int len = sequence.length();
- for (int last = len - 1; last >= 0; last--) {
- if (!matches(sequence.charAt(last))) {
- return sequence.subSequence(0, last + 1).toString();
- }
- }
- return "";
- }
-
- /**
- * Returns a string copy of the input character sequence, with each group of consecutive
- * characters that match this matcher replaced by a single replacement character. For example:
- * <pre> {@code
- *
- * CharMatcher.anyOf("eko").collapseFrom("bookkeeper", '-')}</pre>
- *
- * ... returns {@code "b-p-r"}.
- *
- * <p>The default implementation uses {@link #indexIn(CharSequence)} to find the first matching
- * character, then iterates the remainder of the sequence calling {@link #matches(char)} for each
- * character.
- *
- * @param sequence the character sequence to replace matching groups of characters in
- * @param replacement the character to append to the result string in place of each group of
- * matching characters in {@code sequence}
- * @return the new string
- */
- @CheckReturnValue
- public String collapseFrom(CharSequence sequence, char replacement) {
- // This implementation avoids unnecessary allocation.
- int len = sequence.length();
- for (int i = 0; i < len; i++) {
- char c = sequence.charAt(i);
- if (matches(c)) {
- if (c == replacement
- && (i == len - 1 || !matches(sequence.charAt(i + 1)))) {
- // a no-op replacement
- i++;
- } else {
- StringBuilder builder = new StringBuilder(len)
- .append(sequence.subSequence(0, i))
- .append(replacement);
- return finishCollapseFrom(sequence, i + 1, len, replacement, builder, true);
- }
- }
- }
- // no replacement needed
- return sequence.toString();
- }
-
- /**
- * Collapses groups of matching characters exactly as {@link #collapseFrom} does, except that
- * groups of matching characters at the start or end of the sequence are removed without
- * replacement.
- */
- @CheckReturnValue
- public String trimAndCollapseFrom(CharSequence sequence, char replacement) {
- // This implementation avoids unnecessary allocation.
- int len = sequence.length();
- int first;
- int last;
-
- for (first = 0; first < len && matches(sequence.charAt(first)); first++) {}
- for (last = len - 1; last > first && matches(sequence.charAt(last)); last--) {}
-
- return (first == 0 && last == len - 1)
- ? collapseFrom(sequence, replacement)
- : finishCollapseFrom(
- sequence, first, last + 1, replacement,
- new StringBuilder(last + 1 - first),
- false);
- }
-
- private String finishCollapseFrom(
- CharSequence sequence, int start, int end, char replacement,
- StringBuilder builder, boolean inMatchingGroup) {
- for (int i = start; i < end; i++) {
- char c = sequence.charAt(i);
- if (matches(c)) {
- if (!inMatchingGroup) {
- builder.append(replacement);
- inMatchingGroup = true;
- }
- } else {
- builder.append(c);
- inMatchingGroup = false;
- }
- }
- return builder.toString();
- }
-
- // Predicate interface
-
- /**
- * Equivalent to {@link #matches}; provided only to satisfy the {@link Predicate} interface. When
- * using a reference of type {@code CharMatcher}, invoke {@link #matches} directly instead.
- */
- @Override public boolean apply(Character character) {
- return matches(character);
- }
-
- /**
- * Returns a string representation of this {@code CharMatcher}, such as
- * {@code CharMatcher.or(WHITESPACE, JAVA_DIGIT)}.
- */
- @Override
- public String toString() {
- return description;
- }
-
- /**
- * A special-case CharMatcher for Unicode whitespace characters that is extremely
- * efficient both in space required and in time to check for matches.
- *
- * Implementation details.
- * It turns out that all current (early 2012) Unicode characters are unique modulo 79:
- * so we can construct a lookup table of exactly 79 entries, and just check the character code
- * mod 79, and see if that character is in the table.
- *
- * There is a 1 at the beginning of the table so that the null character is not listed
- * as whitespace.
- *
- * Other things we tried that did not prove to be beneficial, mostly due to speed concerns:
- *
- * * Binary search into the sorted list of characters, i.e., what
- * CharMatcher.anyOf() does</li>
- * * Perfect hash function into a table of size 26 (using an offset table and a special
- * Jenkins hash function)</li>
- * * Perfect-ish hash function that required two lookups into a single table of size 26.</li>
- * * Using a power-of-2 sized hash table (size 64) with linear probing.</li>
- *
- * --Christopher Swenson, February 2012.
- */
- private static final String WHITESPACE_TABLE = "\u0001\u0000\u00a0\u0000\u0000\u0000\u0000\u0000"
- + "\u0000\u0009\n\u000b\u000c\r\u0000\u0000\u2028\u2029\u0000\u0000\u0000\u0000\u0000\u202f"
- + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0020\u0000\u0000\u0000\u0000\u0000"
- + "\u0000\u0000\u0000\u0000\u0000\u3000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
- + "\u0000\u0000\u0085\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a"
- + "\u0000\u0000\u0000\u0000\u0000\u205f\u1680\u0000\u0000\u180e\u0000\u0000\u0000";
-
- /**
- * Determines whether a character is whitespace according to the latest Unicode standard, as
- * illustrated
- * <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bwhitespace%7D">here</a>.
- * This is not the same definition used by other Java APIs. (See a
- * <a href="http://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ">comparison of several
- * definitions of "whitespace"</a>.)
- *
- * <p><b>Note:</b> as the Unicode definition evolves, we will modify this constant to keep it up
- * to date.
- */
- public static final CharMatcher WHITESPACE = new FastMatcher("CharMatcher.WHITESPACE") {
-
- @Override public boolean matches(char c) {
- return WHITESPACE_TABLE.charAt(c % 79) == c;
- }
- };
-}
diff --git a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Charsets.java b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Charsets.java
deleted file mode 100644
index 4c080be..0000000
--- a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Charsets.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.nio.charset.Charset;
-
-/**
- * Contains constant definitions for the six standard {@link Charset} instances, which are
- * guaranteed to be supported by all Java platform implementations.
- *
- * <p>Assuming you're free to choose, note that <b>{@link #UTF_8} is widely preferred</b>.
- *
- * <p>See the Guava User Guide article on <a
- * href="http://code.google.com/p/guava-libraries/wiki/StringsExplained#Charsets">
- * {@code Charsets}</a>.
- *
- * @author Mike Bostock
- * @since 1.0
- */
-@GwtCompatible(emulated = true)
-public final class Charsets {
- private Charsets() {}
-
- /**
- * UTF-8: eight-bit UCS Transformation Format.
- */
- public static final Charset UTF_8 = Charset.forName("UTF-8");
-
- /*
- * Please do not add new Charset references to this class, unless those character encodings are
- * part of the set required to be supported by all Java platform implementations! Any Charsets
- * initialized here may cause unexpected delays when this class is loaded. See the Charset
- * Javadocs for the list of built-in character encodings.
- */
-}
-
diff --git a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Enums.java b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Enums.java
deleted file mode 100644
index 61dd6e1..0000000
--- a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Enums.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
-import java.io.Serializable;
-
-import javax.annotation.Nullable;
-
-/**
- * Utility methods for working with {@link Enum} instances.
- *
- * @author Steve McKay
- *
- * @since 9.0
- */
-@GwtCompatible(emulated = true)
-@Beta
-public final class Enums {
-
- private Enums() {}
-
- /**
- * Returns a {@link Function} that maps an {@link Enum} name to the associated
- * {@code Enum} constant. The {@code Function} will return {@code null} if the
- * {@code Enum} constant does not exist.
- *
- * @param enumClass the {@link Class} of the {@code Enum} declaring the
- * constant values.
- */
- public static <T extends Enum<T>> Function<String, T> valueOfFunction(Class<T> enumClass) {
- return new ValueOfFunction<T>(enumClass);
- }
-
- /**
- * A {@link Function} that maps an {@link Enum} name to the associated
- * constant, or {@code null} if the constant does not exist.
- */
- private static final class ValueOfFunction<T extends Enum<T>>
- implements Function<String, T>, Serializable {
-
- private final Class<T> enumClass;
-
- private ValueOfFunction(Class<T> enumClass) {
- this.enumClass = checkNotNull(enumClass);
- }
-
- @Override
- public T apply(String value) {
- try {
- return Enum.valueOf(enumClass, value);
- } catch (IllegalArgumentException e) {
- return null;
- }
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- return obj instanceof ValueOfFunction &&
- enumClass.equals(((ValueOfFunction) obj).enumClass);
- }
-
- @Override public int hashCode() {
- return enumClass.hashCode();
- }
-
- @Override public String toString() {
- return "Enums.valueOf(" + enumClass + ")";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns an optional enum constant for the given type, using {@link Enum#valueOf}. If the
- * constant does not exist, {@link Optional#absent} is returned. A common use case is for parsing
- * user input or falling back to a default enum constant. For example,
- * {@code Enums.getIfPresent(Country.class, countryInput).or(Country.DEFAULT);}
- *
- * @since 12.0
- */
- public static <T extends Enum<T>> Optional<T> getIfPresent(Class<T> enumClass, String value) {
- checkNotNull(enumClass);
- checkNotNull(value);
- try {
- return Optional.of(Enum.valueOf(enumClass, value));
- } catch (IllegalArgumentException iae) {
- return Optional.absent();
- }
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Predicates.java b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Predicates.java
index 04f088e..366ca0d 100644
--- a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Predicates.java
+++ b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Predicates.java
@@ -34,10 +34,6 @@ import javax.annotation.Nullable;
* <p>All methods returns serializable predicates as long as they're given
* serializable parameters.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the
- * use of {@code Predicate}</a>.
- *
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
@@ -230,7 +226,7 @@ public final class Predicates {
return o != null;
}
};
-
+
@SuppressWarnings("unchecked") // these Object predicates work for any T
<T> Predicate<T> withNarrowedType() {
return (Predicate<T>) this;
@@ -245,7 +241,7 @@ public final class Predicates {
this.predicate = checkNotNull(predicate);
}
@Override
- public boolean apply(@Nullable T t) {
+ public boolean apply(T t) {
return !predicate.apply(t);
}
@Override public int hashCode() {
@@ -274,8 +270,7 @@ public final class Predicates {
this.components = components;
}
@Override
- public boolean apply(@Nullable T t) {
- // Avoid using the Iterator to avoid generating garbage (issue 820).
+ public boolean apply(T t) {
for (int i = 0; i < components.size(); i++) {
if (!components.get(i).apply(t)) {
return false;
@@ -284,7 +279,7 @@ public final class Predicates {
return true;
}
@Override public int hashCode() {
- // add a random number to avoid collisions with OrPredicate
+ // 0x12472c2c is a random number to help avoid collisions with OrPredicate
return components.hashCode() + 0x12472c2c;
}
@Override public boolean equals(@Nullable Object obj) {
@@ -308,8 +303,7 @@ public final class Predicates {
this.components = components;
}
@Override
- public boolean apply(@Nullable T t) {
- // Avoid using the Iterator to avoid generating garbage (issue 820).
+ public boolean apply(T t) {
for (int i = 0; i < components.size(); i++) {
if (components.get(i).apply(t)) {
return true;
@@ -318,7 +312,7 @@ public final class Predicates {
return false;
}
@Override public int hashCode() {
- // add a random number to avoid collisions with AndPredicate
+ // 0x053c91cf is a random number to help avoid collisions with AndPredicate
return components.hashCode() + 0x053c91cf;
}
@Override public boolean equals(@Nullable Object obj) {
@@ -371,7 +365,7 @@ public final class Predicates {
}
@Override
- public boolean apply(@Nullable T t) {
+ public boolean apply(T t) {
try {
return target.contains(t);
} catch (NullPointerException e) {
@@ -411,7 +405,7 @@ public final class Predicates {
}
@Override
- public boolean apply(@Nullable A a) {
+ public boolean apply(A a) {
return p.apply(f.apply(a));
}
diff --git a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Splitter.java b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Splitter.java
index 458b5ad..142fbec 100644
--- a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Splitter.java
+++ b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Splitter.java
@@ -30,63 +30,60 @@ import java.util.Map;
import javax.annotation.CheckReturnValue;
/**
- * Extracts non-overlapping substrings from an input string, typically by
- * recognizing appearances of a <i>separator</i> sequence. This separator can be
- * specified as a single {@linkplain #on(char) character}, fixed {@linkplain
- * #on(String) string}, {@linkplain #onPattern regular expression} or {@link
- * #on(CharMatcher) CharMatcher} instance. Or, instead of using a separator at
- * all, a splitter can extract adjacent substrings of a given {@linkplain
- * #fixedLength fixed length}.
+ * An object that divides strings (or other instances of {@code CharSequence})
+ * into substrings, by recognizing a <i>separator</i> (a.k.a. "delimiter")
+ * which can be expressed as a single character, literal string, regular
+ * expression, {@code CharMatcher}, or by using a fixed substring length. This
+ * class provides the complementary functionality to {@link Joiner}.
*
- * <p>For example, this expression: <pre> {@code
+ * <p>Here is the most basic example of {@code Splitter} usage: <pre> {@code
*
- * Splitter.on(',').split("foo,bar,qux")}</pre>
+ * Splitter.on(',').split("foo,bar")}</pre>
*
- * ... produces an {@code Iterable} containing {@code "foo"}, {@code "bar"} and
- * {@code "qux"}, in that order.
+ * This invocation returns an {@code Iterable<String>} containing {@code "foo"}
+ * and {@code "bar"}, in that order.
*
- * <p>By default, {@code Splitter}'s behavior is simplistic and unassuming. The
- * following expression: <pre> {@code
+ * <p>By default {@code Splitter}'s behavior is very simplistic: <pre> {@code
*
- * Splitter.on(',').split(" foo,,, bar ,")}</pre>
+ * Splitter.on(',').split("foo,,bar, quux")}</pre>
*
- * ... yields the substrings {@code [" foo", "", "", " bar ", ""]}. If this
- * is not the desired behavior, use configuration methods to obtain a <i>new</i>
- * splitter instance with modified behavior: <pre> {@code
+ * This returns an iterable containing {@code ["foo", "", "bar", " quux"]}.
+ * Notice that the splitter does not assume that you want empty strings removed,
+ * or that you wish to trim whitespace. If you want features like these, simply
+ * ask for them: <pre> {@code
*
* private static final Splitter MY_SPLITTER = Splitter.on(',')
* .trimResults()
* .omitEmptyStrings();}</pre>
*
- * Now {@code MY_SPLITTER.split("foo,,, bar ,")} returns just {@code ["foo",
- * "bar"]}. Note that the order in which these configuration methods are called
- * is never significant.
+ * Now {@code MY_SPLITTER.split("foo, ,bar, quux,")} returns an iterable
+ * containing just {@code ["foo", "bar", "quux"]}. Note that the order in which
+ * the configuration methods are called is never significant; for instance,
+ * trimming is always applied first before checking for an empty result,
+ * regardless of the order in which the {@link #trimResults()} and
+ * {@link #omitEmptyStrings()} methods were invoked.
*
- * <p><b>Warning:</b> Splitter instances are immutable. Invoking a configuration
- * method has no effect on the receiving instance; you must store and use the
- * new splitter instance it returns instead. <pre> {@code
+ * <p><b>Warning: splitter instances are always immutable</b>; a configuration
+ * method such as {@code omitEmptyStrings} has no effect on the instance it
+ * is invoked on! You must store and use the new splitter instance returned by
+ * the method. This makes splitters thread-safe, and safe to store as {@code
+ * static final} constants (as illustrated above). <pre> {@code
*
- * // Do NOT do this
+ * // Bad! Do not do this!
* Splitter splitter = Splitter.on('/');
* splitter.trimResults(); // does nothing!
* return splitter.split("wrong / wrong / wrong");}</pre>
*
- * <p>For separator-based splitters that do not use {@code omitEmptyStrings}, an
- * input string containing {@code n} occurrences of the separator naturally
- * yields an iterable of size {@code n + 1}. So if the separator does not occur
- * anywhere in the input, a single substring is returned containing the entire
- * input. Consequently, all splitters split the empty string to {@code [""]}
- * (note: even fixed-length splitters).
+ * The separator recognized by the splitter does not have to be a single
+ * literal character as in the examples above. See the methods {@link
+ * #on(String)}, {@link #on(Pattern)} and {@link #on(CharMatcher)} for examples
+ * of other ways to specify separators.
*
- * <p>Splitter instances are thread-safe immutable, and are therefore safe to
- * store as {@code static final} constants.
- *
- * <p>The {@link Joiner} class provides the inverse operation to splitting, but
- * note that a round-trip between the two should be assumed to be lossy.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#Splitter">
- * {@code Splitter}</a>.
+ * <p><b>Note:</b> this class does not mimic any of the quirky behaviors of
+ * similar JDK methods; for instance, it does not silently discard trailing
+ * separators, as does {@link String#split(String)}, nor does it have a default
+ * behavior of using five particular whitespace characters as separators, like
+ * {@link java.util.StringTokenizer}.
*
* @author Julien Silland
* @author Jesse Wilson
@@ -156,8 +153,8 @@ public final class Splitter {
/**
* Returns a splitter that uses the given fixed string as a separator. For
- * example, {@code Splitter.on(", ").split("foo, bar,baz")} returns an
- * iterable containing {@code ["foo", "bar,baz"]}.
+ * example, {@code Splitter.on(", ").split("foo, bar, baz,qux")} returns an
+ * iterable containing {@code ["foo", "bar", "baz,qux"]}.
*
* @param separator the literal, nonempty string to recognize as a separator
* @return a splitter, with default settings, that recognizes that separator
@@ -200,18 +197,9 @@ public final class Splitter {
* iterable containing {@code ["ab", "cd", "e"]}. The last piece can be
* smaller than {@code length} but will never be empty.
*
- * <p><b>Exception:</b> for consistency with separator-based splitters, {@code
- * split("")} does not yield an empty iterable, but an iterable containing
- * {@code ""}. This is the only case in which {@code
- * Iterables.size(split(input))} does not equal {@code
- * IntMath.divide(input.length(), length, CEILING)}. To avoid this behavior,
- * use {@code omitEmptyStrings}.
- *
- * @param length the desired length of pieces after splitting, a positive
- * integer
+ * @param length the desired length of pieces after splitting
* @return a splitter, with default settings, that can split into fixed sized
* pieces
- * @throws IllegalArgumentException if {@code length} is zero or negative
*/
public static Splitter fixedLength(final int length) {
checkArgument(length > 0, "The length may not be less than 1");
@@ -328,12 +316,6 @@ public final class Splitter {
@Override public Iterator<String> iterator() {
return spliterator(sequence);
}
- @Override public String toString() {
- return Joiner.on(", ")
- .appendTo(new StringBuilder().append('['), this)
- .append(']')
- .toString();
- }
};
}
@@ -355,18 +337,6 @@ public final class Splitter {
/**
* Returns a {@code MapSplitter} which splits entries based on this splitter,
- * and splits entries into keys and values using the specified separator.
- *
- * @since 14.0
- */
- @CheckReturnValue
- @Beta
- public MapSplitter withKeyValueSeparator(char separator) {
- return withKeyValueSeparator(on(separator));
- }
-
- /**
- * Returns a {@code MapSplitter} which splits entries based on this splitter,
* and splits entries into keys and values using the specified key-value
* splitter.
*
@@ -435,7 +405,8 @@ public final class Splitter {
Iterator<String> iterator(Splitter splitter, CharSequence toSplit);
}
- private abstract static class SplittingIterator extends AbstractIterator<String> {
+ private abstract static class SplittingIterator
+ extends AbstractIterator<String> {
final CharSequence toSplit;
final CharMatcher trimmer;
final boolean omitEmptyStrings;
@@ -464,15 +435,8 @@ public final class Splitter {
}
@Override protected String computeNext() {
- /*
- * The returned string will be from the end of the last match to the
- * beginning of the next one. nextStart is the start position of the
- * returned substring, while offset is the place to start looking for a
- * separator.
- */
- int nextStart = offset;
while (offset != -1) {
- int start = nextStart;
+ int start = offset;
int end;
int separatorPosition = separatorStart(offset);
@@ -483,20 +447,6 @@ public final class Splitter {
end = separatorPosition;
offset = separatorEnd(separatorPosition);
}
- if (offset == nextStart) {
- /*
- * This occurs when some pattern has an empty match, even if it
- * doesn't match the empty string -- for example, if it requires
- * lookahead or the like. The offset must be increased to look for
- * separators beyond this point, without changing the start position
- * of the next returned substring -- so nextStart stays the same.
- */
- offset++;
- if (offset >= toSplit.length()) {
- offset = -1;
- }
- continue;
- }
while (start < end && trimmer.matches(toSplit.charAt(start))) {
start++;
@@ -506,8 +456,6 @@ public final class Splitter {
}
if (omitEmptyStrings && start == end) {
- // Don't include the (unused) separator in next split string.
- nextStart = offset;
continue;
}
diff --git a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Stopwatch.java b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Stopwatch.java
index d591f62..841362a 100644
--- a/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Stopwatch.java
+++ b/guava-gwt/src-super/com/google/common/base/super/com/google/common/base/Stopwatch.java
@@ -49,7 +49,7 @@ import java.util.concurrent.TimeUnit;
* doSomething();
* stopwatch.{@link #stop stop}(); // optional
*
- * long millis = stopwatch.elapsed(MILLISECONDS);
+ * long millis = stopwatch.{@link #elapsedMillis elapsedMillis}();
*
* log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
* </pre>
@@ -68,7 +68,7 @@ import java.util.concurrent.TimeUnit;
* @since 10.0
*/
@Beta
-@GwtCompatible(emulated = true)
+@GwtCompatible(emulated=true)
public final class Stopwatch {
private final Ticker ticker;
private boolean isRunning;
@@ -88,7 +88,7 @@ public final class Stopwatch {
* source.
*/
public Stopwatch(Ticker ticker) {
- this.ticker = checkNotNull(ticker, "ticker");
+ this.ticker = checkNotNull(ticker);
}
/**
@@ -107,8 +107,7 @@ public final class Stopwatch {
* @throws IllegalStateException if the stopwatch is already running.
*/
public Stopwatch start() {
- checkState(!isRunning,
- "This stopwatch is already running; it cannot be started more than once.");
+ checkState(!isRunning);
isRunning = true;
startTick = ticker.read();
return this;
@@ -123,8 +122,7 @@ public final class Stopwatch {
*/
public Stopwatch stop() {
long tick = ticker.read();
- checkState(isRunning,
- "This stopwatch is already stopped; it cannot be stopped more than once.");
+ checkState(isRunning);
isRunning = false;
elapsedNanos += tick - startTick;
return this;
@@ -153,40 +151,18 @@ public final class Stopwatch {
* <p>Note that the overhead of measurement can be more than a microsecond, so
* it is generally not useful to specify {@link TimeUnit#NANOSECONDS}
* precision here.
- *
- * @since 14.0 (since 10.0 as {@code elapsedTime()})
*/
- public long elapsed(TimeUnit desiredUnit) {
- return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
- }
-
- /**
- * Returns the current elapsed time shown on this stopwatch, expressed
- * in the desired time unit, with any fraction rounded down.
- *
- * <p>Note that the overhead of measurement can be more than a microsecond, so
- * it is generally not useful to specify {@link TimeUnit#NANOSECONDS}
- * precision here.
- *
- * @deprecated Use {@link Stopwatch#elapsed(TimeUnit)} instead. This method is
- * scheduled to be removed in Guava release 16.0.
- */
- @Deprecated
public long elapsedTime(TimeUnit desiredUnit) {
- return elapsed(desiredUnit);
+ return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
}
/**
* Returns the current elapsed time shown on this stopwatch, expressed
* in milliseconds, with any fraction rounded down. This is identical to
- * {@code elapsed(TimeUnit.MILLISECONDS)}.
- *
- * @deprecated Use {@code stopwatch.elapsed(MILLISECONDS)} instead. This
- * method is scheduled to be removed in Guava release 16.0.
+ * {@code elapsedTime(TimeUnit.MILLISECONDS}.
*/
- @Deprecated
public long elapsedMillis() {
- return elapsed(MILLISECONDS);
+ return elapsedTime(MILLISECONDS);
}
private static TimeUnit chooseUnit(long nanos) {
diff --git a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheBuilder.java b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheBuilder.java
index 8b01a0e..4c30815 100644
--- a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheBuilder.java
+++ b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2011 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,251 +16,48 @@
package com.google.common.cache;
-import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Ascii;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Objects;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.base.Ticker;
-import com.google.common.cache.AbstractCache.SimpleStatsCounter;
-import com.google.common.cache.AbstractCache.StatsCounter;
-import com.google.common.cache.LocalCache.Strength;
-
+import com.google.common.base.Function;
+import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ExecutionError;
+import com.google.common.util.concurrent.UncheckedExecutionException;
+import com.google.gwt.user.client.Timer;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.annotation.CheckReturnValue;
+import javax.annotation.Nullable;
/**
- * <p>A builder of {@link LoadingCache} and {@link Cache} instances having any combination of the
- * following features:
- *
- * <ul>
- * <li>automatic loading of entries into the cache
- * <li>least-recently-used eviction when a maximum size is exceeded
- * <li>time-based expiration of entries, measured since last access or last write
- * <li>keys automatically wrapped in {@linkplain WeakReference weak} references
- * <li>values automatically wrapped in {@linkplain WeakReference weak} or
- * {@linkplain SoftReference soft} references
- * <li>notification of evicted (or otherwise removed) entries
- * <li>accumulation of cache access statistics
- * </ul>
- *
- * These features are all optional; caches can be created using all or none of them. By default
- * cache instances created by {@code CacheBuilder} will not perform any type of eviction.
- *
- * <p>Usage example: <pre> {@code
- *
- * LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
- * .maximumSize(10000)
- * .expireAfterWrite(10, TimeUnit.MINUTES)
- * .removalListener(MY_LISTENER)
- * .build(
- * new CacheLoader<Key, Graph>() {
- * public Graph load(Key key) throws AnyException {
- * return createExpensiveGraph(key);
- * }
- * });}</pre>
- *
- * Or equivalently, <pre> {@code
- *
- * // In real life this would come from a command-line flag or config file
- * String spec = "maximumSize=10000,expireAfterWrite=10m";
- *
- * LoadingCache<Key, Graph> graphs = CacheBuilder.from(spec)
- * .removalListener(MY_LISTENER)
- * .build(
- * new CacheLoader<Key, Graph>() {
- * public Graph load(Key key) throws AnyException {
- * return createExpensiveGraph(key);
- * }
- * });}</pre>
- *
- * <p>The returned cache is implemented as a hash table with similar performance characteristics to
- * {@link ConcurrentHashMap}. It implements all optional operations of the {@link LoadingCache} and
- * {@link Cache} interfaces. The {@code asMap} view (and its collection views) have <i>weakly
- * consistent iterators</i>. This means that they are safe for concurrent use, but if other threads
- * modify the cache after the iterator is created, it is undefined which of these changes, if any,
- * are reflected in that iterator. These iterators never throw {@link
- * ConcurrentModificationException}.
- *
- * <p><b>Note:</b> by default, the returned cache uses equality comparisons (the
- * {@link Object#equals equals} method) to determine equality for keys or values. However, if
- * {@link #weakKeys} was specified, the cache uses identity ({@code ==})
- * comparisons instead for keys. Likewise, if {@link #weakValues} or {@link #softValues} was
- * specified, the cache uses identity comparisons for values.
+ * CacheBuilder emulation.
*
- * <p>Entries are automatically evicted from the cache when any of
- * {@linkplain #maximumSize(long) maximumSize}, {@linkplain #maximumWeight(long) maximumWeight},
- * {@linkplain #expireAfterWrite expireAfterWrite},
- * {@linkplain #expireAfterAccess expireAfterAccess}, {@linkplain #weakKeys weakKeys},
- * {@linkplain #weakValues weakValues}, or {@linkplain #softValues softValues} are requested.
- *
- * <p>If {@linkplain #maximumSize(long) maximumSize} or
- * {@linkplain #maximumWeight(long) maximumWeight} is requested entries may be evicted on each cache
- * modification.
- *
- * <p>If {@linkplain #expireAfterWrite expireAfterWrite} or
- * {@linkplain #expireAfterAccess expireAfterAccess} is requested entries may be evicted on each
- * cache modification, on occasional cache accesses, or on calls to {@link Cache#cleanUp}. Expired
- * entries may be counted in {@link Cache#size}, but will never be visible to read or write
- * operations.
- *
- * <p>If {@linkplain #weakKeys weakKeys}, {@linkplain #weakValues weakValues}, or
- * {@linkplain #softValues softValues} are requested, it is possible for a key or value present in
- * the cache to be reclaimed by the garbage collector. Entries with reclaimed keys or values may be
- * removed from the cache on each cache modification, on occasional cache accesses, or on calls to
- * {@link Cache#cleanUp}; such entries may be counted in {@link Cache#size}, but will never be
- * visible to read or write operations.
- *
- * <p>Certain cache configurations will result in the accrual of periodic maintenance tasks which
- * will be performed during write operations, or during occasional read operations in the absense of
- * writes. The {@link Cache#cleanUp} method of the returned cache will also perform maintenance, but
- * calling it should not be necessary with a high throughput cache. Only caches built with
- * {@linkplain #removalListener removalListener}, {@linkplain #expireAfterWrite expireAfterWrite},
- * {@linkplain #expireAfterAccess expireAfterAccess}, {@linkplain #weakKeys weakKeys},
- * {@linkplain #weakValues weakValues}, or {@linkplain #softValues softValues} perform periodic
- * maintenance.
- *
- * <p>The caches produced by {@code CacheBuilder} are serializable, and the deserialized caches
- * retain all the configuration properties of the original cache. Note that the serialized form does
- * <i>not</i> include cache contents, but only configuration.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CachesExplained">caching</a> for a higher-level
- * explanation.
- *
- * @param <K> the base key type for all caches created by this builder
- * @param <V> the base value type for all caches created by this builder
* @author Charles Fry
- * @author Kevin Bourrillion
- * @since 10.0
*/
-@GwtCompatible(emulated = true)
-public final class CacheBuilder<K, V> {
+// TODO(fry): eventually we should emmulate LocalCache instead of CacheBuilder
+public class CacheBuilder<K, V> {
+ private static final int UNSET_INT = -1;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
- private static final int DEFAULT_CONCURRENCY_LEVEL = 4;
private static final int DEFAULT_EXPIRATION_NANOS = 0;
- private static final int DEFAULT_REFRESH_NANOS = 0;
-
- static final Supplier<? extends StatsCounter> NULL_STATS_COUNTER = Suppliers.ofInstance(
- new StatsCounter() {
- @Override
- public void recordHits(int count) {}
- @Override
- public void recordMisses(int count) {}
-
- @Override
- public void recordLoadSuccess(long loadTime) {}
-
- @Override
- public void recordLoadException(long loadTime) {}
-
- @Override
- public void recordEviction() {}
-
- @Override
- public CacheStats snapshot() {
- return EMPTY_STATS;
- }
- });
- static final CacheStats EMPTY_STATS = new CacheStats(0, 0, 0, 0, 0, 0);
+ private int initialCapacity = -1;
+ private int concurrencyLevel = -1;
+ private long expirationMillis = -1;
+ private int maximumSize = -1;
- static final Supplier<StatsCounter> CACHE_STATS_COUNTER =
- new Supplier<StatsCounter>() {
- @Override
- public StatsCounter get() {
- return new SimpleStatsCounter();
- }
- };
-
- enum NullListener implements RemovalListener<Object, Object> {
- INSTANCE;
-
- @Override
- public void onRemoval(RemovalNotification<Object, Object> notification) {}
- }
-
- enum OneWeigher implements Weigher<Object, Object> {
- INSTANCE;
-
- @Override
- public int weigh(Object key, Object value) {
- return 1;
- }
- }
-
- static final Ticker NULL_TICKER = new Ticker() {
- @Override
- public long read() {
- return 0;
- }
- };
-
- private static final Logger logger = Logger.getLogger(CacheBuilder.class.getName());
-
- static final int UNSET_INT = -1;
-
- boolean strictParsing = true;
-
- int initialCapacity = UNSET_INT;
- int concurrencyLevel = UNSET_INT;
- long maximumSize = UNSET_INT;
- long maximumWeight = UNSET_INT;
- Weigher<? super K, ? super V> weigher;
-
- Strength keyStrength;
- Strength valueStrength;
-
- long expireAfterWriteNanos = UNSET_INT;
- long expireAfterAccessNanos = UNSET_INT;
- long refreshNanos = UNSET_INT;
-
- Equivalence<Object> keyEquivalence;
- Equivalence<Object> valueEquivalence;
-
- RemovalListener<? super K, ? super V> removalListener;
- Ticker ticker;
-
- Supplier<? extends StatsCounter> statsCounterSupplier = NULL_STATS_COUNTER;
-
- // TODO(fry): make constructor private and update tests to use newBuilder
CacheBuilder() {}
- /**
- * Constructs a new {@code CacheBuilder} instance with default settings, including strong keys,
- * strong values, and no automatic eviction of any kind.
- */
public static CacheBuilder<Object, Object> newBuilder() {
return new CacheBuilder<Object, Object>();
}
- Equivalence<Object> getKeyEquivalence() {
- return firstNonNull(keyEquivalence, getKeyStrength().defaultEquivalence());
- }
-
- Equivalence<Object> getValueEquivalence() {
- return firstNonNull(valueEquivalence, getValueStrength().defaultEquivalence());
- }
-
- /**
- * Sets the minimum total size for the internal hash tables. For example, if the initial capacity
- * is {@code 60}, and the concurrency level is {@code 8}, then eight segments are created, each
- * having a hash table of size eight. Providing a large enough estimate at construction time
- * avoids the need for expensive resizing operations later, but setting this value unnecessarily
- * high wastes memory.
- *
- * @throws IllegalArgumentException if {@code initialCapacity} is negative
- * @throws IllegalStateException if an initial capacity was already set
- */
public CacheBuilder<K, V> initialCapacity(int initialCapacity) {
checkState(this.initialCapacity == UNSET_INT, "initial capacity was already set to %s",
this.initialCapacity);
@@ -269,354 +66,258 @@ public final class CacheBuilder<K, V> {
return this;
}
- int getInitialCapacity() {
+ private int getInitialCapacity() {
return (initialCapacity == UNSET_INT) ? DEFAULT_INITIAL_CAPACITY : initialCapacity;
}
- /**
- * Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The
- * table is internally partitioned to try to permit the indicated number of concurrent updates
- * without contention. Because assignment of entries to these partitions is not necessarily
- * uniform, the actual concurrency observed may vary. Ideally, you should choose a value to
- * accommodate as many threads as will ever concurrently modify the table. Using a significantly
- * higher value than you need can waste space and time, and a significantly lower value can lead
- * to thread contention. But overestimates and underestimates within an order of magnitude do not
- * usually have much noticeable impact. A value of one permits only one thread to modify the cache
- * at a time, but since read operations and cache loading computations can proceed concurrently,
- * this still yields higher concurrency than full synchronization.
- *
- * <p> Defaults to 4. <b>Note:</b>The default may change in the future. If you care about this
- * value, you should always choose it explicitly.
- *
- * <p>The current implementation uses the concurrency level to create a fixed number of hashtable
- * segments, each governed by its own write lock. The segment lock is taken once for each explicit
- * write, and twice for each cache loading computation (once prior to loading the new value,
- * and once after loading completes). Much internal cache management is performed at the segment
- * granularity. For example, access queues and write queues are kept per segment when they are
- * required by the selected eviction algorithm. As such, when writing unit tests it is not
- * uncommon to specify {@code concurrencyLevel(1)} in order to achieve more deterministic eviction
- * behavior.
- *
- * <p>Note that future implementations may abandon segment locking in favor of more advanced
- * concurrency controls.
- *
- * @throws IllegalArgumentException if {@code concurrencyLevel} is nonpositive
- * @throws IllegalStateException if a concurrency level was already set
- */
public CacheBuilder<K, V> concurrencyLevel(int concurrencyLevel) {
checkState(this.concurrencyLevel == UNSET_INT, "concurrency level was already set to %s",
this.concurrencyLevel);
checkArgument(concurrencyLevel > 0);
+ // GWT technically only supports concurrencyLevel == 1, but we silently
+ // ignore other positive values.
this.concurrencyLevel = concurrencyLevel;
return this;
}
- int getConcurrencyLevel() {
- return (concurrencyLevel == UNSET_INT) ? DEFAULT_CONCURRENCY_LEVEL : concurrencyLevel;
+ public CacheBuilder<K, V> expireAfterWrite(long duration, TimeUnit unit) {
+ checkState(expirationMillis == UNSET_INT, "expireAfterWrite was already set to %s ms",
+ expirationMillis);
+ checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit);
+ this.expirationMillis = unit.toMillis(duration);
+ return this;
}
- /**
- * Specifies the maximum number of entries the cache may contain. Note that the cache <b>may evict
- * an entry before this limit is exceeded</b>. As the cache size grows close to the maximum, the
- * cache evicts entries that are less likely to be used again. For example, the cache may evict an
- * entry because it hasn't been used recently or very often.
- *
- * <p>When {@code size} is zero, elements will be evicted immediately after being loaded into the
- * cache. This can be useful in testing, or to disable caching temporarily without a code change.
- *
- * <p>This feature cannot be used in conjunction with {@link #maximumWeight}.
- *
- * @param size the maximum size of the cache
- * @throws IllegalArgumentException if {@code size} is negative
- * @throws IllegalStateException if a maximum size or weight was already set
- */
- public CacheBuilder<K, V> maximumSize(long size) {
- checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s",
- this.maximumSize);
- checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s",
- this.maximumWeight);
- checkState(this.weigher == null, "maximum size can not be combined with weigher");
- checkArgument(size >= 0, "maximum size must not be negative");
- this.maximumSize = size;
- return this;
+ private long getExpirationMillis() {
+ return (expirationMillis == UNSET_INT) ? DEFAULT_EXPIRATION_NANOS : expirationMillis;
}
- long getMaximumWeight() {
- if (expireAfterWriteNanos == 0 || expireAfterAccessNanos == 0) {
- return 0;
+ public CacheBuilder<K, V> maximumSize(int maximumSize) {
+ if (this.maximumSize != -1) {
+ throw new IllegalStateException("maximum size of " + maximumSize + " was already set");
+ }
+ if (maximumSize < 0) {
+ throw new IllegalArgumentException("invalid maximum size: " + maximumSize);
}
- return (weigher == null) ? maximumSize : maximumWeight;
+ this.maximumSize = maximumSize;
+ return this;
}
- // Make a safe contravariant cast now so we don't have to do it over and over.
- @SuppressWarnings("unchecked")
- <K1 extends K, V1 extends V> Weigher<K1, V1> getWeigher() {
- return (Weigher<K1, V1>) Objects.firstNonNull(weigher, OneWeigher.INSTANCE);
+ public <K1 extends K, V1 extends V> Cache<K1, V1> build() {
+ return new LocalManualCache<K1, V1>(this);
}
- CacheBuilder<K, V> setKeyStrength(Strength strength) {
- checkState(keyStrength == null, "Key strength was already set to %s", keyStrength);
- keyStrength = checkNotNull(strength);
- return this;
+ public <K1 extends K, V1 extends V> LoadingCache<K1, V1> build(
+ CacheLoader<? super K1, V1> loader) {
+ return new LocalLoadingCache<K1, V1>(this, loader);
}
- Strength getKeyStrength() {
- return firstNonNull(keyStrength, Strength.STRONG);
- }
+ private static class LocalManualCache<K, V>
+ extends AbstractCache<K, V> implements Function<K, V> {
+ final LocalCache<K, V> localCache;
- CacheBuilder<K, V> setValueStrength(Strength strength) {
- checkState(valueStrength == null, "Value strength was already set to %s", valueStrength);
- valueStrength = checkNotNull(strength);
- return this;
- }
+ LocalManualCache(CacheBuilder<? super K, ? super V> builder) {
+ this(builder, null);
+ }
- Strength getValueStrength() {
- return firstNonNull(valueStrength, Strength.STRONG);
- }
+ protected LocalManualCache(CacheBuilder<? super K, ? super V> builder,
+ CacheLoader<? super K, V> loader) {
+ this.localCache = new LocalCache<K, V>(builder, loader);
+ }
- /**
- * Specifies that each entry should be automatically removed from the cache once a fixed duration
- * has elapsed after the entry's creation, or the most recent replacement of its value.
- *
- * <p>When {@code duration} is zero, this method hands off to
- * {@link #maximumSize(long) maximumSize}{@code (0)}, ignoring any otherwise-specificed maximum
- * size or weight. This can be useful in testing, or to disable caching temporarily without a code
- * change.
- *
- * <p>Expired entries may be counted in {@link Cache#size}, but will never be visible to read or
- * write operations. Expired entries are cleaned up as part of the routine maintenance described
- * in the class javadoc.
- *
- * @param duration the length of time after an entry is created that it should be automatically
- * removed
- * @param unit the unit that {@code duration} is expressed in
- * @throws IllegalArgumentException if {@code duration} is negative
- * @throws IllegalStateException if the time to live or time to idle was already set
- */
- public CacheBuilder<K, V> expireAfterWrite(long duration, TimeUnit unit) {
- checkState(expireAfterWriteNanos == UNSET_INT, "expireAfterWrite was already set to %s ns",
- expireAfterWriteNanos);
- checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit);
- this.expireAfterWriteNanos = unit.toNanos(duration);
- return this;
- }
+ // Cache methods
- long getExpireAfterWriteNanos() {
- return (expireAfterWriteNanos == UNSET_INT) ? DEFAULT_EXPIRATION_NANOS : expireAfterWriteNanos;
- }
+ @Override
+ public V get(K key) throws ExecutionException {
+ return localCache.getOrLoad(key);
+ }
- /**
- * Specifies that each entry should be automatically removed from the cache once a fixed duration
- * has elapsed after the entry's creation, the most recent replacement of its value, or its last
- * access. Access time is reset by all cache read and write operations (including
- * {@code Cache.asMap().get(Object)} and {@code Cache.asMap().put(K, V)}), but not by operations
- * on the collection-views of {@link Cache#asMap}.
- *
- * <p>When {@code duration} is zero, this method hands off to
- * {@link #maximumSize(long) maximumSize}{@code (0)}, ignoring any otherwise-specificed maximum
- * size or weight. This can be useful in testing, or to disable caching temporarily without a code
- * change.
- *
- * <p>Expired entries may be counted in {@link Cache#size}, but will never be visible to read or
- * write operations. Expired entries are cleaned up as part of the routine maintenance described
- * in the class javadoc.
- *
- * @param duration the length of time after an entry is last accessed that it should be
- * automatically removed
- * @param unit the unit that {@code duration} is expressed in
- * @throws IllegalArgumentException if {@code duration} is negative
- * @throws IllegalStateException if the time to idle or time to live was already set
- */
- public CacheBuilder<K, V> expireAfterAccess(long duration, TimeUnit unit) {
- checkState(expireAfterAccessNanos == UNSET_INT, "expireAfterAccess was already set to %s ns",
- expireAfterAccessNanos);
- checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit);
- this.expireAfterAccessNanos = unit.toNanos(duration);
- return this;
- }
+ @Override
+ public V getUnchecked(K key) {
+ try {
+ return get(key);
+ } catch (ExecutionException e) {
+ throw new UncheckedExecutionException(e.getCause());
+ }
+ }
- long getExpireAfterAccessNanos() {
- return (expireAfterAccessNanos == UNSET_INT)
- ? DEFAULT_EXPIRATION_NANOS : expireAfterAccessNanos;
- }
+ @Override
+ public final V apply(K key) {
+ return getUnchecked(key);
+ }
- long getRefreshNanos() {
- return (refreshNanos == UNSET_INT) ? DEFAULT_REFRESH_NANOS : refreshNanos;
- }
+ @Override
+ @Nullable
+ public V getIfPresent(K key) {
+ return localCache.get(key);
+ }
- /**
- * Specifies a nanosecond-precision time source for use in determining when entries should be
- * expired. By default, {@link System#nanoTime} is used.
- *
- * <p>The primary intent of this method is to facilitate testing of caches which have been
- * configured with {@link #expireAfterWrite} or {@link #expireAfterAccess}.
- *
- * @throws IllegalStateException if a ticker was already set
- */
- public CacheBuilder<K, V> ticker(Ticker ticker) {
- checkState(this.ticker == null);
- this.ticker = checkNotNull(ticker);
- return this;
- }
+ @Override
+ public void put(K key, V value) {
+ localCache.put(key, value);
+ }
- Ticker getTicker(boolean recordsTime) {
- if (ticker != null) {
- return ticker;
+ @Override
+ public void invalidate(Object key) {
+ checkNotNull(key);
+ localCache.remove(key);
}
- return recordsTime ? Ticker.systemTicker() : NULL_TICKER;
- }
- /**
- * Specifies a listener instance that caches should notify each time an entry is removed for any
- * {@linkplain RemovalCause reason}. Each cache created by this builder will invoke this listener
- * as part of the routine maintenance described in the class documentation above.
- *
- * <p><b>Warning:</b> after invoking this method, do not continue to use <i>this</i> cache
- * builder reference; instead use the reference this method <i>returns</i>. At runtime, these
- * point to the same instance, but only the returned reference has the correct generic type
- * information so as to ensure type safety. For best results, use the standard method-chaining
- * idiom illustrated in the class documentation above, configuring a builder and building your
- * cache in a single statement. Failure to heed this advice can result in a {@link
- * ClassCastException} being thrown by a cache operation at some <i>undefined</i> point in the
- * future.
- *
- * <p><b>Warning:</b> any exception thrown by {@code listener} will <i>not</i> be propagated to
- * the {@code Cache} user, only logged via a {@link Logger}.
- *
- * @return the cache builder reference that should be used instead of {@code this} for any
- * remaining configuration and cache building
- * @throws IllegalStateException if a removal listener was already set
- */
- @CheckReturnValue
- public <K1 extends K, V1 extends V> CacheBuilder<K1, V1> removalListener(
- RemovalListener<? super K1, ? super V1> listener) {
- checkState(this.removalListener == null);
-
- // safely limiting the kinds of caches this can produce
- @SuppressWarnings("unchecked")
- CacheBuilder<K1, V1> me = (CacheBuilder<K1, V1>) this;
- me.removalListener = checkNotNull(listener);
- return me;
- }
+ @Override
+ public void invalidateAll() {
+ localCache.clear();
+ }
- // Make a safe contravariant cast now so we don't have to do it over and over.
- @SuppressWarnings("unchecked")
- <K1 extends K, V1 extends V> RemovalListener<K1, V1> getRemovalListener() {
- return (RemovalListener<K1, V1>) Objects.firstNonNull(removalListener, NullListener.INSTANCE);
- }
+ @Override
+ public long size() {
+ return localCache.size();
+ }
- /**
- * Enable the accumulation of {@link CacheStats} during the operation of the cache. Without this
- * {@link Cache#stats} will return zero for all statistics. Note that recording stats requires
- * bookkeeping to be performed with each operation, and thus imposes a performance penalty on
- * cache operation.
- *
- * @since 12.0 (previously, stats collection was automatic)
- */
- public CacheBuilder<K, V> recordStats() {
- statsCounterSupplier = CACHE_STATS_COUNTER;
- return this;
+ @Override
+ public ConcurrentMap<K, V> asMap() {
+ return localCache;
+ }
}
- Supplier<? extends StatsCounter> getStatsCounterSupplier() {
- return statsCounterSupplier;
- }
+ private static class LocalLoadingCache<K, V>
+ extends LocalManualCache<K, V> implements LoadingCache<K, V> {
- /**
- * Builds a cache, which either returns an already-loaded value for a given key or atomically
- * computes or retrieves it using the supplied {@code CacheLoader}. If another thread is currently
- * loading the value for this key, simply waits for that thread to finish and returns its
- * loaded value. Note that multiple threads can concurrently load values for distinct keys.
- *
- * <p>This method does not alter the state of this {@code CacheBuilder} instance, so it can be
- * invoked again to create multiple independent caches.
- *
- * @param loader the cache loader used to obtain new values
- * @return a cache having the requested features
- */
- public <K1 extends K, V1 extends V> LoadingCache<K1, V1> build(
- CacheLoader<? super K1, V1> loader) {
- checkWeightWithWeigher();
- return new LocalCache.LocalLoadingCache<K1, V1>(this, loader);
- }
+ LocalLoadingCache(CacheBuilder<? super K, ? super V> builder,
+ CacheLoader<? super K, V> loader) {
+ super(builder, checkNotNull(loader));
+ }
- /**
- * Builds a cache which does not automatically load values when keys are requested.
- *
- * <p>Consider {@link #build(CacheLoader)} instead, if it is feasible to implement a
- * {@code CacheLoader}.
- *
- * <p>This method does not alter the state of this {@code CacheBuilder} instance, so it can be
- * invoked again to create multiple independent caches.
- *
- * @return a cache having the requested features
- * @since 11.0
- */
- public <K1 extends K, V1 extends V> Cache<K1, V1> build() {
- checkWeightWithWeigher();
- checkNonLoadingCache();
- return new LocalCache.LocalManualCache<K1, V1>(this);
- }
+ // Cache methods
- private void checkNonLoadingCache() {
- checkState(refreshNanos == UNSET_INT, "refreshAfterWrite requires a LoadingCache");
- }
+ @Override
+ public ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
+ throw new UnsupportedOperationException();
+ }
- private void checkWeightWithWeigher() {
- if (weigher == null) {
- checkState(maximumWeight == UNSET_INT, "maximumWeight requires weigher");
- } else {
- if (strictParsing) {
- checkState(maximumWeight != UNSET_INT, "weigher requires maximumWeight");
- } else {
- if (maximumWeight == UNSET_INT) {
- logger.log(Level.WARNING, "ignoring weigher specified without maximumWeight");
- }
- }
+ @Override
+ public void refresh(K key) {
+ throw new UnsupportedOperationException();
}
}
- /**
- * Returns a string representation for this CacheBuilder instance. The exact form of the returned
- * string is not specified.
- */
- @Override
- public String toString() {
- Objects.ToStringHelper s = Objects.toStringHelper(this);
- if (initialCapacity != UNSET_INT) {
- s.add("initialCapacity", initialCapacity);
+ // TODO(fry,user): ConcurrentHashMap never throws a CME when mutating the map during iteration, but
+ // this implementation (based on a LHM) does. This will all be replaced soon anyways, so leaving
+ // it as is for now.
+ private static class LocalCache<K, V> extends LinkedHashMap<K, V>
+ implements ConcurrentMap<K, V> {
+ private final CacheLoader<? super K, V> loader;
+ private final long expirationMillis;
+ private final int maximumSize;
+
+ LocalCache(CacheBuilder<? super K, ? super V> builder, CacheLoader<? super K, V> loader) {
+ super(builder.getInitialCapacity(), 0.75f, (builder.maximumSize != UNSET_INT));
+ this.loader = loader;
+ this.expirationMillis = builder.getExpirationMillis();
+ this.maximumSize = builder.maximumSize;
}
- if (concurrencyLevel != UNSET_INT) {
- s.add("concurrencyLevel", concurrencyLevel);
- }
- if (maximumSize != UNSET_INT) {
- s.add("maximumSize", maximumSize);
+
+ @Override
+ public V put(K key, V value) {
+ V result = super.put(key, value);
+ if (expirationMillis > 0) {
+ scheduleRemoval(key, value);
+ }
+ return result;
}
- if (maximumWeight != UNSET_INT) {
- s.add("maximumWeight", maximumWeight);
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<K, V> ignored) {
+ return (maximumSize == -1) ? false : size() > maximumSize;
}
- if (expireAfterWriteNanos != UNSET_INT) {
- s.add("expireAfterWrite", expireAfterWriteNanos + "ns");
+
+ @Override
+ public V putIfAbsent(K key, V value) {
+ if (!containsKey(key)) {
+ return put(key, value);
+ } else {
+ return get(key);
+ }
}
- if (expireAfterAccessNanos != UNSET_INT) {
- s.add("expireAfterAccess", expireAfterAccessNanos + "ns");
+
+ @Override
+ public boolean remove(Object key, Object value) {
+ if (containsKey(key) && get(key).equals(value)) {
+ remove(key);
+ return true;
+ }
+ return false;
}
- if (keyStrength != null) {
- s.add("keyStrength", Ascii.toLowerCase(keyStrength.toString()));
+
+ @Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ if (containsKey(key) && get(key).equals(oldValue)) {
+ put(key, newValue);
+ return true;
+ }
+ return false;
}
- if (valueStrength != null) {
- s.add("valueStrength", Ascii.toLowerCase(valueStrength.toString()));
+
+ @Override
+ public V replace(K key, V value) {
+ return containsKey(key) ? put(key, value) : null;
}
- if (keyEquivalence != null) {
- s.addValue("keyEquivalence");
+
+ private void scheduleRemoval(final K key, final V value) {
+ /*
+ * TODO: Keep weak reference to map, too. Build a priority queue out of the entries themselves
+ * instead of creating a task per entry. Then, we could have one recurring task per map (which
+ * would clean the entire map and then reschedule itself depending upon when the next
+ * expiration comes). We also want to avoid removing an entry prematurely if the entry was set
+ * to the same value again.
+ */
+ Timer timer = new Timer() {
+ @Override
+ public void run() {
+ remove(key, value);
+ }
+ };
+ timer.schedule((int) expirationMillis);
}
- if (valueEquivalence != null) {
- s.addValue("valueEquivalence");
+
+ public V getOrLoad(Object k) throws ExecutionException {
+ // from CustomConcurrentHashMap
+ V result = super.get(k);
+ if (result == null) {
+ /*
+ * This cast isn't safe, but we can rely on the fact that K is almost always passed to
+ * Map.get(), and tools like IDEs and Findbugs can catch situations where this isn't the
+ * case.
+ *
+ * The alternative is to add an overloaded method, but the chances of a user calling get()
+ * instead of the new API and the risks inherent in adding a new API outweigh this little
+ * hole.
+ */
+ @SuppressWarnings("unchecked")
+ K key = (K) k;
+ result = compute(key);
+ }
+ return result;
}
- if (removalListener != null) {
- s.addValue("removalListener");
+
+ private V compute(K key) throws ExecutionException {
+ V value;
+ try {
+ value = loader.load(key);
+ } catch (RuntimeException e) {
+ throw new UncheckedExecutionException(e);
+ } catch (Exception e) {
+ throw new ExecutionException(e);
+ } catch (Error e) {
+ throw new ExecutionError(e);
+ }
+
+ if (value == null) {
+ String message = loader + " returned null for key " + key + ".";
+ throw new InvalidCacheLoadException(message);
+ }
+ put(key, value);
+ return value;
}
- return s.toString();
}
-}
+}
diff --git a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheLoader.java b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheLoader.java
index c345553..c0815dd 100644
--- a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheLoader.java
+++ b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/CacheLoader.java
@@ -18,7 +18,6 @@ package com.google.common.cache;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@@ -27,20 +26,11 @@ import java.io.Serializable;
import java.util.Map;
/**
- * Computes or retrieves values, based on a key, for use in populating a {@link LoadingCache}.
+ * Computes or retrieves values, based on a key, for use in populating a {@code Cache}.
*
* <p>Most implementations will only need to implement {@link #load}. Other methods may be
* overridden as desired.
*
- * <p>Usage example: <pre> {@code
- *
- * CacheLoader<Key, Graph> loader = new CacheLoader<Key, Graph>() {
- * public Graph load(Key key) throws AnyException {
- * return createExpensiveGraph(key);
- * }
- * };
- * LoadingCache<Key, Graph> cache = CacheBuilder.newBuilder().build(loader);}</pre>
- *
* @author Charles Fry
* @since 10.0
*/
@@ -56,16 +46,12 @@ public abstract class CacheLoader<K, V> {
*
* @param key the non-null key whose value should be loaded
* @return the value associated with {@code key}; <b>must not be null</b>
- * @throws Exception if unable to load the result
- * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is
- * treated like any other {@code Exception} in all respects except that, when it is caught,
- * the thread's interrupt status is set
*/
public abstract V load(K key) throws Exception;
/**
* Computes or retrieves the values corresponding to {@code keys}. This method is called by
- * {@link LoadingCache#getAll}.
+ * {@link Cache#getAll}.
*
* <p>If the returned map doesn't contain all requested {@code keys} then the entries it does
* contain will be cached, but {@code getAll} will throw an exception. If the returned map
@@ -73,33 +59,22 @@ public abstract class CacheLoader<K, V> {
* but only the entries for {@code keys} will be returned from {@code getAll}.
*
* <p>This method should be overriden when bulk retrieval is significantly more efficient than
- * many individual lookups. Note that {@link LoadingCache#getAll} will defer to individual calls
- * to {@link LoadingCache#get} if this method is not overriden.
+ * many individual lookups. Note that {@link Cache#getAll} will defer to individual calls to
+ * {@link Cache#get} if this method is not overriden.
*
* @param keys the unique, non-null keys whose values should be loaded
* @return a map from each key in {@code keys} to the value associated with that key;
* <b>may not contain null values</b>
- * @throws Exception if unable to load the result
- * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is
- * treated like any other {@code Exception} in all respects except that, when it is caught,
- * the thread's interrupt status is set
* @since 11.0
*/
public Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception {
- // This will be caught by getAll(), causing it to fall back to multiple calls to
- // LoadingCache.get
+ // This will be caught by getAll(), causing it to fall back to multiple calls to Cache.get
throw new UnsupportedLoadingOperationException();
}
/**
- * Returns a cache loader based on an <i>existing</i> function instance. Note that there's no need
- * to create a <i>new</i> function just to pass it in here; just subclass {@code CacheLoader} and
- * implement {@link #load load} instead.
- *
- * @param function the function to be used for loading values; must never return {@code null}
- * @return a cache loader that loads values by passing each key to {@code function}
+ * Returns a {@code CacheLoader} which creates values by applying a {@code Function} to the key.
*/
- @Beta
public static <K, V> CacheLoader<K, V> from(Function<K, V> function) {
return new FunctionToCacheLoader<K, V>(function);
}
@@ -114,22 +89,16 @@ public abstract class CacheLoader<K, V> {
@Override
public V load(K key) {
- return computingFunction.apply(checkNotNull(key));
+ return computingFunction.apply(key);
}
private static final long serialVersionUID = 0;
}
/**
- * Returns a cache loader based on an <i>existing</i> supplier instance. Note that there's no need
- * to create a <i>new</i> supplier just to pass it in here; just subclass {@code CacheLoader} and
- * implement {@link #load load} instead.
- *
- * @param supplier the supplier to be used for loading values; must never return {@code null}
- * @return a cache loader that loads values by calling {@link Supplier#get}, irrespective of the
- * key
+ * Returns a {@code CacheLoader} which obtains values from a {@code Supplier} (independent of the
+ * key).
*/
- @Beta
public static <V> CacheLoader<Object, V> from(Supplier<V> supplier) {
return new SupplierToCacheLoader<V>(supplier);
}
@@ -144,7 +113,6 @@ public abstract class CacheLoader<K, V> {
@Override
public V load(Object key) {
- checkNotNull(key);
return computingSupplier.get();
}
diff --git a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LocalCache.java b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LocalCache.java
deleted file mode 100644
index 44528bf..0000000
--- a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LocalCache.java
+++ /dev/null
@@ -1,829 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import static com.google.common.base.Objects.firstNonNull;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Equivalence;
-import com.google.common.base.Ticker;
-import com.google.common.cache.AbstractCache.StatsCounter;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ExecutionError;
-import com.google.common.util.concurrent.UncheckedExecutionException;
-
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-
-import javax.annotation.Nullable;
-
-/**
- * LocalCache emulation for GWT.
- *
- * @param <K> the base key type
- * @param <V> the base value type
- * @author Charles Fry
- * @author Jon Donovan
- */
-public class LocalCache<K, V> implements ConcurrentMap<K, V> {
- private static final int UNSET_INT = CacheBuilder.UNSET_INT;
-
- private final LinkedHashMap<K, Timestamped<V>> cachingHashMap;
- private final CacheLoader<? super K, V> loader;
- private final RemovalListener removalListener;
- private final StatsCounter statsCounter;
- private final Ticker ticker;
- private final long expireAfterWrite;
- private final long expireAfterAccess;
-
- LocalCache(CacheBuilder<? super K, ? super V> builder, CacheLoader<? super K, V> loader) {
- this.loader = loader;
- this.removalListener = builder.removalListener;
- this.expireAfterAccess = builder.expireAfterAccessNanos;
- this.expireAfterWrite = builder.expireAfterWriteNanos;
- this.statsCounter = builder.getStatsCounterSupplier().get();
-
- /* Implements size-capped LinkedHashMap */
- final long maximumSize = builder.maximumSize;
- this.cachingHashMap = new CapacityEnforcingLinkedHashMap<K, V>(
- builder.getInitialCapacity(),
- 0.75f,
- (builder.maximumSize != UNSET_INT),
- builder.maximumSize,
- statsCounter,
- removalListener);
-
- this.ticker = firstNonNull(builder.ticker, Ticker.systemTicker());
- }
-
- @Override
- public int size() {
- return cachingHashMap.size();
- }
-
- @Override
- public boolean isEmpty() {
- return cachingHashMap.isEmpty();
- }
-
- @Override
- public V get(Object key) {
- key = checkNotNull(key);
- Timestamped<V> value = cachingHashMap.get(key);
-
- if (value == null) {
- statsCounter.recordMisses(1);
- return null;
- } else if (!isExpired(value)) {
- statsCounter.recordHits(1);
- value.updateTimestamp();
- return value.getValue();
- } else {
- statsCounter.recordEviction();
- statsCounter.recordMisses(1);
- alertListenerIfPresent(key, value.getValue(), RemovalCause.EXPIRED);
- cachingHashMap.remove(key);
- return null;
- }
- }
-
- @Override
- public V put(K key, V value) {
- key = checkNotNull(key);
- value = checkNotNull(value);
- Timestamped<V> oldValue = cachingHashMap.put(key, new Timestamped<V>(value, ticker));
- if (oldValue == null) {
- return null;
- }
- alertListenerIfPresent(key, oldValue.getValue(), RemovalCause.REPLACED);
- return oldValue.getValue();
- }
-
- @Override
- public V remove(Object key) {
- Timestamped<V> stamped = cachingHashMap.remove(key);
- if (stamped != null) {
- V value = stamped.getValue();
-
- if (!isExpired(stamped)) {
- alertListenerIfPresent(key, value, RemovalCause.EXPLICIT);
- return value;
- }
-
- alertListenerIfPresent(key, value, RemovalCause.EXPIRED);
- }
- return null;
- }
-
- @Override
- public void putAll(Map<? extends K, ? extends V> m) {
- for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
- put(entry.getKey(), entry.getValue());
- }
- }
-
- @Override
- public void clear() {
- if (removalListener != null) {
- for (Map.Entry<K, Timestamped<V>> entry : cachingHashMap.entrySet()) {
- alertListenerIfPresent(entry.getKey(), entry.getValue().getValue(), RemovalCause.EXPLICIT);
- }
- }
- cachingHashMap.clear();
- }
-
- @Override
- public V putIfAbsent(K key, V value) {
- V currentValue = get(key);
- if (currentValue != null) {
- return currentValue;
- }
- return put(key, value);
- }
-
- @Override
- public boolean remove(Object key, Object value) {
- if (value.equals(get(key))) {
- alertListenerIfPresent(key, value, RemovalCause.EXPLICIT);
- remove(key);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean replace(K key, V oldValue, V newValue) {
- if (oldValue.equals(get(key))) {
- alertListenerIfPresent(key, oldValue, RemovalCause.REPLACED);
- put(key, newValue);
- return true;
- }
- return false;
- }
-
- @Override
- public V replace(K key, V value) {
- V currentValue = get(key);
- if (currentValue != null) {
- alertListenerIfPresent(key, currentValue, RemovalCause.REPLACED);
- return put(key, value);
- }
- return null;
- }
-
- @Override
- public boolean containsKey(Object key) {
- return cachingHashMap.containsKey(key) && !isExpired(cachingHashMap.get(key));
- }
-
- @Override
- public boolean containsValue(Object value) {
- for (Timestamped<V> val : cachingHashMap.values()) {
- if (val.getValue().equals(value)) {
- if (!isExpired(val)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean isExpired(Timestamped<V> stamped) {
- if ((expireAfterAccess == UNSET_INT) && (expireAfterWrite == UNSET_INT)) {
- return false;
- }
-
- boolean expireWrite = (stamped.getWriteTimestamp() + expireAfterWrite <= currentTimeNanos());
- boolean expireAccess = (stamped.getAccessTimestamp() + expireAfterAccess <= currentTimeNanos());
-
- if (expireAfterAccess == UNSET_INT) {
- return expireWrite;
- }
- if (expireAfterWrite == UNSET_INT) {
- return expireAccess;
- }
-
- return expireWrite || expireAccess;
- }
-
- private long currentTimeNanos() {
- return ticker.read();
- }
-
- private void alertListenerIfPresent(Object key, Object value, RemovalCause cause) {
- if (removalListener != null) {
- removalListener.onRemoval(new RemovalNotification(key, value, cause));
- }
- }
-
- private V load(Object key) throws ExecutionException {
- long startTime = ticker.read();
- V calculatedValue;
- try {
- /*
- * This cast isn't safe, but we can rely on the fact that K is almost always passed to
- * Map.get(), and tools like IDEs and Findbugs can catch situations where this isn't the
- * case.
- *
- * The alternative is to add an overloaded method, but the chances of a user calling get()
- * instead of the new API and the risks inherent in adding a new API outweigh this little
- * hole.
- */
- K castKey = (K) key;
- calculatedValue = loader.load(castKey);
- put(castKey, calculatedValue);
- } catch (RuntimeException e) {
- statsCounter.recordLoadException(ticker.read() - startTime);
- throw new UncheckedExecutionException(e);
- } catch (Exception e) {
- statsCounter.recordLoadException(ticker.read() - startTime);
- throw new ExecutionException(e);
- } catch (Error e) {
- statsCounter.recordLoadException(ticker.read() - startTime);
- throw new ExecutionError(e);
- }
-
- if (calculatedValue == null) {
- String message = loader + " returned null for key " + key + ".";
- throw new CacheLoader.InvalidCacheLoadException(message);
- }
- statsCounter.recordLoadSuccess(ticker.read() - startTime);
- return calculatedValue;
- }
-
- private V getIfPresent(Object key) {
- key = checkNotNull(key);
- Timestamped<V> value = cachingHashMap.get(key);
-
- if (value == null) {
- return null;
- } else if (!isExpired(value)) {
- value.updateTimestamp();
- return value.getValue();
- } else {
- alertListenerIfPresent(key, value.getValue(), RemovalCause.EXPIRED);
- cachingHashMap.remove(key);
- return null;
- }
- }
-
- private V getOrLoad(K key) throws ExecutionException{
- V value = get(key);
- if (value != null) {
- return value;
- }
- return load(key);
- }
-
- private static class Timestamped<V> {
- private final V value;
- private final Ticker ticker;
- private long writeTimestamp;
- private long accessTimestamp;
-
- public Timestamped(V value, Ticker ticker) {
- this.value = checkNotNull(value);
- this.ticker = checkNotNull(ticker);
- this.writeTimestamp = ticker.read();
- this.accessTimestamp = this.writeTimestamp;
- }
-
- public V getValue() {
- return value;
- }
-
- public void updateTimestamp() {
- accessTimestamp = ticker.read();
- }
-
- public long getAccessTimestamp() {
- return accessTimestamp;
- }
-
- public long getWriteTimestamp() {
- return writeTimestamp;
- }
-
- public boolean equals(Object o) {
- return value.equals(o);
- }
-
- public int hashCode() {
- return value.hashCode();
- }
- }
-
- /**
- * LocalManualCache is a wrapper around LocalCache for a cache without loading.
- *
- * @param <K> the base key type
- * @param <V> the base value type
- */
- public static class LocalManualCache<K, V> extends AbstractCache<K, V> {
- final LocalCache<K, V> localCache;
-
- LocalManualCache(CacheBuilder<? super K, ? super V> builder) {
- this(builder, null);
- }
-
- protected LocalManualCache(CacheBuilder<? super K, ? super V> builder,
- CacheLoader<? super K, V> loader) {
- this.localCache = new LocalCache<K, V>(builder, loader);
- }
-
- // Cache methods
-
- @Override
- public V get(K key, Callable<? extends V> valueLoader) throws ExecutionException {
- V value = localCache.get(key);
- if (value != null) {
- return value;
- }
-
- try {
- V newValue = valueLoader.call();
- localCache.put(key, newValue);
- return newValue;
- } catch (Exception e) {
- throw new ExecutionException(e);
- }
- }
-
- @Override
- @Nullable
- public V getIfPresent(Object key) {
- return localCache.getIfPresent(key);
- }
-
- @Override
- public void put(K key, V value) {
- localCache.put(key, value);
- }
-
- @Override
- public void invalidate(Object key) {
- key = checkNotNull(key);
- localCache.remove(key);
- }
-
- @Override
- public void invalidateAll() {
- localCache.clear();
- }
-
- @Override
- public long size() {
- return localCache.size();
- }
-
- @Override
- public ConcurrentMap<K, V> asMap() {
- return localCache;
- }
- }
-
- /**
- * LocalLoadingCache is a wrapper around LocalCache for a cache with loading.
- *
- * @param <K> the base key type
- * @param <V> the base value type
- */
- public static class LocalLoadingCache<K, V>
- extends LocalManualCache<K, V> implements LoadingCache<K, V> {
-
- LocalLoadingCache(CacheBuilder<? super K, ? super V> builder,
- CacheLoader<? super K, V> loader) {
- super(builder, checkNotNull(loader));
- }
-
- // Cache methods
-
- @Override
- public V get(K key) throws ExecutionException {
- return localCache.getOrLoad(key);
- }
-
- @Override
- public V getUnchecked(K key) {
- try {
- return get(key);
- } catch (ExecutionException e) {
- throw new UncheckedExecutionException(e.getCause());
- }
- }
-
- @Override
- public final V apply(K key) {
- return getUnchecked(key);
- }
-
- @Override
- public ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
- Map<K, V> map = new HashMap<K, V>();
- for (K key : keys) {
- map.put(key, localCache.getOrLoad(key));
- }
- return ImmutableMap.copyOf(map);
- }
-
- @Override
- public void refresh(K key) {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * LinkedHashMap that enforces it's maximum size and logs events in a StatsCounter object
- * and an optional RemovalListener.
- *
- * @param <K> the base key type
- * @param <V> the base value type
- */
- private class CapacityEnforcingLinkedHashMap<K, V> extends LinkedHashMap<K, Timestamped<V>> {
-
- private final StatsCounter statsCounter;
- private final RemovalListener removalListener;
- private final long maximumSize;
-
- public CapacityEnforcingLinkedHashMap(
- int initialCapacity,
- float loadFactor,
- boolean accessOrder,
- long maximumSize,
- StatsCounter statsCounter,
- @Nullable RemovalListener removalListener) {
- super(initialCapacity, loadFactor, accessOrder);
- this.maximumSize = maximumSize;
- this.statsCounter = statsCounter;
- this.removalListener = removalListener;
- }
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<K, Timestamped<V>> ignored) {
- boolean removal = (maximumSize == UNSET_INT) ? false : (size() > maximumSize);
- if ((removalListener != null) && removal) {
- removalListener.onRemoval(new RemovalNotification(
- ignored.getKey(),
- ignored.getValue().getValue(),
- RemovalCause.SIZE));
- }
- statsCounter.recordEviction();
- return removal;
- }
- }
-
- /**
- * Any updates to LocalCache.Strength used in CacheBuilder need to be matched in this class for
- * compilation purposes.
- */
- enum Strength {
- /*
- * TODO(kevinb): If we strongly reference the value and aren't loading, we needn't wrap the
- * value. This could save ~8 bytes per entry.
- */
-
- STRONG {
- @Override
- Equivalence<Object> defaultEquivalence() {
- return Equivalence.equals();
- }
- },
-
- SOFT {
- @Override
- Equivalence<Object> defaultEquivalence() {
- return Equivalence.identity();
- }
- },
-
- WEAK {
- @Override
- Equivalence<Object> defaultEquivalence() {
- return Equivalence.identity();
- }
- };
-
- abstract Equivalence<Object> defaultEquivalence();
- }
-
- /**
- * <p>Implementation for the EntryIterator, which is used to build Key and Value iterators.
- *
- * <p>Expiration is only checked on hasNext(), so as to ensure that a next() call never returns
- * null when hasNext() has already been called.
- */
- class EntryIterator implements Iterator<Entry<K, V>> {
- Iterator<Entry<K, Timestamped<V>>> iterator;
- Entry<K, Timestamped<V>> lastEntry;
- Entry<K, Timestamped<V>> nextEntry;
-
- EntryIterator() {
- this.iterator = LocalCache.this.cachingHashMap.entrySet().iterator();
- }
-
- @Override
- public Entry<K, V> next(){
- if (nextEntry == null) {
- hasNext();
-
- if (nextEntry == null) {
- throw new NoSuchElementException();
- }
- }
-
- lastEntry = nextEntry;
- nextEntry = null;
- return new WriteThroughEntry(lastEntry.getKey(), lastEntry.getValue().getValue());
- }
-
- @Override
- public boolean hasNext() {
- if (nextEntry == null) {
- while (iterator.hasNext()) {
- Entry<K, Timestamped<V>> next = iterator.next();
- if (!isExpired(next.getValue())) {
- nextEntry = next;
- return true;
- }
- }
- return false;
- }
- return true;
- }
-
- @Override
- public void remove() {
- checkState(lastEntry != null);
- LocalCache.this.remove(lastEntry.getKey(), lastEntry.getValue());
- lastEntry = null;
- }
- }
-
- /**
- * KeyIterator build on top of EntryIterator.
- */
- final class KeyIterator implements Iterator<K> {
- private EntryIterator iterator;
-
- KeyIterator() {
- iterator = new EntryIterator();
- }
-
- @Override
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- @Override
- public K next() {
- return iterator.next().getKey();
- }
-
- @Override
- public void remove() {
- iterator.remove();
- }
- }
-
- /**
- * ValueIterator build on top of EntryIterator.
- */
- final class ValueIterator implements Iterator<V> {
- private EntryIterator iterator;
-
- ValueIterator() {
- iterator = new EntryIterator();
- }
-
- @Override
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- @Override
- public V next() {
- return iterator.next().getValue();
- }
-
- @Override
- public void remove() {
- iterator.remove();
- }
- }
-
- Set<K> keySet;
-
- @Override
- public Set<K> keySet() {
- // does not impact recency ordering
- Set<K> ks = keySet;
- return (ks != null) ? ks : (keySet = new KeySet(this));
- }
-
- Collection<V> values;
-
- @Override
- public Collection<V> values() {
- // does not impact recency ordering
- Collection<V> vs = values;
- return (vs != null) ? vs : (values = new Values(this));
- }
-
- Set<Entry<K, V>> entrySet;
-
- @Override
- public Set<Entry<K, V>> entrySet() {
- // does not impact recency ordering
- Set<Entry<K, V>> es = entrySet;
- return (es != null) ? es : (entrySet = new EntrySet(this));
- }
-
- /**
- * Custom Entry class used by EntryIterator.next(), that relays setValue changes to the
- * underlying map.
- */
- private final class WriteThroughEntry implements Entry<K, V> {
- final K key;
- V value;
-
- WriteThroughEntry(K key, V value) {
- this.key = checkNotNull(key);
- this.value = checkNotNull(value);
- }
-
- @Override
- public K getKey() {
- return key;
- }
-
- @Override
- public V getValue() {
- return value;
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- // Cannot use key and value equivalence
- if (object instanceof Entry) {
- Entry<?, ?> that = (Entry<?, ?>) object;
- return key.equals(that.getKey()) && value.equals(that.getValue());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- // Cannot use key and value equivalence
- return key.hashCode() ^ value.hashCode();
- }
-
- @Override
- public V setValue(V newValue) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns a string representation of the form <code>{key}={value}</code>.
- */
- @Override
- public String toString() {
- return getKey() + "=" + getValue();
- }
- }
-
- // TODO(fry): Separate logic for consistency between emul and nonemul implementation.
- // TODO(fry): Look into Maps.KeySet and Maps.Values, which can ideally be reused here but are
- // currently only package visible.
- abstract class AbstractCacheSet<T> extends AbstractSet<T> {
- final ConcurrentMap<?, ?> map;
-
- AbstractCacheSet(ConcurrentMap<?, ?> map) {
- this.map = map;
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public void clear() {
- map.clear();
- }
- }
-
- /**
- * Abstraction layer for the KeySet, which redirects to cache methods.
- */
- private final class KeySet extends AbstractCacheSet<K> {
-
- KeySet(ConcurrentMap<?, ?> map) {
- super(map);
- }
-
- @Override
- public Iterator<K> iterator() {
- return new KeyIterator();
- }
-
- @Override
- public boolean contains(Object o) {
- return map.containsKey(o);
- }
-
- @Override
- public boolean remove(Object o) {
- return map.remove(o) != null;
- }
- }
-
- /**
- * Abstraction layer for the Values set, which redirects to cache methods.
- */
- private final class Values extends AbstractCacheSet<V> {
-
- Values(ConcurrentMap<?, ?> map) {
- super(map);
- }
-
- @Override
- public Iterator<V> iterator() {
- return new ValueIterator();
- }
-
- @Override
- public boolean contains(Object o) {
- return map.containsValue(o);
- }
- }
-
- /**
- * Abstraction layer for the EntrySet, which redirects to cache methods.
- */
- private final class EntrySet extends AbstractCacheSet<Entry<K, V>> {
-
- EntrySet(ConcurrentMap<?, ?> map) {
- super(map);
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return new EntryIterator();
- }
-
- @Override
- public boolean contains(Object o) {
- if (!(o instanceof Entry)) {
- return false;
- }
- Entry<?, ?> e = (Entry<?, ?>) o;
- Object key = e.getKey();
- if (key == null) {
- return false;
- }
- V v = LocalCache.this.get(key);
-
- return (v != null) && e.getValue().equals(v);
- }
-
- @Override
- public boolean remove(Object o) {
- if (!(o instanceof Entry)) {
- return false;
- }
- Entry<?, ?> e = (Entry<?, ?>) o;
- Object key = e.getKey();
- return (key != null) && LocalCache.this.remove(key, e.getValue());
- }
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAddables.java b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAddables.java
deleted file mode 100644
index a911ef3..0000000
--- a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAddables.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-/**
- * GWT emulation for LongAddables.
- *
- * @author Louis Wasserman
- */
-final class LongAddables {
- public static LongAddable create() {
- return new LongAdder();
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAdder.java b/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAdder.java
deleted file mode 100644
index 34b6f37..0000000
--- a/guava-gwt/src-super/com/google/common/cache/super/com/google/common/cache/LongAdder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-/**
- * GWT emulated version of LongAdder.
- *
- * @author Charles Fry
- */
-class LongAdder implements LongAddable {
-
- private long value;
-
- public void increment() {
- value++;
- }
-
- public void add(long x) {
- value += x;
- }
-
- public long sum() {
- return value;
- }
-
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractBiMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractBiMap.java
index 7c882fe..a6cec16 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractBiMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractBiMap.java
@@ -45,7 +45,7 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
implements BiMap<K, V>, Serializable {
private transient Map<K, V> delegate;
- transient AbstractBiMap<V, K> inverse;
+ private transient AbstractBiMap<V, K> inverse;
/** Package-private constructor for creating a map-backed bimap. */
AbstractBiMap(Map<K, V> forward, Map<V, K> backward) {
@@ -63,20 +63,6 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
}
/**
- * Returns its input, or throws an exception if this is not a valid key.
- */
- K checkKey(@Nullable K key) {
- return key;
- }
-
- /**
- * Returns its input, or throws an exception if this is not a valid value.
- */
- V checkValue(@Nullable V value) {
- return value;
- }
-
- /**
* Specifies the delegate maps going in each direction. Called by the
* constructor and by subclasses during deserialization.
*/
@@ -96,24 +82,22 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
// Query Operations (optimizations)
- @Override public boolean containsValue(@Nullable Object value) {
+ @Override public boolean containsValue(Object value) {
return inverse.containsKey(value);
}
// Modification Operations
- @Override public V put(@Nullable K key, @Nullable V value) {
+ @Override public V put(K key, V value) {
return putInBothMaps(key, value, false);
}
@Override
- public V forcePut(@Nullable K key, @Nullable V value) {
+ public V forcePut(K key, V value) {
return putInBothMaps(key, value, true);
}
private V putInBothMaps(@Nullable K key, @Nullable V value, boolean force) {
- checkKey(key);
- checkValue(value);
boolean containedKey = containsKey(key);
if (containedKey && Objects.equal(value, get(key))) {
return value;
@@ -136,7 +120,7 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
inverse.delegate.put(newValue, key);
}
- @Override public V remove(@Nullable Object key) {
+ @Override public V remove(Object key) {
return containsKey(key) ? removeFromBothMaps(key) : null;
}
@@ -203,7 +187,27 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
}
@Override public Iterator<K> iterator() {
- return Maps.keyIterator(entrySet().iterator());
+ final Iterator<Entry<K, V>> iterator = delegate.entrySet().iterator();
+ return new Iterator<K>() {
+ Entry<K, V> entry;
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ @Override
+ public K next() {
+ entry = iterator.next();
+ return entry.getKey();
+ }
+ @Override
+ public void remove() {
+ checkState(entry != null);
+ V value = entry.getValue();
+ iterator.remove();
+ removeFromInverseMap(value);
+ }
+ };
}
}
@@ -226,7 +230,23 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
}
@Override public Iterator<V> iterator() {
- return Maps.valueIterator(entrySet().iterator());
+ final Iterator<V> iterator = delegate.values().iterator();
+ return new Iterator<V>() {
+ V valueToRemove;
+
+ @Override public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override public V next() {
+ return valueToRemove = iterator.next();
+ }
+
+ @Override public void remove() {
+ iterator.remove();
+ removeFromInverseMap(valueToRemove);
+ }
+ };
}
@Override public Object[] toArray() {
@@ -358,16 +378,6 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
* If a bimap and its inverse are serialized together, the deserialized
* instances have inverse() methods that return the other.
*/
-
- @Override
- K checkKey(K key) {
- return inverse.checkValue(key);
- }
-
- @Override
- V checkValue(V value) {
- return inverse.checkKey(value);
- }
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultimap.java
deleted file mode 100644
index 2cfb3ef..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultimap.java
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.RandomAccess;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * Basic implementation of the {@link Multimap} interface. This class represents
- * a multimap as a map that associates each key with a collection of values. All
- * methods of {@link Multimap} are supported, including those specified as
- * optional in the interface.
- *
- * <p>To implement a multimap, a subclass must define the method {@link
- * #createCollection()}, which creates an empty collection of values for a key.
- *
- * <p>The multimap constructor takes a map that has a single entry for each
- * distinct key. When you insert a key-value pair with a key that isn't already
- * in the multimap, {@code AbstractMapBasedMultimap} calls {@link #createCollection()}
- * to create the collection of values for that key. The subclass should not call
- * {@link #createCollection()} directly, and a new instance should be created
- * every time the method is called.
- *
- * <p>For example, the subclass could pass a {@link java.util.TreeMap} during
- * construction, and {@link #createCollection()} could return a {@link
- * java.util.TreeSet}, in which case the multimap's iterators would propagate
- * through the keys and values in sorted order.
- *
- * <p>Keys and values may be null, as long as the underlying collection classes
- * support null elements.
- *
- * <p>The collections created by {@link #createCollection()} may or may not
- * allow duplicates. If the collection, such as a {@link Set}, does not support
- * duplicates, an added key-value pair will replace an existing pair with the
- * same key and value, if such a pair is present. With collections like {@link
- * List} that allow duplicates, the collection will keep the existing key-value
- * pairs while adding a new pair.
- *
- * <p>This class is not threadsafe when any concurrent operations update the
- * multimap, even if the underlying map and {@link #createCollection()} method
- * return threadsafe classes. Concurrent read operations will work correctly. To
- * allow concurrent update operations, wrap your multimap with a call to {@link
- * Multimaps#synchronizedMultimap}.
- *
- * <p>For serialization to work, the subclass must specify explicit
- * {@code readObject} and {@code writeObject} methods.
- *
- * @author Jared Levy
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-abstract class AbstractMapBasedMultimap<K, V> extends AbstractMultimap<K, V>
- implements Serializable {
- /*
- * Here's an outline of the overall design.
- *
- * The map variable contains the collection of values associated with each
- * key. When a key-value pair is added to a multimap that didn't previously
- * contain any values for that key, a new collection generated by
- * createCollection is added to the map. That same collection instance
- * remains in the map as long as the multimap has any values for the key. If
- * all values for the key are removed, the key and collection are removed
- * from the map.
- *
- * The get method returns a WrappedCollection, which decorates the collection
- * in the map (if the key is present) or an empty collection (if the key is
- * not present). When the collection delegate in the WrappedCollection is
- * empty, the multimap may contain subsequently added values for that key. To
- * handle that situation, the WrappedCollection checks whether map contains
- * an entry for the provided key, and if so replaces the delegate.
- */
-
- private transient Map<K, Collection<V>> map;
- private transient int totalSize;
-
- /**
- * Creates a new multimap that uses the provided map.
- *
- * @param map place to store the mapping from each key to its corresponding
- * values
- * @throws IllegalArgumentException if {@code map} is not empty
- */
- protected AbstractMapBasedMultimap(Map<K, Collection<V>> map) {
- checkArgument(map.isEmpty());
- this.map = map;
- }
-
- /** Used during deserialization only. */
- final void setMap(Map<K, Collection<V>> map) {
- this.map = map;
- totalSize = 0;
- for (Collection<V> values : map.values()) {
- checkArgument(!values.isEmpty());
- totalSize += values.size();
- }
- }
-
- /**
- * Creates an unmodifiable, empty collection of values.
- *
- * <p>This is used in {@link #removeAll} on an empty key.
- */
- Collection<V> createUnmodifiableEmptyCollection() {
- return unmodifiableCollectionSubclass(createCollection());
- }
-
- /**
- * Creates the collection of values for a single key.
- *
- * <p>Collections with weak, soft, or phantom references are not supported.
- * Each call to {@code createCollection} should create a new instance.
- *
- * <p>The returned collection class determines whether duplicate key-value
- * pairs are allowed.
- *
- * @return an empty collection of values
- */
- abstract Collection<V> createCollection();
-
- /**
- * Creates the collection of values for an explicitly provided key. By
- * default, it simply calls {@link #createCollection()}, which is the correct
- * behavior for most implementations. The {@link LinkedHashMultimap} class
- * overrides it.
- *
- * @param key key to associate with values in the collection
- * @return an empty collection of values
- */
- Collection<V> createCollection(@Nullable K key) {
- return createCollection();
- }
-
- Map<K, Collection<V>> backingMap() {
- return map;
- }
-
- // Query Operations
-
- @Override
- public int size() {
- return totalSize;
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return map.containsKey(key);
- }
-
- // Modification Operations
-
- @Override
- public boolean put(@Nullable K key, @Nullable V value) {
- Collection<V> collection = map.get(key);
- if (collection == null) {
- collection = createCollection(key);
- if (collection.add(value)) {
- totalSize++;
- map.put(key, collection);
- return true;
- } else {
- throw new AssertionError("New Collection violated the Collection spec");
- }
- } else if (collection.add(value)) {
- totalSize++;
- return true;
- } else {
- return false;
- }
- }
-
- private Collection<V> getOrCreateCollection(@Nullable K key) {
- Collection<V> collection = map.get(key);
- if (collection == null) {
- collection = createCollection(key);
- map.put(key, collection);
- }
- return collection;
- }
-
- // Bulk Operations
-
- /**
- * {@inheritDoc}
- *
- * <p>The returned collection is immutable.
- */
- @Override
- public Collection<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
- Iterator<? extends V> iterator = values.iterator();
- if (!iterator.hasNext()) {
- return removeAll(key);
- }
-
- // TODO(user): investigate atomic failure?
- Collection<V> collection = getOrCreateCollection(key);
- Collection<V> oldValues = createCollection();
- oldValues.addAll(collection);
-
- totalSize -= collection.size();
- collection.clear();
-
- while (iterator.hasNext()) {
- if (collection.add(iterator.next())) {
- totalSize++;
- }
- }
-
- return unmodifiableCollectionSubclass(oldValues);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The returned collection is immutable.
- */
- @Override
- public Collection<V> removeAll(@Nullable Object key) {
- Collection<V> collection = map.remove(key);
-
- if (collection == null) {
- return createUnmodifiableEmptyCollection();
- }
-
- Collection<V> output = createCollection();
- output.addAll(collection);
- totalSize -= collection.size();
- collection.clear();
-
- return unmodifiableCollectionSubclass(output);
- }
-
- Collection<V> unmodifiableCollectionSubclass(Collection<V> collection) {
- // We don't deal with NavigableSet here yet for GWT reasons -- instead,
- // non-GWT TreeMultimap explicitly overrides this and uses NavigableSet.
- if (collection instanceof SortedSet) {
- return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
- } else if (collection instanceof Set) {
- return Collections.unmodifiableSet((Set<V>) collection);
- } else if (collection instanceof List) {
- return Collections.unmodifiableList((List<V>) collection);
- } else {
- return Collections.unmodifiableCollection(collection);
- }
- }
-
- @Override
- public void clear() {
- // Clear each collection, to make previously returned collections empty.
- for (Collection<V> collection : map.values()) {
- collection.clear();
- }
- map.clear();
- totalSize = 0;
- }
-
- // Views
-
- /**
- * {@inheritDoc}
- *
- * <p>The returned collection is not serializable.
- */
- @Override
- public Collection<V> get(@Nullable K key) {
- Collection<V> collection = map.get(key);
- if (collection == null) {
- collection = createCollection(key);
- }
- return wrapCollection(key, collection);
- }
-
- /**
- * Generates a decorated collection that remains consistent with the values in
- * the multimap for the provided key. Changes to the multimap may alter the
- * returned collection, and vice versa.
- */
- Collection<V> wrapCollection(@Nullable K key, Collection<V> collection) {
- // We don't deal with NavigableSet here yet for GWT reasons -- instead,
- // non-GWT TreeMultimap explicitly overrides this and uses NavigableSet.
- if (collection instanceof SortedSet) {
- return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
- } else if (collection instanceof Set) {
- return new WrappedSet(key, (Set<V>) collection);
- } else if (collection instanceof List) {
- return wrapList(key, (List<V>) collection, null);
- } else {
- return new WrappedCollection(key, collection, null);
- }
- }
-
- private List<V> wrapList(
- @Nullable K key, List<V> list, @Nullable WrappedCollection ancestor) {
- return (list instanceof RandomAccess)
- ? new RandomAccessWrappedList(key, list, ancestor)
- : new WrappedList(key, list, ancestor);
- }
-
- /**
- * Collection decorator that stays in sync with the multimap values for a key.
- * There are two kinds of wrapped collections: full and subcollections. Both
- * have a delegate pointing to the underlying collection class.
- *
- * <p>Full collections, identified by a null ancestor field, contain all
- * multimap values for a given key. Its delegate is a value in {@link
- * AbstractMapBasedMultimap#map} whenever the delegate is non-empty. The {@code
- * refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} methods ensure
- * that the {@code WrappedCollection} and map remain consistent.
- *
- * <p>A subcollection, such as a sublist, contains some of the values for a
- * given key. Its ancestor field points to the full wrapped collection with
- * all values for the key. The subcollection {@code refreshIfEmpty}, {@code
- * removeIfEmpty}, and {@code addToMap} methods call the corresponding methods
- * of the full wrapped collection.
- */
- private class WrappedCollection extends AbstractCollection<V> {
- final K key;
- Collection<V> delegate;
- final WrappedCollection ancestor;
- final Collection<V> ancestorDelegate;
-
- WrappedCollection(@Nullable K key, Collection<V> delegate,
- @Nullable WrappedCollection ancestor) {
- this.key = key;
- this.delegate = delegate;
- this.ancestor = ancestor;
- this.ancestorDelegate
- = (ancestor == null) ? null : ancestor.getDelegate();
- }
-
- /**
- * If the delegate collection is empty, but the multimap has values for the
- * key, replace the delegate with the new collection for the key.
- *
- * <p>For a subcollection, refresh its ancestor and validate that the
- * ancestor delegate hasn't changed.
- */
- void refreshIfEmpty() {
- if (ancestor != null) {
- ancestor.refreshIfEmpty();
- if (ancestor.getDelegate() != ancestorDelegate) {
- throw new ConcurrentModificationException();
- }
- } else if (delegate.isEmpty()) {
- Collection<V> newDelegate = map.get(key);
- if (newDelegate != null) {
- delegate = newDelegate;
- }
- }
- }
-
- /**
- * If collection is empty, remove it from {@code AbstractMapBasedMultimap.this.map}.
- * For subcollections, check whether the ancestor collection is empty.
- */
- void removeIfEmpty() {
- if (ancestor != null) {
- ancestor.removeIfEmpty();
- } else if (delegate.isEmpty()) {
- map.remove(key);
- }
- }
-
- K getKey() {
- return key;
- }
-
- /**
- * Add the delegate to the map. Other {@code WrappedCollection} methods
- * should call this method after adding elements to a previously empty
- * collection.
- *
- * <p>Subcollection add the ancestor's delegate instead.
- */
- void addToMap() {
- if (ancestor != null) {
- ancestor.addToMap();
- } else {
- map.put(key, delegate);
- }
- }
-
- @Override public int size() {
- refreshIfEmpty();
- return delegate.size();
- }
-
- @Override public boolean equals(@Nullable Object object) {
- if (object == this) {
- return true;
- }
- refreshIfEmpty();
- return delegate.equals(object);
- }
-
- @Override public int hashCode() {
- refreshIfEmpty();
- return delegate.hashCode();
- }
-
- @Override public String toString() {
- refreshIfEmpty();
- return delegate.toString();
- }
-
- Collection<V> getDelegate() {
- return delegate;
- }
-
- @Override public Iterator<V> iterator() {
- refreshIfEmpty();
- return new WrappedIterator();
- }
-
- /** Collection iterator for {@code WrappedCollection}. */
- class WrappedIterator implements Iterator<V> {
- final Iterator<V> delegateIterator;
- final Collection<V> originalDelegate = delegate;
-
- WrappedIterator() {
- delegateIterator = iteratorOrListIterator(delegate);
- }
-
- WrappedIterator(Iterator<V> delegateIterator) {
- this.delegateIterator = delegateIterator;
- }
-
- /**
- * If the delegate changed since the iterator was created, the iterator is
- * no longer valid.
- */
- void validateIterator() {
- refreshIfEmpty();
- if (delegate != originalDelegate) {
- throw new ConcurrentModificationException();
- }
- }
-
- @Override
- public boolean hasNext() {
- validateIterator();
- return delegateIterator.hasNext();
- }
-
- @Override
- public V next() {
- validateIterator();
- return delegateIterator.next();
- }
-
- @Override
- public void remove() {
- delegateIterator.remove();
- totalSize--;
- removeIfEmpty();
- }
-
- Iterator<V> getDelegateIterator() {
- validateIterator();
- return delegateIterator;
- }
- }
-
- @Override public boolean add(V value) {
- refreshIfEmpty();
- boolean wasEmpty = delegate.isEmpty();
- boolean changed = delegate.add(value);
- if (changed) {
- totalSize++;
- if (wasEmpty) {
- addToMap();
- }
- }
- return changed;
- }
-
- WrappedCollection getAncestor() {
- return ancestor;
- }
-
- // The following methods are provided for better performance.
-
- @Override public boolean addAll(Collection<? extends V> collection) {
- if (collection.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = delegate.addAll(collection);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- if (oldSize == 0) {
- addToMap();
- }
- }
- return changed;
- }
-
- @Override public boolean contains(Object o) {
- refreshIfEmpty();
- return delegate.contains(o);
- }
-
- @Override public boolean containsAll(Collection<?> c) {
- refreshIfEmpty();
- return delegate.containsAll(c);
- }
-
- @Override public void clear() {
- int oldSize = size(); // calls refreshIfEmpty
- if (oldSize == 0) {
- return;
- }
- delegate.clear();
- totalSize -= oldSize;
- removeIfEmpty(); // maybe shouldn't be removed if this is a sublist
- }
-
- @Override public boolean remove(Object o) {
- refreshIfEmpty();
- boolean changed = delegate.remove(o);
- if (changed) {
- totalSize--;
- removeIfEmpty();
- }
- return changed;
- }
-
- @Override public boolean removeAll(Collection<?> c) {
- if (c.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = delegate.removeAll(c);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- removeIfEmpty();
- }
- return changed;
- }
-
- @Override public boolean retainAll(Collection<?> c) {
- checkNotNull(c);
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = delegate.retainAll(c);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- removeIfEmpty();
- }
- return changed;
- }
- }
-
- private Iterator<V> iteratorOrListIterator(Collection<V> collection) {
- return (collection instanceof List)
- ? ((List<V>) collection).listIterator()
- : collection.iterator();
- }
-
- /** Set decorator that stays in sync with the multimap values for a key. */
- private class WrappedSet extends WrappedCollection implements Set<V> {
- WrappedSet(@Nullable K key, Set<V> delegate) {
- super(key, delegate, null);
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- if (c.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
-
- // Guava issue 1013: AbstractSet and most JDK set implementations are
- // susceptible to quadratic removeAll performance on lists;
- // use a slightly smarter implementation here
- boolean changed = Sets.removeAllImpl((Set<V>) delegate, c);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- removeIfEmpty();
- }
- return changed;
- }
- }
-
- /**
- * SortedSet decorator that stays in sync with the multimap values for a key.
- */
- private class WrappedSortedSet extends WrappedCollection
- implements SortedSet<V> {
- WrappedSortedSet(@Nullable K key, SortedSet<V> delegate,
- @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
-
- SortedSet<V> getSortedSetDelegate() {
- return (SortedSet<V>) getDelegate();
- }
-
- @Override
- public Comparator<? super V> comparator() {
- return getSortedSetDelegate().comparator();
- }
-
- @Override
- public V first() {
- refreshIfEmpty();
- return getSortedSetDelegate().first();
- }
-
- @Override
- public V last() {
- refreshIfEmpty();
- return getSortedSetDelegate().last();
- }
-
- @Override
- public SortedSet<V> headSet(V toElement) {
- refreshIfEmpty();
- return new WrappedSortedSet(
- getKey(), getSortedSetDelegate().headSet(toElement),
- (getAncestor() == null) ? this : getAncestor());
- }
-
- @Override
- public SortedSet<V> subSet(V fromElement, V toElement) {
- refreshIfEmpty();
- return new WrappedSortedSet(
- getKey(), getSortedSetDelegate().subSet(fromElement, toElement),
- (getAncestor() == null) ? this : getAncestor());
- }
-
- @Override
- public SortedSet<V> tailSet(V fromElement) {
- refreshIfEmpty();
- return new WrappedSortedSet(
- getKey(), getSortedSetDelegate().tailSet(fromElement),
- (getAncestor() == null) ? this : getAncestor());
- }
- }
-
- /** List decorator that stays in sync with the multimap values for a key. */
- private class WrappedList extends WrappedCollection implements List<V> {
- WrappedList(@Nullable K key, List<V> delegate,
- @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
-
- List<V> getListDelegate() {
- return (List<V>) getDelegate();
- }
-
- @Override
- public boolean addAll(int index, Collection<? extends V> c) {
- if (c.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = getListDelegate().addAll(index, c);
- if (changed) {
- int newSize = getDelegate().size();
- totalSize += (newSize - oldSize);
- if (oldSize == 0) {
- addToMap();
- }
- }
- return changed;
- }
-
- @Override
- public V get(int index) {
- refreshIfEmpty();
- return getListDelegate().get(index);
- }
-
- @Override
- public V set(int index, V element) {
- refreshIfEmpty();
- return getListDelegate().set(index, element);
- }
-
- @Override
- public void add(int index, V element) {
- refreshIfEmpty();
- boolean wasEmpty = getDelegate().isEmpty();
- getListDelegate().add(index, element);
- totalSize++;
- if (wasEmpty) {
- addToMap();
- }
- }
-
- @Override
- public V remove(int index) {
- refreshIfEmpty();
- V value = getListDelegate().remove(index);
- totalSize--;
- removeIfEmpty();
- return value;
- }
-
- @Override
- public int indexOf(Object o) {
- refreshIfEmpty();
- return getListDelegate().indexOf(o);
- }
-
- @Override
- public int lastIndexOf(Object o) {
- refreshIfEmpty();
- return getListDelegate().lastIndexOf(o);
- }
-
- @Override
- public ListIterator<V> listIterator() {
- refreshIfEmpty();
- return new WrappedListIterator();
- }
-
- @Override
- public ListIterator<V> listIterator(int index) {
- refreshIfEmpty();
- return new WrappedListIterator(index);
- }
-
- @Override
- public List<V> subList(int fromIndex, int toIndex) {
- refreshIfEmpty();
- return wrapList(getKey(),
- getListDelegate().subList(fromIndex, toIndex),
- (getAncestor() == null) ? this : getAncestor());
- }
-
- /** ListIterator decorator. */
- private class WrappedListIterator extends WrappedIterator
- implements ListIterator<V> {
- WrappedListIterator() {}
-
- public WrappedListIterator(int index) {
- super(getListDelegate().listIterator(index));
- }
-
- private ListIterator<V> getDelegateListIterator() {
- return (ListIterator<V>) getDelegateIterator();
- }
-
- @Override
- public boolean hasPrevious() {
- return getDelegateListIterator().hasPrevious();
- }
-
- @Override
- public V previous() {
- return getDelegateListIterator().previous();
- }
-
- @Override
- public int nextIndex() {
- return getDelegateListIterator().nextIndex();
- }
-
- @Override
- public int previousIndex() {
- return getDelegateListIterator().previousIndex();
- }
-
- @Override
- public void set(V value) {
- getDelegateListIterator().set(value);
- }
-
- @Override
- public void add(V value) {
- boolean wasEmpty = isEmpty();
- getDelegateListIterator().add(value);
- totalSize++;
- if (wasEmpty) {
- addToMap();
- }
- }
- }
- }
-
- /**
- * List decorator that stays in sync with the multimap values for a key and
- * supports rapid random access.
- */
- private class RandomAccessWrappedList extends WrappedList
- implements RandomAccess {
- RandomAccessWrappedList(@Nullable K key, List<V> delegate,
- @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
- }
-
- @Override
- Set<K> createKeySet() {
- // TreeMultimap uses NavigableKeySet explicitly, but we don't handle that here for GWT
- // compatibility reasons
- return (map instanceof SortedMap)
- ? new SortedKeySet((SortedMap<K, Collection<V>>) map) : new KeySet(map);
- }
-
- private class KeySet extends Maps.KeySet<K, Collection<V>> {
-
- /**
- * This is usually the same as map, except when someone requests a
- * subcollection of a {@link SortedKeySet}.
- */
- final Map<K, Collection<V>> subMap;
-
- KeySet(final Map<K, Collection<V>> subMap) {
- this.subMap = subMap;
- }
-
- @Override
- Map<K, Collection<V>> map() {
- return subMap;
- }
-
- @Override public Iterator<K> iterator() {
- final Iterator<Map.Entry<K, Collection<V>>> entryIterator
- = subMap.entrySet().iterator();
- return new Iterator<K>() {
- Map.Entry<K, Collection<V>> entry;
-
- @Override
- public boolean hasNext() {
- return entryIterator.hasNext();
- }
- @Override
- public K next() {
- entry = entryIterator.next();
- return entry.getKey();
- }
- @Override
- public void remove() {
- Iterators.checkRemove(entry != null);
- Collection<V> collection = entry.getValue();
- entryIterator.remove();
- totalSize -= collection.size();
- collection.clear();
- }
- };
- }
-
- // The following methods are included for better performance.
-
- @Override public boolean remove(Object key) {
- int count = 0;
- Collection<V> collection = subMap.remove(key);
- if (collection != null) {
- count = collection.size();
- collection.clear();
- totalSize -= count;
- }
- return count > 0;
- }
-
- @Override
- public void clear() {
- Iterators.clear(iterator());
- }
-
- @Override public boolean containsAll(Collection<?> c) {
- return subMap.keySet().containsAll(c);
- }
-
- @Override public boolean equals(@Nullable Object object) {
- return this == object || this.subMap.keySet().equals(object);
- }
-
- @Override public int hashCode() {
- return subMap.keySet().hashCode();
- }
- }
-
- private class SortedKeySet extends KeySet implements SortedSet<K> {
-
- SortedKeySet(SortedMap<K, Collection<V>> subMap) {
- super(subMap);
- }
-
- SortedMap<K, Collection<V>> sortedMap() {
- return (SortedMap<K, Collection<V>>) subMap;
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return sortedMap().comparator();
- }
-
- @Override
- public K first() {
- return sortedMap().firstKey();
- }
-
- @Override
- public SortedSet<K> headSet(K toElement) {
- return new SortedKeySet(sortedMap().headMap(toElement));
- }
-
- @Override
- public K last() {
- return sortedMap().lastKey();
- }
-
- @Override
- public SortedSet<K> subSet(K fromElement, K toElement) {
- return new SortedKeySet(sortedMap().subMap(fromElement, toElement));
- }
-
- @Override
- public SortedSet<K> tailSet(K fromElement) {
- return new SortedKeySet(sortedMap().tailMap(fromElement));
- }
- }
-
- /**
- * Removes all values for the provided key. Unlike {@link #removeAll}, it
- * returns the number of removed mappings.
- */
- private int removeValuesForKey(Object key) {
- Collection<V> collection = Maps.safeRemove(map, key);
-
- int count = 0;
- if (collection != null) {
- count = collection.size();
- collection.clear();
- totalSize -= count;
- }
- return count;
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The iterator generated by the returned collection traverses the values
- * for one key, followed by the values of a second key, and so on.
- */
- @Override public Collection<V> values() {
- return super.values();
- }
-
- /*
- * TODO(kevinb): should we copy this javadoc to each concrete class, so that
- * classes like LinkedHashMultimap that need to say something different are
- * still able to {@inheritDoc} all the way from Multimap?
- */
-
- /**
- * {@inheritDoc}
- *
- * <p>The iterator generated by the returned collection traverses the values
- * for one key, followed by the values of a second key, and so on.
- *
- * <p>Each entry is an immutable snapshot of a key-value mapping in the
- * multimap, taken at the time the entry is returned by a method call to the
- * collection or its iterator.
- */
- @Override
- public Collection<Map.Entry<K, V>> entries() {
- return super.entries();
- }
-
- /**
- * Returns an iterator across all key-value map entries, used by {@code
- * entries().iterator()} and {@code values().iterator()}. The default
- * behavior, which traverses the values for one key, the values for a second
- * key, and so on, suffices for most {@code AbstractMapBasedMultimap} implementations.
- *
- * @return an iterator across map entries
- */
- @Override
- Iterator<Map.Entry<K, V>> entryIterator() {
- return new EntryIterator();
- }
-
- /** Iterator across all key-value pairs. */
- private class EntryIterator implements Iterator<Map.Entry<K, V>> {
- final Iterator<Map.Entry<K, Collection<V>>> keyIterator;
- K key;
- Collection<V> collection;
- Iterator<V> valueIterator;
-
- EntryIterator() {
- keyIterator = map.entrySet().iterator();
- if (keyIterator.hasNext()) {
- findValueIteratorAndKey();
- } else {
- valueIterator = Iterators.emptyModifiableIterator();
- }
- }
-
- void findValueIteratorAndKey() {
- Map.Entry<K, Collection<V>> entry = keyIterator.next();
- key = entry.getKey();
- collection = entry.getValue();
- valueIterator = collection.iterator();
- }
-
- @Override
- public boolean hasNext() {
- return keyIterator.hasNext() || valueIterator.hasNext();
- }
-
- @Override
- public Map.Entry<K, V> next() {
- if (!valueIterator.hasNext()) {
- findValueIteratorAndKey();
- }
- return Maps.immutableEntry(key, valueIterator.next());
- }
-
- @Override
- public void remove() {
- valueIterator.remove();
- if (collection.isEmpty()) {
- keyIterator.remove();
- }
- totalSize--;
- }
- }
-
- @Override
- Map<K, Collection<V>> createAsMap() {
- // TreeMultimap uses NavigableAsMap explicitly, but we don't handle that here for GWT
- // compatibility reasons
- return (map instanceof SortedMap)
- ? new SortedAsMap((SortedMap<K, Collection<V>>) map) : new AsMap(map);
- }
-
- private class AsMap extends AbstractMap<K, Collection<V>> {
- /**
- * Usually the same as map, but smaller for the headMap(), tailMap(), or
- * subMap() of a SortedAsMap.
- */
- final transient Map<K, Collection<V>> submap;
-
- AsMap(Map<K, Collection<V>> submap) {
- this.submap = submap;
- }
-
- transient Set<Map.Entry<K, Collection<V>>> entrySet;
-
- @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
- Set<Map.Entry<K, Collection<V>>> result = entrySet;
- return (result == null) ? entrySet = new AsMapEntries() : result;
- }
-
- // The following methods are included for performance.
-
- @Override public boolean containsKey(Object key) {
- return Maps.safeContainsKey(submap, key);
- }
-
- @Override public Collection<V> get(Object key) {
- Collection<V> collection = Maps.safeGet(submap, key);
- if (collection == null) {
- return null;
- }
- @SuppressWarnings("unchecked")
- K k = (K) key;
- return wrapCollection(k, collection);
- }
-
- @Override public Set<K> keySet() {
- return AbstractMapBasedMultimap.this.keySet();
- }
-
- @Override
- public int size() {
- return submap.size();
- }
-
- @Override public Collection<V> remove(Object key) {
- Collection<V> collection = submap.remove(key);
- if (collection == null) {
- return null;
- }
-
- Collection<V> output = createCollection();
- output.addAll(collection);
- totalSize -= collection.size();
- collection.clear();
- return output;
- }
-
- @Override public boolean equals(@Nullable Object object) {
- return this == object || submap.equals(object);
- }
-
- @Override public int hashCode() {
- return submap.hashCode();
- }
-
- @Override public String toString() {
- return submap.toString();
- }
-
- @Override
- public void clear() {
- if (submap == map) {
- AbstractMapBasedMultimap.this.clear();
- } else {
-
- Iterators.clear(new AsMapIterator());
- }
- }
-
- Entry<K, Collection<V>> wrapEntry(Entry<K, Collection<V>> entry) {
- K key = entry.getKey();
- return Maps.immutableEntry(key, wrapCollection(key, entry.getValue()));
- }
-
- class AsMapEntries extends Maps.EntrySet<K, Collection<V>> {
- @Override
- Map<K, Collection<V>> map() {
- return AsMap.this;
- }
-
- @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
- return new AsMapIterator();
- }
-
- // The following methods are included for performance.
-
- @Override public boolean contains(Object o) {
- return Collections2.safeContains(submap.entrySet(), o);
- }
-
- @Override public boolean remove(Object o) {
- if (!contains(o)) {
- return false;
- }
- Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
- removeValuesForKey(entry.getKey());
- return true;
- }
- }
-
- /** Iterator across all keys and value collections. */
- class AsMapIterator implements Iterator<Map.Entry<K, Collection<V>>> {
- final Iterator<Map.Entry<K, Collection<V>>> delegateIterator
- = submap.entrySet().iterator();
- Collection<V> collection;
-
- @Override
- public boolean hasNext() {
- return delegateIterator.hasNext();
- }
-
- @Override
- public Map.Entry<K, Collection<V>> next() {
- Map.Entry<K, Collection<V>> entry = delegateIterator.next();
- collection = entry.getValue();
- return wrapEntry(entry);
- }
-
- @Override
- public void remove() {
- delegateIterator.remove();
- totalSize -= collection.size();
- collection.clear();
- }
- }
- }
-
- private class SortedAsMap extends AsMap
- implements SortedMap<K, Collection<V>> {
- SortedAsMap(SortedMap<K, Collection<V>> submap) {
- super(submap);
- }
-
- SortedMap<K, Collection<V>> sortedMap() {
- return (SortedMap<K, Collection<V>>) submap;
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return sortedMap().comparator();
- }
-
- @Override
- public K firstKey() {
- return sortedMap().firstKey();
- }
-
- @Override
- public K lastKey() {
- return sortedMap().lastKey();
- }
-
- @Override
- public SortedMap<K, Collection<V>> headMap(K toKey) {
- return new SortedAsMap(sortedMap().headMap(toKey));
- }
-
- @Override
- public SortedMap<K, Collection<V>> subMap(K fromKey, K toKey) {
- return new SortedAsMap(sortedMap().subMap(fromKey, toKey));
- }
-
- @Override
- public SortedMap<K, Collection<V>> tailMap(K fromKey) {
- return new SortedAsMap(sortedMap().tailMap(fromKey));
- }
-
- SortedSet<K> sortedKeySet;
-
- // returns a SortedSet, even though returning a Set would be sufficient to
- // satisfy the SortedMap.keySet() interface
- @Override public SortedSet<K> keySet() {
- SortedSet<K> result = sortedKeySet;
- return (result == null) ? sortedKeySet = createKeySet() : result;
- }
-
- SortedSet<K> createKeySet() {
- return new SortedKeySet(sortedMap());
- }
- }
-
- private static final long serialVersionUID = 2447537837011683357L;
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultiset.java
index 3c0f05d..6bccc6d 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultiset.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractMapBasedMultiset.java
@@ -25,6 +25,7 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.primitives.Ints;
import java.io.Serializable;
+import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Map;
@@ -34,7 +35,7 @@ import javax.annotation.Nullable;
/**
* Basic implementation of {@code Multiset<E>} backed by an instance of {@code
- * Map<E, Count>}.
+ * Map<E, AtomicInteger>}.
*
* <p>For serialization to work, the subclass must specify explicit {@code
* readObject} and {@code writeObject} methods.
@@ -60,6 +61,10 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
this.size = super.size();
}
+ Map<E, Count> backingMap() {
+ return backingMap;
+ }
+
/** Used during deserialization only. The backing map must be empty. */
void setBackingMap(Map<E, Count> backingMap) {
this.backingMap = backingMap;
@@ -116,7 +121,8 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
@Override
public void remove() {
- Iterators.checkRemove(toRemove != null);
+ checkState(toRemove != null,
+ "no calls to next() since the last call to remove()");
size -= toRemove.getValue().getAndSet(0);
backingEntries.remove();
toRemove = null;
@@ -150,7 +156,7 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
/*
* Not subclassing AbstractMultiset$MultisetIterator because next() needs to
- * retrieve the Map.Entry<E, Count> entry, which can then be used for
+ * retrieve the Map.Entry<E, AtomicInteger> entry, which can then be used for
* a more efficient remove() call.
*/
private class MapBasedMultisetIterator implements Iterator<E> {
@@ -196,8 +202,14 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
}
@Override public int count(@Nullable Object element) {
- Count frequency = Maps.safeGet(backingMap, element);
- return (frequency == null) ? 0 : frequency.get();
+ try {
+ Count frequency = backingMap.get(element);
+ return (frequency == null) ? 0 : frequency.get();
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
}
// Optional Operations - Modification Operations
@@ -258,7 +270,7 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
}
// Roughly a 33% performance improvement over AbstractMultiset.setCount().
- @Override public int setCount(@Nullable E element, int count) {
+ @Override public int setCount(E element, int count) {
checkNonnegative(count, "count");
Count existingCounter;
@@ -287,6 +299,97 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
return i.getAndSet(count);
}
+ private int removeAllOccurrences(@Nullable Object element,
+ Map<E, Count> map) {
+ Count frequency = map.remove(element);
+ if (frequency == null) {
+ return 0;
+ }
+ int numberRemoved = frequency.getAndSet(0);
+ size -= numberRemoved;
+ return numberRemoved;
+ }
+
+ // Views
+
+ @Override Set<E> createElementSet() {
+ return new MapBasedElementSet(backingMap);
+ }
+
+ // TODO(user): once TreeMultiset is replaced with a SortedMultiset
+ // implementation, replace this with a subclass of Multisets.ElementSet.
+ class MapBasedElementSet extends ForwardingSet<E> {
+
+ // This mapping is the usually the same as 'backingMap', but can be a
+ // submap in some implementations.
+ private final Map<E, Count> map;
+ private final Set<E> delegate;
+
+ MapBasedElementSet(Map<E, Count> map) {
+ this.map = map;
+ delegate = map.keySet();
+ }
+
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+
+ @Override public Iterator<E> iterator() {
+ final Iterator<Map.Entry<E, Count>> entries
+ = map.entrySet().iterator();
+ return new Iterator<E>() {
+ Map.Entry<E, Count> toRemove;
+
+ @Override
+ public boolean hasNext() {
+ return entries.hasNext();
+ }
+
+ @Override
+ public E next() {
+ toRemove = entries.next();
+ return toRemove.getKey();
+ }
+
+ @Override
+ public void remove() {
+ checkState(toRemove != null,
+ "no calls to next() since the last call to remove()");
+ size -= toRemove.getValue().getAndSet(0);
+ entries.remove();
+ toRemove = null;
+ }
+ };
+ }
+
+ @Override public boolean remove(Object element) {
+ return removeAllOccurrences(element, map) != 0;
+ }
+
+ @Override public boolean removeAll(Collection<?> elementsToRemove) {
+ return Iterators.removeAll(iterator(), elementsToRemove);
+ }
+
+ @Override public boolean retainAll(Collection<?> elementsToRetain) {
+ return Iterators.retainAll(iterator(), elementsToRetain);
+ }
+
+ @Override public void clear() {
+ if (map == backingMap) {
+ AbstractMapBasedMultiset.this.clear();
+ } else {
+ Iterator<E> i = iterator();
+ while (i.hasNext()) {
+ i.next();
+ i.remove();
+ }
+ }
+ }
+
+ public Map<E, Count> getMap() {
+ return map;
+ }
+ }
+
// Don't allow default serialization.
}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractSortedMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractSortedMultiset.java
deleted file mode 100644
index 3eea734..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/AbstractSortedMultiset.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * This class provides a skeletal implementation of the {@link SortedMultiset} interface.
- *
- * <p>The {@link #count} and {@link #size} implementations all iterate across the set returned by
- * {@link Multiset#entrySet()}, as do many methods acting on the set returned by
- * {@link #elementSet()}. Override those methods for better performance.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-abstract class AbstractSortedMultiset<E> extends AbstractMultiset<E> implements SortedMultiset<E> {
- @GwtTransient final Comparator<? super E> comparator;
-
- // needed for serialization
- @SuppressWarnings("unchecked")
- AbstractSortedMultiset() {
- this((Comparator) Ordering.natural());
- }
-
- AbstractSortedMultiset(Comparator<? super E> comparator) {
- this.comparator = checkNotNull(comparator);
- }
-
- @Override
- public SortedSet<E> elementSet() {
- return (SortedSet<E>) super.elementSet();
- }
-
- @Override
- SortedSet<E> createElementSet() {
- return new SortedMultisets.ElementSet<E>(this);
- }
-
- @Override
- public Comparator<? super E> comparator() {
- return comparator;
- }
-
- @Override
- public Entry<E> firstEntry() {
- Iterator<Entry<E>> entryIterator = entryIterator();
- return entryIterator.hasNext() ? entryIterator.next() : null;
- }
-
- @Override
- public Entry<E> lastEntry() {
- Iterator<Entry<E>> entryIterator = descendingEntryIterator();
- return entryIterator.hasNext() ? entryIterator.next() : null;
- }
-
- @Override
- public Entry<E> pollFirstEntry() {
- Iterator<Entry<E>> entryIterator = entryIterator();
- if (entryIterator.hasNext()) {
- Entry<E> result = entryIterator.next();
- result = Multisets.immutableEntry(result.getElement(), result.getCount());
- entryIterator.remove();
- return result;
- }
- return null;
- }
-
- @Override
- public Entry<E> pollLastEntry() {
- Iterator<Entry<E>> entryIterator = descendingEntryIterator();
- if (entryIterator.hasNext()) {
- Entry<E> result = entryIterator.next();
- result = Multisets.immutableEntry(result.getElement(), result.getCount());
- entryIterator.remove();
- return result;
- }
- return null;
- }
-
- @Override
- public SortedMultiset<E> subMultiset(@Nullable E fromElement, BoundType fromBoundType,
- @Nullable E toElement, BoundType toBoundType) {
- // These are checked elsewhere, but NullPointerTester wants them checked eagerly.
- checkNotNull(fromBoundType);
- checkNotNull(toBoundType);
- return tailMultiset(fromElement, fromBoundType).headMultiset(toElement, toBoundType);
- }
-
- abstract Iterator<Entry<E>> descendingEntryIterator();
-
- Iterator<E> descendingIterator() {
- return Multisets.iteratorImpl(descendingMultiset());
- }
-
- private transient SortedMultiset<E> descendingMultiset;
-
- @Override
- public SortedMultiset<E> descendingMultiset() {
- SortedMultiset<E> result = descendingMultiset;
- return (result == null) ? descendingMultiset = createDescendingMultiset() : result;
- }
-
- SortedMultiset<E> createDescendingMultiset() {
- return new DescendingMultiset<E>() {
- @Override
- SortedMultiset<E> forwardMultiset() {
- return AbstractSortedMultiset.this;
- }
-
- @Override
- Iterator<Entry<E>> entryIterator() {
- return descendingEntryIterator();
- }
-
- @Override
- public Iterator<E> iterator() {
- return descendingIterator();
- }
- };
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayListMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayListMultimap.java
index 59d4e77..da5478c 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayListMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayListMultimap.java
@@ -50,10 +50,6 @@ import java.util.List;
* multimap. Concurrent read operations will work correctly. To allow concurrent
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedListMultimap}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
*
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -61,7 +57,7 @@ import java.util.List;
@GwtCompatible(serializable = true, emulated = true)
public final class ArrayListMultimap<K, V> extends AbstractListMultimap<K, V> {
// Default from ArrayList
- private static final int DEFAULT_VALUES_PER_KEY = 3;
+ private static final int DEFAULT_VALUES_PER_KEY = 10;
@VisibleForTesting transient int expectedValuesPerKey;
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayTable.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayTable.java
deleted file mode 100644
index bde92c5..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ArrayTable.java
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkElementIndex;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Objects;
-
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.AbstractSet;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Fixed-size {@link Table} implementation backed by a two-dimensional array.
- *
- * <p>The allowed row and column keys must be supplied when the table is
- * created. The table always contains a mapping for every row key / column pair.
- * The value corresponding to a given row and column is null unless another
- * value is provided.
- *
- * <p>The table's size is constant: the product of the number of supplied row
- * keys and the number of supplied column keys. The {@code remove} and {@code
- * clear} methods are not supported by the table or its views. The {@link
- * #erase} and {@link #eraseAll} methods may be used instead.
- *
- * <p>The ordering of the row and column keys provided when the table is
- * constructed determines the iteration ordering across rows and columns in the
- * table's views. None of the view iterators support {@link Iterator#remove}.
- * If the table is modified after an iterator is created, the iterator remains
- * valid.
- *
- * <p>This class requires less memory than the {@link HashBasedTable} and {@link
- * TreeBasedTable} implementations, except when the table is sparse.
- *
- * <p>Null row keys or column keys are not permitted.
- *
- * <p>This class provides methods involving the underlying array structure,
- * where the array indices correspond to the position of a row or column in the
- * lists of allowed keys and values. See the {@link #at}, {@link #set}, {@link
- * #toArray}, {@link #rowKeyList}, and {@link #columnKeyList} methods for more
- * details.
- *
- * <p>Note that this implementation is not synchronized. If multiple threads
- * access the same cell of an {@code ArrayTable} concurrently and one of the
- * threads modifies its value, there is no guarantee that the new value will be
- * fully visible to the other threads. To guarantee that modifications are
- * visible, synchronize access to the table. Unlike other {@code Table}
- * implementations, synchronization is unnecessary between a thread that writes
- * to one cell and a thread that reads from another.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table">
- * {@code Table}</a>.
- *
- * @author Jared Levy
- * @since 10.0
- */
-@Beta
-@GwtCompatible(emulated = true)
-public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
-
- /**
- * Creates an empty {@code ArrayTable}.
- *
- * @param rowKeys row keys that may be stored in the generated table
- * @param columnKeys column keys that may be stored in the generated table
- * @throws NullPointerException if any of the provided keys is null
- * @throws IllegalArgumentException if {@code rowKeys} or {@code columnKeys}
- * contains duplicates or is empty
- */
- public static <R, C, V> ArrayTable<R, C, V> create(
- Iterable<? extends R> rowKeys, Iterable<? extends C> columnKeys) {
- return new ArrayTable<R, C, V>(rowKeys, columnKeys);
- }
-
- /*
- * TODO(jlevy): Add factory methods taking an Enum class, instead of an
- * iterable, to specify the allowed row keys and/or column keys. Note that
- * custom serialization logic is needed to support different enum sizes during
- * serialization and deserialization.
- */
-
- /**
- * Creates an {@code ArrayTable} with the mappings in the provided table.
- *
- * <p>If {@code table} includes a mapping with row key {@code r} and a
- * separate mapping with column key {@code c}, the returned table contains a
- * mapping with row key {@code r} and column key {@code c}. If that row key /
- * column key pair in not in {@code table}, the pair maps to {@code null} in
- * the generated table.
- *
- * <p>The returned table allows subsequent {@code put} calls with the row keys
- * in {@code table.rowKeySet()} and the column keys in {@code
- * table.columnKeySet()}. Calling {@link #put} with other keys leads to an
- * {@code IllegalArgumentException}.
- *
- * <p>The ordering of {@code table.rowKeySet()} and {@code
- * table.columnKeySet()} determines the row and column iteration ordering of
- * the returned table.
- *
- * @throws NullPointerException if {@code table} has a null key
- * @throws IllegalArgumentException if the provided table is empty
- */
- public static <R, C, V> ArrayTable<R, C, V> create(Table<R, C, V> table) {
- return new ArrayTable<R, C, V>(table);
- }
-
- /**
- * Creates an {@code ArrayTable} with the same mappings, allowed keys, and
- * iteration ordering as the provided {@code ArrayTable}.
- */
- public static <R, C, V> ArrayTable<R, C, V> create(
- ArrayTable<R, C, V> table) {
- return new ArrayTable<R, C, V>(table);
- }
-
- private final ImmutableList<R> rowList;
- private final ImmutableList<C> columnList;
-
- // TODO(jlevy): Add getters returning rowKeyToIndex and columnKeyToIndex?
- private final ImmutableMap<R, Integer> rowKeyToIndex;
- private final ImmutableMap<C, Integer> columnKeyToIndex;
- private final V[][] array;
-
- private ArrayTable(Iterable<? extends R> rowKeys,
- Iterable<? extends C> columnKeys) {
- this.rowList = ImmutableList.copyOf(rowKeys);
- this.columnList = ImmutableList.copyOf(columnKeys);
- checkArgument(!rowList.isEmpty());
- checkArgument(!columnList.isEmpty());
-
- /*
- * TODO(jlevy): Support empty rowKeys or columnKeys? If we do, when
- * columnKeys is empty but rowKeys isn't, the table is empty but
- * containsRow() can return true and rowKeySet() isn't empty.
- */
- rowKeyToIndex = index(rowList);
- columnKeyToIndex = index(columnList);
-
- @SuppressWarnings("unchecked")
- V[][] tmpArray
- = (V[][]) new Object[rowList.size()][columnList.size()];
- array = tmpArray;
- // Necessary because in GWT the arrays are initialized with "undefined" instead of null.
- eraseAll();
- }
-
- private static <E> ImmutableMap<E, Integer> index(List<E> list) {
- ImmutableMap.Builder<E, Integer> columnBuilder = ImmutableMap.builder();
- for (int i = 0; i < list.size(); i++) {
- columnBuilder.put(list.get(i), i);
- }
- return columnBuilder.build();
- }
-
- private ArrayTable(Table<R, C, V> table) {
- this(table.rowKeySet(), table.columnKeySet());
- putAll(table);
- }
-
- private ArrayTable(ArrayTable<R, C, V> table) {
- rowList = table.rowList;
- columnList = table.columnList;
- rowKeyToIndex = table.rowKeyToIndex;
- columnKeyToIndex = table.columnKeyToIndex;
- @SuppressWarnings("unchecked")
- V[][] copy = (V[][]) new Object[rowList.size()][columnList.size()];
- array = copy;
- // Necessary because in GWT the arrays are initialized with "undefined" instead of null.
- eraseAll();
- for (int i = 0; i < rowList.size(); i++) {
- System.arraycopy(table.array[i], 0, copy[i], 0, table.array[i].length);
- }
- }
-
- private abstract static class ArrayMap<K, V> extends Maps.ImprovedAbstractMap<K, V> {
- private final ImmutableMap<K, Integer> keyIndex;
-
- private ArrayMap(ImmutableMap<K, Integer> keyIndex) {
- this.keyIndex = keyIndex;
- }
-
- @Override
- public Set<K> keySet() {
- return keyIndex.keySet();
- }
-
- K getKey(int index) {
- return keyIndex.keySet().asList().get(index);
- }
-
- abstract String getKeyRole();
-
- @Nullable abstract V getValue(int index);
-
- @Nullable abstract V setValue(int index, V newValue);
-
- @Override
- public int size() {
- return keyIndex.size();
- }
-
- @Override
- public boolean isEmpty() {
- return keyIndex.isEmpty();
- }
-
- @Override
- protected Set<Entry<K, V>> createEntrySet() {
- return new Maps.EntrySet<K, V>() {
- @Override
- Map<K, V> map() {
- return ArrayMap.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return new AbstractIndexedListIterator<Entry<K, V>>(size()) {
- @Override
- protected Entry<K, V> get(final int index) {
- return new AbstractMapEntry<K, V>() {
- @Override
- public K getKey() {
- return ArrayMap.this.getKey(index);
- }
-
- @Override
- public V getValue() {
- return ArrayMap.this.getValue(index);
- }
-
- @Override
- public V setValue(V value) {
- return ArrayMap.this.setValue(index, value);
- }
- };
- }
- };
- }
- };
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return keyIndex.containsKey(key);
- }
-
- @Override
- public V get(@Nullable Object key) {
- Integer index = keyIndex.get(key);
- if (index == null) {
- return null;
- } else {
- return getValue(index);
- }
- }
-
- @Override
- public V put(K key, V value) {
- Integer index = keyIndex.get(key);
- if (index == null) {
- throw new IllegalArgumentException(
- getKeyRole() + " " + key + " not in " + keyIndex.keySet());
- }
- return setValue(index, value);
- }
-
- @Override
- public V remove(Object key) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Returns, as an immutable list, the row keys provided when the table was
- * constructed, including those that are mapped to null values only.
- */
- public ImmutableList<R> rowKeyList() {
- return rowList;
- }
-
- /**
- * Returns, as an immutable list, the column keys provided when the table was
- * constructed, including those that are mapped to null values only.
- */
- public ImmutableList<C> columnKeyList() {
- return columnList;
- }
-
- /**
- * Returns the value corresponding to the specified row and column indices.
- * The same value is returned by {@code
- * get(rowKeyList().get(rowIndex), columnKeyList().get(columnIndex))}, but
- * this method runs more quickly.
- *
- * @param rowIndex position of the row key in {@link #rowKeyList()}
- * @param columnIndex position of the row key in {@link #columnKeyList()}
- * @return the value with the specified row and column
- * @throws IndexOutOfBoundsException if either index is negative, {@code
- * rowIndex} is greater then or equal to the number of allowed row keys,
- * or {@code columnIndex} is greater then or equal to the number of
- * allowed column keys
- */
- public V at(int rowIndex, int columnIndex) {
- // In GWT array access never throws IndexOutOfBoundsException.
- checkElementIndex(rowIndex, rowList.size());
- checkElementIndex(columnIndex, columnList.size());
- return array[rowIndex][columnIndex];
- }
-
- /**
- * Associates {@code value} with the specified row and column indices. The
- * logic {@code
- * put(rowKeyList().get(rowIndex), columnKeyList().get(columnIndex), value)}
- * has the same behavior, but this method runs more quickly.
- *
- * @param rowIndex position of the row key in {@link #rowKeyList()}
- * @param columnIndex position of the row key in {@link #columnKeyList()}
- * @param value value to store in the table
- * @return the previous value with the specified row and column
- * @throws IndexOutOfBoundsException if either index is negative, {@code
- * rowIndex} is greater then or equal to the number of allowed row keys,
- * or {@code columnIndex} is greater then or equal to the number of
- * allowed column keys
- */
- public V set(int rowIndex, int columnIndex, @Nullable V value) {
- // In GWT array access never throws IndexOutOfBoundsException.
- checkElementIndex(rowIndex, rowList.size());
- checkElementIndex(columnIndex, columnList.size());
- V oldValue = array[rowIndex][columnIndex];
- array[rowIndex][columnIndex] = value;
- return oldValue;
- }
-
- /**
- * Not supported. Use {@link #eraseAll} instead.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Use {@link #eraseAll}
- */
- @Override
- @Deprecated public void clear() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Associates the value {@code null} with every pair of allowed row and column
- * keys.
- */
- public void eraseAll() {
- for (V[] row : array) {
- Arrays.fill(row, null);
- }
- }
-
- /**
- * Returns {@code true} if the provided keys are among the keys provided when
- * the table was constructed.
- */
- @Override
- public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) {
- return containsRow(rowKey) && containsColumn(columnKey);
- }
-
- /**
- * Returns {@code true} if the provided column key is among the column keys
- * provided when the table was constructed.
- */
- @Override
- public boolean containsColumn(@Nullable Object columnKey) {
- return columnKeyToIndex.containsKey(columnKey);
- }
-
- /**
- * Returns {@code true} if the provided row key is among the row keys
- * provided when the table was constructed.
- */
- @Override
- public boolean containsRow(@Nullable Object rowKey) {
- return rowKeyToIndex.containsKey(rowKey);
- }
-
- @Override
- public boolean containsValue(@Nullable Object value) {
- for (V[] row : array) {
- for (V element : row) {
- if (Objects.equal(value, element)) {
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
- Integer rowIndex = rowKeyToIndex.get(rowKey);
- Integer columnIndex = columnKeyToIndex.get(columnKey);
- return (rowIndex == null || columnIndex == null)
- ? null : at(rowIndex, columnIndex);
- }
-
- /**
- * Always returns {@code false}.
- */
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @throws IllegalArgumentException if {@code rowKey} is not in {@link
- * #rowKeySet()} or {@code columnKey} is not in {@link #columnKeySet()}.
- */
- @Override
- public V put(R rowKey, C columnKey, @Nullable V value) {
- checkNotNull(rowKey);
- checkNotNull(columnKey);
- Integer rowIndex = rowKeyToIndex.get(rowKey);
- checkArgument(rowIndex != null, "Row %s not in %s", rowKey, rowList);
- Integer columnIndex = columnKeyToIndex.get(columnKey);
- checkArgument(columnIndex != null,
- "Column %s not in %s", columnKey, columnList);
- return set(rowIndex, columnIndex, value);
- }
-
- /*
- * TODO(jlevy): Consider creating a merge() method, similar to putAll() but
- * copying non-null values only.
- */
-
- /**
- * {@inheritDoc}
- *
- * <p>If {@code table} is an {@code ArrayTable}, its null values will be
- * stored in this table, possibly replacing values that were previously
- * non-null.
- *
- * @throws NullPointerException if {@code table} has a null key
- * @throws IllegalArgumentException if any of the provided table's row keys or
- * column keys is not in {@link #rowKeySet()} or {@link #columnKeySet()}
- */
- @Override
- public void putAll(Table<? extends R, ? extends C, ? extends V> table) {
- for (Cell<? extends R, ? extends C, ? extends V> cell : table.cellSet()) {
- put(cell.getRowKey(), cell.getColumnKey(), cell.getValue());
- }
- }
-
- /**
- * Not supported. Use {@link #erase} instead.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Use {@link #erase}
- */
- @Override
- @Deprecated public V remove(Object rowKey, Object columnKey) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Associates the value {@code null} with the specified keys, assuming both
- * keys are valid. If either key is null or isn't among the keys provided
- * during construction, this method has no effect.
- *
- * <p>This method is equivalent to {@code put(rowKey, columnKey, null)} when
- * both provided keys are valid.
- *
- * @param rowKey row key of mapping to be erased
- * @param columnKey column key of mapping to be erased
- * @return the value previously associated with the keys, or {@code null} if
- * no mapping existed for the keys
- */
- public V erase(@Nullable Object rowKey, @Nullable Object columnKey) {
- Integer rowIndex = rowKeyToIndex.get(rowKey);
- Integer columnIndex = columnKeyToIndex.get(columnKey);
- if (rowIndex == null || columnIndex == null) {
- return null;
- }
- return set(rowIndex, columnIndex, null);
- }
-
- // TODO(jlevy): Add eraseRow and eraseColumn methods?
-
- @Override
- public int size() {
- return rowList.size() * columnList.size();
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof Table) {
- Table<?, ?, ?> other = (Table<?, ?, ?>) obj;
- return cellSet().equals(other.cellSet());
- }
- return false;
- }
-
- @Override public int hashCode() {
- return cellSet().hashCode();
- }
-
- /**
- * Returns the string representation {@code rowMap().toString()}.
- */
- @Override public String toString() {
- return rowMap().toString();
- }
-
- private transient CellSet cellSet;
-
- /**
- * Returns an unmodifiable set of all row key / column key / value
- * triplets. Changes to the table will update the returned set.
- *
- * <p>The returned set's iterator traverses the mappings with the first row
- * key, the mappings with the second row key, and so on.
- *
- * <p>The value in the returned cells may change if the table subsequently
- * changes.
- *
- * @return set of table cells consisting of row key / column key / value
- * triplets
- */
- @Override
- public Set<Cell<R, C, V>> cellSet() {
- CellSet set = cellSet;
- return (set == null) ? cellSet = new CellSet() : set;
- }
-
- private class CellSet extends AbstractSet<Cell<R, C, V>> {
-
- @Override public Iterator<Cell<R, C, V>> iterator() {
- return new AbstractIndexedListIterator<Cell<R, C, V>>(size()) {
- @Override protected Cell<R, C, V> get(final int index) {
- return new Tables.AbstractCell<R, C, V>() {
- final int rowIndex = index / columnList.size();
- final int columnIndex = index % columnList.size();
- @Override
- public R getRowKey() {
- return rowList.get(rowIndex);
- }
- @Override
- public C getColumnKey() {
- return columnList.get(columnIndex);
- }
- @Override
- public V getValue() {
- return at(rowIndex, columnIndex);
- }
- };
- }
- };
- }
-
- @Override public int size() {
- return ArrayTable.this.size();
- }
-
- @Override public boolean contains(Object obj) {
- if (obj instanceof Cell) {
- Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
- Integer rowIndex = rowKeyToIndex.get(cell.getRowKey());
- Integer columnIndex = columnKeyToIndex.get(cell.getColumnKey());
- return rowIndex != null
- && columnIndex != null
- && Objects.equal(at(rowIndex, columnIndex), cell.getValue());
- }
- return false;
- }
- }
-
- /**
- * Returns a view of all mappings that have the given column key. If the
- * column key isn't in {@link #columnKeySet()}, an empty immutable map is
- * returned.
- *
- * <p>Otherwise, for each row key in {@link #rowKeySet()}, the returned map
- * associates the row key with the corresponding value in the table. Changes
- * to the returned map will update the underlying table, and vice versa.
- *
- * @param columnKey key of column to search for in the table
- * @return the corresponding map from row keys to values
- */
- @Override
- public Map<R, V> column(C columnKey) {
- checkNotNull(columnKey);
- Integer columnIndex = columnKeyToIndex.get(columnKey);
- return (columnIndex == null)
- ? ImmutableMap.<R, V>of() : new Column(columnIndex);
- }
-
- private class Column extends ArrayMap<R, V> {
- final int columnIndex;
-
- Column(int columnIndex) {
- super(rowKeyToIndex);
- this.columnIndex = columnIndex;
- }
-
- @Override
- String getKeyRole() {
- return "Row";
- }
-
- @Override
- V getValue(int index) {
- return at(index, columnIndex);
- }
-
- @Override
- V setValue(int index, V newValue) {
- return set(index, columnIndex, newValue);
- }
- }
-
- /**
- * Returns an immutable set of the valid column keys, including those that
- * are associated with null values only.
- *
- * @return immutable set of column keys
- */
- @Override
- public ImmutableSet<C> columnKeySet() {
- return columnKeyToIndex.keySet();
- }
-
- private transient ColumnMap columnMap;
-
- @Override
- public Map<C, Map<R, V>> columnMap() {
- ColumnMap map = columnMap;
- return (map == null) ? columnMap = new ColumnMap() : map;
- }
-
- private class ColumnMap extends ArrayMap<C, Map<R, V>> {
- private ColumnMap() {
- super(columnKeyToIndex);
- }
-
- @Override
- String getKeyRole() {
- return "Column";
- }
-
- @Override
- Map<R, V> getValue(int index) {
- return new Column(index);
- }
-
- @Override
- Map<R, V> setValue(int index, Map<R, V> newValue) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Map<R, V> put(C key, Map<R, V> value) {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Returns a view of all mappings that have the given row key. If the
- * row key isn't in {@link #rowKeySet()}, an empty immutable map is
- * returned.
- *
- * <p>Otherwise, for each column key in {@link #columnKeySet()}, the returned
- * map associates the column key with the corresponding value in the
- * table. Changes to the returned map will update the underlying table, and
- * vice versa.
- *
- * @param rowKey key of row to search for in the table
- * @return the corresponding map from column keys to values
- */
- @Override
- public Map<C, V> row(R rowKey) {
- checkNotNull(rowKey);
- Integer rowIndex = rowKeyToIndex.get(rowKey);
- return (rowIndex == null) ? ImmutableMap.<C, V>of() : new Row(rowIndex);
- }
-
- private class Row extends ArrayMap<C, V> {
- final int rowIndex;
-
- Row(int rowIndex) {
- super(columnKeyToIndex);
- this.rowIndex = rowIndex;
- }
-
- @Override
- String getKeyRole() {
- return "Column";
- }
-
- @Override
- V getValue(int index) {
- return at(rowIndex, index);
- }
-
- @Override
- V setValue(int index, V newValue) {
- return set(rowIndex, index, newValue);
- }
- }
-
- /**
- * Returns an immutable set of the valid row keys, including those that are
- * associated with null values only.
- *
- * @return immutable set of row keys
- */
- @Override
- public ImmutableSet<R> rowKeySet() {
- return rowKeyToIndex.keySet();
- }
-
- private transient RowMap rowMap;
-
- @Override
- public Map<R, Map<C, V>> rowMap() {
- RowMap map = rowMap;
- return (map == null) ? rowMap = new RowMap() : map;
- }
-
- private class RowMap extends ArrayMap<R, Map<C, V>> {
- private RowMap() {
- super(rowKeyToIndex);
- }
-
- @Override
- String getKeyRole() {
- return "Row";
- }
-
- @Override
- Map<C, V> getValue(int index) {
- return new Row(index);
- }
-
- @Override
- Map<C, V> setValue(int index, Map<C, V> newValue) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Map<C, V> put(R key, Map<C, V> value) {
- throw new UnsupportedOperationException();
- }
- }
-
- private transient Collection<V> values;
-
- /**
- * Returns an unmodifiable collection of all values, which may contain
- * duplicates. Changes to the table will update the returned collection.
- *
- * <p>The returned collection's iterator traverses the values of the first row
- * key, the values of the second row key, and so on.
- *
- * @return collection of values
- */
- @Override
- public Collection<V> values() {
- Collection<V> v = values;
- return (v == null) ? values = new Values() : v;
- }
-
- private class Values extends AbstractCollection<V> {
- @Override public Iterator<V> iterator() {
- return new TransformedIterator<Cell<R, C, V>, V>(cellSet().iterator()) {
- @Override
- V transform(Cell<R, C, V> cell) {
- return cell.getValue();
- }
- };
- }
-
- @Override public int size() {
- return ArrayTable.this.size();
- }
- }
-
- private static final long serialVersionUID = 0;
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ContiguousSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ContiguousSet.java
deleted file mode 100644
index 5cebc98..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ContiguousSet.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.NoSuchElementException;
-
-/**
- * A sorted set of contiguous values in a given {@link DiscreteDomain}.
- *
- * <p><b>Warning:</b> Be extremely careful what you do with conceptually large instances (such as
- * {@code ContiguousSet.create(Range.greaterThan(0), DiscreteDomains.integers()}). Certain
- * operations on such a set can be performed efficiently, but others (such as {@link Set#hashCode}
- * or {@link Collections#frequency}) can cause major performance problems.
- *
- * @author Gregory Kick
- * @since 10.0
- */
-@Beta
-@GwtCompatible(emulated = true)
-@SuppressWarnings("rawtypes") // allow ungenerified Comparable types
-public abstract class ContiguousSet<C extends Comparable> extends ImmutableSortedSet<C> {
- /**
- * Returns a {@code ContiguousSet} containing the same values in the given domain
- * {@linkplain Range#contains contained} by the range.
- *
- * @throws IllegalArgumentException if neither range nor the domain has a lower bound, or if
- * neither has an upper bound
- *
- * @since 13.0
- */
- public static <C extends Comparable> ContiguousSet<C> create(
- Range<C> range, DiscreteDomain<C> domain) {
- checkNotNull(range);
- checkNotNull(domain);
- Range<C> effectiveRange = range;
- try {
- if (!range.hasLowerBound()) {
- effectiveRange = effectiveRange.intersection(Range.atLeast(domain.minValue()));
- }
- if (!range.hasUpperBound()) {
- effectiveRange = effectiveRange.intersection(Range.atMost(domain.maxValue()));
- }
- } catch (NoSuchElementException e) {
- throw new IllegalArgumentException(e);
- }
-
- // Per class spec, we are allowed to throw CCE if necessary
- boolean empty = effectiveRange.isEmpty()
- || Range.compareOrThrow(
- range.lowerBound.leastValueAbove(domain),
- range.upperBound.greatestValueBelow(domain)) > 0;
-
- return empty
- ? new EmptyContiguousSet<C>(domain)
- : new RegularContiguousSet<C>(effectiveRange, domain);
- }
-
- final DiscreteDomain<C> domain;
-
- ContiguousSet(DiscreteDomain<C> domain) {
- super(Ordering.natural());
- this.domain = domain;
- }
-
- @Override public ContiguousSet<C> headSet(C toElement) {
- return headSetImpl(checkNotNull(toElement), false);
- }
-
- @Override public ContiguousSet<C> subSet(C fromElement, C toElement) {
- checkNotNull(fromElement);
- checkNotNull(toElement);
- checkArgument(comparator().compare(fromElement, toElement) <= 0);
- return subSetImpl(fromElement, true, toElement, false);
- }
-
- @Override public ContiguousSet<C> tailSet(C fromElement) {
- return tailSetImpl(checkNotNull(fromElement), true);
- }
-
- /*
- * These methods perform most headSet, subSet, and tailSet logic, besides parameter validation.
- */
- /*@Override*/ abstract ContiguousSet<C> headSetImpl(C toElement, boolean inclusive);
-
- /*@Override*/ abstract ContiguousSet<C> subSetImpl(C fromElement, boolean fromInclusive,
- C toElement, boolean toInclusive);
-
- /*@Override*/ abstract ContiguousSet<C> tailSetImpl(C fromElement, boolean inclusive);
-
- /**
- * Returns the set of values that are contained in both this set and the other.
- *
- * <p>This method should always be used instead of
- * {@link Sets#intersection} for {@link ContiguousSet} instances.
- */
- public abstract ContiguousSet<C> intersection(ContiguousSet<C> other);
-
- /**
- * Returns a range, closed on both ends, whose endpoints are the minimum and maximum values
- * contained in this set. This is equivalent to {@code range(CLOSED, CLOSED)}.
- *
- * @throws NoSuchElementException if this set is empty
- */
- public abstract Range<C> range();
-
- /**
- * Returns the minimal range with the given boundary types for which all values in this set are
- * {@linkplain Range#contains(Comparable) contained} within the range.
- *
- * <p>Note that this method will return ranges with unbounded endpoints if {@link BoundType#OPEN}
- * is requested for a domain minimum or maximum. For example, if {@code set} was created from the
- * range {@code [1..Integer.MAX_VALUE]} then {@code set.range(CLOSED, OPEN)} must return
- * {@code [1..∞)}.
- *
- * @throws NoSuchElementException if this set is empty
- */
- public abstract Range<C> range(BoundType lowerBoundType, BoundType upperBoundType);
-
- /** Returns a short-hand representation of the contents such as {@code "[1..100]"}. */
- @Override public String toString() {
- return range().toString();
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/DescendingMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/DescendingMultiset.java
deleted file mode 100644
index a708d9c..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/DescendingMultiset.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * A skeleton implementation of a descending multiset. Only needs
- * {@code forwardMultiset()} and {@code entryIterator()}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-abstract class DescendingMultiset<E> extends ForwardingMultiset<E>
- implements SortedMultiset<E> {
- abstract SortedMultiset<E> forwardMultiset();
-
- private transient Comparator<? super E> comparator;
-
- @Override public Comparator<? super E> comparator() {
- Comparator<? super E> result = comparator;
- if (result == null) {
- return comparator =
- Ordering.from(forwardMultiset().comparator()).<E>reverse();
- }
- return result;
- }
-
- private transient SortedSet<E> elementSet;
-
- @Override public SortedSet<E> elementSet() {
- SortedSet<E> result = elementSet;
- if (result == null) {
- return elementSet = new SortedMultisets.ElementSet<E>(this);
- }
- return result;
- }
-
- @Override public Entry<E> pollFirstEntry() {
- return forwardMultiset().pollLastEntry();
- }
-
- @Override public Entry<E> pollLastEntry() {
- return forwardMultiset().pollFirstEntry();
- }
-
- @Override public SortedMultiset<E> headMultiset(E toElement,
- BoundType boundType) {
- return forwardMultiset().tailMultiset(toElement, boundType)
- .descendingMultiset();
- }
-
- @Override public SortedMultiset<E> subMultiset(E fromElement,
- BoundType fromBoundType, E toElement, BoundType toBoundType) {
- return forwardMultiset().subMultiset(toElement, toBoundType, fromElement,
- fromBoundType).descendingMultiset();
- }
-
- @Override public SortedMultiset<E> tailMultiset(E fromElement,
- BoundType boundType) {
- return forwardMultiset().headMultiset(fromElement, boundType)
- .descendingMultiset();
- }
-
- @Override protected Multiset<E> delegate() {
- return forwardMultiset();
- }
-
- @Override public SortedMultiset<E> descendingMultiset() {
- return forwardMultiset();
- }
-
- @Override public Entry<E> firstEntry() {
- return forwardMultiset().lastEntry();
- }
-
- @Override public Entry<E> lastEntry() {
- return forwardMultiset().firstEntry();
- }
-
- abstract Iterator<Entry<E>> entryIterator();
-
- private transient Set<Entry<E>> entrySet;
-
- @Override public Set<Entry<E>> entrySet() {
- Set<Entry<E>> result = entrySet;
- return (result == null) ? entrySet = createEntrySet() : result;
- }
-
- Set<Entry<E>> createEntrySet() {
- return new Multisets.EntrySet<E>() {
- @Override Multiset<E> multiset() {
- return DescendingMultiset.this;
- }
-
- @Override public Iterator<Entry<E>> iterator() {
- return entryIterator();
- }
-
- @Override public int size() {
- return forwardMultiset().entrySet().size();
- }
- };
- }
-
- @Override public Iterator<E> iterator() {
- return Multisets.iteratorImpl(this);
- }
-
- @Override public Object[] toArray() {
- return standardToArray();
- }
-
- @Override public <T> T[] toArray(T[] array) {
- return standardToArray(array);
- }
-
- @Override public String toString() {
- return entrySet().toString();
- }
-} \ No newline at end of file
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyContiguousSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyContiguousSet.java
index 368e856..f8fbe59 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyContiguousSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyContiguousSet.java
@@ -69,6 +69,11 @@ final class EmptyContiguousSet<C extends Comparable> extends ContiguousSet<C> {
return this;
}
+ //Abstract method doesn't exist in GWT emulation
+ /* @Override */ int indexOf(Object target) {
+ return -1;
+ }
+
@Override public UnmodifiableIterator<C> iterator() {
return Iterators.emptyIterator();
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableList.java
index 24b1151..435fc26 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableList.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableList.java
@@ -13,25 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.google.common.collect;
-import static java.util.Collections.emptyList;
-
-import java.util.List;
-
/**
* GWT emulated version of EmptyImmutableList.
*
* @author Hayward Chan
*/
-final class EmptyImmutableList extends ForwardingImmutableList<Object> {
- static final EmptyImmutableList INSTANCE = new EmptyImmutableList();
-
- private EmptyImmutableList() {
- }
+final class EmptyImmutableList extends ImmutableList<Object> {
- @Override List<Object> delegateList() {
- return emptyList();
- }
+ static final EmptyImmutableList INSTANCE = new EmptyImmutableList();
}
diff --git a/guava-gwt/src/com/google/common/collect/ForwardingImmutableSet_CustomFieldSerializer.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableMap.java
index b49de22..dc3fecf 100644
--- a/guava-gwt/src/com/google/common/collect/ForwardingImmutableSet_CustomFieldSerializer.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableMap.java
@@ -17,9 +17,12 @@
package com.google.common.collect;
/**
- * Even though {@link ForwardingImmutableSet} cannot be instantiated, we still
- * need a custom field serializer. TODO(cpovirk): why?
+ * GWT emulation of {@link EmptyImmutableMap}. In GWT, it is a thin wrapper
+ * around {@link java.util.Collections#emptyMap()}.
*
* @author Hayward Chan
*/
-public final class ForwardingImmutableSet_CustomFieldSerializer {}
+final class EmptyImmutableMap extends ImmutableMap<Object, Object> {
+
+ static final EmptyImmutableMap INSTANCE = new EmptyImmutableMap();
+}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSet.java
index ae3b3f3..6166c36 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSet.java
@@ -16,17 +16,12 @@
package com.google.common.collect;
-import java.util.Collections;
-
/**
* GWT emulation of {@link EmptyImmutableSet}.
*
* @author Hayward Chan
*/
-final class EmptyImmutableSet extends ForwardingImmutableSet<Object> {
- private EmptyImmutableSet() {
- super(Collections.emptySet());
- }
+final class EmptyImmutableSet extends ImmutableSet<Object> {
static final EmptyImmutableSet INSTANCE = new EmptyImmutableSet();
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedMap.java
deleted file mode 100644
index 4159cd4..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedMap.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Comparator;
-import java.util.TreeMap;
-
-/**
- * GWT emulated version of {@link EmptyImmutableSortedMap}.
- *
- * @author Chris Povirk
- */
-final class EmptyImmutableSortedMap<K, V> extends ImmutableSortedMap<K, V> {
- private EmptyImmutableSortedMap(Comparator<? super K> comparator) {
- super(new TreeMap<K, V>(comparator), comparator);
- }
-
- @SuppressWarnings("unchecked")
- private static final ImmutableSortedMap<Object, Object> NATURAL_EMPTY_MAP =
- new EmptyImmutableSortedMap<Object, Object>(NATURAL_ORDER);
-
- static <K, V> ImmutableSortedMap<K, V> forComparator(Comparator<? super K> comparator) {
- if (comparator == NATURAL_ORDER) {
- return (ImmutableSortedMap) NATURAL_EMPTY_MAP;
- }
- return new EmptyImmutableSortedMap<K, V>(comparator);
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedSet.java
index ff45a39..b21896b 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableSortedSet.java
@@ -25,6 +25,6 @@ import java.util.Comparator;
*/
class EmptyImmutableSortedSet<E> extends ImmutableSortedSet<E> {
EmptyImmutableSortedSet(Comparator<? super E> comparator) {
- super(Sets.newTreeSet(comparator));
+ super(comparator);
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumBiMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumBiMap.java
index 46fa641..f6d7e90 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumBiMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumBiMap.java
@@ -17,7 +17,6 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
@@ -28,10 +27,6 @@ import java.util.Map;
* A {@code BiMap} backed by two {@code EnumMap} instances. Null keys and values
* are not permitted. An {@code EnumBiMap} and its inverse are both
* serializable.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap">
- * {@code BiMap}</a>.
*
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
@@ -106,15 +101,5 @@ public final class EnumBiMap<K extends Enum<K>, V extends Enum<V>>
public Class<V> valueType() {
return valueType;
}
-
- @Override
- K checkKey(K key) {
- return checkNotNull(key);
- }
-
- @Override
- V checkValue(V value) {
- return checkNotNull(value);
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumHashBiMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumHashBiMap.java
index 3d9503f..dce8d66 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumHashBiMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumHashBiMap.java
@@ -16,8 +16,6 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.GwtCompatible;
import java.util.EnumMap;
@@ -30,10 +28,6 @@ import javax.annotation.Nullable;
* a {@code HashMap} instance for values-to-keys. Null keys are not permitted,
* but null values are. An {@code EnumHashBiMap} and its inverse are both
* serializable.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap">
- * {@code BiMap}</a>.
*
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
@@ -78,12 +72,7 @@ public final class EnumHashBiMap<K extends Enum<K>, V>
this.keyType = keyType;
}
- // Overriding these 3 methods to show that values may be null (but not keys)
-
- @Override
- K checkKey(K key) {
- return checkNotNull(key);
- }
+ // Overriding these two methods to show that values may be null (but not keys)
@Override public V put(K key, @Nullable V value) {
return super.put(key, value);
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumMultiset.java
index 4e769fb..589706b 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumMultiset.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EnumMultiset.java
@@ -23,10 +23,6 @@ import java.util.Iterator;
/**
* Multiset implementation backed by an {@link EnumMap}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
*
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -54,19 +50,6 @@ public final class EnumMultiset<E extends Enum<E>> extends AbstractMapBasedMulti
Iterables.addAll(multiset, elements);
return multiset;
}
-
- /**
- * Returns a new {@code EnumMultiset} instance containing the given elements. Unlike
- * {@link EnumMultiset#create(Iterable)}, this method does not produce an exception on an empty
- * iterable.
- *
- * @since 14.0
- */
- public static <E extends Enum<E>> EnumMultiset<E> create(Iterable<E> elements, Class<E> type) {
- EnumMultiset<E> result = create(type);
- Iterables.addAll(result, elements);
- return result;
- }
private transient Class<E> type;
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/FluentIterable.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/FluentIterable.java
deleted file mode 100644
index 7c08944..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/FluentIterable.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a
- * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set
- * of elements. The following types of methods are provided on {@code FluentIterable}:
- * <ul>
- * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents
- * of the current one (for example {@link #transform})
- * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or
- * array (for example {@link #toList})
- * <li>element extraction methods which facilitate the retrieval of certain elements (for example
- * {@link #last})
- * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example
- * {@link #anyMatch})
- * </ul>
- *
- * <p>Here is an example that merges the lists returned by two separate database calls, transforms
- * it by invoking {@code toString()} on each element, and returns the first 10 elements as an
- * {@code ImmutableList}: <pre> {@code
- *
- * FluentIterable
- * .from(database.getClientList())
- * .filter(activeInLastMonth())
- * .transform(Functions.toStringFunction())
- * .limit(10)
- * .toList();}</pre>
- *
- * Anything which can be done using {@code FluentIterable} could be done in a different fashion
- * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of
- * operations significantly more concise.
- *
- * @author Marcin Mikosik
- * @since 12.0
- */
-@GwtCompatible(emulated = true)
-public abstract class FluentIterable<E> implements Iterable<E> {
- // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof
- // checks on the _original_ iterable when FluentIterable.from is used.
- private final Iterable<E> iterable;
-
- /** Constructor for use by subclasses. */
- protected FluentIterable() {
- this.iterable = this;
- }
-
- FluentIterable(Iterable<E> iterable) {
- this.iterable = checkNotNull(iterable);
- }
-
- /**
- * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it
- * is already a {@code FluentIterable}.
- */
- public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
- return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable
- : new FluentIterable<E>(iterable) {
- @Override
- public Iterator<E> iterator() {
- return iterable.iterator();
- }
- };
- }
-
- /**
- * Construct a fluent iterable from another fluent iterable. This is obviously never necessary,
- * but is intended to help call out cases where one migration from {@code Iterable} to
- * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}.
- *
- * @deprecated instances of {@code FluentIterable} don't need to be converted to
- * {@code FluentIterable}
- */
- @Deprecated
- public static <E> FluentIterable<E> from(FluentIterable<E> iterable) {
- return checkNotNull(iterable);
- }
-
- /**
- * Returns a string representation of this fluent iterable, with the format
- * {@code [e1, e2, ..., en]}.
- */
- @Override
- public String toString() {
- return Iterables.toString(iterable);
- }
-
- /**
- * Returns the number of elements in this fluent iterable.
- */
- public final int size() {
- return Iterables.size(iterable);
- }
-
- /**
- * Returns {@code true} if this fluent iterable contains any object for which
- * {@code equals(element)} is true.
- */
- public final boolean contains(@Nullable Object element) {
- return Iterables.contains(iterable, element);
- }
-
- /**
- * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of
- * this fluent iterable.
- *
- * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After
- * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in
- * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until
- * this fluent iterable is empty.
- *
- * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You
- * should use an explicit {@code break} or be certain that you will eventually remove all the
- * elements.
- */
- public final FluentIterable<E> cycle() {
- return from(Iterables.cycle(iterable));
- }
-
- /**
- * Returns the elements from this fluent iterable that satisfy a predicate. The
- * resulting fluent iterable's iterator does not support {@code remove()}.
- */
- public final FluentIterable<E> filter(Predicate<? super E> predicate) {
- return from(Iterables.filter(iterable, predicate));
- }
-
- /**
- * Returns {@code true} if any element in this fluent iterable satisfies the predicate.
- */
- public final boolean anyMatch(Predicate<? super E> predicate) {
- return Iterables.any(iterable, predicate);
- }
-
- /**
- * Returns {@code true} if every element in this fluent iterable satisfies the predicate.
- * If this fluent iterable is empty, {@code true} is returned.
- */
- public final boolean allMatch(Predicate<? super E> predicate) {
- return Iterables.all(iterable, predicate);
- }
-
- /**
- * Returns an {@link Optional} containing the first element in this fluent iterable that
- * satisfies the given predicate, if such an element exists.
- *
- * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null}
- * is matched in this fluent iterable, a {@link NullPointerException} will be thrown.
- */
- public final Optional<E> firstMatch(Predicate<? super E> predicate) {
- return Iterables.tryFind(iterable, predicate);
- }
-
- /**
- * Returns a fluent iterable that applies {@code function} to each element of this
- * fluent iterable.
- *
- * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's
- * iterator does. After a successful {@code remove()} call, this fluent iterable no longer
- * contains the corresponding element.
- */
- public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
- return from(Iterables.transform(iterable, function));
- }
-
- /**
- * Applies {@code function} to each element of this fluent iterable and returns
- * a fluent iterable with the concatenated combination of results. {@code function}
- * returns an Iterable of results.
- *
- * <p>The returned fluent iterable's iterator supports {@code remove()} if this
- * function-returned iterables' iterator does. After a successful {@code remove()} call,
- * the returned fluent iterable no longer contains the corresponding element.
- *
- * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0)
- */
- public <T> FluentIterable<T> transformAndConcat(
- Function<? super E, ? extends Iterable<? extends T>> function) {
- return from(Iterables.concat(transform(function)));
- }
-
- /**
- * Returns an {@link Optional} containing the first element in this fluent iterable.
- * If the iterable is empty, {@code Optional.absent()} is returned.
- *
- * @throws NullPointerException if the first element is null; if this is a possibility, use
- * {@code iterator().next()} or {@link Iterables#getFirst} instead.
- */
- public final Optional<E> first() {
- Iterator<E> iterator = iterable.iterator();
- return iterator.hasNext()
- ? Optional.of(iterator.next())
- : Optional.<E>absent();
- }
-
- /**
- * Returns an {@link Optional} containing the last element in this fluent iterable.
- * If the iterable is empty, {@code Optional.absent()} is returned.
- *
- * @throws NullPointerException if the last element is null; if this is a possibility, use
- * {@link Iterables#getLast} instead.
- */
- public final Optional<E> last() {
- // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE
-
- // TODO(kevinb): Support a concurrently modified collection?
- if (iterable instanceof List) {
- List<E> list = (List<E>) iterable;
- if (list.isEmpty()) {
- return Optional.absent();
- }
- return Optional.of(list.get(list.size() - 1));
- }
- Iterator<E> iterator = iterable.iterator();
- if (!iterator.hasNext()) {
- return Optional.absent();
- }
-
- /*
- * TODO(kevinb): consider whether this "optimization" is worthwhile. Users
- * with SortedSets tend to know they are SortedSets and probably would not
- * call this method.
- */
- if (iterable instanceof SortedSet) {
- SortedSet<E> sortedSet = (SortedSet<E>) iterable;
- return Optional.of(sortedSet.last());
- }
-
- while (true) {
- E current = iterator.next();
- if (!iterator.hasNext()) {
- return Optional.of(current);
- }
- }
- }
-
- /**
- * Returns a view of this fluent iterable that skips its first {@code numberToSkip}
- * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements,
- * the returned fluent iterable skips all of its elements.
- *
- * <p>Modifications to this fluent iterable before a call to {@code iterator()} are
- * reflected in the returned fluent iterable. That is, the its iterator skips the first
- * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()}
- * is called.
- *
- * <p>The returned fluent iterable's iterator supports {@code remove()} if the
- * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i>
- * possible to delete the last skipped element by immediately calling {@code remove()} on the
- * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call
- * to {@code * remove()} before a call to {@code next()} will throw an
- * {@link IllegalStateException}.
- */
- public final FluentIterable<E> skip(int numberToSkip) {
- return from(Iterables.skip(iterable, numberToSkip));
- }
-
- /**
- * Creates a fluent iterable with the first {@code size} elements of this
- * fluent iterable. If this fluent iterable does not contain that many elements,
- * the returned fluent iterable will have the same behavior as this fluent iterable.
- * The returned fluent iterable's iterator supports {@code remove()} if this
- * fluent iterable's iterator does.
- *
- * @param size the maximum number of elements in the returned fluent iterable
- * @throws IllegalArgumentException if {@code size} is negative
- */
- public final FluentIterable<E> limit(int size) {
- return from(Iterables.limit(iterable, size));
- }
-
- /**
- * Determines whether this fluent iterable is empty.
- */
- public final boolean isEmpty() {
- return !iterable.iterator().hasNext();
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in
- * proper sequence.
- *
- * @since 14.0 (since 12.0 as {@code toImmutableList()}).
- */
- public final ImmutableList<E> toList() {
- return ImmutableList.copyOf(iterable);
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this {@code
- * FluentIterable} in the order specified by {@code comparator}. To produce an {@code
- * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}.
- *
- * @param comparator the function by which to sort list elements
- * @throws NullPointerException if any element is null
- * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}).
- */
- @Beta
- public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) {
- return Ordering.from(comparator).immutableSortedCopy(iterable);
- }
-
- /**
- * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with
- * duplicates removed.
- *
- * @since 14.0 (since 12.0 as {@code toImmutableSet()}).
- */
- public final ImmutableSet<E> toSet() {
- return ImmutableSet.copyOf(iterable);
- }
-
- /**
- * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code
- * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by
- * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted
- * by its natural ordering, use {@code toSortedSet(Ordering.natural())}.
- *
- * @param comparator the function by which to sort set elements
- * @throws NullPointerException if any element is null
- * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}).
- */
- public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) {
- return ImmutableSortedSet.copyOf(comparator, iterable);
- }
-
- /**
- * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in
- * the same order, mapped to values by the given function. If this iterable contains duplicate
- * elements, the returned map will contain each distinct element once in the order it first
- * appears.
- *
- * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code
- * valueFunction} produces {@code null} for any key
- * @since 14.0
- */
- public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) {
- return Maps.toMap(iterable, valueFunction);
- }
-
- /**
- * Creates an index {@code ImmutableListMultimap} that contains the results of applying a
- * specified function to each item in this {@code FluentIterable} of values. Each element of this
- * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same
- * size as this iterable. The key used to store that value in the multimap will be the result of
- * calling the function on that value. The resulting multimap is created as an immutable snapshot.
- * In the returned multimap, keys appear in the order they are first encountered, and the values
- * corresponding to each key appear in the same order as they are encountered.
- *
- * @param keyFunction the function used to produce the key for each value
- * @throws NullPointerException if any of the following cases is true:
- * <ul>
- * <li>{@code keyFunction} is null
- * <li>An element in this fluent iterable is null
- * <li>{@code keyFunction} returns {@code null} for any element of this iterable
- * </ul>
- * @since 14.0
- */
- public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) {
- return Multimaps.index(iterable, keyFunction);
- }
-
- /**
- * Returns an immutable map for which the {@link java.util.Map#values} are the elements of this
- * {@code FluentIterable} in the given order, and each key is the product of invoking a supplied
- * function on its corresponding value.
- *
- * @param keyFunction the function used to produce the key for each value
- * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
- * value in this fluent iterable
- * @throws NullPointerException if any element of this fluent iterable is null, or if
- * {@code keyFunction} produces {@code null} for any value
- * @since 14.0
- */
- public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) {
- return Maps.uniqueIndex(iterable, keyFunction);
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this
- * fluent iterable in proper sequence.
- *
- * @deprecated Use {@link #toList()} instead. This method is scheduled for removal in Guava 15.0.
- */
- @Deprecated
- public final ImmutableList<E> toImmutableList() {
- return toList();
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this
- * {@code FluentIterable} in the order specified by {@code comparator}. To produce an
- * {@code ImmutableList} sorted by its natural ordering, use
- * {@code toSortedImmutableList(Ordering.natural())}.
- *
- * @param comparator the function by which to sort list elements
- * @throws NullPointerException if any element is null
- * @since 13.0
- * @deprecated Use {@link #toSortedList(Comparator)} instead. This method is scheduled for removal
- * in Guava 15.0.
- */
- @Deprecated
- public final ImmutableList<E> toSortedImmutableList(Comparator<? super E> comparator) {
- return toSortedList(comparator);
- }
-
- /**
- * Returns an {@code ImmutableSet} containing all of the elements from this
- * fluent iterable with duplicates removed.
- *
- * @deprecated Use {@link #toSet()} instead. This method is scheduled for removal in Guava 15.0.
- */
- @Deprecated
- public final ImmutableSet<E> toImmutableSet() {
- return toSet();
- }
-
- /**
- * Returns an {@code ImmutableSortedSet} containing all of the elements from this
- * {@code FluentIterable} in the order specified by {@code comparator}, with duplicates
- * (determined by {@code comparator.compare(x, y) == 0}) removed. To produce an
- * {@code ImmutableSortedSet} sorted by its natural ordering, use
- * {@code toImmutableSortedSet(Ordering.natural())}.
- *
- * @param comparator the function by which to sort set elements
- * @throws NullPointerException if any element is null
- * @deprecated Use {@link #toSortedSet(Comparator)} instead. This method is scheduled for removal
- * in Guava 15.0.
- */
- @Deprecated
- public final ImmutableSortedSet<E> toImmutableSortedSet(Comparator<? super E> comparator) {
- return toSortedSet(comparator);
- }
-
- /**
- * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to
- * calling {@code Iterables.addAll(collection, this)}.
- *
- * @param collection the collection to copy elements to
- * @return {@code collection}, for convenience
- * @since 14.0
- */
- public final <C extends Collection<? super E>> C copyInto(C collection) {
- checkNotNull(collection);
- if (iterable instanceof Collection) {
- collection.addAll(Collections2.cast(iterable));
- } else {
- for (E item : iterable) {
- collection.add(item);
- }
- }
- return collection;
- }
-
- /**
- * Returns the element at the specified position in this fluent iterable.
- *
- * @param position position of the element to return
- * @return the element at the specified position in this fluent iterable
- * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to
- * the size of this fluent iterable
- */
- public final E get(int position) {
- return Iterables.get(iterable, position);
- }
-
- /**
- * Function that transforms {@code Iterable<E>} into a fluent iterable.
- */
- private static class FromIterableFunction<E>
- implements Function<Iterable<E>, FluentIterable<E>> {
- @Override
- public FluentIterable<E> apply(Iterable<E> fromObject) {
- return FluentIterable.from(fromObject);
- }
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableList.java
deleted file mode 100644
index 1327ba0..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableList.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Collection;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-/**
- * GWT emulated version of {@link ImmutableList}.
- * TODO(cpovirk): more doc
- *
- * @author Hayward Chan
- */
-abstract class ForwardingImmutableList<E> extends ImmutableList<E> {
-
- ForwardingImmutableList() {
- }
-
- abstract List<E> delegateList();
-
- public int indexOf(@Nullable Object object) {
- return delegateList().indexOf(object);
- }
-
- public int lastIndexOf(@Nullable Object object) {
- return delegateList().lastIndexOf(object);
- }
-
- public E get(int index) {
- return delegateList().get(index);
- }
-
- public ImmutableList<E> subList(int fromIndex, int toIndex) {
- return unsafeDelegateList(delegateList().subList(fromIndex, toIndex));
- }
-
- @Override public Object[] toArray() {
- // Note that ArrayList.toArray() doesn't work here because it returns E[]
- // instead of Object[].
- return delegateList().toArray(new Object[size()]);
- }
-
- @Override public boolean equals(Object obj) {
- return delegateList().equals(obj);
- }
-
- @Override public int hashCode() {
- return delegateList().hashCode();
- }
-
- @Override public UnmodifiableIterator<E> iterator() {
- return Iterators.unmodifiableIterator(delegateList().iterator());
- }
-
- @Override public boolean contains(@Nullable Object object) {
- return object != null && delegateList().contains(object);
- }
-
- @Override public boolean containsAll(Collection<?> targets) {
- return delegateList().containsAll(targets);
- }
-
- public int size() {
- return delegateList().size();
- }
-
- @Override public boolean isEmpty() {
- return delegateList().isEmpty();
- }
-
- @Override public <T> T[] toArray(T[] other) {
- return delegateList().toArray(other);
- }
-
- @Override public String toString() {
- return delegateList().toString();
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableMap.java
deleted file mode 100644
index 9ef0d96..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableMap.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * GWT implementation of {@link ImmutableMap} that forwards to another map.
- *
- * @author Hayward Chan
- */
-public abstract class ForwardingImmutableMap<K, V> extends ImmutableMap<K, V> {
-
- final transient Map<K, V> delegate;
-
- ForwardingImmutableMap(Map<? extends K, ? extends V> delegate) {
- this.delegate = Collections.unmodifiableMap(delegate);
- }
-
- @SuppressWarnings("unchecked")
- ForwardingImmutableMap(Entry<? extends K, ? extends V>... entries) {
- Map<K, V> delegate = Maps.newLinkedHashMap();
- for (Entry<? extends K, ? extends V> entry : entries) {
- K key = checkNotNull(entry.getKey());
- V previous = delegate.put(key, checkNotNull(entry.getValue()));
- if (previous != null) {
- throw new IllegalArgumentException("duplicate key: " + key);
- }
- }
- this.delegate = Collections.unmodifiableMap(delegate);
- }
-
- boolean isPartialView() {
- return false;
- }
-
- public final boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- public final boolean containsKey(@Nullable Object key) {
- return Maps.safeContainsKey(delegate, key);
- }
-
- public final boolean containsValue(@Nullable Object value) {
- return delegate.containsValue(value);
- }
-
- public V get(@Nullable Object key) {
- return (key == null) ? null : Maps.safeGet(delegate, key);
- }
-
- @Override ImmutableSet<Entry<K, V>> createEntrySet() {
- return ImmutableSet.unsafeDelegate(
- new ForwardingSet<Entry<K, V>>() {
- @Override protected Set<Entry<K, V>> delegate() {
- return delegate.entrySet();
- }
- @Override public boolean contains(Object object) {
- if (object instanceof Entry<?, ?>
- && ((Entry<?, ?>) object).getKey() == null) {
- return false;
- }
- try {
- return super.contains(object);
- } catch (ClassCastException e) {
- return false;
- }
- }
- @Override public <T> T[] toArray(T[] array) {
- T[] result = super.toArray(array);
- if (size() < result.length) {
- // It works around a GWT bug where elements after last is not
- // properly null'ed.
- result[size()] = null;
- }
- return result;
- }
- });
- }
-
- @Override ImmutableSet<K> createKeySet() {
- return ImmutableSet.unsafeDelegate(delegate.keySet());
- }
-
- @Override ImmutableCollection<V> createValues() {
- return ImmutableCollection.unsafeDelegate(delegate.values());
- }
-
- @Override public int size() {
- return delegate.size();
- }
-
- @Override public boolean equals(@Nullable Object object) {
- return delegate.equals(object);
- }
-
- @Override public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override public String toString() {
- return delegate.toString();
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableSet.java
deleted file mode 100644
index 6db3339..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ForwardingImmutableSet.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * GWT implementation of {@link ImmutableSet} that forwards to another {@code Set} implementation.
- *
- * @author Hayward Chan
- */
-@SuppressWarnings("serial") // Serialization only done in GWT.
-public abstract class ForwardingImmutableSet<E> extends ImmutableSet<E> {
- private final transient Set<E> delegate;
-
- ForwardingImmutableSet(Set<E> delegate) {
- // TODO(cpovirk): are we over-wrapping?
- this.delegate = Collections.unmodifiableSet(delegate);
- }
-
- @Override public UnmodifiableIterator<E> iterator() {
- return Iterators.unmodifiableIterator(delegate.iterator());
- }
-
- @Override public boolean contains(@Nullable Object object) {
- return object != null && delegate.contains(object);
- }
-
- @Override public boolean containsAll(Collection<?> targets) {
- return delegate.containsAll(targets);
- }
-
- @Override public int size() {
- return delegate.size();
- }
-
- @Override public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- @Override public Object[] toArray() {
- return delegate.toArray();
- }
-
- @Override public <T> T[] toArray(T[] other) {
- return delegate.toArray(other);
- }
-
- @Override public String toString() {
- return delegate.toString();
- }
-
- // TODO(cpovirk): equals(), as well, in case it's any faster than Sets.equalsImpl?
-
- @Override public int hashCode() {
- return delegate.hashCode();
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/GenericMapMaker.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/GenericMapMaker.java
index b3b4319..b75f4bf 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/GenericMapMaker.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/GenericMapMaker.java
@@ -52,11 +52,28 @@ public abstract class GenericMapMaker<K0, V0> {
abstract GenericMapMaker<K0, V0> maximumSize(int maximumSize);
/**
+ * See {@link MapMaker#strongKeys}.
+ */
+ abstract GenericMapMaker<K0, V0> strongKeys();
+
+ /**
* See {@link MapMaker#concurrencyLevel}.
*/
public abstract GenericMapMaker<K0, V0> concurrencyLevel(int concurrencyLevel);
/**
+ * See {@link MapMaker#strongValues}.
+ */
+ abstract GenericMapMaker<K0, V0> strongValues();
+
+ /**
+ * See {@link MapMaker#expiration}.
+ */
+ @Deprecated
+ public
+ abstract GenericMapMaker<K0, V0> expiration(long duration, TimeUnit unit);
+
+ /**
* See {@link MapMaker#expireAfterWrite}.
*/
abstract GenericMapMaker<K0, V0> expireAfterWrite(long duration, TimeUnit unit);
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashBiMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashBiMap.java
index 10e4e35..15c3f9e 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashBiMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashBiMap.java
@@ -16,16 +16,22 @@
package com.google.common.collect;
+import com.google.common.annotations.GwtCompatible;
+
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
/**
- * GWT emulation of {@code HashBiMap} that just delegates to two HashMaps.
+ * A {@link BiMap} backed by two {@link HashMap} instances. This implementation
+ * allows null keys and values. A {@code HashBiMap} and its inverse are both
+ * serializable.
*
* @author Mike Bostock
+ * @since 2.0 (imported from Google Collections Library)
*/
+@GwtCompatible(emulated = true)
public final class HashBiMap<K, V> extends AbstractBiMap<K, V> {
/**
@@ -79,3 +85,4 @@ public final class HashBiMap<K, V> extends AbstractBiMap<K, V> {
return super.forcePut(key, value);
}
}
+
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashMultimap.java
index 582c2f7..55ecd46 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/HashMultimap.java
@@ -43,7 +43,7 @@ import java.util.Set;
*/
@GwtCompatible(serializable = true, emulated = true)
public final class HashMultimap<K, V> extends AbstractSetMultimap<K, V> {
- private static final int DEFAULT_VALUES_PER_KEY = 2;
+ private static final int DEFAULT_VALUES_PER_KEY = 8;
@VisibleForTesting
transient int expectedValuesPerKey = DEFAULT_VALUES_PER_KEY;
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList.java
index 1279bee..a790487 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2010 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,39 +16,15 @@
package com.google.common.collect;
-import com.google.common.annotations.GwtCompatible;
+import java.util.List;
/**
- * List returned by {@link ImmutableCollection#asList} that delegates {@code contains} checks
- * to the backing collection.
+ * GWT emulation of {@link ImmutableAsList}.
*
- * @author Jared Levy
- * @author Louis Wasserman
+ * @author Hayward Chan
*/
-@GwtCompatible(serializable = true, emulated = true)
-@SuppressWarnings("serial")
-abstract class ImmutableAsList<E> extends ImmutableList<E> {
- abstract ImmutableCollection<E> delegateCollection();
-
- @Override public boolean contains(Object target) {
- // The collection's contains() is at least as fast as ImmutableList's
- // and is often faster.
- return delegateCollection().contains(target);
- }
-
- @Override
- public int size() {
- return delegateCollection().size();
- }
-
- @Override
- public boolean isEmpty() {
- return delegateCollection().isEmpty();
- }
-
- @Override
- boolean isPartialView() {
- return delegateCollection().isPartialView();
+final class ImmutableAsList<E> extends RegularImmutableList<E> {
+ ImmutableAsList(List<E> delegate) {
+ super(delegate);
}
}
-
diff --git a/guava-gwt/src/com/google/common/collect/RegularImmutableAsList_CustomFieldSerializer.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java
index f41b8cf..1712f5a 100644
--- a/guava-gwt/src/com/google/common/collect/RegularImmutableAsList_CustomFieldSerializer.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java
@@ -16,35 +16,35 @@
package com.google.common.collect;
-import com.google.common.annotations.GwtCompatible;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+import com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase;
+
+import java.util.ArrayList;
+import java.util.List;
/**
- * This class implements the server-side GWT serialization of
- * {@link RegularImmutableAsList}.
+ * This class implements the client-side GWT serialization of
+ * {@link ImmutableAsList}.
*
* @author Hayward Chan
*/
-@GwtCompatible(emulated = true)
-public class RegularImmutableAsList_CustomFieldSerializer {
+public class ImmutableAsList_CustomFieldSerializer {
public static void deserialize(SerializationStreamReader reader,
- RegularImmutableAsList<?> instance) {
+ RegularImmutableList<?> instance) {
}
- public static RegularImmutableAsList<Object> instantiate(
+ public static ImmutableAsList<Object> instantiate(
SerializationStreamReader reader) throws SerializationException {
- @SuppressWarnings("unchecked") // serialization is necessarily type unsafe
- ImmutableCollection<Object> delegateCollection = (ImmutableCollection) reader.readObject();
- ImmutableList<?> delegateList = (ImmutableList<?>) reader.readObject();
- return new RegularImmutableAsList<Object>(delegateCollection, delegateList);
+ List<Object> elements = new ArrayList<Object>();
+ Collection_CustomFieldSerializerBase.deserialize(reader, elements);
+ return new ImmutableAsList<Object>(elements);
}
public static void serialize(SerializationStreamWriter writer,
- RegularImmutableAsList<?> instance) throws SerializationException {
- writer.writeObject(instance.delegateCollection());
- writer.writeObject(instance.delegateList());
+ ImmutableAsList<?> instance) throws SerializationException {
+ Collection_CustomFieldSerializerBase.serialize(writer, instance);
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableBiMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableBiMap.java
index c8cdebb..59cb788 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableBiMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableBiMap.java
@@ -16,8 +16,7 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
+import java.util.Collections;
import java.util.Map;
/**
@@ -25,18 +24,20 @@ import java.util.Map;
*
* @author Hayward Chan
*/
-public abstract class ImmutableBiMap<K, V> extends ForwardingImmutableMap<K, V>
+public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K,V>
implements BiMap<K, V> {
+ private static final ImmutableBiMap<Object, Object> EMPTY_IMMUTABLE_BIMAP
+ = new EmptyBiMap();
+
// Casting to any type is safe because the set will never hold any elements.
@SuppressWarnings("unchecked")
public static <K, V> ImmutableBiMap<K, V> of() {
- return (ImmutableBiMap<K, V>) EmptyImmutableBiMap.INSTANCE;
+ return (ImmutableBiMap<K, V>) EMPTY_IMMUTABLE_BIMAP;
}
public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1) {
- return new SingletonImmutableBiMap<K, V>(
- checkNotNull(k1), checkNotNull(v1));
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1));
}
public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1, K k2, V v2) {
@@ -117,4 +118,14 @@ public abstract class ImmutableBiMap<K, V> extends ForwardingImmutableMap<K, V>
public final V forcePut(K key, V value) {
throw new UnsupportedOperationException();
}
+
+ @SuppressWarnings("serial")
+ static class EmptyBiMap extends ImmutableBiMap<Object, Object> {
+ EmptyBiMap() {
+ super(Collections.emptyMap());
+ }
+ @Override public ImmutableBiMap<Object, Object> inverse() {
+ return this;
+ }
+ }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableCollection.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableCollection.java
index 936f900..04bd060 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableCollection.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableCollection.java
@@ -16,15 +16,16 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.io.Serializable;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import javax.annotation.Nullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* GWT emulated version of {@link ImmutableCollection}.
*
@@ -88,10 +89,6 @@ public abstract class ImmutableCollection<E>
return size() == 0;
}
- @Override public String toString() {
- return Collections2.toStringImpl(this);
- }
-
public final boolean add(E e) {
throw new UnsupportedOperationException();
}
@@ -130,13 +127,15 @@ public abstract class ImmutableCollection<E>
case 1:
return ImmutableList.of(iterator().next());
default:
- return new RegularImmutableAsList<E>(this, toArray());
+ @SuppressWarnings("unchecked")
+ E[] castedArray = (E[]) toArray();
+ return new ImmutableAsList<E>(Arrays.asList(castedArray));
}
}
static <E> ImmutableCollection<E> unsafeDelegate(Collection<E> delegate) {
return new ForwardingImmutableCollection<E>(delegate);
}
-
+
boolean isPartialView(){
return false;
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumMap.java
deleted file mode 100644
index 86f0c26..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumMap.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-
-/**
- * GWT emulation of {@link ImmutableEnumMap}. The type parameter is not bounded
- * by {@code Enum<E>} to avoid code-size bloat.
- *
- * @author Hayward Chan
- */
-final class ImmutableEnumMap<K, V> extends ForwardingImmutableMap<K, V> {
- static <K, V> ImmutableMap<K, V> asImmutable(Map<K, V> map) {
- for (Map.Entry<K, V> entry : checkNotNull(map).entrySet()) {
- checkNotNull(entry.getKey());
- checkNotNull(entry.getValue());
- }
- return new ImmutableEnumMap<K, V>(map);
- }
-
- ImmutableEnumMap(Map<? extends K, ? extends V> delegate) {
- super(WellBehavedMap.wrap(delegate));
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumSet.java
index a9c21c8..14506c2 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableEnumSet.java
@@ -24,18 +24,7 @@ import java.util.Set;
*
* @author Hayward Chan
*/
-final class ImmutableEnumSet<E> extends ForwardingImmutableSet<E> {
- static <E> ImmutableSet<E> asImmutable(Set<E> delegate) {
- switch (delegate.size()) {
- case 0:
- return ImmutableSet.of();
- case 1:
- return ImmutableSet.of(Iterables.getOnlyElement(delegate));
- default:
- return new ImmutableEnumSet<E>(delegate);
- }
- }
-
+final class ImmutableEnumSet<E> extends ImmutableSet<E> {
public ImmutableEnumSet(Set<E> delegate) {
super(delegate);
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableList.java
index ca5a95a..db67daa 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableList.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableList.java
@@ -26,20 +26,30 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.RandomAccess;
import javax.annotation.Nullable;
/**
* GWT emulated version of {@link ImmutableList}.
- * TODO(cpovirk): more doc
*
* @author Hayward Chan
*/
@SuppressWarnings("serial") // we're overriding default serialization
-public abstract class ImmutableList<E> extends ImmutableCollection<E>
+public abstract class ImmutableList<E> extends ForwardingImmutableCollection<E>
implements List<E>, RandomAccess {
- ImmutableList() {}
+
+ private transient final List<E> delegate;
+
+ ImmutableList(List<E> delegate) {
+ super(delegate);
+ this.delegate = Collections.unmodifiableList(delegate);
+ }
+
+ ImmutableList() {
+ this(Collections.<E>emptyList());
+ }
// Casting to any type is safe because the list will never hold any elements.
@SuppressWarnings("unchecked")
@@ -116,6 +126,19 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
return new RegularImmutableList<E>(ImmutableList.<E>nullCheckedList(array));
}
+ public static <E> ImmutableList<E> of(E[] elements) {
+ checkNotNull(elements); // for GWT
+ switch (elements.length) {
+ case 0:
+ return ImmutableList.of();
+ case 1:
+ return new SingletonImmutableList<E>(elements[0]);
+ default:
+ return new RegularImmutableList<E>(
+ ImmutableList.<E>nullCheckedList(elements));
+ }
+ }
+
private static void arrayCopy(Object[] dest, int pos, Object... source) {
System.arraycopy(source, 0, dest, pos, source.length);
}
@@ -165,7 +188,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
}
// Factory method that skips the null checks. Used only when the elements
- // are guaranteed to be non-null.
+ // are guaranteed to be null.
static <E> ImmutableList<E> unsafeDelegateList(List<? extends E> list) {
switch (list.size()) {
case 0:
@@ -179,14 +202,8 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
}
}
- /**
- * Views the array as an immutable list. The array must have only {@code E} elements.
- *
- * <p>The array must be internally created.
- */
- @SuppressWarnings("unchecked") // caller is reponsible for getting this right
- static <E> ImmutableList<E> asImmutableList(Object[] elements) {
- return unsafeDelegateList((List) Arrays.asList(elements));
+ static <E> ImmutableList<E> backedBy(E[] elements) {
+ return unsafeDelegateList(Arrays.asList(elements));
}
private static <E> List<E> nullCheckedList(Object... array) {
@@ -200,14 +217,12 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
return Arrays.asList(castedArray);
}
- @Override
public int indexOf(@Nullable Object object) {
- return (object == null) ? -1 : Lists.indexOfImpl(this, object);
+ return delegate.indexOf(object);
}
- @Override
public int lastIndexOf(@Nullable Object object) {
- return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object);
+ return delegate.lastIndexOf(object);
}
public final boolean addAll(int index, Collection<? extends E> newElements) {
@@ -226,45 +241,44 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
throw new UnsupportedOperationException();
}
- @Override public UnmodifiableIterator<E> iterator() {
- return listIterator();
+ public E get(int index) {
+ return delegate.get(index);
}
- @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
- return unsafeDelegateList(Lists.subListImpl(this, fromIndex, toIndex));
+ public ImmutableList<E> subList(int fromIndex, int toIndex) {
+ return unsafeDelegateList(delegate.subList(fromIndex, toIndex));
}
- @Override public UnmodifiableListIterator<E> listIterator() {
- return listIterator(0);
+ public ListIterator<E> listIterator() {
+ return delegate.listIterator();
}
- @Override public UnmodifiableListIterator<E> listIterator(int index) {
- return new AbstractIndexedListIterator<E>(size(), index) {
- @Override
- protected E get(int index) {
- return ImmutableList.this.get(index);
- }
- };
+ public ListIterator<E> listIterator(int index) {
+ return delegate.listIterator(index);
}
@Override public ImmutableList<E> asList() {
return this;
}
+
+ public ImmutableList<E> reverse(){
+ List<E> list = Lists.newArrayList(this);
+ Collections.reverse(list);
+ return unsafeDelegateList(list);
+ }
- @Override
- public boolean equals(@Nullable Object obj) {
- return Lists.equalsImpl(this, obj);
+ @Override public Object[] toArray() {
+ // Note that ArrayList.toArray() doesn't work here because it returns E[]
+ // instead of Object[].
+ return delegate.toArray(new Object[size()]);
}
- @Override
- public int hashCode() {
- return Lists.hashCodeImpl(this);
+ @Override public boolean equals(Object obj) {
+ return delegate.equals(obj);
}
- public ImmutableList<E> reverse() {
- List<E> list = Lists.newArrayList(this);
- Collections.reverse(list);
- return unsafeDelegateList(list);
+ @Override public int hashCode() {
+ return delegate.hashCode();
}
public static <E> Builder<E> builder() {
@@ -272,15 +286,9 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
}
public static final class Builder<E> extends ImmutableCollection.Builder<E> {
- private final ArrayList<E> contents;
+ private final ArrayList<E> contents = Lists.newArrayList();
- public Builder() {
- contents = Lists.newArrayList();
- }
-
- Builder(int capacity) {
- contents = Lists.newArrayListWithCapacity(capacity);
- }
+ public Builder() {}
@Override public Builder<E> add(E element) {
contents.add(checkNotNull(element));
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableListMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableListMultimap.java
index 5803848..fe445d9 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableListMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableListMultimap.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
@@ -40,10 +41,6 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this class
* are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
@@ -195,7 +192,7 @@ public class ImmutableListMultimap<K, V>
*
* @since 8.0
*/
- @Override
+ @Beta @Override
public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
super.orderKeysBy(keyComparator);
return this;
@@ -206,7 +203,7 @@ public class ImmutableListMultimap<K, V>
*
* @since 8.0
*/
- @Override
+ @Beta @Override
public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
super.orderValuesBy(valueComparator);
return this;
@@ -286,14 +283,13 @@ public class ImmutableListMultimap<K, V>
/**
* {@inheritDoc}
*
- * <p>Because an inverse of a list multimap can contain multiple pairs with
- * the same key and value, this method returns an {@code
- * ImmutableListMultimap} rather than the {@code ImmutableMultimap} specified
- * in the {@code ImmutableMultimap} class.
+ * <p>Because an inverse of a list multimap can contain multiple pairs with the same key and
+ * value, this method returns an {@code ImmutableListMultimap} rather than the
+ * {@code ImmutableMultimap} specified in the {@code ImmutableMultimap} class.
*
- * @since 11.0
+ * @since 11
*/
- @Override
+ @Beta
public ImmutableListMultimap<V, K> inverse() {
ImmutableListMultimap<V, K> result = inverse;
return (result == null) ? (inverse = invert()) : result;
@@ -313,9 +309,8 @@ public class ImmutableListMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableList<V> removeAll(Object key) {
+ @Override public ImmutableList<V> removeAll(Object key) {
throw new UnsupportedOperationException();
}
@@ -323,9 +318,8 @@ public class ImmutableListMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableList<V> replaceValues(
+ @Override public ImmutableList<V> replaceValues(
K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMap.java
index 410538c..84896b5 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMap.java
@@ -21,10 +21,9 @@ import static com.google.common.collect.Iterables.getOnlyElement;
import java.io.Serializable;
import java.util.Collections;
-import java.util.EnumMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.annotation.Nullable;
@@ -40,15 +39,39 @@ import javax.annotation.Nullable;
* @author Hayward Chan
*/
public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
+
+ private transient final Map<K, V> delegate;
- ImmutableMap() {}
+ ImmutableMap() {
+ this.delegate = Collections.emptyMap();
+ }
+
+ ImmutableMap(Map<? extends K, ? extends V> delegate) {
+ this.delegate = Collections.unmodifiableMap(delegate);
+ }
+
+ @SuppressWarnings("unchecked")
+ ImmutableMap(Entry<? extends K, ? extends V>... entries) {
+ Map<K, V> delegate = Maps.newLinkedHashMap();
+ for (Entry<? extends K, ? extends V> entry : entries) {
+ K key = checkNotNull(entry.getKey());
+ V previous = delegate.put(key, checkNotNull(entry.getValue()));
+ if (previous != null) {
+ throw new IllegalArgumentException("duplicate key: " + key);
+ }
+ }
+ this.delegate = Collections.unmodifiableMap(delegate);
+ }
+ // Casting to any type is safe because the set will never hold any elements.
+ @SuppressWarnings("unchecked")
public static <K, V> ImmutableMap<K, V> of() {
- return ImmutableBiMap.of();
+ return (ImmutableMap<K, V>) EmptyImmutableMap.INSTANCE;
}
public static <K, V> ImmutableMap<K, V> of(K k1, V v1) {
- return ImmutableBiMap.of(k1, v1);
+ return new SingletonImmutableMap<K, V>(
+ checkNotNull(k1), checkNotNull(v1));
}
public static <K, V> ImmutableMap<K, V> of(K k1, V v1, K k2, V v2) {
@@ -94,7 +117,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
}
public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
- if (entry instanceof ImmutableEntry) {
+ if (entry instanceof ImmutableEntry<?, ?>) {
checkNotNull(entry.getKey());
checkNotNull(entry.getValue());
@SuppressWarnings("unchecked") // all supported methods are covariant
@@ -125,7 +148,8 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
return of();
case 1:
Entry<K, V> entry = getOnlyElement(entries);
- return of(entry.getKey(), entry.getValue());
+ return new SingletonImmutableMap<K, V>(
+ entry.getKey(), entry.getValue());
default:
@SuppressWarnings("unchecked")
Entry<K, V>[] entryArray
@@ -141,16 +165,6 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
@SuppressWarnings("unchecked") // safe since map is not writable
ImmutableMap<K, V> kvMap = (ImmutableMap<K, V>) map;
return kvMap;
- } else if (map instanceof EnumMap) {
- EnumMap<?, ?> enumMap = (EnumMap<?, ?>) map;
- for (Map.Entry<?, ?> entry : enumMap.entrySet()) {
- checkNotNull(entry.getKey());
- checkNotNull(entry.getValue());
- }
- @SuppressWarnings("unchecked")
- // immutable collections are safe for covariant casts
- ImmutableMap<K, V> result = ImmutableEnumMap.asImmutable(new EnumMap(enumMap));
- return result;
}
int size = map.size();
@@ -170,8 +184,10 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
return new RegularImmutableMap<K, V>(orderPreservingCopy);
}
}
-
- abstract boolean isPartialView();
+
+ boolean isPartialView(){
+ return false;
+ }
public final V put(K k, V v) {
throw new UnsupportedOperationException();
@@ -189,19 +205,20 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
throw new UnsupportedOperationException();
}
- @Override
- public boolean isEmpty() {
- return size() == 0;
+ public final boolean isEmpty() {
+ return delegate.isEmpty();
}
- @Override
- public boolean containsKey(@Nullable Object key) {
- return get(key) != null;
+ public final boolean containsKey(@Nullable Object key) {
+ return Maps.safeContainsKey(delegate, key);
}
- @Override
- public boolean containsValue(@Nullable Object value) {
- return value != null && Maps.containsValueImpl(this, value);
+ public final boolean containsValue(@Nullable Object value) {
+ return delegate.containsValue(value);
+ }
+
+ public final V get(@Nullable Object key) {
+ return (key == null) ? null : Maps.safeGet(delegate, key);
}
private transient ImmutableSet<Entry<K, V>> cachedEntrySet = null;
@@ -210,22 +227,41 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
if (cachedEntrySet != null) {
return cachedEntrySet;
}
- return cachedEntrySet = createEntrySet();
+ return cachedEntrySet = ImmutableSet.unsafeDelegate(
+ new ForwardingSet<Entry<K, V>>() {
+ @Override protected Set<Entry<K, V>> delegate() {
+ return delegate.entrySet();
+ }
+ @Override public boolean contains(Object object) {
+ if (object instanceof Entry<?, ?>
+ && ((Entry<?, ?>) object).getKey() == null) {
+ return false;
+ }
+ try {
+ return super.contains(object);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ @Override public <T> T[] toArray(T[] array) {
+ T[] result = super.toArray(array);
+ if (size() < result.length) {
+ // It works around a GWT bug where elements after last is not
+ // properly null'ed.
+ result[size()] = null;
+ }
+ return result;
+ }
+ });
}
- abstract ImmutableSet<Entry<K, V>> createEntrySet();
-
private transient ImmutableSet<K> cachedKeySet = null;
public ImmutableSet<K> keySet() {
if (cachedKeySet != null) {
return cachedKeySet;
}
- return cachedKeySet = createKeySet();
- }
-
- ImmutableSet<K> createKeySet() {
- return new ImmutableMapKeySet<K, V>(this);
+ return cachedKeySet = ImmutableSet.unsafeDelegate(delegate.keySet());
}
private transient ImmutableCollection<V> cachedValues = null;
@@ -234,102 +270,22 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
if (cachedValues != null) {
return cachedValues;
}
- return cachedValues = createValues();
- }
-
- // esnickell is editing here
-
- // cached so that this.multimapView().inverse() only computes inverse once
- private transient ImmutableSetMultimap<K, V> multimapView;
-
- public ImmutableSetMultimap<K, V> asMultimap() {
- ImmutableSetMultimap<K, V> result = multimapView;
- return (result == null) ? (multimapView = createMultimapView()) : result;
- }
-
- private ImmutableSetMultimap<K, V> createMultimapView() {
- ImmutableMap<K, ImmutableSet<V>> map = viewValuesAsImmutableSet();
- return new ImmutableSetMultimap<K, V>(map, map.size(), null);
- }
-
- private ImmutableMap<K, ImmutableSet<V>> viewValuesAsImmutableSet() {
- final Map<K, V> outer = this;
- return new ImmutableMap<K, ImmutableSet<V>>() {
- @Override
- public int size() {
- return outer.size();
- }
-
- @Override
- public ImmutableSet<V> get(@Nullable Object key) {
- V outerValue = outer.get(key);
- return outerValue == null ? null : ImmutableSet.of(outerValue);
- }
-
- @Override
- ImmutableSet<Entry<K, ImmutableSet<V>>> createEntrySet() {
- return new ImmutableSet<Entry<K, ImmutableSet<V>>>() {
- @Override
- public UnmodifiableIterator<Entry<K, ImmutableSet<V>>> iterator() {
- final Iterator<Entry<K,V>> outerEntryIterator = outer.entrySet().iterator();
- return new UnmodifiableIterator<Entry<K, ImmutableSet<V>>>() {
- @Override
- public boolean hasNext() {
- return outerEntryIterator.hasNext();
- }
-
- @Override
- public Entry<K, ImmutableSet<V>> next() {
- final Entry<K, V> outerEntry = outerEntryIterator.next();
- return new AbstractMapEntry<K, ImmutableSet<V>>() {
- @Override
- public K getKey() {
- return outerEntry.getKey();
- }
-
- @Override
- public ImmutableSet<V> getValue() {
- return ImmutableSet.of(outerEntry.getValue());
- }
- };
- }
- };
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
-
- @Override
- public int size() {
- return outer.size();
- }
- };
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
- };
+ return cachedValues = ImmutableCollection.unsafeDelegate(delegate.values());
}
- ImmutableCollection<V> createValues() {
- return new ImmutableMapValues<K, V>(this);
+ public int size() {
+ return delegate.size();
}
@Override public boolean equals(@Nullable Object object) {
- return Maps.equalsImpl(this, object);
+ return delegate.equals(object);
}
@Override public int hashCode() {
- // not caching hash code since it could change if map values are mutable
- // in a way that modifies their hash codes
- return entrySet().hashCode();
+ return delegate.hashCode();
}
@Override public String toString() {
- return Maps.toStringImpl(this);
+ return delegate.toString();
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapEntrySet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapEntrySet.java
deleted file mode 100644
index 7a5e580..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapEntrySet.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Map.Entry;
-
-import javax.annotation.Nullable;
-
-/**
- * {@code entrySet()} implementation for {@link ImmutableMap}.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-abstract class ImmutableMapEntrySet<K, V> extends ImmutableSet<Entry<K, V>> {
- ImmutableMapEntrySet() {}
-
- abstract ImmutableMap<K, V> map();
-
- @Override
- public int size() {
- return map().size();
- }
-
- @Override
- public boolean contains(@Nullable Object object) {
- if (object instanceof Entry) {
- Entry<?, ?> entry = (Entry<?, ?>) object;
- V value = map().get(entry.getKey());
- return value != null && value.equals(entry.getValue());
- }
- return false;
- }
-
- @Override
- boolean isPartialView() {
- return map().isPartialView();
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapKeySet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapKeySet.java
deleted file mode 100644
index 78508f4..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapKeySet.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Map.Entry;
-
-import javax.annotation.Nullable;
-
-/**
- * {@code keySet()} implementation for {@link ImmutableMap}.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-final class ImmutableMapKeySet<K, V> extends ImmutableSet<K> {
- private final ImmutableMap<K, V> map;
-
- ImmutableMapKeySet(ImmutableMap<K, V> map) {
- this.map = map;
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public UnmodifiableIterator<K> iterator() {
- return asList().iterator();
- }
-
- @Override
- public boolean contains(@Nullable Object object) {
- return map.containsKey(object);
- }
-
- @Override
- ImmutableList<K> createAsList() {
- final ImmutableList<Entry<K, V>> entryList = map.entrySet().asList();
- return new ImmutableAsList<K>() {
-
- @Override
- public K get(int index) {
- return entryList.get(index).getKey();
- }
-
- @Override
- ImmutableCollection<K> delegateCollection() {
- return ImmutableMapKeySet.this;
- }
-
- };
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapValues.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapValues.java
deleted file mode 100644
index ccf4b7d..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMapValues.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Map.Entry;
-
-/**
- * {@code values()} implementation for {@link ImmutableMap}.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-final class ImmutableMapValues<K, V> extends ImmutableCollection<V> {
- private final ImmutableMap<K, V> map;
-
- ImmutableMapValues(ImmutableMap<K, V> map) {
- this.map = map;
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public UnmodifiableIterator<V> iterator() {
- return Maps.valueIterator(map.entrySet().iterator());
- }
-
- @Override
- public boolean contains(Object object) {
- return map.containsValue(object);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
-
- @Override
- ImmutableList<V> createAsList() {
- final ImmutableList<Entry<K, V>> entryList = map.entrySet().asList();
- return new ImmutableAsList<V>() {
- @Override
- public V get(int index) {
- return entryList.get(index).getValue();
- }
-
- @Override
- ImmutableCollection<V> delegateCollection() {
- return ImmutableMapValues.this;
- }
- };
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMultimap.java
index f02ea43..a971129 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableMultimap.java
@@ -18,8 +18,8 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
import java.io.Serializable;
import java.util.Arrays;
@@ -29,9 +29,8 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
+import java.util.TreeMap;
import javax.annotation.Nullable;
@@ -53,16 +52,13 @@ import javax.annotation.Nullable;
* <p>In addition to methods defined by {@link Multimap}, an {@link #inverse}
* method is also supported.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(emulated = true)
-public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
- implements Serializable {
+// TODO(user): If BiMultimap graduates from labs, this class should implement it.
+public abstract class ImmutableMultimap<K, V>
+ implements Multimap<K, V>, Serializable {
/** Returns an empty multimap. */
public static <K, V> ImmutableMultimap<K, V> of() {
@@ -122,7 +118,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* value orderings, allows duplicate values, and performs better than
* {@link LinkedListMultimap}.
*/
- private static class BuilderMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
+ private static class BuilderMultimap<K, V> extends AbstractMultimap<K, V> {
BuilderMultimap() {
super(new LinkedHashMap<K, Collection<V>>());
}
@@ -133,6 +129,23 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
}
/**
+ * Multimap for {@link ImmutableMultimap.Builder} that sorts key and allows
+ * duplicate values,
+ */
+ private static class SortedKeyBuilderMultimap<K, V>
+ extends AbstractMultimap<K, V> {
+ SortedKeyBuilderMultimap(
+ Comparator<? super K> keyComparator, Multimap<K, V> multimap) {
+ super(new TreeMap<K, Collection<V>>(keyComparator));
+ putAll(multimap);
+ }
+ @Override Collection<V> createCollection() {
+ return Lists.newArrayList();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
* A builder for creating immutable multimap instances, especially
* {@code public static final} multimaps ("constant multimaps"). Example:
* <pre> {@code
@@ -152,7 +165,6 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
public static class Builder<K, V> {
Multimap<K, V> builderMultimap = new BuilderMultimap<K, V>();
- Comparator<? super K> keyComparator;
Comparator<? super V> valueComparator;
/**
@@ -227,8 +239,10 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*
* @since 8.0
*/
+ @Beta
public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
- this.keyComparator = checkNotNull(keyComparator);
+ builderMultimap = new SortedKeyBuilderMultimap<K, V>(
+ checkNotNull(keyComparator), builderMultimap);
return this;
}
@@ -237,6 +251,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*
* @since 8.0
*/
+ @Beta
public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
this.valueComparator = checkNotNull(valueComparator);
return this;
@@ -252,23 +267,6 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
Collections.sort(list, valueComparator);
}
}
- if (keyComparator != null) {
- Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
- List<Map.Entry<K, Collection<V>>> entries = Lists.newArrayList(
- builderMultimap.asMap().entrySet());
- Collections.sort(
- entries,
- Ordering.from(keyComparator).onResultOf(new Function<Entry<K, Collection<V>>, K>() {
- @Override
- public K apply(Entry<K, Collection<V>> entry) {
- return entry.getKey();
- }
- }));
- for (Map.Entry<K, Collection<V>> entry : entries) {
- sortedCopy.putAll(entry.getKey(), entry.getValue());
- }
- builderMultimap = sortedCopy;
- }
return copyOf(builderMultimap);
}
}
@@ -317,9 +315,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public ImmutableCollection<V> removeAll(Object key) {
throw new UnsupportedOperationException();
@@ -329,9 +325,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public ImmutableCollection<V> replaceValues(K key,
Iterable<? extends V> values) {
@@ -342,9 +336,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public void clear() {
throw new UnsupportedOperationException();
@@ -364,17 +356,16 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* key-value mapping in the original, the result will have a mapping with
* key and value reversed.
*
- * @since 11.0
+ * @since 11
*/
+ @Beta
public abstract ImmutableMultimap<V, K> inverse();
/**
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean put(K key, V value) {
throw new UnsupportedOperationException();
@@ -384,9 +375,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean putAll(K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
@@ -396,9 +385,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
throw new UnsupportedOperationException();
@@ -408,30 +395,65 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
- boolean isPartialView() {
+ boolean isPartialView(){
return map.isPartialView();
}
// accessors
@Override
+ public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
+ Collection<V> values = map.get(key);
+ return values != null && values.contains(value);
+ }
+
+ @Override
public boolean containsKey(@Nullable Object key) {
return map.containsKey(key);
}
@Override
+ public boolean containsValue(@Nullable Object value) {
+ for (Collection<V> valueCollection : map.values()) {
+ if (valueCollection.contains(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ @Override
public int size() {
return size;
}
+ @Override public boolean equals(@Nullable Object object) {
+ if (object instanceof Multimap) {
+ Multimap<?, ?> that = (Multimap<?, ?>) object;
+ return this.map.equals(that.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ return map.toString();
+ }
+
// views
/**
@@ -453,11 +475,8 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
public ImmutableMap<K, Collection<V>> asMap() {
return (ImmutableMap) map;
}
-
- @Override
- Map<K, Collection<V>> createAsMap() {
- throw new AssertionError("should never be called");
- }
+
+ private transient ImmutableCollection<Entry<K, V>> entries;
/**
* Returns an immutable collection of all key-value pairs in the multimap. Its
@@ -466,12 +485,9 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
@Override
public ImmutableCollection<Entry<K, V>> entries() {
- return (ImmutableCollection<Entry<K, V>>) super.entries();
- }
-
- @Override
- ImmutableCollection<Entry<K, V>> createEntries() {
- return new EntryCollection<K, V>(this);
+ ImmutableCollection<Entry<K, V>> result = entries;
+ return (result == null)
+ ? (entries = new EntryCollection<K, V>(this)) : result;
}
private static class EntryCollection<K, V>
@@ -483,7 +499,30 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
}
@Override public UnmodifiableIterator<Entry<K, V>> iterator() {
- return multimap.entryIterator();
+ final Iterator<? extends Entry<K, ? extends ImmutableCollection<V>>>
+ mapIterator = this.multimap.map.entrySet().iterator();
+
+ return new UnmodifiableIterator<Entry<K, V>>() {
+ K key;
+ Iterator<V> valueIterator;
+
+ @Override
+ public boolean hasNext() {
+ return (key != null && valueIterator.hasNext())
+ || mapIterator.hasNext();
+ }
+
+ @Override
+ public Entry<K, V> next() {
+ if (key == null || !valueIterator.hasNext()) {
+ Entry<K, ? extends ImmutableCollection<V>> entry
+ = mapIterator.next();
+ key = entry.getKey();
+ valueIterator = entry.getValue().iterator();
+ }
+ return Maps.immutableEntry(key, valueIterator.next());
+ }
+ };
}
@Override boolean isPartialView() {
@@ -505,34 +544,8 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
private static final long serialVersionUID = 0;
}
-
- @Override
- UnmodifiableIterator<Entry<K, V>> entryIterator() {
- final Iterator<? extends Entry<K, ? extends ImmutableCollection<V>>>
- mapIterator = map.entrySet().iterator();
-
- return new UnmodifiableIterator<Entry<K, V>>() {
- K key;
- Iterator<V> valueIterator;
-
- @Override
- public boolean hasNext() {
- return (key != null && valueIterator.hasNext())
- || mapIterator.hasNext();
- }
- @Override
- public Entry<K, V> next() {
- if (key == null || !valueIterator.hasNext()) {
- Entry<K, ? extends ImmutableCollection<V>> entry
- = mapIterator.next();
- key = entry.getKey();
- valueIterator = entry.getValue().iterator();
- }
- return Maps.immutableEntry(key, valueIterator.next());
- }
- };
- }
+ private transient ImmutableMultiset<K> keys;
/**
* Returns a collection, which may contain duplicates, of all keys. The number
@@ -542,78 +555,21 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
@Override
public ImmutableMultiset<K> keys() {
- return (ImmutableMultiset<K>) super.keys();
+ ImmutableMultiset<K> result = keys;
+ return (result == null) ? (keys = createKeys()) : result;
}
- @Override
- ImmutableMultiset<K> createKeys() {
- return new Keys();
- }
-
- @SuppressWarnings("serial") // Uses writeReplace, not default serialization
- class Keys extends ImmutableMultiset<K> {
- @Override
- public boolean contains(@Nullable Object object) {
- return containsKey(object);
- }
-
- @Override
- public int count(@Nullable Object element) {
- Collection<V> values = map.get(element);
- return (values == null) ? 0 : values.size();
- }
-
- @Override
- public Set<K> elementSet() {
- return keySet();
- }
-
- @Override
- public int size() {
- return ImmutableMultimap.this.size();
- }
-
- @Override
- ImmutableSet<Entry<K>> createEntrySet() {
- return new KeysEntrySet();
- }
-
- private class KeysEntrySet extends ImmutableMultiset<K>.EntrySet {
- @Override
- public int size() {
- return keySet().size();
- }
-
- @Override
- public UnmodifiableIterator<Entry<K>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<K>> createAsList() {
- final ImmutableList<? extends Map.Entry<K, ? extends Collection<V>>> mapEntries =
- map.entrySet().asList();
- return new ImmutableAsList<Entry<K>>() {
- @Override
- public Entry<K> get(int index) {
- Map.Entry<K, ? extends Collection<V>> entry = mapEntries.get(index);
- return Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
- }
-
- @Override
- ImmutableCollection<Entry<K>> delegateCollection() {
- return KeysEntrySet.this;
- }
- };
- }
- }
-
- @Override
- boolean isPartialView() {
- return true;
+ private ImmutableMultiset<K> createKeys() {
+ ImmutableMultiset.Builder<K> builder = ImmutableMultiset.builder();
+ for (Entry<K, ? extends ImmutableCollection<V>> entry
+ : map.entrySet()) {
+ builder.addCopies(entry.getKey(), entry.getValue().size());
}
+ return builder.build();
}
+ private transient ImmutableCollection<V> values;
+
/**
* Returns an immutable collection of the values in this multimap. Its
* iterator traverses the values for the first key, the values for the second
@@ -621,12 +577,8 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
@Override
public ImmutableCollection<V> values() {
- return (ImmutableCollection<V>) super.values();
- }
-
- @Override
- ImmutableCollection<V> createValues() {
- return new Values<V>(this);
+ ImmutableCollection<V> result = values;
+ return (result == null) ? (values = new Values<V>(this)) : result;
}
private static class Values<V> extends ImmutableCollection<V> {
@@ -637,7 +589,18 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
}
@Override public UnmodifiableIterator<V> iterator() {
- return Maps.valueIterator(multimap.entries().iterator());
+ final Iterator<? extends Entry<?, V>> entryIterator
+ = multimap.entries().iterator();
+ return new UnmodifiableIterator<V>() {
+ @Override
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ @Override
+ public V next() {
+ return entryIterator.next().getValue();
+ }
+ };
}
@Override
@@ -654,4 +617,3 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
private static final long serialVersionUID = 0;
}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSet.java
index 97d9dd1..26bc57f 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSet.java
@@ -37,8 +37,16 @@ import java.util.Set;
* @author Hayward Chan
*/
@SuppressWarnings("serial") // Serialization only done in GWT.
-public abstract class ImmutableSet<E> extends ImmutableCollection<E> implements Set<E> {
- ImmutableSet() {}
+public abstract class ImmutableSet<E> extends ForwardingImmutableCollection<E>
+ implements Set<E> {
+
+ ImmutableSet(Set<E> delegate) {
+ super(Collections.unmodifiableSet(delegate));
+ }
+
+ ImmutableSet() {
+ this(Collections.<E>emptySet());
+ }
// Casting to any type is safe because the set will never hold any elements.
@SuppressWarnings({"unchecked"})
@@ -71,7 +79,8 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E> implements
}
@SuppressWarnings("unchecked")
- public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) {
+ public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6,
+ E... others) {
int size = others.length + 6;
List<E> all = new ArrayList<E>(size);
Collections.addAll(all, e1, e2, e3, e4, e5, e6);
@@ -102,7 +111,8 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E> implements
}
public static <E> ImmutableSet<E> copyOf(Iterable<? extends E> elements) {
- if (elements instanceof ImmutableSet && !(elements instanceof ImmutableSortedSet)) {
+ if (elements instanceof ImmutableSet
+ && !(elements instanceof ImmutableSortedSet)) {
@SuppressWarnings("unchecked") // all supported methods are covariant
ImmutableSet<E> set = (ImmutableSet<E>) elements;
return set;
@@ -165,7 +175,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E> implements
}
@Override public int hashCode() {
- return Sets.hashCodeImpl(this);
+ return delegate.hashCode();
}
public static <E> Builder<E> builder() {
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSetMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSetMultimap.java
index 43e701e..b5eaabf 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSetMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSetMultimap.java
@@ -18,17 +18,15 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
+import java.util.TreeMap;
import javax.annotation.Nullable;
@@ -48,10 +46,6 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this class
* are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Mike Ward
* @since 2.0 (imported from Google Collections Library)
*/
@@ -146,7 +140,7 @@ public class ImmutableSetMultimap<K, V>
* Multimap for {@link ImmutableSetMultimap.Builder} that maintains key
* and value orderings and performs better than {@link LinkedHashMultimap}.
*/
- private static class BuilderMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
+ private static class BuilderMultimap<K, V> extends AbstractMultimap<K, V> {
BuilderMultimap() {
super(new LinkedHashMap<K, Collection<V>>());
}
@@ -157,6 +151,23 @@ public class ImmutableSetMultimap<K, V>
}
/**
+ * Multimap for {@link ImmutableSetMultimap.Builder} that sorts keys and
+ * maintains value orderings.
+ */
+ private static class SortedKeyBuilderMultimap<K, V>
+ extends AbstractMultimap<K, V> {
+ SortedKeyBuilderMultimap(
+ Comparator<? super K> keyComparator, Multimap<K, V> multimap) {
+ super(new TreeMap<K, Collection<V>>(keyComparator));
+ putAll(multimap);
+ }
+ @Override Collection<V> createCollection() {
+ return Sets.newLinkedHashSet();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
* A builder for creating immutable {@code SetMultimap} instances, especially
* {@code public static final} multimaps ("constant multimaps"). Example:
* <pre> {@code
@@ -181,7 +192,7 @@ public class ImmutableSetMultimap<K, V>
* generated by {@link ImmutableSetMultimap#builder}.
*/
public Builder() {
- builderMultimap = new BuilderMultimap<K, V>();
+ builderMultimap = new BuilderMultimap<K, V>();
}
/**
@@ -230,25 +241,26 @@ public class ImmutableSetMultimap<K, V>
*
* @since 8.0
*/
- @Override
+ @Beta @Override
public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
- this.keyComparator = checkNotNull(keyComparator);
+ builderMultimap = new SortedKeyBuilderMultimap<K, V>(
+ checkNotNull(keyComparator), builderMultimap);
return this;
}
/**
* Specifies the ordering of the generated multimap's values for each key.
- *
- * <p>If this method is called, the sets returned by the {@code get()}
+ *
+ * <p>If this method is called, the sets returned by the {@code get()}
* method of the generated multimap and its {@link Multimap#asMap()} view
* are {@link ImmutableSortedSet} instances. However, serialization does not
* preserve that property, though it does maintain the key and value
* ordering.
- *
+ *
* @since 8.0
*/
// TODO: Make serialization behavior consistent.
- @Override
+ @Beta @Override
public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
super.orderValuesBy(valueComparator);
return this;
@@ -258,23 +270,6 @@ public class ImmutableSetMultimap<K, V>
* Returns a newly-created immutable set multimap.
*/
@Override public ImmutableSetMultimap<K, V> build() {
- if (keyComparator != null) {
- Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
- List<Map.Entry<K, Collection<V>>> entries = Lists.newArrayList(
- builderMultimap.asMap().entrySet());
- Collections.sort(
- entries,
- Ordering.from(keyComparator).onResultOf(new Function<Entry<K, Collection<V>>, K>() {
- @Override
- public K apply(Entry<K, Collection<V>> entry) {
- return entry.getKey();
- }
- }));
- for (Map.Entry<K, Collection<V>> entry : entries) {
- sortedCopy.putAll(entry.getKey(), entry.getValue());
- }
- builderMultimap = sortedCopy;
- }
return copyOf(builderMultimap, valueComparator);
}
}
@@ -297,7 +292,7 @@ public class ImmutableSetMultimap<K, V>
Multimap<? extends K, ? extends V> multimap) {
return copyOf(multimap, null);
}
-
+
private static <K, V> ImmutableSetMultimap<K, V> copyOf(
Multimap<? extends K, ? extends V> multimap,
Comparator<? super V> valueComparator) {
@@ -323,7 +318,7 @@ public class ImmutableSetMultimap<K, V>
K key = entry.getKey();
Collection<? extends V> values = entry.getValue();
ImmutableSet<V> set = (valueComparator == null)
- ? ImmutableSet.copyOf(values)
+ ? ImmutableSet.copyOf(values)
: ImmutableSortedSet.copyOf(valueComparator, values);
if (!set.isEmpty()) {
builder.put(key, set);
@@ -338,10 +333,10 @@ public class ImmutableSetMultimap<K, V>
// Returned by get() when values are sorted and a missing key is provided.
private final transient ImmutableSortedSet<V> emptySet;
- ImmutableSetMultimap(ImmutableMap<K, ImmutableSet<V>> map, int size,
+ ImmutableSetMultimap(ImmutableMap<K, ImmutableSet<V>> map, int size,
@Nullable Comparator<? super V> valueComparator) {
super(map, size);
- this.emptySet = (valueComparator == null)
+ this.emptySet = (valueComparator == null)
? null : ImmutableSortedSet.<V>emptySet(valueComparator);
}
@@ -370,13 +365,13 @@ public class ImmutableSetMultimap<K, V>
/**
* {@inheritDoc}
*
- * <p>Because an inverse of a set multimap cannot contain multiple pairs with
- * the same key and value, this method returns an {@code ImmutableSetMultimap}
- * rather than the {@code ImmutableMultimap} specified in the {@code
- * ImmutableMultimap} class.
+ * <p>Because an inverse of a set multimap cannot contain multiple pairs with the same key and
+ * value, this method returns an {@code ImmutableSetMultimap} rather than the
+ * {@code ImmutableMultimap} specified in the {@code ImmutableMultimap} class.
*
- * @since 11.0
+ * @since 11
*/
+ @Beta
public ImmutableSetMultimap<V, K> inverse() {
ImmutableSetMultimap<V, K> result = inverse;
return (result == null) ? (inverse = invert()) : result;
@@ -396,9 +391,8 @@ public class ImmutableSetMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableSet<V> removeAll(Object key) {
+ @Override public ImmutableSet<V> removeAll(Object key) {
throw new UnsupportedOperationException();
}
@@ -406,9 +400,8 @@ public class ImmutableSetMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableSet<V> replaceValues(
+ @Override public ImmutableSet<V> replaceValues(
K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedAsList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedAsList.java
deleted file mode 100644
index c94e88e..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedAsList.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Comparator;
-
-/**
- * List returned by {@code ImmutableSortedSet.asList()} when the set isn't empty.
- *
- * @author Jared Levy
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-@SuppressWarnings("serial")
-final class ImmutableSortedAsList<E> extends RegularImmutableAsList<E>
- implements SortedIterable<E> {
- ImmutableSortedAsList(
- ImmutableSortedSet<E> backingSet, ImmutableList<E> backingList) {
- super(backingSet, backingList);
- }
-
- @Override
- ImmutableSortedSet<E> delegateCollection() {
- return (ImmutableSortedSet<E>) super.delegateCollection();
- }
-
- @Override public Comparator<? super E> comparator() {
- return delegateCollection().comparator();
- }
-
- // Override indexOf() and lastIndexOf() to be O(log N) instead of O(N).
-
- @Override
- public boolean contains(Object target) {
- // Necessary for ISS's with comparators inconsistent with equals.
- return indexOf(target) >= 0;
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedMap.java
index 19139d1..89624d8 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedMap.java
@@ -18,11 +18,10 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Maps.newTreeMap;
-import static java.util.Collections.unmodifiableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
@@ -34,49 +33,60 @@ import java.util.SortedMap;
*
* @author Hayward Chan
*/
-public abstract class ImmutableSortedMap<K, V>
- extends ForwardingImmutableMap<K, V> implements SortedMap<K, V> {
+public class ImmutableSortedMap<K, V>
+ extends ImmutableMap<K, V> implements SortedMap<K, V> {
+
+ // TODO: Confirm that ImmutableSortedMap is faster to construct and uses less
+ // memory than TreeMap; then say so in the class Javadoc.
+
+ // TODO: Create separate subclasses for empty, single-entry, and
+ // multiple-entry instances.
+
+ @SuppressWarnings("unchecked")
+ private static final Comparator NATURAL_ORDER = Ordering.natural();
@SuppressWarnings("unchecked")
- static final Comparator NATURAL_ORDER = Ordering.natural();
+ private static final ImmutableSortedMap<Object, Object> NATURAL_EMPTY_MAP
+ = create(NATURAL_ORDER);
// This reference is only used by GWT compiler to infer the keys and values
// of the map that needs to be serialized.
- private Comparator<? super K> unusedComparatorForSerialization;
+ private Comparator<K> unusedComparatorForSerialization;
private K unusedKeyForSerialization;
private V unusedValueForSerialization;
- private final transient SortedMap<K, V> sortedDelegate;
+ private transient final SortedMap<K, V> sortedDelegate;
// The comparator used by this map. It's the same as that of sortedDelegate,
// except that when sortedDelegate's comparator is null, it points to a
// non-null instance of Ordering.natural().
- // (cpovirk: Is sortedDelegate's comparator really ever null?)
- // The comparator will likely also differ because of our nullAccepting hack.
- // See the bottom of the file for more information about it.
- private final transient Comparator<? super K> comparator;
+ private transient final Comparator<K> comparator;
- ImmutableSortedMap(SortedMap<K, V> delegate, Comparator<? super K> comparator) {
+ // If map has a null comparator, the keys should have a natural ordering,
+ // even though K doesn't explicitly implement Comparable.
+ @SuppressWarnings("unchecked")
+ ImmutableSortedMap(SortedMap<K, ? extends V> delegate) {
super(delegate);
- this.comparator = comparator;
- this.sortedDelegate = delegate;
+ this.comparator = (delegate.comparator() == null)
+ ? NATURAL_ORDER : delegate.comparator();
+ this.sortedDelegate = Collections.unmodifiableSortedMap(delegate);
}
private static <K, V> ImmutableSortedMap<K, V> create(
Comparator<? super K> comparator,
Entry<? extends K, ? extends V>... entries) {
checkNotNull(comparator);
- SortedMap<K, V> delegate = newModifiableDelegate(comparator);
+ SortedMap<K, V> delegate = Maps.newTreeMap(comparator);
for (Entry<? extends K, ? extends V> entry : entries) {
delegate.put(entry.getKey(), entry.getValue());
}
- return newView(unmodifiableSortedMap(delegate), comparator);
+ return new ImmutableSortedMap<K, V>(delegate);
}
// Casting to any type is safe because the set will never hold any elements.
@SuppressWarnings("unchecked")
public static <K, V> ImmutableSortedMap<K, V> of() {
- return EmptyImmutableSortedMap.forComparator(NATURAL_ORDER);
+ return (ImmutableSortedMap) NATURAL_EMPTY_MAP;
}
public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
@@ -145,11 +155,11 @@ public abstract class ImmutableSortedMap<K, V>
}
}
- SortedMap<K, V> delegate = newModifiableDelegate(comparator);
+ SortedMap<K, V> delegate = Maps.newTreeMap(comparator);
for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
putEntryWithChecks(delegate, entry);
}
- return newView(unmodifiableSortedMap(delegate), comparator);
+ return new ImmutableSortedMap<K, V>(delegate);
}
private static <K, V> void putEntryWithChecks(
@@ -169,7 +179,7 @@ public abstract class ImmutableSortedMap<K, V>
map.put(key, value);
}
- public static <K extends Comparable<?>, V> Builder<K, V> naturalOrder() {
+ public static <K extends Comparable<K>, V> Builder<K, V> naturalOrder() {
return new Builder<K, V>(Ordering.natural());
}
@@ -177,7 +187,7 @@ public abstract class ImmutableSortedMap<K, V>
return new Builder<K, V>(comparator);
}
- public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
+ public static <K extends Comparable<K>, V> Builder<K, V> reverseOrder() {
return new Builder<K, V>(Ordering.natural().reverse());
}
@@ -206,11 +216,11 @@ public abstract class ImmutableSortedMap<K, V>
}
@Override public ImmutableSortedMap<K, V> build() {
- SortedMap<K, V> delegate = newModifiableDelegate(comparator);
+ SortedMap<K, V> delegate = Maps.newTreeMap(comparator);
for (Entry<? extends K, ? extends V> entry : entries) {
putEntryWithChecks(delegate, entry);
}
- return newView(unmodifiableSortedMap(delegate), comparator);
+ return new ImmutableSortedMap<K, V>(delegate);
}
}
@@ -221,7 +231,7 @@ public abstract class ImmutableSortedMap<K, V>
return (ks == null) ? (keySet = createKeySet()) : ks;
}
- @Override ImmutableSortedSet<K> createKeySet() {
+ private ImmutableSortedSet<K> createKeySet() {
// the keySet() of the delegate is only a Set and TreeMap.navigatableKeySet
// is not available in GWT yet. To keep the code simple and code size more,
// we make a copy here, instead of creating a view of it.
@@ -256,7 +266,7 @@ public abstract class ImmutableSortedMap<K, V>
public ImmutableSortedMap<K, V> headMap(K toKey) {
checkNotNull(toKey);
- return newView(sortedDelegate.headMap(toKey));
+ return new ImmutableSortedMap<K, V>(sortedDelegate.headMap(toKey));
}
ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive) {
@@ -275,7 +285,7 @@ public abstract class ImmutableSortedMap<K, V>
checkNotNull(fromKey);
checkNotNull(toKey);
checkArgument(comparator.compare(fromKey, toKey) <= 0);
- return newView(sortedDelegate.subMap(fromKey, toKey));
+ return new ImmutableSortedMap<K, V>(sortedDelegate.subMap(fromKey, toKey));
}
ImmutableSortedMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive){
@@ -284,10 +294,10 @@ public abstract class ImmutableSortedMap<K, V>
checkArgument(comparator.compare(fromKey, toKey) <= 0);
return tailMap(fromKey, fromInclusive).headMap(toKey, toInclusive);
}
-
+
public ImmutableSortedMap<K, V> tailMap(K fromKey) {
checkNotNull(fromKey);
- return newView(sortedDelegate.tailMap(fromKey));
+ return new ImmutableSortedMap<K, V>(sortedDelegate.tailMap(fromKey));
}
public ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) {
@@ -295,42 +305,16 @@ public abstract class ImmutableSortedMap<K, V>
if (!inclusive) {
fromKey = higher(fromKey);
if (fromKey == null) {
- return EmptyImmutableSortedMap.forComparator(comparator());
+ return emptyMap(comparator());
}
}
return tailMap(fromKey);
}
- private ImmutableSortedMap<K, V> newView(SortedMap<K, V> delegate) {
- return newView(delegate, comparator);
- }
-
- private static <K, V> ImmutableSortedMap<K, V> newView(
- SortedMap<K, V> delegate, Comparator<? super K> comparator) {
- if (delegate.isEmpty()) {
- return EmptyImmutableSortedMap.forComparator(comparator);
+ static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) {
+ if (comparator == NATURAL_ORDER) {
+ return (ImmutableSortedMap) NATURAL_EMPTY_MAP;
}
- return new RegularImmutableSortedMap<K, V>(delegate, comparator);
- }
-
- /*
- * We don't permit nulls, but we wrap every comparator with nullsFirst().
- * Why? We want for queries like containsKey(null) to return false, but the
- * GWT SortedMap implementation that we delegate to throws
- * NullPointerException if the comparator does. Since our construction
- * methods ensure that null is never present in the map, it's OK for the
- * comparator to look for it wherever it wants.
- *
- * Note that we do NOT touch the comparator returned by comparator(), which
- * should be identical to the one the user passed in. We touch only the
- * "secret" comparator used by the delegate implementation.
- */
-
- private static <K, V> SortedMap<K, V> newModifiableDelegate(Comparator<? super K> comparator) {
- return newTreeMap(nullAccepting(comparator));
- }
-
- private static <E> Comparator<E> nullAccepting(Comparator<E> comparator) {
- return Ordering.from(comparator).nullsFirst();
+ return create(comparator);
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedSet.java
index c3cb7aa..cfb1da2 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedSet.java
@@ -16,8 +16,8 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
import java.util.ArrayList;
import java.util.Collection;
@@ -36,8 +36,7 @@ import javax.annotation.Nullable;
* @author Hayward Chan
*/
public abstract class ImmutableSortedSet<E>
- extends ForwardingImmutableSet<E> implements SortedSet<E>, SortedIterable<E> {
- // TODO(cpovirk): split into ImmutableSortedSet/ForwardingImmutableSortedSet?
+ extends ImmutableSet<E> implements SortedSet<E>, SortedIterable<E> {
// In the non-emulated source, this is in ImmutableSortedSetFauxverideShim,
// which overrides ImmutableSet & which ImmutableSortedSet extends.
@@ -247,19 +246,6 @@ public abstract class ImmutableSortedSet<E>
private transient final SortedSet<E> sortedDelegate;
- /**
- * Scary constructor for ContiguousSet. This constructor (in this file, the
- * GWT emulation of ImmutableSortedSet) creates an empty sortedDelegate,
- * which, in a vacuum, sets this object's contents to empty. By contrast,
- * the non-GWT constructor with the same signature uses the comparator only
- * as a comparator. It does NOT assume empty contents. (It requires an
- * implementation of iterator() to define its contents, and methods like
- * contains() are implemented in terms of that method (though they will
- * likely be overridden by subclasses for performance reasons).) This means
- * that a call to this method have can different behavior in GWT and non-GWT
- * environments UNLESS subclasses are careful to always override all methods
- * implemented in terms of sortedDelegate (except comparator()).
- */
ImmutableSortedSet(Comparator<? super E> comparator) {
this(Sets.newTreeSet(comparator));
}
@@ -385,11 +371,11 @@ public abstract class ImmutableSortedSet<E>
return new Builder<E>(comparator);
}
- public static <E extends Comparable<?>> Builder<E> reverseOrder() {
+ public static <E extends Comparable<E>> Builder<E> reverseOrder() {
return new Builder<E>(Ordering.natural().reverse());
}
- public static <E extends Comparable<?>> Builder<E> naturalOrder() {
+ public static <E extends Comparable<E>> Builder<E> naturalOrder() {
return new Builder<E>(Ordering.natural());
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterables.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterables.java
index 330c5bf..1299a62 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterables.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterables.java
@@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
+import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
@@ -48,10 +49,6 @@ import javax.annotation.Nullable;
* produced in this class are <i>lazy</i>, which means that their iterators
* only advance the backing iteration when absolutely necessary.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Iterables">
- * {@code Iterables}</a>.
- *
* @author Kevin Bourrillion
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -82,7 +79,7 @@ public final class Iterables {
return checkNotNull(iterable);
}
- private static final class UnmodifiableIterable<T> extends FluentIterable<T> {
+ private static final class UnmodifiableIterable<T> implements Iterable<T> {
private final Iterable<T> iterable;
private UnmodifiableIterable(Iterable<T> iterable) {
@@ -111,14 +108,20 @@ public final class Iterables {
}
/**
- * Returns {@code true} if {@code iterable} contains any object for which {@code equals(element)}
- * is true.
+ * Returns {@code true} if {@code iterable} contains {@code element}; that is,
+ * any object for which {@code equals(element)} is true.
*/
public static boolean contains(Iterable<?> iterable, @Nullable Object element)
{
if (iterable instanceof Collection) {
Collection<?> collection = (Collection<?>) iterable;
- return Collections2.safeContains(collection, element);
+ try {
+ return collection.contains(element);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
}
return Iterators.contains(iterable.iterator(), element);
}
@@ -240,13 +243,6 @@ public final class Iterables {
*/
public static boolean elementsEqual(
Iterable<?> iterable1, Iterable<?> iterable2) {
- if (iterable1 instanceof Collection && iterable2 instanceof Collection) {
- Collection<?> collection1 = (Collection<?>) iterable1;
- Collection<?> collection2 = (Collection<?>) iterable2;
- if (collection1.size() != collection2.size()) {
- return false;
- }
- }
return Iterators.elementsEqual(iterable1.iterator(), iterable2.iterator());
}
@@ -276,9 +272,8 @@ public final class Iterables {
* @throws IllegalArgumentException if the iterator contains multiple
* elements
*/
- @Nullable
public static <T> T getOnlyElement(
- Iterable<? extends T> iterable, @Nullable T defaultValue) {
+ Iterable<T> iterable, @Nullable T defaultValue) {
return Iterators.getOnlyElement(iterable.iterator(), defaultValue);
}
@@ -355,7 +350,7 @@ public final class Iterables {
*/
public static <T> Iterable<T> cycle(final Iterable<T> iterable) {
checkNotNull(iterable);
- return new FluentIterable<T>() {
+ return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.cycle(iterable);
@@ -470,7 +465,7 @@ public final class Iterables {
public static <T> Iterable<T> concat(
final Iterable<? extends Iterable<? extends T>> inputs) {
checkNotNull(inputs);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.concat(iterators(inputs));
@@ -521,7 +516,7 @@ public final class Iterables {
final Iterable<T> iterable, final int size) {
checkNotNull(iterable);
checkArgument(size > 0);
- return new FluentIterable<List<T>>() {
+ return new IterableWithToString<List<T>>() {
@Override
public Iterator<List<T>> iterator() {
return Iterators.partition(iterable.iterator(), size);
@@ -550,7 +545,7 @@ public final class Iterables {
final Iterable<T> iterable, final int size) {
checkNotNull(iterable);
checkArgument(size > 0);
- return new FluentIterable<List<T>>() {
+ return new IterableWithToString<List<T>>() {
@Override
public Iterator<List<T>> iterator() {
return Iterators.paddedPartition(iterable.iterator(), size);
@@ -566,7 +561,7 @@ public final class Iterables {
final Iterable<T> unfiltered, final Predicate<? super T> predicate) {
checkNotNull(unfiltered);
checkNotNull(predicate);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.filter(unfiltered.iterator(), predicate);
@@ -575,7 +570,8 @@ public final class Iterables {
}
/**
- * Returns {@code true} if any element in {@code iterable} satisfies the predicate.
+ * Returns {@code true} if one or more elements in {@code iterable} satisfy
+ * the predicate.
*/
public static <T> boolean any(
Iterable<T> iterable, Predicate<? super T> predicate) {
@@ -594,8 +590,8 @@ public final class Iterables {
/**
* Returns the first element in {@code iterable} that satisfies the given
* predicate; use this method only when such an element is known to exist. If
- * it is possible that <i>no</i> element will match, use {@link #tryFind} or
- * {@link #find(Iterable, Predicate, Object)} instead.
+ * it is possible that <i>no</i> element will match, use {@link
+ * #tryFind)} or {@link #find(Iterable, Predicate, T)} instead.
*
* @throws NoSuchElementException if no element in {@code iterable} matches
* the given predicate
@@ -613,8 +609,7 @@ public final class Iterables {
*
* @since 7.0
*/
- @Nullable
- public static <T> T find(Iterable<? extends T> iterable,
+ public static <T> T find(Iterable<T> iterable,
Predicate<? super T> predicate, @Nullable T defaultValue) {
return Iterators.find(iterable.iterator(), predicate, defaultValue);
}
@@ -666,7 +661,7 @@ public final class Iterables {
final Function<? super F, ? extends T> function) {
checkNotNull(fromIterable);
checkNotNull(function);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.transform(fromIterable.iterator(), function);
@@ -719,8 +714,8 @@ public final class Iterables {
* @throws IndexOutOfBoundsException if {@code position} is negative
* @since 4.0
*/
- @Nullable
- public static <T> T get(Iterable<? extends T> iterable, int position, @Nullable T defaultValue) {
+ public static <T> T get(Iterable<T> iterable, int position,
+ @Nullable T defaultValue) {
checkNotNull(iterable);
checkNonnegativeIndex(position);
@@ -736,16 +731,11 @@ public final class Iterables {
* the iterable is empty. The {@link Iterators} analog to this method is
* {@link Iterators#getNext}.
*
- * <p>If no default value is desired (and the caller instead wants a
- * {@link NoSuchElementException} to be thrown), it is recommended that
- * {@code iterable.iterator().next()} is used instead.
- *
* @param defaultValue the default value to return if the iterable is empty
* @return the first element of {@code iterable} or the default value
* @since 7.0
*/
- @Nullable
- public static <T> T getFirst(Iterable<? extends T> iterable, @Nullable T defaultValue) {
+ public static <T> T getFirst(Iterable<T> iterable, @Nullable T defaultValue) {
return Iterators.getNext(iterable.iterator(), defaultValue);
}
@@ -786,17 +776,16 @@ public final class Iterables {
* @return the last element of {@code iterable} or the default value
* @since 3.0
*/
- @Nullable
- public static <T> T getLast(Iterable<? extends T> iterable, @Nullable T defaultValue) {
+ public static <T> T getLast(Iterable<T> iterable, @Nullable T defaultValue) {
if (iterable instanceof Collection) {
- Collection<? extends T> collection = Collections2.cast(iterable);
+ Collection<T> collection = (Collection<T>) iterable;
if (collection.isEmpty()) {
return defaultValue;
}
}
if (iterable instanceof List) {
- List<? extends T> list = Lists.cast(iterable);
+ List<T> list = (List<T>) iterable;
return getLastInNonemptyList(list);
}
@@ -806,7 +795,7 @@ public final class Iterables {
* call this method.
*/
if (iterable instanceof SortedSet) {
- SortedSet<? extends T> sortedSet = Sets.cast(iterable);
+ SortedSet<T> sortedSet = (SortedSet<T>) iterable;
return sortedSet.last();
}
@@ -844,7 +833,7 @@ public final class Iterables {
if (iterable instanceof List) {
final List<T> list = (List<T>) iterable;
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
// TODO(kevinb): Support a concurrently modified collection?
@@ -855,12 +844,12 @@ public final class Iterables {
};
}
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
final Iterator<T> iterator = iterable.iterator();
- Iterators.advance(iterator, numberToSkip);
+ Iterators.skip(iterator, numberToSkip);
/*
* We can't just return the iterator because an immediate call to its
@@ -916,7 +905,7 @@ public final class Iterables {
final Iterable<T> iterable, final int limitSize) {
checkNotNull(iterable);
checkArgument(limitSize >= 0, "limit is negative");
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.limit(iterable.iterator(), limitSize);
@@ -945,7 +934,7 @@ public final class Iterables {
*/
public static <T> Iterable<T> consumingIterable(final Iterable<T> iterable) {
if (iterable instanceof Queue) {
- return new FluentIterable<T>() {
+ return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new ConsumingQueueIterator<T>((Queue<T>) iterable);
@@ -955,7 +944,7 @@ public final class Iterables {
checkNotNull(iterable);
- return new FluentIterable<T>() {
+ return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.consumingIterator(iterable.iterator());
@@ -982,6 +971,30 @@ public final class Iterables {
// Methods only in Iterables, not in Iterators
/**
+ * Adapts a list to an iterable with reversed iteration order. It is
+ * especially useful in foreach-style loops: <pre> {@code
+ *
+ * List<String> mylist = ...
+ * for (String str : Iterables.reverse(mylist)) {
+ * ...
+ * }}</pre>
+ *
+ * There is no corresponding method in {@link Iterators}, since {@link
+ * Iterable#iterator} can simply be invoked on the result of calling this
+ * method.
+ *
+ * @return an iterable with the same elements as the list, in reverse
+ *
+ * @deprecated use {@link Lists#reverse(List)} or {@link
+ * ImmutableList#reverse()}. <b>This method is scheduled for deletion in
+ * July 2012.</b>
+ */
+ @Deprecated
+ public static <T> Iterable<T> reverse(final List<T> list) {
+ return Lists.reverse(list);
+ }
+
+ /**
* Determines if the given iterable contains no elements.
*
* <p>There is no precise {@link Iterator} equivalent to this method, since
@@ -997,6 +1010,43 @@ public final class Iterables {
return !iterable.iterator().hasNext();
}
+ // Non-public
+
+ /**
+ * Removes the specified element from the specified iterable.
+ *
+ * <p>This method iterates over the iterable, checking each element returned
+ * by the iterator in turn to see if it equals the object {@code o}. If they
+ * are equal, it is removed from the iterable with the iterator's
+ * {@code remove} method. At most one element is removed, even if the iterable
+ * contains multiple members that equal {@code o}.
+ *
+ * <p><b>Warning:</b> Do not use this method for a collection, such as a
+ * {@link HashSet}, that has a fast {@code remove} method.
+ *
+ * @param iterable the iterable from which to remove
+ * @param o an element to remove from the collection
+ * @return {@code true} if the iterable changed as a result
+ * @throws UnsupportedOperationException if the iterator does not support the
+ * {@code remove} method and the iterable contains the object
+ */
+ static boolean remove(Iterable<?> iterable, @Nullable Object o) {
+ Iterator<?> i = iterable.iterator();
+ while (i.hasNext()) {
+ if (Objects.equal(i.next(), o)) {
+ i.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ abstract static class IterableWithToString<E> implements Iterable<E> {
+ @Override public String toString() {
+ return Iterables.toString(this);
+ }
+ }
+
/**
* Returns an iterable over the merged contents of all given
* {@code iterables}. Equivalent entries will not be de-duplicated.
@@ -1015,7 +1065,7 @@ public final class Iterables {
final Comparator<? super T> comparator) {
checkNotNull(iterables, "iterables");
checkNotNull(comparator, "comparator");
- Iterable<T> iterable = new FluentIterable<T>() {
+ Iterable<T> iterable = new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.mergeSorted(
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterators.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterators.java
index ead102f..9da1da6 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterators.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Iterators.java
@@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
-import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
@@ -36,7 +35,6 @@ import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
-import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.Queue;
@@ -52,10 +50,6 @@ import javax.annotation.Nullable;
* produced in this class are <i>lazy</i>, which means that they only advance
* the backing iteration when absolutely necessary.
*
- * <p>See the Guava User Guide section on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Iterables">
- * {@code Iterators}</a>.
- *
* @author Kevin Bourrillion
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -64,8 +58,8 @@ import javax.annotation.Nullable;
public final class Iterators {
private Iterators() {}
- static final UnmodifiableListIterator<Object> EMPTY_LIST_ITERATOR
- = new UnmodifiableListIterator<Object>() {
+ static final UnmodifiableIterator<Object> EMPTY_ITERATOR
+ = new UnmodifiableIterator<Object>() {
@Override
public boolean hasNext() {
return false;
@@ -74,22 +68,6 @@ public final class Iterators {
public Object next() {
throw new NoSuchElementException();
}
- @Override
- public boolean hasPrevious() {
- return false;
- }
- @Override
- public Object previous() {
- throw new NoSuchElementException();
- }
- @Override
- public int nextIndex() {
- return 0;
- }
- @Override
- public int previousIndex() {
- return -1;
- }
};
/**
@@ -98,20 +76,10 @@ public final class Iterators {
* <p>The {@link Iterable} equivalent of this method is {@link
* ImmutableSet#of()}.
*/
- public static <T> UnmodifiableIterator<T> emptyIterator() {
- return emptyListIterator();
- }
-
- /**
- * Returns the empty iterator.
- *
- * <p>The {@link Iterable} equivalent of this method is {@link
- * ImmutableSet#of()}.
- */
// Casting to any type is safe since there are no actual elements.
@SuppressWarnings("unchecked")
- static <T> UnmodifiableListIterator<T> emptyListIterator() {
- return (UnmodifiableListIterator<T>) EMPTY_LIST_ITERATOR;
+ public static <T> UnmodifiableIterator<T> emptyIterator() {
+ return (UnmodifiableIterator<T>) EMPTY_ITERATOR;
}
private static final Iterator<Object> EMPTY_MODIFIABLE_ITERATOR =
@@ -305,11 +273,15 @@ public final class Iterators {
* {@code hasNext()} method will return {@code false}.
*/
public static String toString(Iterator<?> iterator) {
- return Joiner.on(", ")
- .useForNull("null")
- .appendTo(new StringBuilder().append('['), iterator)
- .append(']')
- .toString();
+ if (!iterator.hasNext()) {
+ return "[]";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append('[').append(iterator.next());
+ while (iterator.hasNext()) {
+ builder.append(", ").append(iterator.next());
+ }
+ return builder.append(']').toString();
}
/**
@@ -345,8 +317,8 @@ public final class Iterators {
* @throws IllegalArgumentException if the iterator contains multiple
* elements. The state of the iterator is unspecified.
*/
- @Nullable
- public static <T> T getOnlyElement(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getOnlyElement(
+ Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? getOnlyElement(iterator) : defaultValue;
}
@@ -441,8 +413,8 @@ public final class Iterators {
/**
* Returns an iterator that cycles indefinitely over the provided elements.
*
- * <p>The returned iterator supports {@code remove()}. After {@code remove()}
- * is called, subsequent cycles omit the removed
+ * <p>The returned iterator supports {@code remove()} if the provided iterator
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
* element, but {@code elements} does not change. The iterator's
* {@code hasNext()} method returns {@code true} until all of the original
* elements have been removed.
@@ -462,11 +434,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -484,11 +451,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -507,11 +469,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -532,11 +489,6 @@ public final class Iterators {
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
*
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
- *
* @throws NullPointerException if any of the provided iterators is null
*/
public static <T> Iterator<T> concat(Iterator<? extends T>... inputs) {
@@ -551,11 +503,6 @@ public final class Iterators {
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it. The methods of the returned iterator may throw
* {@code NullPointerException} if any of the input iterators is null.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
public static <T> Iterator<T> concat(
final Iterator<? extends Iterator<? extends T>> inputs) {
@@ -728,8 +675,8 @@ public final class Iterators {
* predicate; use this method only when such an element is known to exist. If
* no such element is found, the iterator will be left exhausted: its {@code
* hasNext()} method will return {@code false}. If it is possible that
- * <i>no</i> element will match, use {@link #tryFind} or {@link
- * #find(Iterator, Predicate, Object)} instead.
+ * <i>no</i> element will match, use {@link #tryFind)} or {@link
+ * #find(Iterator, Predicate, T)} instead.
*
* @throws NoSuchElementException if no element in {@code iterator} matches
* the given predicate
@@ -749,10 +696,9 @@ public final class Iterators {
*
* @since 7.0
*/
- @Nullable
- public static <T> T find(Iterator<? extends T> iterator, Predicate<? super T> predicate,
+ public static <T> T find(Iterator<T> iterator, Predicate<? super T> predicate,
@Nullable T defaultValue) {
- UnmodifiableIterator<? extends T> filteredIterator = filter(iterator, predicate);
+ UnmodifiableIterator<T> filteredIterator = filter(iterator, predicate);
return filteredIterator.hasNext() ? filteredIterator.next() : defaultValue;
}
@@ -817,12 +763,22 @@ public final class Iterators {
*/
public static <F, T> Iterator<T> transform(final Iterator<F> fromIterator,
final Function<? super F, ? extends T> function) {
+ checkNotNull(fromIterator);
checkNotNull(function);
- return new TransformedIterator<F, T>(fromIterator) {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return fromIterator.hasNext();
+ }
@Override
- T transform(F from) {
+ public T next() {
+ F from = fromIterator.next();
return function.apply(from);
}
+ @Override
+ public void remove() {
+ fromIterator.remove();
+ }
};
}
@@ -874,8 +830,8 @@ public final class Iterators {
* @throws IndexOutOfBoundsException if {@code position} is negative
* @since 4.0
*/
- @Nullable
- public static <T> T get(Iterator<? extends T> iterator, int position, @Nullable T defaultValue) {
+ public static <T> T get(Iterator<T> iterator, int position,
+ @Nullable T defaultValue) {
checkNonnegative(position);
try {
@@ -894,8 +850,7 @@ public final class Iterators {
* @return the next element of {@code iterator} or the default value
* @since 7.0
*/
- @Nullable
- public static <T> T getNext(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getNext(Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? iterator.next() : defaultValue;
}
@@ -922,24 +877,24 @@ public final class Iterators {
* @return the last element of {@code iterator}
* @since 3.0
*/
- @Nullable
- public static <T> T getLast(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getLast(Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? getLast(iterator) : defaultValue;
}
/**
- * Calls {@code next()} on {@code iterator}, either {@code numberToAdvance} times
+ * Calls {@code next()} on {@code iterator}, either {@code numberToSkip} times
* or until {@code hasNext()} returns {@code false}, whichever comes first.
*
- * @return the number of elements the iterator was advanced
- * @since 13.0 (since 3.0 as {@code Iterators.skip})
+ * @return the number of elements skipped
+ * @since 3.0
*/
- public static int advance(Iterator<?> iterator, int numberToAdvance) {
+ @Beta
+ public static <T> int skip(Iterator<T> iterator, int numberToSkip) {
checkNotNull(iterator);
- checkArgument(numberToAdvance >= 0, "number to advance cannot be negative");
+ checkArgument(numberToSkip >= 0, "number to skip cannot be negative");
int i;
- for (i = 0; i < numberToAdvance && iterator.hasNext(); i++) {
+ for (i = 0; i < numberToSkip && iterator.hasNext(); i++) {
iterator.next();
}
return i;
@@ -1015,21 +970,6 @@ public final class Iterators {
};
}
- /**
- * Deletes and returns the next value from the iterator, or returns
- * {@code defaultValue} if there is no such value.
- */
- @Nullable
- static <T> T pollNext(Iterator<T> iterator) {
- if (iterator.hasNext()) {
- T result = iterator.next();
- iterator.remove();
- return result;
- } else {
- return null;
- }
- }
-
// Methods only in Iterators, not in Iterables
/**
@@ -1067,14 +1007,21 @@ public final class Iterators {
}
/**
- * Returns a list iterator containing the elements in the specified range of
- * {@code array} in order, starting at the specified index.
+ * Returns an iterator containing the elements in the specified range of
+ * {@code array} in order. The returned iterator is a view of the array;
+ * subsequent changes to the array will be reflected in the iterator.
*
* <p>The {@code Iterable} equivalent of this method is {@code
- * Arrays.asList(array).subList(offset, offset + length).listIterator(index)}.
+ * Arrays.asList(array).subList(offset, offset + length)}.
+ *
+ * @param array array to read elements out of
+ * @param offset index of first array element to retrieve
+ * @param length number of elements in iteration
+ * @throws IndexOutOfBoundsException if {@code offset} is negative, {@code
+ * length} is negative, or {@code offset + length > array.length}
*/
- static <T> UnmodifiableListIterator<T> forArray(
- final T[] array, final int offset, int length, int index) {
+ static <T> UnmodifiableIterator<T> forArray(
+ final T[] array, final int offset, int length) {
checkArgument(length >= 0);
int end = offset + length;
@@ -1086,7 +1033,7 @@ public final class Iterators {
* because the returned Iterator is a ListIterator that may be moved back
* past the beginning of the iteration.
*/
- return new AbstractIndexedListIterator<T>(length, index) {
+ return new AbstractIndexedListIterator<T>(length) {
@Override protected T get(int index) {
return array[offset + index];
}
@@ -1343,19 +1290,4 @@ public final class Iterators {
return next;
}
}
-
- /**
- * Precondition tester for {@code Iterator.remove()} that throws an exception with a consistent
- * error message.
- */
- static void checkRemove(boolean canRemove) {
- checkState(canRemove, "no calls to next() since the last call to remove()");
- }
-
- /**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
- */
- static <T> ListIterator<T> cast(Iterator<T> iterator) {
- return (ListIterator<T>) iterator;
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultimap.java
index 74e0ff1..d426893 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultimap.java
@@ -16,20 +16,16 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Ints;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Set;
import javax.annotation.Nullable;
@@ -65,23 +61,29 @@ import javax.annotation.Nullable;
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedSetMultimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Jared Levy
- * @author Louis Wasserman
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(serializable = true, emulated = true)
public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
+ private static final int DEFAULT_VALUES_PER_KEY = 8;
+
+ @VisibleForTesting
+ transient int expectedValuesPerKey = DEFAULT_VALUES_PER_KEY;
+
+ /**
+ * Map entries with an iteration order corresponding to the order in which the
+ * key-value pairs were added to the multimap.
+ */
+ // package-private for GWT deserialization
+ transient Collection<Map.Entry<K, V>> linkedEntries;
/**
* Creates a new, empty {@code LinkedHashMultimap} with the default initial
* capacities.
*/
public static <K, V> LinkedHashMultimap<K, V> create() {
- return new LinkedHashMultimap<K, V>(DEFAULT_KEY_CAPACITY, DEFAULT_VALUE_SET_CAPACITY);
+ return new LinkedHashMultimap<K, V>();
}
/**
@@ -95,9 +97,7 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
*/
public static <K, V> LinkedHashMultimap<K, V> create(
int expectedKeys, int expectedValuesPerKey) {
- return new LinkedHashMultimap<K, V>(
- Maps.capacity(expectedKeys),
- Maps.capacity(expectedValuesPerKey));
+ return new LinkedHashMultimap<K, V>(expectedKeys, expectedValuesPerKey);
}
/**
@@ -111,158 +111,201 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
*/
public static <K, V> LinkedHashMultimap<K, V> create(
Multimap<? extends K, ? extends V> multimap) {
- LinkedHashMultimap<K, V> result = create(multimap.keySet().size(), DEFAULT_VALUE_SET_CAPACITY);
- result.putAll(multimap);
- return result;
- }
-
- private interface ValueSetLink<K, V> {
- ValueSetLink<K, V> getPredecessorInValueSet();
- ValueSetLink<K, V> getSuccessorInValueSet();
-
- void setPredecessorInValueSet(ValueSetLink<K, V> entry);
- void setSuccessorInValueSet(ValueSetLink<K, V> entry);
+ return new LinkedHashMultimap<K, V>(multimap);
}
- private static <K, V> void succeedsInValueSet(ValueSetLink<K, V> pred, ValueSetLink<K, V> succ) {
- pred.setSuccessorInValueSet(succ);
- succ.setPredecessorInValueSet(pred);
+ private LinkedHashMultimap() {
+ super(new LinkedHashMap<K, Collection<V>>());
+ linkedEntries = Sets.newLinkedHashSet();
}
- private static <K, V> void succeedsInMultimap(
- ValueEntry<K, V> pred, ValueEntry<K, V> succ) {
- pred.setSuccessorInMultimap(succ);
- succ.setPredecessorInMultimap(pred);
+ private LinkedHashMultimap(int expectedKeys, int expectedValuesPerKey) {
+ super(new LinkedHashMap<K, Collection<V>>(expectedKeys));
+ Preconditions.checkArgument(expectedValuesPerKey >= 0);
+ this.expectedValuesPerKey = expectedValuesPerKey;
+ linkedEntries = new LinkedHashSet<Map.Entry<K, V>>(
+ (int) Math.min(Ints.MAX_POWER_OF_TWO,
+ ((long) expectedKeys) * expectedValuesPerKey));
}
- private static <K, V> void deleteFromValueSet(ValueSetLink<K, V> entry) {
- succeedsInValueSet(entry.getPredecessorInValueSet(), entry.getSuccessorInValueSet());
+ private LinkedHashMultimap(Multimap<? extends K, ? extends V> multimap) {
+ super(new LinkedHashMap<K, Collection<V>>(
+ Maps.capacity(multimap.keySet().size())));
+ linkedEntries
+ = new LinkedHashSet<Map.Entry<K, V>>(Maps.capacity(multimap.size()));
+ putAll(multimap);
}
- private static <K, V> void deleteFromMultimap(ValueEntry<K, V> entry) {
- succeedsInMultimap(entry.getPredecessorInMultimap(), entry.getSuccessorInMultimap());
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Creates an empty {@code LinkedHashSet} for a collection of values for
+ * one key.
+ *
+ * @return a new {@code LinkedHashSet} containing a collection of values for
+ * one key
+ */
+ @Override Set<V> createCollection() {
+ return new LinkedHashSet<V>(Maps.capacity(expectedValuesPerKey));
}
/**
- * LinkedHashMultimap entries are in no less than three coexisting linked lists:
- * a row in the hash table for a Set<V> associated with a key, the linked list
- * of insertion-ordered entries in that Set<V>, and the linked list of entries
- * in the LinkedHashMultimap as a whole.
+ * {@inheritDoc}
+ *
+ * <p>Creates a decorated {@code LinkedHashSet} that also keeps track of the
+ * order in which key-value pairs are added to the multimap.
+ *
+ * @param key key to associate with values in the collection
+ * @return a new decorated {@code LinkedHashSet} containing a collection of
+ * values for one key
*/
- @VisibleForTesting
- static final class ValueEntry<K, V> extends AbstractMapEntry<K, V>
- implements ValueSetLink<K, V> {
- final K key;
- final V value;
- final int valueHash;
-
- @Nullable ValueEntry<K, V> nextInValueSetHashRow;
-
- ValueSetLink<K, V> predecessorInValueSet;
- ValueSetLink<K, V> successorInValueSet;
+ @Override Collection<V> createCollection(@Nullable K key) {
+ return new SetDecorator(key, createCollection());
+ }
- ValueEntry<K, V> predecessorInMultimap;
- ValueEntry<K, V> successorInMultimap;
+ private class SetDecorator extends ForwardingSet<V> {
+ final Set<V> delegate;
+ final K key;
- ValueEntry(@Nullable K key, @Nullable V value, int valueHash,
- @Nullable ValueEntry<K, V> nextInValueSetHashRow) {
+ SetDecorator(@Nullable K key, Set<V> delegate) {
+ this.delegate = delegate;
this.key = key;
- this.value = value;
- this.valueHash = valueHash;
- this.nextInValueSetHashRow = nextInValueSetHashRow;
}
- @Override
- public K getKey() {
- return key;
+ @Override protected Set<V> delegate() {
+ return delegate;
}
- @Override
- public V getValue() {
- return value;
+ <E> Map.Entry<K, E> createEntry(@Nullable E value) {
+ return Maps.immutableEntry(key, value);
}
- @Override
- public ValueSetLink<K, V> getPredecessorInValueSet() {
- return predecessorInValueSet;
+ <E> Collection<Map.Entry<K, E>> createEntries(Collection<E> values) {
+ // converts a collection of values into a list of key/value map entries
+ Collection<Map.Entry<K, E>> entries
+ = Lists.newArrayListWithExpectedSize(values.size());
+ for (E value : values) {
+ entries.add(createEntry(value));
+ }
+ return entries;
}
- @Override
- public ValueSetLink<K, V> getSuccessorInValueSet() {
- return successorInValueSet;
+ @Override public boolean add(@Nullable V value) {
+ boolean changed = delegate.add(value);
+ if (changed) {
+ linkedEntries.add(createEntry(value));
+ }
+ return changed;
}
- @Override
- public void setPredecessorInValueSet(ValueSetLink<K, V> entry) {
- predecessorInValueSet = entry;
+ @Override public boolean addAll(Collection<? extends V> values) {
+ boolean changed = delegate.addAll(values);
+ if (changed) {
+ linkedEntries.addAll(createEntries(delegate()));
+ }
+ return changed;
}
- @Override
- public void setSuccessorInValueSet(ValueSetLink<K, V> entry) {
- successorInValueSet = entry;
+ @Override public void clear() {
+ for (V value : delegate) {
+ linkedEntries.remove(createEntry(value));
+ }
+ delegate.clear();
}
- public ValueEntry<K, V> getPredecessorInMultimap() {
- return predecessorInMultimap;
- }
+ @Override public Iterator<V> iterator() {
+ final Iterator<V> delegateIterator = delegate.iterator();
+ return new Iterator<V>() {
+ V value;
- public ValueEntry<K, V> getSuccessorInMultimap() {
- return successorInMultimap;
+ @Override
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+ @Override
+ public V next() {
+ value = delegateIterator.next();
+ return value;
+ }
+ @Override
+ public void remove() {
+ delegateIterator.remove();
+ linkedEntries.remove(createEntry(value));
+ }
+ };
}
- public void setSuccessorInMultimap(ValueEntry<K, V> multimapSuccessor) {
- this.successorInMultimap = multimapSuccessor;
+ @Override public boolean remove(@Nullable Object value) {
+ boolean changed = delegate.remove(value);
+ if (changed) {
+ /*
+ * linkedEntries.remove() will return false when this method is called
+ * by entries().iterator().remove()
+ */
+ linkedEntries.remove(createEntry(value));
+ }
+ return changed;
}
- public void setPredecessorInMultimap(ValueEntry<K, V> multimapPredecessor) {
- this.predecessorInMultimap = multimapPredecessor;
+ @Override public boolean removeAll(Collection<?> values) {
+ boolean changed = delegate.removeAll(values);
+ if (changed) {
+ linkedEntries.removeAll(createEntries(values));
+ }
+ return changed;
}
- }
- private static final int DEFAULT_KEY_CAPACITY = 16;
- private static final int DEFAULT_VALUE_SET_CAPACITY = 2;
- @VisibleForTesting static final double VALUE_SET_LOAD_FACTOR = 1.0;
-
- @VisibleForTesting transient int valueSetCapacity = DEFAULT_VALUE_SET_CAPACITY;
- private transient ValueEntry<K, V> multimapHeaderEntry;
-
- private LinkedHashMultimap(int keyCapacity, int valueSetCapacity) {
- super(new LinkedHashMap<K, Collection<V>>(keyCapacity));
-
- checkArgument(valueSetCapacity >= 0,
- "expectedValuesPerKey must be >= 0 but was %s", valueSetCapacity);
-
- this.valueSetCapacity = valueSetCapacity;
- this.multimapHeaderEntry = new ValueEntry<K, V>(null, null, 0, null);
- succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry);
+ @Override public boolean retainAll(Collection<?> values) {
+ /*
+ * Calling linkedEntries.retainAll() would incorrectly remove values
+ * with other keys.
+ */
+ boolean changed = false;
+ Iterator<V> iterator = delegate.iterator();
+ while (iterator.hasNext()) {
+ V value = iterator.next();
+ if (!values.contains(value)) {
+ iterator.remove();
+ linkedEntries.remove(Maps.immutableEntry(key, value));
+ changed = true;
+ }
+ }
+ return changed;
+ }
}
/**
* {@inheritDoc}
*
- * <p>Creates an empty {@code LinkedHashSet} for a collection of values for
- * one key.
+ * <p>Generates an iterator across map entries that follows the ordering in
+ * which the key-value pairs were added to the multimap.
*
- * @return a new {@code LinkedHashSet} containing a collection of values for
- * one key
+ * @return a key-value iterator with the correct ordering
*/
- @Override
- Set<V> createCollection() {
- return new LinkedHashSet<V>(valueSetCapacity);
- }
+ @Override Iterator<Map.Entry<K, V>> createEntryIterator() {
+ final Iterator<Map.Entry<K, V>> delegateIterator = linkedEntries.iterator();
- /**
- * {@inheritDoc}
- *
- * <p>Creates a decorated insertion-ordered set that also keeps track of the
- * order in which key-value pairs are added to the multimap.
- *
- * @param key key to associate with values in the collection
- * @return a new decorated set containing a collection of values for one key
- */
- @Override
- Collection<V> createCollection(K key) {
- return new ValueSet(key, valueSetCapacity);
+ return new Iterator<Map.Entry<K, V>>() {
+ Map.Entry<K, V> entry;
+
+ @Override
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+
+ @Override
+ public Map.Entry<K, V> next() {
+ entry = delegateIterator.next();
+ return entry;
+ }
+
+ @Override
+ public void remove() {
+ // Remove from iterator first to keep iterator valid.
+ delegateIterator.remove();
+ LinkedHashMultimap.this.remove(entry.getKey(), entry.getValue());
+ }
+ };
}
/**
@@ -273,8 +316,8 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
* However, the provided values always come last in the {@link #entries()} and
* {@link #values()} iteration orderings.
*/
- @Override
- public Set<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
+ @Override public Set<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
return super.replaceValues(key, values);
}
@@ -305,249 +348,7 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
return super.values();
}
- @VisibleForTesting
- final class ValueSet extends Sets.ImprovedAbstractSet<V> implements ValueSetLink<K, V> {
- /*
- * We currently use a fixed load factor of 1.0, a bit higher than normal to reduce memory
- * consumption.
- */
-
- private final K key;
- @VisibleForTesting ValueEntry<K, V>[] hashTable;
- private int size = 0;
- private int modCount = 0;
-
- // We use the set object itself as the end of the linked list, avoiding an unnecessary
- // entry object per key.
- private ValueSetLink<K, V> firstEntry;
- private ValueSetLink<K, V> lastEntry;
-
- ValueSet(K key, int expectedValues) {
- this.key = key;
- this.firstEntry = this;
- this.lastEntry = this;
- // Round expected values up to a power of 2 to get the table size.
- int tableSize = Hashing.closedTableSize(expectedValues, VALUE_SET_LOAD_FACTOR);
-
- @SuppressWarnings("unchecked")
- ValueEntry<K, V>[] hashTable = new ValueEntry[tableSize];
- this.hashTable = hashTable;
- }
-
- @Override
- public ValueSetLink<K, V> getPredecessorInValueSet() {
- return lastEntry;
- }
-
- @Override
- public ValueSetLink<K, V> getSuccessorInValueSet() {
- return firstEntry;
- }
-
- @Override
- public void setPredecessorInValueSet(ValueSetLink<K, V> entry) {
- lastEntry = entry;
- }
-
- @Override
- public void setSuccessorInValueSet(ValueSetLink<K, V> entry) {
- firstEntry = entry;
- }
-
- @Override
- public Iterator<V> iterator() {
- return new Iterator<V>() {
- ValueSetLink<K, V> nextEntry = firstEntry;
- ValueEntry<K, V> toRemove;
- int expectedModCount = modCount;
-
- private void checkForComodification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
-
- @Override
- public boolean hasNext() {
- checkForComodification();
- return nextEntry != ValueSet.this;
- }
-
- @Override
- public V next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- ValueEntry<K, V> entry = (ValueEntry<K, V>) nextEntry;
- V result = entry.getValue();
- toRemove = entry;
- nextEntry = entry.getSuccessorInValueSet();
- return result;
- }
-
- @Override
- public void remove() {
- checkForComodification();
- Iterators.checkRemove(toRemove != null);
- Object o = toRemove.getValue();
- int hash = (o == null) ? 0 : o.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
- ValueEntry<K, V> prev = null;
- for (ValueEntry<K, V> entry = hashTable[row]; entry != null;
- prev = entry, entry = entry.nextInValueSetHashRow) {
- if (entry == toRemove) {
- if (prev == null) {
- // first entry in row
- hashTable[row] = entry.nextInValueSetHashRow;
- } else {
- prev.nextInValueSetHashRow = entry.nextInValueSetHashRow;
- }
- deleteFromValueSet(toRemove);
- deleteFromMultimap(toRemove);
- size--;
- expectedModCount = ++modCount;
- break;
- }
- }
- toRemove = null;
- }
- };
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public boolean contains(@Nullable Object o) {
- int hash = (o == null) ? 0 : o.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
-
- for (ValueEntry<K, V> entry = hashTable[row]; entry != null;
- entry = entry.nextInValueSetHashRow) {
- if (hash == entry.valueHash && Objects.equal(o, entry.getValue())) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean add(@Nullable V value) {
- int hash = (value == null) ? 0 : value.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
-
- ValueEntry<K, V> rowHead = hashTable[row];
- for (ValueEntry<K, V> entry = rowHead; entry != null;
- entry = entry.nextInValueSetHashRow) {
- if (hash == entry.valueHash && Objects.equal(value, entry.getValue())) {
- return false;
- }
- }
-
- ValueEntry<K, V> newEntry = new ValueEntry<K, V>(key, value, hash, rowHead);
- succeedsInValueSet(lastEntry, newEntry);
- succeedsInValueSet(newEntry, this);
- succeedsInMultimap(multimapHeaderEntry.getPredecessorInMultimap(), newEntry);
- succeedsInMultimap(newEntry, multimapHeaderEntry);
- hashTable[row] = newEntry;
- size++;
- modCount++;
- rehashIfNecessary();
- return true;
- }
-
- private void rehashIfNecessary() {
- if (Hashing.needsResizing(size, hashTable.length, VALUE_SET_LOAD_FACTOR)) {
- @SuppressWarnings("unchecked")
- ValueEntry<K, V>[] hashTable = new ValueEntry[this.hashTable.length * 2];
- this.hashTable = hashTable;
- int mask = hashTable.length - 1;
- for (ValueSetLink<K, V> entry = firstEntry;
- entry != this; entry = entry.getSuccessorInValueSet()) {
- ValueEntry<K, V> valueEntry = (ValueEntry<K, V>) entry;
- int row = Hashing.smear(valueEntry.valueHash) & mask;
- valueEntry.nextInValueSetHashRow = hashTable[row];
- hashTable[row] = valueEntry;
- }
- }
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- int hash = (o == null) ? 0 : o.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
-
- ValueEntry<K, V> prev = null;
- for (ValueEntry<K, V> entry = hashTable[row]; entry != null;
- prev = entry, entry = entry.nextInValueSetHashRow) {
- if (hash == entry.valueHash && Objects.equal(o, entry.getValue())) {
- if (prev == null) {
- // first entry in the row
- hashTable[row] = entry.nextInValueSetHashRow;
- } else {
- prev.nextInValueSetHashRow = entry.nextInValueSetHashRow;
- }
- deleteFromValueSet(entry);
- deleteFromMultimap(entry);
- size--;
- modCount++;
- return true;
- }
- }
- return false;
- }
-
- @Override
- public void clear() {
- Arrays.fill(hashTable, null);
- size = 0;
- for (ValueSetLink<K, V> entry = firstEntry;
- entry != this; entry = entry.getSuccessorInValueSet()) {
- ValueEntry<K, V> valueEntry = (ValueEntry<K, V>) entry;
- deleteFromMultimap(valueEntry);
- }
- succeedsInValueSet(this, this);
- modCount++;
- }
- }
-
- @Override
- Iterator<Map.Entry<K, V>> entryIterator() {
- return new Iterator<Map.Entry<K, V>>() {
- ValueEntry<K, V> nextEntry = multimapHeaderEntry.successorInMultimap;
- ValueEntry<K, V> toRemove;
-
- @Override
- public boolean hasNext() {
- return nextEntry != multimapHeaderEntry;
- }
-
- @Override
- public Map.Entry<K, V> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- ValueEntry<K, V> result = nextEntry;
- toRemove = result;
- nextEntry = nextEntry.successorInMultimap;
- return result;
- }
-
- @Override
- public void remove() {
- Iterators.checkRemove(toRemove != null);
- LinkedHashMultimap.this.remove(toRemove.getKey(), toRemove.getValue());
- toRemove = null;
- }
- };
- }
-
- @Override
- public void clear() {
- super.clear();
- succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry);
- }
+ // Unfortunately, the entries() ordering does not determine the key ordering;
+ // see the example in the LinkedListMultimap class Javadoc.
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultiset.java
index da93ead..7715784 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultiset.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedHashMultiset.java
@@ -27,10 +27,6 @@ import java.util.LinkedHashMap;
* element, those instances are consecutive in the iteration order. If all
* occurrences of an element are removed, after which that element is added to
* the multiset, the element will appear at the end of the iteration.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
*
* @author Kevin Bourrillion
* @author Jared Levy
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedListMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedListMultimap.java
index f51d292..2273535 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedListMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/LinkedListMultimap.java
@@ -17,7 +17,9 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Multisets.setCountImpl;
import static java.util.Collections.unmodifiableList;
import com.google.common.annotations.GwtCompatible;
@@ -25,10 +27,11 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
import java.util.AbstractSequentialList;
+import java.util.AbstractSet;
import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -88,10 +91,6 @@ import javax.annotation.Nullable;
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedListMultimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
*/
@@ -122,32 +121,12 @@ public class LinkedListMultimap<K, V>
return key + "=" + value;
}
}
-
- private static class KeyList<K, V> {
- Node<K, V> head;
- Node<K, V> tail;
- int count;
-
- KeyList(Node<K, V> firstNode) {
- this.head = firstNode;
- this.tail = firstNode;
- firstNode.previousSibling = null;
- firstNode.nextSibling = null;
- this.count = 1;
- }
- }
private transient Node<K, V> head; // the head for all keys
private transient Node<K, V> tail; // the tail for all keys
- private transient Map<K, KeyList<K, V>> keyToKeyList;
- private transient int size;
-
- /*
- * Tracks modifications to keyToKeyList so that addition or removal of keys invalidates
- * preexisting iterators. This does *not* track simple additions and removals of values
- * that are not the first to be added or last to be removed for their key.
- */
- private transient int modCount;
+ private transient Multiset<K> keyCount; // the number of values for each key
+ private transient Map<K, Node<K, V>> keyToKeyHead; // the head for a given key
+ private transient Map<K, Node<K, V>> keyToKeyTail; // the tail for a given key
/**
* Creates a new, empty {@code LinkedListMultimap} with the default initial
@@ -181,11 +160,15 @@ public class LinkedListMultimap<K, V>
}
LinkedListMultimap() {
- keyToKeyList = Maps.newHashMap();
+ keyCount = LinkedHashMultiset.create();
+ keyToKeyHead = Maps.newHashMap();
+ keyToKeyTail = Maps.newHashMap();
}
private LinkedListMultimap(int expectedKeys) {
- keyToKeyList = new HashMap<K, KeyList<K, V>>(expectedKeys);
+ keyCount = LinkedHashMultiset.create(expectedKeys);
+ keyToKeyHead = Maps.newHashMapWithExpectedSize(expectedKeys);
+ keyToKeyTail = Maps.newHashMapWithExpectedSize(expectedKeys);
}
private LinkedListMultimap(Multimap<? extends K, ? extends V> multimap) {
@@ -204,32 +187,27 @@ public class LinkedListMultimap<K, V>
Node<K, V> node = new Node<K, V>(key, value);
if (head == null) { // empty list
head = tail = node;
- keyToKeyList.put(key, new KeyList<K, V>(node));
- modCount++;
+ keyToKeyHead.put(key, node);
+ keyToKeyTail.put(key, node);
} else if (nextSibling == null) { // non-empty list, add to tail
tail.next = node;
node.previous = tail;
- tail = node;
- KeyList<K, V> keyList = keyToKeyList.get(key);
- if (keyList == null) {
- keyToKeyList.put(key, keyList = new KeyList<K, V>(node));
- modCount++;
+ Node<K, V> keyTail = keyToKeyTail.get(key);
+ if (keyTail == null) { // first for this key
+ keyToKeyHead.put(key, node);
} else {
- keyList.count++;
- Node<K, V> keyTail = keyList.tail;
keyTail.nextSibling = node;
node.previousSibling = keyTail;
- keyList.tail = node;
}
+ keyToKeyTail.put(key, node);
+ tail = node;
} else { // non-empty list, insert before nextSibling
- KeyList<K, V> keyList = keyToKeyList.get(key);
- keyList.count++;
node.previous = nextSibling.previous;
node.previousSibling = nextSibling.previousSibling;
node.next = nextSibling;
node.nextSibling = nextSibling;
if (nextSibling.previousSibling == null) { // nextSibling was key head
- keyToKeyList.get(key).head = node;
+ keyToKeyHead.put(key, node);
} else {
nextSibling.previousSibling.nextSibling = node;
}
@@ -241,7 +219,7 @@ public class LinkedListMultimap<K, V>
nextSibling.previous = node;
nextSibling.previousSibling = node;
}
- size++;
+ keyCount.add(key);
return node;
}
@@ -261,27 +239,21 @@ public class LinkedListMultimap<K, V>
} else { // node was tail
tail = node.previous;
}
- if (node.previousSibling == null && node.nextSibling == null) {
- KeyList<K, V> keyList = keyToKeyList.remove(node.key);
- keyList.count = 0;
- modCount++;
+ if (node.previousSibling != null) {
+ node.previousSibling.nextSibling = node.nextSibling;
+ } else if (node.nextSibling != null) { // node was key head
+ keyToKeyHead.put(node.key, node.nextSibling);
} else {
- KeyList<K, V> keyList = keyToKeyList.get(node.key);
- keyList.count--;
-
- if (node.previousSibling == null) {
- keyList.head = node.nextSibling;
- } else {
- node.previousSibling.nextSibling = node.nextSibling;
- }
-
- if (node.nextSibling == null) {
- keyList.tail = node.previousSibling;
- } else {
- node.nextSibling.previousSibling = node.previousSibling;
- }
+ keyToKeyHead.remove(node.key); // don't leak a key-null entry
}
- size--;
+ if (node.nextSibling != null) {
+ node.nextSibling.previousSibling = node.previousSibling;
+ } else if (node.previousSibling != null) { // node was key tail
+ keyToKeyTail.put(node.key, node.previousSibling);
+ } else {
+ keyToKeyTail.remove(node.key); // don't leak a key-null entry
+ }
+ keyCount.remove(node.key);
}
/** Removes all nodes for the specified key. */
@@ -305,7 +277,6 @@ public class LinkedListMultimap<K, V>
Node<K, V> next;
Node<K, V> current;
Node<K, V> previous;
- int expectedModCount = modCount;
NodeIterator() {
next = head;
@@ -327,19 +298,12 @@ public class LinkedListMultimap<K, V>
}
current = null;
}
- private void checkForConcurrentModification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
@Override
public boolean hasNext() {
- checkForConcurrentModification();
return next != null;
}
@Override
public Node<K, V> next() {
- checkForConcurrentModification();
checkElement(next);
previous = current = next;
next = next.next;
@@ -348,7 +312,6 @@ public class LinkedListMultimap<K, V>
}
@Override
public void remove() {
- checkForConcurrentModification();
checkState(current != null);
if (current != next) { // after call to next()
previous = current.previous;
@@ -358,16 +321,13 @@ public class LinkedListMultimap<K, V>
}
removeNode(current);
current = null;
- expectedModCount = modCount;
}
@Override
public boolean hasPrevious() {
- checkForConcurrentModification();
return previous != null;
}
@Override
public Node<K, V> previous() {
- checkForConcurrentModification();
checkElement(previous);
next = current = previous;
previous = previous.previous;
@@ -401,21 +361,13 @@ public class LinkedListMultimap<K, V>
final Set<K> seenKeys = Sets.<K>newHashSetWithExpectedSize(keySet().size());
Node<K, V> next = head;
Node<K, V> current;
- int expectedModCount = modCount;
-
- private void checkForConcurrentModification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
+
@Override
public boolean hasNext() {
- checkForConcurrentModification();
return next != null;
}
@Override
public K next() {
- checkForConcurrentModification();
checkElement(next);
current = next;
seenKeys.add(current.key);
@@ -426,11 +378,9 @@ public class LinkedListMultimap<K, V>
}
@Override
public void remove() {
- checkForConcurrentModification();
checkState(current != null);
removeAllNodes(current.key);
current = null;
- expectedModCount = modCount;
}
}
@@ -445,8 +395,7 @@ public class LinkedListMultimap<K, V>
/** Constructs a new iterator over all values for the specified key. */
ValueForKeyIterator(@Nullable Object key) {
this.key = key;
- KeyList<K, V> keyList = keyToKeyList.get(key);
- next = (keyList == null) ? null : keyList.head;
+ next = keyToKeyHead.get(key);
}
/**
@@ -459,17 +408,16 @@ public class LinkedListMultimap<K, V>
* @throws IndexOutOfBoundsException if index is invalid
*/
public ValueForKeyIterator(@Nullable Object key, int index) {
- KeyList<K, V> keyList = keyToKeyList.get(key);
- int size = (keyList == null) ? 0 : keyList.count;
+ int size = keyCount.count(key);
Preconditions.checkPositionIndex(index, size);
if (index >= (size / 2)) {
- previous = (keyList == null) ? null : keyList.tail;
+ previous = keyToKeyTail.get(key);
nextIndex = size;
while (index++ < size) {
previous();
}
} else {
- next = (keyList == null) ? null : keyList.head;
+ next = keyToKeyHead.get(key);
while (index-- > 0) {
next();
}
@@ -548,7 +496,7 @@ public class LinkedListMultimap<K, V>
@Override
public int size() {
- return size;
+ return keyCount.size();
}
@Override
@@ -558,7 +506,7 @@ public class LinkedListMultimap<K, V>
@Override
public boolean containsKey(@Nullable Object key) {
- return keyToKeyList.containsKey(key);
+ return keyToKeyHead.containsKey(key);
}
@Override
@@ -685,9 +633,9 @@ public class LinkedListMultimap<K, V>
public void clear() {
head = null;
tail = null;
- keyToKeyList.clear();
- size = 0;
- modCount++;
+ keyCount.clear();
+ keyToKeyHead.clear();
+ keyToKeyTail.clear();
}
// Views
@@ -705,8 +653,7 @@ public class LinkedListMultimap<K, V>
public List<V> get(final @Nullable K key) {
return new AbstractSequentialList<V>() {
@Override public int size() {
- KeyList<K, V> keyList = keyToKeyList.get(key);
- return (keyList == null) ? 0 : keyList.count;
+ return keyCount.count(key);
}
@Override public ListIterator<V> listIterator(int index) {
return new ValueForKeyIterator(key, index);
@@ -726,19 +673,19 @@ public class LinkedListMultimap<K, V>
public Set<K> keySet() {
Set<K> result = keySet;
if (result == null) {
- keySet = result = new Sets.ImprovedAbstractSet<K>() {
+ keySet = result = new AbstractSet<K>() {
@Override public int size() {
- return keyToKeyList.size();
+ return keyCount.elementSet().size();
}
@Override public Iterator<K> iterator() {
return new DistinctKeyIterator();
}
@Override public boolean contains(Object key) { // for performance
- return containsKey(key);
+ return keyCount.contains(key);
}
- @Override
- public boolean remove(Object o) { // for performance
- return !LinkedListMultimap.this.removeAll(o).isEmpty();
+ @Override public boolean removeAll(Collection<?> c) {
+ checkNotNull(c); // eager for GWT
+ return super.removeAll(c);
}
};
}
@@ -756,50 +703,39 @@ public class LinkedListMultimap<K, V>
return result;
}
- private class MultisetView extends AbstractMultiset<K> {
- @Override
- public int size() {
- return size;
- }
+ private class MultisetView extends AbstractCollection<K>
+ implements Multiset<K> {
- @Override
- public int count(Object element) {
- KeyList<K, V> keyList = keyToKeyList.get(element);
- return (keyList == null) ? 0 : keyList.count;
+ @Override public int size() {
+ return keyCount.size();
}
- @Override
- Iterator<Entry<K>> entryIterator() {
- return new TransformedIterator<K, Entry<K>>(new DistinctKeyIterator()) {
+ @Override public Iterator<K> iterator() {
+ final Iterator<Node<K, V>> nodes = new NodeIterator();
+ return new Iterator<K>() {
@Override
- Entry<K> transform(final K key) {
- return new Multisets.AbstractEntry<K>() {
- @Override
- public K getElement() {
- return key;
- }
-
- @Override
- public int getCount() {
- return keyToKeyList.get(key).count;
- }
- };
+ public boolean hasNext() {
+ return nodes.hasNext();
+ }
+ @Override
+ public K next() {
+ return nodes.next().key;
+ }
+ @Override
+ public void remove() {
+ nodes.remove();
}
};
}
@Override
- int distinctElements() {
- return elementSet().size();
+ public int count(@Nullable Object key) {
+ return keyCount.count(key);
}
- @Override public Iterator<K> iterator() {
- return new TransformedIterator<Node<K, V>, K>(new NodeIterator()) {
- @Override
- K transform(Node<K, V> node) {
- return node.key;
- }
- };
+ @Override
+ public int add(@Nullable K key, int occurrences) {
+ throw new UnsupportedOperationException();
}
@Override
@@ -815,9 +751,77 @@ public class LinkedListMultimap<K, V>
}
@Override
+ public int setCount(K element, int count) {
+ return setCountImpl(this, element, count);
+ }
+
+ @Override
+ public boolean setCount(K element, int oldCount, int newCount) {
+ return setCountImpl(this, element, oldCount, newCount);
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+
+ @Override
public Set<K> elementSet() {
return keySet();
}
+
+ @Override
+ public Set<Entry<K>> entrySet() {
+ // TODO(jlevy): lazy init?
+ return new AbstractSet<Entry<K>>() {
+ @Override public int size() {
+ return keyCount.elementSet().size();
+ }
+
+ @Override public Iterator<Entry<K>> iterator() {
+ final Iterator<K> keyIterator = new DistinctKeyIterator();
+ return new Iterator<Entry<K>>() {
+ @Override
+ public boolean hasNext() {
+ return keyIterator.hasNext();
+ }
+ @Override
+ public Entry<K> next() {
+ final K key = keyIterator.next();
+ return new Multisets.AbstractEntry<K>() {
+ @Override
+ public K getElement() {
+ return key;
+ }
+ @Override
+ public int getCount() {
+ return keyCount.count(key);
+ }
+ };
+ }
+ @Override
+ public void remove() {
+ keyIterator.remove();
+ }
+ };
+ }
+ };
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return keyCount.equals(object);
+ }
+
+ @Override public int hashCode() {
+ return keyCount.hashCode();
+ }
+
+ @Override public String toString() {
+ return keyCount.toString(); // XXX observe order?
+ }
}
private transient List<V> valuesList;
@@ -837,20 +841,47 @@ public class LinkedListMultimap<K, V>
if (result == null) {
valuesList = result = new AbstractSequentialList<V>() {
@Override public int size() {
- return size;
+ return keyCount.size();
}
@Override
public ListIterator<V> listIterator(int index) {
final NodeIterator nodes = new NodeIterator(index);
- return new TransformedListIterator<Node<K, V>, V>(nodes) {
+ return new ListIterator<V>() {
@Override
- V transform(Node<K, V> node) {
- return node.value;
+ public boolean hasNext() {
+ return nodes.hasNext();
+ }
+ @Override
+ public V next() {
+ return nodes.next().value;
+ }
+ @Override
+ public boolean hasPrevious() {
+ return nodes.hasPrevious();
+ }
+ @Override
+ public V previous() {
+ return nodes.previous().value;
}
-
@Override
- public void set(V value) {
- nodes.setValue(value);
+ public int nextIndex() {
+ return nodes.nextIndex();
+ }
+ @Override
+ public int previousIndex() {
+ return nodes.previousIndex();
+ }
+ @Override
+ public void remove() {
+ nodes.remove();
+ }
+ @Override
+ public void set(V e) {
+ nodes.setValue(e);
+ }
+ @Override
+ public void add(V e) {
+ throw new UnsupportedOperationException();
}
};
}
@@ -901,14 +932,55 @@ public class LinkedListMultimap<K, V>
if (result == null) {
entries = result = new AbstractSequentialList<Entry<K, V>>() {
@Override public int size() {
- return size;
+ return keyCount.size();
}
@Override public ListIterator<Entry<K, V>> listIterator(int index) {
- return new TransformedListIterator<Node<K, V>, Entry<K, V>>(new NodeIterator(index)) {
+ final ListIterator<Node<K, V>> nodes = new NodeIterator(index);
+ return new ListIterator<Entry<K, V>>() {
+ @Override
+ public boolean hasNext() {
+ return nodes.hasNext();
+ }
+
+ @Override
+ public Entry<K, V> next() {
+ return createEntry(nodes.next());
+ }
+
+ @Override
+ public void remove() {
+ nodes.remove();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return nodes.hasPrevious();
+ }
+
+ @Override
+ public Map.Entry<K, V> previous() {
+ return createEntry(nodes.previous());
+ }
+
+ @Override
+ public int nextIndex() {
+ return nodes.nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return nodes.previousIndex();
+ }
+
+ @Override
+ public void set(Map.Entry<K, V> e) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
- Entry<K, V> transform(Node<K, V> node) {
- return createEntry(node);
+ public void add(Map.Entry<K, V> e) {
+ throw new UnsupportedOperationException();
}
};
}
@@ -917,39 +989,75 @@ public class LinkedListMultimap<K, V>
return result;
}
+ private class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
+ @Override public int size() {
+ return keyCount.elementSet().size();
+ }
+
+ @Override public Iterator<Entry<K, Collection<V>>> iterator() {
+ final Iterator<K> keyIterator = new DistinctKeyIterator();
+ return new Iterator<Entry<K, Collection<V>>>() {
+ @Override
+ public boolean hasNext() {
+ return keyIterator.hasNext();
+ }
+
+ @Override
+ public Entry<K, Collection<V>> next() {
+ final K key = keyIterator.next();
+ return new AbstractMapEntry<K, Collection<V>>() {
+ @Override public K getKey() {
+ return key;
+ }
+
+ @Override public Collection<V> getValue() {
+ return LinkedListMultimap.this.get(key);
+ }
+ };
+ }
+
+ @Override
+ public void remove() {
+ keyIterator.remove();
+ }
+ };
+ }
+
+ // TODO(jlevy): Override contains() and remove() for better performance.
+ }
+
private transient Map<K, Collection<V>> map;
@Override
public Map<K, Collection<V>> asMap() {
Map<K, Collection<V>> result = map;
if (result == null) {
- map = result = new Multimaps.AsMap<K, V>() {
- @Override
- public int size() {
- return keyToKeyList.size();
+ map = result = new AbstractMap<K, Collection<V>>() {
+ Set<Entry<K, Collection<V>>> entrySet;
+
+ @Override public Set<Entry<K, Collection<V>>> entrySet() {
+ Set<Entry<K, Collection<V>>> result = entrySet;
+ if (result == null) {
+ entrySet = result = new AsMapEntries();
+ }
+ return result;
}
- @Override
- Multimap<K, V> multimap() {
- return LinkedListMultimap.this;
+ // The following methods are included for performance.
+
+ @Override public boolean containsKey(@Nullable Object key) {
+ return LinkedListMultimap.this.containsKey(key);
}
- @Override
- Iterator<Entry<K, Collection<V>>> entryIterator() {
- return new TransformedIterator<K, Entry<K, Collection<V>>>(new DistinctKeyIterator()) {
- @Override
- Entry<K, Collection<V>> transform(final K key) {
- return new AbstractMapEntry<K, Collection<V>>() {
- @Override public K getKey() {
- return key;
- }
+ @SuppressWarnings("unchecked")
+ @Override public Collection<V> get(@Nullable Object key) {
+ Collection<V> collection = LinkedListMultimap.this.get((K) key);
+ return collection.isEmpty() ? null : collection;
+ }
- @Override public Collection<V> getValue() {
- return LinkedListMultimap.this.get(key);
- }
- };
- }
- };
+ @Override public Collection<V> remove(@Nullable Object key) {
+ Collection<V> collection = removeAll(key);
+ return collection.isEmpty() ? null : collection;
}
};
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Lists.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Lists.java
deleted file mode 100644
index 0bdb38a..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Lists.java
+++ /dev/null
@@ -1,1122 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkElementIndex;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndex;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.primitives.Ints;
-
-import java.io.Serializable;
-import java.util.AbstractList;
-import java.util.AbstractSequentialList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-import java.util.RandomAccess;
-
-import javax.annotation.Nullable;
-
-/**
- * Static utility methods pertaining to {@link List} instances. Also see this
- * class's counterparts {@link Sets}, {@link Maps} and {@link Queues}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Lists">
- * {@code Lists}</a>.
- *
- * @author Kevin Bourrillion
- * @author Mike Bostock
- * @author Louis Wasserman
- * @since 2.0 (imported from Google Collections Library)
- */
-@GwtCompatible(emulated = true)
-public final class Lists {
- private Lists() {}
-
- // ArrayList
-
- /**
- * Creates a <i>mutable</i>, empty {@code ArrayList} instance.
- *
- * <p><b>Note:</b> if mutability is not required, use {@link
- * ImmutableList#of()} instead.
- *
- * @return a new, empty {@code ArrayList}
- */
- @GwtCompatible(serializable = true)
- public static <E> ArrayList<E> newArrayList() {
- return new ArrayList<E>();
- }
-
- /**
- * Creates a <i>mutable</i> {@code ArrayList} instance containing the given
- * elements.
- *
- * <p><b>Note:</b> if mutability is not required and the elements are
- * non-null, use an overload of {@link ImmutableList#of()} (for varargs) or
- * {@link ImmutableList#copyOf(Object[])} (for an array) instead.
- *
- * @param elements the elements that the list should contain, in order
- * @return a new {@code ArrayList} containing those elements
- */
- @GwtCompatible(serializable = true)
- public static <E> ArrayList<E> newArrayList(E... elements) {
- checkNotNull(elements); // for GWT
- // Avoid integer overflow when a large array is passed in
- int capacity = computeArrayListCapacity(elements.length);
- ArrayList<E> list = new ArrayList<E>(capacity);
- Collections.addAll(list, elements);
- return list;
- }
-
- @VisibleForTesting static int computeArrayListCapacity(int arraySize) {
- checkArgument(arraySize >= 0);
-
- // TODO(kevinb): Figure out the right behavior, and document it
- return Ints.saturatedCast(5L + arraySize + (arraySize / 10));
- }
-
- /**
- * Creates a <i>mutable</i> {@code ArrayList} instance containing the given
- * elements.
- *
- * <p><b>Note:</b> if mutability is not required and the elements are
- * non-null, use {@link ImmutableList#copyOf(Iterator)} instead.
- *
- * @param elements the elements that the list should contain, in order
- * @return a new {@code ArrayList} containing those elements
- */
- @GwtCompatible(serializable = true)
- public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
- checkNotNull(elements); // for GWT
- // Let ArrayList's sizing logic work, if possible
- return (elements instanceof Collection)
- ? new ArrayList<E>(Collections2.cast(elements))
- : newArrayList(elements.iterator());
- }
-
- /**
- * Creates a <i>mutable</i> {@code ArrayList} instance containing the given
- * elements.
- *
- * <p><b>Note:</b> if mutability is not required and the elements are
- * non-null, use {@link ImmutableList#copyOf(Iterator)} instead.
- *
- * @param elements the elements that the list should contain, in order
- * @return a new {@code ArrayList} containing those elements
- */
- @GwtCompatible(serializable = true)
- public static <E> ArrayList<E> newArrayList(Iterator<? extends E> elements) {
- checkNotNull(elements); // for GWT
- ArrayList<E> list = newArrayList();
- while (elements.hasNext()) {
- list.add(elements.next());
- }
- return list;
- }
-
- /**
- * Creates an {@code ArrayList} instance backed by an array of the
- * <i>exact</i> size specified; equivalent to
- * {@link ArrayList#ArrayList(int)}.
- *
- * <p><b>Note:</b> if you know the exact size your list will be, consider
- * using a fixed-size list ({@link Arrays#asList(Object[])}) or an {@link
- * ImmutableList} instead of a growable {@link ArrayList}.
- *
- * <p><b>Note:</b> If you have only an <i>estimate</i> of the eventual size of
- * the list, consider padding this estimate by a suitable amount, or simply
- * use {@link #newArrayListWithExpectedSize(int)} instead.
- *
- * @param initialArraySize the exact size of the initial backing array for
- * the returned array list ({@code ArrayList} documentation calls this
- * value the "capacity")
- * @return a new, empty {@code ArrayList} which is guaranteed not to resize
- * itself unless its size reaches {@code initialArraySize + 1}
- * @throws IllegalArgumentException if {@code initialArraySize} is negative
- */
- @GwtCompatible(serializable = true)
- public static <E> ArrayList<E> newArrayListWithCapacity(
- int initialArraySize) {
- checkArgument(initialArraySize >= 0); // for GWT.
- return new ArrayList<E>(initialArraySize);
- }
-
- /**
- * Creates an {@code ArrayList} instance sized appropriately to hold an
- * <i>estimated</i> number of elements without resizing. A small amount of
- * padding is added in case the estimate is low.
- *
- * <p><b>Note:</b> If you know the <i>exact</i> number of elements the list
- * will hold, or prefer to calculate your own amount of padding, refer to
- * {@link #newArrayListWithCapacity(int)}.
- *
- * @param estimatedSize an estimate of the eventual {@link List#size()} of
- * the new list
- * @return a new, empty {@code ArrayList}, sized appropriately to hold the
- * estimated number of elements
- * @throws IllegalArgumentException if {@code estimatedSize} is negative
- */
- @GwtCompatible(serializable = true)
- public static <E> ArrayList<E> newArrayListWithExpectedSize(
- int estimatedSize) {
- return new ArrayList<E>(computeArrayListCapacity(estimatedSize));
- }
-
- // LinkedList
-
- /**
- * Creates an empty {@code LinkedList} instance.
- *
- * <p><b>Note:</b> if you need an immutable empty {@link List}, use
- * {@link ImmutableList#of()} instead.
- *
- * @return a new, empty {@code LinkedList}
- */
- @GwtCompatible(serializable = true)
- public static <E> LinkedList<E> newLinkedList() {
- return new LinkedList<E>();
- }
-
- /**
- * Creates a {@code LinkedList} instance containing the given elements.
- *
- * @param elements the elements that the list should contain, in order
- * @return a new {@code LinkedList} containing those elements
- */
- @GwtCompatible(serializable = true)
- public static <E> LinkedList<E> newLinkedList(
- Iterable<? extends E> elements) {
- LinkedList<E> list = newLinkedList();
- for (E element : elements) {
- list.add(element);
- }
- return list;
- }
-
- /**
- * Returns an unmodifiable list containing the specified first element and
- * backed by the specified array of additional elements. Changes to the {@code
- * rest} array will be reflected in the returned list. Unlike {@link
- * Arrays#asList}, the returned list is unmodifiable.
- *
- * <p>This is useful when a varargs method needs to use a signature such as
- * {@code (Foo firstFoo, Foo... moreFoos)}, in order to avoid overload
- * ambiguity or to enforce a minimum argument count.
- *
- * <p>The returned list is serializable and implements {@link RandomAccess}.
- *
- * @param first the first element
- * @param rest an array of additional elements, possibly empty
- * @return an unmodifiable list containing the specified elements
- */
- public static <E> List<E> asList(@Nullable E first, E[] rest) {
- return new OnePlusArrayList<E>(first, rest);
- }
-
- /** @see Lists#asList(Object, Object[]) */
- private static class OnePlusArrayList<E> extends AbstractList<E>
- implements Serializable, RandomAccess {
- final E first;
- final E[] rest;
-
- OnePlusArrayList(@Nullable E first, E[] rest) {
- this.first = first;
- this.rest = checkNotNull(rest);
- }
- @Override public int size() {
- return rest.length + 1;
- }
- @Override public E get(int index) {
- // check explicitly so the IOOBE will have the right message
- checkElementIndex(index, size());
- return (index == 0) ? first : rest[index - 1];
- }
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns an unmodifiable list containing the specified first and second
- * element, and backed by the specified array of additional elements. Changes
- * to the {@code rest} array will be reflected in the returned list. Unlike
- * {@link Arrays#asList}, the returned list is unmodifiable.
- *
- * <p>This is useful when a varargs method needs to use a signature such as
- * {@code (Foo firstFoo, Foo secondFoo, Foo... moreFoos)}, in order to avoid
- * overload ambiguity or to enforce a minimum argument count.
- *
- * <p>The returned list is serializable and implements {@link RandomAccess}.
- *
- * @param first the first element
- * @param second the second element
- * @param rest an array of additional elements, possibly empty
- * @return an unmodifiable list containing the specified elements
- */
- public static <E> List<E> asList(
- @Nullable E first, @Nullable E second, E[] rest) {
- return new TwoPlusArrayList<E>(first, second, rest);
- }
-
- /** @see Lists#asList(Object, Object, Object[]) */
- private static class TwoPlusArrayList<E> extends AbstractList<E>
- implements Serializable, RandomAccess {
- final E first;
- final E second;
- final E[] rest;
-
- TwoPlusArrayList(@Nullable E first, @Nullable E second, E[] rest) {
- this.first = first;
- this.second = second;
- this.rest = checkNotNull(rest);
- }
- @Override public int size() {
- return rest.length + 2;
- }
- @Override public E get(int index) {
- switch (index) {
- case 0:
- return first;
- case 1:
- return second;
- default:
- // check explicitly so the IOOBE will have the right message
- checkElementIndex(index, size());
- return rest[index - 2];
- }
- }
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns every possible list that can be formed by choosing one element
- * from each of the given lists in order; the "n-ary
- * <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
- * product</a>" of the lists. For example: <pre> {@code
- *
- * Lists.cartesianProduct(ImmutableList.of(
- * ImmutableList.of(1, 2),
- * ImmutableList.of("A", "B", "C")))}</pre>
- *
- * returns a list containing six lists in the following order:
- *
- * <ul>
- * <li>{@code ImmutableList.of(1, "A")}
- * <li>{@code ImmutableList.of(1, "B")}
- * <li>{@code ImmutableList.of(1, "C")}
- * <li>{@code ImmutableList.of(2, "A")}
- * <li>{@code ImmutableList.of(2, "B")}
- * <li>{@code ImmutableList.of(2, "C")}
- * </ul>
- *
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : lists.get(0)) {
- * for (B b1 : lists.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input list is empty, the Cartesian product will also be
- * empty. If no lists at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
- *
- * <p><i>Performance notes:</i> while the cartesian product of lists of size
- * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory
- * consumption is much smaller. When the cartesian product is constructed, the
- * input lists are merely copied. Only as the resulting list is iterated are
- * the individual lists created, and these are not retained after iteration.
- *
- * @param lists the lists to choose elements from, in the order that
- * the elements chosen from those lists should appear in the resulting
- * lists
- * @param <B> any common base class shared by all axes (often just {@link
- * Object})
- * @return the Cartesian product, as an immutable list containing immutable
- * lists
- * @throws IllegalArgumentException if the size of the cartesian product would
- * be greater than {@link Integer#MAX_VALUE}
- * @throws NullPointerException if {@code lists}, any one of the {@code lists},
- * or any element of a provided list is null
- */
- static <B> List<List<B>> cartesianProduct(
- List<? extends List<? extends B>> lists) {
- return CartesianList.create(lists);
- }
-
- /**
- * Returns every possible list that can be formed by choosing one element
- * from each of the given lists in order; the "n-ary
- * <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
- * product</a>" of the lists. For example: <pre> {@code
- *
- * Lists.cartesianProduct(ImmutableList.of(
- * ImmutableList.of(1, 2),
- * ImmutableList.of("A", "B", "C")))}</pre>
- *
- * returns a list containing six lists in the following order:
- *
- * <ul>
- * <li>{@code ImmutableList.of(1, "A")}
- * <li>{@code ImmutableList.of(1, "B")}
- * <li>{@code ImmutableList.of(1, "C")}
- * <li>{@code ImmutableList.of(2, "A")}
- * <li>{@code ImmutableList.of(2, "B")}
- * <li>{@code ImmutableList.of(2, "C")}
- * </ul>
- *
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : lists.get(0)) {
- * for (B b1 : lists.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input list is empty, the Cartesian product will also be
- * empty. If no lists at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
- *
- * <p><i>Performance notes:</i> while the cartesian product of lists of size
- * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory
- * consumption is much smaller. When the cartesian product is constructed, the
- * input lists are merely copied. Only as the resulting list is iterated are
- * the individual lists created, and these are not retained after iteration.
- *
- * @param lists the lists to choose elements from, in the order that
- * the elements chosen from those lists should appear in the resulting
- * lists
- * @param <B> any common base class shared by all axes (often just {@link
- * Object})
- * @return the Cartesian product, as an immutable list containing immutable
- * lists
- * @throws IllegalArgumentException if the size of the cartesian product would
- * be greater than {@link Integer#MAX_VALUE}
- * @throws NullPointerException if {@code lists}, any one of the
- * {@code lists}, or any element of a provided list is null
- */
- static <B> List<List<B>> cartesianProduct(List<? extends B>... lists) {
- return cartesianProduct(Arrays.asList(lists));
- }
-
- /**
- * Returns a list that applies {@code function} to each element of {@code
- * fromList}. The returned list is a transformed view of {@code fromList};
- * changes to {@code fromList} will be reflected in the returned list and vice
- * versa.
- *
- * <p>Since functions are not reversible, the transform is one-way and new
- * items cannot be stored in the returned list. The {@code add},
- * {@code addAll} and {@code set} methods are unsupported in the returned
- * list.
- *
- * <p>The function is applied lazily, invoked when needed. This is necessary
- * for the returned list to be a view, but it means that the function will be
- * applied many times for bulk operations like {@link List#contains} and
- * {@link List#hashCode}. For this to perform well, {@code function} should be
- * fast. To avoid lazy evaluation when the returned list doesn't need to be a
- * view, copy the returned list into a new list of your choosing.
- *
- * <p>If {@code fromList} implements {@link RandomAccess}, so will the
- * returned list. The returned list is threadsafe if the supplied list and
- * function are.
- *
- * <p>If only a {@code Collection} or {@code Iterable} input is available, use
- * {@link Collections2#transform} or {@link Iterables#transform}.
- *
- * <p><b>Note:</b> serializing the returned list is implemented by serializing
- * {@code fromList}, its contents, and {@code function} -- <i>not</i> by
- * serializing the transformed values. This can lead to surprising behavior,
- * so serializing the returned list is <b>not recommended</b>. Instead,
- * copy the list using {@link ImmutableList#copyOf(Collection)} (for example),
- * then serialize the copy. Other methods similar to this do not implement
- * serialization at all for this reason.
- */
- public static <F, T> List<T> transform(
- List<F> fromList, Function<? super F, ? extends T> function) {
- return (fromList instanceof RandomAccess)
- ? new TransformingRandomAccessList<F, T>(fromList, function)
- : new TransformingSequentialList<F, T>(fromList, function);
- }
-
- /**
- * Implementation of a sequential transforming list.
- *
- * @see Lists#transform
- */
- private static class TransformingSequentialList<F, T>
- extends AbstractSequentialList<T> implements Serializable {
- final List<F> fromList;
- final Function<? super F, ? extends T> function;
-
- TransformingSequentialList(
- List<F> fromList, Function<? super F, ? extends T> function) {
- this.fromList = checkNotNull(fromList);
- this.function = checkNotNull(function);
- }
- /**
- * The default implementation inherited is based on iteration and removal of
- * each element which can be overkill. That's why we forward this call
- * directly to the backing list.
- */
- @Override public void clear() {
- fromList.clear();
- }
- @Override public int size() {
- return fromList.size();
- }
- @Override public ListIterator<T> listIterator(final int index) {
- return new TransformedListIterator<F, T>(fromList.listIterator(index)) {
- @Override
- T transform(F from) {
- return function.apply(from);
- }
- };
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Implementation of a transforming random access list. We try to make as many
- * of these methods pass-through to the source list as possible so that the
- * performance characteristics of the source list and transformed list are
- * similar.
- *
- * @see Lists#transform
- */
- private static class TransformingRandomAccessList<F, T>
- extends AbstractList<T> implements RandomAccess, Serializable {
- final List<F> fromList;
- final Function<? super F, ? extends T> function;
-
- TransformingRandomAccessList(
- List<F> fromList, Function<? super F, ? extends T> function) {
- this.fromList = checkNotNull(fromList);
- this.function = checkNotNull(function);
- }
- @Override public void clear() {
- fromList.clear();
- }
- @Override public T get(int index) {
- return function.apply(fromList.get(index));
- }
- @Override public boolean isEmpty() {
- return fromList.isEmpty();
- }
- @Override public T remove(int index) {
- return function.apply(fromList.remove(index));
- }
- @Override public int size() {
- return fromList.size();
- }
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns consecutive {@linkplain List#subList(int, int) sublists} of a list,
- * each of the same size (the final list may be smaller). For example,
- * partitioning a list containing {@code [a, b, c, d, e]} with a partition
- * size of 3 yields {@code [[a, b, c], [d, e]]} -- an outer list containing
- * two inner lists of three and two elements, all in the original order.
- *
- * <p>The outer list is unmodifiable, but reflects the latest state of the
- * source list. The inner lists are sublist views of the original list,
- * produced on demand using {@link List#subList(int, int)}, and are subject
- * to all the usual caveats about modification as explained in that API.
- *
- * @param list the list to return consecutive sublists of
- * @param size the desired size of each sublist (the last may be
- * smaller)
- * @return a list of consecutive sublists
- * @throws IllegalArgumentException if {@code partitionSize} is nonpositive
- */
- public static <T> List<List<T>> partition(List<T> list, int size) {
- checkNotNull(list);
- checkArgument(size > 0);
- return (list instanceof RandomAccess)
- ? new RandomAccessPartition<T>(list, size)
- : new Partition<T>(list, size);
- }
-
- private static class Partition<T> extends AbstractList<List<T>> {
- final List<T> list;
- final int size;
-
- Partition(List<T> list, int size) {
- this.list = list;
- this.size = size;
- }
-
- @Override public List<T> get(int index) {
- int listSize = size();
- checkElementIndex(index, listSize);
- int start = index * size;
- int end = Math.min(start + size, list.size());
- return list.subList(start, end);
- }
-
- @Override public int size() {
- // TODO(user): refactor to common.math.IntMath.divide
- int result = list.size() / size;
- if (result * size != list.size()) {
- result++;
- }
- return result;
- }
-
- @Override public boolean isEmpty() {
- return list.isEmpty();
- }
- }
-
- private static class RandomAccessPartition<T> extends Partition<T>
- implements RandomAccess {
- RandomAccessPartition(List<T> list, int size) {
- super(list, size);
- }
- }
-
- /**
- * Returns a view of the specified string as an immutable list of {@code
- * Character} values.
- *
- * @since 7.0
- */
- @Beta public static ImmutableList<Character> charactersOf(String string) {
- return new StringAsImmutableList(checkNotNull(string));
- }
-
- @SuppressWarnings("serial") // serialized using ImmutableList serialization
- private static final class StringAsImmutableList
- extends ImmutableList<Character> {
-
- private final String string;
-
- StringAsImmutableList(String string) {
- this.string = string;
- }
-
- @Override public int indexOf(@Nullable Object object) {
- return (object instanceof Character)
- ? string.indexOf((Character) object) : -1;
- }
-
- @Override public int lastIndexOf(@Nullable Object object) {
- return (object instanceof Character)
- ? string.lastIndexOf((Character) object) : -1;
- }
-
- @Override public ImmutableList<Character> subList(
- int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size()); // for GWT
- return charactersOf(string.substring(fromIndex, toIndex));
- }
-
- @Override boolean isPartialView() {
- return false;
- }
-
- @Override public Character get(int index) {
- checkElementIndex(index, size()); // for GWT
- return string.charAt(index);
- }
-
- @Override public int size() {
- return string.length();
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof List)) {
- return false;
- }
- List<?> list = (List<?>) obj;
- int n = string.length();
- if (n != list.size()) {
- return false;
- }
- Iterator<?> iterator = list.iterator();
- for (int i = 0; i < n; i++) {
- Object elem = iterator.next();
- if (!(elem instanceof Character)
- || ((Character) elem).charValue() != string.charAt(i)) {
- return false;
- }
- }
- return true;
- }
-
- int hash = 0;
-
- @Override public int hashCode() {
- int h = hash;
- if (h == 0) {
- h = 1;
- for (int i = 0; i < string.length(); i++) {
- h = h * 31 + string.charAt(i);
- }
- hash = h;
- }
- return h;
- }
- }
-
- /**
- * Returns a view of the specified {@code CharSequence} as a {@code
- * List<Character>}, viewing {@code sequence} as a sequence of Unicode code
- * units. The view does not support any modification operations, but reflects
- * any changes to the underlying character sequence.
- *
- * @param sequence the character sequence to view as a {@code List} of
- * characters
- * @return an {@code List<Character>} view of the character sequence
- * @since 7.0
- */
- @Beta public static List<Character> charactersOf(CharSequence sequence) {
- return new CharSequenceAsList(checkNotNull(sequence));
- }
-
- private static final class CharSequenceAsList
- extends AbstractList<Character> {
- private final CharSequence sequence;
-
- CharSequenceAsList(CharSequence sequence) {
- this.sequence = sequence;
- }
-
- @Override public Character get(int index) {
- checkElementIndex(index, size()); // for GWT
- return sequence.charAt(index);
- }
-
- @Override public boolean contains(@Nullable Object o) {
- return indexOf(o) >= 0;
- }
-
- @Override public int indexOf(@Nullable Object o) {
- if (o instanceof Character) {
- char c = (Character) o;
- for (int i = 0; i < sequence.length(); i++) {
- if (sequence.charAt(i) == c) {
- return i;
- }
- }
- }
- return -1;
- }
-
- @Override public int lastIndexOf(@Nullable Object o) {
- if (o instanceof Character) {
- char c = ((Character) o).charValue();
- for (int i = sequence.length() - 1; i >= 0; i--) {
- if (sequence.charAt(i) == c) {
- return i;
- }
- }
- }
- return -1;
- }
-
- @Override public int size() {
- return sequence.length();
- }
-
- @Override public List<Character> subList(int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size()); // for GWT
- return charactersOf(sequence.subSequence(fromIndex, toIndex));
- }
-
- @Override public int hashCode() {
- int hash = 1;
- for (int i = 0; i < sequence.length(); i++) {
- hash = hash * 31 + sequence.charAt(i);
- }
- return hash;
- }
-
- @Override public boolean equals(@Nullable Object o) {
- if (!(o instanceof List)) {
- return false;
- }
- List<?> list = (List<?>) o;
- int n = sequence.length();
- if (n != list.size()) {
- return false;
- }
- Iterator<?> iterator = list.iterator();
- for (int i = 0; i < n; i++) {
- Object elem = iterator.next();
- if (!(elem instanceof Character)
- || ((Character) elem).charValue() != sequence.charAt(i)) {
- return false;
- }
- }
- return true;
- }
- }
-
- /**
- * Returns a reversed view of the specified list. For example, {@code
- * Lists.reverse(Arrays.asList(1, 2, 3))} returns a list containing {@code 3,
- * 2, 1}. The returned list is backed by this list, so changes in the returned
- * list are reflected in this list, and vice-versa. The returned list supports
- * all of the optional list operations supported by this list.
- *
- * <p>The returned list is random-access if the specified list is random
- * access.
- *
- * @since 7.0
- */
- public static <T> List<T> reverse(List<T> list) {
- if (list instanceof ReverseList) {
- return ((ReverseList<T>) list).getForwardList();
- } else if (list instanceof RandomAccess) {
- return new RandomAccessReverseList<T>(list);
- } else {
- return new ReverseList<T>(list);
- }
- }
-
- private static class ReverseList<T> extends AbstractList<T> {
- private final List<T> forwardList;
-
- ReverseList(List<T> forwardList) {
- this.forwardList = checkNotNull(forwardList);
- }
-
- List<T> getForwardList() {
- return forwardList;
- }
-
- private int reverseIndex(int index) {
- int size = size();
- checkElementIndex(index, size);
- return (size - 1) - index;
- }
-
- private int reversePosition(int index) {
- int size = size();
- checkPositionIndex(index, size);
- return size - index;
- }
-
- @Override public void add(int index, @Nullable T element) {
- forwardList.add(reversePosition(index), element);
- }
-
- @Override public void clear() {
- forwardList.clear();
- }
-
- @Override public T remove(int index) {
- return forwardList.remove(reverseIndex(index));
- }
-
- @Override protected void removeRange(int fromIndex, int toIndex) {
- subList(fromIndex, toIndex).clear();
- }
-
- @Override public T set(int index, @Nullable T element) {
- return forwardList.set(reverseIndex(index), element);
- }
-
- @Override public T get(int index) {
- return forwardList.get(reverseIndex(index));
- }
-
- @Override public boolean isEmpty() {
- return forwardList.isEmpty();
- }
-
- @Override public int size() {
- return forwardList.size();
- }
-
- @Override public boolean contains(@Nullable Object o) {
- return forwardList.contains(o);
- }
-
- @Override public boolean containsAll(Collection<?> c) {
- return forwardList.containsAll(c);
- }
-
- @Override public List<T> subList(int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size());
- return reverse(forwardList.subList(
- reversePosition(toIndex), reversePosition(fromIndex)));
- }
-
- @Override public int indexOf(@Nullable Object o) {
- int index = forwardList.lastIndexOf(o);
- return (index >= 0) ? reverseIndex(index) : -1;
- }
-
- @Override public int lastIndexOf(@Nullable Object o) {
- int index = forwardList.indexOf(o);
- return (index >= 0) ? reverseIndex(index) : -1;
- }
-
- @Override public Iterator<T> iterator() {
- return listIterator();
- }
-
- @Override public ListIterator<T> listIterator(int index) {
- int start = reversePosition(index);
- final ListIterator<T> forwardIterator = forwardList.listIterator(start);
- return new ListIterator<T>() {
-
- boolean canRemove;
- boolean canSet;
-
- @Override public void add(T e) {
- forwardIterator.add(e);
- forwardIterator.previous();
- canSet = canRemove = false;
- }
-
- @Override public boolean hasNext() {
- return forwardIterator.hasPrevious();
- }
-
- @Override public boolean hasPrevious() {
- return forwardIterator.hasNext();
- }
-
- @Override public T next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- canSet = canRemove = true;
- return forwardIterator.previous();
- }
-
- @Override public int nextIndex() {
- return reversePosition(forwardIterator.nextIndex());
- }
-
- @Override public T previous() {
- if (!hasPrevious()) {
- throw new NoSuchElementException();
- }
- canSet = canRemove = true;
- return forwardIterator.next();
- }
-
- @Override public int previousIndex() {
- return nextIndex() - 1;
- }
-
- @Override public void remove() {
- checkState(canRemove);
- forwardIterator.remove();
- canRemove = canSet = false;
- }
-
- @Override public void set(T e) {
- checkState(canSet);
- forwardIterator.set(e);
- }
- };
- }
- }
-
- private static class RandomAccessReverseList<T> extends ReverseList<T>
- implements RandomAccess {
- RandomAccessReverseList(List<T> forwardList) {
- super(forwardList);
- }
- }
-
- /**
- * An implementation of {@link List#hashCode()}.
- */
- static int hashCodeImpl(List<?> list) {
- int hashCode = 1;
- for (Object o : list) {
- hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
-
- hashCode = ~~hashCode;
- // needed to deal with GWT integer overflow
- }
- return hashCode;
- }
-
- /**
- * An implementation of {@link List#equals(Object)}.
- */
- static boolean equalsImpl(List<?> list, @Nullable Object object) {
- if (object == checkNotNull(list)) {
- return true;
- }
- if (!(object instanceof List)) {
- return false;
- }
-
- List<?> o = (List<?>) object;
-
- return list.size() == o.size()
- && Iterators.elementsEqual(list.iterator(), o.iterator());
- }
-
- /**
- * An implementation of {@link List#addAll(int, Collection)}.
- */
- static <E> boolean addAllImpl(
- List<E> list, int index, Iterable<? extends E> elements) {
- boolean changed = false;
- ListIterator<E> listIterator = list.listIterator(index);
- for (E e : elements) {
- listIterator.add(e);
- changed = true;
- }
- return changed;
- }
-
- /**
- * An implementation of {@link List#indexOf(Object)}.
- */
- static int indexOfImpl(List<?> list, @Nullable Object element){
- ListIterator<?> listIterator = list.listIterator();
- while (listIterator.hasNext()) {
- if (Objects.equal(element, listIterator.next())) {
- return listIterator.previousIndex();
- }
- }
- return -1;
- }
-
- /**
- * An implementation of {@link List#lastIndexOf(Object)}.
- */
- static int lastIndexOfImpl(List<?> list, @Nullable Object element){
- ListIterator<?> listIterator = list.listIterator(list.size());
- while (listIterator.hasPrevious()) {
- if (Objects.equal(element, listIterator.previous())) {
- return listIterator.nextIndex();
- }
- }
- return -1;
- }
-
- /**
- * Returns an implementation of {@link List#listIterator(int)}.
- */
- static <E> ListIterator<E> listIteratorImpl(List<E> list, int index) {
- return new AbstractListWrapper<E>(list).listIterator(index);
- }
-
- /**
- * An implementation of {@link List#subList(int, int)}.
- */
- static <E> List<E> subListImpl(
- final List<E> list, int fromIndex, int toIndex) {
- List<E> wrapper;
- if (list instanceof RandomAccess) {
- wrapper = new RandomAccessListWrapper<E>(list) {
- @Override public ListIterator<E> listIterator(int index) {
- return backingList.listIterator(index);
- }
-
- private static final long serialVersionUID = 0;
- };
- } else {
- wrapper = new AbstractListWrapper<E>(list) {
- @Override public ListIterator<E> listIterator(int index) {
- return backingList.listIterator(index);
- }
-
- private static final long serialVersionUID = 0;
- };
- }
- return wrapper.subList(fromIndex, toIndex);
- }
-
- private static class AbstractListWrapper<E> extends AbstractList<E> {
- final List<E> backingList;
-
- AbstractListWrapper(List<E> backingList) {
- this.backingList = checkNotNull(backingList);
- }
-
- @Override public void add(int index, E element) {
- backingList.add(index, element);
- }
-
- @Override public boolean addAll(int index, Collection<? extends E> c) {
- return backingList.addAll(index, c);
- }
-
- @Override public E get(int index) {
- return backingList.get(index);
- }
-
- @Override public E remove(int index) {
- return backingList.remove(index);
- }
-
- @Override public E set(int index, E element) {
- return backingList.set(index, element);
- }
-
- @Override public boolean contains(Object o) {
- return backingList.contains(o);
- }
-
- @Override public int size() {
- return backingList.size();
- }
- }
-
- private static class RandomAccessListWrapper<E>
- extends AbstractListWrapper<E> implements RandomAccess {
- RandomAccessListWrapper(List<E> backingList) {
- super(backingList);
- }
- }
-
- /**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
- */
- static <T> List<T> cast(Iterable<T> iterable) {
- return (List<T>) iterable;
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/MapMaker.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/MapMaker.java
index 6f88f89..52c1a98 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/MapMaker.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/MapMaker.java
@@ -42,8 +42,8 @@ public class MapMaker extends GenericMapMaker<Object, Object> {
private final Function<? super K, ? extends V> computer;
private final int maximumSize;
- ExpiringComputingMap(
- long expirationMillis, int maximumSize, int initialCapacity, float loadFactor) {
+ ExpiringComputingMap(long expirationMillis, int maximumSize, int initialCapacity,
+ float loadFactor) {
this(expirationMillis, null, maximumSize, initialCapacity, loadFactor);
}
@@ -184,6 +184,12 @@ public class MapMaker extends GenericMapMaker<Object, Object> {
}
@Override
+ public
+ MapMaker expiration(long duration, TimeUnit unit) {
+ return expireAfterWrite(duration, unit);
+ }
+
+ @Override
MapMaker expireAfterWrite(long duration, TimeUnit unit) {
if (expirationMillis != 0) {
throw new IllegalStateException(
@@ -221,16 +227,26 @@ public class MapMaker extends GenericMapMaker<Object, Object> {
}
@Override
+ MapMaker strongKeys() {
+ return this;
+ }
+
+ @Override
+ MapMaker strongValues() {
+ return this;
+ }
+
+ @Override
public <K, V> ConcurrentMap<K, V> makeMap() {
return useCustomMap
- ? new ExpiringComputingMap<K, V>(
- expirationMillis, null, maximumSize, initialCapacity, loadFactor)
+ ? new ExpiringComputingMap<K, V>(expirationMillis, null, maximumSize, initialCapacity,
+ loadFactor)
: new ConcurrentHashMap<K, V>(initialCapacity, loadFactor);
}
@Override
public <K, V> ConcurrentMap<K, V> makeComputingMap(Function<? super K, ? extends V> computer) {
- return new ExpiringComputingMap<K, V>(
- expirationMillis, computer, maximumSize, initialCapacity, loadFactor);
+ return new ExpiringComputingMap<K, V>(expirationMillis, computer, maximumSize, initialCapacity,
+ loadFactor);
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Maps.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Maps.java
index fd6909d..78165de 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Maps.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Maps.java
@@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Function;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.base.Objects;
@@ -34,6 +35,7 @@ import com.google.common.primitives.Ints;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractMap;
+import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -46,20 +48,14 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
-import java.util.SortedSet;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nullable;
/**
- * Static utility methods pertaining to {@link Map} instances (including instances of
- * {@link SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts
- * {@link Lists}, {@link Sets} and {@link Queues}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Maps">
- * {@code Maps}</a>.
+ * Static utility methods pertaining to {@link Map} instances. Also see this
+ * class's counterparts {@link Lists} and {@link Sets}.
*
* @author Kevin Bourrillion
* @author Mike Bostock
@@ -71,60 +67,6 @@ import javax.annotation.Nullable;
public final class Maps {
private Maps() {}
- private enum EntryFunction implements Function<Entry, Object> {
- KEY {
- @Override
- @Nullable
- public Object apply(Entry entry) {
- return entry.getKey();
- }
- },
- VALUE {
- @Override
- @Nullable
- public Object apply(Entry entry) {
- return entry.getValue();
- }
- };
- }
-
- @SuppressWarnings("unchecked")
- static <K> Function<Entry<K, ?>, K> keyFunction() {
- return (Function) EntryFunction.KEY;
- }
-
- static <V> Function<Entry<?, V>, V> valueFunction() {
- return (Function) EntryFunction.VALUE;
- }
-
- /**
- * Returns an immutable map instance containing the given entries.
- * Internally, the returned set will be backed by an {@link EnumMap}.
- *
- * <p>The iteration order of the returned map follows the enum's iteration
- * order, not the order in which the elements appear in the given map.
- *
- * @param map the map to make an immutable copy of
- * @return an immutable map containing those entries
- * @since 14.0
- */
- @GwtCompatible(serializable = true)
- @Beta
- public static <K extends Enum<K>, V> ImmutableMap<K, V> immutableEnumMap(
- Map<K, V> map) {
- if (map instanceof ImmutableEnumMap) {
- return (ImmutableEnumMap<K, V>) map;
- } else if (map.isEmpty()) {
- return ImmutableMap.of();
- } else {
- for (Map.Entry<K, V> entry : map.entrySet()) {
- checkNotNull(entry.getKey());
- checkNotNull(entry.getValue());
- }
- return ImmutableEnumMap.asImmutable(new EnumMap<K, V>(map));
- }
- }
-
/**
* Creates a <i>mutable</i>, empty {@code HashMap} instance.
*
@@ -324,6 +266,38 @@ public final class Maps {
}
/**
+ * Returns a synchronized (thread-safe) bimap backed by the specified bimap.
+ * In order to guarantee serial access, it is critical that <b>all</b> access
+ * to the backing bimap is accomplished through the returned bimap.
+ *
+ * <p>It is imperative that the user manually synchronize on the returned map
+ * when accessing any of its collection views: <pre> {@code
+ *
+ * BiMap<Long, String> map = Maps.synchronizedBiMap(
+ * HashBiMap.<Long, String>create());
+ * ...
+ * Set<Long> set = map.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (map) { // Synchronizing on map, not set!
+ * Iterator<Long> it = set.iterator(); // Must be in synchronized block
+ * while (it.hasNext()) {
+ * foo(it.next());
+ * }
+ * }}</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>The returned bimap will be serializable if the specified bimap is
+ * serializable.
+ *
+ * @param bimap the bimap to be wrapped in a synchronized view
+ * @return a sychronized view of the specified bimap
+ */
+ public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
+ return Synchronized.biMap(bimap, null);
+ }
+
+ /**
* Computes the difference between two maps. This difference is an immutable
* snapshot of the state of the maps at the time this method is called. It
* will never change, even if the maps change at a later time.
@@ -347,7 +321,7 @@ public final class Maps {
SortedMapDifference<K, V> result = difference(sortedLeft, right);
return result;
}
- return difference(left, right, Equivalence.equals());
+ return difference(left, right, Equivalences.equals());
}
/**
@@ -519,7 +493,7 @@ public final class Maps {
}
@Override public boolean equals(@Nullable Object object) {
- if (object instanceof MapDifference.ValueDifference) {
+ if (object instanceof MapDifference.ValueDifference<?>) {
MapDifference.ValueDifference<?> that =
(MapDifference.ValueDifference<?>) object;
return Objects.equal(this.left, that.leftValue())
@@ -556,6 +530,7 @@ public final class Maps {
* @return the difference between the two maps
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMapDifference<K, V> difference(
SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
checkNotNull(left);
@@ -640,313 +615,6 @@ public final class Maps {
}
return (Comparator<E>) Ordering.natural();
}
-
- /**
- * Returns a view of the set as a map, mapping keys from the set according to
- * the specified function.
- *
- * <p>Specifically, for each {@code k} in the backing set, the returned map
- * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
- * keySet}, {@code values}, and {@code entrySet} views of the returned map
- * iterate in the same order as the backing set.
- *
- * <p>Modifications to the backing set are read through to the returned map.
- * The returned map supports removal operations if the backing set does.
- * Removal operations write through to the backing set. The returned map
- * does not support put operations.
- *
- * <p><b>Warning</b>: If the function rejects {@code null}, caution is
- * required to make sure the set does not contain {@code null}, because the
- * view cannot stop {@code null} from being added to the set.
- *
- * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
- * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also
- * of type {@code K}. Using a key type for which this may not hold, such as
- * {@code ArrayList}, may risk a {@code ClassCastException} when calling
- * methods on the resulting map view.
- *
- * @since 14.0
- */
- @Beta
- public static <K, V> Map<K, V> asMap(
- Set<K> set, Function<? super K, V> function) {
- if (set instanceof SortedSet) {
- return asMap((SortedSet<K>) set, function);
- } else {
- return new AsMapView<K, V>(set, function);
- }
- }
-
- /**
- * Returns a view of the sorted set as a map, mapping keys from the set
- * according to the specified function.
- *
- * <p>Specifically, for each {@code k} in the backing set, the returned map
- * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
- * keySet}, {@code values}, and {@code entrySet} views of the returned map
- * iterate in the same order as the backing set.
- *
- * <p>Modifications to the backing set are read through to the returned map.
- * The returned map supports removal operations if the backing set does.
- * Removal operations write through to the backing set. The returned map does
- * not support put operations.
- *
- * <p><b>Warning</b>: If the function rejects {@code null}, caution is
- * required to make sure the set does not contain {@code null}, because the
- * view cannot stop {@code null} from being added to the set.
- *
- * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
- * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
- * type {@code K}. Using a key type for which this may not hold, such as
- * {@code ArrayList}, may risk a {@code ClassCastException} when calling
- * methods on the resulting map view.
- *
- * @since 14.0
- */
- @Beta
- public static <K, V> SortedMap<K, V> asMap(
- SortedSet<K> set, Function<? super K, V> function) {
- return Platform.mapsAsMapSortedSet(set, function);
- }
-
- static <K, V> SortedMap<K, V> asMapSortedIgnoreNavigable(SortedSet<K> set,
- Function<? super K, V> function) {
- return new SortedAsMapView<K, V>(set, function);
- }
-
- private static class AsMapView<K, V> extends ImprovedAbstractMap<K, V> {
-
- private final Set<K> set;
- final Function<? super K, V> function;
-
- Set<K> backingSet() {
- return set;
- }
-
- AsMapView(Set<K> set, Function<? super K, V> function) {
- this.set = checkNotNull(set);
- this.function = checkNotNull(function);
- }
-
- @Override
- public Set<K> keySet() {
- // probably not worth caching
- return removeOnlySet(backingSet());
- }
-
- @Override
- public Collection<V> values() {
- // probably not worth caching
- return Collections2.transform(set, function);
- }
-
- @Override
- public int size() {
- return backingSet().size();
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return backingSet().contains(key);
- }
-
- @Override
- public V get(@Nullable Object key) {
- if (backingSet().contains(key)) {
- @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
- K k = (K) key;
- return function.apply(k);
- } else {
- return null;
- }
- }
-
- @Override
- public V remove(@Nullable Object key) {
- if (backingSet().remove(key)) {
- @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
- K k = (K) key;
- return function.apply(k);
- } else {
- return null;
- }
- }
-
- @Override
- public void clear() {
- backingSet().clear();
- }
-
- @Override
- protected Set<Entry<K, V>> createEntrySet() {
- return new EntrySet<K, V>() {
- @Override
- Map<K, V> map() {
- return AsMapView.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return asSetEntryIterator(backingSet(), function);
- }
- };
- }
- }
-
- private static <K, V> Iterator<Entry<K, V>> asSetEntryIterator(
- Set<K> set, final Function<? super K, V> function) {
- return new TransformedIterator<K, Entry<K,V>>(set.iterator()) {
- @Override
- Entry<K, V> transform(K key) {
- return Maps.immutableEntry(key, function.apply(key));
- }
- };
- }
-
- private static class SortedAsMapView<K, V> extends AsMapView<K, V>
- implements SortedMap<K, V> {
-
- SortedAsMapView(SortedSet<K> set, Function<? super K, V> function) {
- super(set, function);
- }
-
- @Override
- SortedSet<K> backingSet() {
- return (SortedSet<K>) super.backingSet();
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return backingSet().comparator();
- }
-
- @Override
- public Set<K> keySet() {
- return removeOnlySortedSet(backingSet());
- }
-
- @Override
- public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return asMap(backingSet().subSet(fromKey, toKey), function);
- }
-
- @Override
- public SortedMap<K, V> headMap(K toKey) {
- return asMap(backingSet().headSet(toKey), function);
- }
-
- @Override
- public SortedMap<K, V> tailMap(K fromKey) {
- return asMap(backingSet().tailSet(fromKey), function);
- }
-
- @Override
- public K firstKey() {
- return backingSet().first();
- }
-
- @Override
- public K lastKey() {
- return backingSet().last();
- }
- }
-
- private static <E> Set<E> removeOnlySet(final Set<E> set) {
- return new ForwardingSet<E>() {
- @Override
- protected Set<E> delegate() {
- return set;
- }
-
- @Override
- public boolean add(E element) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean addAll(Collection<? extends E> es) {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- private static <E> SortedSet<E> removeOnlySortedSet(final SortedSet<E> set) {
- return new ForwardingSortedSet<E>() {
- @Override
- protected SortedSet<E> delegate() {
- return set;
- }
-
- @Override
- public boolean add(E element) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean addAll(Collection<? extends E> es) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SortedSet<E> headSet(E toElement) {
- return removeOnlySortedSet(super.headSet(toElement));
- }
-
- @Override
- public SortedSet<E> subSet(E fromElement, E toElement) {
- return removeOnlySortedSet(super.subSet(fromElement, toElement));
- }
-
- @Override
- public SortedSet<E> tailSet(E fromElement) {
- return removeOnlySortedSet(super.tailSet(fromElement));
- }
- };
- }
-
- /**
- * Returns an immutable map for which the given {@code keys} are mapped to
- * values by the given function in the order they appear in the original
- * iterable. If {@code keys} contains duplicate elements, the returned map
- * will contain each distinct key once in the order it first appears in
- * {@code keys}.
- *
- * @throws NullPointerException if any element of {@code keys} is
- * {@code null}, or if {@code valueFunction} produces {@code null}
- * for any key
- * @since 14.0
- */
- @Beta
- public static <K, V> ImmutableMap<K, V> toMap(Iterable<K> keys,
- Function<? super K, V> valueFunction) {
- return toMap(keys.iterator(), valueFunction);
- }
-
- /**
- * Returns an immutable map for which the given {@code keys} are mapped to
- * values by the given function in the order they appear in the original
- * iterator. If {@code keys} contains duplicate elements, the returned map
- * will contain each distinct key once in the order it first appears in
- * {@code keys}.
- *
- * @throws NullPointerException if any element of {@code keys} is
- * {@code null}, or if {@code valueFunction} produces {@code null}
- * for any key
- * @since 14.0
- */
- @Beta
- public static <K, V> ImmutableMap<K, V> toMap(Iterator<K> keys,
- Function<? super K, V> valueFunction) {
- checkNotNull(valueFunction);
- // Using LHM instead of a builder so as not to fail on duplicate keys
- Map<K, V> builder = newLinkedHashMap();
- while (keys.hasNext()) {
- K key = keys.next();
- builder.put(key, valueFunction.apply(key));
- }
- return ImmutableMap.copyOf(builder);
- }
-
/**
* Returns an immutable map for which the {@link Map#values} are the given
* elements in the given order, and each key is the product of invoking a
@@ -967,6 +635,24 @@ public final class Maps {
}
/**
+ * <b>Deprecated.</b>
+ *
+ * @since 10.0
+ * @deprecated use {@link #uniqueIndex(Iterator, Function)} by casting {@code
+ * values} to {@code Iterator<V>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled
+ * for deletion in March 2012.</b>
+ */
+ @Beta
+ @Deprecated
+ public static <K, V, I extends Object & Iterable<V> & Iterator<V>>
+ ImmutableMap<K, V> uniqueIndex(
+ I values, Function<? super V, K> keyFunction) {
+ Iterable<V> valuesIterable = checkNotNull(values);
+ return uniqueIndex(valuesIterable, keyFunction);
+ }
+
+ /**
* Returns an immutable map for which the {@link Map#values} are the given
* elements in the given order, and each key is the product of invoking a
* supplied function on its corresponding value.
@@ -1128,38 +814,6 @@ public final class Maps {
}
/**
- * Returns a synchronized (thread-safe) bimap backed by the specified bimap.
- * In order to guarantee serial access, it is critical that <b>all</b> access
- * to the backing bimap is accomplished through the returned bimap.
- *
- * <p>It is imperative that the user manually synchronize on the returned map
- * when accessing any of its collection views: <pre> {@code
- *
- * BiMap<Long, String> map = Maps.synchronizedBiMap(
- * HashBiMap.<Long, String>create());
- * ...
- * Set<Long> set = map.keySet(); // Needn't be in synchronized block
- * ...
- * synchronized (map) { // Synchronizing on map, not set!
- * Iterator<Long> it = set.iterator(); // Must be in synchronized block
- * while (it.hasNext()) {
- * foo(it.next());
- * }
- * }}</pre>
- *
- * Failure to follow this advice may result in non-deterministic behavior.
- *
- * <p>The returned bimap will be serializable if the specified bimap is
- * serializable.
- *
- * @param bimap the bimap to be wrapped in a synchronized view
- * @return a sychronized view of the specified bimap
- */
- public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
- return Synchronized.biMap(bimap, null);
- }
-
- /**
* Returns an unmodifiable view of the specified bimap. This method allows
* modules to provide users with "read-only" access to internal bimaps. Query
* operations on the returned bimap "read through" to the specified bimap, and
@@ -1182,7 +836,7 @@ public final class Maps {
extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable {
final Map<K, V> unmodifiableMap;
final BiMap<? extends K, ? extends V> delegate;
- BiMap<V, K> inverse;
+ transient BiMap<V, K> inverse;
transient Set<V> values;
UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate,
@@ -1256,8 +910,16 @@ public final class Maps {
* a view, copy the returned map into a new map of your choosing.
*/
public static <K, V1, V2> Map<K, V2> transformValues(
- Map<K, V1> fromMap, Function<? super V1, V2> function) {
- return transformEntries(fromMap, asEntryTransformer(function));
+ Map<K, V1> fromMap, final Function<? super V1, V2> function) {
+ checkNotNull(function);
+ EntryTransformer<K, V1, V2> transformer =
+ new EntryTransformer<K, V1, V2>() {
+ @Override
+ public V2 transformEntry(K key, V1 value) {
+ return function.apply(value);
+ }
+ };
+ return transformEntries(fromMap, transformer);
}
/**
@@ -1299,20 +961,18 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V1, V2> SortedMap<K, V2> transformValues(
- SortedMap<K, V1> fromMap, Function<? super V1, V2> function) {
- return transformEntries(fromMap, asEntryTransformer(function));
- }
-
- private static <K, V1, V2> EntryTransformer<K, V1, V2>
- asEntryTransformer(final Function<? super V1, V2> function) {
+ SortedMap<K, V1> fromMap, final Function<? super V1, V2> function) {
checkNotNull(function);
- return new EntryTransformer<K, V1, V2>() {
- @Override
- public V2 transformEntry(K key, V1 value) {
- return function.apply(value);
- }
- };
+ EntryTransformer<K, V1, V2> transformer =
+ new EntryTransformer<K, V1, V2>() {
+ @Override
+ public V2 transformEntry(K key, V1 value) {
+ return function.apply(value);
+ }
+ };
+ return transformEntries(fromMap, transformer);
}
/**
@@ -1427,14 +1087,9 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V1, V2> SortedMap<K, V2> transformEntries(
- SortedMap<K, V1> fromMap,
- EntryTransformer<? super K, ? super V1, V2> transformer) {
- return Platform.mapsTransformEntriesSortedMap(fromMap, transformer);
- }
-
- static <K, V1, V2> SortedMap<K, V2> transformEntriesIgnoreNavigable(
- SortedMap<K, V1> fromMap,
+ final SortedMap<K, V1> fromMap,
EntryTransformer<? super K, ? super V1, V2> transformer) {
return new TransformedEntriesSortedMap<K, V1, V2>(fromMap, transformer);
}
@@ -1526,23 +1181,17 @@ public final class Maps {
}
@Override public Iterator<Entry<K, V2>> iterator() {
- return new TransformedIterator<Entry<K, V1>, Entry<K, V2>>(
- fromMap.entrySet().iterator()) {
- @Override
- Entry<K, V2> transform(final Entry<K, V1> entry) {
- return new AbstractMapEntry<K, V2>() {
- @Override
- public K getKey() {
- return entry.getKey();
+ final Iterator<Entry<K, V1>> backingIterator =
+ fromMap.entrySet().iterator();
+ return Iterators.transform(backingIterator,
+ new Function<Entry<K, V1>, Entry<K, V2>>() {
+ @Override public Entry<K, V2> apply(Entry<K, V1> entry) {
+ return immutableEntry(
+ entry.getKey(),
+ transformer.transformEntry(entry.getKey(),
+ entry.getValue()));
}
-
- @Override
- public V2 getValue() {
- return transformer.transformEntry(entry.getKey(), entry.getValue());
- }
- };
- }
- };
+ });
}
};
}
@@ -1600,32 +1249,7 @@ public final class Maps {
@Override public SortedMap<K, V2> tailMap(K fromKey) {
return transformEntries(fromMap().tailMap(fromKey), transformer);
}
- }
-
- private static final class KeyPredicate<K, V> implements Predicate<Entry<K, V>> {
- private final Predicate<? super K> keyPredicate;
-
- KeyPredicate(Predicate<? super K> keyPredicate) {
- this.keyPredicate = checkNotNull(keyPredicate);
- }
- @Override
- public boolean apply(Entry<K, V> input) {
- return keyPredicate.apply(input.getKey());
- }
- }
-
- private static final class ValuePredicate<K, V> implements Predicate<Entry<K, V>> {
- private final Predicate<? super V> valuePredicate;
-
- ValuePredicate(Predicate<? super V> valuePredicate) {
- this.valuePredicate = checkNotNull(valuePredicate);
- }
-
- @Override
- public boolean apply(Entry<K, V> input) {
- return valuePredicate.apply(input.getValue());
- }
}
/**
@@ -1660,11 +1284,15 @@ public final class Maps {
Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
if (unfiltered instanceof SortedMap) {
return filterKeys((SortedMap<K, V>) unfiltered, keyPredicate);
- } else if (unfiltered instanceof BiMap) {
- return filterKeys((BiMap<K, V>) unfiltered, keyPredicate);
}
checkNotNull(keyPredicate);
- Predicate<Entry<K, V>> entryPredicate = new KeyPredicate<K, V>(keyPredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return keyPredicate.apply(input.getKey());
+ }
+ };
return (unfiltered instanceof AbstractFilteredMap)
? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
: new FilteredKeyMap<K, V>(
@@ -1701,42 +1329,19 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMap<K, V> filterKeys(
SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
- // TODO(user): Return a subclass of Maps.FilteredKeyMap for slightly better
+ // TODO: Return a subclass of Maps.FilteredKeyMap for slightly better
// performance.
- return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate));
- }
-
- /**
- * Returns a bimap containing the mappings in {@code unfiltered} whose keys satisfy a predicate.
- * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
- *
- * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
- * iterators that don't support {@code remove()}, but all other methods are supported by the
- * bimap and its views. When given a key that doesn't satisfy the predicate, the bimap's {@code
- * put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
- * IllegalArgumentException}.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
- * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
- * bimap.
- *
- * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
- *
- * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key in
- * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
- * needed, it may be faster to copy the filtered bimap and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as
- * documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- public static <K, V> BiMap<K, V> filterKeys(
- BiMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
checkNotNull(keyPredicate);
- return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate));
+ Predicate<Entry<K, V>> entryPredicate = new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return keyPredicate.apply(input.getKey());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -1772,10 +1377,16 @@ public final class Maps {
Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
if (unfiltered instanceof SortedMap) {
return filterValues((SortedMap<K, V>) unfiltered, valuePredicate);
- } else if (unfiltered instanceof BiMap) {
- return filterValues((BiMap<K, V>) unfiltered, valuePredicate);
}
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
+ checkNotNull(valuePredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return valuePredicate.apply(input.getValue());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -1809,42 +1420,18 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMap<K, V> filterValues(
SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
- }
-
- /**
- * Returns a bimap containing the mappings in {@code unfiltered} whose values satisfy a
- * predicate. The returned bimap is a live view of {@code unfiltered}; changes to one affect the
- * other.
- *
- * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
- * iterators that don't support {@code remove()}, but all other methods are supported by the
- * bimap and its views. When given a value that doesn't satisfy the predicate, the bimap's
- * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
- * IllegalArgumentException}. Similarly, the map's entries have a {@link Entry#setValue} method
- * that throws an {@link IllegalArgumentException} when the provided value doesn't satisfy the
- * predicate.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
- * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
- * bimap.
- *
- * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
- *
- * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every value in
- * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
- * needed, it may be faster to copy the filtered bimap and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as
- * documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- public static <K, V> BiMap<K, V> filterValues(
- BiMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
+ checkNotNull(valuePredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return valuePredicate.apply(input.getValue());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -1880,8 +1467,6 @@ public final class Maps {
Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
if (unfiltered instanceof SortedMap) {
return filterEntries((SortedMap<K, V>) unfiltered, entryPredicate);
- } else if (unfiltered instanceof BiMap) {
- return filterEntries((BiMap<K, V>) unfiltered, entryPredicate);
}
checkNotNull(entryPredicate);
return (unfiltered instanceof AbstractFilteredMap)
@@ -1920,15 +1505,10 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMap<K, V> filterEntries(
SortedMap<K, V> unfiltered,
Predicate<? super Entry<K, V>> entryPredicate) {
- return Platform.mapsFilterSortedMap(unfiltered, entryPredicate);
- }
-
- static <K, V> SortedMap<K, V> filterSortedIgnoreNavigable(
- SortedMap<K, V> unfiltered,
- Predicate<? super Entry<K, V>> entryPredicate) {
checkNotNull(entryPredicate);
return (unfiltered instanceof FilteredEntrySortedMap)
? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate)
@@ -1936,42 +1516,6 @@ public final class Maps {
}
/**
- * Returns a bimap containing the mappings in {@code unfiltered} that satisfy a predicate. The
- * returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
- *
- * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
- * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
- * and its views. When given a key/value pair that doesn't satisfy the predicate, the bimap's
- * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an
- * {@link IllegalArgumentException}. Similarly, the map's entries have an {@link Entry#setValue}
- * method that throws an {@link IllegalArgumentException} when the existing key and the provided
- * value don't satisfy the predicate.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
- * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
- * bimap.
- *
- * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
- *
- * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every
- * key/value mapping in the underlying bimap and determine which satisfy the filter. When a live
- * view is <i>not</i> needed, it may be faster to copy the filtered bimap and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as
- * documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- public static <K, V> BiMap<K, V> filterEntries(
- BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
- checkNotNull(unfiltered);
- checkNotNull(entryPredicate);
- return (unfiltered instanceof FilteredEntryBiMap)
- ? filterFiltered((FilteredEntryBiMap<K, V>) unfiltered, entryPredicate)
- : new FilteredEntryBiMap<K, V>(unfiltered, entryPredicate);
- }
-
- /**
* Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
* filtering a filtered map.
*/
@@ -2116,7 +1660,6 @@ public final class Maps {
}
}
}
-
/**
* Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
* filtering a filtered sorted map.
@@ -2177,66 +1720,6 @@ public final class Maps {
}
}
- /**
- * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
- * filtering a filtered map.
- */
- private static <K, V> BiMap<K, V> filterFiltered(
- FilteredEntryBiMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
- Predicate<Entry<K, V>> predicate = Predicates.and(map.predicate, entryPredicate);
- return new FilteredEntryBiMap<K, V>(map.unfiltered(), predicate);
- }
-
- static final class FilteredEntryBiMap<K, V> extends FilteredEntryMap<K, V>
- implements BiMap<K, V> {
- private final BiMap<V, K> inverse;
-
- private static <K, V> Predicate<Entry<V, K>> inversePredicate(
- final Predicate<? super Entry<K, V>> forwardPredicate) {
- return new Predicate<Entry<V, K>>() {
- @Override
- public boolean apply(Entry<V, K> input) {
- return forwardPredicate.apply(
- Maps.immutableEntry(input.getValue(), input.getKey()));
- }
- };
- }
-
- FilteredEntryBiMap(BiMap<K, V> delegate,
- Predicate<? super Entry<K, V>> predicate) {
- super(delegate, predicate);
- this.inverse = new FilteredEntryBiMap<V, K>(
- delegate.inverse(), inversePredicate(predicate), this);
- }
-
- private FilteredEntryBiMap(
- BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate,
- BiMap<V, K> inverse) {
- super(delegate, predicate);
- this.inverse = inverse;
- }
-
- BiMap<K, V> unfiltered() {
- return (BiMap<K, V>) unfiltered;
- }
-
- @Override
- public V forcePut(@Nullable K key, @Nullable V value) {
- checkArgument(predicate.apply(Maps.immutableEntry(key, value)));
- return unfiltered().forcePut(key, value);
- }
-
- @Override
- public BiMap<V, K> inverse() {
- return inverse;
- }
-
- @Override
- public Set<V> values() {
- return inverse.keySet();
- }
- }
-
private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> {
Predicate<? super K> keyPredicate;
@@ -2328,14 +1811,10 @@ public final class Maps {
@Override public Set<K> keySet() {
Set<K> result = keySet;
- return (result == null) ? keySet = createKeySet() : result;
- }
-
- Set<K> createKeySet() {
- return new KeySet();
+ return (result == null) ? keySet = new KeySet() : result;
}
- private class KeySet extends Sets.ImprovedAbstractSet<K> {
+ private class KeySet extends AbstractSet<K> {
@Override public Iterator<K> iterator() {
final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator();
return new UnmodifiableIterator<K>() {
@@ -2371,13 +1850,22 @@ public final class Maps {
return false;
}
+ @Override public boolean removeAll(Collection<?> collection) {
+ checkNotNull(collection); // for GWT
+ boolean changed = false;
+ for (Object obj : collection) {
+ changed |= remove(obj);
+ }
+ return changed;
+ }
+
@Override public boolean retainAll(Collection<?> collection) {
checkNotNull(collection); // for GWT
boolean changed = false;
Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator();
while (iterator.hasNext()) {
Entry<K, V> entry = iterator.next();
- if (predicate.apply(entry) && !collection.contains(entry.getKey())) {
+ if (!collection.contains(entry.getKey()) && predicate.apply(entry)) {
iterator.remove();
changed = true;
}
@@ -2396,10 +1884,6 @@ public final class Maps {
}
}
- @Nullable private static <K, V> Entry<K, V> unmodifiableOrNull(@Nullable Entry<K, V> entry) {
- return (entry == null) ? null : Maps.unmodifiableEntry(entry);
- }
-
/**
* {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code
* entrySet().isEmpty()} instead of {@code size() == 0} to speed up
@@ -2408,7 +1892,7 @@ public final class Maps {
* implementation.
*/
@GwtCompatible
- abstract static class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> {
+ static abstract class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> {
/**
* Creates the entry set to be returned by {@link #entrySet()}. This method
* is invoked at most once on a given map, at the time when {@code entrySet}
@@ -2445,7 +1929,7 @@ public final class Maps {
@Override public Collection<V> values() {
Collection<V> result = values;
if (result == null) {
- return values = new Values<K, V>() {
+ return values = new Values<K, V>(){
@Override Map<K, V> map() {
return ImprovedAbstractMap.this;
}
@@ -2453,6 +1937,17 @@ public final class Maps {
}
return result;
}
+
+ /**
+ * Returns {@code true} if this map contains no key-value mappings.
+ *
+ * <p>The implementation returns {@code entrySet().isEmpty()}.
+ *
+ * @return {@code true} if this map contains no key-value mappings
+ */
+ @Override public boolean isEmpty() {
+ return entrySet().isEmpty();
+ }
}
static final MapJoiner STANDARD_JOINER =
@@ -2460,46 +1955,25 @@ public final class Maps {
/**
* Delegates to {@link Map#get}. Returns {@code null} on {@code
- * ClassCastException} and {@code NullPointerException}.
+ * ClassCastException}.
*/
static <V> V safeGet(Map<?, V> map, Object key) {
- checkNotNull(map);
try {
return map.get(key);
} catch (ClassCastException e) {
return null;
- } catch (NullPointerException e) {
- return null;
}
}
/**
* Delegates to {@link Map#containsKey}. Returns {@code false} on {@code
- * ClassCastException} and {@code NullPointerException}.
+ * ClassCastException}
*/
static boolean safeContainsKey(Map<?, ?> map, Object key) {
- checkNotNull(map);
try {
return map.containsKey(key);
} catch (ClassCastException e) {
return false;
- } catch (NullPointerException e) {
- return false;
- }
- }
-
- /**
- * Delegates to {@link Map#remove}. Returns {@code null} on {@code
- * ClassCastException} and {@code NullPointerException}.
- */
- static <V> V safeRemove(Map<?, V> map, Object key) {
- checkNotNull(map);
- try {
- return map.remove(key);
- } catch (ClassCastException e) {
- return null;
- } catch (NullPointerException e) {
- return null;
}
}
@@ -2558,6 +2032,13 @@ public final class Maps {
}
/**
+ * An implementation of {@link Map#hashCode}.
+ */
+ static int hashCodeImpl(Map<?, ?> map) {
+ return Sets.hashCodeImpl(map.entrySet());
+ }
+
+ /**
* An implementation of {@link Map#toString}.
*/
static String toStringImpl(Map<?, ?> map) {
@@ -2581,30 +2062,36 @@ public final class Maps {
* An admittedly inefficient implementation of {@link Map#containsKey}.
*/
static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) {
- return Iterators.contains(keyIterator(map.entrySet().iterator()), key);
+ for (Entry<?, ?> entry : map.entrySet()) {
+ if (Objects.equal(entry.getKey(), key)) {
+ return true;
+ }
+ }
+ return false;
}
/**
* An implementation of {@link Map#containsValue}.
*/
static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) {
- return Iterators.contains(valueIterator(map.entrySet().iterator()), value);
- }
-
- static <K, V> Iterator<K> keyIterator(Iterator<Entry<K, V>> entryIterator) {
- return new TransformedIterator<Entry<K, V>, K>(entryIterator) {
- @Override
- K transform(Entry<K, V> entry) {
- return entry.getKey();
+ for (Entry<?, ?> entry : map.entrySet()) {
+ if (Objects.equal(entry.getValue(), value)) {
+ return true;
}
- };
+ }
+ return false;
}
- abstract static class KeySet<K, V> extends Sets.ImprovedAbstractSet<K> {
+ abstract static class KeySet<K, V> extends AbstractSet<K> {
abstract Map<K, V> map();
@Override public Iterator<K> iterator() {
- return keyIterator(map().entrySet().iterator());
+ return Iterators.transform(map().entrySet().iterator(),
+ new Function<Map.Entry<K, V>, K>() {
+ @Override public K apply(Entry<K, V> entry) {
+ return entry.getKey();
+ }
+ });
}
@Override public int size() {
@@ -2627,50 +2114,27 @@ public final class Maps {
return false;
}
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ // TODO(user): find out why this is necessary to make GWT tests pass.
+ return super.removeAll(checkNotNull(c));
+ }
+
@Override public void clear() {
map().clear();
}
}
- @Nullable
- static <K> K keyOrNull(@Nullable Entry<K, ?> entry) {
- return (entry == null) ? null : entry.getKey();
- }
-
- @Nullable
- static <V> V valueOrNull(@Nullable Entry<?, V> entry) {
- return (entry == null) ? null : entry.getValue();
- }
-
- static <K, V> Iterator<V> valueIterator(Iterator<Entry<K, V>> entryIterator) {
- return new TransformedIterator<Entry<K, V>, V>(entryIterator) {
- @Override
- V transform(Entry<K, V> entry) {
- return entry.getValue();
- }
- };
- }
-
- static <K, V> UnmodifiableIterator<V> valueIterator(
- final UnmodifiableIterator<Entry<K, V>> entryIterator) {
- return new UnmodifiableIterator<V>() {
- @Override
- public boolean hasNext() {
- return entryIterator.hasNext();
- }
-
- @Override
- public V next() {
- return entryIterator.next().getValue();
- }
- };
- }
-
abstract static class Values<K, V> extends AbstractCollection<V> {
abstract Map<K, V> map();
@Override public Iterator<V> iterator() {
- return valueIterator(map().entrySet().iterator());
+ return Iterators.transform(map().entrySet().iterator(),
+ new Function<Entry<K, V>, V>() {
+ @Override public V apply(Entry<K, V> entry) {
+ return entry.getValue();
+ }
+ });
}
@Override public boolean remove(Object o) {
@@ -2732,8 +2196,7 @@ public final class Maps {
}
}
- abstract static class EntrySet<K, V>
- extends Sets.ImprovedAbstractSet<Entry<K, V>> {
+ abstract static class EntrySet<K, V> extends AbstractSet<Entry<K, V>> {
abstract Map<K, V> map();
@Override public int size() {
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Multimaps.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Multimaps.java
index c2d630f..7e8e2f7 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Multimaps.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Multimaps.java
@@ -20,17 +20,21 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
+import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
+import com.google.common.collect.Collections2.TransformedCollection;
import com.google.common.collect.Maps.EntryTransformer;
import java.io.Serializable;
import java.util.AbstractCollection;
+import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -48,10 +52,6 @@ import javax.annotation.Nullable;
/**
* Provides static methods acting on or generating a {@code Multimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multimaps">
- * {@code Multimaps}</a>.
- *
* @author Jared Levy
* @author Robert Konigsberg
* @author Mike Bostock
@@ -63,14 +63,9 @@ public final class Multimaps {
private Multimaps() {}
/**
- * Creates a new {@code Multimap} backed by {@code map}, whose internal value
- * collections are generated by {@code factory}.
- *
- * <b>Warning: do not use</b> this method when the collections returned by
- * {@code factory} implement either {@link List} or {@code Set}! Use the more
- * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link
- * #newSortedSetMultimap} instead, to avoid very surprising behavior from
- * {@link Multimap#equals}.
+ * Creates a new {@code Multimap} that uses the provided map and factory. It
+ * can generate a multimap based on arbitrary {@link Map} and
+ * {@link Collection} classes.
*
* <p>The {@code factory}-generated and {@code map} classes determine the
* multimap iteration order. They also specify the behavior of the
@@ -110,7 +105,7 @@ public final class Multimaps {
return new CustomMultimap<K, V>(map, factory);
}
- private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
+ private static class CustomMultimap<K, V> extends AbstractMultimap<K, V> {
transient Supplier<? extends Collection<V>> factory;
CustomMultimap(Map<K, Collection<V>> map,
@@ -334,13 +329,13 @@ public final class Multimaps {
* <p>It is imperative that the user manually synchronize on the returned
* multimap when accessing any of its collection views: <pre> {@code
*
- * Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
+ * Multimap<K, V> m = Multimaps.synchronizedMultimap(
* HashMultimap.<K, V>create());
* ...
- * Collection<V> values = multimap.get(key); // Needn't be in synchronized block
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
* ...
- * synchronized (multimap) { // Synchronizing on multimap, not values!
- * Iterator<V> i = values.iterator(); // Must be in synchronized block
+ * synchronized (m) { // Synchronizing on m, not s!
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
* while (i.hasNext()) {
* foo(i.next());
* }
@@ -541,7 +536,7 @@ public final class Multimaps {
}
@Override public Iterator<Collection<V>> iterator() {
final Iterator<Collection<V>> iterator = delegate.iterator();
- return new UnmodifiableIterator<Collection<V>>() {
+ return new Iterator<Collection<V>>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
@@ -550,6 +545,10 @@ public final class Multimaps {
public Collection<V> next() {
return unmodifiableValueCollection(iterator.next());
}
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
};
}
@Override public Object[] toArray() {
@@ -972,7 +971,7 @@ public final class Multimaps {
@Override
public Set<V> get(final K key) {
- return new Sets.ImprovedAbstractSet<V>() {
+ return new AbstractSet<V>() {
@Override public Iterator<V> iterator() {
return new Iterator<V>() {
int i;
@@ -1053,7 +1052,7 @@ public final class Multimaps {
@Override
public Multiset<K> keys() {
- return new Multimaps.Keys<K, V>(this);
+ return Multisets.forSet(map.keySet());
}
@Override
@@ -1104,27 +1103,35 @@ public final class Multimaps {
}
/** @see MapMultimap#asMap */
- class AsMapEntries extends Sets.ImprovedAbstractSet<Entry<K, Collection<V>>> {
+ class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
@Override public int size() {
return map.size();
}
@Override public Iterator<Entry<K, Collection<V>>> iterator() {
- return new TransformedIterator<K, Entry<K, Collection<V>>>(map.keySet().iterator()) {
+ return new Iterator<Entry<K, Collection<V>>>() {
+ final Iterator<K> keys = map.keySet().iterator();
+
@Override
- Entry<K, Collection<V>> transform(final K key) {
+ public boolean hasNext() {
+ return keys.hasNext();
+ }
+ @Override
+ public Entry<K, Collection<V>> next() {
+ final K key = keys.next();
return new AbstractMapEntry<K, Collection<V>>() {
- @Override
- public K getKey() {
+ @Override public K getKey() {
return key;
}
-
- @Override
- public Collection<V> getValue() {
+ @Override public Collection<V> getValue() {
return get(key);
}
};
}
+ @Override
+ public void remove() {
+ keys.remove();
+ }
};
}
@@ -1226,6 +1233,7 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> Multimap<K, V2> transformValues(
Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
checkNotNull(function);
@@ -1294,29 +1302,15 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> Multimap<K, V2> transformEntries(
Multimap<K, V1> fromMap,
EntryTransformer<? super K, ? super V1, V2> transformer) {
return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer);
}
-
- static final class ValueFunction<K, V1, V2> implements Function<V1, V2> {
- private final K key;
- private final EntryTransformer<? super K, ? super V1, V2> transformer;
-
- ValueFunction(K key, EntryTransformer<? super K, ? super V1, V2> transformer) {
- this.key = key;
- this.transformer = transformer;
- }
-
- @Override
- public V2 apply(@Nullable V1 value) {
- return transformer.transformEntry(key, value);
- }
- }
private static class TransformedEntriesMultimap<K, V1, V2>
- extends AbstractMultimap<K, V2> {
+ implements Multimap<K, V2> {
final Multimap<K, V1> fromMultimap;
final EntryTransformer<? super K, ? super V1, V2> transformer;
@@ -1326,25 +1320,30 @@ public final class Multimaps {
this.transformer = checkNotNull(transformer);
}
- Collection<V2> transform(K key, Collection<V1> values) {
- Function<V1, V2> function = new ValueFunction<K, V1, V2>(key, transformer);
- if (values instanceof List) {
- return Lists.transform((List<V1>) values, function);
- } else {
- return Collections2.transform(values, function);
- }
+ Collection<V2> transform(final K key, Collection<V1> values) {
+ return Collections2.transform(values, new Function<V1, V2>() {
+ @Override public V2 apply(V1 value) {
+ return transformer.transformEntry(key, value);
+ }
+ });
}
- @Override
- Map<K, Collection<V2>> createAsMap() {
- return Maps.transformEntries(fromMultimap.asMap(),
- new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
+ private transient Map<K, Collection<V2>> asMap;
- @Override public Collection<V2> transformEntry(
- K key, Collection<V1> value) {
- return transform(key, value);
- }
- });
+ @Override public Map<K, Collection<V2>> asMap() {
+ if (asMap == null) {
+ Map<K, Collection<V2>> aM = Maps.transformEntries(fromMultimap.asMap(),
+ new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
+
+ @Override public Collection<V2> transformEntry(
+ K key, Collection<V1> value) {
+ return transform(key, value);
+ }
+ });
+ asMap = aM;
+ return aM;
+ }
+ return asMap;
}
@Override public void clear() {
@@ -1365,25 +1364,58 @@ public final class Multimaps {
return values().contains(value);
}
- @Override
- Iterator<Entry<K, V2>> entryIterator() {
- return Iterators.transform(
- fromMultimap.entries().iterator(), new Function<Entry<K, V1>, Entry<K, V2>>() {
- @Override
- public Entry<K, V2> apply(final Entry<K, V1> entry) {
- return new AbstractMapEntry<K, V2>() {
- @Override
- public K getKey() {
- return entry.getKey();
- }
+ private transient Collection<Entry<K, V2>> entries;
+
+ @Override public Collection<Entry<K, V2>> entries() {
+ if (entries == null) {
+ Collection<Entry<K, V2>> es = new TransformedEntries(transformer);
+ entries = es;
+ return es;
+ }
+ return entries;
+ }
+
+ private class TransformedEntries
+ extends TransformedCollection<Entry<K, V1>, Entry<K, V2>> {
+
+ TransformedEntries(
+ final EntryTransformer<? super K, ? super V1, V2> transformer) {
+ super(fromMultimap.entries(),
+ new Function<Entry<K, V1>, Entry<K, V2>>() {
+ @Override public Entry<K, V2> apply(final Entry<K, V1> entry) {
+ return new AbstractMapEntry<K, V2>() {
+
+ @Override public K getKey() {
+ return entry.getKey();
+ }
+
+ @Override public V2 getValue() {
+ return transformer.transformEntry(
+ entry.getKey(), entry.getValue());
+ }
+ };
+ }
+ });
+ }
+
+ @Override public boolean contains(Object o) {
+ if (o instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ return containsEntry(entry.getKey(), entry.getValue());
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override public boolean remove(Object o) {
+ if (o instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ Collection<V2> values = get((K) entry.getKey());
+ return values.remove(entry.getValue());
+ }
+ return false;
+ }
- @Override
- public V2 getValue() {
- return transformer.transformEntry(entry.getKey(), entry.getValue());
- }
- };
- }
- });
}
@Override public Collection<V2> get(final K key) {
@@ -1433,16 +1465,39 @@ public final class Multimaps {
@Override public int size() {
return fromMultimap.size();
}
-
- @Override
- Collection<V2> createValues() {
- return Collections2.transform(
- fromMultimap.entries(), new Function<Entry<K, V1>, V2>() {
- @Override public V2 apply(Entry<K, V1> entry) {
- return transformer.transformEntry(
- entry.getKey(), entry.getValue());
- }
- });
+
+ private transient Collection<V2> values;
+
+ @Override public Collection<V2> values() {
+ if (values == null) {
+ Collection<V2> vs = Collections2.transform(
+ fromMultimap.entries(), new Function<Entry<K, V1>, V2>() {
+
+ @Override public V2 apply(Entry<K, V1> entry) {
+ return transformer.transformEntry(
+ entry.getKey(), entry.getValue());
+ }
+ });
+ values = vs;
+ return vs;
+ }
+ return values;
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof Multimap) {
+ Multimap<?, ?> other = (Multimap<?, ?>) obj;
+ return asMap().equals(other.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return asMap().hashCode();
+ }
+
+ @Override public String toString() {
+ return asMap().toString();
}
}
@@ -1487,6 +1542,7 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> ListMultimap<K, V2> transformValues(
ListMultimap<K, V1> fromMultimap,
final Function<? super V1, V2> function) {
@@ -1553,6 +1609,7 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
ListMultimap<K, V1> fromMap,
EntryTransformer<? super K, ? super V1, V2> transformer) {
@@ -1639,6 +1696,24 @@ public final class Multimaps {
}
/**
+ * <b>Deprecated.</b>
+ *
+ * @since 10.0
+ * @deprecated use {@link #index(Iterator, Function)} by casting {@code
+ * values} to {@code Iterator<V>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled
+ * for deletion in March 2012.</b>
+ */
+ @Beta
+ @Deprecated
+ public static <K, V, I extends Object & Iterable<V> & Iterator<V>>
+ ImmutableListMultimap<K, V> index(
+ I values, Function<? super V, K> keyFunction) {
+ Iterable<V> valuesIterable = checkNotNull(values);
+ return index(valuesIterable, keyFunction);
+ }
+
+ /**
* Creates an index {@code ImmutableListMultimap} that contains the results of
* applying a specified function to each item in an {@code Iterator} of
* values. Each value will be stored as a value in the resulting multimap,
@@ -1694,36 +1769,39 @@ public final class Multimaps {
return builder.build();
}
- static class Keys<K, V> extends AbstractMultiset<K> {
- final Multimap<K, V> multimap;
-
- Keys(Multimap<K, V> multimap) {
- this.multimap = multimap;
- }
+ static abstract class Keys<K, V> extends AbstractMultiset<K> {
+ abstract Multimap<K, V> multimap();
@Override Iterator<Multiset.Entry<K>> entryIterator() {
- return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>(
- multimap.asMap().entrySet().iterator()) {
- @Override
- Multiset.Entry<K> transform(
- final Map.Entry<K, Collection<V>> backingEntry) {
+ final Iterator<Map.Entry<K, Collection<V>>> backingIterator =
+ multimap().asMap().entrySet().iterator();
+ return new Iterator<Multiset.Entry<K>>() {
+ @Override public boolean hasNext() {
+ return backingIterator.hasNext();
+ }
+
+ @Override public Multiset.Entry<K> next() {
+ final Map.Entry<K, Collection<V>> backingEntry =
+ backingIterator.next();
return new Multisets.AbstractEntry<K>() {
- @Override
- public K getElement() {
+ @Override public K getElement() {
return backingEntry.getKey();
}
- @Override
- public int getCount() {
+ @Override public int getCount() {
return backingEntry.getValue().size();
}
};
}
+
+ @Override public void remove() {
+ backingIterator.remove();
+ }
};
}
@Override int distinctElements() {
- return multimap.asMap().size();
+ return multimap().asMap().size();
}
@Override Set<Multiset.Entry<K>> createEntrySet() {
@@ -1744,22 +1822,22 @@ public final class Multimaps {
}
@Override public boolean isEmpty() {
- return multimap.isEmpty();
+ return multimap().isEmpty();
}
@Override public boolean contains(@Nullable Object o) {
- if (o instanceof Multiset.Entry) {
+ if (o instanceof Multiset.Entry<?>) {
Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
- Collection<V> collection = multimap.asMap().get(entry.getElement());
+ Collection<V> collection = multimap().asMap().get(entry.getElement());
return collection != null && collection.size() == entry.getCount();
}
return false;
}
@Override public boolean remove(@Nullable Object o) {
- if (o instanceof Multiset.Entry) {
+ if (o instanceof Multiset.Entry<?>) {
Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
- Collection<V> collection = multimap.asMap().get(entry.getElement());
+ Collection<V> collection = multimap().asMap().get(entry.getElement());
if (collection != null && collection.size() == entry.getCount()) {
collection.clear();
return true;
@@ -1770,16 +1848,30 @@ public final class Multimaps {
}
@Override public boolean contains(@Nullable Object element) {
- return multimap.containsKey(element);
+ return multimap().containsKey(element);
}
@Override public Iterator<K> iterator() {
- return Maps.keyIterator(multimap.entries().iterator());
+ return Iterators.transform(multimap().entries().iterator(),
+ new Function<Map.Entry<K, V>, K>() {
+ @Override public K apply(Map.Entry<K, V> entry) {
+ return entry.getKey();
+ }
+ });
}
@Override public int count(@Nullable Object element) {
- Collection<V> values = Maps.safeGet(multimap.asMap(), element);
- return (values == null) ? 0 : values.size();
+ try {
+ if (multimap().containsKey(element)) {
+ Collection<V> values = multimap().asMap().get(element);
+ return (values == null) ? 0 : values.size();
+ }
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ } catch (NullPointerException e) {
+ return 0;
+ }
}
@Override public int remove(@Nullable Object element, int occurrences) {
@@ -1788,7 +1880,14 @@ public final class Multimaps {
return count(element);
}
- Collection<V> values = Maps.safeGet(multimap.asMap(), element);
+ Collection<V> values;
+ try {
+ values = multimap().asMap().get(element);
+ } catch (ClassCastException e) {
+ return 0;
+ } catch (NullPointerException e) {
+ return 0;
+ }
if (values == null) {
return 0;
@@ -1808,35 +1907,45 @@ public final class Multimaps {
}
@Override public void clear() {
- multimap.clear();
+ multimap().clear();
}
@Override public Set<K> elementSet() {
- return multimap.keySet();
+ return multimap().keySet();
}
}
- static class Values<K, V> extends AbstractCollection<V> {
- final Multimap<K, V> multimap;
-
- Values(Multimap<K, V> multimap) {
- this.multimap = multimap;
- }
+ static abstract class Values<K, V> extends AbstractCollection<V> {
+ abstract Multimap<K, V> multimap();
@Override public Iterator<V> iterator() {
- return Maps.valueIterator(multimap.entries().iterator());
+ final Iterator<Map.Entry<K, V>> backingIterator =
+ multimap().entries().iterator();
+ return new Iterator<V>() {
+ @Override public boolean hasNext() {
+ return backingIterator.hasNext();
+ }
+
+ @Override public V next() {
+ return backingIterator.next().getValue();
+ }
+
+ @Override public void remove() {
+ backingIterator.remove();
+ }
+ };
}
@Override public int size() {
- return multimap.size();
+ return multimap().size();
}
@Override public boolean contains(@Nullable Object o) {
- return multimap.containsValue(o);
+ return multimap().containsValue(o);
}
@Override public void clear() {
- multimap.clear();
+ multimap().clear();
}
}
@@ -1852,7 +1961,7 @@ public final class Multimaps {
}
@Override public boolean contains(@Nullable Object o) {
- if (o instanceof Map.Entry) {
+ if (o instanceof Map.Entry<?, ?>) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
return multimap().containsEntry(entry.getKey(), entry.getValue());
}
@@ -1860,7 +1969,7 @@ public final class Multimaps {
}
@Override public boolean remove(@Nullable Object o) {
- if (o instanceof Map.Entry) {
+ if (o instanceof Map.Entry<?, ?>) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
return multimap().remove(entry.getKey(), entry.getValue());
}
@@ -1953,15 +2062,476 @@ public final class Multimaps {
/**
* Support removal operations when filtering a filtered multimap. Since a
* filtered multimap has iterators that don't support remove, passing one to
- * the FilteredEntryMultimap constructor would lead to a multimap whose removal
+ * the FilteredMultimap constructor would lead to a multimap whose removal
* operations would fail. This method combines the predicates to avoid that
* problem.
*/
- private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> multimap,
+ private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> map,
Predicate<? super Entry<K, V>> entryPredicate) {
Predicate<Entry<K, V>> predicate
- = Predicates.and(multimap.entryPredicate(), entryPredicate);
- return new FilteredEntryMultimap<K, V>(multimap.unfiltered, predicate);
+ = Predicates.and(map.predicate, entryPredicate);
+ return new FilteredMultimap<K, V>(map.unfiltered, predicate);
+ }
+
+ private static class FilteredMultimap<K, V> implements Multimap<K, V> {
+ final Multimap<K, V> unfiltered;
+ final Predicate<? super Entry<K, V>> predicate;
+
+ FilteredMultimap(Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
+ this.unfiltered = unfiltered;
+ this.predicate = predicate;
+ }
+
+ @Override public int size() {
+ return entries().size();
+ }
+
+ @Override public boolean isEmpty() {
+ return entries().isEmpty();
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return asMap().containsKey(key);
+ }
+
+ @Override public boolean containsValue(Object value) {
+ return values().contains(value);
+ }
+
+ // This method should be called only when key is a K and value is a V.
+ @SuppressWarnings("unchecked")
+ boolean satisfiesPredicate(Object key, Object value) {
+ return predicate.apply(Maps.immutableEntry((K) key, (V) value));
+ }
+
+ @Override public boolean containsEntry(Object key, Object value) {
+ return unfiltered.containsEntry(key, value) && satisfiesPredicate(key, value);
+ }
+
+ @Override public boolean put(K key, V value) {
+ checkArgument(satisfiesPredicate(key, value));
+ return unfiltered.put(key, value);
+ }
+
+ @Override public boolean remove(Object key, Object value) {
+ return containsEntry(key, value) ? unfiltered.remove(key, value) : false;
+ }
+
+ @Override public boolean putAll(K key, Iterable<? extends V> values) {
+ for (V value : values) {
+ checkArgument(satisfiesPredicate(key, value));
+ }
+ return unfiltered.putAll(key, values);
+ }
+
+ @Override public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ for (Entry<? extends K, ? extends V> entry : multimap.entries()) {
+ checkArgument(satisfiesPredicate(entry.getKey(), entry.getValue()));
+ }
+ return unfiltered.putAll(multimap);
+ }
+
+ @Override public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
+ for (V value : values) {
+ checkArgument(satisfiesPredicate(key, value));
+ }
+ // Not calling unfiltered.replaceValues() since values that don't satisify
+ // the filter should remain in the multimap.
+ Collection<V> oldValues = removeAll(key);
+ unfiltered.putAll(key, values);
+ return oldValues;
+ }
+
+ @Override public Collection<V> removeAll(Object key) {
+ List<V> removed = Lists.newArrayList();
+ Collection<V> values = unfiltered.asMap().get(key);
+ if (values != null) {
+ Iterator<V> iterator = values.iterator();
+ while (iterator.hasNext()) {
+ V value = iterator.next();
+ if (satisfiesPredicate(key, value)) {
+ removed.add(value);
+ iterator.remove();
+ }
+ }
+ }
+ if (unfiltered instanceof SetMultimap) {
+ return Collections.unmodifiableSet(Sets.newLinkedHashSet(removed));
+ } else {
+ return Collections.unmodifiableList(removed);
+ }
+ }
+
+ @Override public void clear() {
+ entries().clear();
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Multimap) {
+ Multimap<?, ?> that = (Multimap<?, ?>) object;
+ return asMap().equals(that.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return asMap().hashCode();
+ }
+
+ @Override public String toString() {
+ return asMap().toString();
+ }
+
+ class ValuePredicate implements Predicate<V> {
+ final K key;
+ ValuePredicate(K key) {
+ this.key = key;
+ }
+ @Override public boolean apply(V value) {
+ return satisfiesPredicate(key, value);
+ }
+ }
+
+ Collection<V> filterCollection(Collection<V> collection, Predicate<V> predicate) {
+ if (collection instanceof Set) {
+ return Sets.filter((Set<V>) collection, predicate);
+ } else {
+ return Collections2.filter(collection, predicate);
+ }
+ }
+
+ @Override public Collection<V> get(K key) {
+ return filterCollection(unfiltered.get(key), new ValuePredicate(key));
+ }
+
+ @Override public Set<K> keySet() {
+ return asMap().keySet();
+ }
+
+ Collection<V> values;
+
+ @Override public Collection<V> values() {
+ return (values == null) ? values = new Values() : values;
+ }
+
+ class Values extends Multimaps.Values<K, V> {
+ @Override Multimap<K, V> multimap() {
+ return FilteredMultimap.this;
+ }
+
+ @Override public boolean contains(@Nullable Object o) {
+ return Iterators.contains(iterator(), o);
+ }
+
+ // Override remove methods since iterator doesn't support remove.
+
+ @Override public boolean remove(Object o) {
+ Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
+ while (iterator.hasNext()) {
+ Entry<K, V> entry = iterator.next();
+ if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) {
+ iterator.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ boolean changed = false;
+ Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
+ while (iterator.hasNext()) {
+ Entry<K, V> entry = iterator.next();
+ if (c.contains(entry.getValue()) && predicate.apply(entry)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ boolean changed = false;
+ Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
+ while (iterator.hasNext()) {
+ Entry<K, V> entry = iterator.next();
+ if (!c.contains(entry.getValue()) && predicate.apply(entry)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+ }
+
+ Collection<Entry<K, V>> entries;
+
+ @Override public Collection<Entry<K, V>> entries() {
+ return (entries == null)
+ ? entries = Collections2.filter(unfiltered.entries(), predicate)
+ : entries;
+ }
+
+ /**
+ * Remove all filtered asMap() entries that satisfy the predicate.
+ */
+ boolean removeEntriesIf(Predicate<Map.Entry<K, Collection<V>>> removalPredicate) {
+ Iterator<Map.Entry<K, Collection<V>>> iterator = unfiltered.asMap().entrySet().iterator();
+ boolean changed = false;
+ while (iterator.hasNext()) {
+ // Determine whether to remove the filtered values with this key.
+ Map.Entry<K, Collection<V>> entry = iterator.next();
+ K key = entry.getKey();
+ Collection<V> collection = entry.getValue();
+ Predicate<V> valuePredicate = new ValuePredicate(key);
+ Collection<V> filteredCollection = filterCollection(collection, valuePredicate);
+ Map.Entry<K, Collection<V>> filteredEntry = Maps.immutableEntry(key, filteredCollection);
+ if (removalPredicate.apply(filteredEntry) && !filteredCollection.isEmpty()) {
+ changed = true;
+ if (Iterables.all(collection, valuePredicate)) {
+ iterator.remove(); // Remove all values for the key.
+ } else {
+ filteredCollection.clear(); // Remove the filtered values only.
+ }
+ }
+ }
+ return changed;
+ }
+
+ Map<K, Collection<V>> asMap;
+
+ @Override public Map<K, Collection<V>> asMap() {
+ return (asMap == null) ? asMap = createAsMap() : asMap;
+ }
+
+ static final Predicate<Collection<?>> NOT_EMPTY = new Predicate<Collection<?>>() {
+ @Override public boolean apply(Collection<?> input) {
+ return !input.isEmpty();
+ }
+ };
+
+ Map<K, Collection<V>> createAsMap() {
+ // Select the values that satisify the predicate.
+ EntryTransformer<K, Collection<V>, Collection<V>> transformer
+ = new EntryTransformer<K, Collection<V>, Collection<V>>() {
+ @Override public Collection<V> transformEntry(K key, Collection<V> collection) {
+ return filterCollection(collection, new ValuePredicate(key));
+ }
+ };
+ Map<K, Collection<V>> transformed
+ = Maps.transformEntries(unfiltered.asMap(), transformer);
+
+ // Select the keys that have at least one value remaining.
+ Map<K, Collection<V>> filtered = Maps.filterValues(transformed, NOT_EMPTY);
+
+ // Override the removal methods, since removing a map entry should not
+ // affect values that don't satisfy the filter.
+ return new AsMap(filtered);
+ }
+
+ class AsMap extends ForwardingMap<K, Collection<V>> {
+ final Map<K, Collection<V>> delegate;
+
+ AsMap(Map<K, Collection<V>> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override protected Map<K, Collection<V>> delegate() {
+ return delegate;
+ }
+
+ @Override public Collection<V> remove(Object o) {
+ Collection<V> output = FilteredMultimap.this.removeAll(o);
+ return output.isEmpty() ? null : output;
+ }
+
+ @Override public void clear() {
+ FilteredMultimap.this.clear();
+ }
+
+ Set<K> keySet;
+
+ @Override public Set<K> keySet() {
+ return (keySet == null) ? keySet = new KeySet() : keySet;
+ }
+
+ class KeySet extends Maps.KeySet<K, Collection<V>> {
+ @Override Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public boolean remove(Object o) {
+ Collection<V> collection = delegate.get(o);
+ if (collection == null) {
+ return false;
+ }
+ collection.clear();
+ return true;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Sets.removeAllImpl(this, c);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return !c.contains(entry.getKey());
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+
+ Values asMapValues;
+
+ @Override public Collection<Collection<V>> values() {
+ return (asMapValues == null) ? asMapValues = new Values() : asMapValues;
+ }
+
+ class Values extends Maps.Values<K, Collection<V>> {
+ @Override Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public boolean remove(Object o) {
+ for (Collection<V> collection : this) {
+ if (collection.equals(o)) {
+ collection.clear();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean removeAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return c.contains(entry.getValue());
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return !c.contains(entry.getValue());
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+
+ EntrySet entrySet;
+
+ @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
+ return (entrySet == null) ? entrySet = new EntrySet(super.entrySet()) : entrySet;
+ }
+
+ class EntrySet extends Maps.EntrySet<K, Collection<V>> {
+ Set<Map.Entry<K, Collection<V>>> delegateEntries;
+
+ public EntrySet(Set<Map.Entry<K, Collection<V>>> delegateEntries) {
+ this.delegateEntries = delegateEntries;
+ }
+
+ @Override Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
+ return delegateEntries.iterator();
+ }
+
+ @Override public boolean remove(Object o) {
+ if (o instanceof Entry<?, ?>) {
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ Collection<V> collection = delegate.get(entry.getKey());
+ if (collection != null && collection.equals(entry.getValue())) {
+ collection.clear();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Sets.removeAllImpl(this, c);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return !c.contains(entry);
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+ }
+
+ AbstractMultiset<K> keys;
+
+ @Override public Multiset<K> keys() {
+ return (keys == null) ? keys = new Keys() : keys;
+ }
+
+ class Keys extends Multimaps.Keys<K, V> {
+ @Override Multimap<K, V> multimap() {
+ return FilteredMultimap.this;
+ }
+
+ @Override public int remove(Object o, int occurrences) {
+ checkArgument(occurrences >= 0);
+ Collection<V> values = unfiltered.asMap().get(o);
+ if (values == null) {
+ return 0;
+ }
+ int priorCount = 0;
+ int removed = 0;
+ Iterator<V> iterator = values.iterator();
+ while (iterator.hasNext()) {
+ if (satisfiesPredicate(o, iterator.next())) {
+ priorCount++;
+ if (removed < occurrences) {
+ iterator.remove();
+ removed++;
+ }
+ }
+ }
+ return priorCount;
+ }
+
+ @Override Set<Multiset.Entry<K>> createEntrySet() {
+ return new EntrySet();
+ }
+
+ class EntrySet extends Multimaps.Keys<K, V>.KeysEntrySet {
+ @Override public boolean removeAll(Collection<?> c) {
+ return Sets.removeAllImpl(this, c);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ Multiset.Entry<K> multisetEntry
+ = Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
+ return !c.contains(multisetEntry);
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+ }
}
// TODO(jlevy): Create methods that filter a SetMultimap or SortedSetMultimap.
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ObjectArrays.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ObjectArrays.java
index 6465ee7..087fd17 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ObjectArrays.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ObjectArrays.java
@@ -30,8 +30,6 @@ import javax.annotation.Nullable;
*/
@GwtCompatible(emulated = true)
public final class ObjectArrays {
- static final Object[] EMPTY_ARRAY = new Object[0];
-
private ObjectArrays() {}
/**
@@ -57,7 +55,7 @@ public final class ObjectArrays {
public static <T> T[] concat(@Nullable T element, T[] array) {
T[] result = newArray(array, array.length + 1);
result[0] = element;
- System.arraycopy(array, 0, result, 1, array.length);
+ Platform.unsafeArrayCopy(array, 0, result, 1, array.length);
return result;
}
@@ -79,7 +77,7 @@ public final class ObjectArrays {
/** GWT safe version of Arrays.copyOf. */
static <T> T[] arraysCopyOf(T[] original, int newLength) {
T[] copy = newArray(original, newLength);
- System.arraycopy(
+ Platform.unsafeArrayCopy(
original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
@@ -154,14 +152,5 @@ public final class ObjectArrays {
array[i] = array[j];
array[j] = temp;
}
-
- // We do this instead of Preconditions.checkNotNull to save boxing and array
- // creation cost.
- static Object checkElementNotNull(Object element, int index) {
- if (element == null) {
- throw new NullPointerException("at index " + index);
- }
- return element;
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Platform.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Platform.java
index 3fe8150..4fbdde0 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Platform.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Platform.java
@@ -16,14 +16,6 @@
package com.google.common.collect;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Maps.EntryTransformer;
-
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
/**
* Minimal GWT emulation of {@code com.google.common.collect.Platform}.
*
@@ -37,32 +29,24 @@ class Platform {
return GwtPlatform.clone(array);
}
- static <T> T[] newArray(T[] reference, int length) {
- return GwtPlatform.newArray(reference, length);
+ // TODO: Fix System.arraycopy in GWT so that it isn't necessary.
+ static void unsafeArrayCopy(
+ Object[] src, int srcPos, Object[] dest, int destPos, int length) {
+ for (int i = 0; i < length; i++) {
+ dest[destPos + i] = src[srcPos + i];
+ }
}
- static MapMaker tryWeakKeys(MapMaker mapMaker) {
- return mapMaker;
+ static <T> T[] newArray(Class<T> type, int length) {
+ throw new UnsupportedOperationException(
+ "Platform.newArray is not supported in GWT yet.");
}
- static <K, V1, V2> SortedMap<K, V2> mapsTransformEntriesSortedMap(
- SortedMap<K, V1> fromMap,
- EntryTransformer<? super K, ? super V1, V2> transformer) {
- return Maps.transformEntriesIgnoreNavigable(fromMap, transformer);
- }
-
- static <K, V> SortedMap<K, V> mapsAsMapSortedSet(
- SortedSet<K> set, Function<? super K, V> function) {
- return Maps.asMapSortedIgnoreNavigable(set, function);
+ static <T> T[] newArray(T[] reference, int length) {
+ return GwtPlatform.newArray(reference, length);
}
- static <E> SortedSet<E> setsFilterSortedSet(
- SortedSet<E> unfiltered, Predicate<? super E> predicate) {
- return Sets.filterSortedIgnoreNavigable(unfiltered, predicate);
- }
-
- static <K, V> SortedMap<K, V> mapsFilterSortedMap(
- SortedMap<K, V> unfiltered, Predicate<? super Map.Entry<K, V>> predicate) {
- return Maps.filterSortedIgnoreNavigable(unfiltered, predicate);
+ static MapMaker tryWeakKeys(MapMaker mapMaker) {
+ return mapMaker;
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularContiguousSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularContiguousSet.java
index 999f6ee..a63b391 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularContiguousSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularContiguousSet.java
@@ -39,33 +39,32 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
this.range = range;
}
- private ContiguousSet<C> intersectionInCurrentDomain(Range<C> other) {
- return (range.isConnected(other))
- ? ContiguousSet.create(range.intersection(other), domain)
- : new EmptyContiguousSet<C>(domain);
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ ContiguousSet<C> headSetImpl(C toElement, boolean inclusive) {
+ return range.intersection(Ranges.upTo(toElement, BoundType.forBoolean(inclusive)))
+ .asSet(domain);
}
- @Override ContiguousSet<C> headSetImpl(C toElement, boolean inclusive) {
- return intersectionInCurrentDomain(Range.upTo(toElement, BoundType.forBoolean(inclusive)));
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ int indexOf(Object target) {
+ return contains(target) ? (int) domain.distance(first(), (C) target) : -1;
}
- @Override ContiguousSet<C> subSetImpl(C fromElement, boolean fromInclusive, C toElement,
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ ContiguousSet<C> subSetImpl(C fromElement, boolean fromInclusive, C toElement,
boolean toInclusive) {
- if (fromElement.compareTo(toElement) == 0 && !fromInclusive && !toInclusive) {
- // Range would reject our attempt to create (x, x).
- return new EmptyContiguousSet<C>(domain);
- }
- return intersectionInCurrentDomain(Range.range(
- fromElement, BoundType.forBoolean(fromInclusive),
- toElement, BoundType.forBoolean(toInclusive)));
+ return range.intersection(Ranges.range(fromElement, BoundType.forBoolean(fromInclusive),
+ toElement, BoundType.forBoolean(toInclusive))).asSet(domain);
}
- @Override ContiguousSet<C> tailSetImpl(C fromElement, boolean inclusive) {
- return intersectionInCurrentDomain(Range.downTo(fromElement, BoundType.forBoolean(inclusive)));
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ ContiguousSet<C> tailSetImpl(C fromElement, boolean inclusive) {
+ return range.intersection(Ranges.downTo(fromElement, BoundType.forBoolean(inclusive)))
+ .asSet(domain);
}
@Override public UnmodifiableIterator<C> iterator() {
- return new AbstractSequentialIterator<C>(first()) {
+ return new AbstractLinkedIterator<C>(first()) {
final C last = last();
@Override
@@ -96,10 +95,7 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
return (distance >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) distance + 1;
}
- @Override public boolean contains(@Nullable Object object) {
- if (object == null) {
- return false;
- }
+ @Override public boolean contains(Object object) {
try {
return range.contains((C) object);
} catch (ClassCastException e) {
@@ -108,7 +104,11 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
}
@Override public boolean containsAll(Collection<?> targets) {
- return Collections2.containsAllImpl(this, targets);
+ try {
+ return range.containsAll((Iterable<? extends C>) targets);
+ } catch (ClassCastException e) {
+ return false;
+ }
}
@Override public boolean isEmpty() {
@@ -134,7 +134,7 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
C lowerEndpoint = Ordering.natural().max(this.first(), other.first());
C upperEndpoint = Ordering.natural().min(this.last(), other.last());
return (lowerEndpoint.compareTo(upperEndpoint) < 0)
- ? ContiguousSet.create(Range.closed(lowerEndpoint, upperEndpoint), domain)
+ ? Ranges.closed(lowerEndpoint, upperEndpoint).asSet(domain)
: new EmptyContiguousSet<C>(domain);
}
}
@@ -144,14 +144,14 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
}
@Override public Range<C> range(BoundType lowerBoundType, BoundType upperBoundType) {
- return Range.create(range.lowerBound.withLowerBoundType(lowerBoundType, domain),
+ return Ranges.create(range.lowerBound.withLowerBoundType(lowerBoundType, domain),
range.upperBound.withUpperBoundType(upperBoundType, domain));
}
- @Override public boolean equals(@Nullable Object object) {
+ @Override public boolean equals(Object object) {
if (object == this) {
return true;
- } else if (object instanceof RegularContiguousSet) {
+ } else if (object instanceof RegularContiguousSet<?>) {
RegularContiguousSet<?> that = (RegularContiguousSet<?>) object;
if (this.domain.equals(that.domain)) {
return this.first().equals(that.first())
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableList.java
index f82a6b6..5cdddff 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableList.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableList.java
@@ -16,8 +16,6 @@
package com.google.common.collect;
-import static java.util.Collections.unmodifiableList;
-
import java.util.List;
/**
@@ -25,15 +23,8 @@ import java.util.List;
*
* @author Hayward Chan
*/
-class RegularImmutableList<E> extends ForwardingImmutableList<E> {
- private final List<E> delegate;
-
+class RegularImmutableList<E> extends ImmutableList<E> {
RegularImmutableList(List<E> delegate) {
- // TODO(cpovirk): avoid redundant unmodifiableList wrapping
- this.delegate = unmodifiableList(delegate);
- }
-
- @Override List<E> delegateList() {
- return delegate;
+ super(delegate);
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableMap.java
index b79ce80..bdf536b 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableMap.java
@@ -23,7 +23,7 @@ import java.util.Map;
*
* @author Hayward Chan
*/
-final class RegularImmutableMap<K, V> extends ForwardingImmutableMap<K, V> {
+final class RegularImmutableMap<K, V> extends ImmutableMap<K, V> {
RegularImmutableMap(Map<? extends K, ? extends V> delegate) {
super(delegate);
@@ -31,5 +31,5 @@ final class RegularImmutableMap<K, V> extends ForwardingImmutableMap<K, V> {
RegularImmutableMap(Entry<? extends K, ? extends V>... entries) {
super(entries);
- }
+ }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSet.java
index 72da3e4..f462ade 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSet.java
@@ -25,7 +25,7 @@ import java.util.Set;
*
* @author Hayward Chan
*/
-final class RegularImmutableSet<E> extends ForwardingImmutableSet<E> {
+final class RegularImmutableSet<E> extends ImmutableSet<E> {
RegularImmutableSet(Set<E> delegate) {
super(delegate);
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedMap.java
deleted file mode 100644
index 2e36f39..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedMap.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Comparator;
-import java.util.SortedMap;
-
-/**
- * GWT emulated version of {@link RegularImmutableSortedMap}.
- *
- * @author Chris Povirk
- */
-final class RegularImmutableSortedMap<K, V> extends ImmutableSortedMap<K, V> {
- RegularImmutableSortedMap(SortedMap<K, V> delegate, Comparator<? super K> comparator) {
- super(delegate, comparator);
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedSet.java
index 3279449..8256e98 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/RegularImmutableSortedSet.java
@@ -32,8 +32,4 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
super(delegate);
this.isSubset = isSubset;
}
-
- @Override ImmutableList<E> createAsList() {
- return new ImmutableSortedAsList<E>(this, ImmutableList.<E>asImmutableList(toArray()));
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Sets.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Sets.java
index bb06a9c..be31363 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Sets.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Sets.java
@@ -19,10 +19,15 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2.FilteredCollection;
+import com.google.common.math.IntMath;
import java.io.Serializable;
import java.util.AbstractSet;
@@ -45,11 +50,7 @@ import javax.annotation.Nullable;
/**
* Static utility methods pertaining to {@link Set} instances. Also see this
- * class's counterparts {@link Lists}, {@link Maps} and {@link Queues}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Sets">
- * {@code Sets}</a>.
+ * class's counterparts {@link Lists} and {@link Maps}.
*
* @author Kevin Bourrillion
* @author Jared Levy
@@ -61,22 +62,6 @@ public final class Sets {
private Sets() {}
/**
- * {@link AbstractSet} substitute without the potentially-quadratic
- * {@code removeAll} implementation.
- */
- abstract static class ImprovedAbstractSet<E> extends AbstractSet<E> {
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeAllImpl(this, c);
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return super.retainAll(checkNotNull(c)); // GWT compatibility
- }
- }
-
- /**
* Returns an immutable set instance containing the given enum elements.
* Internally, the returned set will be backed by an {@link EnumSet}.
*
@@ -91,7 +76,7 @@ public final class Sets {
@GwtCompatible(serializable = true)
public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(
E anElement, E... otherElements) {
- return ImmutableEnumSet.asImmutable(EnumSet.of(anElement, otherElements));
+ return new ImmutableEnumSet<E>(EnumSet.of(anElement, otherElements));
}
/**
@@ -109,25 +94,20 @@ public final class Sets {
@GwtCompatible(serializable = true)
public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(
Iterable<E> elements) {
- if (elements instanceof ImmutableEnumSet) {
- return (ImmutableEnumSet<E>) elements;
- } else if (elements instanceof Collection) {
- Collection<E> collection = (Collection<E>) elements;
- if (collection.isEmpty()) {
- return ImmutableSet.of();
- } else {
- return ImmutableEnumSet.asImmutable(EnumSet.copyOf(collection));
- }
- } else {
- Iterator<E> itr = elements.iterator();
- if (itr.hasNext()) {
- EnumSet<E> enumSet = EnumSet.of(itr.next());
- Iterators.addAll(enumSet, itr);
- return ImmutableEnumSet.asImmutable(enumSet);
- } else {
- return ImmutableSet.of();
- }
+ Iterator<E> iterator = elements.iterator();
+ if (!iterator.hasNext()) {
+ return ImmutableSet.of();
+ }
+ if (elements instanceof EnumSet) {
+ EnumSet<E> enumSetClone = EnumSet.copyOf((EnumSet<E>) elements);
+ return new ImmutableEnumSet<E>(enumSetClone);
}
+ E first = iterator.next();
+ EnumSet<E> set = EnumSet.of(first);
+ while (iterator.hasNext()) {
+ set.add(iterator.next());
+ }
+ return new ImmutableEnumSet<E>(set);
}
/**
@@ -138,6 +118,20 @@ public final class Sets {
*/
public static <E extends Enum<E>> EnumSet<E> newEnumSet(Iterable<E> iterable,
Class<E> elementType) {
+ /*
+ * TODO(cpovirk): noneOf() and addAll() will both throw
+ * NullPointerExceptions when appropriate. However, NullPointerTester will
+ * fail on this method because it passes in Class.class instead of an enum
+ * type. This means that, when iterable is null but elementType is not,
+ * noneOf() will throw a ClassCastException before addAll() has a chance to
+ * throw a NullPointerException. NullPointerTester considers this a failure.
+ * Ideally the test would be fixed, but it would require a special case for
+ * Class<E> where E extends Enum. Until that happens (if ever), leave
+ * checkNotNull() here. For now, contemplate the irony that checking
+ * elementType, the problem argument, is harmful, while checking iterable,
+ * the innocent bystander, is effective.
+ */
+ checkNotNull(iterable);
EnumSet<E> set = EnumSet.noneOf(elementType);
Iterables.addAll(set, iterable);
return set;
@@ -572,11 +566,6 @@ public final class Sets {
* <p><b>Note:</b> The returned view performs better when {@code set1} is the
* smaller of the two sets. If you have reason to believe one of your sets
* will generally be smaller than the other, pass it first.
- *
- * <p>Further, note that the current implementation is not suitable for nested
- * {@code union} views, i.e. the following should be avoided when in a loop:
- * {@code union = Sets.union(union, anotherSet);}, since iterating over the resulting
- * set has a cubic complexity to the depth of the nesting.
*/
public static <E> SetView<E> union(
final Set<? extends E> set1, final Set<? extends E> set2) {
@@ -807,13 +796,10 @@ public final class Sets {
*
* @since 11.0
*/
+ @Beta
+ @SuppressWarnings("unchecked")
public static <E> SortedSet<E> filter(
SortedSet<E> unfiltered, Predicate<? super E> predicate) {
- return Platform.setsFilterSortedSet(unfiltered, predicate);
- }
-
- static <E> SortedSet<E> filterSortedIgnoreNavigable(
- SortedSet<E> unfiltered, Predicate<? super E> predicate) {
if (unfiltered instanceof FilteredSet) {
// Support clear(), removeAll(), and retainAll() when filtering a filtered
// collection.
@@ -828,13 +814,21 @@ public final class Sets {
checkNotNull(unfiltered), checkNotNull(predicate));
}
- private static class FilteredSortedSet<E> extends FilteredSet<E>
+ private static class FilteredSortedSet<E> extends FilteredCollection<E>
implements SortedSet<E> {
FilteredSortedSet(SortedSet<E> unfiltered, Predicate<? super E> predicate) {
super(unfiltered, predicate);
}
+ @Override public boolean equals(@Nullable Object object) {
+ return equalsImpl(this, object);
+ }
+
+ @Override public int hashCode() {
+ return hashCodeImpl(this);
+ }
+
@Override
public Comparator<? super E> comparator() {
return ((SortedSet<E>) unfiltered).comparator();
@@ -895,22 +889,12 @@ public final class Sets {
* <li>{@code ImmutableList.of(2, "C")}
* </ul>
*
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : sets.get(0)) {
- * for (B b1 : sets.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input set is empty, the Cartesian product will also be
- * empty. If no sets at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
+ * The order in which these lists are returned is not guaranteed, however the
+ * position of an element inside a tuple always corresponds to the position of
+ * the set from which it came in the input list. Note that if any input set is
+ * empty, the Cartesian product will also be empty. If no sets at all are
+ * provided (an empty list), the resulting Cartesian product has one element,
+ * an empty list (counter-intuitive, but mathematically consistent).
*
* <p><i>Performance notes:</i> while the cartesian product of sets of size
* {@code m, n, p} is a set of size {@code m x n x p}, its actual memory
@@ -936,7 +920,8 @@ public final class Sets {
return ImmutableSet.of();
}
}
- return CartesianSet.create(sets);
+ CartesianSet<B> cartesianSet = new CartesianSet<B>(sets);
+ return cartesianSet;
}
/**
@@ -960,22 +945,12 @@ public final class Sets {
* <li>{@code ImmutableList.of(2, "C")}
* </ul>
*
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : sets.get(0)) {
- * for (B b1 : sets.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input set is empty, the Cartesian product will also be
- * empty. If no sets at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
+ * The order in which these lists are returned is not guaranteed, however the
+ * position of an element inside a tuple always corresponds to the position of
+ * the set from which it came in the input list. Note that if any input set is
+ * empty, the Cartesian product will also be empty. If no sets at all are
+ * provided, the resulting Cartesian product has one element, an empty list
+ * (counter-intuitive, but mathematically consistent).
*
* <p><i>Performance notes:</i> while the cartesian product of sets of size
* {@code m, n, p} is a set of size {@code m x n x p}, its actual memory
@@ -999,51 +974,73 @@ public final class Sets {
return cartesianProduct(Arrays.asList(sets));
}
- private static final class CartesianSet<E>
- extends ForwardingCollection<List<E>> implements Set<List<E>> {
- private transient final ImmutableList<ImmutableSet<E>> axes;
- private transient final CartesianList<E> delegate;
-
- static <E> Set<List<E>> create(List<? extends Set<? extends E>> sets) {
- ImmutableList.Builder<ImmutableSet<E>> axesBuilder =
- new ImmutableList.Builder<ImmutableSet<E>>(sets.size());
- for (Set<? extends E> set : sets) {
- ImmutableSet<E> copy = ImmutableSet.copyOf(set);
- if (copy.isEmpty()) {
- return ImmutableSet.of();
+ private static class CartesianSet<B> extends AbstractSet<List<B>> {
+ final ImmutableList<Axis> axes;
+ final int size;
+
+ CartesianSet(List<? extends Set<? extends B>> sets) {
+ int dividend = 1;
+ ImmutableList.Builder<Axis> builder = ImmutableList.builder();
+ try {
+ for (Set<? extends B> set : sets) {
+ Axis axis = new Axis(set, dividend);
+ builder.add(axis);
+ dividend = IntMath.checkedMultiply(dividend, axis.size());
}
- axesBuilder.add(copy);
+ } catch (ArithmeticException overflow) {
+ throw new IllegalArgumentException("cartesian product too big");
}
- final ImmutableList<ImmutableSet<E>> axes = axesBuilder.build();
- ImmutableList<List<E>> listAxes = new ImmutableList<List<E>>() {
+ this.axes = builder.build();
+ size = dividend;
+ }
- @Override
- public int size() {
- return axes.size();
- }
+ @Override public int size() {
+ return size;
+ }
+
+ @Override public UnmodifiableIterator<List<B>> iterator() {
+ return new UnmodifiableIterator<List<B>>() {
+ int index;
@Override
- public List<E> get(int index) {
- return axes.get(index).asList();
+ public boolean hasNext() {
+ return index < size;
}
@Override
- boolean isPartialView() {
- return true;
+ public List<B> next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ Object[] tuple = new Object[axes.size()];
+ for (int i = 0 ; i < tuple.length; i++) {
+ tuple[i] = axes.get(i).getForIndex(index);
+ }
+ index++;
+
+ @SuppressWarnings("unchecked") // only B's are put in here
+ List<B> result = (ImmutableList<B>) ImmutableList.copyOf(tuple);
+ return result;
}
};
- return new CartesianSet<E>(axes, new CartesianList<E>(listAxes));
}
- private CartesianSet(
- ImmutableList<ImmutableSet<E>> axes, CartesianList<E> delegate) {
- this.axes = axes;
- this.delegate = delegate;
- }
-
- @Override
- protected Collection<List<E>> delegate() {
- return delegate;
+ @Override public boolean contains(Object element) {
+ if (!(element instanceof List<?>)) {
+ return false;
+ }
+ List<?> tuple = (List<?>) element;
+ int dimensions = axes.size();
+ if (tuple.size() != dimensions) {
+ return false;
+ }
+ for (int i = 0; i < dimensions; i++) {
+ if (!axes.get(i).contains(tuple.get(i))) {
+ return false;
+ }
+ }
+ return true;
}
@Override public boolean equals(@Nullable Object object) {
@@ -1056,26 +1053,56 @@ public final class Sets {
return super.equals(object);
}
- @Override
- public int hashCode() {
+ @Override public int hashCode() {
// Warning: this is broken if size() == 0, so it is critical that we
// substitute an empty ImmutableSet to the user in place of this
// It's a weird formula, but tests prove it works.
- int adjust = size() - 1;
+ int adjust = size - 1;
for (int i = 0; i < axes.size(); i++) {
adjust *= 31;
- adjust = ~~adjust;
- // in GWT, we have to deal with integer overflow carefully
}
- int hash = 1;
- for (Set<E> axis : axes) {
- hash = 31 * hash + (size() / axis.size() * axis.hashCode());
+ return axes.hashCode() + adjust;
+ }
- hash = ~~hash;
+ private class Axis {
+ final ImmutableSet<? extends B> choices;
+ final ImmutableList<? extends B> choicesList;
+ final int dividend;
+
+ Axis(Set<? extends B> set, int dividend) {
+ choices = ImmutableSet.copyOf(set);
+ choicesList = choices.asList();
+ this.dividend = dividend;
+ }
+
+ int size() {
+ return choices.size();
+ }
+
+ B getForIndex(int index) {
+ return choicesList.get(index / dividend % size());
+ }
+
+ boolean contains(Object target) {
+ return choices.contains(target);
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof CartesianSet.Axis) {
+ CartesianSet.Axis that = (CartesianSet.Axis) obj;
+ return this.choices.equals(that.choices);
+ // dividends must be equal or we wouldn't have gotten this far
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ // Because Axis instances are not exposed, we can
+ // opportunistically choose whatever bizarre formula happens
+ // to make CartesianSet.hashCode() as simple as possible.
+ return size / choices.size() * choices.hashCode();
}
- hash += adjust;
- return ~~hash;
}
}
@@ -1213,9 +1240,6 @@ public final class Sets {
int hashCode = 0;
for (Object o : s) {
hashCode += o != null ? o.hashCode() : 0;
-
- hashCode = ~~hashCode;
- // Needed to deal with unusual integer overflow in GWT.
}
return hashCode;
}
@@ -1242,47 +1266,117 @@ public final class Sets {
}
/**
- * Remove each element in an iterable from a set.
+ * Creates a view of Set<B> for a Set<A>, given a bijection between A and B.
+ * (Modelled for now as InvertibleFunction<A, B>, can't be Converter<A, B>
+ * because that's not in Guava, though both designs are less than optimal).
+ * Note that the bijection is treated as undefined for values not in the
+ * given Set<A> - it doesn't have to define a true bijection for those.
+ *
+ * <p>Note that the returned Set's contains method is unsafe -
+ * you *must* pass an instance of B to it, since the bijection
+ * can only invert B's (not any Object) back to A, so we can
+ * then delegate the call to the original Set<A>.
*/
- static boolean removeAllImpl(Set<?> set, Iterator<?> iterator) {
- boolean changed = false;
- while (iterator.hasNext()) {
- changed |= set.remove(iterator.next());
+ static <A, B> Set<B> transform(
+ Set<A> set, InvertibleFunction<A, B> bijection) {
+ return new TransformedSet<A, B>(
+ Preconditions.checkNotNull(set, "set"),
+ Preconditions.checkNotNull(bijection, "bijection")
+ );
+ }
+
+ /**
+ * Stop-gap measure since there is no bijection related type in Guava.
+ */
+ abstract static class InvertibleFunction<A, B> implements Function<A, B> {
+ abstract A invert(B b);
+
+ public InvertibleFunction<B, A> inverse() {
+ return new InvertibleFunction<B, A>() {
+ @Override public A apply(B b) {
+ return InvertibleFunction.this.invert(b);
+ }
+
+ @Override B invert(A a) {
+ return InvertibleFunction.this.apply(a);
+ }
+
+ // Not required per se, but just for good karma.
+ @Override public InvertibleFunction<A, B> inverse() {
+ return InvertibleFunction.this;
+ }
+ };
}
- return changed;
}
- static boolean removeAllImpl(Set<?> set, Collection<?> collection) {
- checkNotNull(collection); // for GWT
- if (collection instanceof Multiset) {
- collection = ((Multiset<?>) collection).elementSet();
+ private static class TransformedSet<A, B> extends AbstractSet<B> {
+ final Set<A> delegate;
+ final InvertibleFunction<A, B> bijection;
+
+ TransformedSet(Set<A> delegate, InvertibleFunction<A, B> bijection) {
+ this.delegate = delegate;
+ this.bijection = bijection;
}
- /*
- * AbstractSet.removeAll(List) has quadratic behavior if the list size
- * is just less than the set's size. We augment the test by
- * assuming that sets have fast contains() performance, and other
- * collections don't. See
- * http://code.google.com/p/guava-libraries/issues/detail?id=1013
- */
- if (collection instanceof Set && collection.size() > set.size()) {
- Iterator<?> setIterator = set.iterator();
- boolean changed = false;
- while (setIterator.hasNext()) {
- if (collection.contains(setIterator.next())) {
- changed = true;
- setIterator.remove();
- }
- }
- return changed;
- } else {
- return removeAllImpl(set, collection.iterator());
+
+ @Override public Iterator<B> iterator() {
+ return Iterators.transform(delegate.iterator(), bijection);
+ }
+
+ @Override public int size() {
+ return delegate.size();
+ }
+
+ @SuppressWarnings("unchecked") // unsafe, passed object *must* be B
+ @Override public boolean contains(Object o) {
+ B b = (B) o;
+ A a = bijection.invert(b);
+ /*
+ * Mathematically, Converter<A, B> defines a bijection between ALL A's
+ * on ALL B's. Here we concern ourselves with a subset
+ * of this relation: we only want the part that is defined by a *subset*
+ * of all A's (defined by that Set<A> delegate), and the image
+ * of *that* on B (which is this set). We don't care whether
+ * the converter is *not* a bijection for A's that are not in Set<A>
+ * or B's not in this Set<B>.
+ *
+ * We only want to return true if and only f the user passes a B instance
+ * that is contained in precisely in the image of Set<A>.
+ *
+ * The first test is whether the inverse image of this B is indeed
+ * in Set<A>. But we don't know whether that B belongs in this Set<B>
+ * or not; if not, the converter is free to return
+ * anything it wants, even an element of Set<A> (and this relationship
+ * is not part of the Set<A> <--> Set<B> bijection), and we must not
+ * be confused by that. So we have to do a final check to see if the
+ * image of that A is really equivalent to the passed B, which proves
+ * that the given B belongs indeed in the image of Set<A>.
+ */
+ return delegate.contains(a) && Objects.equal(bijection.apply(a), o);
+ }
+
+ @Override public boolean add(B b) {
+ return delegate.add(bijection.invert(b));
+ }
+
+ @SuppressWarnings("unchecked") // unsafe, passed object *must* be B
+ @Override public boolean remove(Object o) {
+ return contains(o) && delegate.remove(bijection.invert((B) o));
+ }
+
+ @Override public void clear() {
+ delegate.clear();
}
}
/**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
+ * Remove each element in an iterable from a set.
*/
- static <T> SortedSet<T> cast(Iterable<T> iterable) {
- return (SortedSet<T>) iterable;
+ static boolean removeAllImpl(Set<?> set, Iterable<?> iterable) {
+ // TODO(jlevy): Have ForwardingSet.standardRemoveAll() call this method.
+ boolean changed = false;
+ for (Object o : iterable) {
+ changed |= set.remove(o);
+ }
+ return changed;
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableList.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableList.java
index e570f00..6172191 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableList.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableList.java
@@ -17,29 +17,23 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Collections.singletonList;
-import java.util.List;
+import java.util.Collections;
/**
* GWT emulated version of {@link SingletonImmutableList}.
*
* @author Hayward Chan
*/
-final class SingletonImmutableList<E> extends ForwardingImmutableList<E> {
+final class SingletonImmutableList<E> extends ImmutableList<E> {
- final transient List<E> delegate;
// This reference is used both by the custom field serializer, and by the
// GWT compiler to infer the elements of the lists that needs to be
// serialized.
E element;
SingletonImmutableList(E element) {
- this.delegate = singletonList(checkNotNull(element));
+ super(Collections.singletonList(checkNotNull(element)));
this.element = element;
}
-
- @Override List<E> delegateList() {
- return delegate;
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableBiMap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableMap.java
index f086bf3..236d76e 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableBiMap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableMap.java
@@ -21,11 +21,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collections;
/**
- * GWT emulation of {@link SingletonImmutableBiMap}.
+ * GWT emulation of {@link SingletonImmutableMap}.
*
* @author Hayward Chan
*/
-final class SingletonImmutableBiMap<K, V> extends ImmutableBiMap<K, V> {
+final class SingletonImmutableMap<K, V> extends ImmutableMap<K, V> {
// These references are used both by the custom field serializer, and by the
// GWT compiler to infer the keys and values of the map that needs to be
@@ -36,34 +36,9 @@ final class SingletonImmutableBiMap<K, V> extends ImmutableBiMap<K, V> {
K singleKey;
V singleValue;
- transient SingletonImmutableBiMap<V, K> inverse;
-
- SingletonImmutableBiMap(K key, V value) {
+ SingletonImmutableMap(K key, V value) {
super(Collections.singletonMap(checkNotNull(key), checkNotNull(value)));
this.singleKey = key;
this.singleValue = value;
}
-
- private SingletonImmutableBiMap(
- K key, V value, SingletonImmutableBiMap<V, K> inverse) {
- super(Collections.singletonMap(checkNotNull(key), checkNotNull(value)));
- this.singleKey = singleKey;
- this.singleValue = singleValue;
- this.inverse = inverse;
- }
-
- @Override
- public ImmutableBiMap<V, K> inverse() {
- ImmutableBiMap<V, K> result = inverse;
- if (result == null) {
- return inverse = new SingletonImmutableBiMap<V, K>(singleValue, singleKey, this);
- } else {
- return result;
- }
- }
-
- @Override
- public ImmutableSet<V> values() {
- return ImmutableSet.of(singleValue);
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableSet.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableSet.java
index d1aa6b2..b51d4aa 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableSet.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SingletonImmutableSet.java
@@ -18,8 +18,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.UnmodifiableIterator;
+import java.util.Collections;
/**
* GWT emulation of {@link SingletonImmutableSet}.
@@ -27,7 +26,7 @@ import com.google.common.collect.UnmodifiableIterator;
* @author Hayward Chan
*/
final class SingletonImmutableSet<E> extends ImmutableSet<E> {
-
+
// This reference is used both by the custom field serializer, and by the
// GWT compiler to infer the elements of the lists that needs to be
// serialized.
@@ -36,21 +35,7 @@ final class SingletonImmutableSet<E> extends ImmutableSet<E> {
E element;
SingletonImmutableSet(E element) {
- this.element = checkNotNull(element);
- }
-
- @Override
- public int size() {
- return 1;
- }
-
- @Override
- public UnmodifiableIterator<E> iterator() {
- return Iterators.singletonIterator(element);
- }
-
- @Override
- public boolean contains(Object object) {
- return element.equals(object);
+ super(Collections.singleton(checkNotNull(element)));
+ this.element = element;
}
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultiset.java
deleted file mode 100644
index d9248dd..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultiset.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.Beta;
-
-import java.util.Comparator;
-import java.util.SortedSet;
-
-/**
- * GWT emulation of {@code SortedMultiset}, with {@code elementSet} reduced
- * to returning a {@code SortedSet} for GWT compatibility.
- *
- * @author Louis Wasserman
- * @since 11.0
- */
-@Beta
-public interface SortedMultiset<E> extends Multiset<E>, SortedIterable<E> {
- Comparator<? super E> comparator();
-
- Entry<E> firstEntry();
-
- Entry<E> lastEntry();
-
- Entry<E> pollFirstEntry();
-
- Entry<E> pollLastEntry();
-
- /**
- * Returns a {@link SortedSet} view of the distinct elements in this multiset.
- * (Outside GWT, this returns a {@code NavigableSet}.)
- */
- @Override SortedSet<E> elementSet();
-
- SortedMultiset<E> descendingMultiset();
-
- SortedMultiset<E> headMultiset(E upperBound, BoundType boundType);
-
- SortedMultiset<E> subMultiset(E lowerBound, BoundType lowerBoundType,
- E upperBound, BoundType upperBoundType);
-
- SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType);
-}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultisets.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultisets.java
deleted file mode 100644
index e3955b5..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/SortedMultisets.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BoundType.CLOSED;
-import static com.google.common.collect.BoundType.OPEN;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multiset.Entry;
-
-import java.util.Comparator;
-import java.util.NoSuchElementException;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * Provides static utility methods for creating and working with
- * {@link SortedMultiset} instances.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-final class SortedMultisets {
- private SortedMultisets() {
- }
-
- /**
- * A skeleton implementation for {@link SortedMultiset#elementSet}.
- */
- static class ElementSet<E> extends Multisets.ElementSet<E> implements
- SortedSet<E> {
- private final SortedMultiset<E> multiset;
-
- ElementSet(SortedMultiset<E> multiset) {
- this.multiset = multiset;
- }
-
- @Override final SortedMultiset<E> multiset() {
- return multiset;
- }
-
- @Override public Comparator<? super E> comparator() {
- return multiset().comparator();
- }
-
- @Override public SortedSet<E> subSet(E fromElement, E toElement) {
- return multiset().subMultiset(fromElement, CLOSED, toElement, OPEN).elementSet();
- }
-
- @Override public SortedSet<E> headSet(E toElement) {
- return multiset().headMultiset(toElement, OPEN).elementSet();
- }
-
- @Override public SortedSet<E> tailSet(E fromElement) {
- return multiset().tailMultiset(fromElement, CLOSED).elementSet();
- }
-
- @Override public E first() {
- return getElementOrThrow(multiset().firstEntry());
- }
-
- @Override public E last() {
- return getElementOrThrow(multiset().lastEntry());
- }
- }
-
- private static <E> E getElementOrThrow(Entry<E> entry) {
- if (entry == null) {
- throw new NoSuchElementException();
- }
- return entry.getElement();
- }
-
- private static <E> E getElementOrNull(@Nullable Entry<E> entry) {
- return (entry == null) ? null : entry.getElement();
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Synchronized.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Synchronized.java
index c809da8..fd09c97 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Synchronized.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/Synchronized.java
@@ -28,8 +28,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Queue;
import java.util.RandomAccess;
import java.util.Set;
import java.util.SortedMap;
@@ -196,7 +194,7 @@ final class Synchronized {
static class SynchronizedSet<E>
extends SynchronizedCollection<E> implements Set<E> {
-
+
SynchronizedSet(Set<E> delegate, @Nullable Object mutex) {
super(delegate, mutex);
}
@@ -836,7 +834,7 @@ final class Synchronized {
}
@Override public Map.Entry<K, Collection<V>> next() {
- final Map.Entry<K, Collection<V>> entry = super.next();
+ final Map.Entry<K, Collection<V>> entry = iterator.next();
return new ForwardingMapEntry<K, Collection<V>>() {
@Override protected Map.Entry<K, Collection<V>> delegate() {
return entry;
@@ -1028,12 +1026,12 @@ final class Synchronized {
private static final long serialVersionUID = 0;
}
-
+
static <K, V> SortedMap<K, V> sortedMap(
SortedMap<K, V> sortedMap, @Nullable Object mutex) {
return new SynchronizedSortedMap<K, V>(sortedMap, mutex);
}
-
+
static class SynchronizedSortedMap<K, V> extends SynchronizedMap<K, V>
implements SortedMap<K, V> {
@@ -1197,67 +1195,12 @@ final class Synchronized {
return iterator;
}
@Override public Collection<V> next() {
- return typePreservingCollection(super.next(), mutex);
+ return typePreservingCollection(iterator.next(), mutex);
}
};
}
private static final long serialVersionUID = 0;
}
-
- static <E> Queue<E> queue(Queue<E> queue, @Nullable Object mutex) {
- return (queue instanceof SynchronizedQueue)
- ? queue
- : new SynchronizedQueue<E>(queue, mutex);
- }
-
- private static class SynchronizedQueue<E> extends SynchronizedCollection<E>
- implements Queue<E> {
-
- SynchronizedQueue(Queue<E> delegate, @Nullable Object mutex) {
- super(delegate, mutex);
- }
-
- @Override Queue<E> delegate() {
- return (Queue<E>) super.delegate();
- }
-
- @Override
- public E element() {
- synchronized (mutex) {
- return delegate().element();
- }
- }
-
- @Override
- public boolean offer(E e) {
- synchronized (mutex) {
- return delegate().offer(e);
- }
- }
-
- @Override
- public E peek() {
- synchronized (mutex) {
- return delegate().peek();
- }
- }
-
- @Override
- public E poll() {
- synchronized (mutex) {
- return delegate().poll();
- }
- }
-
- @Override
- public E remove() {
- synchronized (mutex) {
- return delegate().remove();
- }
- }
-
- private static final long serialVersionUID = 0;
- }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultimap.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultimap.java
index 5023a0c..228dc2d 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultimap.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultimap.java
@@ -22,12 +22,11 @@ import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
import java.util.Comparator;
+import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
-import javax.annotation.Nullable;
-
/**
* Implementation of {@code Multimap} whose keys and values are ordered by
* their natural ordering or by supplied comparators. In all cases, this
@@ -61,16 +60,11 @@ import javax.annotation.Nullable;
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedSortedSetMultimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Jared Levy
- * @author Louis Wasserman
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(serializable = true, emulated = true)
-public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V> {
+public class TreeMultimap<K, V> extends AbstractSortedSetMultimap<K, V> {
private transient Comparator<? super K> keyComparator;
private transient Comparator<? super V> valueComparator;
@@ -136,14 +130,6 @@ public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V>
return new TreeSet<V>(valueComparator);
}
- @Override
- Collection<V> createCollection(@Nullable K key) {
- if (key == null) {
- keyComparator().compare(key, key);
- }
- return super.createCollection(key);
- }
-
/**
* Returns the comparator that orders the multimap keys.
*/
@@ -156,10 +142,26 @@ public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V>
return valueComparator;
}
- /*
- * The following @GwtIncompatible methods override the methods in
- * AbstractSortedKeySortedSetMultimap, so GWT will fall back to the ASKSSM implementations,
- * which return SortedSets and SortedMaps.
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code TreeMultimap} has unique sorted keys, this method
+ * returns a {@link SortedSet}, instead of the {@link java.util.Set} specified
+ * in the {@link Multimap} interface.
*/
+ @Override public SortedSet<K> keySet() {
+ return (SortedSet<K>) super.keySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Because a {@code TreeMultimap} has unique sorted keys, this method
+ * returns a {@link SortedMap}, instead of the {@link java.util.Map} specified
+ * in the {@link Multimap} interface.
+ */
+ @Override public SortedMap<K, Collection<V>> asMap() {
+ return (SortedMap<K, Collection<V>>) super.asMap();
+ }
}
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultiset.java
index b45d127..622454d 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultiset.java
+++ b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/TreeMultiset.java
@@ -17,217 +17,168 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Objects;
-import com.google.common.primitives.Ints;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
import java.io.Serializable;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
-import java.util.NoSuchElementException;
import javax.annotation.Nullable;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.primitives.Ints;
+
/**
- * A multiset which maintains the ordering of its elements, according to either their natural order
- * or an explicit {@link Comparator}. In all cases, this implementation uses
- * {@link Comparable#compareTo} or {@link Comparator#compare} instead of {@link Object#equals} to
- * determine equivalence of instances.
+ * A multiset which maintains the ordering of its elements, according to either
+ * their natural order or an explicit {@link Comparator}. In all cases, this
+ * implementation uses {@link Comparable#compareTo} or {@link
+ * Comparator#compare} instead of {@link Object#equals} to determine
+ * equivalence of instances.
*
- * <p><b>Warning:</b> The comparison must be <i>consistent with equals</i> as explained by the
- * {@link Comparable} class specification. Otherwise, the resulting multiset will violate the
- * {@link java.util.Collection} contract, which is specified in terms of {@link Object#equals}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
+ * <p><b>Warning:</b> The comparison must be <i>consistent with equals</i> as
+ * explained by the {@link Comparable} class specification. Otherwise, the
+ * resulting multiset will violate the {@link java.util.Collection} contract,
+ * which is specified in terms of {@link Object#equals}.
*
* @author Louis Wasserman
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(emulated = true)
-public final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements Serializable {
+public final class TreeMultiset<E> extends AbstractSortedMultiset<E>
+ implements Serializable {
/**
- * Creates a new, empty multiset, sorted according to the elements' natural order. All elements
- * inserted into the multiset must implement the {@code Comparable} interface. Furthermore, all
- * such elements must be <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
- * {@code ClassCastException} for any elements {@code e1} and {@code e2} in the multiset. If the
- * user attempts to add an element to the multiset that violates this constraint (for example,
- * the user attempts to add a string element to a set whose elements are integers), the
- * {@code add(Object)} call will throw a {@code ClassCastException}.
+ * Creates a new, empty multiset, sorted according to the elements' natural
+ * order. All elements inserted into the multiset must implement the
+ * {@code Comparable} interface. Furthermore, all such elements must be
+ * <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
+ * {@code ClassCastException} for any elements {@code e1} and {@code e2} in
+ * the multiset. If the user attempts to add an element to the multiset that
+ * violates this constraint (for example, the user attempts to add a string
+ * element to a set whose elements are integers), the {@code add(Object)}
+ * call will throw a {@code ClassCastException}.
*
- * <p>The type specification is {@code <E extends Comparable>}, instead of the more specific
- * {@code <E extends Comparable<? super E>>}, to support classes defined without generics.
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
*/
public static <E extends Comparable> TreeMultiset<E> create() {
return new TreeMultiset<E>(Ordering.natural());
}
/**
- * Creates a new, empty multiset, sorted according to the specified comparator. All elements
- * inserted into the multiset must be <i>mutually comparable</i> by the specified comparator:
- * {@code comparator.compare(e1,
- * e2)} must not throw a {@code ClassCastException} for any elements {@code e1} and {@code e2} in
- * the multiset. If the user attempts to add an element to the multiset that violates this
- * constraint, the {@code add(Object)} call will throw a {@code ClassCastException}.
+ * Creates a new, empty multiset, sorted according to the specified
+ * comparator. All elements inserted into the multiset must be <i>mutually
+ * comparable</i> by the specified comparator: {@code comparator.compare(e1,
+ * e2)} must not throw a {@code ClassCastException} for any elements {@code
+ * e1} and {@code e2} in the multiset. If the user attempts to add an element
+ * to the multiset that violates this constraint, the {@code add(Object)} call
+ * will throw a {@code ClassCastException}.
*
- * @param comparator
- * the comparator that will be used to sort this multiset. A null value indicates that
- * the elements' <i>natural ordering</i> should be used.
+ * @param comparator the comparator that will be used to sort this multiset. A
+ * null value indicates that the elements' <i>natural ordering</i> should
+ * be used.
*/
@SuppressWarnings("unchecked")
- public static <E> TreeMultiset<E> create(@Nullable Comparator<? super E> comparator) {
+ public static <E> TreeMultiset<E> create(
+ @Nullable Comparator<? super E> comparator) {
return (comparator == null)
- ? new TreeMultiset<E>((Comparator) Ordering.natural())
- : new TreeMultiset<E>(comparator);
+ ? new TreeMultiset<E>((Comparator) Ordering.natural())
+ : new TreeMultiset<E>(comparator);
}
/**
- * Creates an empty multiset containing the given initial elements, sorted according to the
- * elements' natural order.
+ * Creates an empty multiset containing the given initial elements, sorted
+ * according to the elements' natural order.
*
- * <p>This implementation is highly efficient when {@code elements} is itself a {@link Multiset}.
+ * <p>This implementation is highly efficient when {@code elements} is itself
+ * a {@link Multiset}.
*
- * <p>The type specification is {@code <E extends Comparable>}, instead of the more specific
- * {@code <E extends Comparable<? super E>>}, to support classes defined without generics.
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
*/
- public static <E extends Comparable> TreeMultiset<E> create(Iterable<? extends E> elements) {
+ public static <E extends Comparable> TreeMultiset<E> create(
+ Iterable<? extends E> elements) {
TreeMultiset<E> multiset = create();
Iterables.addAll(multiset, elements);
return multiset;
}
- private final transient Reference<AvlNode<E>> rootReference;
- private final transient GeneralRange<E> range;
- private final transient AvlNode<E> header;
-
- TreeMultiset(Reference<AvlNode<E>> rootReference, GeneralRange<E> range, AvlNode<E> endLink) {
- super(range.comparator());
- this.rootReference = rootReference;
- this.range = range;
- this.header = endLink;
+ /**
+ * Returns an iterator over the elements contained in this collection.
+ */
+ @Override
+ public Iterator<E> iterator() {
+ // Needed to avoid Javadoc bug.
+ return super.iterator();
}
- TreeMultiset(Comparator<? super E> comparator) {
+ private TreeMultiset(Comparator<? super E> comparator) {
super(comparator);
this.range = GeneralRange.all(comparator);
- this.header = new AvlNode<E>(null, 1);
- successor(header, header);
- this.rootReference = new Reference<AvlNode<E>>();
+ this.rootReference = new Reference<Node<E>>();
}
- /**
- * A function which can be summed across a subtree.
- */
- private enum Aggregate {
- SIZE {
- @Override
- int nodeAggregate(AvlNode<?> node) {
- return node.elemCount;
- }
+ private TreeMultiset(GeneralRange<E> range, Reference<Node<E>> root) {
+ super(range.comparator());
+ this.range = range;
+ this.rootReference = root;
+ }
- @Override
- long treeAggregate(@Nullable AvlNode<?> root) {
- return (root == null) ? 0 : root.totalCount;
- }
- },
- DISTINCT {
- @Override
- int nodeAggregate(AvlNode<?> node) {
- return 1;
- }
+ @SuppressWarnings("unchecked")
+ E checkElement(Object o) {
+ return (E) o;
+ }
- @Override
- long treeAggregate(@Nullable AvlNode<?> root) {
- return (root == null) ? 0 : root.distinctElements;
- }
- };
- abstract int nodeAggregate(AvlNode<?> node);
+ private transient final GeneralRange<E> range;
- abstract long treeAggregate(@Nullable AvlNode<?> root);
- }
+ private transient final Reference<Node<E>> rootReference;
- private long aggregateForEntries(Aggregate aggr) {
- AvlNode<E> root = rootReference.get();
- long total = aggr.treeAggregate(root);
- if (range.hasLowerBound()) {
- total -= aggregateBelowRange(aggr, root);
- }
- if (range.hasUpperBound()) {
- total -= aggregateAboveRange(aggr, root);
- }
- return total;
- }
+ static final class Reference<T> {
+ T value;
- private long aggregateBelowRange(Aggregate aggr, @Nullable AvlNode<E> node) {
- if (node == null) {
- return 0;
- }
- int cmp = comparator().compare(range.getLowerEndpoint(), node.elem);
- if (cmp < 0) {
- return aggregateBelowRange(aggr, node.left);
- } else if (cmp == 0) {
- switch (range.getLowerBoundType()) {
- case OPEN:
- return aggr.nodeAggregate(node) + aggr.treeAggregate(node.left);
- case CLOSED:
- return aggr.treeAggregate(node.left);
- default:
- throw new AssertionError();
- }
- } else {
- return aggr.treeAggregate(node.left) + aggr.nodeAggregate(node)
- + aggregateBelowRange(aggr, node.right);
- }
- }
+ public Reference() {}
- private long aggregateAboveRange(Aggregate aggr, @Nullable AvlNode<E> node) {
- if (node == null) {
- return 0;
+ public T get() {
+ return value;
}
- int cmp = comparator().compare(range.getUpperEndpoint(), node.elem);
- if (cmp > 0) {
- return aggregateAboveRange(aggr, node.right);
- } else if (cmp == 0) {
- switch (range.getUpperBoundType()) {
- case OPEN:
- return aggr.nodeAggregate(node) + aggr.treeAggregate(node.right);
- case CLOSED:
- return aggr.treeAggregate(node.right);
- default:
- throw new AssertionError();
+
+ public boolean compareAndSet(T expected, T newValue) {
+ if (value == expected) {
+ value = newValue;
+ return true;
}
- } else {
- return aggr.treeAggregate(node.right) + aggr.nodeAggregate(node)
- + aggregateAboveRange(aggr, node.left);
+ return false;
}
}
@Override
- public int size() {
- return Ints.saturatedCast(aggregateForEntries(Aggregate.SIZE));
+ int distinctElements() {
+ Node<E> root = rootReference.get();
+ return Ints.checkedCast(BstRangeOps.totalInRange(distinctAggregate(), range, root));
}
@Override
- int distinctElements() {
- return Ints.saturatedCast(aggregateForEntries(Aggregate.DISTINCT));
+ public int size() {
+ Node<E> root = rootReference.get();
+ return Ints.saturatedCast(BstRangeOps.totalInRange(sizeAggregate(), range, root));
}
@Override
public int count(@Nullable Object element) {
try {
- @SuppressWarnings("unchecked")
- E e = (E) element;
- AvlNode<E> root = rootReference.get();
- if (!range.contains(e) || root == null) {
- return 0;
+ E e = checkElement(element);
+ if (range.contains(e)) {
+ Node<E> node = BstOperations.seek(comparator(), rootReference.get(), e);
+ return countOrZero(node);
}
- return root.count(comparator(), e);
+ return 0;
} catch (ClassCastException e) {
return 0;
} catch (NullPointerException e) {
@@ -235,713 +186,354 @@ public final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements
}
}
+ private int mutate(@Nullable E e, MultisetModifier modifier) {
+ BstMutationRule<E, Node<E>> mutationRule = BstMutationRule.createRule(
+ modifier,
+ BstCountBasedBalancePolicies.
+ <E, Node<E>>singleRebalancePolicy(distinctAggregate()),
+ nodeFactory());
+ BstMutationResult<E, Node<E>> mutationResult =
+ BstOperations.mutate(comparator(), mutationRule, rootReference.get(), e);
+ if (!rootReference.compareAndSet(
+ mutationResult.getOriginalRoot(), mutationResult.getChangedRoot())) {
+ throw new ConcurrentModificationException();
+ }
+ Node<E> original = mutationResult.getOriginalTarget();
+ return countOrZero(original);
+ }
+
@Override
- public int add(@Nullable E element, int occurrences) {
- checkArgument(occurrences >= 0, "occurrences must be >= 0 but was %s", occurrences);
+ public int add(E element, int occurrences) {
+ checkElement(element);
if (occurrences == 0) {
return count(element);
}
checkArgument(range.contains(element));
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- comparator().compare(element, element);
- AvlNode<E> newRoot = new AvlNode<E>(element, occurrences);
- successor(header, newRoot, header);
- rootReference.checkAndSet(root, newRoot);
- return 0;
- }
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot = root.add(comparator(), element, occurrences, result);
- rootReference.checkAndSet(root, newRoot);
- return result[0];
+ return mutate(element, new AddModifier(occurrences));
}
@Override
public int remove(@Nullable Object element, int occurrences) {
- checkArgument(occurrences >= 0, "occurrences must be >= 0 but was %s", occurrences);
- if (occurrences == 0) {
+ if (element == null) {
+ return 0;
+ } else if (occurrences == 0) {
return count(element);
}
- AvlNode<E> root = rootReference.get();
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot;
try {
- @SuppressWarnings("unchecked")
- E e = (E) element;
- if (!range.contains(e) || root == null) {
- return 0;
- }
- newRoot = root.remove(comparator(), e, occurrences, result);
+ E e = checkElement(element);
+ return range.contains(e) ? mutate(e, new RemoveModifier(occurrences)) : 0;
} catch (ClassCastException e) {
return 0;
- } catch (NullPointerException e) {
- return 0;
}
- rootReference.checkAndSet(root, newRoot);
- return result[0];
}
@Override
- public int setCount(@Nullable E element, int count) {
- checkArgument(count >= 0);
- if (!range.contains(element)) {
- checkArgument(count == 0);
- return 0;
- }
-
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- if (count > 0) {
- add(element, count);
- }
- return 0;
- }
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot = root.setCount(comparator(), element, count, result);
- rootReference.checkAndSet(root, newRoot);
- return result[0];
+ public boolean setCount(E element, int oldCount, int newCount) {
+ checkElement(element);
+ checkArgument(range.contains(element));
+ return mutate(element, new ConditionalSetCountModifier(oldCount, newCount))
+ == oldCount;
}
@Override
- public boolean setCount(@Nullable E element, int oldCount, int newCount) {
- checkArgument(newCount >= 0);
- checkArgument(oldCount >= 0);
+ public int setCount(E element, int count) {
+ checkElement(element);
checkArgument(range.contains(element));
-
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- if (oldCount == 0) {
- if (newCount > 0) {
- add(element, newCount);
- }
- return true;
- } else {
- return false;
- }
- }
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot = root.setCount(comparator(), element, oldCount, newCount, result);
- rootReference.checkAndSet(root, newRoot);
- return result[0] == oldCount;
+ return mutate(element, new SetCountModifier(count));
}
- private Entry<E> wrapEntry(final AvlNode<E> baseEntry) {
- return new Multisets.AbstractEntry<E>() {
- @Override
- public E getElement() {
- return baseEntry.getElement();
- }
-
- @Override
- public int getCount() {
- int result = baseEntry.getCount();
- if (result == 0) {
- return count(getElement());
- } else {
- return result;
- }
- }
- };
+ private BstPathFactory<Node<E>, BstInOrderPath<Node<E>>> pathFactory() {
+ return BstInOrderPath.inOrderFactory();
}
- /**
- * Returns the first node in the tree that is in range.
- */
- @Nullable private AvlNode<E> firstNode() {
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- return null;
- }
- AvlNode<E> node;
- if (range.hasLowerBound()) {
- E endpoint = range.getLowerEndpoint();
- node = rootReference.get().ceiling(comparator(), endpoint);
- if (node == null) {
- return null;
- }
- if (range.getLowerBoundType() == BoundType.OPEN
- && comparator().compare(endpoint, node.getElement()) == 0) {
- node = node.succ;
- }
- } else {
- node = header.succ;
- }
- return (node == header || !range.contains(node.getElement())) ? null : node;
+ @Override
+ Iterator<Entry<E>> entryIterator() {
+ Node<E> root = rootReference.get();
+ final BstInOrderPath<Node<E>> startingPath =
+ BstRangeOps.furthestPath(range, LEFT, pathFactory(), root);
+ return iteratorInDirection(startingPath, RIGHT);
}
- @Nullable private AvlNode<E> lastNode() {
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- return null;
- }
- AvlNode<E> node;
- if (range.hasUpperBound()) {
- E endpoint = range.getUpperEndpoint();
- node = rootReference.get().floor(comparator(), endpoint);
- if (node == null) {
- return null;
- }
- if (range.getUpperBoundType() == BoundType.OPEN
- && comparator().compare(endpoint, node.getElement()) == 0) {
- node = node.pred;
- }
- } else {
- node = header.pred;
- }
- return (node == header || !range.contains(node.getElement())) ? null : node;
+ @Override
+ Iterator<Entry<E>> descendingEntryIterator() {
+ Node<E> root = rootReference.get();
+ final BstInOrderPath<Node<E>> startingPath =
+ BstRangeOps.furthestPath(range, RIGHT, pathFactory(), root);
+ return iteratorInDirection(startingPath, LEFT);
}
- @Override
- Iterator<Entry<E>> entryIterator() {
+ private Iterator<Entry<E>> iteratorInDirection(
+ @Nullable BstInOrderPath<Node<E>> start, final BstSide direction) {
+ final Iterator<BstInOrderPath<Node<E>>> pathIterator =
+ new AbstractLinkedIterator<BstInOrderPath<Node<E>>>(start) {
+ @Override
+ protected BstInOrderPath<Node<E>> computeNext(BstInOrderPath<Node<E>> previous) {
+ if (!previous.hasNext(direction)) {
+ return null;
+ }
+ BstInOrderPath<Node<E>> next = previous.next(direction);
+ // TODO(user): only check against one side
+ return range.contains(next.getTip().getKey()) ? next : null;
+ }
+ };
return new Iterator<Entry<E>>() {
- AvlNode<E> current = firstNode();
- Entry<E> prevEntry;
+ E toRemove = null;
@Override
public boolean hasNext() {
- if (current == null) {
- return false;
- } else if (range.tooHigh(current.getElement())) {
- current = null;
- return false;
- } else {
- return true;
- }
+ return pathIterator.hasNext();
}
@Override
public Entry<E> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- Entry<E> result = wrapEntry(current);
- prevEntry = result;
- if (current.succ == header) {
- current = null;
- } else {
- current = current.succ;
- }
- return result;
+ BstInOrderPath<Node<E>> path = pathIterator.next();
+ return new LiveEntry(
+ toRemove = path.getTip().getKey(), path.getTip().elemCount());
}
@Override
public void remove() {
- checkState(prevEntry != null);
- setCount(prevEntry.getElement(), 0);
- prevEntry = null;
+ checkState(toRemove != null);
+ setCount(toRemove, 0);
+ toRemove = null;
}
};
}
- @Override
- Iterator<Entry<E>> descendingEntryIterator() {
- return new Iterator<Entry<E>>() {
- AvlNode<E> current = lastNode();
- Entry<E> prevEntry = null;
+ class LiveEntry extends Multisets.AbstractEntry<E> {
+ private Node<E> expectedRoot;
+ private final E element;
+ private int count;
- @Override
- public boolean hasNext() {
- if (current == null) {
- return false;
- } else if (range.tooLow(current.getElement())) {
- current = null;
- return false;
- } else {
- return true;
- }
- }
+ private LiveEntry(E element, int count) {
+ this.expectedRoot = rootReference.get();
+ this.element = element;
+ this.count = count;
+ }
- @Override
- public Entry<E> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- Entry<E> result = wrapEntry(current);
- prevEntry = result;
- if (current.pred == header) {
- current = null;
- } else {
- current = current.pred;
- }
- return result;
- }
+ @Override
+ public E getElement() {
+ return element;
+ }
- @Override
- public void remove() {
- checkState(prevEntry != null);
- setCount(prevEntry.getElement(), 0);
- prevEntry = null;
+ @Override
+ public int getCount() {
+ if (rootReference.get() == expectedRoot) {
+ return count;
+ } else {
+ // check for updates
+ expectedRoot = rootReference.get();
+ return count = TreeMultiset.this.count(element);
}
- };
+ }
}
@Override
- public SortedMultiset<E> headMultiset(@Nullable E upperBound, BoundType boundType) {
- return new TreeMultiset<E>(rootReference, range.intersect(GeneralRange.upTo(
- comparator(),
- upperBound,
- boundType)), header);
+ public void clear() {
+ Node<E> root = rootReference.get();
+ Node<E> cleared = BstRangeOps.minusRange(range,
+ BstCountBasedBalancePolicies.<E, Node<E>>fullRebalancePolicy(distinctAggregate()),
+ nodeFactory(), root);
+ if (!rootReference.compareAndSet(root, cleared)) {
+ throw new ConcurrentModificationException();
+ }
}
@Override
- public SortedMultiset<E> tailMultiset(@Nullable E lowerBound, BoundType boundType) {
- return new TreeMultiset<E>(rootReference, range.intersect(GeneralRange.downTo(
- comparator(),
- lowerBound,
- boundType)), header);
+ public SortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
+ checkNotNull(upperBound);
+ return new TreeMultiset<E>(
+ range.intersect(GeneralRange.upTo(comparator, upperBound, boundType)), rootReference);
}
- static int distinctElements(@Nullable AvlNode<?> node) {
- return (node == null) ? 0 : node.distinctElements;
+ @Override
+ public SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
+ checkNotNull(lowerBound);
+ return new TreeMultiset<E>(
+ range.intersect(GeneralRange.downTo(comparator, lowerBound, boundType)), rootReference);
}
- private static final class Reference<T> {
- @Nullable private T value;
-
- @Nullable public T get() {
- return value;
- }
-
- public void checkAndSet(@Nullable T expected, T newValue) {
- if (value != expected) {
- throw new ConcurrentModificationException();
- }
- value = newValue;
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @since 11.0
+ */
+ @Override
+ public Comparator<? super E> comparator() {
+ return super.comparator();
}
- private static final class AvlNode<E> extends Multisets.AbstractEntry<E> {
- @Nullable private final E elem;
+ private static final class Node<E> extends BstNode<E, Node<E>> implements Serializable {
+ private final long size;
+ private final int distinct;
- // elemCount is 0 iff this node has been deleted.
- private int elemCount;
-
- private int distinctElements;
- private long totalCount;
- private int height;
- private AvlNode<E> left;
- private AvlNode<E> right;
- private AvlNode<E> pred;
- private AvlNode<E> succ;
-
- AvlNode(@Nullable E elem, int elemCount) {
+ private Node(E key, int elemCount, @Nullable Node<E> left,
+ @Nullable Node<E> right) {
+ super(key, left, right);
checkArgument(elemCount > 0);
- this.elem = elem;
- this.elemCount = elemCount;
- this.totalCount = elemCount;
- this.distinctElements = 1;
- this.height = 1;
- this.left = null;
- this.right = null;
- }
-
- public int count(Comparator<? super E> comparator, E e) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- return (left == null) ? 0 : left.count(comparator, e);
- } else if (cmp > 0) {
- return (right == null) ? 0 : right.count(comparator, e);
- } else {
- return elemCount;
- }
- }
-
- private AvlNode<E> addRightChild(E e, int count) {
- right = new AvlNode<E>(e, count);
- successor(this, right, succ);
- height = Math.max(2, height);
- distinctElements++;
- totalCount += count;
- return this;
+ this.size = (long) elemCount + sizeOrZero(left) + sizeOrZero(right);
+ this.distinct = 1 + distinctOrZero(left) + distinctOrZero(right);
}
- private AvlNode<E> addLeftChild(E e, int count) {
- left = new AvlNode<E>(e, count);
- successor(pred, left, this);
- height = Math.max(2, height);
- distinctElements++;
- totalCount += count;
- return this;
+ int elemCount() {
+ long result = size - sizeOrZero(childOrNull(LEFT))
+ - sizeOrZero(childOrNull(RIGHT));
+ return Ints.checkedCast(result);
}
- AvlNode<E> add(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
- /*
- * It speeds things up considerably to unconditionally add count to totalCount here,
- * but that destroys failure atomicity in the case of count overflow. =(
- */
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- return addLeftChild(e, count);
- }
- int initHeight = initLeft.height;
-
- left = initLeft.add(comparator, e, count, result);
- if (result[0] == 0) {
- distinctElements++;
- }
- this.totalCount += count;
- return (left.height == initHeight) ? this : rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- return addRightChild(e, count);
- }
- int initHeight = initRight.height;
-
- right = initRight.add(comparator, e, count, result);
- if (result[0] == 0) {
- distinctElements++;
- }
- this.totalCount += count;
- return (right.height == initHeight) ? this : rebalance();
- }
-
- // adding count to me! No rebalance possible.
- result[0] = elemCount;
- long resultCount = (long) elemCount + count;
- checkArgument(resultCount <= Integer.MAX_VALUE);
- this.elemCount += count;
- this.totalCount += count;
- return this;
+ private Node(E key, int elemCount) {
+ this(key, elemCount, null, null);
}
- AvlNode<E> remove(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- return this;
- }
+ private static final long serialVersionUID = 0;
+ }
- left = initLeft.remove(comparator, e, count, result);
+ private static long sizeOrZero(@Nullable Node<?> node) {
+ return (node == null) ? 0 : node.size;
+ }
- if (result[0] > 0) {
- if (count >= result[0]) {
- this.distinctElements--;
- this.totalCount -= result[0];
- } else {
- this.totalCount -= count;
- }
- }
- return (result[0] == 0) ? this : rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- return this;
- }
+ private static int distinctOrZero(@Nullable Node<?> node) {
+ return (node == null) ? 0 : node.distinct;
+ }
- right = initRight.remove(comparator, e, count, result);
+ private static int countOrZero(@Nullable Node<?> entry) {
+ return (entry == null) ? 0 : entry.elemCount();
+ }
- if (result[0] > 0) {
- if (count >= result[0]) {
- this.distinctElements--;
- this.totalCount -= result[0];
- } else {
- this.totalCount -= count;
- }
- }
- return rebalance();
- }
+ @SuppressWarnings("unchecked")
+ private BstAggregate<Node<E>> distinctAggregate() {
+ return (BstAggregate) DISTINCT_AGGREGATE;
+ }
- // removing count from me!
- result[0] = elemCount;
- if (count >= elemCount) {
- return deleteMe();
- } else {
- this.elemCount -= count;
- this.totalCount -= count;
- return this;
- }
+ private static final BstAggregate<Node<Object>> DISTINCT_AGGREGATE =
+ new BstAggregate<Node<Object>>() {
+ @Override
+ public int entryValue(Node<Object> entry) {
+ return 1;
}
- AvlNode<E> setCount(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- return (count > 0) ? addLeftChild(e, count) : this;
- }
-
- left = initLeft.setCount(comparator, e, count, result);
-
- if (count == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (count > 0 && result[0] == 0) {
- this.distinctElements++;
- }
-
- this.totalCount += count - result[0];
- return rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- return (count > 0) ? addRightChild(e, count) : this;
- }
-
- right = initRight.setCount(comparator, e, count, result);
-
- if (count == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (count > 0 && result[0] == 0) {
- this.distinctElements++;
- }
-
- this.totalCount += count - result[0];
- return rebalance();
- }
-
- // setting my count
- result[0] = elemCount;
- if (count == 0) {
- return deleteMe();
- }
- this.totalCount += count - elemCount;
- this.elemCount = count;
- return this;
+ @Override
+ public long treeValue(@Nullable Node<Object> tree) {
+ return distinctOrZero(tree);
}
+ };
- AvlNode<E> setCount(
- Comparator<? super E> comparator,
- @Nullable E e,
- int expectedCount,
- int newCount,
- int[] result) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- if (expectedCount == 0 && newCount > 0) {
- return addLeftChild(e, newCount);
- }
- return this;
- }
-
- left = initLeft.setCount(comparator, e, expectedCount, newCount, result);
+ @SuppressWarnings("unchecked")
+ private BstAggregate<Node<E>> sizeAggregate() {
+ return (BstAggregate) SIZE_AGGREGATE;
+ }
- if (result[0] == expectedCount) {
- if (newCount == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (newCount > 0 && result[0] == 0) {
- this.distinctElements++;
- }
- this.totalCount += newCount - result[0];
- }
- return rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- if (expectedCount == 0 && newCount > 0) {
- return addRightChild(e, newCount);
- }
- return this;
+ private static final BstAggregate<Node<Object>> SIZE_AGGREGATE =
+ new BstAggregate<Node<Object>>() {
+ @Override
+ public int entryValue(Node<Object> entry) {
+ return entry.elemCount();
}
- right = initRight.setCount(comparator, e, expectedCount, newCount, result);
-
- if (result[0] == expectedCount) {
- if (newCount == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (newCount > 0 && result[0] == 0) {
- this.distinctElements++;
- }
- this.totalCount += newCount - result[0];
+ @Override
+ public long treeValue(@Nullable Node<Object> tree) {
+ return sizeOrZero(tree);
}
- return rebalance();
- }
+ };
- // setting my count
- result[0] = elemCount;
- if (expectedCount == elemCount) {
- if (newCount == 0) {
- return deleteMe();
- }
- this.totalCount += newCount - elemCount;
- this.elemCount = newCount;
- }
- return this;
- }
+ @SuppressWarnings("unchecked")
+ private BstNodeFactory<Node<E>> nodeFactory() {
+ return (BstNodeFactory) NODE_FACTORY;
+ }
- private AvlNode<E> deleteMe() {
- int oldElemCount = this.elemCount;
- this.elemCount = 0;
- successor(pred, succ);
- if (left == null) {
- return right;
- } else if (right == null) {
- return left;
- } else if (left.height >= right.height) {
- AvlNode<E> newTop = pred;
- // newTop is the maximum node in my left subtree
- newTop.left = left.removeMax(newTop);
- newTop.right = right;
- newTop.distinctElements = distinctElements - 1;
- newTop.totalCount = totalCount - oldElemCount;
- return newTop.rebalance();
- } else {
- AvlNode<E> newTop = succ;
- newTop.right = right.removeMin(newTop);
- newTop.left = left;
- newTop.distinctElements = distinctElements - 1;
- newTop.totalCount = totalCount - oldElemCount;
- return newTop.rebalance();
- }
- }
+ private static final BstNodeFactory<Node<Object>> NODE_FACTORY =
+ new BstNodeFactory<Node<Object>>() {
+ @Override
+ public Node<Object> createNode(Node<Object> source, @Nullable Node<Object> left,
+ @Nullable Node<Object> right) {
+ return new Node<Object>(source.getKey(), source.elemCount(), left, right);
+ }
+ };
- // Removes the minimum node from this subtree to be reused elsewhere
- private AvlNode<E> removeMin(AvlNode<E> node) {
- if (left == null) {
- return right;
- } else {
- left = left.removeMin(node);
- distinctElements--;
- totalCount -= node.elemCount;
- return rebalance();
- }
- }
+ private abstract class MultisetModifier implements BstModifier<E, Node<E>> {
+ abstract int newCount(int oldCount);
- // Removes the maximum node from this subtree to be reused elsewhere
- private AvlNode<E> removeMax(AvlNode<E> node) {
- if (right == null) {
- return left;
+ @Nullable
+ @Override
+ public BstModificationResult<Node<E>> modify(E key, @Nullable Node<E> originalEntry) {
+ int oldCount = countOrZero(originalEntry);
+ int newCount = newCount(oldCount);
+ if (oldCount == newCount) {
+ return BstModificationResult.identity(originalEntry);
+ } else if (newCount == 0) {
+ return BstModificationResult.rebalancingChange(originalEntry, null);
+ } else if (oldCount == 0) {
+ return BstModificationResult.rebalancingChange(null, new Node<E>(key, newCount));
} else {
- right = right.removeMax(node);
- distinctElements--;
- totalCount -= node.elemCount;
- return rebalance();
+ return BstModificationResult.rebuildingChange(originalEntry,
+ new Node<E>(originalEntry.getKey(), newCount));
}
}
+ }
- private void recomputeMultiset() {
- this.distinctElements = 1 + TreeMultiset.distinctElements(left)
- + TreeMultiset.distinctElements(right);
- this.totalCount = elemCount + totalCount(left) + totalCount(right);
- }
-
- private void recomputeHeight() {
- this.height = 1 + Math.max(height(left), height(right));
- }
-
- private void recompute() {
- recomputeMultiset();
- recomputeHeight();
- }
+ private final class AddModifier extends MultisetModifier {
+ private final int countToAdd;
- private AvlNode<E> rebalance() {
- switch (balanceFactor()) {
- case -2:
- if (right.balanceFactor() > 0) {
- right = right.rotateRight();
- }
- return rotateLeft();
- case 2:
- if (left.balanceFactor() < 0) {
- left = left.rotateLeft();
- }
- return rotateRight();
- default:
- recomputeHeight();
- return this;
- }
+ private AddModifier(int countToAdd) {
+ checkArgument(countToAdd > 0);
+ this.countToAdd = countToAdd;
}
- private int balanceFactor() {
- return height(left) - height(right);
+ @Override
+ int newCount(int oldCount) {
+ checkArgument(countToAdd <= Integer.MAX_VALUE - oldCount, "Cannot add this many elements");
+ return oldCount + countToAdd;
}
+ }
- private AvlNode<E> rotateLeft() {
- checkState(right != null);
- AvlNode<E> newTop = right;
- this.right = newTop.left;
- newTop.left = this;
- newTop.totalCount = this.totalCount;
- newTop.distinctElements = this.distinctElements;
- this.recompute();
- newTop.recomputeHeight();
- return newTop;
- }
+ private final class RemoveModifier extends MultisetModifier {
+ private final int countToRemove;
- private AvlNode<E> rotateRight() {
- checkState(left != null);
- AvlNode<E> newTop = left;
- this.left = newTop.right;
- newTop.right = this;
- newTop.totalCount = this.totalCount;
- newTop.distinctElements = this.distinctElements;
- this.recompute();
- newTop.recomputeHeight();
- return newTop;
+ private RemoveModifier(int countToRemove) {
+ checkArgument(countToRemove > 0);
+ this.countToRemove = countToRemove;
}
- private static long totalCount(@Nullable AvlNode<?> node) {
- return (node == null) ? 0 : node.totalCount;
+ @Override
+ int newCount(int oldCount) {
+ return Math.max(0, oldCount - countToRemove);
}
+ }
- private static int height(@Nullable AvlNode<?> node) {
- return (node == null) ? 0 : node.height;
- }
+ private final class SetCountModifier extends MultisetModifier {
+ private final int countToSet;
- @Nullable private AvlNode<E> ceiling(Comparator<? super E> comparator, E e) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- return (left == null) ? this : Objects.firstNonNull(left.ceiling(comparator, e), this);
- } else if (cmp == 0) {
- return this;
- } else {
- return (right == null) ? null : right.ceiling(comparator, e);
- }
- }
-
- @Nullable private AvlNode<E> floor(Comparator<? super E> comparator, E e) {
- int cmp = comparator.compare(e, elem);
- if (cmp > 0) {
- return (right == null) ? this : Objects.firstNonNull(right.floor(comparator, e), this);
- } else if (cmp == 0) {
- return this;
- } else {
- return (left == null) ? null : left.floor(comparator, e);
- }
+ private SetCountModifier(int countToSet) {
+ checkArgument(countToSet >= 0);
+ this.countToSet = countToSet;
}
@Override
- public E getElement() {
- return elem;
+ int newCount(int oldCount) {
+ return countToSet;
}
+ }
- @Override
- public int getCount() {
- return elemCount;
+ private final class ConditionalSetCountModifier extends MultisetModifier {
+ private final int expectedCount;
+ private final int setCount;
+
+ private ConditionalSetCountModifier(int expectedCount, int setCount) {
+ checkArgument(setCount >= 0 & expectedCount >= 0);
+ this.expectedCount = expectedCount;
+ this.setCount = setCount;
}
@Override
- public String toString() {
- return Multisets.immutableEntry(getElement(), getCount()).toString();
+ int newCount(int oldCount) {
+ return (oldCount == expectedCount) ? setCount : oldCount;
}
}
- private static <T> void successor(AvlNode<T> a, AvlNode<T> b) {
- a.succ = b;
- b.pred = a;
- }
-
- private static <T> void successor(AvlNode<T> a, AvlNode<T> b, AvlNode<T> c) {
- successor(a, b);
- successor(b, c);
- }
-
/*
- * TODO(jlevy): Decide whether entrySet() should return entries with an equals() method that
- * calls the comparator to compare the two keys. If that change is made,
- * AbstractMultiset.equals() can simply check whether two multisets have equal entry sets.
+ * TODO(jlevy): Decide whether entrySet() should return entries with an
+ * equals() method that calls the comparator to compare the two keys. If that
+ * change is made, AbstractMultiset.equals() can simply check whether two
+ * multisets have equal entry sets.
*/
}
-
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/UnmodifiableSortedMultiset.java b/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/UnmodifiableSortedMultiset.java
deleted file mode 100644
index 87937fe..0000000
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/UnmodifiableSortedMultiset.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.collect.Multisets.UnmodifiableMultiset;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.SortedSet;
-
-/**
- * Implementation of {@link Multisets#unmodifiableSortedMultiset(SortedMultiset)}
- * for GWT.
- *
- * @author Louis Wasserman
- */
-final class UnmodifiableSortedMultiset<E>
- extends UnmodifiableMultiset<E> implements SortedMultiset<E> {
- UnmodifiableSortedMultiset(SortedMultiset<E> delegate) {
- super(delegate);
- }
-
- @Override
- protected SortedMultiset<E> delegate() {
- return (SortedMultiset<E>) super.delegate();
- }
-
- @Override
- public Comparator<? super E> comparator() {
- return delegate().comparator();
- }
-
- @Override
- SortedSet<E> createElementSet() {
- return Collections.unmodifiableSortedSet(delegate().elementSet());
- }
-
- @Override
- public SortedSet<E> elementSet() {
- return (SortedSet<E>) super.elementSet();
- }
-
- private transient UnmodifiableSortedMultiset<E> descendingMultiset;
-
- @Override
- public SortedMultiset<E> descendingMultiset() {
- UnmodifiableSortedMultiset<E> result = descendingMultiset;
- if (result == null) {
- result = new UnmodifiableSortedMultiset<E>(
- delegate().descendingMultiset());
- result.descendingMultiset = this;
- return descendingMultiset = result;
- }
- return result;
- }
-
- @Override
- public Entry<E> firstEntry() {
- return delegate().firstEntry();
- }
-
- @Override
- public Entry<E> lastEntry() {
- return delegate().lastEntry();
- }
-
- @Override
- public Entry<E> pollFirstEntry() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Entry<E> pollLastEntry() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
- return Multisets.unmodifiableSortedMultiset(
- delegate().headMultiset(upperBound, boundType));
- }
-
- @Override
- public SortedMultiset<E> subMultiset(
- E lowerBound, BoundType lowerBoundType,
- E upperBound, BoundType upperBoundType) {
- return Multisets.unmodifiableSortedMultiset(delegate().subMultiset(
- lowerBound, lowerBoundType, upperBound, upperBoundType));
- }
-
- @Override
- public SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
- return Multisets.unmodifiableSortedMultiset(
- delegate().tailMultiset(lowerBound, boundType));
- }
-
- private static final long serialVersionUID = 0;
-} \ No newline at end of file
diff --git a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableBiMap.java b/guava-gwt/src-super/com/google/common/escape/super/com/google/common/escape/Platform.java
index 1520d58..36f1b2e 100644
--- a/guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/EmptyImmutableBiMap.java
+++ b/guava-gwt/src-super/com/google/common/escape/super/com/google/common/escape/Platform.java
@@ -14,23 +14,20 @@
* limitations under the License.
*/
-package com.google.common.collect;
-
-import java.util.Collections;
+package com.google.common.escape;
/**
- * GWT emulation of {@link EmptyImmutableBiMap}.
- *
- * @author Hayward Chan
+ * @author Jesse Wilson
*/
-@SuppressWarnings("serial")
-final class EmptyImmutableBiMap extends ImmutableBiMap<Object, Object> {
- static final EmptyImmutableBiMap INSTANCE = new EmptyImmutableBiMap();
+class Platform {
- private EmptyImmutableBiMap() {
- super(Collections.emptyMap());
- }
- @Override public ImmutableBiMap<Object, Object> inverse() {
- return this;
+ private static final char[] CHAR_BUFFER = new char[1024];
+
+ static char[] charBufferFromThreadLocal() {
+ // ThreadLocal is not available to GWT, so we always reuse the same
+ // instance. It is always safe to return the same instance because
+ // javascript is single-threaded, and only used by blocks that doesn't
+ // involve async callbacks.
+ return CHAR_BUFFER;
}
}
diff --git a/guava-gwt/src-super/com/google/common/io/super/com/google/common/io/BaseEncoding.java b/guava-gwt/src-super/com/google/common/io/super/com/google/common/io/BaseEncoding.java
deleted file mode 100644
index dee5b89..0000000
--- a/guava-gwt/src-super/com/google/common/io/super/com/google/common/io/BaseEncoding.java
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.io.GwtWorkarounds.asCharInput;
-import static com.google.common.io.GwtWorkarounds.stringBuilderOutput;
-import static com.google.common.math.IntMath.divide;
-import static com.google.common.math.IntMath.log2;
-import static java.math.RoundingMode.CEILING;
-import static java.math.RoundingMode.FLOOR;
-import static java.math.RoundingMode.UNNECESSARY;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Ascii;
-import com.google.common.base.CharMatcher;
-import com.google.common.io.GwtWorkarounds.ByteInput;
-import com.google.common.io.GwtWorkarounds.ByteOutput;
-import com.google.common.io.GwtWorkarounds.CharInput;
-import com.google.common.io.GwtWorkarounds.CharOutput;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nullable;
-
-/**
- * A binary encoding scheme for reversibly translating between byte sequences and printable ASCII
- * strings. This class includes several constants for encoding schemes specified by <a
- * href="http://tools.ietf.org/html/rfc4648">RFC 4648</a>. For example, the expression:
- * <pre> {@code
- *
- * BaseEncoding.base32().encode("foo".getBytes(Charsets.US_ASCII))
- * }</pre>
- * returns the string {@code "MZXW6==="}, and <pre> {@code
- *
- * byte[] decoded = BaseEncoding.base32().decode("MZXW6===");
- * }</pre>
- *
- * ...returns the ASCII bytes of the string {@code "foo"}.
- *
- * <p>By default, {@code BaseEncoding}'s behavior is relatively strict and in accordance with
- * RFC 4648. Decoding rejects characters in the wrong case, though padding is optional.
- * To modify encoding and decoding behavior, use configuration methods to obtain a new encoding
- * with modified behavior: <pre> {@code
- *
- * BaseEncoding.base16().lowerCase().decode("deadbeef");
- * }</pre>
- *
- * <p>Warning: BaseEncoding instances are immutable. Invoking a configuration method has no effect
- * on the receiving instance; you must store and use the new encoding instance it returns, instead.
- * <pre> {@code
- *
- * // Do NOT do this
- * BaseEncoding hex = BaseEncoding.base16();
- * hex.lowerCase(); // does nothing!
- * return hex.decode("deadbeef"); // throws an IllegalArgumentException
- * }</pre>
- *
- * <p>It is guaranteed that {@code encoding.decode(encoding.encode(x))} is always equal to
- * {@code x}, but the reverse does not necessarily hold.
- *
- * <p>
- * <table>
- * <tr>
- * <th>Encoding
- * <th>Alphabet
- * <th>{@code char:byte} ratio
- * <th>Default padding
- * <th>Comments
- * <tr>
- * <td>{@link #base16()}
- * <td>0-9 A-F
- * <td>2.00
- * <td>N/A
- * <td>Traditional hexadecimal. Defaults to upper case.
- * <tr>
- * <td>{@link #base32()}
- * <td>A-Z 2-7
- * <td>1.60
- * <td>=
- * <td>Human-readable; no possibility of mixing up 0/O or 1/I. Defaults to upper case.
- * <tr>
- * <td>{@link #base32Hex()}
- * <td>0-9 A-V
- * <td>1.60
- * <td>=
- * <td>"Numerical" base 32; extended from the traditional hex alphabet. Defaults to upper case.
- * <tr>
- * <td>{@link #base64()}
- * <td>A-Z a-z 0-9 + /
- * <td>1.33
- * <td>=
- * <td>
- * <tr>
- * <td>{@link #base64Url()}
- * <td>A-Z a-z 0-9 - _
- * <td>1.33
- * <td>=
- * <td>Safe to use as filenames, or to pass in URLs without escaping
- * </table>
- *
- * <p>
- * All instances of this class are immutable, so they may be stored safely as static constants.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-@GwtCompatible(emulated = true)
-public abstract class BaseEncoding {
- // TODO(user): consider adding encodeTo(Appendable, byte[], [int, int])
-
- BaseEncoding() {}
-
- /**
- * Encodes the specified byte array, and returns the encoded {@code String}.
- */
- public String encode(byte[] bytes) {
- return encode(checkNotNull(bytes), 0, bytes.length);
- }
-
- /**
- * Encodes the specified range of the specified byte array, and returns the encoded
- * {@code String}.
- */
- public final String encode(byte[] bytes, int off, int len) {
- checkNotNull(bytes);
- checkPositionIndexes(off, off + len, bytes.length);
- CharOutput result = stringBuilderOutput(maxEncodedSize(len));
- ByteOutput byteOutput = encodingStream(result);
- try {
- for (int i = 0; i < len; i++) {
- byteOutput.write(bytes[off + i]);
- }
- byteOutput.close();
- } catch (IOException impossible) {
- throw new AssertionError("impossible");
- }
- return result.toString();
- }
-
- // TODO(user): document the extent of leniency, probably after adding ignore(CharMatcher)
-
- private static byte[] extract(byte[] result, int length) {
- if (length == result.length) {
- return result;
- } else {
- byte[] trunc = new byte[length];
- System.arraycopy(result, 0, trunc, 0, length);
- return trunc;
- }
- }
-
- /**
- * Decodes the specified character sequence, and returns the resulting {@code byte[]}.
- * This is the inverse operation to {@link #encode(byte[])}.
- *
- * @throws IllegalArgumentException if the input is not a valid encoded string according to this
- * encoding.
- */
- public final byte[] decode(CharSequence chars) {
- chars = padding().trimTrailingFrom(chars);
- ByteInput decodedInput = decodingStream(asCharInput(chars));
- byte[] tmp = new byte[maxDecodedSize(chars.length())];
- int index = 0;
- try {
- for (int i = decodedInput.read(); i != -1; i = decodedInput.read()) {
- tmp[index++] = (byte) i;
- }
- } catch (IOException badInput) {
- throw new IllegalArgumentException(badInput);
- }
- return extract(tmp, index);
- }
-
- // Implementations for encoding/decoding
-
- abstract int maxEncodedSize(int bytes);
-
- abstract ByteOutput encodingStream(CharOutput charOutput);
-
- abstract int maxDecodedSize(int chars);
-
- abstract ByteInput decodingStream(CharInput charInput);
-
- abstract CharMatcher padding();
-
- // Modified encoding generators
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but omits any padding
- * characters as specified by <a href="http://tools.ietf.org/html/rfc4648#section-3.2">RFC 4648
- * section 3.2</a>, Padding of Encoded Data.
- */
- @CheckReturnValue
- public abstract BaseEncoding omitPadding();
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but uses an alternate character
- * for padding.
- *
- * @throws IllegalArgumentException if this padding character is already used in the alphabet or a
- * separator
- */
- @CheckReturnValue
- public abstract BaseEncoding withPadChar(char padChar);
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but adds a separator string
- * after every {@code n} characters. Any occurrences of any characters that occur in the separator
- * are skipped over in decoding.
- *
- * @throws IllegalArgumentException if any alphabet or padding characters appear in the separator
- * string, or if {@code n <= 0}
- * @throws UnsupportedOperationException if this encoding already uses a separator
- */
- @CheckReturnValue
- public abstract BaseEncoding withSeparator(String separator, int n);
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but encodes and decodes with
- * uppercase letters. Padding and separator characters remain in their original case.
- *
- * @throws IllegalStateException if the alphabet used by this encoding contains mixed upper- and
- * lower-case characters
- */
- @CheckReturnValue
- public abstract BaseEncoding upperCase();
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but encodes and decodes with
- * lowercase letters. Padding and separator characters remain in their original case.
- *
- * @throws IllegalStateException if the alphabet used by this encoding contains mixed upper- and
- * lower-case characters
- */
- @CheckReturnValue
- public abstract BaseEncoding lowerCase();
-
- private static final BaseEncoding BASE64 = new StandardBaseEncoding(
- "base64()", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", '=');
-
- /**
- * The "base64" base encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-4">RFC 4648 section 4</a>, Base 64 Encoding.
- * (This is the same as the base 64 encoding from <a
- * href="http://tools.ietf.org/html/rfc3548#section-3">RFC 3548</a>.)
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base64() {
- return BASE64;
- }
-
- private static final BaseEncoding BASE64_URL = new StandardBaseEncoding(
- "base64Url()", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", '=');
-
- /**
- * The "base64url" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-5">RFC 4648 section 5</a>, Base 64 Encoding
- * with URL and Filename Safe Alphabet, also sometimes referred to as the "web safe Base64."
- * (This is the same as the base 64 encoding with URL and filename safe alphabet from <a
- * href="http://tools.ietf.org/html/rfc3548#section-4">RFC 3548</a>.)
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base64Url() {
- return BASE64_URL;
- }
-
- private static final BaseEncoding BASE32 =
- new StandardBaseEncoding("base32()", "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", '=');
-
- /**
- * The "base32" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-6">RFC 4648 section 6</a>, Base 32 Encoding.
- * (This is the same as the base 32 encoding from <a
- * href="http://tools.ietf.org/html/rfc3548#section-5">RFC 3548</a>.)
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base32() {
- return BASE32;
- }
-
- private static final BaseEncoding BASE32_HEX =
- new StandardBaseEncoding("base32Hex()", "0123456789ABCDEFGHIJKLMNOPQRSTUV", '=');
-
- /**
- * The "base32hex" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-7">RFC 4648 section 7</a>, Base 32 Encoding
- * with Extended Hex Alphabet. There is no corresponding encoding in RFC 3548.
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base32Hex() {
- return BASE32_HEX;
- }
-
- private static final BaseEncoding BASE16 =
- new StandardBaseEncoding("base16()", "0123456789ABCDEF", null);
-
- /**
- * The "base16" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-8">RFC 4648 section 8</a>, Base 16 Encoding.
- * (This is the same as the base 16 encoding from <a
- * href="http://tools.ietf.org/html/rfc3548#section-6">RFC 3548</a>.) This is commonly known as
- * "hexadecimal" format.
- *
- * <p>No padding is necessary in base 16, so {@link #withPadChar(char)} and
- * {@link #omitPadding()} have no effect.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base16() {
- return BASE16;
- }
-
- private static final class Alphabet extends CharMatcher {
- private final String name;
- // this is meant to be immutable -- don't modify it!
- private final char[] chars;
- final int mask;
- final int bitsPerChar;
- final int charsPerChunk;
- final int bytesPerChunk;
- private final byte[] decodabet;
- private final boolean[] validPadding;
-
- Alphabet(String name, char[] chars) {
- this.name = checkNotNull(name);
- this.chars = checkNotNull(chars);
- try {
- this.bitsPerChar = log2(chars.length, UNNECESSARY);
- } catch (ArithmeticException e) {
- throw new IllegalArgumentException("Illegal alphabet length " + chars.length, e);
- }
-
- /*
- * e.g. for base64, bitsPerChar == 6, charsPerChunk == 4, and bytesPerChunk == 3. This makes
- * for the smallest chunk size that still has charsPerChunk * bitsPerChar be a multiple of 8.
- */
- int gcd = Math.min(8, Integer.lowestOneBit(bitsPerChar));
- this.charsPerChunk = 8 / gcd;
- this.bytesPerChunk = bitsPerChar / gcd;
-
- this.mask = chars.length - 1;
-
- byte[] decodabet = new byte[Ascii.MAX + 1];
- Arrays.fill(decodabet, (byte) -1);
- for (int i = 0; i < chars.length; i++) {
- char c = chars[i];
- checkArgument(CharMatcher.ASCII.matches(c), "Non-ASCII character: %s", c);
- checkArgument(decodabet[c] == -1, "Duplicate character: %s", c);
- decodabet[c] = (byte) i;
- }
- this.decodabet = decodabet;
-
- boolean[] validPadding = new boolean[charsPerChunk];
- for (int i = 0; i < bytesPerChunk; i++) {
- validPadding[divide(i * 8, bitsPerChar, CEILING)] = true;
- }
- this.validPadding = validPadding;
- }
-
- char encode(int bits) {
- return chars[bits];
- }
-
- boolean isValidPaddingStartPosition(int index) {
- return validPadding[index % charsPerChunk];
- }
-
- int decode(char ch) throws IOException {
- if (ch > Ascii.MAX || decodabet[ch] == -1) {
- throw new IOException("Unrecognized character: " + ch);
- }
- return decodabet[ch];
- }
-
- private boolean hasLowerCase() {
- for (char c : chars) {
- if (Ascii.isLowerCase(c)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean hasUpperCase() {
- for (char c : chars) {
- if (Ascii.isUpperCase(c)) {
- return true;
- }
- }
- return false;
- }
-
- Alphabet upperCase() {
- if (!hasLowerCase()) {
- return this;
- } else {
- checkState(!hasUpperCase(), "Cannot call upperCase() on a mixed-case alphabet");
- char[] upperCased = new char[chars.length];
- for (int i = 0; i < chars.length; i++) {
- upperCased[i] = Ascii.toUpperCase(chars[i]);
- }
- return new Alphabet(name + ".upperCase()", upperCased);
- }
- }
-
- Alphabet lowerCase() {
- if (!hasUpperCase()) {
- return this;
- } else {
- checkState(!hasLowerCase(), "Cannot call lowerCase() on a mixed-case alphabet");
- char[] lowerCased = new char[chars.length];
- for (int i = 0; i < chars.length; i++) {
- lowerCased[i] = Ascii.toLowerCase(chars[i]);
- }
- return new Alphabet(name + ".lowerCase()", lowerCased);
- }
- }
-
- @Override
- public boolean matches(char c) {
- return CharMatcher.ASCII.matches(c) && decodabet[c] != -1;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- static final class StandardBaseEncoding extends BaseEncoding {
- // TODO(user): provide a useful toString
- private final Alphabet alphabet;
-
- @Nullable
- private final Character paddingChar;
-
- StandardBaseEncoding(String name, String alphabetChars, @Nullable Character paddingChar) {
- this(new Alphabet(name, alphabetChars.toCharArray()), paddingChar);
- }
-
- StandardBaseEncoding(Alphabet alphabet, Character paddingChar) {
- this.alphabet = checkNotNull(alphabet);
- checkArgument(paddingChar == null || !alphabet.matches(paddingChar),
- "Padding character %s was already in alphabet", paddingChar);
- this.paddingChar = paddingChar;
- }
-
- @Override
- CharMatcher padding() {
- return (paddingChar == null) ? CharMatcher.NONE : CharMatcher.is(paddingChar.charValue());
- }
-
- @Override
- int maxEncodedSize(int bytes) {
- return alphabet.charsPerChunk * divide(bytes, alphabet.bytesPerChunk, CEILING);
- }
-
- @Override
- ByteOutput encodingStream(final CharOutput out) {
- checkNotNull(out);
- return new ByteOutput() {
- int bitBuffer = 0;
- int bitBufferLength = 0;
- int writtenChars = 0;
-
- @Override
- public void write(byte b) throws IOException {
- bitBuffer <<= 8;
- bitBuffer |= b & 0xFF;
- bitBufferLength += 8;
- while (bitBufferLength >= alphabet.bitsPerChar) {
- int charIndex = (bitBuffer >> (bitBufferLength - alphabet.bitsPerChar))
- & alphabet.mask;
- out.write(alphabet.encode(charIndex));
- writtenChars++;
- bitBufferLength -= alphabet.bitsPerChar;
- }
- }
-
- @Override
- public void flush() throws IOException {
- out.flush();
- }
-
- @Override
- public void close() throws IOException {
- if (bitBufferLength > 0) {
- int charIndex = (bitBuffer << (alphabet.bitsPerChar - bitBufferLength))
- & alphabet.mask;
- out.write(alphabet.encode(charIndex));
- writtenChars++;
- if (paddingChar != null) {
- while (writtenChars % alphabet.charsPerChunk != 0) {
- out.write(paddingChar.charValue());
- writtenChars++;
- }
- }
- }
- out.close();
- }
- };
- }
-
- @Override
- int maxDecodedSize(int chars) {
- return (int) ((alphabet.bitsPerChar * (long) chars + 7L) / 8L);
- }
-
- @Override
- ByteInput decodingStream(final CharInput reader) {
- checkNotNull(reader);
- return new ByteInput() {
- int bitBuffer = 0;
- int bitBufferLength = 0;
- int readChars = 0;
- boolean hitPadding = false;
- final CharMatcher paddingMatcher = padding();
-
- @Override
- public int read() throws IOException {
- while (true) {
- int readChar = reader.read();
- if (readChar == -1) {
- if (!hitPadding && !alphabet.isValidPaddingStartPosition(readChars)) {
- throw new IOException("Invalid input length " + readChars);
- }
- return -1;
- }
- readChars++;
- char ch = (char) readChar;
- if (paddingMatcher.matches(ch)) {
- if (!hitPadding
- && (readChars == 1 || !alphabet.isValidPaddingStartPosition(readChars - 1))) {
- throw new IOException("Padding cannot start at index " + readChars);
- }
- hitPadding = true;
- } else if (hitPadding) {
- throw new IOException(
- "Expected padding character but found '" + ch + "' at index " + readChars);
- } else {
- bitBuffer <<= alphabet.bitsPerChar;
- bitBuffer |= alphabet.decode(ch);
- bitBufferLength += alphabet.bitsPerChar;
-
- if (bitBufferLength >= 8) {
- bitBufferLength -= 8;
- return (bitBuffer >> bitBufferLength) & 0xFF;
- }
- }
- }
- }
-
- @Override
- public void close() throws IOException {
- reader.close();
- }
- };
- }
-
- @Override
- public BaseEncoding omitPadding() {
- return (paddingChar == null) ? this : new StandardBaseEncoding(alphabet, null);
- }
-
- @Override
- public BaseEncoding withPadChar(char padChar) {
- if (8 % alphabet.bitsPerChar == 0 ||
- (paddingChar != null && paddingChar.charValue() == padChar)) {
- return this;
- } else {
- return new StandardBaseEncoding(alphabet, padChar);
- }
- }
-
- @Override
- public BaseEncoding withSeparator(String separator, int afterEveryChars) {
- checkNotNull(separator);
- checkArgument(padding().or(alphabet).matchesNoneOf(separator),
- "Separator cannot contain alphabet or padding characters");
- return new SeparatedBaseEncoding(this, separator, afterEveryChars);
- }
-
- private transient BaseEncoding upperCase;
- private transient BaseEncoding lowerCase;
-
- @Override
- public BaseEncoding upperCase() {
- BaseEncoding result = upperCase;
- if (result == null) {
- Alphabet upper = alphabet.upperCase();
- result = upperCase =
- (upper == alphabet) ? this : new StandardBaseEncoding(upper, paddingChar);
- }
- return result;
- }
-
- @Override
- public BaseEncoding lowerCase() {
- BaseEncoding result = lowerCase;
- if (result == null) {
- Alphabet lower = alphabet.lowerCase();
- result = lowerCase =
- (lower == alphabet) ? this : new StandardBaseEncoding(lower, paddingChar);
- }
- return result;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder("BaseEncoding.");
- builder.append(alphabet.toString());
- if (8 % alphabet.bitsPerChar != 0) {
- if (paddingChar == null) {
- builder.append(".omitPadding()");
- } else {
- builder.append(".withPadChar(").append(paddingChar).append(')');
- }
- }
- return builder.toString();
- }
- }
-
- static CharInput ignoringInput(final CharInput delegate, final CharMatcher toIgnore) {
- checkNotNull(delegate);
- checkNotNull(toIgnore);
- return new CharInput() {
- @Override
- public int read() throws IOException {
- int readChar;
- do {
- readChar = delegate.read();
- } while (readChar != -1 && toIgnore.matches((char) readChar));
- return readChar;
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
- };
- }
-
- static CharOutput separatingOutput(
- final CharOutput delegate, final String separator, final int afterEveryChars) {
- checkNotNull(delegate);
- checkNotNull(separator);
- checkArgument(afterEveryChars > 0);
- return new CharOutput() {
- int charsUntilSeparator = afterEveryChars;
-
- @Override
- public void write(char c) throws IOException {
- if (charsUntilSeparator == 0) {
- for (int i = 0; i < separator.length(); i++) {
- delegate.write(separator.charAt(i));
- }
- charsUntilSeparator = afterEveryChars;
- }
- delegate.write(c);
- charsUntilSeparator--;
- }
-
- @Override
- public void flush() throws IOException {
- delegate.flush();
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
- };
- }
-
- static final class SeparatedBaseEncoding extends BaseEncoding {
- private final BaseEncoding delegate;
- private final String separator;
- private final int afterEveryChars;
- private final CharMatcher separatorChars;
-
- SeparatedBaseEncoding(BaseEncoding delegate, String separator, int afterEveryChars) {
- this.delegate = checkNotNull(delegate);
- this.separator = checkNotNull(separator);
- this.afterEveryChars = afterEveryChars;
- checkArgument(
- afterEveryChars > 0, "Cannot add a separator after every %s chars", afterEveryChars);
- this.separatorChars = CharMatcher.anyOf(separator).precomputed();
- }
-
- @Override
- CharMatcher padding() {
- return delegate.padding();
- }
-
- @Override
- int maxEncodedSize(int bytes) {
- int unseparatedSize = delegate.maxEncodedSize(bytes);
- return unseparatedSize + separator.length()
- * divide(Math.max(0, unseparatedSize - 1), afterEveryChars, FLOOR);
- }
-
- @Override
- ByteOutput encodingStream(final CharOutput output) {
- return delegate.encodingStream(separatingOutput(output, separator, afterEveryChars));
- }
-
- @Override
- int maxDecodedSize(int chars) {
- return delegate.maxDecodedSize(chars);
- }
-
- @Override
- ByteInput decodingStream(final CharInput input) {
- return delegate.decodingStream(ignoringInput(input, separatorChars));
- }
-
- @Override
- public BaseEncoding omitPadding() {
- return delegate.omitPadding().withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public BaseEncoding withPadChar(char padChar) {
- return delegate.withPadChar(padChar).withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public BaseEncoding withSeparator(String separator, int afterEveryChars) {
- throw new UnsupportedOperationException("Already have a separator");
- }
-
- @Override
- public BaseEncoding upperCase() {
- return delegate.upperCase().withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public BaseEncoding lowerCase() {
- return delegate.lowerCase().withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public String toString() {
- return delegate.toString() +
- ".withSeparator(\"" + separator + "\", " + afterEveryChars + ")";
- }
- }
-}
diff --git a/guava-gwt/src-super/com/google/common/io/super/com/google/common/io/GwtWorkarounds.java b/guava-gwt/src-super/com/google/common/io/super/com/google/common/io/GwtWorkarounds.java
deleted file mode 100644
index f3f955e..0000000
--- a/guava-gwt/src-super/com/google/common/io/super/com/google/common/io/GwtWorkarounds.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.io.IOException;
-
-/**
- * Provides simple GWT-compatible substitutes for {@code InputStream}, {@code OutputStream},
- * {@code Reader}, and {@code Writer} so that {@code BaseEncoding} can use streaming implementations
- * while remaining GWT-compatible.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-final class GwtWorkarounds {
- private GwtWorkarounds() {}
-
- /**
- * A GWT-compatible substitute for a {@code Reader}.
- */
- interface CharInput {
- int read() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * Views a {@code CharSequence} as a {@code CharInput}.
- */
- static CharInput asCharInput(final CharSequence chars) {
- checkNotNull(chars);
- return new CharInput() {
- int index = 0;
-
- @Override
- public int read() {
- if (index < chars.length()) {
- return chars.charAt(index++);
- } else {
- return -1;
- }
- }
-
- @Override
- public void close() {
- index = chars.length();
- }
- };
- }
-
- /**
- * A GWT-compatible substitute for an {@code InputStream}.
- */
- interface ByteInput {
- int read() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * A GWT-compatible substitute for an {@code OutputStream}.
- */
- interface ByteOutput {
- void write(byte b) throws IOException;
- void flush() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * A GWT-compatible substitute for a {@code Writer}.
- */
- interface CharOutput {
- void write(char c) throws IOException;
- void flush() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * Returns a {@code CharOutput} whose {@code toString()} method can be used
- * to get the combined output.
- */
- static CharOutput stringBuilderOutput(int initialSize) {
- final StringBuilder builder = new StringBuilder(initialSize);
- return new CharOutput() {
-
- @Override
- public void write(char c) {
- builder.append(c);
- }
-
- @Override
- public void flush() {}
-
- @Override
- public void close() {}
-
- @Override
- public String toString() {
- return builder.toString();
- }
- };
- }
-}
-
diff --git a/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/BigIntegerMath.java b/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/BigIntegerMath.java
deleted file mode 100644
index 75f19be..0000000
--- a/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/BigIntegerMath.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.math.MathPreconditions.checkNonNegative;
-import static com.google.common.math.MathPreconditions.checkPositive;
-import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
-import static java.math.RoundingMode.CEILING;
-import static java.math.RoundingMode.FLOOR;
-import static java.math.RoundingMode.HALF_EVEN;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.VisibleForTesting;
-
-import java.math.BigInteger;
-import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A class for arithmetic on values of type {@code BigInteger}.
- *
- * <p>The implementations of many methods in this class are based on material from Henry S. Warren,
- * Jr.'s <i>Hacker's Delight</i>, (Addison Wesley, 2002).
- *
- * <p>Similar functionality for {@code int} and for {@code long} can be found in
- * {@link IntMath} and {@link LongMath} respectively.
- *
- * @author Louis Wasserman
- * @since 11.0
- */
-@GwtCompatible(emulated = true)
-public final class BigIntegerMath {
- /**
- * Returns {@code true} if {@code x} represents a power of two.
- */
- public static boolean isPowerOfTwo(BigInteger x) {
- checkNotNull(x);
- return x.signum() > 0 && x.getLowestSetBit() == x.bitLength() - 1;
- }
-
- /**
- * Returns the base-2 logarithm of {@code x}, rounded according to the specified rounding mode.
- *
- * @throws IllegalArgumentException if {@code x <= 0}
- * @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
- * is not a power of two
- */
- @SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
- public static int log2(BigInteger x, RoundingMode mode) {
- checkPositive("x", checkNotNull(x));
- int logFloor = x.bitLength() - 1;
- switch (mode) {
- case UNNECESSARY:
- checkRoundingUnnecessary(isPowerOfTwo(x)); // fall through
- case DOWN:
- case FLOOR:
- return logFloor;
-
- case UP:
- case CEILING:
- return isPowerOfTwo(x) ? logFloor : logFloor + 1;
-
- case HALF_DOWN:
- case HALF_UP:
- case HALF_EVEN:
- if (logFloor < SQRT2_PRECOMPUTE_THRESHOLD) {
- BigInteger halfPower = SQRT2_PRECOMPUTED_BITS.shiftRight(
- SQRT2_PRECOMPUTE_THRESHOLD - logFloor);
- if (x.compareTo(halfPower) <= 0) {
- return logFloor;
- } else {
- return logFloor + 1;
- }
- }
- /*
- * Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5
- *
- * To determine which side of logFloor.5 the logarithm is, we compare x^2 to 2^(2 *
- * logFloor + 1).
- */
- BigInteger x2 = x.pow(2);
- int logX2Floor = x2.bitLength() - 1;
- return (logX2Floor < 2 * logFloor + 1) ? logFloor : logFloor + 1;
-
- default:
- throw new AssertionError();
- }
- }
-
- /*
- * The maximum number of bits in a square root for which we'll precompute an explicit half power
- * of two. This can be any value, but higher values incur more class load time and linearly
- * increasing memory consumption.
- */
- @VisibleForTesting static final int SQRT2_PRECOMPUTE_THRESHOLD = 256;
-
- @VisibleForTesting static final BigInteger SQRT2_PRECOMPUTED_BITS =
- new BigInteger("16a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b0667322a", 16);
-
- private static final double LN_10 = Math.log(10);
- private static final double LN_2 = Math.log(2);
-
- /**
- * Returns {@code n!}, that is, the product of the first {@code n} positive
- * integers, or {@code 1} if {@code n == 0}.
- *
- * <p><b>Warning</b>: the result takes <i>O(n log n)</i> space, so use cautiously.
- *
- * <p>This uses an efficient binary recursive algorithm to compute the factorial
- * with balanced multiplies. It also removes all the 2s from the intermediate
- * products (shifting them back in at the end).
- *
- * @throws IllegalArgumentException if {@code n < 0}
- */
- public static BigInteger factorial(int n) {
- checkNonNegative("n", n);
-
- // If the factorial is small enough, just use LongMath to do it.
- if (n < LongMath.factorials.length) {
- return BigInteger.valueOf(LongMath.factorials[n]);
- }
-
- // Pre-allocate space for our list of intermediate BigIntegers.
- int approxSize = IntMath.divide(n * IntMath.log2(n, CEILING), Long.SIZE, CEILING);
- ArrayList<BigInteger> bignums = new ArrayList<BigInteger>(approxSize);
-
- // Start from the pre-computed maximum long factorial.
- int startingNumber = LongMath.factorials.length;
- long product = LongMath.factorials[startingNumber - 1];
- // Strip off 2s from this value.
- int shift = Long.numberOfTrailingZeros(product);
- product >>= shift;
-
- // Use floor(log2(num)) + 1 to prevent overflow of multiplication.
- int productBits = LongMath.log2(product, FLOOR) + 1;
- int bits = LongMath.log2(startingNumber, FLOOR) + 1;
- // Check for the next power of two boundary, to save us a CLZ operation.
- int nextPowerOfTwo = 1 << (bits - 1);
-
- // Iteratively multiply the longs as big as they can go.
- for (long num = startingNumber; num <= n; num++) {
- // Check to see if the floor(log2(num)) + 1 has changed.
- if ((num & nextPowerOfTwo) != 0) {
- nextPowerOfTwo <<= 1;
- bits++;
- }
- // Get rid of the 2s in num.
- int tz = Long.numberOfTrailingZeros(num);
- long normalizedNum = num >> tz;
- shift += tz;
- // Adjust floor(log2(num)) + 1.
- int normalizedBits = bits - tz;
- // If it won't fit in a long, then we store off the intermediate product.
- if (normalizedBits + productBits >= Long.SIZE) {
- bignums.add(BigInteger.valueOf(product));
- product = 1;
- productBits = 0;
- }
- product *= normalizedNum;
- productBits = LongMath.log2(product, FLOOR) + 1;
- }
- // Check for leftovers.
- if (product > 1) {
- bignums.add(BigInteger.valueOf(product));
- }
- // Efficiently multiply all the intermediate products together.
- return listProduct(bignums).shiftLeft(shift);
- }
-
- static BigInteger listProduct(List<BigInteger> nums) {
- return listProduct(nums, 0, nums.size());
- }
-
- static BigInteger listProduct(List<BigInteger> nums, int start, int end) {
- switch (end - start) {
- case 0:
- return BigInteger.ONE;
- case 1:
- return nums.get(start);
- case 2:
- return nums.get(start).multiply(nums.get(start + 1));
- case 3:
- return nums.get(start).multiply(nums.get(start + 1)).multiply(nums.get(start + 2));
- default:
- // Otherwise, split the list in half and recursively do this.
- int m = (end + start) >>> 1;
- return listProduct(nums, start, m).multiply(listProduct(nums, m, end));
- }
- }
-
- /**
- * Returns {@code n} choose {@code k}, also known as the binomial coefficient of {@code n} and
- * {@code k}, that is, {@code n! / (k! (n - k)!)}.
- *
- * <p><b>Warning</b>: the result can take as much as <i>O(k log n)</i> space.
- *
- * @throws IllegalArgumentException if {@code n < 0}, {@code k < 0}, or {@code k > n}
- */
- public static BigInteger binomial(int n, int k) {
- checkNonNegative("n", n);
- checkNonNegative("k", k);
- checkArgument(k <= n, "k (%s) > n (%s)", k, n);
- if (k > (n >> 1)) {
- k = n - k;
- }
- if (k < LongMath.biggestBinomials.length && n <= LongMath.biggestBinomials[k]) {
- return BigInteger.valueOf(LongMath.binomial(n, k));
- }
-
- BigInteger accum = BigInteger.ONE;
-
- long numeratorAccum = n;
- long denominatorAccum = 1;
-
- int bits = LongMath.log2(n, RoundingMode.CEILING);
-
- int numeratorBits = bits;
-
- for (int i = 1; i < k; i++) {
- int p = n - i;
- int q = i + 1;
-
- // log2(p) >= bits - 1, because p >= n/2
-
- if (numeratorBits + bits >= Long.SIZE - 1) {
- // The numerator is as big as it can get without risking overflow.
- // Multiply numeratorAccum / denominatorAccum into accum.
- accum = accum
- .multiply(BigInteger.valueOf(numeratorAccum))
- .divide(BigInteger.valueOf(denominatorAccum));
- numeratorAccum = p;
- denominatorAccum = q;
- numeratorBits = bits;
- } else {
- // We can definitely multiply into the long accumulators without overflowing them.
- numeratorAccum *= p;
- denominatorAccum *= q;
- numeratorBits += bits;
- }
- }
- return accum
- .multiply(BigInteger.valueOf(numeratorAccum))
- .divide(BigInteger.valueOf(denominatorAccum));
- }
-
- // Returns true if BigInteger.valueOf(x.longValue()).equals(x).
-
- private BigIntegerMath() {}
-}
-
diff --git a/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/IntMath.java b/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/IntMath.java
index 31703ed..352351c 100644
--- a/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/IntMath.java
+++ b/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/IntMath.java
@@ -16,42 +16,35 @@
package com.google.common.math;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.math.MathPreconditions.checkNoOverflow;
import static com.google.common.math.MathPreconditions.checkNonNegative;
-import static com.google.common.math.MathPreconditions.checkPositive;
-import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
-import static java.lang.Math.abs;
-import static java.lang.Math.min;
-import static java.math.RoundingMode.HALF_EVEN;
-import static java.math.RoundingMode.HALF_UP;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
-import java.math.RoundingMode;
-
/**
* A class for arithmetic on values of type {@code int}. Where possible, methods are defined and
* named analogously to their {@code BigInteger} counterparts.
- *
+ *
* <p>The implementations of many methods in this class are based on material from Henry S. Warren,
* Jr.'s <i>Hacker's Delight</i>, (Addison Wesley, 2002).
- *
+ *
* <p>Similar functionality for {@code long} and for {@link BigInteger} can be found in
* {@link LongMath} and {@link BigIntegerMath} respectively. For other common operations on
* {@code int} values, see {@link com.google.common.primitives.Ints}.
- *
+ *
* @author Louis Wasserman
* @since 11.0
*/
+@Beta
@GwtCompatible(emulated = true)
public final class IntMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
/**
* Returns {@code true} if {@code x} represents a power of two.
- *
+ *
* <p>This differs from {@code Integer.bitCount(x) == 1}, because
* {@code Integer.bitCount(Integer.MIN_VALUE) == 1}, but {@link Integer#MIN_VALUE} is not a power
* of two.
@@ -60,75 +53,23 @@ public final class IntMath {
return x > 0 & (x & (x - 1)) == 0;
}
- /**
- * Returns the base-2 logarithm of {@code x}, rounded according to the specified rounding mode.
- *
- * @throws IllegalArgumentException if {@code x <= 0}
- * @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
- * is not a power of two
- */
- @SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
- public static int log2(int x, RoundingMode mode) {
- checkPositive("x", x);
- switch (mode) {
- case UNNECESSARY:
- checkRoundingUnnecessary(isPowerOfTwo(x));
- // fall through
- case DOWN:
- case FLOOR:
- return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(x);
-
- case UP:
- case CEILING:
- return Integer.SIZE - Integer.numberOfLeadingZeros(x - 1);
-
- case HALF_DOWN:
- case HALF_UP:
- case HALF_EVEN:
- // Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5
- int leadingZeros = Integer.numberOfLeadingZeros(x);
- int cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros;
- // floor(2^(logFloor + 0.5))
- int logFloor = (Integer.SIZE - 1) - leadingZeros;
- return (x <= cmp) ? logFloor : logFloor + 1;
-
- default:
- throw new AssertionError();
- }
- }
-
/** The biggest half power of two that can fit in an unsigned int. */
@VisibleForTesting static final int MAX_POWER_OF_SQRT2_UNSIGNED = 0xB504F333;
-
+
private static int log10Floor(int x) {
- /*
- * Based on Hacker's Delight Fig. 11-5, the two-table-lookup, branch-free implementation.
- *
- * The key idea is that based on the number of leading zeros (equivalently, floor(log2(x))),
- * we can narrow the possible floor(log10(x)) values to two. For example, if floor(log2(x))
- * is 6, then 64 <= x < 128, so floor(log10(x)) is either 1 or 2.
- */
- int y = maxLog10ForLeadingZeros[Integer.numberOfLeadingZeros(x)];
- // y is the higher of the two possible values of floor(log10(x))
-
- int sgn = (x - powersOf10[y]) >>> (Integer.SIZE - 1);
- /*
- * sgn is the sign bit of x - 10^y; it is 1 if x < 10^y, and 0 otherwise. If x < 10^y, then we
- * want the lower of the two possible values, or y - 1, otherwise, we want y.
- */
- return y - sgn;
+ for (int i = 1; i < POWERS_OF_10.length; i++) {
+ if (x < POWERS_OF_10[i]) {
+ return i - 1;
+ }
+ }
+ return POWERS_OF_10.length - 1;
}
- // maxLog10ForLeadingZeros[i] == floor(log10(2^(Long.SIZE - i)))
- @VisibleForTesting static final byte[] maxLog10ForLeadingZeros = {9, 9, 9, 8, 8, 8,
- 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0};
-
- @VisibleForTesting static final int[] powersOf10 = {1, 10, 100, 1000, 10000,
- 100000, 1000000, 10000000, 100000000, 1000000000};
+ @VisibleForTesting static final int[] POWERS_OF_10 =
+ {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
- // halfPowersOf10[i] = largest int less than 10^(i + 0.5)
- @VisibleForTesting static final int[] halfPowersOf10 =
+ // HALF_POWERS_OF_10[i] = largest int less than 10^(i + 0.5)
+ @VisibleForTesting static final int[] HALF_POWERS_OF_10 =
{3, 31, 316, 3162, 31622, 316227, 3162277, 31622776, 316227766, Integer.MAX_VALUE};
private static int sqrtFloor(int x) {
@@ -138,81 +79,17 @@ public final class IntMath {
}
/**
- * Returns the result of dividing {@code p} by {@code q}, rounding using the specified
- * {@code RoundingMode}.
- *
- * @throws ArithmeticException if {@code q == 0}, or if {@code mode == UNNECESSARY} and {@code a}
- * is not an integer multiple of {@code b}
- */
- @SuppressWarnings("fallthrough")
- public static int divide(int p, int q, RoundingMode mode) {
- checkNotNull(mode);
- if (q == 0) {
- throw new ArithmeticException("/ by zero"); // for GWT
- }
- int div = p / q;
- int rem = p - q * div; // equal to p % q
-
- if (rem == 0) {
- return div;
- }
-
- /*
- * Normal Java division rounds towards 0, consistently with RoundingMode.DOWN. We just have to
- * deal with the cases where rounding towards 0 is wrong, which typically depends on the sign of
- * p / q.
- *
- * signum is 1 if p and q are both nonnegative or both negative, and -1 otherwise.
- */
- int signum = 1 | ((p ^ q) >> (Integer.SIZE - 1));
- boolean increment;
- switch (mode) {
- case UNNECESSARY:
- checkRoundingUnnecessary(rem == 0);
- // fall through
- case DOWN:
- increment = false;
- break;
- case UP:
- increment = true;
- break;
- case CEILING:
- increment = signum > 0;
- break;
- case FLOOR:
- increment = signum < 0;
- break;
- case HALF_EVEN:
- case HALF_DOWN:
- case HALF_UP:
- int absRem = abs(rem);
- int cmpRemToHalfDivisor = absRem - (abs(q) - absRem);
- // subtracting two nonnegative ints can't overflow
- // cmpRemToHalfDivisor has the same sign as compare(abs(rem), abs(q) / 2).
- if (cmpRemToHalfDivisor == 0) { // exactly on the half mark
- increment = (mode == HALF_UP || (mode == HALF_EVEN & (div & 1) != 0));
- } else {
- increment = cmpRemToHalfDivisor > 0; // closer to the UP value
- }
- break;
- default:
- throw new AssertionError();
- }
- return increment ? div + signum : div;
- }
-
- /**
* Returns {@code x mod m}. This differs from {@code x % m} in that it always returns a
* non-negative result.
- *
+ *
* <p>For example:<pre> {@code
- *
+ *
* mod(7, 4) == 3
* mod(-7, 4) == 1
* mod(-1, 4) == 3
* mod(-8, 4) == 0
* mod(8, 4) == 0}</pre>
- *
+ *
* @throws ArithmeticException if {@code m <= 0}
*/
public static int mod(int x, int m) {
@@ -226,7 +103,7 @@ public final class IntMath {
/**
* Returns the greatest common divisor of {@code a, b}. Returns {@code 0} if
* {@code a == 0 && b == 0}.
- *
+ *
* @throws IllegalArgumentException if {@code a < 0} or {@code b < 0}
*/
public static int gcd(int a, int b) {
@@ -237,46 +114,18 @@ public final class IntMath {
*/
checkNonNegative("a", a);
checkNonNegative("b", b);
- if (a == 0) {
- // 0 % b == 0, so b divides a, but the converse doesn't hold.
- // BigInteger.gcd is consistent with this decision.
- return b;
- } else if (b == 0) {
- return a; // similar logic
- }
- /*
- * Uses the binary GCD algorithm; see http://en.wikipedia.org/wiki/Binary_GCD_algorithm.
- * This is >40% faster than the Euclidean algorithm in benchmarks.
- */
- int aTwos = Integer.numberOfTrailingZeros(a);
- a >>= aTwos; // divide out all 2s
- int bTwos = Integer.numberOfTrailingZeros(b);
- b >>= bTwos; // divide out all 2s
- while (a != b) { // both a, b are odd
- // The key to the binary GCD algorithm is as follows:
- // Both a and b are odd. Assume a > b; then gcd(a - b, b) = gcd(a, b).
- // But in gcd(a - b, b), a - b is even and b is odd, so we can divide out powers of two.
-
- // We bend over backwards to avoid branching, adapting a technique from
- // http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
-
- int delta = a - b; // can't overflow, since a and b are nonnegative
-
- int minDeltaOrZero = delta & (delta >> (Integer.SIZE - 1));
- // equivalent to Math.min(delta, 0)
-
- a = delta - minDeltaOrZero - minDeltaOrZero; // sets a to Math.abs(a - b)
- // a is now nonnegative and even
-
- b += minDeltaOrZero; // sets b to min(old a, b)
- a >>= Integer.numberOfTrailingZeros(a); // divide out all 2s, since 2 doesn't divide b
+ // The simple Euclidean algorithm is the fastest for ints, and is easily the most readable.
+ while (b != 0) {
+ int t = b;
+ b = a % b;
+ a = t;
}
- return a << min(aTwos, bTwos);
+ return a;
}
/**
* Returns the sum of {@code a} and {@code b}, provided it does not overflow.
- *
+ *
* @throws ArithmeticException if {@code a + b} overflows in signed {@code int} arithmetic
*/
public static int checkedAdd(int a, int b) {
@@ -287,7 +136,7 @@ public final class IntMath {
/**
* Returns the difference of {@code a} and {@code b}, provided it does not overflow.
- *
+ *
* @throws ArithmeticException if {@code a - b} overflows in signed {@code int} arithmetic
*/
public static int checkedSubtract(int a, int b) {
@@ -298,7 +147,7 @@ public final class IntMath {
/**
* Returns the product of {@code a} and {@code b}, provided it does not overflow.
- *
+ *
* @throws ArithmeticException if {@code a * b} overflows in signed {@code int} arithmetic
*/
public static int checkedMultiply(int a, int b) {
@@ -307,67 +156,9 @@ public final class IntMath {
return (int) result;
}
- /**
- * Returns the {@code b} to the {@code k}th power, provided it does not overflow.
- *
- * <p>{@link #pow} may be faster, but does not check for overflow.
- *
- * @throws ArithmeticException if {@code b} to the {@code k}th power overflows in signed
- * {@code int} arithmetic
- */
- public static int checkedPow(int b, int k) {
- checkNonNegative("exponent", k);
- switch (b) {
- case 0:
- return (k == 0) ? 1 : 0;
- case 1:
- return 1;
- case (-1):
- return ((k & 1) == 0) ? 1 : -1;
- case 2:
- checkNoOverflow(k < Integer.SIZE - 1);
- return 1 << k;
- case (-2):
- checkNoOverflow(k < Integer.SIZE);
- return ((k & 1) == 0) ? 1 << k : -1 << k;
- default:
- // continue below to handle the general case
- }
- int accum = 1;
- while (true) {
- switch (k) {
- case 0:
- return accum;
- case 1:
- return checkedMultiply(accum, b);
- default:
- if ((k & 1) != 0) {
- accum = checkedMultiply(accum, b);
- }
- k >>= 1;
- if (k > 0) {
- checkNoOverflow(-FLOOR_SQRT_MAX_INT <= b & b <= FLOOR_SQRT_MAX_INT);
- b *= b;
- }
- }
- }
- }
-
@VisibleForTesting static final int FLOOR_SQRT_MAX_INT = 46340;
-
- /**
- * Returns {@code n!}, that is, the product of the first {@code n} positive
- * integers, {@code 1} if {@code n == 0}, or {@link Integer#MAX_VALUE} if the
- * result does not fit in a {@code int}.
- *
- * @throws IllegalArgumentException if {@code n < 0}
- */
- public static int factorial(int n) {
- checkNonNegative("n", n);
- return (n < factorials.length) ? factorials[n] : Integer.MAX_VALUE;
- }
-
- private static final int[] factorials = {
+
+ static final int[] FACTORIALS = {
1,
1,
1 * 2,
@@ -382,8 +173,8 @@ public final class IntMath {
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11,
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12};
- // binomial(biggestBinomials[k], k) fits in an int, but not binomial(biggestBinomials[k]+1,k).
- @VisibleForTesting static int[] biggestBinomials = {
+ // binomial(BIGGEST_BINOMIALS[k], k) fits in an int, but not binomial(BIGGEST_BINOMIALS[k]+1,k).
+ @VisibleForTesting static int[] BIGGEST_BINOMIALS = {
Integer.MAX_VALUE,
Integer.MAX_VALUE,
65536,
@@ -402,20 +193,7 @@ public final class IntMath {
34,
33
};
-
- /**
- * Returns the arithmetic mean of {@code x} and {@code y}, rounded towards
- * negative infinity. This method is overflow resilient.
- *
- * @since 14.0
- */
- public static int mean(int x, int y) {
- // Efficient method for computing the arithmetic mean.
- // The alternative (x + y) / 2 fails for large values.
- // The alternative (x + y) >>> 1 fails for negative values.
- return (x & y) + ((x ^ y) >> 1);
- }
-
+
private IntMath() {}
}
diff --git a/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/LongMath.java b/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/LongMath.java
deleted file mode 100644
index 2f15360..0000000
--- a/guava-gwt/src-super/com/google/common/math/super/com/google/common/math/LongMath.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.math.MathPreconditions.checkNonNegative;
-import static com.google.common.math.MathPreconditions.checkPositive;
-import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
-import static java.lang.Math.min;
-import static java.math.RoundingMode.HALF_EVEN;
-import static java.math.RoundingMode.HALF_UP;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.VisibleForTesting;
-
-import java.math.RoundingMode;
-
-/**
- * A class for arithmetic on values of type {@code long}. Where possible, methods are defined and
- * named analogously to their {@code BigInteger} counterparts.
- *
- * <p>The implementations of many methods in this class are based on material from Henry S. Warren,
- * Jr.'s <i>Hacker's Delight</i>, (Addison Wesley, 2002).
- *
- * <p>Similar functionality for {@code int} and for {@link BigInteger} can be found in
- * {@link IntMath} and {@link BigIntegerMath} respectively. For other common operations on
- * {@code long} values, see {@link com.google.common.primitives.Longs}.
- *
- * @author Louis Wasserman
- * @since 11.0
- */
-@GwtCompatible(emulated = true)
-public final class LongMath {
- // NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
-
- /**
- * Returns {@code true} if {@code x} represents a power of two.
- *
- * <p>This differs from {@code Long.bitCount(x) == 1}, because
- * {@code Long.bitCount(Long.MIN_VALUE) == 1}, but {@link Long#MIN_VALUE} is not a power of two.
- */
- public static boolean isPowerOfTwo(long x) {
- return x > 0 & (x & (x - 1)) == 0;
- }
-
- /**
- * Returns the base-2 logarithm of {@code x}, rounded according to the specified rounding mode.
- *
- * @throws IllegalArgumentException if {@code x <= 0}
- * @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
- * is not a power of two
- */
- @SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
- public static int log2(long x, RoundingMode mode) {
- checkPositive("x", x);
- switch (mode) {
- case UNNECESSARY:
- checkRoundingUnnecessary(isPowerOfTwo(x));
- // fall through
- case DOWN:
- case FLOOR:
- return (Long.SIZE - 1) - Long.numberOfLeadingZeros(x);
-
- case UP:
- case CEILING:
- return Long.SIZE - Long.numberOfLeadingZeros(x - 1);
-
- case HALF_DOWN:
- case HALF_UP:
- case HALF_EVEN:
- // Since sqrt(2) is irrational, log2(x) - logFloor cannot be exactly 0.5
- int leadingZeros = Long.numberOfLeadingZeros(x);
- long cmp = MAX_POWER_OF_SQRT2_UNSIGNED >>> leadingZeros;
- // floor(2^(logFloor + 0.5))
- int logFloor = (Long.SIZE - 1) - leadingZeros;
- return (x <= cmp) ? logFloor : logFloor + 1;
-
- default:
- throw new AssertionError("impossible");
- }
- }
-
- /** The biggest half power of two that fits into an unsigned long */
- @VisibleForTesting static final long MAX_POWER_OF_SQRT2_UNSIGNED = 0xB504F333F9DE6484L;
-
- // maxLog10ForLeadingZeros[i] == floor(log10(2^(Long.SIZE - i)))
- @VisibleForTesting static final byte[] maxLog10ForLeadingZeros = {
- 19, 18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12,
- 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4,
- 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0 };
-
- // halfPowersOf10[i] = largest long less than 10^(i + 0.5)
-
- /**
- * Returns the greatest common divisor of {@code a, b}. Returns {@code 0} if
- * {@code a == 0 && b == 0}.
- *
- * @throws IllegalArgumentException if {@code a < 0} or {@code b < 0}
- */
- public static long gcd(long a, long b) {
- /*
- * The reason we require both arguments to be >= 0 is because otherwise, what do you return on
- * gcd(0, Long.MIN_VALUE)? BigInteger.gcd would return positive 2^63, but positive 2^63 isn't
- * an int.
- */
- checkNonNegative("a", a);
- checkNonNegative("b", b);
- if (a == 0) {
- // 0 % b == 0, so b divides a, but the converse doesn't hold.
- // BigInteger.gcd is consistent with this decision.
- return b;
- } else if (b == 0) {
- return a; // similar logic
- }
- /*
- * Uses the binary GCD algorithm; see http://en.wikipedia.org/wiki/Binary_GCD_algorithm.
- * This is >60% faster than the Euclidean algorithm in benchmarks.
- */
- int aTwos = Long.numberOfTrailingZeros(a);
- a >>= aTwos; // divide out all 2s
- int bTwos = Long.numberOfTrailingZeros(b);
- b >>= bTwos; // divide out all 2s
- while (a != b) { // both a, b are odd
- // The key to the binary GCD algorithm is as follows:
- // Both a and b are odd. Assume a > b; then gcd(a - b, b) = gcd(a, b).
- // But in gcd(a - b, b), a - b is even and b is odd, so we can divide out powers of two.
-
- // We bend over backwards to avoid branching, adapting a technique from
- // http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
-
- long delta = a - b; // can't overflow, since a and b are nonnegative
-
- long minDeltaOrZero = delta & (delta >> (Long.SIZE - 1));
- // equivalent to Math.min(delta, 0)
-
- a = delta - minDeltaOrZero - minDeltaOrZero; // sets a to Math.abs(a - b)
- // a is now nonnegative and even
-
- b += minDeltaOrZero; // sets b to min(old a, b)
- a >>= Long.numberOfTrailingZeros(a); // divide out all 2s, since 2 doesn't divide b
- }
- return a << min(aTwos, bTwos);
- }
-
- static final long[] factorials = {
- 1L,
- 1L,
- 1L * 2,
- 1L * 2 * 3,
- 1L * 2 * 3 * 4,
- 1L * 2 * 3 * 4 * 5,
- 1L * 2 * 3 * 4 * 5 * 6,
- 1L * 2 * 3 * 4 * 5 * 6 * 7,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19,
- 1L * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20
- };
-
- /**
- * Returns {@code n} choose {@code k}, also known as the binomial coefficient of {@code n} and
- * {@code k}, or {@link Long#MAX_VALUE} if the result does not fit in a {@code long}.
- *
- * @throws IllegalArgumentException if {@code n < 0}, {@code k < 0}, or {@code k > n}
- */
- public static long binomial(int n, int k) {
- checkNonNegative("n", n);
- checkNonNegative("k", k);
- checkArgument(k <= n, "k (%s) > n (%s)", k, n);
- if (k > (n >> 1)) {
- k = n - k;
- }
- switch (k) {
- case 0:
- return 1;
- case 1:
- return n;
- default:
- if (n < factorials.length) {
- return factorials[n] / (factorials[k] * factorials[n - k]);
- } else if (k >= biggestBinomials.length || n > biggestBinomials[k]) {
- return Long.MAX_VALUE;
- } else if (k < biggestSimpleBinomials.length && n <= biggestSimpleBinomials[k]) {
- // guaranteed not to overflow
- long result = n--;
- for (int i = 2; i <= k; n--, i++) {
- result *= n;
- result /= i;
- }
- return result;
- } else {
- int nBits = LongMath.log2(n, RoundingMode.CEILING);
-
- long result = 1;
- long numerator = n--;
- long denominator = 1;
-
- int numeratorBits = nBits;
- // This is an upper bound on log2(numerator, ceiling).
-
- /*
- * We want to do this in long math for speed, but want to avoid overflow. We adapt the
- * technique previously used by BigIntegerMath: maintain separate numerator and
- * denominator accumulators, multiplying the fraction into result when near overflow.
- */
- for (int i = 2; i <= k; i++, n--) {
- if (numeratorBits + nBits < Long.SIZE - 1) {
- // It's definitely safe to multiply into numerator and denominator.
- numerator *= n;
- denominator *= i;
- numeratorBits += nBits;
- } else {
- // It might not be safe to multiply into numerator and denominator,
- // so multiply (numerator / denominator) into result.
- result = multiplyFraction(result, numerator, denominator);
- numerator = n;
- denominator = i;
- numeratorBits = nBits;
- }
- }
- return multiplyFraction(result, numerator, denominator);
- }
- }
- }
-
- /**
- * Returns (x * numerator / denominator), which is assumed to come out to an integral value.
- */
- static long multiplyFraction(long x, long numerator, long denominator) {
- if (x == 1) {
- return numerator / denominator;
- }
- long commonDivisor = gcd(x, denominator);
- x /= commonDivisor;
- denominator /= commonDivisor;
- // We know gcd(x, denominator) = 1, and x * numerator / denominator is exact,
- // so denominator must be a divisor of numerator.
- return x * (numerator / denominator);
- }
-
- /*
- * binomial(biggestBinomials[k], k) fits in a long, but not
- * binomial(biggestBinomials[k] + 1, k).
- */
- static final int[] biggestBinomials =
- {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 3810779, 121977, 16175, 4337, 1733,
- 887, 534, 361, 265, 206, 169, 143, 125, 111, 101, 94, 88, 83, 79, 76, 74, 72, 70, 69, 68,
- 67, 67, 66, 66, 66, 66};
-
- /*
- * binomial(biggestSimpleBinomials[k], k) doesn't need to use the slower GCD-based impl,
- * but binomial(biggestSimpleBinomials[k] + 1, k) does.
- */
- @VisibleForTesting static final int[] biggestSimpleBinomials =
- {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 2642246, 86251, 11724, 3218, 1313,
- 684, 419, 287, 214, 169, 139, 119, 105, 95, 87, 81, 76, 73, 70, 68, 66, 64, 63, 62, 62,
- 61, 61, 61};
- // These values were generated by using checkedMultiply to see when the simple multiply/divide
- // algorithm would lead to an overflow.
-
- /**
- * Returns the arithmetic mean of {@code x} and {@code y}, rounded toward
- * negative infinity. This method is resilient to overflow.
- *
- * @since 14.0
- */
- public static long mean(long x, long y) {
- // Efficient method for computing the arithmetic mean.
- // The alternative (x + y) / 2 fails for large values.
- // The alternative (x + y) >>> 1 fails for negative values.
- return (x & y) + ((x ^ y) >> 1);
- }
-
- private LongMath() {}
-}
-
diff --git a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Chars.java b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Chars.java
index 62c716a..5f78865 100644
--- a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Chars.java
+++ b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Chars.java
@@ -38,10 +38,6 @@ import java.util.RandomAccess;
* <p>All the operations in this class treat {@code char} values strictly
* numerically; they are neither Unicode-aware nor locale-dependent.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -472,8 +468,7 @@ public final class Chars {
@Override public Character set(int index, Character element) {
checkElementIndex(index, size());
char oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -524,7 +519,7 @@ public final class Chars {
}
char[] toCharArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
char[] result = new char[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Ints.java b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Ints.java
index 8f9315d..0cee6c4 100644
--- a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Ints.java
+++ b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Ints.java
@@ -35,10 +35,6 @@ import java.util.RandomAccess;
* Static utility methods pertaining to {@code int} primitives, that are not
* already found in either {@link Integer} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -364,21 +360,20 @@ public final class Ints {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code int} value in the manner of {@link Number#intValue}.
+ * Copies a collection of {@code Integer} instances into a new array of
+ * primitive {@code int} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Integer} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Integer>} before 12.0)
*/
- public static int[] toArray(Collection<? extends Number> collection) {
+ public static int[] toArray(Collection<Integer> collection) {
if (collection instanceof IntArrayAsList) {
return ((IntArrayAsList) collection).toIntArray();
}
@@ -388,7 +383,7 @@ public final class Ints {
int[] array = new int[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).intValue();
+ array[i] = (Integer) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -475,8 +470,7 @@ public final class Ints {
@Override public Integer set(int index, Integer element) {
checkElementIndex(index, size());
int oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -527,7 +521,7 @@ public final class Ints {
}
int[] toIntArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
int[] result = new int[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Doubles.java b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Longs.java
index 3634fe7..000e055 100644
--- a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Doubles.java
+++ b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Longs.java
@@ -20,8 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static java.lang.Double.NEGATIVE_INFINITY;
-import static java.lang.Double.POSITIVE_INFINITY;
import com.google.common.annotations.GwtCompatible;
@@ -34,80 +32,69 @@ import java.util.List;
import java.util.RandomAccess;
/**
- * Static utility methods pertaining to {@code double} primitives, that are not
- * already found in either {@link Double} or {@link Arrays}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
+ * Static utility methods pertaining to {@code long} primitives, that are not
+ * already found in either {@link Long} or {@link Arrays}.
*
* @author Kevin Bourrillion
* @since 1.0
*/
@GwtCompatible(emulated = true)
-public final class Doubles {
- private Doubles() {}
+public final class Longs {
+ private Longs() {}
/**
- * The number of bytes required to represent a primitive {@code double}
+ * The number of bytes required to represent a primitive {@code long}
* value.
+ */
+ public static final int BYTES = Long.SIZE / Byte.SIZE;
+
+ /**
+ * The largest power of two that can be represented as a {@code long}.
*
* @since 10.0
*/
- public static final int BYTES = Double.SIZE / Byte.SIZE;
+ public static final long MAX_POWER_OF_TWO = 1L << (Long.SIZE - 2);
/**
* Returns a hash code for {@code value}; equal to the result of invoking
- * {@code ((Double) value).hashCode()}.
+ * {@code ((Long) value).hashCode()}.
+ *
+ * <p>This method always return the value specified by {@link
+ * Long#hashCode()} in java, which might be different from
+ * {@code ((Long) value).hashCode()} in GWT because {@link Long#hashCode()}
+ * in GWT does not obey the JRE contract.
*
- * @param value a primitive {@code double} value
+ * @param value a primitive {@code long} value
* @return a hash code for the value
*/
- public static int hashCode(double value) {
- return ((Double) value).hashCode();
- // TODO(kevinb): do it this way when we can (GWT problem):
- // long bits = Double.doubleToLongBits(value);
- // return (int)(bits ^ (bits >>> 32));
+ public static int hashCode(long value) {
+ return (int) (value ^ (value >>> 32));
}
/**
- * Compares the two specified {@code double} values. The sign of the value
- * returned is the same as that of <code>((Double) a).{@linkplain
- * Double#compareTo compareTo}(b)</code>. As with that method, {@code NaN} is
- * treated as greater than all other values, and {@code 0.0 > -0.0}.
+ * Compares the two specified {@code long} values. The sign of the value
+ * returned is the same as that of {@code ((Long) a).compareTo(b)}.
*
- * @param a the first {@code double} to compare
- * @param b the second {@code double} to compare
+ * @param a the first {@code long} to compare
+ * @param b the second {@code long} to compare
* @return a negative value if {@code a} is less than {@code b}; a positive
* value if {@code a} is greater than {@code b}; or zero if they are equal
*/
- public static int compare(double a, double b) {
- return Double.compare(a, b);
- }
-
- /**
- * Returns {@code true} if {@code value} represents a real number. This is
- * equivalent to, but not necessarily implemented as,
- * {@code !(Double.isInfinite(value) || Double.isNaN(value))}.
- *
- * @since 10.0
- */
- public static boolean isFinite(double value) {
- return NEGATIVE_INFINITY < value & value < POSITIVE_INFINITY;
+ public static int compare(long a, long b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
}
/**
* Returns {@code true} if {@code target} is present as an element anywhere in
- * {@code array}. Note that this always returns {@code false} when {@code
- * target} is {@code NaN}.
+ * {@code array}.
*
- * @param array an array of {@code double} values, possibly empty
- * @param target a primitive {@code double} value
+ * @param array an array of {@code long} values, possibly empty
+ * @param target a primitive {@code long} value
* @return {@code true} if {@code array[i] == target} for some value of {@code
* i}
*/
- public static boolean contains(double[] array, double target) {
- for (double value : array) {
+ public static boolean contains(long[] array, long target) {
+ for (long value : array) {
if (value == target) {
return true;
}
@@ -117,21 +104,20 @@ public final class Doubles {
/**
* Returns the index of the first appearance of the value {@code target} in
- * {@code array}. Note that this always returns {@code -1} when {@code target}
- * is {@code NaN}.
+ * {@code array}.
*
- * @param array an array of {@code double} values, possibly empty
- * @param target a primitive {@code double} value
+ * @param array an array of {@code long} values, possibly empty
+ * @param target a primitive {@code long} value
* @return the least index {@code i} for which {@code array[i] == target}, or
* {@code -1} if no such index exists.
*/
- public static int indexOf(double[] array, double target) {
+ public static int indexOf(long[] array, long target) {
return indexOf(array, target, 0, array.length);
}
// TODO(kevinb): consider making this public
private static int indexOf(
- double[] array, double target, int start, int end) {
+ long[] array, long target, int start, int end) {
for (int i = start; i < end; i++) {
if (array[i] == target) {
return i;
@@ -148,13 +134,10 @@ public final class Doubles {
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
* the same elements as {@code target}.
*
- * <p>Note that this always returns {@code -1} when {@code target} contains
- * {@code NaN}.
- *
* @param array the array to search for the sequence {@code target}
* @param target the array to search for as a sub-sequence of {@code array}
*/
- public static int indexOf(double[] array, double[] target) {
+ public static int indexOf(long[] array, long[] target) {
checkNotNull(array, "array");
checkNotNull(target, "target");
if (target.length == 0) {
@@ -175,21 +158,20 @@ public final class Doubles {
/**
* Returns the index of the last appearance of the value {@code target} in
- * {@code array}. Note that this always returns {@code -1} when {@code target}
- * is {@code NaN}.
+ * {@code array}.
*
- * @param array an array of {@code double} values, possibly empty
- * @param target a primitive {@code double} value
+ * @param array an array of {@code long} values, possibly empty
+ * @param target a primitive {@code long} value
* @return the greatest index {@code i} for which {@code array[i] == target},
* or {@code -1} if no such index exists.
*/
- public static int lastIndexOf(double[] array, double target) {
+ public static int lastIndexOf(long[] array, long target) {
return lastIndexOf(array, target, 0, array.length);
}
// TODO(kevinb): consider making this public
private static int lastIndexOf(
- double[] array, double target, int start, int end) {
+ long[] array, long target, int start, int end) {
for (int i = end - 1; i >= start; i--) {
if (array[i] == target) {
return i;
@@ -199,58 +181,60 @@ public final class Doubles {
}
/**
- * Returns the least value present in {@code array}, using the same rules of
- * comparison as {@link Math#min(double, double)}.
+ * Returns the least value present in {@code array}.
*
- * @param array a <i>nonempty</i> array of {@code double} values
+ * @param array a <i>nonempty</i> array of {@code long} values
* @return the value present in {@code array} that is less than or equal to
* every other value in the array
* @throws IllegalArgumentException if {@code array} is empty
*/
- public static double min(double... array) {
+ public static long min(long... array) {
checkArgument(array.length > 0);
- double min = array[0];
+ long min = array[0];
for (int i = 1; i < array.length; i++) {
- min = Math.min(min, array[i]);
+ if (array[i] < min) {
+ min = array[i];
+ }
}
return min;
}
/**
- * Returns the greatest value present in {@code array}, using the same rules
- * of comparison as {@link Math#max(double, double)}.
+ * Returns the greatest value present in {@code array}.
*
- * @param array a <i>nonempty</i> array of {@code double} values
+ * @param array a <i>nonempty</i> array of {@code long} values
* @return the value present in {@code array} that is greater than or equal to
* every other value in the array
* @throws IllegalArgumentException if {@code array} is empty
*/
- public static double max(double... array) {
+ public static long max(long... array) {
checkArgument(array.length > 0);
- double max = array[0];
+ long max = array[0];
for (int i = 1; i < array.length; i++) {
- max = Math.max(max, array[i]);
+ if (array[i] > max) {
+ max = array[i];
+ }
}
return max;
}
/**
* Returns the values from each provided array combined into a single array.
- * For example, {@code concat(new double[] {a, b}, new double[] {}, new
- * double[] {c}} returns the array {@code {a, b, c}}.
+ * For example, {@code concat(new long[] {a, b}, new long[] {}, new
+ * long[] {c}} returns the array {@code {a, b, c}}.
*
- * @param arrays zero or more {@code double} arrays
+ * @param arrays zero or more {@code long} arrays
* @return a single array containing all the values from the source arrays, in
* order
*/
- public static double[] concat(double[]... arrays) {
+ public static long[] concat(long[]... arrays) {
int length = 0;
- for (double[] array : arrays) {
+ for (long[] array : arrays) {
length += array.length;
}
- double[] result = new double[length];
+ long[] result = new long[length];
int pos = 0;
- for (double[] array : arrays) {
+ for (long[] array : arrays) {
System.arraycopy(array, 0, result, pos, array.length);
pos += array.length;
}
@@ -273,8 +257,8 @@ public final class Doubles {
* @return an array containing the values of {@code array}, with guaranteed
* minimum length {@code minLength}
*/
- public static double[] ensureCapacity(
- double[] array, int minLength, int padding) {
+ public static long[] ensureCapacity(
+ long[] array, int minLength, int padding) {
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
checkArgument(padding >= 0, "Invalid padding: %s", padding);
return (array.length < minLength)
@@ -283,34 +267,29 @@ public final class Doubles {
}
// Arrays.copyOf() requires Java 6
- private static double[] copyOf(double[] original, int length) {
- double[] copy = new double[length];
+ private static long[] copyOf(long[] original, int length) {
+ long[] copy = new long[length];
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
return copy;
}
/**
- * Returns a string containing the supplied {@code double} values, converted
- * to strings as specified by {@link Double#toString(double)}, and separated
- * by {@code separator}. For example, {@code join("-", 1.0, 2.0, 3.0)} returns
- * the string {@code "1.0-2.0-3.0"}.
- *
- * <p>Note that {@link Double#toString(double)} formats {@code double}
- * differently in GWT sometimes. In the previous example, it returns the
- * string {@code "1-2-3"}.
+ * Returns a string containing the supplied {@code long} values separated
+ * by {@code separator}. For example, {@code join("-", 1L, 2L, 3L)} returns
+ * the string {@code "1-2-3"}.
*
* @param separator the text that should appear between consecutive values in
* the resulting string (but not at the start or end)
- * @param array an array of {@code double} values, possibly empty
+ * @param array an array of {@code long} values, possibly empty
*/
- public static String join(String separator, double... array) {
+ public static String join(String separator, long... array) {
checkNotNull(separator);
if (array.length == 0) {
return "";
}
// For pre-sizing a builder, just get the right order of magnitude
- StringBuilder builder = new StringBuilder(array.length * 12);
+ StringBuilder builder = new StringBuilder(array.length * 10);
builder.append(array[0]);
for (int i = 1; i < array.length; i++) {
builder.append(separator).append(array[i]);
@@ -319,33 +298,33 @@ public final class Doubles {
}
/**
- * Returns a comparator that compares two {@code double} arrays
+ * Returns a comparator that compares two {@code long} arrays
* lexicographically. That is, it compares, using {@link
- * #compare(double, double)}), the first pair of values that follow any
+ * #compare(long, long)}), the first pair of values that follow any
* common prefix, or when one array is a prefix of the other, treats the
* shorter array as the lesser. For example,
- * {@code [] < [1.0] < [1.0, 2.0] < [2.0]}.
+ * {@code [] < [1L] < [1L, 2L] < [2L]}.
*
* <p>The returned comparator is inconsistent with {@link
* Object#equals(Object)} (since arrays support only identity equality), but
- * it is consistent with {@link Arrays#equals(double[], double[])}.
+ * it is consistent with {@link Arrays#equals(long[], long[])}.
*
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
* Lexicographical order article at Wikipedia</a>
* @since 2.0
*/
- public static Comparator<double[]> lexicographicalComparator() {
+ public static Comparator<long[]> lexicographicalComparator() {
return LexicographicalComparator.INSTANCE;
}
- private enum LexicographicalComparator implements Comparator<double[]> {
+ private enum LexicographicalComparator implements Comparator<long[]> {
INSTANCE;
@Override
- public int compare(double[] left, double[] right) {
+ public int compare(long[] left, long[] right) {
int minLength = Math.min(left.length, right.length);
for (int i = 0; i < minLength; i++) {
- int result = Doubles.compare(left[i], right[i]);
+ int result = Longs.compare(left[i], right[i]);
if (result != 0) {
return result;
}
@@ -355,31 +334,30 @@ public final class Doubles {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code double} value in the manner of {@link Number#doubleValue}.
+ * Copies a collection of {@code Long} instances into a new array of
+ * primitive {@code long} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Long} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Double>} before 12.0)
*/
- public static double[] toArray(Collection<? extends Number> collection) {
- if (collection instanceof DoubleArrayAsList) {
- return ((DoubleArrayAsList) collection).toDoubleArray();
+ public static long[] toArray(Collection<Long> collection) {
+ if (collection instanceof LongArrayAsList) {
+ return ((LongArrayAsList) collection).toLongArray();
}
Object[] boxedArray = collection.toArray();
int len = boxedArray.length;
- double[] array = new double[len];
+ long[] array = new long[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).doubleValue();
+ array[i] = (Long) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -391,35 +369,32 @@ public final class Doubles {
* NullPointerException}.
*
* <p>The returned list maintains the values, but not the identities, of
- * {@code Double} objects written to or read from it. For example, whether
+ * {@code Long} objects written to or read from it. For example, whether
* {@code list.get(0) == list.get(0)} is true for the returned list is
* unspecified.
*
- * <p>The returned list may have unexpected behavior if it contains {@code
- * NaN}, or if {@code NaN} is used as a parameter to any of its methods.
- *
* @param backingArray the array to back the list
* @return a list view of the array
*/
- public static List<Double> asList(double... backingArray) {
+ public static List<Long> asList(long... backingArray) {
if (backingArray.length == 0) {
return Collections.emptyList();
}
- return new DoubleArrayAsList(backingArray);
+ return new LongArrayAsList(backingArray);
}
@GwtCompatible
- private static class DoubleArrayAsList extends AbstractList<Double>
+ private static class LongArrayAsList extends AbstractList<Long>
implements RandomAccess, Serializable {
- final double[] array;
+ final long[] array;
final int start;
final int end;
- DoubleArrayAsList(double[] array) {
+ LongArrayAsList(long[] array) {
this(array, 0, array.length);
}
- DoubleArrayAsList(double[] array, int start, int end) {
+ LongArrayAsList(long[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
@@ -433,21 +408,21 @@ public final class Doubles {
return false;
}
- @Override public Double get(int index) {
+ @Override public Long get(int index) {
checkElementIndex(index, size());
return array[start + index];
}
@Override public boolean contains(Object target) {
// Overridden to prevent a ton of boxing
- return (target instanceof Double)
- && Doubles.indexOf(array, (Double) target, start, end) != -1;
+ return (target instanceof Long)
+ && Longs.indexOf(array, (Long) target, start, end) != -1;
}
@Override public int indexOf(Object target) {
// Overridden to prevent a ton of boxing
- if (target instanceof Double) {
- int i = Doubles.indexOf(array, (Double) target, start, end);
+ if (target instanceof Long) {
+ int i = Longs.indexOf(array, (Long) target, start, end);
if (i >= 0) {
return i - start;
}
@@ -457,8 +432,8 @@ public final class Doubles {
@Override public int lastIndexOf(Object target) {
// Overridden to prevent a ton of boxing
- if (target instanceof Double) {
- int i = Doubles.lastIndexOf(array, (Double) target, start, end);
+ if (target instanceof Long) {
+ int i = Longs.lastIndexOf(array, (Long) target, start, end);
if (i >= 0) {
return i - start;
}
@@ -466,29 +441,28 @@ public final class Doubles {
return -1;
}
- @Override public Double set(int index, Double element) {
+ @Override public Long set(int index, Long element) {
checkElementIndex(index, size());
- double oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ long oldValue = array[start + index];
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
- @Override public List<Double> subList(int fromIndex, int toIndex) {
+ @Override public List<Long> subList(int fromIndex, int toIndex) {
int size = size();
checkPositionIndexes(fromIndex, toIndex, size);
if (fromIndex == toIndex) {
return Collections.emptyList();
}
- return new DoubleArrayAsList(array, start + fromIndex, start + toIndex);
+ return new LongArrayAsList(array, start + fromIndex, start + toIndex);
}
@Override public boolean equals(Object object) {
if (object == this) {
return true;
}
- if (object instanceof DoubleArrayAsList) {
- DoubleArrayAsList that = (DoubleArrayAsList) object;
+ if (object instanceof LongArrayAsList) {
+ LongArrayAsList that = (LongArrayAsList) object;
int size = size();
if (that.size() != size) {
return false;
@@ -506,13 +480,13 @@ public final class Doubles {
@Override public int hashCode() {
int result = 1;
for (int i = start; i < end; i++) {
- result = 31 * result + Doubles.hashCode(array[i]);
+ result = 31 * result + Longs.hashCode(array[i]);
}
return result;
}
@Override public String toString() {
- StringBuilder builder = new StringBuilder(size() * 12);
+ StringBuilder builder = new StringBuilder(size() * 10);
builder.append('[').append(array[start]);
for (int i = start + 1; i < end; i++) {
builder.append(", ").append(array[i]);
@@ -520,10 +494,10 @@ public final class Doubles {
return builder.append(']').toString();
}
- double[] toDoubleArray() {
- // Arrays.copyOfRange() is not available under GWT
+ long[] toLongArray() {
+ // Arrays.copyOfRange() requires Java 6
int size = size();
- double[] result = new double[size];
+ long[] result = new long[size];
System.arraycopy(array, start, result, 0, size);
return result;
}
diff --git a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Shorts.java b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Shorts.java
index 92899c7..d1cee13 100644
--- a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Shorts.java
+++ b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Shorts.java
@@ -35,10 +35,6 @@ import java.util.RandomAccess;
* Static utility methods pertaining to {@code short} primitives, that are not
* already found in either {@link Short} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -366,21 +362,20 @@ public final class Shorts {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code short} value in the manner of {@link Number#shortValue}.
+ * Copies a collection of {@code Short} instances into a new array of
+ * primitive {@code short} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Short} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Short>} before 12.0)
*/
- public static short[] toArray(Collection<? extends Number> collection) {
+ public static short[] toArray(Collection<Short> collection) {
if (collection instanceof ShortArrayAsList) {
return ((ShortArrayAsList) collection).toShortArray();
}
@@ -390,7 +385,7 @@ public final class Shorts {
short[] array = new short[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).shortValue();
+ array[i] = (Short) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -477,8 +472,7 @@ public final class Shorts {
@Override public Short set(int index, Short element) {
checkElementIndex(index, size());
short oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -529,7 +523,7 @@ public final class Shorts {
}
short[] toShortArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
short[] result = new short[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/UnsignedInteger.java b/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/UnsignedInteger.java
deleted file mode 100644
index 20e6dce..0000000
--- a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/UnsignedInteger.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.primitives;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.primitives.UnsignedInts.INT_MASK;
-import static com.google.common.primitives.UnsignedInts.compare;
-import static com.google.common.primitives.UnsignedInts.toLong;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
-import java.math.BigInteger;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nullable;
-
-/**
- * A wrapper class for unsigned {@code int} values, supporting arithmetic operations.
- *
- * <p>In some cases, when speed is more important than code readability, it may be faster simply to
- * treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
- * unsigned primitive utilities</a>.
- *
- * @author Louis Wasserman
- * @since 11.0
- */
-@GwtCompatible(emulated = true)
-public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
- public static final UnsignedInteger ZERO = asUnsigned(0);
- public static final UnsignedInteger ONE = asUnsigned(1);
- public static final UnsignedInteger MAX_VALUE = asUnsigned(-1);
-
- private final int value;
-
- private UnsignedInteger(int value) {
- // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
- this.value = value & 0xffffffff;
- }
-
- /**
- * Returns an {@code UnsignedInteger} that, when treated as signed, is
- * equal to {@code value}.
- *
- * @deprecated Use {@link #fromIntBits(int)}. This method is scheduled to be removed in Guava
- * release 15.0.
- */
- @Deprecated
- @Beta
- public static UnsignedInteger asUnsigned(int value) {
- return fromIntBits(value);
- }
-
- /**
- * Returns an {@code UnsignedInteger} corresponding to a given bit representation.
- * The argument is interpreted as an unsigned 32-bit value. Specifically, the sign bit
- * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual.
- *
- * <p>If the argument is nonnegative, the returned result will be equal to {@code bits},
- * otherwise, the result will be equal to {@code 2^32 + bits}.
- *
- * <p>To represent unsigned decimal constants, consider {@link #valueOf(long)} instead.
- *
- * @since 14.0
- */
- public static UnsignedInteger fromIntBits(int bits) {
- return new UnsignedInteger(bits);
- }
-
- /**
- * Returns an {@code UnsignedInteger} that is equal to {@code value},
- * if possible. The inverse operation of {@link #longValue()}.
- */
- public static UnsignedInteger valueOf(long value) {
- checkArgument((value & INT_MASK) == value,
- "value (%s) is outside the range for an unsigned integer value", value);
- return fromIntBits((int) value);
- }
-
- /**
- * Returns a {@code UnsignedInteger} representing the same value as the specified
- * {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
- *
- * @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32}
- */
- public static UnsignedInteger valueOf(BigInteger value) {
- checkNotNull(value);
- checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
- "value (%s) is outside the range for an unsigned integer value", value);
- return fromIntBits(value.intValue());
- }
-
- /**
- * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
- * as an unsigned {@code int} value.
- *
- * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
- * value
- */
- public static UnsignedInteger valueOf(String string) {
- return valueOf(string, 10);
- }
-
- /**
- * Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
- * as an unsigned {@code int} value in the specified radix.
- *
- * @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
- * value
- */
- public static UnsignedInteger valueOf(String string, int radix) {
- return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix));
- }
-
- /**
- * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
- * returns the low 32 bits of the result.
- *
- * @deprecated Use {@link #plus(UnsignedInteger)}. This method is scheduled to be removed in Guava
- * release 15.0.
- */
- @Deprecated
- @Beta
- public UnsignedInteger add(UnsignedInteger val) {
- return plus(val);
- }
-
- /**
- * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
- * returns the low 32 bits of the result.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger plus(UnsignedInteger val) {
- return fromIntBits(this.value + checkNotNull(val).value);
- }
-
- /**
- * Returns the result of subtracting this and {@code val}. If the result would be negative,
- * returns the low 32 bits of the result.
- *
- * @deprecated Use {@link #minus(UnsignedInteger)}. This method is scheduled to be removed in
- * Guava release 15.0.
- */
- @Deprecated
- @Beta
- public UnsignedInteger subtract(UnsignedInteger val) {
- return minus(val);
- }
-
- /**
- * Returns the result of subtracting this and {@code val}. If the result would be negative,
- * returns the low 32 bits of the result.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger minus(UnsignedInteger val) {
- return fromIntBits(value - checkNotNull(val).value);
- }
-
- /**
- * Returns the result of dividing this by {@code val}.
- *
- * @deprecated Use {@link #dividedBy(UnsignedInteger)}. This method is scheduled to be removed in
- * Guava release 15.0.
- */
- @Deprecated
- @Beta
- public UnsignedInteger divide(UnsignedInteger val) {
- return dividedBy(val);
- }
-
- /**
- * Returns the result of dividing this by {@code val}.
- *
- * @throws ArithmeticException if {@code val} is zero
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger dividedBy(UnsignedInteger val) {
- return fromIntBits(UnsignedInts.divide(value, checkNotNull(val).value));
- }
-
- /**
- * Returns the remainder of dividing this by {@code val}.
- *
- * @deprecated Use {@link #mod(UnsignedInteger)}. This method is scheduled to be removed in Guava
- * release 15.0.
- */
- @Deprecated
- @Beta
- public UnsignedInteger remainder(UnsignedInteger val) {
- return mod(val);
- }
-
- /**
- * Returns this mod {@code val}.
- *
- * @throws ArithmeticException if {@code val} is zero
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger mod(UnsignedInteger val) {
- return fromIntBits(UnsignedInts.remainder(value, checkNotNull(val).value));
- }
-
- /**
- * Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse
- * operation to {@link #fromIntBits}.
- *
- * <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value
- * will be equal to {@code this - 2^32}.
- */
- @Override
- public int intValue() {
- return value;
- }
-
- /**
- * Returns the value of this {@code UnsignedInteger} as a {@code long}.
- */
- @Override
- public long longValue() {
- return toLong(value);
- }
-
- /**
- * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
- * primitive conversion from {@code int} to {@code float}, and correctly rounded.
- */
- @Override
- public float floatValue() {
- return longValue();
- }
-
- /**
- * Returns the value of this {@code UnsignedInteger} as a {@code float}, analogous to a widening
- * primitive conversion from {@code int} to {@code double}, and correctly rounded.
- */
- @Override
- public double doubleValue() {
- return longValue();
- }
-
- /**
- * Returns the value of this {@code UnsignedInteger} as a {@link BigInteger}.
- */
- public BigInteger bigIntegerValue() {
- return BigInteger.valueOf(longValue());
- }
-
- /**
- * Compares this unsigned integer to another unsigned integer.
- * Returns {@code 0} if they are equal, a negative number if {@code this < other},
- * and a positive number if {@code this > other}.
- */
- @Override
- public int compareTo(UnsignedInteger other) {
- checkNotNull(other);
- return compare(value, other.value);
- }
-
- @Override
- public int hashCode() {
- return value;
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof UnsignedInteger) {
- UnsignedInteger other = (UnsignedInteger) obj;
- return value == other.value;
- }
- return false;
- }
-
- /**
- * Returns a string representation of the {@code UnsignedInteger} value, in base 10.
- */
- @Override
- public String toString() {
- return toString(10);
- }
-
- /**
- * Returns a string representation of the {@code UnsignedInteger} value, in base {@code radix}.
- * If {@code radix < Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}, the radix
- * {@code 10} is used.
- */
- public String toString(int radix) {
- return UnsignedInts.toString(value, radix);
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/testing/super/com/google/common/testing/Platform.java b/guava-gwt/src-super/com/google/common/testing/super/com/google/common/testing/Platform.java
index 9fa092e..9fa092e 100644
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/testing/super/com/google/common/testing/Platform.java
+++ b/guava-gwt/src-super/com/google/common/testing/super/com/google/common/testing/Platform.java
diff --git a/guava-gwt/src-super/java/nio/charset/Charset.gwt.xml b/guava-gwt/src-super/java/nio/charset/Charset.gwt.xml
deleted file mode 100644
index d23fb8c..0000000
--- a/guava-gwt/src-super/java/nio/charset/Charset.gwt.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<module>
- <source path=""/>
- <inherits name="java.nio.charset.Charset"/>
-</module> \ No newline at end of file
diff --git a/guava-gwt/src-super/java/nio/charset/Charset.java b/guava-gwt/src-super/java/nio/charset/Charset.java
deleted file mode 100644
index 1463333..0000000
--- a/guava-gwt/src-super/java/nio/charset/Charset.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.charset;
-
-import java.util.Collections;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * A minimal GWT emulation of {@link Charset}.
- *
- * @author Gregory Kick
- */
-public abstract class Charset implements Comparable<Charset> {
- private static final Charset UTF_8 = new Charset("UTF-8") {};
-
- private static final SortedMap<String, Charset> AVAILABLE_CHARSETS =
- new TreeMap<String, Charset>();
- static {
- AVAILABLE_CHARSETS.put(UTF_8.name(), UTF_8);
- }
-
- public static SortedMap<String, Charset> availableCharsets() {
- return Collections.unmodifiableSortedMap(AVAILABLE_CHARSETS);
- }
-
- public static Charset forName(String charsetName) {
- if (charsetName == null) {
- throw new IllegalArgumentException("Null charset name");
- }
- int length = charsetName.length();
- if (length == 0) {
- throw new IllegalCharsetNameException(charsetName);
- }
- for (int i = 0; i < length; i++) {
- char c = charsetName.charAt(i);
- if ((c >= 'A' && c <= 'Z')
- || (c >= 'a' && c <= 'z')
- || (c >= '0' && c <= '9')
- || (c == '-' && i != 0)
- || (c == ':' && i != 0)
- || (c == '_' && i != 0)
- || (c == '.' && i != 0)) {
- continue;
- }
- throw new IllegalCharsetNameException(charsetName);
- }
- Charset charset = AVAILABLE_CHARSETS.get(charsetName.toUpperCase());
- if (charset != null) {
- return charset;
- }
- throw new UnsupportedCharsetException(charsetName);
- }
-
- private final String name;
-
- private Charset(String name) {
- this.name = name;
- }
-
- public final String name() {
- return name;
- }
-
- public final int compareTo(Charset that) {
- return this.name.compareToIgnoreCase(that.name);
- }
-
- public final int hashCode() {
- return name.hashCode();
- }
-
- public final boolean equals(Object o) {
- if (o == this) {
- return true;
- } else if (o instanceof Charset) {
- Charset that = (Charset) o;
- return this.name.equals(that.name);
- } else {
- return false;
- }
- }
-
- public final String toString() {
- return name;
- }
-}
diff --git a/guava-gwt/src-super/java/nio/charset/IllegalCharsetNameException.java b/guava-gwt/src-super/java/nio/charset/IllegalCharsetNameException.java
deleted file mode 100644
index 19755e2..0000000
--- a/guava-gwt/src-super/java/nio/charset/IllegalCharsetNameException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.charset;
-
-/**
- * GWT emulation of {@link IllegalCharsetNameException}.
- *
- * @author Gregory Kick
- */
-public class IllegalCharsetNameException extends IllegalArgumentException {
- private final String charsetName;
-
- public IllegalCharsetNameException(String charsetName) {
- super(String.valueOf(charsetName));
- this.charsetName = charsetName;
- }
-
- public String getCharsetName() {
- return charsetName;
- }
-}
diff --git a/guava-gwt/src-super/java/nio/charset/UnsupportedCharsetException.java b/guava-gwt/src-super/java/nio/charset/UnsupportedCharsetException.java
deleted file mode 100644
index f489a1d..0000000
--- a/guava-gwt/src-super/java/nio/charset/UnsupportedCharsetException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio.charset;
-
-/**
- * GWT emulation of {@link UnsupportedCharsetException}.
- *
- * @author Gregory Kick
- */
-public class UnsupportedCharsetException extends IllegalArgumentException {
- private final String charsetName;
-
- public UnsupportedCharsetException(String charsetName) {
- super(String.valueOf(charsetName));
- this.charsetName = charsetName;
- }
-
- public String getCharsetName() {
- return charsetName;
- }
-}
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/Callable.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/Callable.java
index 607d3f7..548f3a6 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/Callable.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/Callable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Guava Authors
+ * Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentHashMap.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentHashMap.java
index 886d8f7..77544b5 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentHashMap.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentHashMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentMap.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentMap.java
index 49c05ce..61a8a04 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentMap.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/ConcurrentMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/ExecutionException.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/ExecutionException.java
index c1fc0f4..b25f476 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/ExecutionException.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/ExecutionException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Guava Authors
+ * Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package java.util.concurrent;
/**
* Emulation of ExecutionException.
*
- * @author Charles Fry
+ * @author fry@google.com (Charles Fry)
*/
public class ExecutionException extends Exception {
protected ExecutionException() { }
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/TimeUnit.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/TimeUnit.java
index 52f3fb4..2ce1de3 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/TimeUnit.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/TimeUnit.java
@@ -1,8 +1,4 @@
/*
- * This file is a modified version of
- * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/TimeUnit.java
- * which contained the following notice:
- *
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicInteger.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicInteger.java
index d9c16a6..ac98dcf 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicInteger.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicInteger.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicLong.java b/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicLong.java
index fdd1b34..8696422 100644
--- a/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicLong.java
+++ b/guava-gwt/src-super/java/util/super/java/util/concurrent/atomic/AtomicLong.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Guava Authors
+ * Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-gwt/src/com/google/common/ForceGuavaCompilation.gwt.xml b/guava-gwt/src/com/google/common/ForceGuavaCompilation.gwt.xml
deleted file mode 100644
index 9c4d507..0000000
--- a/guava-gwt/src/com/google/common/ForceGuavaCompilation.gwt.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<module>
- <inherits name="com.google.common.annotations.Annotations" />
- <inherits name="com.google.common.base.Base" />
- <inherits name="com.google.common.cache.Cache" />
- <inherits name="com.google.common.collect.Collect" />
- <inherits name="com.google.common.io.Io" />
- <inherits name="com.google.common.math.Math" />
- <inherits name="com.google.common.net.Net" />
- <inherits name="com.google.common.primitives.Primitives" />
- <inherits name="com.google.common.util.concurrent.Concurrent" />
- <inherits name="com.google.gwt.user.User" />
-
- <source path="" />
- <entry-point class="com.google.common.ForceGuavaCompilationEntryPoint" />
-</module>
diff --git a/guava-gwt/src/com/google/common/ForceGuavaCompilationEntryPoint.java b/guava-gwt/src/com/google/common/ForceGuavaCompilationEntryPoint.java
deleted file mode 100644
index f7260a2..0000000
--- a/guava-gwt/src/com/google/common/ForceGuavaCompilationEntryPoint.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common;
-
-import com.google.gwt.core.client.EntryPoint;
-
-/**
- * A dummy entry point to convince Maven to compile our classes.
- *
- * @author Chris Povirk
- */
-public class ForceGuavaCompilationEntryPoint implements EntryPoint {
- @Override public void onModuleLoad() {
- }
-}
diff --git a/guava-gwt/src/com/google/common/annotations/Annotations.gwt.xml b/guava-gwt/src/com/google/common/annotations/Annotations.gwt.xml
index 8903a62..0b388fa 100644
--- a/guava-gwt/src/com/google/common/annotations/Annotations.gwt.xml
+++ b/guava-gwt/src/com/google/common/annotations/Annotations.gwt.xml
@@ -1,4 +1,3 @@
-<!-- semi-autogenerated module descriptor -->
<module>
-<source path=""/>
+ <source path=""/>
</module>
diff --git a/guava-gwt/src/com/google/common/base/Absent_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/base/Absent_CustomFieldSerializer.java
deleted file mode 100644
index ecdac0f..0000000
--- a/guava-gwt/src/com/google/common/base/Absent_CustomFieldSerializer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * Custom GWT serializer for {@link Absent}.
- *
- * <p>GWT can serialize an absent {@code Optional} on its own, but the resulting object is a
- * different instance than the singleton {@code Absent.INSTANCE}, which breaks equality. We
- * implement a custom serializer to maintain the singleton property.
- *
- * @author Chris Povirk
- */
-@GwtCompatible
-public class Absent_CustomFieldSerializer {
- public static void deserialize(SerializationStreamReader reader, Absent instance) {}
-
- public static Absent instantiate(SerializationStreamReader reader) {
- return Absent.INSTANCE;
- }
-
- public static void serialize(SerializationStreamWriter writer, Absent instance) {}
-}
diff --git a/guava-gwt/src/com/google/common/base/Base.gwt.xml b/guava-gwt/src/com/google/common/base/Base.gwt.xml
index d0c84c8..f1ca187 100644
--- a/guava-gwt/src/com/google/common/base/Base.gwt.xml
+++ b/guava-gwt/src/com/google/common/base/Base.gwt.xml
@@ -1,15 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
-
<source path=""/>
-
<super-source path="super"/>
-
- <inherits name="java.nio.charset.Charset"/>
-
<inherits name="java.util.Util"/>
-
- <inherits name="com.google.common.annotations.Annotations"/>
-
</module>
diff --git a/guava-gwt/src/com/google/common/base/GwtSerializationDependencies.java b/guava-gwt/src/com/google/common/base/GwtSerializationDependencies.java
index 7f0643f..77f93f2 100644
--- a/guava-gwt/src/com/google/common/base/GwtSerializationDependencies.java
+++ b/guava-gwt/src/com/google/common/base/GwtSerializationDependencies.java
@@ -18,10 +18,6 @@ package com.google.common.base;
import com.google.common.annotations.GwtCompatible;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
/**
* Contains dummy collection implementations to convince GWT that part of
* serializing a collection is serializing its elements.
@@ -36,57 +32,4 @@ import javax.annotation.Nullable;
@SuppressWarnings("serial")
final class GwtSerializationDependencies {
private GwtSerializationDependencies() {}
-
- static final class OptionalDependencies<T> extends Optional<T> {
- T value;
-
- OptionalDependencies() {
- super();
- }
-
- @Override public boolean isPresent() {
- throw new AssertionError();
- }
-
- @Override public T get() {
- throw new AssertionError();
- }
-
- @Override public T or(T defaultValue) {
- throw new AssertionError();
- }
-
- @Override public Optional<T> or(Optional<? extends T> secondChoice) {
- throw new AssertionError();
- }
-
- @Override public T or(Supplier<? extends T> supplier) {
- throw new AssertionError();
- }
-
- @Override public T orNull() {
- throw new AssertionError();
- }
-
- @Override public Set<T> asSet() {
- throw new AssertionError();
- }
-
- @Override public <V> Optional<V> transform(
- Function<? super T, V> function) {
- throw new AssertionError();
- }
-
- @Override public boolean equals(@Nullable Object object) {
- throw new AssertionError();
- }
-
- @Override public int hashCode() {
- throw new AssertionError();
- }
-
- @Override public String toString() {
- throw new AssertionError();
- }
- }
}
diff --git a/guava-gwt/src/com/google/common/base/PairwiseEquivalence_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/base/PairwiseEquivalence_CustomFieldSerializer.java
index 531550c..6f125f9 100644
--- a/guava-gwt/src/com/google/common/base/PairwiseEquivalence_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/base/PairwiseEquivalence_CustomFieldSerializer.java
@@ -23,7 +23,7 @@ import com.google.gwt.user.client.rpc.SerializationStreamWriter;
/**
* GWT serialization logic for {@link PairwiseEquivalence}.
*
- * @author Kedar Kanitkar
+ * @author kkanitkar@google.com (Kedar Kanitkar)
*/
public class PairwiseEquivalence_CustomFieldSerializer {
diff --git a/guava-gwt/src/com/google/common/base/Present_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/base/Present_CustomFieldSerializer.java
deleted file mode 100644
index 710086d..0000000
--- a/guava-gwt/src/com/google/common/base/Present_CustomFieldSerializer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * Custom GWT serializer for {@link Present}.
- *
- * @author Chris Povirk
- */
-@GwtCompatible
-public class Present_CustomFieldSerializer {
- public static void deserialize(SerializationStreamReader reader, Present<?> instance) {}
-
- public static Present<Object> instantiate(SerializationStreamReader reader)
- throws SerializationException {
- return (Present<Object>) Optional.of(reader.readObject());
- }
-
- public static void serialize(SerializationStreamWriter writer, Present<?> instance)
- throws SerializationException {
- writer.writeObject(instance.get());
- }
-}
diff --git a/guava-gwt/src/com/google/common/cache/Cache.gwt.xml b/guava-gwt/src/com/google/common/cache/Cache.gwt.xml
index 62c7187..9c5b758 100644
--- a/guava-gwt/src/com/google/common/cache/Cache.gwt.xml
+++ b/guava-gwt/src/com/google/common/cache/Cache.gwt.xml
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
<source path=""/>
<super-source path="super"/>
-
- <inherits name="java.util.Util"/>
<inherits name="com.google.common.annotations.Annotations"/>
@@ -16,4 +13,6 @@
<inherits name="com.google.common.util.concurrent.Concurrent"/>
+ <inherits name="java.util.Util"/>
+
</module>
diff --git a/guava-gwt/src/com/google/common/collect/AllEqualOrdering_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/AllEqualOrdering_CustomFieldSerializer.java
deleted file mode 100644
index 4b9d370..0000000
--- a/guava-gwt/src/com/google/common/collect/AllEqualOrdering_CustomFieldSerializer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * This class implements the GWT serialization of {@link AllEqualOrdering}.
- *
- * @author Chris Povirk
- */
-public class AllEqualOrdering_CustomFieldSerializer {
- public static void deserialize(SerializationStreamReader reader, AllEqualOrdering instance) {
- }
-
- public static AllEqualOrdering instantiate(SerializationStreamReader reader) {
- return AllEqualOrdering.INSTANCE;
- }
-
- public static void serialize(SerializationStreamWriter writer, AllEqualOrdering instance) {
- }
-}
diff --git a/guava-gwt/src/com/google/common/collect/Collect.gwt.xml b/guava-gwt/src/com/google/common/collect/Collect.gwt.xml
index e042bcb..31441af 100644
--- a/guava-gwt/src/com/google/common/collect/Collect.gwt.xml
+++ b/guava-gwt/src/com/google/common/collect/Collect.gwt.xml
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
<source path=""/>
<super-source path="super"/>
-
- <inherits name="java.util.Util"/>
<inherits name="com.google.common.annotations.Annotations"/>
@@ -15,5 +12,7 @@
<inherits name="com.google.common.math.Math"/>
<inherits name="com.google.common.primitives.Primitives"/>
-
+
+ <inherits name="java.util.Util"/>
+
</module>
diff --git a/guava-gwt/src/com/google/common/collect/EmptyImmutableBiMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/EmptyImmutableMap_CustomFieldSerializer.java
index c2d7a05..67d63b2 100644
--- a/guava-gwt/src/com/google/common/collect/EmptyImmutableBiMap_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/EmptyImmutableMap_CustomFieldSerializer.java
@@ -21,18 +21,22 @@ import com.google.gwt.user.client.rpc.SerializationStreamWriter;
/**
* This class implements the GWT serialization of
- * {@link EmptyImmutableBiMap}.
- *
+ * {@link EmptyImmutableMap}.
+ *
* @author Chris Povirk
*/
-public class EmptyImmutableBiMap_CustomFieldSerializer {
- public static void deserialize(SerializationStreamReader reader, EmptyImmutableBiMap instance) {
+public class EmptyImmutableMap_CustomFieldSerializer {
+
+ public static void deserialize(SerializationStreamReader reader,
+ EmptyImmutableMap instance) {
}
- public static EmptyImmutableBiMap instantiate(SerializationStreamReader reader) {
- return EmptyImmutableBiMap.INSTANCE;
+ public static EmptyImmutableMap instantiate(
+ SerializationStreamReader reader) {
+ return EmptyImmutableMap.INSTANCE;
}
- public static void serialize(SerializationStreamWriter writer, EmptyImmutableBiMap instance) {
+ public static void serialize(SerializationStreamWriter writer,
+ EmptyImmutableMap instance) {
}
}
diff --git a/guava-gwt/src/com/google/common/collect/EmptyImmutableSortedMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/EmptyImmutableSortedMap_CustomFieldSerializer.java
deleted file mode 100644
index a47f6a0..0000000
--- a/guava-gwt/src/com/google/common/collect/EmptyImmutableSortedMap_CustomFieldSerializer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * This class implements the GWT serialization of {@link EmptyImmutableSortedMap}.
- *
- * @author Chris Povirk
- */
-public class EmptyImmutableSortedMap_CustomFieldSerializer {
- public static void deserialize(
- SerializationStreamReader reader, EmptyImmutableSortedMap<?, ?> instance) {
- }
-
- public static EmptyImmutableSortedMap<?, ?> instantiate(
- SerializationStreamReader reader) throws SerializationException {
- return (EmptyImmutableSortedMap<?, ?>)
- ImmutableSortedMap_CustomFieldSerializerBase.instantiate(reader);
- }
-
- public static void serialize(
- SerializationStreamWriter writer, EmptyImmutableSortedMap<?, ?> instance)
- throws SerializationException {
- ImmutableSortedMap_CustomFieldSerializerBase.serialize(writer, instance);
- }
-}
diff --git a/guava-gwt/src/com/google/common/collect/GwtPlatform.java b/guava-gwt/src/com/google/common/collect/GwtPlatform.java
deleted file mode 100644
index e4d62e1..0000000
--- a/guava-gwt/src/com/google/common/collect/GwtPlatform.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.gwt.core.client.GwtScriptOnly;
-
-import java.lang.reflect.Array;
-
-// TODO(kevinb): guava javadoc path seems set wrong, doesn't find that last
-// import
-/**
- * Version of {@link GwtPlatform} used in hosted-mode. It includes methods in
- * {@link Platform} that requires different implementions in web mode and
- * hosted mode. It is factored out from {@link Platform} because {@code
- * GwtScriptOnly} only supports public classes and methods.
- *
- * @author Hayward Chan
- */
-// TODO(hhchan): Once we start using server-side source in hosted mode, we won't
-// need this.
-@GwtCompatible(emulated = true)
-@GwtScriptOnly
-public final class GwtPlatform {
-
- private GwtPlatform() {}
-
- /** See {@link Platform#clone(Object[])} */
- public static <T> T[] clone(T[] array) {
- return array.clone();
- }
-
- /** See {@link Platform#newArray(Object[], int)} */
- public static <T> T[] newArray(T[] reference, int length) {
- Class<?> type = reference.getClass().getComponentType();
-
- // the cast is safe because
- // result.getClass() == reference.getClass().getComponentType()
- @SuppressWarnings("unchecked")
- T[] result = (T[]) Array.newInstance(type, length);
- return result;
- }
-}
diff --git a/guava-gwt/src/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java
index 7466c22..4cb55ee 100644
--- a/guava-gwt/src/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/ImmutableAsList_CustomFieldSerializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2010 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,40 @@
package com.google.common.collect;
+import com.google.common.annotations.GwtCompatible;
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.client.rpc.SerializationStreamReader;
+import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+import com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase;
+
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * Even though {@link ImmutableAsList} cannot be instantiated, we still need
- * a custom field serializer. TODO(cpovirk): why?
+ * This class implements the server-side GWT serialization of
+ * {@link ImmutableAsList}.
*
* @author Hayward Chan
*/
-public final class ImmutableAsList_CustomFieldSerializer {}
+@GwtCompatible(emulated = true)
+public class ImmutableAsList_CustomFieldSerializer {
+
+ public static void deserialize(SerializationStreamReader reader,
+ ImmutableAsList<?> instance) {
+ }
+
+ public static ImmutableAsList<Object> instantiate(
+ SerializationStreamReader reader) throws SerializationException {
+ List<Object> elements = new ArrayList<Object>();
+ Collection_CustomFieldSerializerBase.deserialize(reader, elements);
+ ImmutableList<Object> asImmutableList = ImmutableList.copyOf(elements);
+ return new ImmutableAsList<Object>(
+ asImmutableList.toArray(new Object[asImmutableList.size()]),
+ asImmutableList);
+ }
+
+ public static void serialize(SerializationStreamWriter writer,
+ ImmutableAsList<?> instance) throws SerializationException {
+ Collection_CustomFieldSerializerBase.serialize(writer, instance);
+ }
+}
diff --git a/guava-gwt/src/com/google/common/collect/ImmutableBiMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/ImmutableBiMap_CustomFieldSerializer.java
deleted file mode 100644
index 5f290dc..0000000
--- a/guava-gwt/src/com/google/common/collect/ImmutableBiMap_CustomFieldSerializer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-/**
- * Even though {@link ImmutableBiMap} cannot be instantiated, we still need
- * a custom field serializer to unify the type signature of
- * {@code ImmutableBiMap[]} on server and client side.
- *
- * @author Hayward Chan
- */
-public final class ImmutableBiMap_CustomFieldSerializer {}
diff --git a/guava-gwt/src/com/google/common/collect/ImmutableEntry_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/ImmutableEntry_CustomFieldSerializer.java
index 821c33a..ab1512a 100644
--- a/guava-gwt/src/com/google/common/collect/ImmutableEntry_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/ImmutableEntry_CustomFieldSerializer.java
@@ -24,7 +24,7 @@ import com.google.gwt.user.client.rpc.SerializationStreamWriter;
* This class implements the GWT serialization of
* {@link ImmutableEntry}.
*
- * @author Kyle Butt
+ * @author iteratee@google.com (Kyle Butt)
*/
public class ImmutableEntry_CustomFieldSerializer {
diff --git a/guava-gwt/src/com/google/common/collect/ImmutableEnumMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/ImmutableEnumMap_CustomFieldSerializer.java
deleted file mode 100644
index 868cb74..0000000
--- a/guava-gwt/src/com/google/common/collect/ImmutableEnumMap_CustomFieldSerializer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-import com.google.gwt.user.client.rpc.core.java.util.Map_CustomFieldSerializerBase;
-
-import java.util.Map;
-
-/**
- * This class implements the GWT serialization of {@link ImmutableEnumMap}.
- *
- * @author Louis Wasserman
- */
-public class ImmutableEnumMap_CustomFieldSerializer {
-
- public static void deserialize(SerializationStreamReader reader,
- ImmutableEnumMap<?, ?> instance) {
- }
-
- public static <K extends Enum<K>, V> ImmutableEnumMap<?, ?> instantiate(
- SerializationStreamReader reader) throws SerializationException {
- Map<K, V> deserialized = Maps.newHashMap();
- Map_CustomFieldSerializerBase.deserialize(reader, deserialized);
- /*
- * It is safe to cast to ImmutableEnumSet because in order for it to be
- * serialized as an ImmutableEnumSet, it must be non-empty to start
- * with.
- */
- return (ImmutableEnumMap<?, ?>) Maps.immutableEnumMap(deserialized);
- }
-
- public static void serialize(SerializationStreamWriter writer,
- ImmutableEnumMap<?, ?> instance) throws SerializationException {
- Map_CustomFieldSerializerBase.serialize(writer, instance);
- }
-
-}
diff --git a/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializer.java
index 70cf908..6293686 100644
--- a/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializer.java
@@ -16,11 +16,44 @@
package com.google.common.collect;
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.client.rpc.SerializationStreamReader;
+import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+import com.google.gwt.user.client.rpc.core.java.util.Map_CustomFieldSerializerBase;
+
+import java.util.Comparator;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
/**
- * Even though {@link ImmutableSortedMap} cannot be instantiated, we still need a custom field
- * serializer. TODO(cpovirk): why? Does it help if ensure that the GWT and non-GWT classes have the
- * same fields? Is that worth the trouble?
+ * This class implements the GWT serialization of {@link ImmutableSortedMap}.
*
* @author Chris Povirk
*/
-public final class ImmutableSortedMap_CustomFieldSerializer {}
+public class ImmutableSortedMap_CustomFieldSerializer {
+ public static void deserialize(SerializationStreamReader reader,
+ ImmutableSortedMap<?, ?> instance) {
+ }
+
+ public static ImmutableSortedMap<?, ?> instantiate(
+ SerializationStreamReader reader) throws SerializationException {
+ /*
+ * Nothing we can do, but we're already assuming the serialized form is
+ * correctly typed, anyway.
+ */
+ @SuppressWarnings("unchecked")
+ Comparator<Object> comparator = (Comparator<Object>) reader.readObject();
+
+ SortedMap<Object, Object> entries = new TreeMap<Object, Object>(comparator);
+ Map_CustomFieldSerializerBase.deserialize(reader, entries);
+
+ return ImmutableSortedMap.orderedBy(comparator).putAll(entries).build();
+ }
+
+ public static void serialize(SerializationStreamWriter writer,
+ ImmutableSortedMap<?, ?> instance) throws SerializationException {
+ writer.writeObject(instance.comparator());
+
+ Map_CustomFieldSerializerBase.serialize(writer, instance);
+ }
+}
diff --git a/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializerBase.java b/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializerBase.java
deleted file mode 100644
index 4ccaaa1..0000000
--- a/guava-gwt/src/com/google/common/collect/ImmutableSortedMap_CustomFieldSerializerBase.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-import com.google.gwt.user.client.rpc.core.java.util.Map_CustomFieldSerializerBase;
-
-import java.util.Comparator;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * This class contains static utility methods for writing {@code ImmutableSortedMap} GWT field
- * serializers.
- *
- * @author Chris Povirk
- */
-final class ImmutableSortedMap_CustomFieldSerializerBase {
- static ImmutableSortedMap<Object, Object> instantiate(SerializationStreamReader reader)
- throws SerializationException {
- /*
- * Nothing we can do, but we're already assuming the serialized form is
- * correctly typed, anyway.
- */
- @SuppressWarnings("unchecked")
- Comparator<Object> comparator = (Comparator<Object>) reader.readObject();
-
- SortedMap<Object, Object> entries = new TreeMap<Object, Object>(comparator);
- Map_CustomFieldSerializerBase.deserialize(reader, entries);
-
- return ImmutableSortedMap.orderedBy(comparator).putAll(entries).build();
- }
-
- static void serialize(SerializationStreamWriter writer, ImmutableSortedMap<?, ?> instance)
- throws SerializationException {
- writer.writeObject(instance.comparator());
-
- Map_CustomFieldSerializerBase.serialize(writer, instance);
- }
-
- private ImmutableSortedMap_CustomFieldSerializerBase() {}
-}
diff --git a/guava-gwt/src/com/google/common/collect/LexicographicalOrdering_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/LexicographicalOrdering_CustomFieldSerializer.java
index 597207d..fdc1956 100644
--- a/guava-gwt/src/com/google/common/collect/LexicographicalOrdering_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/LexicographicalOrdering_CustomFieldSerializer.java
@@ -21,8 +21,7 @@ import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
/**
- * This class implements the GWT serialization of {@link
- * LexicographicalOrdering}.
+ * This class implements the GWT serialization of {@link LexicographicalOrdering}.
*
* @author Chris Povirk
*/
diff --git a/guava-gwt/src/com/google/common/collect/LinkedHashMultimap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/LinkedHashMultimap_CustomFieldSerializer.java
index a0a9163..30a280e 100644
--- a/guava-gwt/src/com/google/common/collect/LinkedHashMultimap_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/LinkedHashMultimap_CustomFieldSerializer.java
@@ -20,13 +20,11 @@ import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-import java.util.Collection;
-import java.util.LinkedHashMap;
import java.util.Map;
/**
* This class implements the GWT serialization of {@link LinkedHashMultimap}.
- *
+ *
* @author Chris Povirk
*/
public class LinkedHashMultimap_CustomFieldSerializer {
@@ -36,39 +34,28 @@ public class LinkedHashMultimap_CustomFieldSerializer {
}
public static LinkedHashMultimap<Object, Object> instantiate(
- SerializationStreamReader stream) throws SerializationException {
- LinkedHashMultimap<Object, Object> multimap = LinkedHashMultimap.create();
-
- multimap.valueSetCapacity = stream.readInt();
- int distinctKeys = stream.readInt();
- Map<Object, Collection<Object>> map =
- new LinkedHashMap<Object, Collection<Object>>(Maps.capacity(distinctKeys));
- for (int i = 0; i < distinctKeys; i++) {
- Object key = stream.readObject();
- map.put(key, multimap.createCollection(key));
+ SerializationStreamReader in) throws SerializationException {
+ LinkedHashMultimap<Object, Object> multimap =
+ (LinkedHashMultimap<Object, Object>)
+ Multimap_CustomFieldSerializerBase.populate(
+ in, LinkedHashMultimap.create());
+
+ multimap.linkedEntries.clear(); // will clear and repopulate entries
+ for (int i = 0; i < multimap.size(); i++) {
+ Object key = in.readObject();
+ Object value = in.readObject();
+ multimap.linkedEntries.add(Maps.immutableEntry(key, value));
}
- int entries = stream.readInt();
- for (int i = 0; i < entries; i++) {
- Object key = stream.readObject();
- Object value = stream.readObject();
- map.get(key).add(value);
- }
- multimap.setMap(map);
return multimap;
}
- public static void serialize(SerializationStreamWriter stream,
+ public static void serialize(SerializationStreamWriter out,
LinkedHashMultimap<?, ?> multimap) throws SerializationException {
- stream.writeInt(multimap.valueSetCapacity);
- stream.writeInt(multimap.keySet().size());
- for (Object key : multimap.keySet()) {
- stream.writeObject(key);
- }
- stream.writeInt(multimap.size());
+ Multimap_CustomFieldSerializerBase.serialize(out, multimap);
for (Map.Entry<?, ?> entry : multimap.entries()) {
- stream.writeObject(entry.getKey());
- stream.writeObject(entry.getValue());
+ out.writeObject(entry.getKey());
+ out.writeObject(entry.getValue());
}
}
}
diff --git a/guava-gwt/src/com/google/common/collect/Multiset_CustomFieldSerializerBase.java b/guava-gwt/src/com/google/common/collect/Multiset_CustomFieldSerializerBase.java
index 7c44bba..0cad199 100644
--- a/guava-gwt/src/com/google/common/collect/Multiset_CustomFieldSerializerBase.java
+++ b/guava-gwt/src/com/google/common/collect/Multiset_CustomFieldSerializerBase.java
@@ -23,12 +23,25 @@ import com.google.gwt.user.client.rpc.SerializationStreamWriter;
/**
* This class contains static utility methods for writing {@code Multiset} GWT
* field serializers. Serializers should delegate to
- * {@link #serialize(SerializationStreamWriter, Multiset)} and
+ * {@link #serialize(SerializationStreamWriter, Multiset)} and to either
+ * {@link #instantiate(SerializationStreamReader, ImmutableMultiset.Builder)} or
* {@link #populate(SerializationStreamReader, Multiset)}.
*
* @author Chris Povirk
*/
final class Multiset_CustomFieldSerializerBase {
+ static ImmutableMultiset<Object> instantiate(
+ SerializationStreamReader reader,
+ ImmutableMultiset.Builder<Object> builder)
+ throws SerializationException {
+ int distinctElements = reader.readInt();
+ for (int i = 0; i < distinctElements; i++) {
+ Object element = reader.readObject();
+ int count = reader.readInt();
+ builder.addCopies(element, count);
+ }
+ return builder.build();
+ }
static Multiset<Object> populate(
SerializationStreamReader reader, Multiset<Object> multiset)
diff --git a/guava-gwt/src/com/google/common/collect/RegularImmutableSortedMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/RegularImmutableSortedMap_CustomFieldSerializer.java
deleted file mode 100644
index 9f64e37..0000000
--- a/guava-gwt/src/com/google/common/collect/RegularImmutableSortedMap_CustomFieldSerializer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * This class implements the GWT serialization of {@link RegularImmutableSortedMap}.
- *
- * @author Chris Povirk
- */
-public class RegularImmutableSortedMap_CustomFieldSerializer {
- public static void deserialize(
- SerializationStreamReader reader, RegularImmutableSortedMap<?, ?> instance) {
- }
-
- public static RegularImmutableSortedMap<?, ?> instantiate(
- SerializationStreamReader reader) throws SerializationException {
- return (RegularImmutableSortedMap<?, ?>)
- ImmutableSortedMap_CustomFieldSerializerBase.instantiate(reader);
- }
-
- public static void serialize(
- SerializationStreamWriter writer, RegularImmutableSortedMap<?, ?> instance)
- throws SerializationException {
- ImmutableSortedMap_CustomFieldSerializerBase.serialize(writer, instance);
- }
-}
diff --git a/guava-gwt/src/com/google/common/collect/SingletonImmutableBiMap_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/collect/SingletonImmutableMap_CustomFieldSerializer.java
index 7b87633..6a3ef38 100644
--- a/guava-gwt/src/com/google/common/collect/SingletonImmutableBiMap_CustomFieldSerializer.java
+++ b/guava-gwt/src/com/google/common/collect/SingletonImmutableMap_CustomFieldSerializer.java
@@ -23,25 +23,25 @@ import com.google.gwt.user.client.rpc.SerializationStreamReader;
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
/**
- * This class implements the GWT serialization of {@link SingletonImmutableBiMap}.
+ * This class implements the GWT serialization of {@link SingletonImmutableMap}.
*
* @author Chris Povirk
*/
-public class SingletonImmutableBiMap_CustomFieldSerializer {
+public class SingletonImmutableMap_CustomFieldSerializer {
public static void deserialize(SerializationStreamReader reader,
- SingletonImmutableBiMap<?, ?> instance) {
+ SingletonImmutableMap<?, ?> instance) {
}
- public static SingletonImmutableBiMap<Object, Object> instantiate(
+ public static SingletonImmutableMap<Object, Object> instantiate(
SerializationStreamReader reader) throws SerializationException {
Object key = checkNotNull(reader.readObject());
Object value = checkNotNull(reader.readObject());
- return new SingletonImmutableBiMap<Object, Object>(key, value);
+ return new SingletonImmutableMap<Object, Object>(key, value);
}
public static void serialize(SerializationStreamWriter writer,
- SingletonImmutableBiMap<?, ?> instance) throws SerializationException {
+ SingletonImmutableMap<?, ?> instance) throws SerializationException {
writer.writeObject(instance.singleKey);
writer.writeObject(instance.singleValue);
}
diff --git a/guava-gwt/src/com/google/common/io/Io.gwt.xml b/guava-gwt/src/com/google/common/io/Io.gwt.xml
deleted file mode 100644
index f272c7c..0000000
--- a/guava-gwt/src/com/google/common/io/Io.gwt.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
-<module>
-
- <source path=""/>
-
- <super-source path="super"/>
-
- <inherits name="com.google.common.annotations.Annotations"/>
-
- <inherits name="com.google.common.base.Base"/>
-
- <inherits name="com.google.common.math.Math"/>
-
- <inherits name="com.google.common.primitives.Primitives"/>
-
-</module>
diff --git a/guava-gwt/src/com/google/common/math/Math.gwt.xml b/guava-gwt/src/com/google/common/math/Math.gwt.xml
index a87feb1..1ccb925 100644
--- a/guava-gwt/src/com/google/common/math/Math.gwt.xml
+++ b/guava-gwt/src/com/google/common/math/Math.gwt.xml
@@ -1,13 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
-
<source path=""/>
-
<super-source path="super"/>
-
<inherits name="com.google.common.annotations.Annotations"/>
-
<inherits name="com.google.common.base.Base"/>
-
</module>
diff --git a/guava-gwt/src/com/google/common/net/Net.gwt.xml b/guava-gwt/src/com/google/common/net/Net.gwt.xml
index b6f5049..6df61fb 100644
--- a/guava-gwt/src/com/google/common/net/Net.gwt.xml
+++ b/guava-gwt/src/com/google/common/net/Net.gwt.xml
@@ -1,19 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
<source path=""/>
<super-source path="super"/>
-
- <inherits name="java.nio.charset.Charset"/>
-
- <inherits name="java.util.Util"/>
<inherits name="com.google.common.annotations.Annotations"/>
<inherits name="com.google.common.base.Base"/>
<inherits name="com.google.common.collect.Collect"/>
-
+
+ <inherits name="com.google.common.escape.Escape"/>
+
+ <inherits name="com.google.common.primitives.Primitives"/>
+
+ <inherits name="java.util.Util"/>
+
</module>
diff --git a/guava-gwt/src/com/google/common/primitives/Primitives.gwt.xml b/guava-gwt/src/com/google/common/primitives/Primitives.gwt.xml
index 3966a51..fa86e6b 100644
--- a/guava-gwt/src/com/google/common/primitives/Primitives.gwt.xml
+++ b/guava-gwt/src/com/google/common/primitives/Primitives.gwt.xml
@@ -1,13 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
-
- <source path=""/>
-
- <super-source path="super"/>
-
- <inherits name="com.google.common.annotations.Annotations"/>
-
- <inherits name="com.google.common.base.Base"/>
-
+ <source path=""/>
+ <super-source path="super"/>
+ <inherits name="com.google.common.annotations.Annotations"/>
+ <inherits name="com.google.common.base.Base"/>
</module>
diff --git a/guava-gwt/src/com/google/common/primitives/UnsignedLong_CustomFieldSerializer.java b/guava-gwt/src/com/google/common/primitives/UnsignedLong_CustomFieldSerializer.java
deleted file mode 100644
index 732730e..0000000
--- a/guava-gwt/src/com/google/common/primitives/UnsignedLong_CustomFieldSerializer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.primitives;
-
-import com.google.gwt.user.client.rpc.SerializationException;
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
-
-/**
- * This class implements the GWT serialization of {@code UnsignedLong}.
- *
- * @author Louis Wasserman
- */
-public class UnsignedLong_CustomFieldSerializer {
- public static void deserialize(SerializationStreamReader reader,
- UnsignedLong instance) {}
-
- public static UnsignedLong instantiate(SerializationStreamReader reader)
- throws SerializationException {
- return UnsignedLong.fromLongBits(reader.readLong());
- }
-
- public static void serialize(SerializationStreamWriter writer,
- UnsignedLong instance) throws SerializationException {
- writer.writeLong(instance.longValue());
- }
-}
diff --git a/guava-gwt/src/com/google/common/util/concurrent/Concurrent.gwt.xml b/guava-gwt/src/com/google/common/util/concurrent/Concurrent.gwt.xml
index 1bb0da0..cc8ffd6 100644
--- a/guava-gwt/src/com/google/common/util/concurrent/Concurrent.gwt.xml
+++ b/guava-gwt/src/com/google/common/util/concurrent/Concurrent.gwt.xml
@@ -1,13 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
-
<source path=""/>
-
<inherits name="com.google.common.annotations.Annotations"/>
-
- <inherits name="com.google.common.base.Base"/>
-
- <inherits name="com.google.common.collect.Collect"/>
-
</module>
diff --git a/guava-gwt/test/com/google/common/cache/TestModuleEntryPoint.java b/guava-gwt/test/com/google/common/cache/TestModuleEntryPoint.java
deleted file mode 100644
index baf8478..0000000
--- a/guava-gwt/test/com/google/common/cache/TestModuleEntryPoint.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.gwt.core.client.EntryPoint;
-
-/**
- * A dummy entry point of the test module.
- *
- * @author Hayward Chan
- */
-public class TestModuleEntryPoint implements EntryPoint {
-
- @Override public void onModuleLoad() {
- }
-}
diff --git a/guava-gwt/test/com/google/common/cache/testModule.gwt.xml b/guava-gwt/test/com/google/common/cache/testModule.gwt.xml
deleted file mode 100644
index 7de886b..0000000
--- a/guava-gwt/test/com/google/common/cache/testModule.gwt.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<module>
- <inherits name="com.google.gwt.user.User"/>
- <inherits name="com.google.gwt.junit.JUnit"/>
- <inherits name="com.google.common.annotations.Annotations"/>
- <inherits name="com.google.common.base.Base"/>
- <inherits name="com.google.common.cache.Cache"/>
- <inherits name="com.google.common.collect.Collect"/>
- <inherits name="com.google.common.testing.Testing"/>
- <inherits name="com.google.common.util.concurrent.Concurrent"/>
- <inherits name="org.junit.contrib.truth.Truth"/>
- <entry-point class="com.google.common.cache.TestModuleEntryPoint"/>
-
- <source path=""/>
-
- <add-linker name="std"/>
-
- <super-source path="super"/>
-
-</module>
diff --git a/guava-gwt/test/com/google/common/collect/testModule.gwt.xml b/guava-gwt/test/com/google/common/collect/testModule.gwt.xml
index 72ee8bf..47b2f23 100644
--- a/guava-gwt/test/com/google/common/collect/testModule.gwt.xml
+++ b/guava-gwt/test/com/google/common/collect/testModule.gwt.xml
@@ -4,10 +4,9 @@
<inherits name="com.google.gwt.junit.JUnit"/>
<inherits name="com.google.common.base.Base"/>
<inherits name="com.google.common.collect.Collect"/>
- <inherits name="com.google.common.collect.testing.Testing"/>
- <inherits name="com.google.common.collect.testing.google.Google"/>
<inherits name="com.google.common.testing.Testing"/>
<inherits name="org.junit.contrib.truth.Truth"/>
+ <inherits name="com.google.common.annotations.Annotations"/>
<entry-point class="com.google.common.collect.TestModuleEntryPoint"/>
<source path=""/>
diff --git a/guava-gwt/test/com/google/common/io/TestModuleEntryPoint.java b/guava-gwt/test/com/google/common/io/TestModuleEntryPoint.java
deleted file mode 100644
index e06885a..0000000
--- a/guava-gwt/test/com/google/common/io/TestModuleEntryPoint.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import com.google.gwt.core.client.EntryPoint;
-
-/**
- * A dummy entry point of the test module.
- *
- * @author Hayward Chan
- */
-public class TestModuleEntryPoint implements EntryPoint {
-
- @Override public void onModuleLoad() {
- }
-}
diff --git a/guava-gwt/test/com/google/common/io/testModule.gwt.xml b/guava-gwt/test/com/google/common/io/testModule.gwt.xml
deleted file mode 100644
index 3611690..0000000
--- a/guava-gwt/test/com/google/common/io/testModule.gwt.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<module>
- <inherits name="com.google.gwt.user.User"/>
- <inherits name="com.google.gwt.junit.JUnit"/>
- <inherits name="com.google.common.annotations.Annotations"/>
- <inherits name="com.google.common.base.Base"/>
- <inherits name="com.google.common.collect.Collect"/>
- <inherits name="com.google.common.io.Io"/>
- <inherits name="com.google.common.math.Math"/>
- <entry-point class="com.google.common.io.TestModuleEntryPoint"/>
-
- <source path=""/>
-
- <add-linker name="std"/>
-
- <super-source path="super"/>
-
-</module>
diff --git a/guava-gwt/test/com/google/common/math/testModule.gwt.xml b/guava-gwt/test/com/google/common/math/testModule.gwt.xml
index 58552f1..17f579d 100644
--- a/guava-gwt/test/com/google/common/math/testModule.gwt.xml
+++ b/guava-gwt/test/com/google/common/math/testModule.gwt.xml
@@ -6,8 +6,8 @@
<inherits name="com.google.common.collect.Collect"/>
<inherits name="com.google.common.math.Math"/>
<inherits name="com.google.common.testing.Testing"/>
- <inherits name="org.junit.contrib.truth.Truth"/>
<inherits name="com.google.common.annotations.Annotations"/>
+ <inherits name="org.junit.contrib.truth.Truth"/>
<entry-point class="com.google.common.math.TestModuleEntryPoint"/>
<source path=""/>
diff --git a/guava-tests/test/com/google/common/net/TestPlatform.java b/guava-gwt/test/com/google/common/net/TestPlatform.java
index 39301d5..39301d5 100644
--- a/guava-tests/test/com/google/common/net/TestPlatform.java
+++ b/guava-gwt/test/com/google/common/net/TestPlatform.java
diff --git a/guava-gwt/test/com/google/common/net/testModule.gwt.xml b/guava-gwt/test/com/google/common/net/testModule.gwt.xml
index 1b61e1b..0e6338b 100644
--- a/guava-gwt/test/com/google/common/net/testModule.gwt.xml
+++ b/guava-gwt/test/com/google/common/net/testModule.gwt.xml
@@ -6,6 +6,7 @@
<inherits name="com.google.common.net.Net"/>
<inherits name="com.google.common.testing.Testing"/>
<inherits name="org.junit.contrib.truth.Truth"/>
+ <inherits name="com.google.common.annotations.Annotations"/>
<entry-point class="com.google.common.net.TestModuleEntryPoint"/>
<source path=""/>
diff --git a/guava-gwt/test/com/google/common/primitives/testModule.gwt.xml b/guava-gwt/test/com/google/common/primitives/testModule.gwt.xml
index 72da4d2..7bb4013 100644
--- a/guava-gwt/test/com/google/common/primitives/testModule.gwt.xml
+++ b/guava-gwt/test/com/google/common/primitives/testModule.gwt.xml
@@ -2,10 +2,10 @@
<module>
<inherits name="com.google.gwt.user.User"/>
<inherits name="com.google.gwt.junit.JUnit"/>
- <inherits name="com.google.common.collect.testing.Testing"/>
<inherits name="com.google.common.primitives.Primitives"/>
<inherits name="com.google.common.testing.Testing"/>
<inherits name="org.junit.contrib.truth.Truth"/>
+ <inherits name="com.google.common.annotations.Annotations"/>
<entry-point class="com.google.common.primitives.TestModuleEntryPoint"/>
<source path=""/>
diff --git a/guava-testlib/blackhole-gwt/test/com/google/common/testing/TestModuleEntryPoint.java b/guava-gwt/test/com/google/common/testing/TestModuleEntryPoint.java
index ed6e199..ed6e199 100644
--- a/guava-testlib/blackhole-gwt/test/com/google/common/testing/TestModuleEntryPoint.java
+++ b/guava-gwt/test/com/google/common/testing/TestModuleEntryPoint.java
diff --git a/guava-testlib/blackhole-gwt/src/com/google/common/testing/Testing.gwt.xml b/guava-gwt/test/com/google/common/testing/Testing.gwt.xml
index e8fb333..e1f85eb 100644
--- a/guava-testlib/blackhole-gwt/src/com/google/common/testing/Testing.gwt.xml
+++ b/guava-gwt/test/com/google/common/testing/Testing.gwt.xml
@@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
<module>
<source path=""/>
<super-source path="super"/>
- <inherits name="com.google.gwt.junit.JUnit"/>
-
- <inherits name="java.util.Util"/>
-
<inherits name="com.google.common.annotations.Annotations"/>
<inherits name="com.google.common.base.Base"/>
<inherits name="com.google.common.collect.Collect"/>
-
+
+ <inherits name="com.google.gwt.junit.JUnit"/>
+
+ <inherits name="java.util.Util"/>
+
</module>
diff --git a/guava-testlib/blackhole-gwt/test/com/google/common/testing/testModule.gwt.xml b/guava-gwt/test/com/google/common/testing/testModule.gwt.xml
index f35130d..2015440 100644
--- a/guava-testlib/blackhole-gwt/test/com/google/common/testing/testModule.gwt.xml
+++ b/guava-gwt/test/com/google/common/testing/testModule.gwt.xml
@@ -4,7 +4,6 @@
<inherits name="com.google.gwt.junit.JUnit"/>
<inherits name="com.google.common.collect.Collect"/>
<inherits name="com.google.common.testing.Testing"/>
- <inherits name="org.junit.contrib.truth.Truth"/>
<entry-point class="com.google.common.testing.TestModuleEntryPoint"/>
<source path=""/>
diff --git a/guava-gwt/test/com/google/common/util/concurrent/TestModuleEntryPoint.java b/guava-gwt/test/com/google/common/util/concurrent/TestModuleEntryPoint.java
deleted file mode 100644
index 7ed9721..0000000
--- a/guava-gwt/test/com/google/common/util/concurrent/TestModuleEntryPoint.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.gwt.core.client.EntryPoint;
-
-/**
- * A dummy entry point of the test module.
- *
- * @author Hayward Chan
- */
-public class TestModuleEntryPoint implements EntryPoint {
-
- @Override public void onModuleLoad() {
- }
-}
diff --git a/guava-gwt/test/com/google/common/util/concurrent/testModule.gwt.xml b/guava-gwt/test/com/google/common/util/concurrent/testModule.gwt.xml
deleted file mode 100644
index ffae299..0000000
--- a/guava-gwt/test/com/google/common/util/concurrent/testModule.gwt.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<module>
- <inherits name="com.google.gwt.user.User"/>
- <inherits name="com.google.gwt.junit.JUnit"/>
- <inherits name="com.google.common.annotations.Annotations"/>
- <inherits name="com.google.common.base.Base"/>
- <inherits name="com.google.common.collect.Collect"/>
- <inherits name="com.google.common.util.concurrent.Concurrent"/>
- <entry-point class="com.google.common.util.concurrent.TestModuleEntryPoint"/>
-
- <source path=""/>
-
- <add-linker name="std"/>
-
- <super-source path="super"/>
-
-</module>
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java
deleted file mode 100644
index 48b5ce2..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Multiset.Entry;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-
-/**
- * Common superclass for {@link MultisetSetCountUnconditionallyTester} and
- * {@link MultisetSetCountConditionallyTester}. It is used by those testers to
- * test calls to the unconditional {@code setCount()} method and calls to the
- * conditional {@code setCount()} method when the expected present count is
- * correct.
- *
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-public abstract class AbstractMultisetSetCountTester<E>
- extends AbstractMultisetTester<E> {
- /*
- * TODO: consider adding MultisetFeatures.SUPPORTS_SET_COUNT. Currently we
- * assume that using setCount() to increase the count is permitted iff add()
- * is permitted and similarly for decrease/remove(). We assume that a
- * setCount() no-op is permitted if either add() or remove() is permitted,
- * though we also allow it to "succeed" if neither is permitted.
- */
-
- private void assertSetCount(E element, int count) {
- setCountCheckReturnValue(element, count);
-
- assertEquals(
- "multiset.count() should return the value passed to setCount()",
- count, getMultiset().count(element));
-
- int size = 0;
- for (Multiset.Entry<E> entry : getMultiset().entrySet()) {
- size += entry.getCount();
- }
- assertEquals(
- "multiset.size() should be the sum of the counts of all entries",
- size, getMultiset().size());
- }
-
- /**
- * Call the {@code setCount()} method under test, and check its return value.
- */
- abstract void setCountCheckReturnValue(E element, int count);
-
- /**
- * Call the {@code setCount()} method under test, but do not check its return
- * value. Callers should use this method over
- * {@link #setCountCheckReturnValue(Object, int)} when they expect
- * {@code setCount()} to throw an exception, as checking the return value
- * could produce an incorrect error message like
- * "setCount() should return the original count" instead of the message passed
- * to a later invocation of {@code fail()}, like "setCount should throw
- * UnsupportedOperationException."
- */
- abstract void setCountNoCheckReturnValue(E element, int count);
-
- private void assertSetCountIncreasingFailure(E element, int count) {
- try {
- setCountNoCheckReturnValue(element, count);
- fail("a call to multiset.setCount() to increase an element's count "
- + "should throw");
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- private void assertSetCountDecreasingFailure(E element, int count) {
- try {
- setCountNoCheckReturnValue(element, count);
- fail("a call to multiset.setCount() to decrease an element's count "
- + "should throw");
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- // Unconditional setCount no-ops.
-
- private void assertZeroToZero() {
- assertSetCount(samples.e3, 0);
- }
-
- private void assertOneToOne() {
- assertSetCount(samples.e0, 1);
- }
-
- private void assertThreeToThree() {
- initThreeCopies();
- assertSetCount(samples.e0, 3);
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testSetCount_zeroToZero_addSupported() {
- assertZeroToZero();
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_zeroToZero_removeSupported() {
- assertZeroToZero();
- }
-
- @CollectionFeature.Require(absent = {SUPPORTS_ADD, SUPPORTS_REMOVE})
- public void testSetCount_zeroToZero_unsupported() {
- try {
- assertZeroToZero();
- } catch (UnsupportedOperationException tolerated) {
- }
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testSetCount_oneToOne_addSupported() {
- assertOneToOne();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_oneToOne_removeSupported() {
- assertOneToOne();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(absent = {SUPPORTS_ADD, SUPPORTS_REMOVE})
- public void testSetCount_oneToOne_unsupported() {
- try {
- assertOneToOne();
- } catch (UnsupportedOperationException tolerated) {
- }
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testSetCount_threeToThree_addSupported() {
- assertThreeToThree();
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_threeToThree_removeSupported() {
- assertThreeToThree();
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(absent = {SUPPORTS_ADD, SUPPORTS_REMOVE})
- public void testSetCount_threeToThree_unsupported() {
- try {
- assertThreeToThree();
- } catch (UnsupportedOperationException tolerated) {
- }
- }
-
- // Unconditional setCount size increases:
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testSetCount_zeroToOne_supported() {
- assertSetCount(samples.e3, 1);
- }
-
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- public void testSetCountZeroToOneConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertSetCount(samples.e3, 1);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- public void testSetCountZeroToOneConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator();
- assertSetCount(samples.e3, 1);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testSetCount_zeroToThree_supported() {
- assertSetCount(samples.e3, 3);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testSetCount_oneToThree_supported() {
- assertSetCount(samples.e0, 3);
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testSetCount_zeroToOne_unsupported() {
- assertSetCountIncreasingFailure(samples.e3, 1);
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testSetCount_zeroToThree_unsupported() {
- assertSetCountIncreasingFailure(samples.e3, 3);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testSetCount_oneToThree_unsupported() {
- assertSetCountIncreasingFailure(samples.e3, 3);
- }
-
- // Unconditional setCount size decreases:
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_oneToZero_supported() {
- assertSetCount(samples.e0, 0);
- }
-
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(absent = ZERO)
- public void testSetCountOneToZeroConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertSetCount(samples.e0, 0);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- public void testSetCountOneToZeroConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator();
- assertSetCount(samples.e0, 0);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_threeToZero_supported() {
- initThreeCopies();
- assertSetCount(samples.e0, 0);
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_threeToOne_supported() {
- initThreeCopies();
- assertSetCount(samples.e0, 1);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- public void testSetCount_oneToZero_unsupported() {
- assertSetCountDecreasingFailure(samples.e0, 0);
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- public void testSetCount_threeToZero_unsupported() {
- initThreeCopies();
- assertSetCountDecreasingFailure(samples.e0, 0);
- }
-
- @CollectionSize.Require(SEVERAL)
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- public void testSetCount_threeToOne_unsupported() {
- initThreeCopies();
- assertSetCountDecreasingFailure(samples.e0, 1);
- }
-
- // setCount with nulls:
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
- public void testSetCount_removeNull_nullSupported() {
- initCollectionWithNullElement();
- assertSetCount(null, 0);
- }
-
- @CollectionFeature.Require(value = {SUPPORTS_ADD, ALLOWS_NULL_VALUES},
- absent = RESTRICTS_ELEMENTS)
- public void testSetCount_addNull_nullSupported() {
- assertSetCount(null, 1);
- }
-
- @CollectionFeature.Require(value = SUPPORTS_ADD, absent = ALLOWS_NULL_VALUES)
- public void testSetCount_addNull_nullUnsupported() {
- try {
- setCountNoCheckReturnValue(null, 1);
- fail("adding null with setCount() should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- }
-
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- public void testSetCount_noOpNull_nullSupported() {
- try {
- assertSetCount(null, 0);
- } catch (UnsupportedOperationException tolerated) {
- }
- }
-
- @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
- public void testSetCount_noOpNull_nullUnsupported() {
- try {
- assertSetCount(null, 0);
- } catch (NullPointerException tolerated) {
- } catch (UnsupportedOperationException tolerated) {
- }
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- public void testSetCount_existingNoNopNull_nullSupported() {
- initCollectionWithNullElement();
- try {
- assertSetCount(null, 1);
- } catch (UnsupportedOperationException tolerated) {
- }
- }
-
- // Negative count.
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testSetCount_negative_removeSupported() {
- try {
- setCountNoCheckReturnValue(samples.e3, -1);
- fail("calling setCount() with a negative count should throw "
- + "IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- public void testSetCount_negative_removeUnsupported() {
- try {
- setCountNoCheckReturnValue(samples.e3, -1);
- fail("calling setCount() with a negative count should throw "
- + "IllegalArgumentException or UnsupportedOperationException");
- } catch (IllegalArgumentException expected) {
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- // TODO: test adding element of wrong type
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapInverseTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapInverseTester.java
deleted file mode 100644
index eef939b..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapInverseTester.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.testing.SerializableTester;
-
-import java.io.Serializable;
-
-/**
- * Tests for the {@code inverse} view of a BiMap.
- *
- * <p>This assumes that {@code bimap.inverse().inverse() == bimap}, which is not technically
- * required but is fulfilled by all current implementations.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BiMapInverseTester<K, V> extends AbstractBiMapTester<K, V> {
-
- public void testInverseSame() {
- assertSame(getMap(), getMap().inverse().inverse());
- }
-
- @CollectionFeature.Require(SERIALIZABLE)
- public void testInverseSerialization() {
- BiMapPair<K, V> pair = new BiMapPair<K, V>(getMap());
- BiMapPair<K, V> copy = SerializableTester.reserialize(pair);
- assertEquals(pair.forward, copy.forward);
- assertEquals(pair.backward, copy.backward);
- assertSame(copy.backward, copy.forward.inverse());
- assertSame(copy.forward, copy.backward.inverse());
- }
-
- private static class BiMapPair<K, V> implements Serializable {
- final BiMap<K, V> forward;
- final BiMap<V, K> backward;
-
- BiMapPair(BiMap<K, V> original) {
- this.forward = original;
- this.backward = original.inverse();
- }
-
- private static final long serialVersionUID = 0;
- }
-
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapRemoveTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapRemoveTester.java
deleted file mode 100644
index 5c01444..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/BiMapRemoveTester.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Iterator;
-
-/**
- * Tester for {@code BiMap.remove}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BiMapRemoveTester<K, V> extends AbstractBiMapTester<K, V> {
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveKeyRemovesFromInverse() {
- getMap().remove(samples.e0.getKey());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveKeyFromKeySetRemovesFromInverse() {
- getMap().keySet().remove(samples.e0.getKey());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromValuesRemovesFromInverse() {
- getMap().values().remove(samples.e0.getValue());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromInverseRemovesFromForward() {
- getMap().inverse().remove(samples.e0.getValue());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromInverseKeySetRemovesFromForward() {
- getMap().inverse().keySet().remove(samples.e0.getValue());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromInverseValuesRemovesFromInverse() {
- getMap().inverse().values().remove(samples.e0.getKey());
- expectMissing(samples.e0);
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testKeySetIteratorRemove() {
- int initialSize = getNumElements();
- Iterator<K> iterator = getMap().keySet().iterator();
- iterator.next();
- iterator.remove();
- assertEquals(initialSize - 1, getMap().size());
- assertEquals(initialSize - 1, getMap().inverse().size());
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetIteratorTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetIteratorTester.java
deleted file mode 100644
index e665afc..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetIteratorTester.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.IteratorFeature;
-import com.google.common.collect.testing.IteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-/**
- * Tester to make sure the {@code iterator().remove()} implementation of {@code Multiset} works when
- * there are multiple occurrences of elements.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class MultisetIteratorTester<E> extends AbstractMultisetTester<E> {
- @SuppressWarnings("unchecked")
- @CollectionFeature.Require({SUPPORTS_REMOVE, KNOWN_ORDER})
- public void testRemovingIteratorKnownOrder() {
- new IteratorTester<E>(4, IteratorFeature.MODIFIABLE, getSubjectGenerator().order(
- Arrays.asList(samples.e0, samples.e1, samples.e1, samples.e2)),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override
- protected Iterator<E> newTargetIterator() {
- return getSubjectGenerator().create(samples.e0, samples.e1, samples.e1, samples.e2)
- .iterator();
- }
- }.test();
- }
-
- @SuppressWarnings("unchecked")
- @CollectionFeature.Require(value = SUPPORTS_REMOVE, absent = KNOWN_ORDER)
- public void testRemovingIteratorUnknownOrder() {
- new IteratorTester<E>(4, IteratorFeature.MODIFIABLE, Arrays.asList(samples.e0, samples.e1,
- samples.e1, samples.e2), IteratorTester.KnownOrder.UNKNOWN_ORDER) {
- @Override
- protected Iterator<E> newTargetIterator() {
- return getSubjectGenerator().create(samples.e0, samples.e1, samples.e1, samples.e2)
- .iterator();
- }
- }.test();
- }
-
- @SuppressWarnings("unchecked")
- @CollectionFeature.Require(value = KNOWN_ORDER, absent = SUPPORTS_REMOVE)
- public void testIteratorKnownOrder() {
- new IteratorTester<E>(4, IteratorFeature.UNMODIFIABLE, getSubjectGenerator().order(
- Arrays.asList(samples.e0, samples.e1, samples.e1, samples.e2)),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override
- protected Iterator<E> newTargetIterator() {
- return getSubjectGenerator().create(samples.e0, samples.e1, samples.e1, samples.e2)
- .iterator();
- }
- }.test();
- }
-
- @SuppressWarnings("unchecked")
- @CollectionFeature.Require(absent = {SUPPORTS_REMOVE, KNOWN_ORDER})
- public void testIteratorUnknownOrder() {
- new IteratorTester<E>(4, IteratorFeature.UNMODIFIABLE, Arrays.asList(samples.e0, samples.e1,
- samples.e1, samples.e2), IteratorTester.KnownOrder.UNKNOWN_ORDER) {
- @Override
- protected Iterator<E> newTargetIterator() {
- return getSubjectGenerator().create(samples.e0, samples.e1, samples.e1, samples.e2)
- .iterator();
- }
- }.test();
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetReadsTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetReadsTester.java
deleted file mode 100644
index ea11eac..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetReadsTester.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Multisets;
-import com.google.common.collect.testing.WrongType;
-import com.google.common.collect.testing.features.CollectionSize;
-
-/**
- * A generic JUnit test which tests multiset-specific read operations.
- * Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.SetTestSuiteBuilder}.
- *
- * @author Jared Levy
- */
-@GwtCompatible(emulated = true)
-public class MultisetReadsTester<E> extends AbstractMultisetTester<E> {
- public void testCount_0() {
- assertEquals("multiset.count(missing) didn't return 0",
- 0, getMultiset().count(samples.e3));
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testCount_1() {
- assertEquals("multiset.count(present) didn't return 1",
- 1, getMultiset().count(samples.e0));
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testCount_3() {
- initThreeCopies();
- assertEquals("multiset.count(thriceContained) didn't return 3",
- 3, getMultiset().count(samples.e0));
- }
-
- public void testCount_null() {
- assertEquals("multiset.count(null) didn't return 0",
- 0, getMultiset().count(null));
- }
-
- public void testCount_wrongType() {
- assertEquals("multiset.count(wrongType) didn't return 0",
- 0, getMultiset().count(WrongType.VALUE));
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testElementSet_contains() {
- assertTrue("multiset.elementSet().contains(present) returned false",
- getMultiset().elementSet().contains(samples.e0));
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testEntrySet_contains() {
- assertTrue("multiset.entrySet() didn't contain [present, 1]",
- getMultiset().entrySet().contains(
- Multisets.immutableEntry(samples.e0, 1)));
- }
-
- public void testEntrySet_contains_count0() {
- assertFalse("multiset.entrySet() contains [missing, 0]",
- getMultiset().entrySet().contains(
- Multisets.immutableEntry(samples.e3, 0)));
- }
-
- public void testEntrySet_contains_nonentry() {
- assertFalse("multiset.entrySet() contains a non-entry",
- getMultiset().entrySet().contains(samples.e0));
- }
-
- public void testEntrySet_twice() {
- assertEquals("calling multiset.entrySet() twice returned unequal sets",
- getMultiset().entrySet(), getMultiset().entrySet());
- }
-
- @CollectionSize.Require(ZERO)
- public void testEntrySet_hashCode_size0() {
- assertEquals("multiset.entrySet() has incorrect hash code",
- 0, getMultiset().entrySet().hashCode());
- }
-
- @CollectionSize.Require(ONE)
- public void testEntrySet_hashCode_size1() {
- assertEquals("multiset.entrySet() has incorrect hash code",
- 1 ^ samples.e0.hashCode(), getMultiset().entrySet().hashCode());
- }
-
- public void testEquals_yes() {
- assertTrue("multiset doesn't equal a multiset with the same elements",
- getMultiset().equals(HashMultiset.create(getSampleElements())));
- }
-
- public void testEquals_differentSize() {
- Multiset<E> other = HashMultiset.create(getSampleElements());
- other.add(samples.e0);
- assertFalse("multiset equals a multiset with a different size",
- getMultiset().equals(other));
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testEquals_differentElements() {
- Multiset<E> other = HashMultiset.create(getSampleElements());
- other.remove(samples.e0);
- other.add(samples.e3);
- assertFalse("multiset equals a multiset with different elements",
- getMultiset().equals(other));
- }
-
- @CollectionSize.Require(ZERO)
- public void testHashCode_size0() {
- assertEquals("multiset has incorrect hash code",
- 0, getMultiset().hashCode());
- }
-
- @CollectionSize.Require(ONE)
- public void testHashCode_size1() {
- assertEquals("multiset has incorrect hash code",
- 1 ^ samples.e0.hashCode(), getMultiset().hashCode());
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetWritesTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetWritesTester.java
deleted file mode 100644
index 91cd8d3..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/MultisetWritesTester.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Multisets;
-import com.google.common.collect.testing.WrongType;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.Collections;
-import java.util.Iterator;
-
-/**
- * A generic JUnit test which tests multiset-specific write operations.
- * Can't be invoked directly; please see {@link MultisetTestSuiteBuilder}.
- *
- * @author Jared Levy
- */
-@GwtCompatible(emulated = true)
-public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAddOccurrencesZero() {
- int originalCount = getMultiset().count(samples.e0);
- assertEquals("old count", originalCount, getMultiset().add(samples.e0, 0));
- expectUnchanged();
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAddOccurrences() {
- int originalCount = getMultiset().count(samples.e0);
- assertEquals("old count", originalCount, getMultiset().add(samples.e0, 2));
- assertEquals("old count", originalCount + 2, getMultiset().count(samples.e0));
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testAddOccurrences_unsupported() {
- try {
- getMultiset().add(samples.e0, 2);
- fail("unsupported multiset.add(E, int) didn't throw exception");
- } catch (UnsupportedOperationException required) {}
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAdd_occurrences_negative() {
- try {
- getMultiset().add(samples.e0, -1);
- fail("multiset.add(E, -1) didn't throw an exception");
- } catch (IllegalArgumentException required) {}
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveZeroNoOp() {
- int originalCount = getMultiset().count(samples.e0);
- assertEquals("old count", originalCount, getMultiset().remove(samples.e0, 0));
- expectUnchanged();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemove_occurrences_present() {
- assertEquals("multiset.remove(present, 2) didn't return the old count",
- 1, getMultiset().remove(samples.e0, 2));
- assertFalse("multiset contains present after multiset.remove(present, 2)",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemove_occurrences_absent() {
- assertEquals("multiset.remove(absent, 0) didn't return 0",
- 0, getMultiset().remove(samples.e3, 2));
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- public void testRemove_occurrences_unsupported_absent() {
- // notice: we don't care whether it succeeds, or fails with UOE
- try {
- assertEquals(
- "multiset.remove(absent, 2) didn't return 0 or throw an exception",
- 0, getMultiset().remove(samples.e3, 2));
- } catch (UnsupportedOperationException ok) {}
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemove_occurrences_0() {
- int oldCount = getMultiset().count(samples.e0);
- assertEquals("multiset.remove(E, 0) didn't return the old count",
- oldCount, getMultiset().remove(samples.e0, 0));
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemove_occurrences_negative() {
- try {
- getMultiset().remove(samples.e0, -1);
- fail("multiset.remove(E, -1) didn't throw an exception");
- } catch (IllegalArgumentException required) {}
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemove_occurrences_wrongType() {
- assertEquals("multiset.remove(wrongType, 1) didn't return 0",
- 0, getMultiset().remove(WrongType.VALUE, 1));
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_clear() {
- getMultiset().entrySet().clear();
- assertTrue("multiset not empty after entrySet().clear()",
- getMultiset().isEmpty());
- }
-
- @CollectionSize.Require(ONE)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_iterator() {
- Iterator<Multiset.Entry<E>> iterator = getMultiset().entrySet().iterator();
- assertTrue(
- "non-empty multiset.entrySet() iterator.hasNext() returned false",
- iterator.hasNext());
- assertEquals("multiset.entrySet() iterator.next() returned incorrect entry",
- Multisets.immutableEntry(samples.e0, 1), iterator.next());
- assertFalse(
- "size 1 multiset.entrySet() iterator.hasNext() returned true "
- + "after next()",
- iterator.hasNext());
- iterator.remove();
- assertTrue(
- "multiset isn't empty after multiset.entrySet() iterator.remove()",
- getMultiset().isEmpty());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- public void testEntrySet_iterator_remove_unsupported() {
- Iterator<Multiset.Entry<E>> iterator = getMultiset().entrySet().iterator();
- assertTrue(
- "non-empty multiset.entrySet() iterator.hasNext() returned false",
- iterator.hasNext());
- try {
- iterator.remove();
- fail("multiset.entrySet() iterator.remove() didn't throw an exception");
- } catch (UnsupportedOperationException expected) {}
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_remove_present() {
- assertTrue(
- "multiset.entrySet.remove(presentEntry) returned false",
- getMultiset().entrySet().remove(
- Multisets.immutableEntry(samples.e0, 1)));
- assertFalse(
- "multiset contains element after removing its entry",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_remove_missing() {
- assertFalse(
- "multiset.entrySet.remove(missingEntry) returned true",
- getMultiset().entrySet().remove(
- Multisets.immutableEntry(samples.e0, 2)));
- assertTrue(
- "multiset didn't contain element after removing a missing entry",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_removeAll_present() {
- assertTrue(
- "multiset.entrySet.removeAll(presentEntry) returned false",
- getMultiset().entrySet().removeAll(
- Collections.singleton(Multisets.immutableEntry(samples.e0, 1))));
- assertFalse(
- "multiset contains element after removing its entry",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_removeAll_missing() {
- assertFalse(
- "multiset.entrySet.remove(missingEntry) returned true",
- getMultiset().entrySet().removeAll(
- Collections.singleton(Multisets.immutableEntry(samples.e0, 2))));
- assertTrue(
- "multiset didn't contain element after removing a missing entry",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_removeAll_null() {
- try {
- getMultiset().entrySet().removeAll(null);
- fail("multiset.entrySet.removeAll(null) didn't throw an exception");
- } catch (NullPointerException expected) {}
- }
-
- @CollectionSize.Require(ONE)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_retainAll_present() {
- assertFalse(
- "multiset.entrySet.retainAll(presentEntry) returned false",
- getMultiset().entrySet().retainAll(
- Collections.singleton(Multisets.immutableEntry(samples.e0, 1))));
- assertTrue(
- "multiset doesn't contains element after retaining its entry",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionSize.Require(ONE)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_retainAll_missing() {
- assertTrue(
- "multiset.entrySet.retainAll(missingEntry) returned true",
- getMultiset().entrySet().retainAll(
- Collections.singleton(Multisets.immutableEntry(samples.e0, 2))));
- assertFalse(
- "multiset contains element after retaining a different entry",
- getMultiset().contains(samples.e0));
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testEntrySet_retainAll_null() {
- try {
- getMultiset().entrySet().retainAll(null);
- // Returning successfully is not ideal, but tolerated.
- } catch (NullPointerException expected) {}
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/SetGenerators.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/SetGenerators.java
deleted file mode 100644
index 5102cdf..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/google/super/com/google/common/collect/testing/google/SetGenerators.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Sets.newTreeSet;
-import static com.google.common.collect.testing.SampleElements.Strings.AFTER_LAST;
-import static com.google.common.collect.testing.SampleElements.Strings.AFTER_LAST_2;
-import static com.google.common.collect.testing.SampleElements.Strings.BEFORE_FIRST;
-import static com.google.common.collect.testing.SampleElements.Strings.BEFORE_FIRST_2;
-import static junit.framework.Assert.assertEquals;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ContiguousSet;
-import com.google.common.collect.DiscreteDomain;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Range;
-import com.google.common.collect.Sets;
-import com.google.common.collect.testing.TestCollectionGenerator;
-import com.google.common.collect.testing.TestCollidingSetGenerator;
-import com.google.common.collect.testing.TestIntegerSortedSetGenerator;
-import com.google.common.collect.testing.TestSetGenerator;
-import com.google.common.collect.testing.TestStringListGenerator;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.TestStringSortedSetGenerator;
-import com.google.common.collect.testing.TestUnhashableCollectionGenerator;
-import com.google.common.collect.testing.UnhashableObject;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * Generators of different types of sets and derived collections from sets.
- *
- * @author Kevin Bourrillion
- * @author Jared Levy
- * @author Hayward Chan
- */
-@GwtCompatible(emulated = true)
-public class SetGenerators {
-
- public static class ImmutableSetCopyOfGenerator extends TestStringSetGenerator {
- @Override protected Set<String> create(String[] elements) {
- return ImmutableSet.copyOf(elements);
- }
- }
-
- public static class ImmutableSetWithBadHashesGenerator
- extends TestCollidingSetGenerator
- // Work around a GWT compiler bug. Not explicitly listing this will
- // cause the createArray() method missing in the generated javascript.
- // TODO: Remove this once the GWT bug is fixed.
- implements TestCollectionGenerator<Object> {
- @Override
- public Set<Object> create(Object... elements) {
- return ImmutableSet.copyOf(elements);
- }
- }
-
- public static class DegeneratedImmutableSetGenerator
- extends TestStringSetGenerator {
- // Make sure we get what we think we're getting, or else this test
- // is pointless
- @SuppressWarnings("cast")
- @Override protected Set<String> create(String[] elements) {
- return (ImmutableSet<String>)
- ImmutableSet.of(elements[0], elements[0]);
- }
- }
-
- public static class ImmutableSortedSetCopyOfGenerator
- extends TestStringSortedSetGenerator {
- @Override protected SortedSet<String> create(String[] elements) {
- return ImmutableSortedSet.copyOf(elements);
- }
- }
-
- public static class ImmutableSortedSetHeadsetGenerator
- extends TestStringSortedSetGenerator {
- @Override protected SortedSet<String> create(String[] elements) {
- List<String> list = Lists.newArrayList(elements);
- list.add("zzz");
- return ImmutableSortedSet.copyOf(list)
- .headSet("zzy");
- }
- }
-
- public static class ImmutableSortedSetTailsetGenerator
- extends TestStringSortedSetGenerator {
- @Override protected SortedSet<String> create(String[] elements) {
- List<String> list = Lists.newArrayList(elements);
- list.add("\0");
- return ImmutableSortedSet.copyOf(list)
- .tailSet("\0\0");
- }
- }
-
- public static class ImmutableSortedSetSubsetGenerator
- extends TestStringSortedSetGenerator {
- @Override protected SortedSet<String> create(String[] elements) {
- List<String> list = Lists.newArrayList(elements);
- list.add("\0");
- list.add("zzz");
- return ImmutableSortedSet.copyOf(list)
- .subSet("\0\0", "zzy");
- }
- }
-
- public static class ImmutableSortedSetExplicitComparator
- extends TestStringSetGenerator {
-
- private static final Comparator<String> STRING_REVERSED
- = Collections.reverseOrder();
-
- @Override protected SortedSet<String> create(String[] elements) {
- return ImmutableSortedSet.orderedBy(STRING_REVERSED)
- .add(elements)
- .build();
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- Collections.sort(insertionOrder, Collections.reverseOrder());
- return insertionOrder;
- }
- }
-
- public static class ImmutableSortedSetExplicitSuperclassComparatorGenerator
- extends TestStringSetGenerator {
-
- private static final Comparator<Comparable<?>> COMPARABLE_REVERSED
- = Collections.reverseOrder();
-
- @Override protected SortedSet<String> create(String[] elements) {
- return new ImmutableSortedSet.Builder<String>(COMPARABLE_REVERSED)
- .add(elements)
- .build();
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- Collections.sort(insertionOrder, Collections.reverseOrder());
- return insertionOrder;
- }
- }
-
- public static class ImmutableSortedSetReversedOrderGenerator
- extends TestStringSetGenerator {
-
- @Override protected SortedSet<String> create(String[] elements) {
- return ImmutableSortedSet.<String>reverseOrder()
- .addAll(Arrays.asList(elements).iterator())
- .build();
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- Collections.sort(insertionOrder, Collections.reverseOrder());
- return insertionOrder;
- }
- }
-
- public static class ImmutableSortedSetUnhashableGenerator
- extends TestUnhashableSetGenerator {
- @Override public Set<UnhashableObject> create(
- UnhashableObject[] elements) {
- return ImmutableSortedSet.copyOf(elements);
- }
- }
-
- public static class ImmutableSetAsListGenerator
- extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- return ImmutableSet.copyOf(elements).asList();
- }
- }
-
- public static class ImmutableSortedSetAsListGenerator
- extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- Comparator<String> comparator = createExplicitComparator(elements);
- ImmutableSet<String> set = ImmutableSortedSet.copyOf(
- comparator, Arrays.asList(elements));
- return set.asList();
- }
- }
-
- public static class ImmutableSortedSetSubsetAsListGenerator
- extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- Comparator<String> comparator = createExplicitComparator(elements);
- ImmutableSortedSet.Builder<String> builder
- = ImmutableSortedSet.orderedBy(comparator);
- builder.add(BEFORE_FIRST);
- builder.add(elements);
- builder.add(AFTER_LAST);
- return builder.build().subSet(BEFORE_FIRST_2,
- AFTER_LAST).asList();
- }
- }
-
- public static class ImmutableSortedSetAsListSubListGenerator
- extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- Comparator<String> comparator = createExplicitComparator(elements);
- ImmutableSortedSet.Builder<String> builder
- = ImmutableSortedSet.orderedBy(comparator);
- builder.add(BEFORE_FIRST);
- builder.add(elements);
- builder.add(AFTER_LAST);
- return builder.build().asList().subList(1, elements.length + 1);
- }
- }
-
- public static class ImmutableSortedSetSubsetAsListSubListGenerator
- extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- Comparator<String> comparator = createExplicitComparator(elements);
- ImmutableSortedSet.Builder<String> builder
- = ImmutableSortedSet.orderedBy(comparator);
- builder.add(BEFORE_FIRST);
- builder.add(BEFORE_FIRST_2);
- builder.add(elements);
- builder.add(AFTER_LAST);
- builder.add(AFTER_LAST_2);
- return builder.build().subSet(BEFORE_FIRST_2,
- AFTER_LAST_2)
- .asList().subList(1, elements.length + 1);
- }
- }
-
- public abstract static class TestUnhashableSetGenerator
- extends TestUnhashableCollectionGenerator<Set<UnhashableObject>>
- implements TestSetGenerator<UnhashableObject> {
- }
-
- private static Ordering<String> createExplicitComparator(
- String[] elements) {
- // Collapse equal elements, which Ordering.explicit() doesn't support, while
- // maintaining the ordering by first occurrence.
- Set<String> elementsPlus = Sets.newLinkedHashSet();
- elementsPlus.add(BEFORE_FIRST);
- elementsPlus.add(BEFORE_FIRST_2);
- elementsPlus.addAll(Arrays.asList(elements));
- elementsPlus.add(AFTER_LAST);
- elementsPlus.add(AFTER_LAST_2);
- return Ordering.explicit(Lists.newArrayList(elementsPlus));
- }
-
- /*
- * All the ContiguousSet generators below manually reject nulls here. In principle, we'd like to
- * defer that to Range, since it's ContiguousSet.create() that's used to create the sets. However,
- * that gets messy here, and we already have null tests for Range.
- */
-
- /*
- * These generators also rely on consecutive integer inputs (not necessarily in order, but no
- * holes).
- */
-
- // SetCreationTester has some tests that pass in duplicates. Dedup them.
- private static <E extends Comparable<? super E>> SortedSet<E> nullCheckedTreeSet(E[] elements) {
- SortedSet<E> set = newTreeSet();
- for (E element : elements) {
- // Explicit null check because TreeSet wrongly accepts add(null) when empty.
- set.add(checkNotNull(element));
- }
- return set;
- }
-
- public static class ContiguousSetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- return checkedCreate(nullCheckedTreeSet(elements));
- }
- }
-
- public static class ContiguousSetHeadsetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- SortedSet<Integer> set = nullCheckedTreeSet(elements);
- int tooHigh = (set.isEmpty()) ? 0 : set.last() + 1;
- set.add(tooHigh);
- return checkedCreate(set).headSet(tooHigh);
- }
- }
-
- public static class ContiguousSetTailsetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- SortedSet<Integer> set = nullCheckedTreeSet(elements);
- int tooLow = (set.isEmpty()) ? 0 : set.first() - 1;
- set.add(tooLow);
- return checkedCreate(set).tailSet(tooLow + 1);
- }
- }
-
- public static class ContiguousSetSubsetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- SortedSet<Integer> set = nullCheckedTreeSet(elements);
- if (set.isEmpty()) {
- /*
- * The (tooLow + 1, tooHigh) arguments below would be invalid because tooLow would be
- * greater than tooHigh.
- */
- return ContiguousSet.create(Range.openClosed(0, 1), DiscreteDomain.integers()).subSet(0, 1);
- }
- int tooHigh = set.last() + 1;
- int tooLow = set.first() - 1;
- set.add(tooHigh);
- set.add(tooLow);
- return checkedCreate(set).subSet(tooLow + 1, tooHigh);
- }
- }
-
- private abstract static class AbstractContiguousSetGenerator
- extends TestIntegerSortedSetGenerator {
- protected final ContiguousSet<Integer> checkedCreate(SortedSet<Integer> elementsSet) {
- List<Integer> elements = newArrayList(elementsSet);
- /*
- * A ContiguousSet can't have holes. If a test demands a hole, it should be changed so that it
- * doesn't need one, or it should be suppressed for ContiguousSet.
- */
- for (int i = 0; i < elements.size() - 1; i++) {
- assertEquals(elements.get(i) + 1, (int) elements.get(i + 1));
- }
- Range<Integer> range =
- (elements.isEmpty()) ? Range.closedOpen(0, 0) : Range.encloseAll(elements);
- return ContiguousSet.create(range, DiscreteDomain.integers());
- }
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/GwtPlatform.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/GwtPlatform.java
deleted file mode 100644
index b4d12b8..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/GwtPlatform.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.gwt.core.client.GwtScriptOnly;
-import com.google.gwt.lang.Array;
-
-/**
- * Version of {@link GwtPlatform} used in web-mode. It includes methods in
- * {@link Platform} that requires different implementions in web mode and
- * hosted mode. It is factored out from {@link Platform} because <code>
- * {@literal @}GwtScriptOnly</code> only supports public classes and methods.
- *
- * @author Hayward Chan
- */
-@GwtScriptOnly
-public final class GwtPlatform {
-
- private GwtPlatform() {}
-
- public static <T> T[] clone(T[] array) {
- return (T[]) Array.clone(array);
- }
-}
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Helpers.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Helpers.java
deleted file mode 100644
index 28f5571..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Helpers.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static java.util.Collections.sort;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import com.google.common.annotations.GwtCompatible;
-
-import junit.framework.Assert;
-import junit.framework.AssertionFailedError;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-@GwtCompatible(emulated = true)
-public class Helpers {
- // Clone of Objects.equal
- static boolean equal(Object a, Object b) {
- return a == b || (a != null && a.equals(b));
- }
-
- // Clone of Lists.newArrayList
- public static <E> List<E> copyToList(Iterable<? extends E> elements) {
- List<E> list = new ArrayList<E>();
- addAll(list, elements);
- return list;
- }
-
- public static <E> List<E> copyToList(E[] elements) {
- return copyToList(Arrays.asList(elements));
- }
-
- // Clone of Sets.newLinkedHashSet
- public static <E> Set<E> copyToSet(Iterable<? extends E> elements) {
- Set<E> set = new LinkedHashSet<E>();
- addAll(set, elements);
- return set;
- }
-
- public static <E> Set<E> copyToSet(E[] elements) {
- return copyToSet(Arrays.asList(elements));
- }
-
- // Would use Maps.immutableEntry
- public static <K, V> Entry<K, V> mapEntry(K key, V value) {
- return Collections.singletonMap(key, value).entrySet().iterator().next();
- }
-
- public static void assertEqualIgnoringOrder(
- Iterable<?> expected, Iterable<?> actual) {
- List<?> exp = copyToList(expected);
- List<?> act = copyToList(actual);
- String actString = act.toString();
-
- // Of course we could take pains to give the complete description of the
- // problem on any failure.
-
- // Yeah it's n^2.
- for (Object object : exp) {
- if (!act.remove(object)) {
- Assert.fail("did not contain expected element " + object + ", "
- + "expected = " + exp + ", actual = " + actString);
- }
- }
- assertTrue("unexpected elements: " + act, act.isEmpty());
- }
-
- public static void assertContentsAnyOrder(
- Iterable<?> actual, Object... expected) {
- assertEqualIgnoringOrder(Arrays.asList(expected), actual);
- }
-
- public static <E> boolean addAll(
- Collection<E> addTo, Iterable<? extends E> elementsToAdd) {
- boolean modified = false;
- for (E e : elementsToAdd) {
- modified |= addTo.add(e);
- }
- return modified;
- }
-
- static <T> Iterable<T> reverse(final List<T> list) {
- return new Iterable<T>() {
- @Override
- public Iterator<T> iterator() {
- final ListIterator<T> listIter = list.listIterator(list.size());
- return new Iterator<T>() {
- @Override
- public boolean hasNext() {
- return listIter.hasPrevious();
- }
- @Override
- public T next() {
- return listIter.previous();
- }
- @Override
- public void remove() {
- listIter.remove();
- }
- };
- }
- };
- }
-
- static <T> Iterator<T> cycle(final Iterable<T> iterable) {
- return new Iterator<T>() {
- Iterator<T> iterator = Collections.<T>emptySet().iterator();
- @Override
- public boolean hasNext() {
- return true;
- }
- @Override
- public T next() {
- if (!iterator.hasNext()) {
- iterator = iterable.iterator();
- }
- return iterator.next();
- }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- static <T> T get(Iterator<T> iterator, int position) {
- for (int i = 0; i < position; i++) {
- iterator.next();
- }
- return iterator.next();
- }
-
- static void fail(Throwable cause, Object message) {
- AssertionFailedError assertionFailedError =
- new AssertionFailedError(String.valueOf(message));
- assertionFailedError.initCause(cause);
- throw assertionFailedError;
- }
-
- public static <K, V> Comparator<Entry<K, V>> entryComparator(
- final Comparator<? super K> keyComparator) {
- return new Comparator<Entry<K, V>>() {
- @Override
- @SuppressWarnings("unchecked") // no less safe than putting it in the map!
- public int compare(Entry<K, V> a, Entry<K, V> b) {
- return (keyComparator == null)
- ? ((Comparable) a.getKey()).compareTo(b.getKey())
- : keyComparator.compare(a.getKey(), b.getKey());
- }
- };
- }
-
- public static <T> void testComparator(
- Comparator<? super T> comparator, T... valuesInExpectedOrder) {
- testComparator(comparator, Arrays.asList(valuesInExpectedOrder));
- }
-
- public static <T> void testComparator(
- Comparator<? super T> comparator, List<T> valuesInExpectedOrder) {
- // This does an O(n^2) test of all pairs of values in both orders
- for (int i = 0; i < valuesInExpectedOrder.size(); i++) {
- T t = valuesInExpectedOrder.get(i);
-
- for (int j = 0; j < i; j++) {
- T lesser = valuesInExpectedOrder.get(j);
- assertTrue(comparator + ".compare(" + lesser + ", " + t + ")",
- comparator.compare(lesser, t) < 0);
- }
-
- assertEquals(comparator + ".compare(" + t + ", " + t + ")",
- 0, comparator.compare(t, t));
-
- for (int j = i + 1; j < valuesInExpectedOrder.size(); j++) {
- T greater = valuesInExpectedOrder.get(j);
- assertTrue(comparator + ".compare(" + greater + ", " + t + ")",
- comparator.compare(greater, t) > 0);
- }
- }
- }
-
- public static <T extends Comparable<? super T>> void testCompareToAndEquals(
- List<T> valuesInExpectedOrder) {
- // This does an O(n^2) test of all pairs of values in both orders
- for (int i = 0; i < valuesInExpectedOrder.size(); i++) {
- T t = valuesInExpectedOrder.get(i);
-
- for (int j = 0; j < i; j++) {
- T lesser = valuesInExpectedOrder.get(j);
- assertTrue(lesser + ".compareTo(" + t + ')', lesser.compareTo(t) < 0);
- assertFalse(lesser.equals(t));
- }
-
- assertEquals(t + ".compareTo(" + t + ')', 0, t.compareTo(t));
- assertTrue(t.equals(t));
-
- for (int j = i + 1; j < valuesInExpectedOrder.size(); j++) {
- T greater = valuesInExpectedOrder.get(j);
- assertTrue(greater + ".compareTo(" + t + ')', greater.compareTo(t) > 0);
- assertFalse(greater.equals(t));
- }
- }
- }
-
- /**
- * Returns a collection that simulates concurrent modification by
- * having its size method return incorrect values. This is useful
- * for testing methods that must treat the return value from size()
- * as a hint only.
- *
- * @param delta the difference between the true size of the
- * collection and the values returned by the size method
- */
- public static <T> Collection<T> misleadingSizeCollection(final int delta) {
- // It would be nice to be able to return a real concurrent
- // collection like ConcurrentLinkedQueue, so that e.g. concurrent
- // iteration would work, but that would not be GWT-compatible.
- return new ArrayList<T>() {
- @Override public int size() { return Math.max(0, super.size() + delta); }
- };
- }
-
- /**
- * Returns a "nefarious" map entry with the specified key and value,
- * meaning an entry that is suitable for testing that map entries cannot be
- * modified via a nefarious implementation of equals. This is used for testing
- * unmodifiable collections of map entries; for example, it should not be
- * possible to access the raw (modifiable) map entry via a nefarious equals
- * method.
- */
- public static <K, V> Map.Entry<K, V> nefariousMapEntry(final K key,
- final V value) {
- return new Map.Entry<K, V>() {
- @Override public K getKey() {
- return key;
- }
- @Override public V getValue() {
- return value;
- }
- @Override public V setValue(V value) {
- throw new UnsupportedOperationException();
- }
- @SuppressWarnings("unchecked")
- @Override public boolean equals(Object o) {
- if (o instanceof Map.Entry) {
- Map.Entry<K, V> e = (Map.Entry<K, V>) o;
- e.setValue(value); // muhahaha!
-
- return equal(this.getKey(), e.getKey())
- && equal(this.getValue(), e.getValue());
- }
- return false;
- }
-
- @Override public int hashCode() {
- K k = getKey();
- V v = getValue();
- return ((k == null) ?
- 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
- }
-
- /**
- * Returns a string representation of the form <code>{key}={value}</code>.
- */
- @Override public String toString() {
- return getKey() + "=" + getValue();
- }
- };
- }
-
- static <E> List<E> castOrCopyToList(Iterable<E> iterable) {
- if (iterable instanceof List) {
- return (List<E>) iterable;
- }
- List<E> list = new ArrayList<E>();
- for (E e : iterable) {
- list.add(e);
- }
- return list;
- }
-
- private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
- @SuppressWarnings("unchecked") // assume any Comparable is Comparable<Self>
- @Override public int compare(Comparable left, Comparable right) {
- return left.compareTo(right);
- }
- };
-
- public static <K extends Comparable, V> Iterable<Entry<K, V>> orderEntriesByKey(
- List<Entry<K, V>> insertionOrder) {
- sort(insertionOrder, Helpers.<K, V>entryComparator(NATURAL_ORDER));
- return insertionOrder;
- }
-
- /**
- * Private replacement for {@link com.google.gwt.user.client.rpc.GwtTransient} to work around
- * build-system quirks.
- */
- private @interface GwtTransient {}
-
- /**
- * Compares strings in natural order except that null comes immediately before a given value. This
- * works better than Ordering.natural().nullsFirst() because, if null comes before all other
- * values, it lies outside the submap/submultiset ranges we test, and the variety of tests that
- * exercise null handling fail on those subcollections.
- */
- public abstract static class NullsBefore implements Comparator<String>, Serializable {
- /*
- * We don't serialize this class in GWT, so we don't care about whether GWT will serialize this
- * field.
- */
- @GwtTransient private final String justAfterNull;
-
- protected NullsBefore(String justAfterNull) {
- if (justAfterNull == null) {
- throw new NullPointerException();
- }
-
- this.justAfterNull = justAfterNull;
- }
-
- @Override
- public int compare(String lhs, String rhs) {
- if (lhs == rhs) {
- return 0;
- }
- if (lhs == null) {
- // lhs (null) comes just before justAfterNull.
- // If rhs is b, lhs comes first.
- if (rhs.equals(justAfterNull)) {
- return -1;
- }
- return justAfterNull.compareTo(rhs);
- }
- if (rhs == null) {
- // rhs (null) comes just before justAfterNull.
- // If lhs is b, rhs comes first.
- if (lhs.equals(justAfterNull)) {
- return 1;
- }
- return lhs.compareTo(justAfterNull);
- }
- return lhs.compareTo(rhs);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof NullsBefore) {
- NullsBefore other = (NullsBefore) obj;
- return justAfterNull.equals(other.justAfterNull);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return justAfterNull.hashCode();
- }
- }
-
- public static final class NullsBeforeB extends NullsBefore {
- public static final NullsBeforeB INSTANCE = new NullsBeforeB();
-
- private NullsBeforeB() {
- super("b");
- }
- }
-
- public static final class NullsBeforeTwo extends NullsBefore {
- public static final NullsBeforeTwo INSTANCE = new NullsBeforeTwo();
-
- private NullsBeforeTwo() {
- super("two"); // from TestStringSortedMapGenerator's sample keys
- }
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Platform.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Platform.java
deleted file mode 100644
index 110a566..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/Platform.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-/**
- * Minimal GWT emulation of {@code com.google.common.collect.testing.Platform}.
- *
- * <p><strong>This .java file should never be consumed by javac.</strong>
- *
- * @author Hayward Chan
- */
-class Platform {
-
- static boolean checkIsInstance(Class<?> clazz, Object obj) {
- /*
- * In GWT, we can't tell whether obj is an instance of clazz because GWT
- * doesn't support reflections. For testing purposes, we give up this
- * particular assertion (so that we can keep the rest).
- */
- return true;
- }
-
- // Class.cast is not supported in GWT.
- static void checkCast(Class<?> clazz, Object obj) {
- }
-
- static <T> T[] clone(T[] array) {
- return GwtPlatform.clone(array);
- }
-
- // TODO: Consolidate different copies in one single place.
- static String format(String template, Object... args) {
- // start substituting the arguments into the '%s' placeholders
- StringBuilder builder = new StringBuilder(
- template.length() + 16 * args.length);
- int templateStart = 0;
- int i = 0;
- while (i < args.length) {
- int placeholderStart = template.indexOf("%s", templateStart);
- if (placeholderStart == -1) {
- break;
- }
- builder.append(template.substring(templateStart, placeholderStart));
- builder.append(args[i++]);
- templateStart = placeholderStart + 2;
- }
- builder.append(template.substring(templateStart));
-
- // if we run out of placeholders, append the extra args in square braces
- if (i < args.length) {
- builder.append(" [");
- builder.append(args[i++]);
- while (i < args.length) {
- builder.append(", ");
- builder.append(args[i++]);
- }
- builder.append("]");
- }
-
- return builder.toString();
- }
-
- static String classGetSimpleName(Class<?> clazz) {
- throw new UnsupportedOperationException("Shouldn't be called in GWT.");
- }
-}
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddAllTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddAllTester.java
deleted file mode 100644
index 9280c7a..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddAllTester.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static java.util.Collections.singletonList;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.MinimalCollection;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A generic JUnit test which tests addAll operations on a collection. Can't be
- * invoked directly; please see
- * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Kevin Bourrillion
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAddAll_supportedNothing() {
- assertFalse("addAll(nothing) should return false",
- collection.addAll(emptyCollection()));
- expectUnchanged();
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testAddAll_unsupportedNothing() {
- try {
- assertFalse("addAll(nothing) should return false or throw",
- collection.addAll(emptyCollection()));
- } catch (UnsupportedOperationException tolerated) {
- }
- expectUnchanged();
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAddAll_supportedNonePresent() {
- assertTrue("addAll(nonePresent) should return true",
- collection.addAll(createDisjointCollection()));
- expectAdded(samples.e3, samples.e4);
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testAddAll_unsupportedNonePresent() {
- try {
- collection.addAll(createDisjointCollection());
- fail("addAll(nonePresent) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3, samples.e4);
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- public void testAddAll_supportedSomePresent() {
- assertTrue("addAll(somePresent) should return true",
- collection.addAll(MinimalCollection.of(samples.e3, samples.e0)));
- assertTrue("should contain " + samples.e3, collection.contains(samples.e3));
- assertTrue("should contain " + samples.e0, collection.contains(samples.e0));
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- public void testAddAll_unsupportedSomePresent() {
- try {
- collection.addAll(MinimalCollection.of(samples.e3, samples.e0));
- fail("addAll(somePresent) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- }
-
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(absent = ZERO)
- public void testAddAllConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertTrue(collection.addAll(MinimalCollection.of(samples.e3, samples.e0)));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- public void testAddAll_unsupportedAllPresent() {
- try {
- assertFalse("addAll(allPresent) should return false or throw",
- collection.addAll(MinimalCollection.of(samples.e0)));
- } catch (UnsupportedOperationException tolerated) {
- }
- expectUnchanged();
- }
-
- @CollectionFeature.Require(value = {SUPPORTS_ADD,
- ALLOWS_NULL_VALUES}, absent = RESTRICTS_ELEMENTS)
- public void testAddAll_nullSupported() {
- List<E> containsNull = singletonList(null);
- assertTrue("addAll(containsNull) should return true", collection
- .addAll(containsNull));
- /*
- * We need (E) to force interpretation of null as the single element of a
- * varargs array, not the array itself
- */
- expectAdded((E) null);
- }
-
- @CollectionFeature.Require(value = SUPPORTS_ADD,
- absent = ALLOWS_NULL_VALUES)
- public void testAddAll_nullUnsupported() {
- List<E> containsNull = singletonList(null);
- try {
- collection.addAll(containsNull);
- fail("addAll(containsNull) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullMissingWhenNullUnsupported(
- "Should not contain null after unsupported addAll(containsNull)");
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAddAll_nullCollectionReference() {
- try {
- collection.addAll(null);
- fail("addAll(null) should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddTester.java
deleted file mode 100644
index 3a5bc13..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionAddTester.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-
-/**
- * A generic JUnit test which tests {@code add} operations on a collection.
- * Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Kevin Bourrillion
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class CollectionAddTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAdd_supportedNotPresent() {
- assertTrue("add(notPresent) should return true",
- collection.add(samples.e3));
- expectAdded(samples.e3);
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- public void testAdd_unsupportedNotPresent() {
- try {
- collection.add(samples.e3);
- fail("add(notPresent) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3);
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- public void testAdd_unsupportedPresent() {
- try {
- assertFalse("add(present) should return false or throw",
- collection.add(samples.e0));
- } catch (UnsupportedOperationException tolerated) {
- }
- expectUnchanged();
- }
-
- @CollectionFeature.Require(
- value = {SUPPORTS_ADD, ALLOWS_NULL_VALUES},
- absent = RESTRICTS_ELEMENTS)
- public void testAdd_nullSupported() {
- assertTrue("add(null) should return true", collection.add(null));
- expectAdded((E) null);
- }
-
- @CollectionFeature.Require(value = SUPPORTS_ADD,
- absent = ALLOWS_NULL_VALUES)
- public void testAdd_nullUnsupported() {
- try {
- collection.add(null);
- fail("add(null) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullMissingWhenNullUnsupported(
- "Should not contain null after unsupported add(null)");
- }
-
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(absent = ZERO)
- public void testAddConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertTrue(collection.add(samples.e3));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionCreationTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionCreationTester.java
deleted file mode 100644
index bcdf61c..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionCreationTester.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-/**
- * A generic JUnit test which tests creation (typically through a constructor or
- * static factory method) of a collection. Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-public class CollectionCreationTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNull_supported() {
- E[] array = createArrayWithNullElement();
- collection = getSubjectGenerator().create(array);
- expectContents(array);
- }
-
- @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNull_unsupported() {
- E[] array = createArrayWithNullElement();
-
- try {
- getSubjectGenerator().create(array);
- fail("Creating a collection containing null should fail");
- } catch (NullPointerException expected) {
- }
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionIteratorTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionIteratorTester.java
deleted file mode 100644
index 8f54656..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionIteratorTester.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
-import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.IteratorFeature;
-import com.google.common.collect.testing.IteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-/**
- * A generic JUnit test which tests {@code iterator} operations on a collection.
- * Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-public class CollectionIteratorTester<E> extends AbstractCollectionTester<E> {
- public void testIterator() {
- List<E> iteratorElements = new ArrayList<E>();
- for (E element : collection) { // uses iterator()
- iteratorElements.add(element);
- }
- Helpers.assertEqualIgnoringOrder(
- Arrays.asList(createSamplesArray()), iteratorElements);
- }
-
- @CollectionFeature.Require(KNOWN_ORDER)
- public void testIterationOrdering() {
- List<E> iteratorElements = new ArrayList<E>();
- for (E element : collection) { // uses iterator()
- iteratorElements.add(element);
- }
- List<E> expected = Helpers.copyToList(getOrderedElements());
- assertEquals("Different ordered iteration", expected, iteratorElements);
- }
-
- // TODO: switch to DerivedIteratorTestSuiteBuilder
-
- @CollectionFeature.Require({KNOWN_ORDER, SUPPORTS_REMOVE})
- public void testIterator_knownOrderRemoveSupported() {
- runIteratorTest(MODIFIABLE, IteratorTester.KnownOrder.KNOWN_ORDER,
- getOrderedElements());
- }
-
- @CollectionFeature.Require(value = KNOWN_ORDER, absent = SUPPORTS_REMOVE)
- public void testIterator_knownOrderRemoveUnsupported() {
- runIteratorTest(UNMODIFIABLE, IteratorTester.KnownOrder.KNOWN_ORDER,
- getOrderedElements());
- }
-
- @CollectionFeature.Require(absent = KNOWN_ORDER, value = SUPPORTS_REMOVE)
- public void testIterator_unknownOrderRemoveSupported() {
- runIteratorTest(MODIFIABLE, IteratorTester.KnownOrder.UNKNOWN_ORDER,
- getSampleElements());
- }
-
- @CollectionFeature.Require(absent = {KNOWN_ORDER, SUPPORTS_REMOVE})
- public void testIterator_unknownOrderRemoveUnsupported() {
- runIteratorTest(UNMODIFIABLE, IteratorTester.KnownOrder.UNKNOWN_ORDER,
- getSampleElements());
- }
-
- private void runIteratorTest(Set<IteratorFeature> features,
- IteratorTester.KnownOrder knownOrder, Iterable<E> elements) {
- new IteratorTester<E>(Platform.collectionIteratorTesterNumIterations(), features, elements,
- knownOrder) {
- {
- // TODO: don't set this universally
- ignoreSunJavaBug6529795();
- }
-
- @Override protected Iterator<E> newTargetIterator() {
- resetCollection();
- return collection.iterator();
- }
-
- @Override protected void verify(List<E> elements) {
- expectContents(elements);
- }
- }.test();
- }
-
- public void testIteratorNoSuchElementException() {
- Iterator<E> iterator = collection.iterator();
- while (iterator.hasNext()) {
- iterator.next();
- }
-
- try {
- iterator.next();
- fail("iterator.next() should throw NoSuchElementException");
- } catch (NoSuchElementException expected) {}
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionToArrayTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionToArrayTester.java
deleted file mode 100644
index 377ac12..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/CollectionToArrayTester.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.WrongType;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A generic JUnit test which tests {@code toArray()} operations on a
- * collection. Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Kevin Bourrillion
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-public class CollectionToArrayTester<E> extends AbstractCollectionTester<E> {
- public void testToArray_noArgs() {
- Object[] array = collection.toArray();
- expectArrayContentsAnyOrder(createSamplesArray(), array);
- }
-
- /**
- * {@link Collection#toArray(Object[])} says: "Note that
- * <tt>toArray(new Object[0])</tt> is identical in function to
- * <tt>toArray()</tt>."
- *
- * <p>For maximum effect, the collection under test should be created from an
- * element array of a type other than {@code Object[]}.
- */
- public void testToArray_isPlainObjectArray() {
- Object[] array = collection.toArray();
- assertEquals(Object[].class, array.getClass());
- }
-
- public void testToArray_emptyArray() {
- E[] empty = getSubjectGenerator().createArray(0);
- E[] array = collection.toArray(empty);
- assertEquals("toArray(emptyT[]) should return an array of type T",
- empty.getClass(), array.getClass());
- assertEquals("toArray(emptyT[]).length:", getNumElements(), array.length);
- expectArrayContentsAnyOrder(createSamplesArray(), array);
- }
-
- @CollectionFeature.Require(KNOWN_ORDER)
- public void testToArray_emptyArray_ordered() {
- E[] empty = getSubjectGenerator().createArray(0);
- E[] array = collection.toArray(empty);
- assertEquals("toArray(emptyT[]) should return an array of type T",
- empty.getClass(), array.getClass());
- assertEquals("toArray(emptyT[]).length:", getNumElements(), array.length);
- expectArrayContentsInOrder(getOrderedElements(), array);
- }
-
- public void testToArray_emptyArrayOfObject() {
- Object[] in = new Object[0];
- Object[] array = collection.toArray(in);
- assertEquals("toArray(emptyObject[]) should return an array of type Object",
- Object[].class, array.getClass());
- assertEquals("toArray(emptyObject[]).length",
- getNumElements(), array.length);
- expectArrayContentsAnyOrder(createSamplesArray(), array);
- }
-
- public void testToArray_rightSizedArray() {
- E[] array = getSubjectGenerator().createArray(getNumElements());
- assertSame("toArray(sameSizeE[]) should return the given array",
- array, collection.toArray(array));
- expectArrayContentsAnyOrder(createSamplesArray(), array);
- }
-
- @CollectionFeature.Require(KNOWN_ORDER)
- public void testToArray_rightSizedArray_ordered() {
- E[] array = getSubjectGenerator().createArray(getNumElements());
- assertSame("toArray(sameSizeE[]) should return the given array",
- array, collection.toArray(array));
- expectArrayContentsInOrder(getOrderedElements(), array);
- }
-
- public void testToArray_rightSizedArrayOfObject() {
- Object[] array = new Object[getNumElements()];
- assertSame("toArray(sameSizeObject[]) should return the given array",
- array, collection.toArray(array));
- expectArrayContentsAnyOrder(createSamplesArray(), array);
- }
-
- @CollectionFeature.Require(KNOWN_ORDER)
- public void testToArray_rightSizedArrayOfObject_ordered() {
- Object[] array = new Object[getNumElements()];
- assertSame("toArray(sameSizeObject[]) should return the given array",
- array, collection.toArray(array));
- expectArrayContentsInOrder(getOrderedElements(), array);
- }
-
- public void testToArray_oversizedArray() {
- E[] array = getSubjectGenerator().createArray(getNumElements() + 2);
- array[getNumElements()] = samples.e3;
- array[getNumElements() + 1] = samples.e3;
- assertSame("toArray(overSizedE[]) should return the given array",
- array, collection.toArray(array));
-
- List<E> subArray = Arrays.asList(array).subList(0, getNumElements());
- E[] expectedSubArray = createSamplesArray();
- for (int i = 0; i < getNumElements(); i++) {
- assertTrue(
- "toArray(overSizedE[]) should contain element " + expectedSubArray[i],
- subArray.contains(expectedSubArray[i]));
- }
- assertNull("The array element "
- + "immediately following the end of the collection should be nulled",
- array[getNumElements()]);
- // array[getNumElements() + 1] might or might not have been nulled
- }
-
- @CollectionFeature.Require(KNOWN_ORDER)
- public void testToArray_oversizedArray_ordered() {
- E[] array = getSubjectGenerator().createArray(getNumElements() + 2);
- array[getNumElements()] = samples.e3;
- array[getNumElements() + 1] = samples.e3;
- assertSame("toArray(overSizedE[]) should return the given array",
- array, collection.toArray(array));
-
- List<E> expected = getOrderedElements();
- for (int i = 0; i < getNumElements(); i++) {
- assertEquals(expected.get(i), array[i]);
- }
- assertNull("The array element "
- + "immediately following the end of the collection should be nulled",
- array[getNumElements()]);
- // array[getNumElements() + 1] might or might not have been nulled
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testToArray_emptyArrayOfWrongTypeForNonEmptyCollection() {
- try {
- WrongType[] array = new WrongType[0];
- collection.toArray(array);
- fail("toArray(notAssignableTo[]) should throw");
- } catch (ArrayStoreException expected) {
- }
- }
-
- @CollectionSize.Require(ZERO)
- public void testToArray_emptyArrayOfWrongTypeForEmptyCollection() {
- WrongType[] array = new WrongType[0];
- assertSame(
- "toArray(sameSizeNotAssignableTo[]) should return the given array",
- array, collection.toArray(array));
- }
-
- private void expectArrayContentsAnyOrder(Object[] expected, Object[] actual) {
- Helpers.assertEqualIgnoringOrder(
- Arrays.asList(expected), Arrays.asList(actual));
- }
-
- private void expectArrayContentsInOrder(List<E> expected, Object[] actual) {
- assertEquals("toArray() ordered contents: ",
- expected, Arrays.asList(actual));
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddAtIndexTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddAtIndexTester.java
deleted file mode 100644
index 614959a..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddAtIndexTester.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.ListFeature;
-
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-
-/**
- * A generic JUnit test which tests {@code add(int, Object)} operations on a
- * list. Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class ListAddAtIndexTester<E> extends AbstractListTester<E> {
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- @CollectionSize.Require(absent = ZERO)
- public void testAddAtIndex_supportedPresent() {
- getList().add(0, samples.e0);
- expectAdded(0, samples.e0);
- }
-
- @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
- @CollectionSize.Require(absent = ZERO)
- /*
- * absent = ZERO isn't required, since unmodList.add() must
- * throw regardless, but it keeps the method name accurate.
- */
- public void testAddAtIndex_unsupportedPresent() {
- try {
- getList().add(0, samples.e0);
- fail("add(n, present) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- public void testAddAtIndex_supportedNotPresent() {
- getList().add(0, samples.e3);
- expectAdded(0, samples.e3);
- }
-
- @CollectionFeature.Require(FAILS_FAST_ON_CONCURRENT_MODIFICATION)
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- public void testAddAtIndexConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- getList().add(0, samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
- public void testAddAtIndex_unsupportedNotPresent() {
- try {
- getList().add(0, samples.e3);
- fail("add(n, notPresent) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testAddAtIndex_middle() {
- getList().add(getNumElements() / 2, samples.e3);
- expectAdded(getNumElements() / 2, samples.e3);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- @CollectionSize.Require(absent = ZERO)
- public void testAddAtIndex_end() {
- getList().add(getNumElements(), samples.e3);
- expectAdded(getNumElements(), samples.e3);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- public void testAddAtIndex_nullSupported() {
- getList().add(0, null);
- expectAdded(0, (E) null);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
- public void testAddAtIndex_nullUnsupported() {
- try {
- getList().add(0, null);
- fail("add(n, null) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullMissingWhenNullUnsupported(
- "Should not contain null after unsupported add(n, null)");
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- public void testAddAtIndex_negative() {
- try {
- getList().add(-1, samples.e3);
- fail("add(-1, e) should throw");
- } catch (IndexOutOfBoundsException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- public void testAddAtIndex_tooLarge() {
- try {
- getList().add(getNumElements() + 1, samples.e3);
- fail("add(size + 1, e) should throw");
- } catch (IndexOutOfBoundsException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3);
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddTester.java
deleted file mode 100644
index bac3d60..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListAddTester.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.List;
-
-/**
- * A generic JUnit test which tests {@code add(Object)} operations on a list.
- * Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class ListAddTester<E> extends AbstractListTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- public void testAdd_supportedPresent() {
- assertTrue("add(present) should return true", getList().add(samples.e0));
- expectAdded(samples.e0);
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- /*
- * absent = ZERO isn't required, since unmodList.add() must
- * throw regardless, but it keeps the method name accurate.
- */
- public void testAdd_unsupportedPresent() {
- try {
- getList().add(samples.e0);
- fail("add(present) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- @CollectionFeature.Require(value = {SUPPORTS_ADD, ALLOWS_NULL_VALUES})
- @CollectionSize.Require(absent = ZERO)
- public void testAdd_supportedNullPresent() {
- E[] array = createArrayWithNullElement();
- collection = getSubjectGenerator().create(array);
- assertTrue("add(nullPresent) should return true", getList().add(null));
-
- List<E> expected = Helpers.copyToList(array);
- expected.add(null);
- expectContents(expected);
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListHashCodeTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListHashCodeTester.java
deleted file mode 100644
index 501c8ca..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListHashCodeTester.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * Tests {@link java.util.List#hashCode}.
- *
- * <p>This class is GWT compatible.
- *
- * @author George van den Driessche
- */
-@GwtCompatible(emulated = true)
-public class ListHashCodeTester<E> extends AbstractListTester<E> {
- public void testHashCode() {
- int expectedHashCode = 1;
- for (E element : getOrderedElements()) {
- expectedHashCode = 31 * expectedHashCode +
- ((element == null) ? 0 : element.hashCode());
- }
- assertEquals(
- "A List's hashCode() should be computed from those of its elements.",
- expectedHashCode, getList().hashCode());
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListListIteratorTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListListIteratorTester.java
deleted file mode 100644
index dbd2718..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListListIteratorTester.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
-import static com.google.common.collect.testing.testers.Platform.listListIteratorTesterNumIterations;
-import static java.util.Collections.singleton;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.IteratorFeature;
-import com.google.common.collect.testing.ListIteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.ListFeature;
-
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Set;
-
-/**
- * A generic JUnit test which tests {@code listIterator} operations on a list.
- * Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-public class ListListIteratorTester<E> extends AbstractListTester<E> {
- // TODO: switch to DerivedIteratorTestSuiteBuilder
-
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
- @ListFeature.Require(absent = {SUPPORTS_SET, SUPPORTS_ADD_WITH_INDEX})
- public void testListIterator_unmodifiable() {
- runListIteratorTest(UNMODIFIABLE);
- }
-
- /*
- * For now, we don't cope with testing this when the list supports only some
- * modification operations.
- */
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- @ListFeature.Require({SUPPORTS_SET, SUPPORTS_ADD_WITH_INDEX})
- public void testListIterator_fullyModifiable() {
- runListIteratorTest(MODIFIABLE);
- }
-
- private void runListIteratorTest(Set<IteratorFeature> features) {
- new ListIteratorTester<E>(
- listListIteratorTesterNumIterations(), singleton(samples.e4), features,
- Helpers.copyToList(getOrderedElements()), 0) {
- {
- // TODO: don't set this universally
- stopTestingWhenAddThrowsException();
- }
-
- @Override protected ListIterator<E> newTargetIterator() {
- resetCollection();
- return getList().listIterator();
- }
-
- @Override protected void verify(List<E> elements) {
- expectContents(elements);
- }
- }.test();
- }
-
- public void testListIterator_tooLow() {
- try {
- getList().listIterator(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void testListIterator_tooHigh() {
- try {
- getList().listIterator(getNumElements() + 1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void testListIterator_atSize() {
- getList().listIterator(getNumElements());
- // TODO: run the iterator through ListIteratorTester
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSetTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSetTester.java
deleted file mode 100644
index 1a57800..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSetTester.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.ListFeature;
-
-/**
- * A generic JUnit test which tests {@code set()} operations on a list. Can't be
- * invoked directly; please see
- * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author George van den Driessche
- */
-@GwtCompatible(emulated = true)
-public class ListSetTester<E> extends AbstractListTester<E> {
- @ListFeature.Require(SUPPORTS_SET)
- @CollectionSize.Require(absent = ZERO)
- public void testSet() {
- doTestSet(samples.e3);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- @ListFeature.Require(SUPPORTS_SET)
- public void testSet_null() {
- doTestSet(null);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- @ListFeature.Require(SUPPORTS_SET)
- public void testSet_replacingNull() {
- E[] elements = createSamplesArray();
- int i = aValidIndex();
- elements[i] = null;
- collection = getSubjectGenerator().create(elements);
-
- doTestSet(samples.e3);
- }
-
- private void doTestSet(E newValue) {
- int index = aValidIndex();
- E initialValue = getList().get(index);
- assertEquals("set(i, x) should return the old element at position i.",
- initialValue, getList().set(index, newValue));
- assertEquals("After set(i, x), get(i) should return x",
- newValue, getList().get(index));
- assertEquals("set() should not change the size of a list.",
- getNumElements(), getList().size());
- }
-
- @ListFeature.Require(SUPPORTS_SET)
- public void testSet_indexTooLow() {
- try {
- getList().set(-1, samples.e3);
- fail("set(-1) should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException expected) {
- }
- expectUnchanged();
- }
-
- @ListFeature.Require(SUPPORTS_SET)
- public void testSet_indexTooHigh() {
- int index = getNumElements();
- try {
- getList().set(index, samples.e3);
- fail("set(size) should throw IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException expected) {
- }
- expectUnchanged();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @ListFeature.Require(absent = SUPPORTS_SET)
- public void testSet_unsupported() {
- try {
- getList().set(aValidIndex(), samples.e3);
- fail("set() should throw UnsupportedOperationException");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- }
-
- @CollectionSize.Require(ZERO)
- @ListFeature.Require(absent = SUPPORTS_SET)
- public void testSet_unsupportedByEmptyList() {
- try {
- getList().set(0, samples.e3);
- fail("set() should throw UnsupportedOperationException "
- + "or IndexOutOfBoundsException");
- } catch (UnsupportedOperationException tolerated) {
- } catch (IndexOutOfBoundsException tolerated) {
- }
- expectUnchanged();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @ListFeature.Require(SUPPORTS_SET)
- @CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
- public void testSet_nullUnsupported() {
- try {
- getList().set(aValidIndex(), null);
- fail("set(null) should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- }
-
- private int aValidIndex() {
- return getList().size() / 2;
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSubListTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSubListTester.java
deleted file mode 100644
index 5881d8b..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/ListSubListTester.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS;
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_REMOVE_WITH_INDEX;
-import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
-import static java.util.Collections.emptyList;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.ListFeature;
-import com.google.common.testing.SerializableTester;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A generic JUnit test which tests {@code subList()} operations on a list.
- * Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.ListTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class ListSubListTester<E> extends AbstractListTester<E> {
- public void testSubList_startNegative() {
- try {
- getList().subList(-1, 0);
- fail("subList(-1, 0) should throw");
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void testSubList_endTooLarge() {
- try {
- getList().subList(0, getNumElements() + 1);
- fail("subList(0, size + 1) should throw");
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- public void testSubList_startGreaterThanEnd() {
- try {
- getList().subList(1, 0);
- fail("subList(1, 0) should throw");
- } catch (IndexOutOfBoundsException expected) {
- } catch (IllegalArgumentException expected) {
- /*
- * The subList() docs claim that this should be an
- * IndexOutOfBoundsException, but many JDK implementations throw
- * IllegalArgumentException:
- * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4506427
- */
- }
- }
-
- public void testSubList_empty() {
- assertEquals("subList(0, 0) should be empty",
- emptyList(), getList().subList(0, 0));
- }
-
- public void testSubList_entireList() {
- assertEquals("subList(0, size) should be equal to the original list",
- getList(), getList().subList(0, getNumElements()));
- }
-
- @ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
- @CollectionSize.Require(absent = ZERO)
- public void testSubList_subListRemoveAffectsOriginal() {
- List<E> subList = getList().subList(0, 1);
- subList.remove(0);
- List<E> expected =
- Arrays.asList(createSamplesArray()).subList(1, getNumElements());
- expectContents(expected);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- public void testSubList_subListAddAffectsOriginal() {
- List<E> subList = getList().subList(0, 0);
- subList.add(samples.e3);
- expectAdded(0, samples.e3);
- }
-
- @ListFeature.Require(SUPPORTS_SET)
- @CollectionSize.Require(absent = ZERO)
- public void testSubList_subListSetAffectsOriginal() {
- List<E> subList = getList().subList(0, 1);
- subList.set(0, samples.e3);
- List<E> expected = Helpers.copyToList(createSamplesArray());
- expected.set(0, samples.e3);
- expectContents(expected);
- }
-
- @ListFeature.Require(SUPPORTS_SET)
- @CollectionSize.Require(absent = ZERO)
- public void testSubList_originalListSetAffectsSubList() {
- List<E> subList = getList().subList(0, 1);
- getList().set(0, samples.e3);
- assertEquals("A set() call to a list after a sublist has been created "
- + "should be reflected in the sublist",
- Collections.singletonList(samples.e3), subList);
- }
-
- @ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_subListRemoveAffectsOriginalLargeList() {
- List<E> subList = getList().subList(1, 3);
- subList.remove(samples.e2);
- List<E> expected = Helpers.copyToList(createSamplesArray());
- expected.remove(2);
- expectContents(expected);
- }
-
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_subListAddAtIndexAffectsOriginalLargeList() {
- List<E> subList = getList().subList(2, 3);
- subList.add(0, samples.e3);
- expectAdded(2, samples.e3);
- }
-
- @ListFeature.Require(SUPPORTS_SET)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_subListSetAffectsOriginalLargeList() {
- List<E> subList = getList().subList(1, 2);
- subList.set(0, samples.e3);
- List<E> expected = Helpers.copyToList(createSamplesArray());
- expected.set(1, samples.e3);
- expectContents(expected);
- }
-
- @ListFeature.Require(SUPPORTS_SET)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_originalListSetAffectsSubListLargeList() {
- List<E> subList = getList().subList(1, 3);
- getList().set(1, samples.e3);
- assertEquals("A set() call to a list after a sublist has been created "
- + "should be reflected in the sublist",
- Arrays.asList(samples.e3, samples.e2), subList);
- }
-
- public void testSubList_ofSubListEmpty() {
- List<E> subList = getList().subList(0, 0).subList(0, 0);
- assertEquals("subList(0, 0).subList(0, 0) should be an empty list",
- emptyList(), subList);
- }
-
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_ofSubListNonEmpty() {
- List<E> subList = getList().subList(0, 2).subList(1, 2);
- assertEquals("subList(0, 2).subList(1, 2) "
- + "should be a single-element list of the element at index 1",
- Collections.singletonList(getOrderedElements().get(1)), subList);
- }
-
- @CollectionSize.Require(absent = {ZERO})
- public void testSubList_size() {
- List<E> list = getList();
- int size = getNumElements();
- assertEquals(list.subList(0, size).size(),
- size);
- assertEquals(list.subList(0, size - 1).size(),
- size - 1);
- assertEquals(list.subList(1, size).size(),
- size - 1);
- assertEquals(list.subList(size, size).size(),
- 0);
- assertEquals(list.subList(0, 0).size(),
- 0);
- }
-
- @CollectionSize.Require(absent = {ZERO})
- public void testSubList_isEmpty() {
- List<E> list = getList();
- int size = getNumElements();
- for (List<E> subList : Arrays.asList(
- list.subList(0, size),
- list.subList(0, size - 1),
- list.subList(1, size),
- list.subList(0, 0),
- list.subList(size, size))) {
- assertEquals(subList.isEmpty(), subList.size() == 0);
- }
- }
-
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_get() {
- List<E> list = getList();
- int size = getNumElements();
- List<E> copy = list.subList(0, size);
- List<E> head = list.subList(0, size - 1);
- List<E> tail = list.subList(1, size);
- assertEquals(list.get(0), copy.get(0));
- assertEquals(list.get(size - 1), copy.get(size - 1));
- assertEquals(list.get(1), tail.get(0));
- assertEquals(list.get(size - 1), tail.get(size - 2));
- assertEquals(list.get(0), head.get(0));
- assertEquals(list.get(size - 2), head.get(size - 2));
- for (List<E> subList : Arrays.asList(copy, head, tail)) {
- for (int index : Arrays.asList(-1, subList.size())) {
- try {
- subList.get(index);
- fail("expected IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException expected) {
- }
- }
- }
- }
-
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_contains() {
- List<E> list = getList();
- int size = getNumElements();
- List<E> copy = list.subList(0, size);
- List<E> head = list.subList(0, size - 1);
- List<E> tail = list.subList(1, size);
- assertTrue(copy.contains(list.get(0)));
- assertTrue(head.contains(list.get(0)));
- assertTrue(tail.contains(list.get(1)));
- // The following assumes all elements are distinct.
- assertTrue(copy.contains(list.get(size - 1)));
- assertTrue(head.contains(list.get(size - 2)));
- assertTrue(tail.contains(list.get(size - 1)));
- assertFalse(head.contains(list.get(size - 1)));
- assertFalse(tail.contains(list.get(0)));
- }
-
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_indexOf() {
- List<E> list = getList();
- int size = getNumElements();
- List<E> copy = list.subList(0, size);
- List<E> head = list.subList(0, size - 1);
- List<E> tail = list.subList(1, size);
- assertEquals(copy.indexOf(list.get(0)),
- 0);
- assertEquals(head.indexOf(list.get(0)),
- 0);
- assertEquals(tail.indexOf(list.get(1)),
- 0);
- // The following assumes all elements are distinct.
- assertEquals(copy.indexOf(list.get(size - 1)),
- size - 1);
- assertEquals(head.indexOf(list.get(size - 2)),
- size - 2);
- assertEquals(tail.indexOf(list.get(size - 1)),
- size - 2);
- assertEquals(head.indexOf(list.get(size - 1)),
- -1);
- assertEquals(tail.indexOf(list.get(0)),
- -1);
- }
-
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testSubList_lastIndexOf() {
- List<E> list = getList();
- int size = list.size();
- List<E> copy = list.subList(0, size);
- List<E> head = list.subList(0, size - 1);
- List<E> tail = list.subList(1, size);
- assertEquals(copy.lastIndexOf(list.get(size - 1)),
- size - 1);
- assertEquals(head.lastIndexOf(list.get(size - 2)),
- size - 2);
- assertEquals(tail.lastIndexOf(list.get(size - 1)),
- size - 2);
- // The following assumes all elements are distinct.
- assertEquals(copy.lastIndexOf(list.get(0)),
- 0);
- assertEquals(head.lastIndexOf(list.get(0)),
- 0);
- assertEquals(tail.lastIndexOf(list.get(1)),
- 0);
- assertEquals(head.lastIndexOf(list.get(size - 1)),
- -1);
- assertEquals(tail.lastIndexOf(list.get(0)),
- -1);
- }
-
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- public void testReserializeWholeSubList() {
- SerializableTester.reserializeAndAssert(getList().subList(0, getNumElements()));
- }
-
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- public void testReserializeEmptySubList() {
- SerializableTester.reserializeAndAssert(getList().subList(0, 0));
- }
-
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testReserializeSubList() {
- SerializableTester.reserializeAndAssert(getList().subList(0, 2));
- }
-
- /*
- * TODO: perform all List tests on subList(), but beware infinite recursion
- */
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapCreationTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapCreationTester.java
deleted file mode 100644
index 6f8ab8a..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapCreationTester.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.REJECTS_DUPLICATES_AT_CREATION;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map.Entry;
-
-/**
- * A generic JUnit test which tests creation (typically through a constructor or
- * static factory method) of a map. Can't be invoked directly; please see
- * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-public class MapCreationTester<K, V> extends AbstractMapTester<K, V> {
- @MapFeature.Require(ALLOWS_NULL_KEYS)
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNullKeySupported() {
- initMapWithNullKey();
- expectContents(createArrayWithNullKey());
- }
-
- @MapFeature.Require(absent = ALLOWS_NULL_KEYS)
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNullKeyUnsupported() {
- try {
- initMapWithNullKey();
- fail("Creating a map containing a null key should fail");
- } catch (NullPointerException expected) {
- }
- }
-
- @MapFeature.Require(ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNullValueSupported() {
- initMapWithNullValue();
- expectContents(createArrayWithNullValue());
- }
-
- @MapFeature.Require(absent = ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNullValueUnsupported() {
- try {
- initMapWithNullValue();
- fail("Creating a map containing a null value should fail");
- } catch (NullPointerException expected) {
- }
- }
-
- @MapFeature.Require({ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
- @CollectionSize.Require(absent = ZERO)
- public void testCreateWithNullKeyAndValueSupported() {
- Entry<K, V>[] entries = createSamplesArray();
- entries[getNullLocation()] = entry(null, null);
- resetMap(entries);
- expectContents(entries);
- }
-
- @MapFeature.Require(value = ALLOWS_NULL_KEYS,
- absent = REJECTS_DUPLICATES_AT_CREATION)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testCreateWithDuplicates_nullDuplicatesNotRejected() {
- expectFirstRemoved(getEntriesMultipleNullKeys());
- }
-
- @MapFeature.Require(absent = REJECTS_DUPLICATES_AT_CREATION)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testCreateWithDuplicates_nonNullDuplicatesNotRejected() {
- expectFirstRemoved(getEntriesMultipleNonNullKeys());
- }
-
- @MapFeature.Require({ALLOWS_NULL_KEYS, REJECTS_DUPLICATES_AT_CREATION})
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testCreateWithDuplicates_nullDuplicatesRejected() {
- Entry<K, V>[] entries = getEntriesMultipleNullKeys();
- try {
- resetMap(entries);
- fail("Should reject duplicate null elements at creation");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @MapFeature.Require(REJECTS_DUPLICATES_AT_CREATION)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testCreateWithDuplicates_nonNullDuplicatesRejected() {
- Entry<K, V>[] entries = getEntriesMultipleNonNullKeys();
- try {
- resetMap(entries);
- fail("Should reject duplicate non-null elements at creation");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- private Entry<K, V>[] getEntriesMultipleNullKeys() {
- Entry<K, V>[] entries = createArrayWithNullKey();
- entries[0] = entry(null, entries[0].getValue());
- return entries;
- }
-
- private Entry<K, V>[] getEntriesMultipleNonNullKeys() {
- Entry<K, V>[] entries = createSamplesArray();
- entries[0] = entry(samples.e1.getKey(), samples.e0.getValue());
- return entries;
- }
-
- private void expectFirstRemoved(Entry<K, V>[] entries) {
- resetMap(entries);
-
- List<Entry<K, V>> expectedWithDuplicateRemoved =
- Arrays.asList(entries).subList(1, getNumElements());
- expectContents(expectedWithDuplicateRemoved);
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutAllTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutAllTester.java
deleted file mode 100644
index 48ff734..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutAllTester.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import static java.util.Collections.singletonList;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.MinimalCollection;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * A generic JUnit test which tests {@code putAll} operations on a map. Can't be
- * invoked directly; please see
- * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Kevin Bourrillion
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
- private List<Entry<K, V>> containsNullKey;
- private List<Entry<K, V>> containsNullValue;
-
- @Override public void setUp() throws Exception {
- super.setUp();
- containsNullKey = singletonList(entry(null, samples.e3.getValue()));
- containsNullValue = singletonList(entry(samples.e3.getKey(), null));
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAll_supportedNothing() {
- getMap().putAll(emptyMap());
- expectUnchanged();
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- public void testPutAll_unsupportedNothing() {
- try {
- getMap().putAll(emptyMap());
- } catch (UnsupportedOperationException tolerated) {
- }
- expectUnchanged();
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAll_supportedNonePresent() {
- putAll(createDisjointCollection());
- expectAdded(samples.e3, samples.e4);
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- public void testPutAll_unsupportedNonePresent() {
- try {
- putAll(createDisjointCollection());
- fail("putAll(nonePresent) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3, samples.e4);
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutAll_supportedSomePresent() {
- putAll(MinimalCollection.of(samples.e3, samples.e0));
- expectAdded(samples.e3);
- }
-
- @MapFeature.Require({ FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_PUT })
- @CollectionSize.Require(absent = ZERO)
- public void testPutAllSomePresentConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
- putAll(MinimalCollection.of(samples.e3, samples.e0));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutAll_unsupportedSomePresent() {
- try {
- putAll(MinimalCollection.of(samples.e3, samples.e0));
- fail("putAll(somePresent) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutAll_unsupportedAllPresent() {
- try {
- putAll(MinimalCollection.of(samples.e0));
- } catch (UnsupportedOperationException tolerated) {
- }
- expectUnchanged();
- }
-
- @MapFeature.Require({SUPPORTS_PUT,
- ALLOWS_NULL_KEYS})
- public void testPutAll_nullKeySupported() {
- putAll(containsNullKey);
- expectAdded(containsNullKey.get(0));
- }
-
- @MapFeature.Require(value = SUPPORTS_PUT,
- absent = ALLOWS_NULL_KEYS)
- public void testPutAll_nullKeyUnsupported() {
- try {
- putAll(containsNullKey);
- fail("putAll(containsNullKey) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullKeyMissingWhenNullKeysUnsupported(
- "Should not contain null key after unsupported " +
- "putAll(containsNullKey)");
- }
-
- @MapFeature.Require({SUPPORTS_PUT,
- ALLOWS_NULL_VALUES})
- public void testPutAll_nullValueSupported() {
- putAll(containsNullValue);
- expectAdded(containsNullValue.get(0));
- }
-
- @MapFeature.Require(value = SUPPORTS_PUT,
- absent = ALLOWS_NULL_VALUES)
- public void testPutAll_nullValueUnsupported() {
- try {
- putAll(containsNullValue);
- fail("putAll(containsNullValue) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullValueMissingWhenNullValuesUnsupported(
- "Should not contain null value after unsupported " +
- "putAll(containsNullValue)");
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAll_nullCollectionReference() {
- try {
- getMap().putAll(null);
- fail("putAll(null) should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
- }
-
- private Map<K, V> emptyMap() {
- return Collections.emptyMap();
- }
-
- private void putAll(Iterable<Entry<K, V>> entries) {
- Map<K, V> map = new LinkedHashMap<K, V>();
- for (Entry<K, V> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- getMap().putAll(map);
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutTester.java
deleted file mode 100644
index 78de07d..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/MapPutTester.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * A generic JUnit test which tests {@code put} operations on a map. Can't be
- * invoked directly; please see
- * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Kevin Bourrillion
- */
-@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
-public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
- private Entry<K, V> nullKeyEntry;
- private Entry<K, V> nullValueEntry;
- private Entry<K, V> nullKeyValueEntry;
- private Entry<K, V> presentKeyNullValueEntry;
-
- @Override public void setUp() throws Exception {
- super.setUp();
- nullKeyEntry = entry(null, samples.e3.getValue());
- nullValueEntry = entry(samples.e3.getKey(), null);
- nullKeyValueEntry = entry(null, null);
- presentKeyNullValueEntry = entry(samples.e0.getKey(), null);
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPut_supportedNotPresent() {
- assertNull("put(notPresent, value) should return null", put(samples.e3));
- expectAdded(samples.e3);
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
- @CollectionSize.Require(absent = ZERO)
- public void testPutAbsentConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
- put(samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
- @CollectionSize.Require(absent = ZERO)
- public void testPutAbsentConcurrentWithKeySetIteration() {
- try {
- Iterator<K> iterator = getMap().keySet().iterator();
- put(samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
- @CollectionSize.Require(absent = ZERO)
- public void testPutAbsentConcurrentWithValueIteration() {
- try {
- Iterator<V> iterator = getMap().values().iterator();
- put(samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- public void testPut_unsupportedNotPresent() {
- try {
- put(samples.e3);
- fail("put(notPresent, value) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- expectMissing(samples.e3);
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPut_unsupportedPresentExistingValue() {
- try {
- assertEquals("put(present, existingValue) should return present or throw",
- samples.e0.getValue(), put(samples.e0));
- } catch (UnsupportedOperationException tolerated) {
- }
- expectUnchanged();
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPut_unsupportedPresentDifferentValue() {
- try {
- getMap().put(samples.e0.getKey(), samples.e3.getValue());
- fail("put(present, differentValue) should throw");
- } catch (UnsupportedOperationException expected) {
- }
- expectUnchanged();
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
- public void testPut_nullKeySupportedNotPresent() {
- assertNull("put(null, value) should return null", put(nullKeyEntry));
- expectAdded(nullKeyEntry);
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
- @CollectionSize.Require(absent = ZERO)
- public void testPut_nullKeySupportedPresent() {
- Entry<K, V> newEntry = entry(null, samples.e3.getValue());
- initMapWithNullKey();
- assertEquals("put(present, value) should return the associated value",
- getValueForNullKey(), put(newEntry));
-
- Entry<K, V>[] expected = createArrayWithNullKey();
- expected[getNullLocation()] = newEntry;
- expectContents(expected);
- }
-
- @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS)
- public void testPut_nullKeyUnsupported() {
- try {
- put(nullKeyEntry);
- fail("put(null, value) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullKeyMissingWhenNullKeysUnsupported(
- "Should not contain null key after unsupported put(null, value)");
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
- public void testPut_nullValueSupported() {
- assertNull("put(key, null) should return null", put(nullValueEntry));
- expectAdded(nullValueEntry);
- }
-
- @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
- public void testPut_nullValueUnsupported() {
- try {
- put(nullValueEntry);
- fail("put(key, null) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullValueMissingWhenNullValuesUnsupported(
- "Should not contain null value after unsupported put(key, null)");
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
- @CollectionSize.Require(absent = ZERO)
- public void testPut_replaceWithNullValueSupported() {
- assertEquals("put(present, null) should return the associated value",
- samples.e0.getValue(), put(presentKeyNullValueEntry));
- expectReplacement(presentKeyNullValueEntry);
- }
-
- @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testPut_replaceWithNullValueUnsupported() {
- try {
- put(presentKeyNullValueEntry);
- fail("put(present, null) should throw");
- } catch (NullPointerException expected) {
- }
- expectUnchanged();
- expectNullValueMissingWhenNullValuesUnsupported(
- "Should not contain null after unsupported put(present, null)");
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
- @CollectionSize.Require(absent = ZERO)
- public void testPut_replaceNullValueWithNullSupported() {
- initMapWithNullValue();
- assertNull("put(present, null) should return the associated value (null)",
- getMap().put(getKeyForNullValue(), null));
- expectContents(createArrayWithNullValue());
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
- @CollectionSize.Require(absent = ZERO)
- public void testPut_replaceNullValueWithNonNullSupported() {
- Entry<K, V> newEntry = entry(getKeyForNullValue(), samples.e3.getValue());
- initMapWithNullValue();
- assertNull("put(present, value) should return the associated value (null)",
- put(newEntry));
-
- Entry<K, V>[] expected = createArrayWithNullValue();
- expected[getNullLocation()] = newEntry;
- expectContents(expected);
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
- public void testPut_nullKeyAndValueSupported() {
- assertNull("put(null, null) should return null", put(nullKeyValueEntry));
- expectAdded(nullKeyValueEntry);
- }
-
- private V put(Map.Entry<K, V> entry) {
- return getMap().put(entry.getKey(), entry.getValue());
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/Platform.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/Platform.java
deleted file mode 100644
index ce26f1c..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/Platform.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.gwt.core.client.GWT;
-
-/**
- * The emulation source used in GWT.
- *
- * @author Hayward Chan
- */
-@GwtCompatible(emulated = true)
-class Platform {
-
- // Use fewer steps in the ListIteratorTester in ListListIteratorTester because it's slow in prod
- // mode.
- static int listListIteratorTesterNumIterations() {
- // TODO(hhchan): It's 4 in java. Figure out why even 3 is too slow in prod mode.
- return GWT.isProdMode() ? 2 : 4;
- }
-
- // Use fewer steps in the IteratorTester in CollectionIteratorTester because it's slow in prod
- // mode..
- static int collectionIteratorTesterNumIterations() {
- return GWT.isProdMode() ? 3 : 5;
- }
-
- // TODO: Consolidate different copies in one single place.
- static String format(String template, Object... args) {
- // start substituting the arguments into the '%s' placeholders
- StringBuilder builder = new StringBuilder(
- template.length() + 16 * args.length);
- int templateStart = 0;
- int i = 0;
- while (i < args.length) {
- int placeholderStart = template.indexOf("%s", templateStart);
- if (placeholderStart == -1) {
- break;
- }
- builder.append(template.substring(templateStart, placeholderStart));
- builder.append(args[i++]);
- templateStart = placeholderStart + 2;
- }
- builder.append(template.substring(templateStart));
-
- // if we run out of placeholders, append the extra args in square braces
- if (i < args.length) {
- builder.append(" [");
- builder.append(args[i++]);
- while (i < args.length) {
- builder.append(", ");
- builder.append(args[i++]);
- }
- builder.append("]");
- }
-
- return builder.toString();
- }
-}
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetAddTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetAddTester.java
deleted file mode 100644
index a92aabc..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetAddTester.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-/**
- * A generic JUnit test which tests add operations on a set. Can't be
- * invoked directly; please see
- * {@link com.google.common.collect.testing.SetTestSuiteBuilder}.
- *
- * <p>This class is GWT compatible.
- *
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-public class SetAddTester<E> extends AbstractSetTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
- @CollectionSize.Require(absent = ZERO)
- public void testAdd_supportedPresent() {
- assertFalse("add(present) should return false", getSet().add(samples.e0));
- expectUnchanged();
- }
-
- @CollectionFeature.Require(value = {SUPPORTS_ADD, ALLOWS_NULL_VALUES})
- @CollectionSize.Require(absent = ZERO)
- public void testAdd_supportedNullPresent() {
- E[] array = createArrayWithNullElement();
- collection = getSubjectGenerator().create(array);
- assertFalse("add(nullPresent) should return false", getSet().add(null));
- expectContents(array);
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetHashCodeTester.java b/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetHashCodeTester.java
deleted file mode 100644
index 20dea36..0000000
--- a/guava-testlib/blackhole-gwt/src-super/com/google/common/collect/testing/super/com/google/common/collect/testing/testers/SetHashCodeTester.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.Collection;
-
-/**
- * Tests {@link java.util.Set#hashCode}.
- *
- * <p>This class is GWT compatible.
- *
- * @author George van den Driessche
- */
-@GwtCompatible(emulated = true)
-public class SetHashCodeTester<E> extends AbstractSetTester<E> {
- public void testHashCode() {
- int expectedHashCode = 0;
- for (E element : getSampleElements()) {
- expectedHashCode += ((element == null) ? 0 : element.hashCode());
- }
- assertEquals(
- "A Set's hashCode() should be the sum of those of its elements.",
- expectedHashCode, getSet().hashCode());
- }
-
- @CollectionSize.Require(absent = CollectionSize.ZERO)
- @CollectionFeature.Require(ALLOWS_NULL_VALUES)
- public void testHashCode_containingNull() {
- Collection<E> elements = getSampleElements(getNumElements() - 1);
- int expectedHashCode = 0;
- for (E element : elements) {
- expectedHashCode += ((element == null) ? 0 : element.hashCode());
- }
-
- elements.add(null);
- collection = getSubjectGenerator().create(elements.toArray());
- assertEquals(
- "A Set's hashCode() should be the sum of those of its elements (with "
- + "a null element counting as having a hash of zero).",
- expectedHashCode, getSet().hashCode());
- }
-}
-
diff --git a/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/GwtPlatform.java b/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/GwtPlatform.java
deleted file mode 100644
index 4311b8c..0000000
--- a/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/GwtPlatform.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.gwt.core.client.GwtScriptOnly;
-
-/**
- * Version of {@link GwtPlatform} used in hosted-mode. It includes methods in
- * {@link Platform} that requires different implementions in web mode and
- * hosted mode. It is factored out from {@link Platform} because <code>
- * {@literal @}GwtScriptOnly</code> only supports public classes and methods.
- *
- * @author Hayward Chan
- */
-@GwtScriptOnly
-@GwtCompatible
-public final class GwtPlatform {
-
- private GwtPlatform() {}
-
- /** See {@link Platform#clone(Object[])} */
- public static <T> T[] clone(T[] array) {
- return array.clone();
- }
-}
diff --git a/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/Testing.gwt.xml b/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/Testing.gwt.xml
deleted file mode 100644
index c990e09..0000000
--- a/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/Testing.gwt.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
-<module>
-
- <source path=""/>
-
- <super-source path="super"/>
-
- <inherits name="com.google.gwt.junit.JUnit"/>
-
- <inherits name="java.util.Util"/>
-
- <inherits name="com.google.common.annotations.Annotations"/>
-
- <inherits name="com.google.common.testing.Testing"/>
-
-</module>
diff --git a/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/google/Google.gwt.xml b/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/google/Google.gwt.xml
deleted file mode 100644
index 7ffba41..0000000
--- a/guava-testlib/blackhole-gwt/src/com/google/common/collect/testing/google/Google.gwt.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- semi-autogenerated module descriptor -->
-<module>
-
- <source path=""/>
-
- <super-source path="super"/>
-
- <inherits name="com.google.gwt.junit.JUnit"/>
-
- <inherits name="com.google.common.annotations.Annotations"/>
-
- <inherits name="com.google.common.base.Base"/>
-
- <inherits name="com.google.common.collect.Collect"/>
-
- <inherits name="com.google.common.collect.testing.Testing"/>
-
- <inherits name="com.google.common.primitives.Primitives"/>
-
- <inherits name="com.google.common.testing.Testing"/>
-
-</module>
diff --git a/guava-testlib/pom.xml b/guava-testlib/pom.xml
index 2351e09..fed06d7 100644
--- a/guava-testlib/pom.xml
+++ b/guava-testlib/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>com.google.guava</groupId>
<artifactId>guava-parent</artifactId>
- <version>14.0.1</version>
+ <version>11.0.2</version>
</parent>
<artifactId>guava-testlib</artifactId>
<name>Guava Testing Library</name>
@@ -15,12 +15,6 @@
</description>
<dependencies>
<dependency>
- <groupId>com.google.code.findbugs</groupId>
- <artifactId>jsr305</artifactId>
- <version>1.3.9</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>${project.groupId}</groupId>
<artifactId>guava</artifactId>
<version>${project.version}</version>
@@ -31,45 +25,36 @@
<version>4.8.2</version>
</dependency>
<dependency>
- <groupId>org.truth0</groupId>
- <artifactId>truth</artifactId>
- <version>0.10</version>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>2.2.0</version>
+ <scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
+ <source>1.5</source>
+ <target>1.5</target>
</configuration>
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
- <phase>post-integration-test</phase>
- <goals><goal>jar</goal></goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8</version>
- <executions>
- <execution>
- <id>attach-docs</id>
- <phase>post-integration-test</phase>
- <goals><goal>jar</goal></goals>
+ <phase>verify</phase>
+ <goals><goal>jar-no-fork</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
<sourceDirectory>src</sourceDirectory>
- <testSourceDirectory>test</testSourceDirectory>
</build>
</project>
diff --git a/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTestSuiteBuilder.java
index e9aac95..32bc3fb 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTestSuiteBuilder.java
@@ -28,7 +28,6 @@ import com.google.common.collect.testing.testers.CollectionIteratorTester;
import com.google.common.collect.testing.testers.CollectionRemoveAllTester;
import com.google.common.collect.testing.testers.CollectionRemoveTester;
import com.google.common.collect.testing.testers.CollectionRetainAllTester;
-import com.google.common.collect.testing.testers.CollectionSerializationTester;
import com.google.common.collect.testing.testers.CollectionSizeTester;
import com.google.common.collect.testing.testers.CollectionToArrayTester;
import com.google.common.collect.testing.testers.CollectionToStringTester;
@@ -65,15 +64,13 @@ public abstract class AbstractCollectionTestSuiteBuilder<
CollectionRemoveAllTester.class,
CollectionRemoveTester.class,
CollectionRetainAllTester.class,
- CollectionSerializationTester.class,
CollectionSizeTester.class,
CollectionToArrayTester.class,
CollectionToStringTester.class
);
}
- @Override
- protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<
+ @Override List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<
?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>>
parentBuilder) {
DerivedIteratorTestSuiteBuilder<?> iteratorTestSuiteBuilder =
diff --git a/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTester.java b/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTester.java
index 1ddaf93..f1c7688 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AbstractCollectionTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collection;
/**
@@ -29,7 +27,6 @@ import java.util.Collection;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public abstract class AbstractCollectionTester<E>
extends AbstractContainerTester<Collection<E>, E> {
diff --git a/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java b/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java
index e79ee5f..fb95223 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AbstractContainerTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -35,7 +33,6 @@ import java.util.List;
*
* @author George van den Driessche
*/
-@GwtCompatible
public abstract class AbstractContainerTester<C, E>
extends AbstractTester<OneSizeTestContainerGenerator<C, E>> {
protected SampleElements<E> samples;
@@ -113,7 +110,7 @@ public abstract class AbstractContainerTester<C, E>
}
protected void expectUnchanged() {
- expectContents(getOrderedElements());
+ expectContents(getSampleElements());
}
/**
@@ -124,7 +121,7 @@ public abstract class AbstractContainerTester<C, E>
* of each given element has increased by one since the test collection was
* created, and the number of occurrences of all other elements has not
* changed.
- *
+ *
* <p>Note: This means that a test like the following will fail if
* {@code collection} is a {@code Set}:
*
@@ -173,12 +170,6 @@ public abstract class AbstractContainerTester<C, E>
return array;
}
- protected E[] createOrderedArray() {
- E[] array = getSubjectGenerator().createArray(getNumElements());
- getOrderedElements().toArray(array);
- return array;
- }
-
public static class ArrayWithDuplicate<E> {
public final E[] elements;
public final E duplicate;
diff --git a/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java
index d8e52ec..385b92a 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AbstractIteratorTester.java
@@ -19,8 +19,6 @@ package com.google.common.collect.testing;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
-import com.google.common.annotations.GwtCompatible;
-
import junit.framework.AssertionFailedError;
import java.util.ArrayList;
@@ -47,7 +45,6 @@ import java.util.Stack;
* @author Kevin Bourrillion
* @author Chris Povirk
*/
-@GwtCompatible
abstract class AbstractIteratorTester<E, I extends Iterator<E>> {
private boolean whenNextThrowsExceptionStopTestingCallsToRemove;
private boolean whenAddThrowsExceptionStopTesting;
@@ -425,7 +422,7 @@ abstract class AbstractIteratorTester<E, I extends Iterator<E>> {
private static List<Object> subListCopy(Object[] source, int size) {
final Object[] copy = new Object[size];
- System.arraycopy(source, 0, copy, 0, size);
+ Platform.unsafeArrayCopy(source, 0, copy, 0, size);
return Arrays.asList(copy);
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java b/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java
index b86c61a..c8c3169 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AbstractMapTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -38,7 +36,6 @@ import java.util.Map.Entry;
*
* @author George van den Driessche
*/
-@GwtCompatible
public abstract class AbstractMapTester<K, V> extends
AbstractContainerTester<Map<K, V>, Map.Entry<K, V>> {
protected Map<K, V> getMap() {
@@ -175,16 +172,15 @@ public abstract class AbstractMapTester<K, V> extends
for (Entry<K, V> entry : entries) {
assertFalse("Should not contain entry " + entry,
actualContents().contains(entry));
- assertFalse("Should not contain key " + entry.getKey() + " mapped to"
- + " value " + entry.getValue(),
- equal(getMap().get(entry.getKey()), entry.getValue()));
+ assertFalse("Should not contain key " + entry.getKey(),
+ getMap().containsKey(entry.getKey()));
+ assertFalse("Should not contain value " + entry.getValue(),
+ getMap().containsValue(entry.getValue()));
+ assertNull("Should not return a mapping for key " + entry.getKey(),
+ getMap().get(entry.getKey()));
}
}
- private static boolean equal(Object a, Object b) {
- return a == b || (a != null && a.equals(b));
- }
-
// This one-liner saves us from some ugly casts
protected Entry<K, V> entry(K key, V value) {
return Helpers.mapEntry(key, value);
diff --git a/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java b/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java
index e1c8a6f..c141fb4 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AbstractTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import junit.framework.TestCase;
/**
@@ -32,7 +30,6 @@ import junit.framework.TestCase;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class AbstractTester<G> extends TestCase {
private G subjectGenerator;
private String suiteName;
diff --git a/guava-testlib/src/com/google/common/collect/testing/AnEnum.java b/guava-testlib/src/com/google/common/collect/testing/AnEnum.java
index 0c9b98e..3fc1ae3 100644
--- a/guava-testlib/src/com/google/common/collect/testing/AnEnum.java
+++ b/guava-testlib/src/com/google/common/collect/testing/AnEnum.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
/**
* A sample enumerated type we use for testing.
*
@@ -25,7 +23,6 @@ import com.google.common.annotations.GwtCompatible;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public enum AnEnum {
A, B, C, D, E, F
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/BaseComparable.java b/guava-testlib/src/com/google/common/collect/testing/BaseComparable.java
index 7ed604d..93f449c 100644
--- a/guava-testlib/src/com/google/common/collect/testing/BaseComparable.java
+++ b/guava-testlib/src/com/google/common/collect/testing/BaseComparable.java
@@ -16,16 +16,13 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.io.Serializable;
/**
* Simple base class to verify that we handle generics correctly.
- *
+ *
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class BaseComparable implements Comparable<BaseComparable>, Serializable {
private final String s;
diff --git a/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java
index d4143b5..e05a700 100644
--- a/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/CollectionTestSuiteBuilder.java
@@ -16,25 +16,12 @@
package com.google.common.collect.testing;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestSuite;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
/**
* Concrete instantiation of {@link AbstractCollectionTestSuiteBuilder} for
* testing collections that do not have a more specific tester like
* {@link ListTestSuiteBuilder} or {@link SetTestSuiteBuilder}.
*
* @author Chris Povirk
- * @author Louis Wasserman
*/
public class CollectionTestSuiteBuilder<E>
extends AbstractCollectionTestSuiteBuilder<
@@ -43,60 +30,4 @@ public class CollectionTestSuiteBuilder<E>
TestCollectionGenerator<E> generator) {
return new CollectionTestSuiteBuilder<E>().usingGenerator(generator);
}
-
- @Override
- protected
- List<TestSuite>
- createDerivedSuites(
- FeatureSpecificTestSuiteBuilder<
- ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
- List<TestSuite> derivedSuites = new ArrayList<TestSuite>(
- super.createDerivedSuites(parentBuilder));
-
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(CollectionTestSuiteBuilder
- .using(new ReserializedCollectionGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + " reserialized")
- .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
- return derivedSuites;
- }
-
- static class ReserializedCollectionGenerator<E> implements TestCollectionGenerator<E> {
- final OneSizeTestContainerGenerator<Collection<E>, E> gen;
-
- private ReserializedCollectionGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
- this.gen = gen;
- }
-
- @Override
- public SampleElements<E> samples() {
- return gen.samples();
- }
-
- @Override
- public Collection<E> create(Object... elements) {
- return SerializableTester.reserialize(gen.create(elements));
- }
-
- @Override
- public E[] createArray(int length) {
- return gen.createArray(length);
- }
-
- @Override
- public Iterable<E> order(List<E> insertionOrder) {
- return gen.order(insertionOrder);
- }
- }
-
- private static Set<Feature<?>> computeReserializedCollectionFeatures(Set<Feature<?>> features) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- derivedFeatures.addAll(features);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
- return derivedFeatures;
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/ConcurrentMapInterfaceTest.java b/guava-testlib/src/com/google/common/collect/testing/ConcurrentMapInterfaceTest.java
index 55db55c..4ad4230 100644
--- a/guava-testlib/src/com/google/common/collect/testing/ConcurrentMapInterfaceTest.java
+++ b/guava-testlib/src/com/google/common/collect/testing/ConcurrentMapInterfaceTest.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.concurrent.ConcurrentMap;
/**
@@ -33,7 +31,6 @@ import java.util.concurrent.ConcurrentMap;
*
* @author Jared Levy
*/
-@GwtCompatible
public abstract class ConcurrentMapInterfaceTest<K, V>
extends MapInterfaceTest<K, V> {
diff --git a/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java b/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java
deleted file mode 100644
index e177f9f..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/DerivedCollectionGenerators.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.Helpers.castOrCopyToList;
-import static com.google.common.collect.testing.Helpers.equal;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-import static java.util.Collections.sort;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedMap;
-
-/**
- * Derived suite generators, split out of the suite builders so that they are available to GWT.
- *
- * @author George van den Driessche
- */
-@GwtCompatible
-public final class DerivedCollectionGenerators {
- public static class MapEntrySetGenerator<K, V>
- implements TestSetGenerator<Map.Entry<K, V>>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
- mapGenerator;
-
- public MapEntrySetGenerator(
- OneSizeTestContainerGenerator<
- Map<K, V>, Map.Entry<K, V>> mapGenerator) {
- this.mapGenerator = mapGenerator;
- }
-
- @Override
- public SampleElements<Map.Entry<K, V>> samples() {
- return mapGenerator.samples();
- }
-
- @Override
- public Set<Map.Entry<K, V>> create(Object... elements) {
- return mapGenerator.create(elements).entrySet();
- }
-
- @Override
- public Map.Entry<K, V>[] createArray(int length) {
- return mapGenerator.createArray(length);
- }
-
- @Override
- public Iterable<Map.Entry<K, V>> order(
- List<Map.Entry<K, V>> insertionOrder) {
- return mapGenerator.order(insertionOrder);
- }
-
- public OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> getInnerGenerator() {
- return mapGenerator;
- }
- }
-
- // TODO: investigate some API changes to SampleElements that would tidy up
- // parts of the following classes.
-
- public static class MapKeySetGenerator<K, V>
- implements TestSetGenerator<K>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
- mapGenerator;
- private final SampleElements<K> samples;
-
- public MapKeySetGenerator(
- OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
- mapGenerator) {
- this.mapGenerator = mapGenerator;
- final SampleElements<Map.Entry<K, V>> mapSamples =
- this.mapGenerator.samples();
- this.samples = new SampleElements<K>(
- mapSamples.e0.getKey(),
- mapSamples.e1.getKey(),
- mapSamples.e2.getKey(),
- mapSamples.e3.getKey(),
- mapSamples.e4.getKey());
- }
-
- @Override
- public SampleElements<K> samples() {
- return samples;
- }
-
- @Override
- public Set<K> create(Object... elements) {
- @SuppressWarnings("unchecked")
- K[] keysArray = (K[]) elements;
-
- // Start with a suitably shaped collection of entries
- Collection<Map.Entry<K, V>> originalEntries =
- mapGenerator.getSampleElements(elements.length);
-
- // Create a copy of that, with the desired value for each key
- Collection<Map.Entry<K, V>> entries =
- new ArrayList<Entry<K, V>>(elements.length);
- int i = 0;
- for (Map.Entry<K, V> entry : originalEntries) {
- entries.add(Helpers.mapEntry(keysArray[i++], entry.getValue()));
- }
-
- return mapGenerator.create(entries.toArray()).keySet();
- }
-
- @Override
- public K[] createArray(int length) {
- // TODO: with appropriate refactoring of OneSizeGenerator, we can perhaps
- // tidy this up and get rid of the casts here and in
- // MapValueCollectionGenerator.
-
- return ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
- .createKeyArray(length);
- }
-
- @Override
- public Iterable<K> order(List<K> insertionOrder) {
- V v = ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator()).samples().e0.getValue();
- List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
- for (K element : insertionOrder) {
- entries.add(mapEntry(element, v));
- }
-
- List<K> keys = new ArrayList<K>();
- for (Entry<K, V> entry : mapGenerator.order(entries)) {
- keys.add(entry.getKey());
- }
- return keys;
- }
-
- public OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> getInnerGenerator() {
- return mapGenerator;
- }
- }
-
- public static class MapValueCollectionGenerator<K, V>
- implements TestCollectionGenerator<V>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
- mapGenerator;
- private final SampleElements<V> samples;
-
- public MapValueCollectionGenerator(
- OneSizeTestContainerGenerator<
- Map<K, V>, Map.Entry<K, V>> mapGenerator) {
- this.mapGenerator = mapGenerator;
- final SampleElements<Map.Entry<K, V>> mapSamples =
- this.mapGenerator.samples();
- this.samples = new SampleElements<V>(
- mapSamples.e0.getValue(),
- mapSamples.e1.getValue(),
- mapSamples.e2.getValue(),
- mapSamples.e3.getValue(),
- mapSamples.e4.getValue());
- }
-
- @Override
- public SampleElements<V> samples() {
- return samples;
- }
-
- @Override
- public Collection<V> create(Object... elements) {
- @SuppressWarnings("unchecked")
- V[] valuesArray = (V[]) elements;
-
- // Start with a suitably shaped collection of entries
- Collection<Map.Entry<K, V>> originalEntries =
- mapGenerator.getSampleElements(elements.length);
-
- // Create a copy of that, with the desired value for each value
- Collection<Map.Entry<K, V>> entries =
- new ArrayList<Entry<K, V>>(elements.length);
- int i = 0;
- for (Map.Entry<K, V> entry : originalEntries) {
- entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
- }
-
- return mapGenerator.create(entries.toArray()).values();
- }
-
- @Override
- public V[] createArray(int length) {
- //noinspection UnnecessaryLocalVariable
- final V[] vs = ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
- .createValueArray(length);
- return vs;
- }
-
- @Override
- public Iterable<V> order(List<V> insertionOrder) {
- final List<Entry<K, V>> orderedEntries =
- castOrCopyToList(mapGenerator.order(castOrCopyToList(
- mapGenerator.getSampleElements(5))));
- sort(insertionOrder, new Comparator<V>() {
- @Override public int compare(V left, V right) {
- // The indexes are small enough for the subtraction trick to be safe.
- return indexOfEntryWithValue(left) - indexOfEntryWithValue(right);
- }
-
- int indexOfEntryWithValue(V value) {
- for (int i = 0; i < orderedEntries.size(); i++) {
- if (equal(orderedEntries.get(i).getValue(), value)) {
- return i;
- }
- }
- throw new IllegalArgumentException("Map.values generator can order only sample values");
- }
- });
- return insertionOrder;
- }
-
- public OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>> getInnerGenerator() {
- return mapGenerator;
- }
- }
-
- // TODO(cpovirk): could something like this be used elsewhere, e.g., ReserializedListGenerator?
- static class ForwardingTestMapGenerator<K, V> implements TestMapGenerator<K, V> {
- TestMapGenerator<K, V> delegate;
-
- ForwardingTestMapGenerator(TestMapGenerator<K, V> delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
- return delegate.order(insertionOrder);
- }
-
- @Override
- public K[] createKeyArray(int length) {
- return delegate.createKeyArray(length);
- }
-
- @Override
- public V[] createValueArray(int length) {
- return delegate.createValueArray(length);
- }
-
- @Override
- public SampleElements<Entry<K, V>> samples() {
- return delegate.samples();
- }
-
- @Override
- public Map<K, V> create(Object... elements) {
- return delegate.create(elements);
- }
-
- @Override
- public Entry<K, V>[] createArray(int length) {
- return delegate.createArray(length);
- }
- }
-
- /**
- * Two bounds (from and to) define how to build a subMap.
- */
- public enum Bound {
- INCLUSIVE,
- EXCLUSIVE,
- NO_BOUND;
- }
-
- /*
- * TODO(cpovirk): surely we can find a less ugly solution than a class that accepts 3 parameters,
- * exposes as many getters, does work in the constructor, and has both a superclass and a subclass
- */
- public static class SortedMapSubmapTestMapGenerator<K, V>
- extends ForwardingTestMapGenerator<K, V> implements TestSortedMapGenerator<K, V> {
- final Bound to;
- final Bound from;
- final K firstInclusive;
- final K lastInclusive;
- private final Comparator<Entry<K, V>> entryComparator;
-
- public SortedMapSubmapTestMapGenerator(
- TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) {
- super(delegate);
- this.to = to;
- this.from = from;
-
- SortedMap<K, V> emptyMap = delegate.create();
- this.entryComparator = Helpers.entryComparator(emptyMap.comparator());
-
- // derive values for inclusive filtering from the input samples
- SampleElements<Entry<K, V>> samples = delegate.samples();
- @SuppressWarnings("unchecked") // no elements are inserted into the array
- List<Entry<K, V>> samplesList = Arrays.asList(
- samples.e0, samples.e1, samples.e2, samples.e3, samples.e4);
- Collections.sort(samplesList, entryComparator);
- this.firstInclusive = samplesList.get(0).getKey();
- this.lastInclusive = samplesList.get(samplesList.size() - 1).getKey();
- }
-
- @Override public SortedMap<K, V> create(Object... entries) {
- @SuppressWarnings("unchecked") // map generators must past entry objects
- List<Entry<K, V>> normalValues = (List) Arrays.asList(entries);
- List<Entry<K, V>> extremeValues = new ArrayList<Entry<K, V>>();
-
- // prepare extreme values to be filtered out of view
- K firstExclusive = getInnerGenerator().belowSamplesGreater().getKey();
- K lastExclusive = getInnerGenerator().aboveSamplesLesser().getKey();
- if (from != Bound.NO_BOUND) {
- extremeValues.add(getInnerGenerator().belowSamplesLesser());
- extremeValues.add(getInnerGenerator().belowSamplesGreater());
- }
- if (to != Bound.NO_BOUND) {
- extremeValues.add(getInnerGenerator().aboveSamplesLesser());
- extremeValues.add(getInnerGenerator().aboveSamplesGreater());
- }
-
- // the regular values should be visible after filtering
- List<Entry<K, V>> allEntries = new ArrayList<Entry<K, V>>();
- allEntries.addAll(extremeValues);
- allEntries.addAll(normalValues);
- SortedMap<K, V> map = (SortedMap<K, V>)
- delegate.create((Object[])
- allEntries.toArray(new Entry[allEntries.size()]));
-
- return createSubMap(map, firstExclusive, lastExclusive);
- }
-
- /**
- * Calls the smallest subMap overload that filters out the extreme values. This method is
- * overridden in NavigableMapTestSuiteBuilder.
- */
- SortedMap<K, V> createSubMap(SortedMap<K, V> map, K firstExclusive, K lastExclusive) {
- if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) {
- return map.headMap(lastExclusive);
- } else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) {
- return map.tailMap(firstInclusive);
- } else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) {
- return map.subMap(firstInclusive, lastExclusive);
- } else {
- throw new IllegalArgumentException();
- }
- }
-
- public final Bound getTo() {
- return to;
- }
-
- public final Bound getFrom() {
- return from;
- }
-
- public final TestSortedMapGenerator<K, V> getInnerGenerator() {
- return (TestSortedMapGenerator<K, V>) delegate;
- }
-
- @Override
- public Entry<K, V> belowSamplesLesser() {
- // should never reach here!
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Entry<K, V> belowSamplesGreater() {
- // should never reach here!
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Entry<K, V> aboveSamplesLesser() {
- // should never reach here!
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Entry<K, V> aboveSamplesGreater() {
- // should never reach here!
- throw new UnsupportedOperationException();
- }
- }
-
- private DerivedCollectionGenerators() {}
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/DerivedComparable.java b/guava-testlib/src/com/google/common/collect/testing/DerivedComparable.java
index 5b0d16f..254bd57 100644
--- a/guava-testlib/src/com/google/common/collect/testing/DerivedComparable.java
+++ b/guava-testlib/src/com/google/common/collect/testing/DerivedComparable.java
@@ -16,14 +16,11 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
/**
* Simple derived class to verify that we handle generics correctly.
- *
+ *
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class DerivedComparable extends BaseComparable {
public DerivedComparable(String s) {
super(s);
diff --git a/guava-testlib/src/com/google/common/collect/testing/DerivedGenerator.java b/guava-testlib/src/com/google/common/collect/testing/DerivedGenerator.java
deleted file mode 100644
index d80f5a9..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/DerivedGenerator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * A generator that relies on a preexisting generator for most of its work. For example, a derived
- * iterator generator may delegate the work of creating the underlying collection to an inner
- * collection generator.
- *
- * <p>{@code GwtTestSuiteGenerator} expects every {@code DerivedIterator} implementation to provide
- * a one-arg constructor accepting its inner generator as an argument). This requirement enables it
- * to generate source code (since GWT cannot use reflection to generate the suites).
- *
- * @author Chris Povirk
- */
-@GwtCompatible
-public interface DerivedGenerator {
- TestSubjectGenerator<?> getInnerGenerator();
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/DerivedTestIteratorGenerator.java b/guava-testlib/src/com/google/common/collect/testing/DerivedTestIteratorGenerator.java
index cd23173..a1ff114 100644
--- a/guava-testlib/src/com/google/common/collect/testing/DerivedTestIteratorGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/DerivedTestIteratorGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Iterator;
/**
@@ -27,9 +25,8 @@ import java.util.Iterator;
*
* @author George van den Driessche
*/
-@GwtCompatible
public final class DerivedTestIteratorGenerator<E>
- implements TestIteratorGenerator<E>, DerivedGenerator {
+ implements TestIteratorGenerator<E> {
private final TestSubjectGenerator<? extends Iterable<E>>
collectionGenerator;
@@ -38,8 +35,7 @@ public final class DerivedTestIteratorGenerator<E>
this.collectionGenerator = collectionGenerator;
}
- @Override
- public TestSubjectGenerator<? extends Iterable<E>> getInnerGenerator() {
+ public TestSubjectGenerator<? extends Iterable<E>> getCollectionGenerator() {
return collectionGenerator;
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/ExampleIteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/ExampleIteratorTester.java
index 92388e6..6fa6d40 100644
--- a/guava-testlib/src/com/google/common/collect/testing/ExampleIteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/ExampleIteratorTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
/**
* A non-empty tester for {@link java.util.Iterator}.
*
@@ -25,7 +23,6 @@ import com.google.common.annotations.GwtCompatible;
*
* @author George van den Driessche
*/
-@GwtCompatible
public final class ExampleIteratorTester<E>
extends AbstractTester<TestIteratorGenerator<E>> {
public void testSomethingAboutIterators() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java
index 8163bb5..3cee7ce 100644
--- a/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilder.java
@@ -34,9 +34,10 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
@@ -76,7 +77,7 @@ public abstract class FeatureSpecificTestSuiteBuilder<
return self();
}
- public G getSubjectGenerator() {
+ protected G getSubjectGenerator() {
return subjectGenerator;
}
@@ -100,25 +101,22 @@ public abstract class FeatureSpecificTestSuiteBuilder<
// Features
- private Set<Feature<?>> features = new LinkedHashSet<Feature<?>>();
+ private Set<Feature<?>> features;
/**
* Configures this builder to produce tests appropriate for the given
- * features. This method may be called more than once to add features
- * in multiple groups.
+ * features.
*/
public B withFeatures(Feature<?>... features) {
return withFeatures(Arrays.asList(features));
}
public B withFeatures(Iterable<? extends Feature<?>> features) {
- for (Feature<?> feature : features) {
- this.features.add(feature);
- }
+ this.features = Helpers.copyToSet(features);
return self();
}
- public Set<Feature<?>> getFeatures() {
+ protected Set<Feature<?>> getFeatures() {
return Collections.unmodifiableSet(features);
}
@@ -136,7 +134,7 @@ public abstract class FeatureSpecificTestSuiteBuilder<
return self();
}
- public String getName() {
+ protected String getName() {
return name;
}
@@ -161,7 +159,7 @@ public abstract class FeatureSpecificTestSuiteBuilder<
return self();
}
- public Set<Method> getSuppressedTests() {
+ protected Set<Method> getSuppressedTests() {
return suppressedTests;
}
@@ -274,10 +272,10 @@ public abstract class FeatureSpecificTestSuiteBuilder<
private static Method extractMethod(Test test) {
if (test instanceof AbstractTester) {
AbstractTester<?> tester = (AbstractTester<?>) test;
- return Helpers.getMethod(tester.getClass(), tester.getTestMethodName());
+ return Platform.getMethod(tester.getClass(), tester.getTestMethodName());
} else if (test instanceof TestCase) {
TestCase testCase = (TestCase) test;
- return Helpers.getMethod(testCase.getClass(), testCase.getName());
+ return Platform.getMethod(testCase.getClass(), testCase.getName());
} else {
throw new IllegalArgumentException(
"unable to extract method from test: not a TestCase.");
@@ -286,7 +284,7 @@ public abstract class FeatureSpecificTestSuiteBuilder<
protected TestSuite makeSuiteForTesterClass(
Class<? extends AbstractTester<?>> testerClass) {
- final TestSuite candidateTests = new TestSuite(testerClass);
+ final TestSuite candidateTests = getTemplateSuite(testerClass);
final TestSuite suite = filterSuite(candidateTests);
Enumeration<?> allTests = suite.tests();
@@ -302,6 +300,22 @@ public abstract class FeatureSpecificTestSuiteBuilder<
return suite;
}
+ private static final Map<Class<? extends AbstractTester<?>>, TestSuite>
+ templateSuiteForClass =
+ new HashMap<Class<? extends AbstractTester<?>>, TestSuite>();
+
+ private static TestSuite getTemplateSuite(
+ Class<? extends AbstractTester<?>> testerClass) {
+ synchronized (templateSuiteForClass) {
+ TestSuite suite = templateSuiteForClass.get(testerClass);
+ if (suite == null) {
+ suite = new TestSuite(testerClass);
+ templateSuiteForClass.put(testerClass, suite);
+ }
+ return suite;
+ }
+ }
+
private TestSuite filterSuite(TestSuite suite) {
TestSuite filtered = new TestSuite(suite.getName());
final Enumeration<?> tests = suite.tests();
diff --git a/guava-testlib/src/com/google/common/collect/testing/Helpers.java b/guava-testlib/src/com/google/common/collect/testing/Helpers.java
index 277f50d..9c0a5f5 100644
--- a/guava-testlib/src/com/google/common/collect/testing/Helpers.java
+++ b/guava-testlib/src/com/google/common/collect/testing/Helpers.java
@@ -16,19 +16,13 @@
package com.google.common.collect.testing;
-import static java.util.Collections.sort;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
-import java.io.Serializable;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -42,7 +36,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-@GwtCompatible(emulated = true)
+// This class is GWT compatible.
public class Helpers {
// Clone of Objects.equal
static boolean equal(Object a, Object b) {
@@ -72,7 +66,7 @@ public class Helpers {
}
// Would use Maps.immutableEntry
- public static <K, V> Entry<K, V> mapEntry(K key, V value) {
+ static <K, V> Entry<K, V> mapEntry(K key, V value) {
return Collections.singletonMap(key, value).entrySet().iterator().next();
}
@@ -171,11 +165,8 @@ public class Helpers {
final Comparator<? super K> keyComparator) {
return new Comparator<Entry<K, V>>() {
@Override
- @SuppressWarnings("unchecked") // no less safe than putting it in the map!
public int compare(Entry<K, V> a, Entry<K, V> b) {
- return (keyComparator == null)
- ? ((Comparable) a.getKey()).compareTo(b.getKey())
- : keyComparator.compare(a.getKey(), b.getKey());
+ return keyComparator.compare(a.getKey(), b.getKey());
}
};
}
@@ -257,9 +248,9 @@ public class Helpers {
* possible to access the raw (modifiable) map entry via a nefarious equals
* method.
*/
- public static <K, V> Map.Entry<K, V> nefariousMapEntry(final K key,
+ public static <K, V> Map.Entry<K, V> nefariousMapEntry(final K key,
final V value) {
- return new Map.Entry<K, V>() {
+ return new Map.Entry<K, V>() {
@Override public K getKey() {
return key;
}
@@ -271,10 +262,10 @@ public class Helpers {
}
@SuppressWarnings("unchecked")
@Override public boolean equals(Object o) {
- if (o instanceof Map.Entry) {
+ if (o instanceof Map.Entry<?, ?>) {
Map.Entry<K, V> e = (Map.Entry<K, V>) o;
e.setValue(value); // muhahaha!
-
+
return equal(this.getKey(), e.getKey())
&& equal(this.getValue(), e.getValue());
}
@@ -295,120 +286,5 @@ public class Helpers {
return getKey() + "=" + getValue();
}
};
- }
-
- static <E> List<E> castOrCopyToList(Iterable<E> iterable) {
- if (iterable instanceof List) {
- return (List<E>) iterable;
- }
- List<E> list = new ArrayList<E>();
- for (E e : iterable) {
- list.add(e);
- }
- return list;
- }
-
- private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
- @SuppressWarnings("unchecked") // assume any Comparable is Comparable<Self>
- @Override public int compare(Comparable left, Comparable right) {
- return left.compareTo(right);
- }
- };
-
- public static <K extends Comparable, V> Iterable<Entry<K, V>> orderEntriesByKey(
- List<Entry<K, V>> insertionOrder) {
- sort(insertionOrder, Helpers.<K, V>entryComparator(NATURAL_ORDER));
- return insertionOrder;
- }
-
- /**
- * Private replacement for {@link com.google.gwt.user.client.rpc.GwtTransient} to work around
- * build-system quirks.
- */
- private @interface GwtTransient {}
-
- /**
- * Compares strings in natural order except that null comes immediately before a given value. This
- * works better than Ordering.natural().nullsFirst() because, if null comes before all other
- * values, it lies outside the submap/submultiset ranges we test, and the variety of tests that
- * exercise null handling fail on those subcollections.
- */
- public abstract static class NullsBefore implements Comparator<String>, Serializable {
- /*
- * We don't serialize this class in GWT, so we don't care about whether GWT will serialize this
- * field.
- */
- @GwtTransient private final String justAfterNull;
-
- protected NullsBefore(String justAfterNull) {
- if (justAfterNull == null) {
- throw new NullPointerException();
- }
-
- this.justAfterNull = justAfterNull;
- }
-
- @Override
- public int compare(String lhs, String rhs) {
- if (lhs == rhs) {
- return 0;
- }
- if (lhs == null) {
- // lhs (null) comes just before justAfterNull.
- // If rhs is b, lhs comes first.
- if (rhs.equals(justAfterNull)) {
- return -1;
- }
- return justAfterNull.compareTo(rhs);
- }
- if (rhs == null) {
- // rhs (null) comes just before justAfterNull.
- // If lhs is b, rhs comes first.
- if (lhs.equals(justAfterNull)) {
- return 1;
- }
- return lhs.compareTo(justAfterNull);
- }
- return lhs.compareTo(rhs);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof NullsBefore) {
- NullsBefore other = (NullsBefore) obj;
- return justAfterNull.equals(other.justAfterNull);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return justAfterNull.hashCode();
- }
- }
-
- public static final class NullsBeforeB extends NullsBefore {
- public static final NullsBeforeB INSTANCE = new NullsBeforeB();
-
- private NullsBeforeB() {
- super("b");
- }
- }
-
- public static final class NullsBeforeTwo extends NullsBefore {
- public static final NullsBeforeTwo INSTANCE = new NullsBeforeTwo();
-
- private NullsBeforeTwo() {
- super("two"); // from TestStringSortedMapGenerator's sample keys
- }
- }
-
- @GwtIncompatible("reflection")
- public static Method getMethod(Class<?> clazz, String name) {
- try {
- return clazz.getMethod(name);
- } catch (Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
+ }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java b/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java
index 145dfe2..bcf0fdf 100644
--- a/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java
+++ b/guava-testlib/src/com/google/common/collect/testing/IteratorFeature.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
@@ -32,7 +30,6 @@ import java.util.Set;
*
* @author Chris Povirk
*/
-@GwtCompatible
public enum IteratorFeature {
/**
* Support for {@link Iterator#remove()}.
diff --git a/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java
index 2fa77fb..2a17dca 100644
--- a/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/IteratorTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collections;
import java.util.Iterator;
@@ -62,7 +60,6 @@ import java.util.Iterator;
* @author Kevin Bourrillion
* @author Chris Povirk
*/
-@GwtCompatible
public abstract class IteratorTester<E> extends
AbstractIteratorTester<E, Iterator<E>> {
/**
diff --git a/guava-testlib/src/com/google/common/collect/testing/ListIteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/ListIteratorTester.java
index 620b3fd..87d7b71 100644
--- a/guava-testlib/src/com/google/common/collect/testing/ListIteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/ListIteratorTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
@@ -39,7 +37,6 @@ import java.util.ListIterator;
*
* @author Chris Povirk
*/
-@GwtCompatible
public abstract class ListIteratorTester<E> extends
AbstractIteratorTester<E, ListIterator<E>> {
protected ListIteratorTester(int steps, Iterable<E> elementsToInsert,
diff --git a/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java
index 03f16cf..e8bdf78 100644
--- a/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/ListTestSuiteBuilder.java
@@ -18,7 +18,6 @@ package com.google.common.collect.testing;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.testers.CollectionSerializationEqualTester;
import com.google.common.collect.testing.testers.ListAddAllAtIndexTester;
import com.google.common.collect.testing.testers.ListAddAllTester;
import com.google.common.collect.testing.testers.ListAddAtIndexTester;
@@ -37,15 +36,10 @@ import com.google.common.collect.testing.testers.ListRetainAllTester;
import com.google.common.collect.testing.testers.ListSetTester;
import com.google.common.collect.testing.testers.ListSubListTester;
import com.google.common.collect.testing.testers.ListToArrayTester;
-import com.google.common.testing.SerializableTester;
import junit.framework.TestSuite;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* Creates, based on your criteria, a JUnit test suite that exhaustively tests
@@ -64,7 +58,6 @@ public final class ListTestSuiteBuilder<E> extends
List<Class<? extends AbstractTester>> testers
= Helpers.copyToList(super.getTesters());
- testers.add(CollectionSerializationEqualTester.class);
testers.add(ListAddAllAtIndexTester.class);
testers.add(ListAddAllTester.class);
testers.add(ListAddAtIndexTester.class);
@@ -91,64 +84,11 @@ public final class ListTestSuiteBuilder<E> extends
* lists have an iteration ordering corresponding to the insertion order.
*/
@Override public TestSuite createTestSuite() {
- withFeatures(CollectionFeature.KNOWN_ORDER);
- return super.createTestSuite();
- }
-
- @Override
- protected
- List<TestSuite>
- createDerivedSuites(
- FeatureSpecificTestSuiteBuilder<
- ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
- List<TestSuite> derivedSuites = new ArrayList<TestSuite>(
- super.createDerivedSuites(parentBuilder));
-
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(ListTestSuiteBuilder
- .using(new ReserializedListGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + " reserialized")
- .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
- return derivedSuites;
- }
-
- static class ReserializedListGenerator<E> implements TestListGenerator<E>{
- final OneSizeTestContainerGenerator<Collection<E>, E> gen;
-
- private ReserializedListGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
- this.gen = gen;
- }
-
- @Override
- public SampleElements<E> samples() {
- return gen.samples();
+ if (!getFeatures().contains(CollectionFeature.KNOWN_ORDER)) {
+ List<Feature<?>> features = Helpers.copyToList(getFeatures());
+ features.add(CollectionFeature.KNOWN_ORDER);
+ withFeatures(features);
}
-
- @Override
- public List<E> create(Object... elements) {
- return (List<E>) SerializableTester.reserialize(gen.create(elements));
- }
-
- @Override
- public E[] createArray(int length) {
- return gen.createArray(length);
- }
-
- @Override
- public Iterable<E> order(List<E> insertionOrder) {
- return gen.order(insertionOrder);
- }
- }
-
- private static Set<Feature<?>> computeReserializedCollectionFeatures(
- Set<Feature<?>> features) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- derivedFeatures.addAll(features);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
- return derivedFeatures;
+ return super.createTestSuite();
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java b/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java
index d33f49e..e080157 100644
--- a/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java
+++ b/guava-testlib/src/com/google/common/collect/testing/MapInterfaceTest.java
@@ -18,8 +18,6 @@ package com.google.common.collect.testing;
import static java.util.Collections.singleton;
-import com.google.common.annotations.GwtCompatible;
-
import junit.framework.TestCase;
import java.util.Arrays;
@@ -49,7 +47,6 @@ import java.util.Set;
*
* @author George van den Driessche
*/
-@GwtCompatible
public abstract class MapInterfaceTest<K, V> extends TestCase {
/** A key type that is not assignable to any classes but Object. */
diff --git a/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java
index aa5b050..dbb7fa2 100644
--- a/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/MapTestSuiteBuilder.java
@@ -16,9 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.collect.testing.DerivedCollectionGenerators.MapEntrySetGenerator;
-import com.google.common.collect.testing.DerivedCollectionGenerators.MapKeySetGenerator;
-import com.google.common.collect.testing.DerivedCollectionGenerators.MapValueCollectionGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.Feature;
@@ -34,16 +31,17 @@ import com.google.common.collect.testing.testers.MapIsEmptyTester;
import com.google.common.collect.testing.testers.MapPutAllTester;
import com.google.common.collect.testing.testers.MapPutTester;
import com.google.common.collect.testing.testers.MapRemoveTester;
-import com.google.common.collect.testing.testers.MapSerializationTester;
import com.google.common.collect.testing.testers.MapSizeTester;
-import com.google.common.testing.SerializableTester;
import junit.framework.TestSuite;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
/**
@@ -75,13 +73,11 @@ public class MapTestSuiteBuilder<K, V>
MapPutTester.class,
MapPutAllTester.class,
MapRemoveTester.class,
- MapSerializationTester.class,
MapSizeTester.class
);
}
- @Override
- protected List<TestSuite> createDerivedSuites(
+ @Override List<TestSuite> createDerivedSuites(
FeatureSpecificTestSuiteBuilder<
?,
? extends OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>>
@@ -92,15 +88,6 @@ public class MapTestSuiteBuilder<K, V>
List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(MapTestSuiteBuilder.using(
- new ReserializedMapGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeReserializedMapFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + " reserialized")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
-
derivedSuites.add(SetTestSuiteBuilder.using(
new MapEntrySetGenerator<K, V>(parentBuilder.getSubjectGenerator()))
.withFeatures(computeEntrySetFeatures(parentBuilder.getFeatures()))
@@ -131,17 +118,9 @@ public class MapTestSuiteBuilder<K, V>
return SetTestSuiteBuilder.using(keySetGenerator);
}
- private static Set<Feature<?>> computeReserializedMapFeatures(
- Set<Feature<?>> mapFeatures) {
- Set<Feature<?>> derivedFeatures = Helpers.copyToSet(mapFeatures);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
- return derivedFeatures;
- }
-
private static Set<Feature<?>> computeEntrySetFeatures(
Set<Feature<?>> mapFeatures) {
- Set<Feature<?>> entrySetFeatures =
+ Set<Feature<?>> entrySetFeatures =
computeCommonDerivedCollectionFeatures(mapFeatures);
entrySetFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
return entrySetFeatures;
@@ -165,9 +144,8 @@ public class MapTestSuiteBuilder<K, V>
Set<Feature<?>> mapFeatures) {
Set<Feature<?>> valuesCollectionFeatures =
computeCommonDerivedCollectionFeatures(mapFeatures);
- if (mapFeatures.contains(MapFeature.ALLOWS_NULL_QUERIES)) {
- valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
- }
+ valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
+
if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) {
valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
}
@@ -178,21 +156,17 @@ public class MapTestSuiteBuilder<K, V>
private static Set<Feature<?>> computeCommonDerivedCollectionFeatures(
Set<Feature<?>> mapFeatures) {
Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- if (mapFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- derivedFeatures.add(CollectionFeature.SERIALIZABLE);
- }
if (mapFeatures.contains(MapFeature.SUPPORTS_REMOVE)) {
derivedFeatures.add(CollectionFeature.SUPPORTS_REMOVE);
+ derivedFeatures.add(CollectionFeature.SUPPORTS_REMOVE_ALL);
+ derivedFeatures.add(CollectionFeature.SUPPORTS_RETAIN_ALL);
+ }
+ if (mapFeatures.contains(MapFeature.SUPPORTS_CLEAR)) {
+ derivedFeatures.add(CollectionFeature.SUPPORTS_CLEAR);
}
if (mapFeatures.contains(MapFeature.REJECTS_DUPLICATES_AT_CREATION)) {
derivedFeatures.add(CollectionFeature.REJECTS_DUPLICATES_AT_CREATION);
}
- if (mapFeatures.contains(MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION)) {
- derivedFeatures.add(CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION);
- }
- if (mapFeatures.contains(CollectionFeature.KNOWN_ORDER)) {
- derivedFeatures.add(CollectionFeature.KNOWN_ORDER);
- }
// add the intersection of CollectionSize.values() and mapFeatures
for (CollectionSize size : CollectionSize.values()) {
if (mapFeatures.contains(size)) {
@@ -202,12 +176,12 @@ public class MapTestSuiteBuilder<K, V>
return derivedFeatures;
}
- private static class ReserializedMapGenerator<K, V>
- implements TestMapGenerator<K, V> {
+ private static class MapEntrySetGenerator<K, V>
+ implements TestSetGenerator<Map.Entry<K, V>> {
private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
mapGenerator;
- public ReserializedMapGenerator(
+ public MapEntrySetGenerator(
OneSizeTestContainerGenerator<
Map<K, V>, Map.Entry<K, V>> mapGenerator) {
this.mapGenerator = mapGenerator;
@@ -219,6 +193,11 @@ public class MapTestSuiteBuilder<K, V>
}
@Override
+ public Set<Map.Entry<K, V>> create(Object... elements) {
+ return mapGenerator.create(elements).entrySet();
+ }
+
+ @Override
public Map.Entry<K, V>[] createArray(int length) {
return mapGenerator.createArray(length);
}
@@ -228,22 +207,127 @@ public class MapTestSuiteBuilder<K, V>
List<Map.Entry<K, V>> insertionOrder) {
return mapGenerator.order(insertionOrder);
}
+ }
+
+ // TODO: investigate some API changes to SampleElements that would tidy up
+ // parts of the following classes.
+
+ private static class MapKeySetGenerator<K, V> implements TestSetGenerator<K> {
+ private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
+ mapGenerator;
+ private final SampleElements<K> samples;
+
+ public MapKeySetGenerator(
+ OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
+ mapGenerator) {
+ this.mapGenerator = mapGenerator;
+ final SampleElements<Map.Entry<K, V>> mapSamples =
+ this.mapGenerator.samples();
+ this.samples = new SampleElements<K>(
+ mapSamples.e0.getKey(),
+ mapSamples.e1.getKey(),
+ mapSamples.e2.getKey(),
+ mapSamples.e3.getKey(),
+ mapSamples.e4.getKey());
+ }
@Override
- public Map<K, V> create(Object... elements) {
- return SerializableTester.reserialize(mapGenerator.create(elements));
+ public SampleElements<K> samples() {
+ return samples;
}
@Override
- public K[] createKeyArray(int length) {
+ public Set<K> create(Object... elements) {
+ @SuppressWarnings("unchecked")
+ K[] keysArray = (K[]) elements;
+
+ // Start with a suitably shaped collection of entries
+ Collection<Map.Entry<K, V>> originalEntries =
+ mapGenerator.getSampleElements(elements.length);
+
+ // Create a copy of that, with the desired value for each key
+ Collection<Map.Entry<K, V>> entries =
+ new ArrayList<Entry<K, V>>(elements.length);
+ int i = 0;
+ for (Map.Entry<K, V> entry : originalEntries) {
+ entries.add(Helpers.mapEntry(keysArray[i++], entry.getValue()));
+ }
+
+ return mapGenerator.create(entries.toArray()).keySet();
+ }
+
+ @Override
+ public K[] createArray(int length) {
+ // TODO: with appropriate refactoring of OneSizeGenerator, we can perhaps
+ // tidy this up and get rid of the casts here and in
+ // MapValueCollectionGenerator.
+
return ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
.createKeyArray(length);
}
@Override
- public V[] createValueArray(int length) {
- return ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
- .createValueArray(length);
+ public Iterable<K> order(List<K> insertionOrder) {
+ return insertionOrder;
+ }
+ }
+
+ private static class MapValueCollectionGenerator<K, V>
+ implements TestCollectionGenerator<V> {
+ private final OneSizeTestContainerGenerator<Map<K, V>, Map.Entry<K, V>>
+ mapGenerator;
+ private final SampleElements<V> samples;
+
+ public MapValueCollectionGenerator(
+ OneSizeTestContainerGenerator<
+ Map<K, V>, Map.Entry<K, V>> mapGenerator) {
+ this.mapGenerator = mapGenerator;
+ final SampleElements<Map.Entry<K, V>> mapSamples =
+ this.mapGenerator.samples();
+ this.samples = new SampleElements<V>(
+ mapSamples.e0.getValue(),
+ mapSamples.e1.getValue(),
+ mapSamples.e2.getValue(),
+ mapSamples.e3.getValue(),
+ mapSamples.e4.getValue());
+ }
+
+ @Override
+ public SampleElements<V> samples() {
+ return samples;
+ }
+
+ @Override
+ public Collection<V> create(Object... elements) {
+ @SuppressWarnings("unchecked")
+ V[] valuesArray = (V[]) elements;
+
+ // Start with a suitably shaped collection of entries
+ Collection<Map.Entry<K, V>> originalEntries =
+ mapGenerator.getSampleElements(elements.length);
+
+ // Create a copy of that, with the desired value for each value
+ Collection<Map.Entry<K, V>> entries =
+ new ArrayList<Entry<K, V>>(elements.length);
+ int i = 0;
+ for (Map.Entry<K, V> entry : originalEntries) {
+ entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
+ }
+
+ return mapGenerator.create(entries.toArray()).values();
+ }
+
+ @Override
+ public V[] createArray(int length) {
+ //noinspection UnnecessaryLocalVariable
+ final V[] vs = ((TestMapGenerator<K, V>) mapGenerator.getInnerGenerator())
+ .createValueArray(length);
+ return vs;
+ }
+
+ @Override
+ public Iterable<V> order(List<V> insertionOrder) {
+ return insertionOrder;
}
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java b/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java
index 6c30ab9..20c9db9 100644
--- a/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java
+++ b/guava-testlib/src/com/google/common/collect/testing/MinimalCollection.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.AbstractCollection;
import java.util.Arrays;
import java.util.Collection;
@@ -29,7 +27,6 @@ import java.util.Iterator;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class MinimalCollection<E> extends AbstractCollection<E> {
// TODO: expose allow nulls parameter?
@@ -96,7 +93,7 @@ public class MinimalCollection<E> extends AbstractCollection<E> {
@Override public Object[] toArray() {
Object[] result = new Object[contents.length];
- System.arraycopy(contents, 0, result, 0, contents.length);
+ Platform.unsafeArrayCopy(contents, 0, result, 0, contents.length);
return result;
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java b/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java
index 587e3d3..2d2cf10 100644
--- a/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java
+++ b/guava-testlib/src/com/google/common/collect/testing/MinimalIterable.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
@@ -50,7 +48,6 @@ import java.util.Iterator;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public final class MinimalIterable<E> implements Iterable<E> {
/**
* Returns an iterable whose iterator returns the given elements in order.
diff --git a/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java b/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java
index 06e4519..e8270dd 100644
--- a/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java
+++ b/guava-testlib/src/com/google/common/collect/testing/MinimalSet.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -33,7 +31,6 @@ import java.util.Set;
*
* @author Regina O'Dell
*/
-@GwtCompatible
public class MinimalSet<E> extends MinimalCollection<E> implements Set<E> {
@SuppressWarnings("unchecked") // empty Object[] as E[]
diff --git a/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java
index 64df720..1d38601 100644
--- a/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/NavigableMapTestSuiteBuilder.java
@@ -16,30 +16,28 @@
package com.google.common.collect.testing;
-import static com.google.common.collect.testing.Helpers.castOrCopyToList;
-import static java.util.Collections.reverse;
-
-import com.google.common.collect.testing.DerivedCollectionGenerators.Bound;
-import com.google.common.collect.testing.DerivedCollectionGenerators.SortedMapSubmapTestMapGenerator;
import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.testers.NavigableMapNavigationTester;
+import com.google.common.collect.testing.testers.MapNavigationTester;
import junit.framework.TestSuite;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
-import java.util.SortedMap;
+import java.util.Set;
/**
* Creates, based on your criteria, a JUnit test suite that exhaustively tests
* a NavigableMap implementation.
*/
-public class NavigableMapTestSuiteBuilder<K, V> extends SortedMapTestSuiteBuilder<K, V> {
+public class NavigableMapTestSuiteBuilder<K, V> extends MapTestSuiteBuilder<K, V> {
public static <K, V> NavigableMapTestSuiteBuilder<K, V> using(
- TestSortedMapGenerator<K, V> generator) {
+ TestMapGenerator<K, V> generator) {
NavigableMapTestSuiteBuilder<K, V> result = new NavigableMapTestSuiteBuilder<K, V>();
result.usingGenerator(generator);
return result;
@@ -47,12 +45,11 @@ public class NavigableMapTestSuiteBuilder<K, V> extends SortedMapTestSuiteBuilde
@Override protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
- testers.add(NavigableMapNavigationTester.class);
+ testers.add(MapNavigationTester.class);
return testers;
}
- @Override
- protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?,
+ @Override List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?,
? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> parentBuilder) {
List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
@@ -61,52 +58,148 @@ public class NavigableMapTestSuiteBuilder<K, V> extends SortedMapTestSuiteBuilde
}
if (!parentBuilder.getFeatures().contains(NoRecurse.SUBMAP)) {
- // Other combinations are inherited from SortedMapTestSuiteBuilder.
+ derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.EXCLUSIVE));
derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.INCLUSIVE));
derivedSuites.add(createSubmapSuite(parentBuilder, Bound.EXCLUSIVE, Bound.NO_BOUND));
derivedSuites.add(createSubmapSuite(parentBuilder, Bound.EXCLUSIVE, Bound.EXCLUSIVE));
derivedSuites.add(createSubmapSuite(parentBuilder, Bound.EXCLUSIVE, Bound.INCLUSIVE));
+ derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.NO_BOUND));
+ derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.EXCLUSIVE));
derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.INCLUSIVE));
}
return derivedSuites;
}
- @Override protected NavigableSetTestSuiteBuilder<K> createDerivedKeySetSuite(
+ @Override protected SetTestSuiteBuilder<K> createDerivedKeySetSuite(
TestSetGenerator<K> keySetGenerator) {
return NavigableSetTestSuiteBuilder.using(keySetGenerator);
}
- public static final class NavigableMapSubmapTestMapGenerator<K, V>
- extends SortedMapSubmapTestMapGenerator<K, V> {
- public NavigableMapSubmapTestMapGenerator(
- TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) {
- super(delegate, to, from);
- }
+ /**
+ * To avoid infinite recursion, test suites with these marker features won't
+ * have derived suites created for them.
+ */
+ enum NoRecurse implements Feature<Void> {
+ SUBMAP,
+ DESCENDING;
- @Override NavigableMap<K, V> createSubMap(SortedMap<K, V> sortedMap, K firstExclusive,
- K lastExclusive) {
- NavigableMap<K, V> map = (NavigableMap<K, V>) sortedMap;
- if (from == Bound.NO_BOUND && to == Bound.INCLUSIVE) {
- return map.headMap(lastInclusive, true);
- } else if (from == Bound.EXCLUSIVE && to == Bound.NO_BOUND) {
- return map.tailMap(firstExclusive, false);
- } else if (from == Bound.EXCLUSIVE && to == Bound.EXCLUSIVE) {
- return map.subMap(firstExclusive, false, lastExclusive, false);
- } else if (from == Bound.EXCLUSIVE && to == Bound.INCLUSIVE) {
- return map.subMap(firstExclusive, false, lastInclusive, true);
- } else if (from == Bound.INCLUSIVE && to == Bound.INCLUSIVE) {
- return map.subMap(firstInclusive, true, lastInclusive, true);
- } else {
- return (NavigableMap<K, V>) super.createSubMap(map, firstExclusive, lastExclusive);
- }
+ @Override
+ public Set<Feature<? super Void>> getImpliedFeatures() {
+ return Collections.emptySet();
}
}
- @Override
- public NavigableMapTestSuiteBuilder<K, V> newBuilderUsing(
- TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) {
- return using(new NavigableMapSubmapTestMapGenerator<K, V>(delegate, to, from));
+ /**
+ * Two bounds (from and to) define how to build a subMap.
+ */
+ enum Bound {
+ INCLUSIVE,
+ EXCLUSIVE,
+ NO_BOUND;
+ }
+
+ /**
+ * Creates a suite whose map has some elements filtered out of view.
+ *
+ * <p>Because the map may be ascending or descending, this test must derive
+ * the relative order of these extreme values rather than relying on their
+ * regular sort ordering.
+ */
+ private TestSuite createSubmapSuite(final FeatureSpecificTestSuiteBuilder<?,
+ ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>>
+ parentBuilder, final Bound from, final Bound to) {
+ final TestMapGenerator<K, V> delegate
+ = (TestMapGenerator<K, V>) parentBuilder.getSubjectGenerator().getInnerGenerator();
+
+ List<Feature<?>> features = new ArrayList<Feature<?>>();
+ features.add(NoRecurse.SUBMAP);
+ features.addAll(parentBuilder.getFeatures());
+
+ NavigableMap<K, V> emptyMap = (NavigableMap<K, V>) delegate.create();
+ final Comparator<Entry<K, V>> entryComparator = Helpers.entryComparator(emptyMap.comparator());
+
+ // derive values for inclusive filtering from the input samples
+ SampleElements<Entry<K, V>> samples = delegate.samples();
+ @SuppressWarnings("unchecked") // no elements are inserted into the array
+ List<Entry<K, V>> samplesList = Arrays.asList(
+ samples.e0, samples.e1, samples.e2, samples.e3, samples.e4);
+ Collections.sort(samplesList, entryComparator);
+ final K firstInclusive = samplesList.get(0).getKey();
+ final K lastInclusive = samplesList.get(samplesList.size() - 1).getKey();
+
+ return NavigableMapTestSuiteBuilder
+ .using(new ForwardingTestMapGenerator<K, V>(delegate) {
+ @Override public Map<K, V> create(Object... entries) {
+ @SuppressWarnings("unchecked") // we dangerously assume K and V are both strings
+ List<Entry<K, V>> extremeValues = (List) getExtremeValues();
+ @SuppressWarnings("unchecked") // map generators must past entry objects
+ List<Entry<K, V>> normalValues = (List) Arrays.asList(entries);
+
+ // prepare extreme values to be filtered out of view
+ Collections.sort(extremeValues, entryComparator);
+ K firstExclusive = extremeValues.get(1).getKey();
+ K lastExclusive = extremeValues.get(2).getKey();
+ if (from == Bound.NO_BOUND) {
+ extremeValues.remove(0);
+ extremeValues.remove(0);
+ }
+ if (to == Bound.NO_BOUND) {
+ extremeValues.remove(extremeValues.size() - 1);
+ extremeValues.remove(extremeValues.size() - 1);
+ }
+
+ // the regular values should be visible after filtering
+ List<Entry<K, V>> allEntries = new ArrayList<Entry<K, V>>();
+ allEntries.addAll(extremeValues);
+ allEntries.addAll(normalValues);
+ NavigableMap<K, V> map = (NavigableMap<K, V>)
+ delegate.create((Object[])
+ allEntries.toArray(new Entry[allEntries.size()]));
+
+ // call the smallest subMap overload that filters out the extreme values
+ if (from == Bound.NO_BOUND && to == Bound.EXCLUSIVE) {
+ return map.headMap(lastExclusive);
+ } else if (from == Bound.NO_BOUND && to == Bound.INCLUSIVE) {
+ return map.headMap(lastInclusive, true);
+ } else if (from == Bound.EXCLUSIVE && to == Bound.NO_BOUND) {
+ return map.tailMap(firstExclusive, false);
+ } else if (from == Bound.EXCLUSIVE && to == Bound.EXCLUSIVE) {
+ return map.subMap(firstExclusive, false, lastExclusive, false);
+ } else if (from == Bound.EXCLUSIVE && to == Bound.INCLUSIVE) {
+ return map.subMap(firstExclusive, false, lastInclusive, true);
+ } else if (from == Bound.INCLUSIVE && to == Bound.NO_BOUND) {
+ return map.tailMap(firstInclusive);
+ } else if (from == Bound.INCLUSIVE && to == Bound.EXCLUSIVE) {
+ return map.subMap(firstInclusive, lastExclusive);
+ } else if (from == Bound.INCLUSIVE && to == Bound.INCLUSIVE) {
+ return map.subMap(firstInclusive, true, lastInclusive, true);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+ })
+ .named(parentBuilder.getName() + " subMap " + from + "-" + to)
+ .withFeatures(features)
+ .suppressing(parentBuilder.getSuppressedTests())
+ .createTestSuite();
+ }
+
+ /**
+ * Returns an array of four bogus elements that will always be too high or
+ * too low for the display. This includes two values for each extreme.
+ *
+ * <p>This method (dangerously) assume that the strings {@code "!! a"} and
+ * {@code "~~ z"} will work for this purpose, which may cause problems for
+ * navigable maps with non-string or unicode generators.
+ */
+ private List<Entry<String, String>> getExtremeValues() {
+ List<Entry<String, String>> result = new ArrayList<Entry<String, String>>();
+ result.add(Helpers.mapEntry("!! a", "below view"));
+ result.add(Helpers.mapEntry("!! b", "below view"));
+ result.add(Helpers.mapEntry("~~ y", "above view"));
+ result.add(Helpers.mapEntry("~~ z", "above view"));
+ return result;
}
/**
@@ -127,13 +220,6 @@ public class NavigableMapTestSuiteBuilder<K, V> extends SortedMapTestSuiteBuilde
NavigableMap<K, V> map = (NavigableMap<K, V>) delegate.create(entries);
return map.descendingMap();
}
-
- @Override
- public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
- insertionOrder = castOrCopyToList(delegate.order(insertionOrder));
- reverse(insertionOrder);
- return insertionOrder;
- }
})
.named(parentBuilder.getName() + " descending")
.withFeatures(features)
diff --git a/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java
index 7ef68bb..3e0f8b9 100644
--- a/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/NavigableSetTestSuiteBuilder.java
@@ -16,7 +16,7 @@
package com.google.common.collect.testing;
-import com.google.common.collect.testing.testers.NavigableSetNavigationTester;
+import com.google.common.collect.testing.testers.SetNavigationTester;
import java.util.List;
@@ -25,7 +25,7 @@ import java.util.List;
* a NavigableSet implementation.
*/
public final class NavigableSetTestSuiteBuilder<E>
- extends SortedSetTestSuiteBuilder<E> {
+ extends SetTestSuiteBuilder<E> {
public static <E> NavigableSetTestSuiteBuilder<E> using(
TestSetGenerator<E> generator) {
NavigableSetTestSuiteBuilder<E> builder =
@@ -37,7 +37,7 @@ public final class NavigableSetTestSuiteBuilder<E>
@Override protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers =
Helpers.copyToList(super.getTesters());
- testers.add(NavigableSetNavigationTester.class);
+ testers.add(SetNavigationTester.class);
return testers;
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java b/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java
index a5d9fbc..7d3a50b 100644
--- a/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/OneSizeGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionSize;
import java.util.ArrayList;
@@ -31,7 +30,6 @@ import java.util.List;
*
* @author George van den Driessche
*/
-@GwtCompatible
public final class OneSizeGenerator<T, E>
implements OneSizeTestContainerGenerator<T, E> {
private final TestContainerGenerator<T, E> generator;
diff --git a/guava-testlib/src/com/google/common/collect/testing/OneSizeTestContainerGenerator.java b/guava-testlib/src/com/google/common/collect/testing/OneSizeTestContainerGenerator.java
index c3350dc..5296be6 100644
--- a/guava-testlib/src/com/google/common/collect/testing/OneSizeTestContainerGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/OneSizeTestContainerGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionSize;
import java.util.Collection;
@@ -33,7 +32,6 @@ import java.util.Collection;
*
* @author George van den Driessche
*/
-@GwtCompatible
public interface OneSizeTestContainerGenerator<T, E>
extends TestSubjectGenerator<T>, TestContainerGenerator<T, E> {
TestContainerGenerator<T, E> getInnerGenerator();
diff --git a/guava-testlib/src/com/google/common/collect/testing/PerCollectionSizeTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/PerCollectionSizeTestSuiteBuilder.java
index ef3f384..8c219e8 100644
--- a/guava-testlib/src/com/google/common/collect/testing/PerCollectionSizeTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/PerCollectionSizeTestSuiteBuilder.java
@@ -115,7 +115,7 @@ public abstract class PerCollectionSizeTestSuiteBuilder<
return suite;
}
- protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<
+ List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<
?, ? extends OneSizeTestContainerGenerator<T, E>> parentBuilder) {
return new ArrayList<TestSuite>();
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/Platform.java b/guava-testlib/src/com/google/common/collect/testing/Platform.java
index 78d14af..e7ac3ea 100644
--- a/guava-testlib/src/com/google/common/collect/testing/Platform.java
+++ b/guava-testlib/src/com/google/common/collect/testing/Platform.java
@@ -16,7 +16,7 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
+import java.lang.reflect.Method;
/**
* Methods factored out so that they can be emulated differently in GWT.
@@ -25,7 +25,6 @@ import com.google.common.annotations.GwtCompatible;
*
* @author Hayward Chan
*/
-@GwtCompatible
class Platform {
/**
@@ -51,6 +50,31 @@ class Platform {
return String.format(template, args);
}
+ /**
+ * Wrapper around {@link System#arraycopy} so that it can be emulated
+ * correctly in GWT.
+ *
+ * <p>It is only intended for the case {@code src} and {@code dest} are
+ * different. It also doesn't validate the types and indices.
+ *
+ * <p>As of GWT 2.0, The built-in {@link System#arraycopy} doesn't work
+ * in general case. See
+ * http://code.google.com/p/google-web-toolkit/issues/detail?id=3621
+ * for more details.
+ */
+ static void unsafeArrayCopy(
+ Object[] src, int srcPos, Object[] dest, int destPos, int length) {
+ System.arraycopy(src, srcPos, dest, destPos, length);
+ }
+
+ static Method getMethod(Class<?> clazz, String name) {
+ try {
+ return clazz.getMethod(name);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
static String classGetSimpleName(Class<?> clazz) {
return clazz.getSimpleName();
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/SampleElements.java b/guava-testlib/src/com/google/common/collect/testing/SampleElements.java
index 30ddf65..2674dbb 100644
--- a/guava-testlib/src/com/google/common/collect/testing/SampleElements.java
+++ b/guava-testlib/src/com/google/common/collect/testing/SampleElements.java
@@ -16,10 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Arrays;
-import java.util.Iterator;
import java.util.Map;
/**
@@ -29,8 +25,7 @@ import java.util.Map;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
-public class SampleElements<E> implements Iterable<E> {
+public class SampleElements<E> {
// TODO: rename e3, e4 => missing1, missing2
public final E e0;
public final E e1;
@@ -46,11 +41,6 @@ public class SampleElements<E> implements Iterable<E> {
this.e4 = e4;
}
- @Override
- public Iterator<E> iterator() {
- return Arrays.asList(e0, e1, e2, e3, e4).iterator();
- }
-
public static class Strings extends SampleElements<String> {
public Strings() {
// elements aren't sorted, to better test SortedSet iteration ordering
@@ -65,13 +55,6 @@ public class SampleElements<E> implements Iterable<E> {
public static final String AFTER_LAST_2 = "zz";
}
- public static class Chars extends SampleElements<Character> {
- public Chars() {
- // elements aren't sorted, to better test SortedSet iteration ordering
- super('b', 'a', 'c', 'd', 'e');
- }
- }
-
public static class Enums extends SampleElements<AnEnum> {
public Enums() {
// elements aren't sorted, to better test SortedSet iteration ordering
@@ -79,13 +62,6 @@ public class SampleElements<E> implements Iterable<E> {
}
}
- public static class Ints extends SampleElements<Integer> {
- public Ints() {
- // elements aren't sorted, to better test SortedSet iteration ordering
- super(1, 0, 2, 3, 4);
- }
- }
-
public static <K, V> SampleElements<Map.Entry<K, V>> mapEntries(
SampleElements<K> keys, SampleElements<V> values) {
return new SampleElements<Map.Entry<K, V>>(
diff --git a/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
index 7437760..5440d72 100644
--- a/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/SetTestSuiteBuilder.java
@@ -16,24 +16,14 @@
package com.google.common.collect.testing;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.testers.CollectionSerializationEqualTester;
import com.google.common.collect.testing.testers.SetAddAllTester;
import com.google.common.collect.testing.testers.SetAddTester;
import com.google.common.collect.testing.testers.SetCreationTester;
import com.google.common.collect.testing.testers.SetEqualsTester;
import com.google.common.collect.testing.testers.SetHashCodeTester;
import com.google.common.collect.testing.testers.SetRemoveTester;
-import com.google.common.testing.SerializableTester;
-import junit.framework.TestSuite;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* Creates, based on your criteria, a JUnit test suite that exhaustively tests
@@ -51,8 +41,7 @@ public class SetTestSuiteBuilder<E>
@Override protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers
= Helpers.copyToList(super.getTesters());
-
- testers.add(CollectionSerializationEqualTester.class);
+
testers.add(SetAddAllTester.class);
testers.add(SetAddTester.class);
testers.add(SetCreationTester.class);
@@ -64,61 +53,4 @@ public class SetTestSuiteBuilder<E>
// covered by CollectionRemoveAllTester.
return testers;
}
-
- @Override
- protected
- List<TestSuite>
- createDerivedSuites(
- FeatureSpecificTestSuiteBuilder<
- ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
- List<TestSuite> derivedSuites = new ArrayList<TestSuite>(
- super.createDerivedSuites(parentBuilder));
-
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(SetTestSuiteBuilder
- .using(new ReserializedSetGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + " reserialized")
- .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
- return derivedSuites;
- }
-
- static class ReserializedSetGenerator<E> implements TestSetGenerator<E>{
- final OneSizeTestContainerGenerator<Collection<E>, E> gen;
-
- private ReserializedSetGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
- this.gen = gen;
- }
-
- @Override
- public SampleElements<E> samples() {
- return gen.samples();
- }
-
- @Override
- public Set<E> create(Object... elements) {
- return (Set<E>) SerializableTester.reserialize(gen.create(elements));
- }
-
- @Override
- public E[] createArray(int length) {
- return gen.createArray(length);
- }
-
- @Override
- public Iterable<E> order(List<E> insertionOrder) {
- return gen.order(insertionOrder);
- }
- }
-
- private static Set<Feature<?>> computeReserializedCollectionFeatures(
- Set<Feature<?>> features) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- derivedFeatures.addAll(features);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
- return derivedFeatures;
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java b/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java
index 10e5d1b..fdf6632 100644
--- a/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java
+++ b/guava-testlib/src/com/google/common/collect/testing/SortedMapInterfaceTest.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -40,7 +38,6 @@ import java.util.SortedMap;
* @author Jared Levy
*/
// TODO: Use this class to test classes besides ImmutableSortedMap.
-@GwtCompatible
public abstract class SortedMapInterfaceTest<K, V>
extends MapInterfaceTest<K, V> {
diff --git a/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java
deleted file mode 100644
index 11774ef..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/SortedMapTestSuiteBuilder.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.collect.testing.DerivedCollectionGenerators.Bound;
-import com.google.common.collect.testing.DerivedCollectionGenerators.SortedMapSubmapTestMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.testers.SortedMapNavigationTester;
-
-import junit.framework.TestSuite;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests
- * a SortedMap implementation.
- */
-public class SortedMapTestSuiteBuilder<K, V> extends MapTestSuiteBuilder<K, V> {
- public static <K, V> SortedMapTestSuiteBuilder<K, V> using(
- TestSortedMapGenerator<K, V> generator) {
- SortedMapTestSuiteBuilder<K, V> result = new SortedMapTestSuiteBuilder<K, V>();
- result.usingGenerator(generator);
- return result;
- }
-
- @Override protected List<Class<? extends AbstractTester>> getTesters() {
- List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
- testers.add(SortedMapNavigationTester.class);
- return testers;
- }
-
- @Override public TestSuite createTestSuite() {
- if (!getFeatures().contains(CollectionFeature.KNOWN_ORDER)) {
- List<Feature<?>> features = Helpers.copyToList(getFeatures());
- features.add(CollectionFeature.KNOWN_ORDER);
- withFeatures(features);
- }
- return super.createTestSuite();
- }
-
- @Override
- protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<?,
- ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>> parentBuilder) {
- List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
-
- if (!parentBuilder.getFeatures().contains(NoRecurse.SUBMAP)) {
- derivedSuites.add(createSubmapSuite(parentBuilder, Bound.NO_BOUND, Bound.EXCLUSIVE));
- derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.NO_BOUND));
- derivedSuites.add(createSubmapSuite(parentBuilder, Bound.INCLUSIVE, Bound.EXCLUSIVE));
- }
-
- return derivedSuites;
- }
-
- @Override protected SetTestSuiteBuilder<K> createDerivedKeySetSuite(
- TestSetGenerator<K> keySetGenerator) {
- /*
- * TODO(cpovirk): Consider requiring a SortedSet by default and requiring tests of a given
- * implementation to opt out if they wish to return Set. This would encourage us to return
- * keySets that implement SortedSet
- */
- return (keySetGenerator.create() instanceof SortedSet)
- ? SortedSetTestSuiteBuilder.using(keySetGenerator)
- : SetTestSuiteBuilder.using(keySetGenerator);
- }
-
- /**
- * To avoid infinite recursion, test suites with these marker features won't
- * have derived suites created for them.
- */
- enum NoRecurse implements Feature<Void> {
- SUBMAP,
- DESCENDING;
-
- @Override
- public Set<Feature<? super Void>> getImpliedFeatures() {
- return Collections.emptySet();
- }
- }
-
- /**
- * Creates a suite whose map has some elements filtered out of view.
- *
- * <p>Because the map may be ascending or descending, this test must derive
- * the relative order of these extreme values rather than relying on their
- * regular sort ordering.
- */
- final TestSuite createSubmapSuite(final FeatureSpecificTestSuiteBuilder<?,
- ? extends OneSizeTestContainerGenerator<Map<K, V>, Entry<K, V>>>
- parentBuilder, final Bound from, final Bound to) {
- final TestSortedMapGenerator<K, V> delegate
- = (TestSortedMapGenerator<K, V>) parentBuilder.getSubjectGenerator().getInnerGenerator();
-
- List<Feature<?>> features = new ArrayList<Feature<?>>();
- features.add(NoRecurse.SUBMAP);
- features.addAll(parentBuilder.getFeatures());
-
- return newBuilderUsing(delegate, to, from)
- .named(parentBuilder.getName() + " subMap " + from + "-" + to)
- .withFeatures(features)
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- /** Like using() but overrideable by NavigableMapTestSuiteBuilder. */
- SortedMapTestSuiteBuilder<K, V> newBuilderUsing(
- TestSortedMapGenerator<K, V> delegate, Bound to, Bound from) {
- return using(new SortedMapSubmapTestMapGenerator<K, V>(delegate, to, from));
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java
deleted file mode 100644
index 2f457a1..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/SortedSetTestSuiteBuilder.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.testers.SortedSetNavigationTester;
-
-import junit.framework.TestSuite;
-
-import java.util.List;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests
- * a SortedSet implementation.
- */
-public class SortedSetTestSuiteBuilder<E> extends SetTestSuiteBuilder<E> {
- public static <E> SortedSetTestSuiteBuilder<E> using(
- TestSetGenerator<E> generator) {
- SortedSetTestSuiteBuilder<E> builder =
- new SortedSetTestSuiteBuilder<E>();
- builder.usingGenerator(generator);
- return builder;
- }
-
- @Override protected List<Class<? extends AbstractTester>> getTesters() {
- List<Class<? extends AbstractTester>> testers =
- Helpers.copyToList(super.getTesters());
- testers.add(SortedSetNavigationTester.class);
- return testers;
- }
-
- @Override public TestSuite createTestSuite() {
- if (!getFeatures().contains(CollectionFeature.KNOWN_ORDER)) {
- List<Feature<?>> features = Helpers.copyToList(getFeatures());
- features.add(CollectionFeature.KNOWN_ORDER);
- withFeatures(features);
- }
- return super.createTestSuite();
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestCharacterListGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestCharacterListGenerator.java
deleted file mode 100644
index 9f9befe..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/TestCharacterListGenerator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.SampleElements.Chars;
-
-import java.util.List;
-
-/**
- * Generates {@code List<Character>} instances for test suites.
- *
- * <p>This class is GWT compatible.
- *
- * @author Kevin Bourrillion
- * @author Louis Wasserman
- */
-@GwtCompatible
-public abstract class TestCharacterListGenerator
- implements TestListGenerator<Character> {
- @Override
- public SampleElements<Character> samples() {
- return new Chars();
- }
-
- @Override
- public List<Character> create(Object... elements) {
- Character[] array = new Character[elements.length];
- int i = 0;
- for (Object e : elements) {
- array[i++] = (Character) e;
- }
- return create(array);
- }
-
- /**
- * Creates a new collection containing the given elements; implement this
- * method instead of {@link #create(Object...)}.
- */
- protected abstract List<Character> create(Character[] elements);
-
- @Override
- public Character[] createArray(int length) {
- return new Character[length];
- }
-
- /** Returns the original element list, unchanged. */
- @Override
- public List<Character> order(List<Character> insertionOrder) {
- return insertionOrder;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestCollectionGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestCollectionGenerator.java
index f50b695..92367a2 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestCollectionGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestCollectionGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collection;
/**
@@ -27,7 +25,6 @@ import java.util.Collection;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public interface TestCollectionGenerator<E>
extends TestContainerGenerator<Collection<E>, E> {
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestCollidingSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestCollidingSetGenerator.java
index f053f4e..ed26b65 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestCollidingSetGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestCollidingSetGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Colliders;
import java.util.List;
@@ -28,7 +27,6 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public abstract class TestCollidingSetGenerator
implements TestSetGenerator<Object> {
@Override
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestContainerGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestContainerGenerator.java
index 00d167c..1511040 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestContainerGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestContainerGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -32,7 +30,6 @@ import java.util.Map;
*
* @author George van den Driessche
*/
-@GwtCompatible
public interface TestContainerGenerator<T, E> {
/**
* Returns the sample elements that this generate populates its container
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestEnumMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestEnumMapGenerator.java
index 579c522..42bc48a 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestEnumMapGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestEnumMapGenerator.java
@@ -16,10 +16,6 @@
package com.google.common.collect.testing;
-import static com.google.common.collect.testing.Helpers.orderEntriesByKey;
-
-import com.google.common.annotations.GwtCompatible;
-
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -31,7 +27,6 @@ import java.util.Map.Entry;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public abstract class TestEnumMapGenerator
implements TestMapGenerator<AnEnum, String> {
@@ -78,10 +73,10 @@ public abstract class TestEnumMapGenerator
return new String[length];
}
- /** Returns the elements sorted in natural order. */
+ /** Returns the original element list, unchanged. */
@Override
public Iterable<Entry<AnEnum, String>> order(
List<Entry<AnEnum, String>> insertionOrder) {
- return orderEntriesByKey(insertionOrder);
+ return insertionOrder;
}
-}
+} \ No newline at end of file
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestEnumSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestEnumSetGenerator.java
index f4b9c80..fd7155c 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestEnumSetGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestEnumSetGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Enums;
import java.util.Collections;
@@ -30,7 +29,6 @@ import java.util.Set;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public abstract class TestEnumSetGenerator implements TestSetGenerator<AnEnum> {
@Override
public SampleElements<AnEnum> samples() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestIntegerSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestIntegerSetGenerator.java
deleted file mode 100644
index 7e11e3a..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/TestIntegerSetGenerator.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.SampleElements.Ints;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Create integer sets for collection tests.
- *
- * <p>This class is GWT compatible.
- *
- * @author Gregory Kick
- */
-@GwtCompatible
-public abstract class TestIntegerSetGenerator implements TestSetGenerator<Integer> {
- @Override public SampleElements<Integer> samples() {
- return new Ints();
- }
-
- @Override public Set<Integer> create(Object... elements) {
- Integer[] array = new Integer[elements.length];
- int i = 0;
- for (Object e : elements) {
- array[i++] = (Integer) e;
- }
- return create(array);
- }
-
- protected abstract Set<Integer> create(Integer[] elements);
-
- @Override public Integer[] createArray(int length) {
- return new Integer[length];
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>By default, returns the supplied elements in their given order; however,
- * generators for containers with a known order other than insertion order
- * must override this method.
- *
- * <p>Note: This default implementation is overkill (but valid) for an
- * unordered container. An equally valid implementation for an unordered
- * container is to throw an exception. The chosen implementation, however, has
- * the advantage of working for insertion-ordered containers, as well.
- */
- @Override public List<Integer> order(List<Integer> insertionOrder) {
- return insertionOrder;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestIntegerSortedSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestIntegerSortedSetGenerator.java
deleted file mode 100644
index 8e577e8..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/TestIntegerSortedSetGenerator.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.SortedSet;
-
-/**
- * Create integer sets for testing collections that are sorted by natural
- * ordering.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Jared Levy
- */
-@GwtCompatible
-public abstract class TestIntegerSortedSetGenerator
- extends TestIntegerSetGenerator {
- @Override protected abstract SortedSet<Integer> create(Integer[] elements);
-
- /** Sorts the elements by their natural ordering. */
- @Override public List<Integer> order(List<Integer> insertionOrder) {
- Collections.sort(insertionOrder);
- return insertionOrder;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestIteratorGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestIteratorGenerator.java
index 8304364..1c718c5 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestIteratorGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestIteratorGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Iterator;
/**
@@ -29,7 +27,6 @@ import java.util.Iterator;
*
* @author George van den Driessche
*/
-@GwtCompatible
public interface TestIteratorGenerator<E> {
Iterator<E> get();
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestListGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestListGenerator.java
index 2027ce4..11e2604 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestListGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestListGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.List;
/**
@@ -27,7 +25,6 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public interface TestListGenerator<E> extends TestCollectionGenerator<E> {
@Override
List<E> create(Object... elements);
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestMapEntrySetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestMapEntrySetGenerator.java
index c57f7ac..e1a9611 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestMapEntrySetGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestMapEntrySetGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -29,7 +27,6 @@ import java.util.Set;
*
* @author Jesse Wilson
*/
-@GwtCompatible
public abstract class TestMapEntrySetGenerator<K, V>
implements TestSetGenerator<Map.Entry<K, V>> {
private final SampleElements<K> keys;
@@ -49,7 +46,7 @@ public abstract class TestMapEntrySetGenerator<K, V>
@Override
public Set<Map.Entry<K, V>> create(Object... elements) {
Map.Entry<K, V>[] entries = createArray(elements.length);
- System.arraycopy(elements, 0, entries, 0, elements.length);
+ Platform.unsafeArrayCopy(elements, 0, entries, 0, elements.length);
return createFromEntries(entries);
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestMapGenerator.java
index 2d18e06..e7add5a 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestMapGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestMapGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Map;
/**
@@ -27,7 +25,6 @@ import java.util.Map;
*
* @author George van den Driessche
*/
-@GwtCompatible
public interface TestMapGenerator<K, V>
extends TestContainerGenerator<Map<K, V>, Map.Entry<K, V>> {
K[] createKeyArray(int length);
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestQueueGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestQueueGenerator.java
index 5bb3188..f8d8dc6 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestQueueGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestQueueGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Queue;
/**
@@ -27,7 +25,6 @@ import java.util.Queue;
*
* @author Jared Levy
*/
-@GwtCompatible
public interface TestQueueGenerator<E> extends TestCollectionGenerator<E> {
@Override
Queue<E> create(Object... elements);
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestSetGenerator.java
index 2586f70..106112b 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestSetGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestSetGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Set;
/**
@@ -27,7 +25,6 @@ import java.util.Set;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public interface TestSetGenerator<E> extends TestCollectionGenerator<E> {
@Override
Set<E> create(Object... elements);
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestSortedMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestSortedMapGenerator.java
deleted file mode 100644
index 9a9ab73..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/TestSortedMapGenerator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Map;
-import java.util.SortedMap;
-
-/**
- * Creates sorted maps, containing sample elements, to be tested.
- *
- * <p>This class is GWT compatible.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public interface TestSortedMapGenerator<K, V> extends TestMapGenerator<K, V> {
- @Override
- SortedMap<K, V> create(Object... elements);
-
- /**
- * Returns an entry with a key less than the keys of the {@link #samples()}
- * and less than the key of {@link #belowSamplesGreater()}.
- */
- Map.Entry<K, V> belowSamplesLesser();
-
- /**
- * Returns an entry with a key less than the keys of the {@link #samples()}
- * but greater than the key of {@link #belowSamplesLesser()}.
- */
- Map.Entry<K, V> belowSamplesGreater();
-
- /**
- * Returns an entry with a key greater than the keys of the {@link #samples()}
- * but less than the key of {@link #aboveSamplesGreater()}.
- */
- Map.Entry<K, V> aboveSamplesLesser();
-
- /**
- * Returns an entry with a key greater than the keys of the {@link #samples()}
- * and greater than the key of {@link #aboveSamplesLesser()}.
- */
- Map.Entry<K, V> aboveSamplesGreater();
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringCollectionGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringCollectionGenerator.java
index fa4b8f6..2248853 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringCollectionGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestStringCollectionGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Strings;
import java.util.Collection;
@@ -29,7 +28,6 @@ import java.util.List;
*
* @author Jared Levy
*/
-@GwtCompatible
public abstract class TestStringCollectionGenerator
implements TestCollectionGenerator<String> {
@Override
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringListGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringListGenerator.java
index 842d653..ea024ad 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringListGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestStringListGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Strings;
import java.util.List;
@@ -28,7 +27,6 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public abstract class TestStringListGenerator
implements TestListGenerator<String> {
@Override
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringMapGenerator.java
index 9505c8e..2f9b51b 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringMapGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestStringMapGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -32,7 +30,6 @@ import java.util.Map.Entry;
* @author Jared Levy
* @author George van den Driessche
*/
-@GwtCompatible
public abstract class TestStringMapGenerator
implements TestMapGenerator<String, String> {
@@ -48,7 +45,7 @@ public abstract class TestStringMapGenerator
}
@Override
- public Map<String, String> create(Object... entries) {
+ public final Map<String, String> create(Object... entries) {
@SuppressWarnings("unchecked")
Entry<String, String>[] array = new Entry[entries.length];
int i = 0;
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringQueueGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringQueueGenerator.java
index d2ba7ce..d116044 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringQueueGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestStringQueueGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Strings;
import java.util.List;
@@ -29,7 +28,6 @@ import java.util.Queue;
*
* @author Jared Levy
*/
-@GwtCompatible
public abstract class TestStringQueueGenerator
implements TestQueueGenerator<String>
{
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringSetGenerator.java
index 339a79e..712b533 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringSetGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestStringSetGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Strings;
import java.util.List;
@@ -29,7 +28,6 @@ import java.util.Set;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public abstract class TestStringSetGenerator implements TestSetGenerator<String>
{
@Override
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringSortedMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringSortedMapGenerator.java
deleted file mode 100644
index 6c357e6..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringSortedMapGenerator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.Helpers.orderEntriesByKey;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.SortedMap;
-
-/**
- * Implementation helper for {@link TestMapGenerator} for use with sorted maps of strings.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- */
-@GwtCompatible
-public abstract class TestStringSortedMapGenerator extends TestStringMapGenerator
- implements TestSortedMapGenerator<String, String> {
- @Override
- public Entry<String, String> belowSamplesLesser() {
- return Helpers.mapEntry("!! a", "below view");
- }
-
- @Override
- public Entry<String, String> belowSamplesGreater() {
- return Helpers.mapEntry("!! b", "below view");
- }
-
- @Override
- public Entry<String, String> aboveSamplesLesser() {
- return Helpers.mapEntry("~~ a", "above view");
- }
-
- @Override
- public Entry<String, String> aboveSamplesGreater() {
- return Helpers.mapEntry("~~ b", "above view");
- }
-
- @Override
- public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) {
- return orderEntriesByKey(insertionOrder);
- }
-
- @Override
- protected abstract SortedMap<String, String> create(Entry<String, String>[] entries);
-
- @Override
- public SortedMap<String, String> create(Object... entries) {
- return (SortedMap<String, String>) super.create(entries);
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestStringSortedSetGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestStringSortedSetGenerator.java
index c2e7cc0..833ffe9 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestStringSortedSetGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestStringSortedSetGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
@@ -30,7 +28,6 @@ import java.util.SortedSet;
*
* @author Jared Levy
*/
-@GwtCompatible
public abstract class TestStringSortedSetGenerator
extends TestStringSetGenerator {
@Override protected abstract SortedSet<String> create(String[] elements);
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestSubjectGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestSubjectGenerator.java
index 3b968e5..fa8970d 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestSubjectGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestSubjectGenerator.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
/**
* To be implemented by test generators that can produce test subjects without
* requiring any parameters.
@@ -28,7 +26,6 @@ import com.google.common.annotations.GwtCompatible;
*
* @author George van den Driessche
*/
-@GwtCompatible
public interface TestSubjectGenerator<T> {
T createTestSubject();
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestUnhashableCollectionGenerator.java b/guava-testlib/src/com/google/common/collect/testing/TestUnhashableCollectionGenerator.java
index 92020c9..3010b47 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestUnhashableCollectionGenerator.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestUnhashableCollectionGenerator.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.SampleElements.Unhashables;
import java.util.Collection;
@@ -29,7 +28,6 @@ import java.util.List;
*
* @author Regina O'Dell
*/
-@GwtCompatible
public abstract class
TestUnhashableCollectionGenerator<T extends Collection<UnhashableObject>>
implements TestCollectionGenerator<UnhashableObject> {
@@ -64,4 +62,4 @@ public abstract class
List<UnhashableObject> insertionOrder) {
return insertionOrder;
}
-}
+} \ No newline at end of file
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestsForListsInJavaUtil.java b/guava-testlib/src/com/google/common/collect/testing/TestsForListsInJavaUtil.java
index 8191d70..c9961f3 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestsForListsInJavaUtil.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestsForListsInJavaUtil.java
@@ -102,7 +102,7 @@ public class TestsForListsInJavaUtil {
})
.named("emptyList")
.withFeatures(
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.NONE,
CollectionSize.ZERO)
.suppressing(suppressForEmptyList())
.createTestSuite();
@@ -117,7 +117,7 @@ public class TestsForListsInJavaUtil {
})
.named("singletonList")
.withFeatures(
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.NONE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ONE)
.suppressing(suppressForSingletonList())
@@ -134,7 +134,6 @@ public class TestsForListsInJavaUtil {
.named("Arrays.asList")
.withFeatures(
ListFeature.SUPPORTS_SET,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ANY)
.suppressing(suppressForArraysAsList())
@@ -151,9 +150,7 @@ public class TestsForListsInJavaUtil {
.named("ArrayList")
.withFeatures(
ListFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionSize.ANY)
.suppressing(suppressForArrayList())
.createTestSuite();
@@ -169,9 +166,7 @@ public class TestsForListsInJavaUtil {
.named("LinkedList")
.withFeatures(
ListFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionSize.ANY)
.suppressing(suppressForLinkedList())
.createTestSuite();
@@ -188,7 +183,6 @@ public class TestsForListsInJavaUtil {
.named("CopyOnWriteArrayList")
.withFeatures(
ListFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ANY)
.suppressing(suppressForCopyOnWriteArrayList())
@@ -206,7 +200,7 @@ public class TestsForListsInJavaUtil {
})
.named("unmodifiableList/ArrayList")
.withFeatures(
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.NONE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ANY)
.suppressing(suppressForUnmodifiableList())
@@ -225,7 +219,6 @@ public class TestsForListsInJavaUtil {
.named("checkedList/ArrayList")
.withFeatures(
ListFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.RESTRICTS_ELEMENTS,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ANY)
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestsForMapsInJavaUtil.java b/guava-testlib/src/com/google/common/collect/testing/TestsForMapsInJavaUtil.java
index fa996b3..6b71f22 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestsForMapsInJavaUtil.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestsForMapsInJavaUtil.java
@@ -23,7 +23,6 @@ import com.google.common.collect.testing.features.MapFeature;
import junit.framework.Test;
import junit.framework.TestSuite;
-import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
@@ -31,12 +30,11 @@ import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListMap;
/**
* Generates a test suite covering the {@link Map} implementations in the
@@ -46,7 +44,6 @@ import java.util.concurrent.ConcurrentSkipListMap;
* @author Kevin Bourrillion
*/
public class TestsForMapsInJavaUtil {
-
public static Test suite() {
return new TestsForMapsInJavaUtil().allTests();
}
@@ -57,12 +54,9 @@ public class TestsForMapsInJavaUtil {
suite.addTest(testsForSingletonMap());
suite.addTest(testsForHashMap());
suite.addTest(testsForLinkedHashMap());
- suite.addTest(testsForTreeMapNatural());
- suite.addTest(testsForTreeMapWithComparator());
+ suite.addTest(testsForTreeMap());
suite.addTest(testsForEnumMap());
suite.addTest(testsForConcurrentHashMap());
- suite.addTest(testsForConcurrentSkipListMapNatural());
- suite.addTest(testsForConcurrentSkipListMapWithComparator());
return suite;
}
@@ -78,10 +72,7 @@ public class TestsForMapsInJavaUtil {
protected Collection<Method> suppressForLinkedHashMap() {
return Collections.emptySet();
}
- protected Collection<Method> suppressForTreeMapNatural() {
- return Collections.emptySet();
- }
- protected Collection<Method> suppressForTreeMapWithComparator() {
+ protected Collection<Method> suppressForTreeMap() {
return Collections.emptySet();
}
protected Collection<Method> suppressForEnumMap() {
@@ -90,9 +81,6 @@ public class TestsForMapsInJavaUtil {
protected Collection<Method> suppressForConcurrentHashMap() {
return Collections.emptySet();
}
- protected Collection<Method> suppressForConcurrentSkipListMap() {
- return Collections.emptySet();
- }
public Test testsForEmptyMap() {
return MapTestSuiteBuilder
@@ -104,7 +92,7 @@ public class TestsForMapsInJavaUtil {
})
.named("emptyMap")
.withFeatures(
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.NONE,
CollectionSize.ZERO)
.suppressing(suppressForEmptyMap())
.createTestSuite();
@@ -123,7 +111,6 @@ public class TestsForMapsInJavaUtil {
.withFeatures(
MapFeature.ALLOWS_NULL_KEYS,
MapFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.SERIALIZABLE,
CollectionSize.ONE)
.suppressing(suppressForSingletonMap())
.createTestSuite();
@@ -136,14 +123,20 @@ public class TestsForMapsInJavaUtil {
Entry<String, String>[] entries) {
return toHashMap(entries);
}
+ @Override public Iterable<Entry<String, String>> order(
+ List<Entry<String, String>> insertionOrder) {
+ /*
+ * For convenience, make this test double as a test that no tester
+ * calls order() on a container without the KNOWN_ORDER feature.
+ */
+ throw new UnsupportedOperationException();
+ }
})
.named("HashMap")
.withFeatures(
MapFeature.GENERAL_PURPOSE,
MapFeature.ALLOWS_NULL_KEYS,
MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.SERIALIZABLE,
CollectionSize.ANY)
.suppressing(suppressForHashMap())
.createTestSuite();
@@ -162,57 +155,29 @@ public class TestsForMapsInJavaUtil {
MapFeature.GENERAL_PURPOSE,
MapFeature.ALLOWS_NULL_KEYS,
MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
CollectionSize.ANY)
.suppressing(suppressForLinkedHashMap())
.createTestSuite();
}
- public Test testsForTreeMapNatural() {
+ public Test testsForTreeMap() {
return NavigableMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- /*
- * TODO(cpovirk): it would be nice to create an input Map and use
- * the copy constructor here and in the other tests
- */
- return populate(new TreeMap<String, String>(), entries);
- }
- })
- .named("TreeMap, natural")
- .withFeatures(
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .suppressing(suppressForTreeMapNatural())
- .createTestSuite();
- }
-
- public Test testsForTreeMapWithComparator() {
- return NavigableMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
+ .using(new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
Entry<String, String>[] entries) {
return populate(new TreeMap<String, String>(
arbitraryNullFriendlyComparator()), entries);
}
})
- .named("TreeMap, with comparator")
+ .named("TreeMap")
.withFeatures(
MapFeature.GENERAL_PURPOSE,
MapFeature.ALLOWS_NULL_KEYS,
MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
CollectionSize.ANY)
- .suppressing(suppressForTreeMapWithComparator())
+ .suppressing(suppressForTreeMap())
.createTestSuite();
}
@@ -231,7 +196,6 @@ public class TestsForMapsInJavaUtil {
MapFeature.ALLOWS_NULL_VALUES,
MapFeature.RESTRICTS_KEYS,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
CollectionSize.ANY)
.suppressing(suppressForEnumMap())
.createTestSuite();
@@ -248,49 +212,11 @@ public class TestsForMapsInJavaUtil {
.named("ConcurrentHashMap")
.withFeatures(
MapFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionSize.ANY)
.suppressing(suppressForConcurrentHashMap())
.createTestSuite();
}
- public Test testsForConcurrentSkipListMapNatural() {
- return NavigableMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- return populate(new ConcurrentSkipListMap<String, String>(), entries);
- }
- })
- .named("ConcurrentSkipListMap, natural")
- .withFeatures(
- MapFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .suppressing(suppressForConcurrentSkipListMap())
- .createTestSuite();
- }
-
- public Test testsForConcurrentSkipListMapWithComparator() {
- return NavigableMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- return populate(new ConcurrentSkipListMap<String, String>(
- arbitraryNullFriendlyComparator()), entries);
- }
- })
- .named("ConcurrentSkipListMap, with comparator")
- .withFeatures(
- MapFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .suppressing(suppressForConcurrentSkipListMap())
- .createTestSuite();
- }
-
// TODO: IdentityHashMap, AbstractMap
private static Map<String, String> toHashMap(
@@ -300,8 +226,8 @@ public class TestsForMapsInJavaUtil {
// TODO: call conversion constructors or factory methods instead of using
// populate() on an empty map
- private static <T, M extends Map<T, String>> M populate(
- M map, Entry<T, String>[] entries) {
+ private static <T> Map<T, String> populate(
+ Map<T, String> map, Entry<T, String>[] entries) {
for (Entry<T, String> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
@@ -309,13 +235,11 @@ public class TestsForMapsInJavaUtil {
}
static <T> Comparator<T> arbitraryNullFriendlyComparator() {
- return new NullFriendlyComparator<T>();
- }
-
- private static final class NullFriendlyComparator<T> implements Comparator<T>, Serializable {
- @Override
- public int compare(T left, T right) {
- return String.valueOf(left).compareTo(String.valueOf(right));
- }
+ return new Comparator<T>() {
+ @Override
+ public int compare(T left, T right) {
+ return String.valueOf(left).compareTo(String.valueOf(right));
+ }
+ };
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/TestsForSetsInJavaUtil.java b/guava-testlib/src/com/google/common/collect/testing/TestsForSetsInJavaUtil.java
index b6484ac..4b4b924 100644
--- a/guava-testlib/src/com/google/common/collect/testing/TestsForSetsInJavaUtil.java
+++ b/guava-testlib/src/com/google/common/collect/testing/TestsForSetsInJavaUtil.java
@@ -19,12 +19,10 @@ package com.google.common.collect.testing;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.SetFeature;
-import com.google.common.collect.testing.testers.CollectionIteratorTester;
import junit.framework.Test;
import junit.framework.TestSuite;
-import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.AbstractSet;
import java.util.Collection;
@@ -37,7 +35,6 @@ import java.util.LinkedHashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
-import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArraySet;
/**
@@ -66,8 +63,6 @@ public class TestsForSetsInJavaUtil {
suite.addTest(testsForCheckedSet());
suite.addTest(testsForAbstractSet());
suite.addTest(testsForBadlyCollidingHashSet());
- suite.addTest(testsForConcurrentSkipListSetNatural());
- suite.addTest(testsForConcurrentSkipListSetWithComparator());
return suite;
}
@@ -94,8 +89,7 @@ public class TestsForSetsInJavaUtil {
return Collections.emptySet();
}
protected Collection<Method> suppressForCopyOnWriteArraySet() {
- return Collections.singleton(CollectionIteratorTester
- .getIteratorKnownOrderRemoveSupportedMethod());
+ return Collections.emptySet();
}
protected Collection<Method> suppressForUnmodifiableSet() {
return Collections.emptySet();
@@ -106,12 +100,6 @@ public class TestsForSetsInJavaUtil {
protected Collection<Method> suppressForAbstractSet() {
return Collections.emptySet();
}
- protected Collection<Method> suppressForConcurrentSkipListSetNatural() {
- return Collections.emptySet();
- }
- protected Collection<Method> suppressForConcurrentSkipListSetWithComparator() {
- return Collections.emptySet();
- }
public Test testsForEmptySet() {
return SetTestSuiteBuilder
@@ -122,7 +110,7 @@ public class TestsForSetsInJavaUtil {
})
.named("emptySet")
.withFeatures(
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.NONE,
CollectionSize.ZERO)
.suppressing(suppressForEmptySet())
.createTestSuite();
@@ -137,7 +125,7 @@ public class TestsForSetsInJavaUtil {
})
.named("singleton")
.withFeatures(
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.NONE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ONE)
.suppressing(suppressForSingletonSet())
@@ -154,9 +142,7 @@ public class TestsForSetsInJavaUtil {
.named("HashSet")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionSize.ANY)
.suppressing(suppressForHashSet())
.createTestSuite();
@@ -172,10 +158,8 @@ public class TestsForSetsInJavaUtil {
.named("LinkedHashSet")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionSize.ANY)
.suppressing(suppressForLinkedHashSet())
.createTestSuite();
@@ -193,7 +177,6 @@ public class TestsForSetsInJavaUtil {
.named("EnumSet")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.KNOWN_ORDER,
CollectionFeature.RESTRICTS_ELEMENTS,
CollectionSize.ANY)
@@ -211,9 +194,7 @@ public class TestsForSetsInJavaUtil {
.named("TreeSet, natural")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionSize.ANY)
.suppressing(suppressForTreeSetNatural())
.createTestSuite();
@@ -232,10 +213,8 @@ public class TestsForSetsInJavaUtil {
.named("TreeSet, with comparator")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
CollectionSize.ANY)
.suppressing(suppressForTreeSetWithComparator())
.createTestSuite();
@@ -252,7 +231,6 @@ public class TestsForSetsInJavaUtil {
.named("CopyOnWriteArraySet")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER,
CollectionSize.ANY)
@@ -272,7 +250,6 @@ public class TestsForSetsInJavaUtil {
.named("unmodifiableSet/HashSet")
.withFeatures(
CollectionFeature.NONE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionSize.ANY)
.suppressing(suppressForUnmodifiableSet())
@@ -291,7 +268,6 @@ public class TestsForSetsInJavaUtil {
.named("checkedSet/HashSet")
.withFeatures(
SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.RESTRICTS_ELEMENTS,
CollectionSize.ANY)
@@ -341,43 +317,6 @@ public class TestsForSetsInJavaUtil {
.createTestSuite();
}
- public Test testsForConcurrentSkipListSetNatural() {
- return SetTestSuiteBuilder
- .using(new TestStringSortedSetGenerator() {
- @Override public SortedSet<String> create(String[] elements) {
- return new ConcurrentSkipListSet<String>(MinimalCollection.of(elements));
- }
- })
- .named("ConcurrentSkipListSet, natural")
- .withFeatures(
- SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .suppressing(suppressForConcurrentSkipListSetNatural())
- .createTestSuite();
- }
-
- public Test testsForConcurrentSkipListSetWithComparator() {
- return SetTestSuiteBuilder
- .using(new TestStringSortedSetGenerator() {
- @Override public SortedSet<String> create(String[] elements) {
- SortedSet<String> set
- = new ConcurrentSkipListSet<String>(arbitraryNullFriendlyComparator());
- Collections.addAll(set, elements);
- return set;
- }
- })
- .named("ConcurrentSkipListSet, with comparator")
- .withFeatures(
- SetFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .suppressing(suppressForConcurrentSkipListSetWithComparator())
- .createTestSuite();
- }
-
private static String[] dedupe(String[] elements) {
Set<String> tmp = new LinkedHashSet<String>();
Collections.addAll(tmp, elements);
@@ -385,14 +324,11 @@ public class TestsForSetsInJavaUtil {
}
static <T> Comparator<T> arbitraryNullFriendlyComparator() {
- return new NullFriendlyComparator<T>();
- }
-
- private static final class NullFriendlyComparator<T>
- implements Comparator<T>, Serializable {
- @Override
- public int compare(T left, T right) {
- return String.valueOf(left).compareTo(String.valueOf(right));
- }
+ return new Comparator<T>() {
+ @Override
+ public int compare(T left, T right) {
+ return String.valueOf(left).compareTo(String.valueOf(right));
+ }
+ };
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/UnhashableObject.java b/guava-testlib/src/com/google/common/collect/testing/UnhashableObject.java
index 014995d..d038cfb 100644
--- a/guava-testlib/src/com/google/common/collect/testing/UnhashableObject.java
+++ b/guava-testlib/src/com/google/common/collect/testing/UnhashableObject.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
/**
* An unhashable object to be used in testing as values in our collections.
*
@@ -25,7 +23,6 @@ import com.google.common.annotations.GwtCompatible;
*
* @author Regina O'Dell
*/
-@GwtCompatible
public class UnhashableObject implements Comparable<UnhashableObject> {
private final int value;
diff --git a/guava-testlib/src/com/google/common/collect/testing/WrongType.java b/guava-testlib/src/com/google/common/collect/testing/WrongType.java
index d49e942..0fecaba 100644
--- a/guava-testlib/src/com/google/common/collect/testing/WrongType.java
+++ b/guava-testlib/src/com/google/common/collect/testing/WrongType.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing;
-import com.google.common.annotations.GwtCompatible;
-
/**
* A type which will never be used as the element type of any collection in our
* tests, and so can be used to test how a Collection behaves when given input
@@ -25,7 +23,6 @@ import com.google.common.annotations.GwtCompatible;
*
* <p>This class is GWT compatible.
*/
-@GwtCompatible
public enum WrongType {
VALUE
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/CollectionFeature.java b/guava-testlib/src/com/google/common/collect/testing/features/CollectionFeature.java
index 831c99f..4f14c3c 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/CollectionFeature.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/CollectionFeature.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.lang.annotation.Inherited;
@@ -36,8 +35,7 @@ import java.util.SortedSet;
*/
// Enum values use constructors with generic varargs.
@SuppressWarnings("unchecked")
-@GwtCompatible
-public enum CollectionFeature implements Feature<Collection> {
+public enum CollectionFeature implements Feature<Collection> {
/**
* The collection must not throw {@code NullPointerException} on calls
* such as {@code contains(null)} or {@code remove(null)}, but instead
@@ -63,7 +61,7 @@ public enum CollectionFeature implements Feature<Collection> {
* Indicates that a collection has a well-defined ordering of its elements.
* The ordering may depend on the element values, such as a {@link SortedSet},
* or on the insertion ordering, such as a {@link LinkedHashSet}. All list
- * tests and sorted-collection tests automatically specify this feature.
+ * tests automatically specify this feature.
*/
KNOWN_ORDER,
@@ -84,7 +82,10 @@ public enum CollectionFeature implements Feature<Collection> {
SUPPORTS_ADD,
SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ SUPPORTS_ADD_ALL,
+ SUPPORTS_REMOVE_ALL,
+ SUPPORTS_RETAIN_ALL,
+ SUPPORTS_CLEAR,
/**
* Features supported by general-purpose collections -
@@ -93,13 +94,18 @@ public enum CollectionFeature implements Feature<Collection> {
*/
GENERAL_PURPOSE(
SUPPORTS_ADD,
- SUPPORTS_REMOVE),
+ SUPPORTS_REMOVE,
+ SUPPORTS_ADD_ALL,
+ SUPPORTS_REMOVE_ALL,
+ SUPPORTS_RETAIN_ALL,
+ SUPPORTS_CLEAR),
/** Features supported by collections where only removal is allowed. */
REMOVE_OPERATIONS(
- SUPPORTS_REMOVE),
-
- SERIALIZABLE, SERIALIZABLE_INCLUDING_VIEWS(SERIALIZABLE),
+ SUPPORTS_REMOVE,
+ SUPPORTS_REMOVE_ALL,
+ SUPPORTS_RETAIN_ALL,
+ SUPPORTS_CLEAR),
/**
* For documenting collections that support no optional features, such as
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java b/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java
index b919850..f986d35 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/CollectionSize.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.lang.annotation.Inherited;
@@ -48,7 +47,6 @@ import java.util.Set;
*/
// Enum values use constructors with generic varargs.
@SuppressWarnings("unchecked")
-@GwtCompatible
public enum CollectionSize implements Feature<Collection>,
Comparable<CollectionSize> {
/** Test an empty collection. */
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/ConflictingRequirementsException.java b/guava-testlib/src/com/google/common/collect/testing/features/ConflictingRequirementsException.java
index ace5afc..e70ed0d 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/ConflictingRequirementsException.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/ConflictingRequirementsException.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Set;
/**
@@ -28,7 +26,6 @@ import java.util.Set;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class ConflictingRequirementsException extends Exception {
private Set<Feature<?>> conflicts;
private Object source;
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/Feature.java b/guava-testlib/src/com/google/common/collect/testing/features/Feature.java
index db7c9ee..b185803 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/Feature.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/Feature.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Set;
/**
@@ -28,7 +26,6 @@ import java.util.Set;
* @param <T> The interface whose features are to be enumerated.
* @author George van den Driessche
*/
-@GwtCompatible
public interface Feature<T> {
/** Returns the set of features that are implied by this feature. */
Set<Feature<? super T>> getImpliedFeatures();
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java b/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java
index 0351b16..3edffa3 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/FeatureUtil.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.lang.annotation.Annotation;
@@ -36,7 +35,6 @@ import java.util.Set;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class FeatureUtil {
/**
* A cache of annotated objects (typically a Class or Method) to its
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/ListFeature.java b/guava-testlib/src/com/google/common/collect/testing/features/ListFeature.java
index 14ae4c0..095723f 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/ListFeature.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/ListFeature.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.lang.annotation.Inherited;
@@ -34,22 +33,23 @@ import java.util.Set;
*/
// Enum values use constructors with generic varargs.
@SuppressWarnings("unchecked")
-@GwtCompatible
public enum ListFeature implements Feature<List> {
SUPPORTS_SET,
- SUPPORTS_ADD_WITH_INDEX(CollectionFeature.SUPPORTS_ADD),
- SUPPORTS_REMOVE_WITH_INDEX(CollectionFeature.SUPPORTS_REMOVE),
+ SUPPORTS_ADD_WITH_INDEX,
+ SUPPORTS_ADD_ALL_WITH_INDEX,
+ SUPPORTS_REMOVE_WITH_INDEX,
GENERAL_PURPOSE(
CollectionFeature.GENERAL_PURPOSE,
SUPPORTS_SET,
SUPPORTS_ADD_WITH_INDEX,
+ SUPPORTS_ADD_ALL_WITH_INDEX,
SUPPORTS_REMOVE_WITH_INDEX
),
/** Features supported by lists where only removal is allowed. */
REMOVE_OPERATIONS(
- CollectionFeature.SUPPORTS_REMOVE,
+ CollectionFeature.REMOVE_OPERATIONS,
SUPPORTS_REMOVE_WITH_INDEX
);
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/MapFeature.java b/guava-testlib/src/com/google/common/collect/testing/features/MapFeature.java
index 482d5b9..8d97a09 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/MapFeature.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/MapFeature.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.lang.annotation.Inherited;
@@ -34,7 +33,6 @@ import java.util.Set;
*/
// Enum values use constructors with generic varargs.
@SuppressWarnings("unchecked")
-@GwtCompatible
public enum MapFeature implements Feature<Map> {
/**
* The map does not throw {@code NullPointerException} on calls such as
@@ -46,8 +44,9 @@ public enum MapFeature implements Feature<Map> {
RESTRICTS_KEYS,
RESTRICTS_VALUES,
SUPPORTS_PUT,
+ SUPPORTS_PUT_ALL,
SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ SUPPORTS_CLEAR,
/**
* Indicates that the constructor or factory method of a map, usually an
* immutable map, throws an {@link IllegalArgumentException} when presented
@@ -57,8 +56,16 @@ public enum MapFeature implements Feature<Map> {
GENERAL_PURPOSE(
SUPPORTS_PUT,
- SUPPORTS_REMOVE
- );
+ SUPPORTS_PUT_ALL,
+ SUPPORTS_REMOVE,
+ SUPPORTS_CLEAR
+ ),
+
+ /** Features supported by maps where only removal is allowed. */
+ REMOVE_OPERATIONS(
+ SUPPORTS_REMOVE,
+ SUPPORTS_CLEAR
+ );
private final Set<Feature<? super Map>> implied;
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/SetFeature.java b/guava-testlib/src/com/google/common/collect/testing/features/SetFeature.java
index 977eefa..7b6c069 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/SetFeature.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/SetFeature.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.lang.annotation.Inherited;
@@ -33,7 +32,6 @@ import java.util.Set;
*/
// Enum values use constructors with generic varargs.
@SuppressWarnings("unchecked")
-@GwtCompatible
public enum SetFeature implements Feature<Set> {
GENERAL_PURPOSE(
CollectionFeature.GENERAL_PURPOSE
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/TesterAnnotation.java b/guava-testlib/src/com/google/common/collect/testing/features/TesterAnnotation.java
index 850124e..bec249c 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/TesterAnnotation.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/TesterAnnotation.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
-
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -41,6 +39,5 @@ import java.lang.annotation.Target;
@Target(value = {java.lang.annotation.ElementType.ANNOTATION_TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
-@GwtCompatible
public @interface TesterAnnotation {
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/features/TesterRequirements.java b/guava-testlib/src/com/google/common/collect/testing/features/TesterRequirements.java
index 82c542a..1d72e3d 100644
--- a/guava-testlib/src/com/google/common/collect/testing/features/TesterRequirements.java
+++ b/guava-testlib/src/com/google/common/collect/testing/features/TesterRequirements.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.features;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import java.util.Collections;
@@ -30,7 +29,6 @@ import java.util.Set;
*
* @author George van den Driessche
*/
-@GwtCompatible
public final class TesterRequirements {
private final Set<Feature<?>> presentFeatures;
private final Set<Feature<?>> absentFeatures;
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/AbstractBiMapTester.java b/guava-testlib/src/com/google/common/collect/testing/google/AbstractBiMapTester.java
deleted file mode 100644
index 88f1b24..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/AbstractBiMapTester.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.Helpers;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map.Entry;
-
-/**
- * Skeleton for a tester of a {@code BiMap}.
- */
-@GwtCompatible
-public abstract class AbstractBiMapTester<K, V> extends AbstractMapTester<K, V> {
-
- @Override
- protected BiMap<K, V> getMap() {
- return (BiMap<K, V>) super.getMap();
- }
-
- static <K, V> Entry<V, K> reverseEntry(Entry<K, V> entry) {
- return Helpers.mapEntry(entry.getValue(), entry.getKey());
- }
-
- @Override
- protected void expectContents(Collection<Entry<K, V>> expected) {
- super.expectContents(expected);
- List<Entry<V, K>> reversedEntries = new ArrayList<Entry<V, K>>();
- for (Entry<K, V> entry : expected) {
- reversedEntries.add(reverseEntry(entry));
- }
- Helpers.assertEqualIgnoringOrder(getMap().inverse().entrySet(), reversedEntries);
-
- for (Entry<K, V> entry : expected) {
- assertEquals("Wrong key for value " + entry.getValue(), entry.getKey(), getMap()
- .inverse()
- .get(entry.getValue()));
- }
- }
-
- @Override
- protected void expectMissing(Entry<K, V>... entries) {
- super.expectMissing(entries);
- for (Entry<K, V> entry : entries) {
- Entry<V, K> reversed = reverseEntry(entry);
- BiMap<V, K> inv = getMap().inverse();
- assertFalse("Inverse should not contain entry " + reversed,
- inv.entrySet().contains(entry));
- assertFalse("Inverse should not contain key " + entry.getValue(),
- inv.containsKey(entry.getValue()));
- assertFalse("Inverse should not contain value " + entry.getKey(),
- inv.containsValue(entry.getKey()));
- assertNull("Inverse should not return a mapping for key " + entry.getValue(),
- getMap().get(entry.getValue()));
- }
- }
-
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/AbstractListMultimapTester.java b/guava-testlib/src/com/google/common/collect/testing/google/AbstractListMultimapTester.java
deleted file mode 100644
index 9f81b4c..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/AbstractListMultimapTester.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-/**
- * Superclass for all {@code ListMultimap} testers.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class AbstractListMultimapTester<K, V>
- extends AbstractMultimapTester<K, V, ListMultimap<K, V>> {
-
- protected void assertGet(K key, V... values) {
- assertGet(key, Arrays.asList(values));
- }
-
- protected void assertGet(K key, Collection<V> values) {
- ASSERT.that(multimap().get(key)).has().allFrom(values).inOrder();
-
- if (!values.isEmpty()) {
- ASSERT.that(multimap().asMap().get(key)).has().allFrom(values).inOrder();
- assertFalse(multimap().isEmpty());
- } else {
- ASSERT.that(multimap().asMap().get(key)).isNull();
- }
-
- assertEquals(values.size(), multimap().get(key).size());
- assertEquals(values.size() > 0, multimap().containsKey(key));
- assertEquals(values.size() > 0, multimap().keySet().contains(key));
- assertEquals(values.size() > 0, multimap().keys().contains(key));
- }
-}
-
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java b/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java
deleted file mode 100644
index a0c0b89..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultimapTester.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.AbstractContainerTester;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.SampleElements;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Superclass for all {@code Multimap} testers.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public abstract class AbstractMultimapTester<K, V, M extends Multimap<K, V>>
- extends AbstractContainerTester<M, Map.Entry<K, V>> {
-
- private M multimap;
-
- protected M multimap() {
- return multimap;
- }
-
- /**
- * @return an array of the proper size with {@code null} as the key of the
- * middle element.
- */
- protected Map.Entry<K, V>[] createArrayWithNullKey() {
- Map.Entry<K, V>[] array = createSamplesArray();
- final int nullKeyLocation = getNullLocation();
- final Map.Entry<K, V> oldEntry = array[nullKeyLocation];
- array[nullKeyLocation] = Helpers.mapEntry(null, oldEntry.getValue());
- return array;
- }
-
- /**
- * @return an array of the proper size with {@code null} as the value of the
- * middle element.
- */
- protected Map.Entry<K, V>[] createArrayWithNullValue() {
- Map.Entry<K, V>[] array = createSamplesArray();
- final int nullValueLocation = getNullLocation();
- final Map.Entry<K, V> oldEntry = array[nullValueLocation];
- array[nullValueLocation] = Helpers.mapEntry(oldEntry.getKey(), null);
- return array;
- }
-
- /**
- * @return an array of the proper size with {@code null} as the key and value of the
- * middle element.
- */
- protected Map.Entry<K, V>[] createArrayWithNullKeyAndValue() {
- Map.Entry<K, V>[] array = createSamplesArray();
- final int nullValueLocation = getNullLocation();
- array[nullValueLocation] = Helpers.mapEntry(null, null);
- return array;
- }
-
- protected V getValueForNullKey() {
- return getEntryNullReplaces().getValue();
- }
-
- protected K getKeyForNullValue() {
- return getEntryNullReplaces().getKey();
- }
-
- private Entry<K, V> getEntryNullReplaces() {
- Iterator<Entry<K, V>> entries = getSampleElements().iterator();
- for (int i = 0; i < getNullLocation(); i++) {
- entries.next();
- }
- return entries.next();
- }
-
- protected void initMultimapWithNullKey() {
- resetContainer(getSubjectGenerator().create(createArrayWithNullKey()));
- }
-
- protected void initMultimapWithNullValue() {
- resetContainer(getSubjectGenerator().create(createArrayWithNullValue()));
- }
-
- protected void initMultimapWithNullKeyAndValue() {
- resetContainer(getSubjectGenerator().create(createArrayWithNullKeyAndValue()));
- }
-
- protected SampleElements<K> sampleKeys() {
- return ((TestMultimapGenerator<K, V, ? extends Multimap<K, V>>) getSubjectGenerator()
- .getInnerGenerator()).sampleKeys();
- }
-
- protected SampleElements<V> sampleValues() {
- return ((TestMultimapGenerator<K, V, ? extends Multimap<K, V>>) getSubjectGenerator()
- .getInnerGenerator()).sampleValues();
- }
-
- @Override
- protected Collection<Entry<K, V>> actualContents() {
- return multimap.entries();
- }
-
- // TODO: dispose of this once collection is encapsulated.
- @Override
- protected M resetContainer(M newContents) {
- multimap = super.resetContainer(newContents);
- return multimap;
- }
-
- protected Multimap<K, V> resetContainer(Entry<K, V>... newContents) {
- multimap = super.resetContainer(getSubjectGenerator().create(newContents));
- return multimap;
- }
-
- /** @see AbstractContainerTester#resetContainer() */
- protected void resetCollection() {
- resetContainer();
- }
-
- protected void assertGet(K key, V... values) {
- assertGet(key, Arrays.asList(values));
- }
-
- protected void assertGet(K key, Collection<V> values) {
- ASSERT.that(multimap().get(key)).has().allFrom(values);
-
- if (!values.isEmpty()) {
- ASSERT.that(multimap().asMap().get(key)).has().allFrom(values);
- assertFalse(multimap().isEmpty());
- } else {
- ASSERT.that(multimap().asMap().get(key)).isNull();
- }
-
- // TODO(user): Add proper overrides to prevent autoboxing.
- // Truth+autoboxing == compile error. Cast int to long to fix:
- ASSERT.that(multimap().get(key).size()).is((long) values.size());
-
- assertEquals(values.size() > 0, multimap().containsKey(key));
- assertEquals(values.size() > 0, multimap().keySet().contains(key));
- assertEquals(values.size() > 0, multimap().keys().contains(key));
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java b/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java
index 55749b2..9219e3e 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/AbstractMultisetSetCountTester.java
@@ -17,7 +17,6 @@
package com.google.common.collect.testing.google;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
@@ -25,17 +24,12 @@ import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Multiset;
-import com.google.common.collect.Multiset.Entry;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import java.lang.reflect.Method;
import java.util.Arrays;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
import java.util.List;
/**
@@ -47,7 +41,7 @@ import java.util.List;
*
* @author Chris Povirk
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public abstract class AbstractMultisetSetCountTester<E>
extends AbstractMultisetTester<E> {
/*
@@ -191,32 +185,6 @@ public abstract class AbstractMultisetSetCountTester<E>
assertSetCount(samples.e3, 1);
}
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- public void testSetCountZeroToOneConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertSetCount(samples.e3, 1);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- public void testSetCountZeroToOneConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator();
- assertSetCount(samples.e3, 1);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@CollectionFeature.Require(SUPPORTS_ADD)
public void testSetCount_zeroToThree_supported() {
assertSetCount(samples.e3, 3);
@@ -252,33 +220,6 @@ public abstract class AbstractMultisetSetCountTester<E>
assertSetCount(samples.e0, 0);
}
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(absent = ZERO)
- public void testSetCountOneToZeroConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertSetCount(samples.e0, 0);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- public void testSetCountOneToZeroConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<E>> iterator = getMultiset().entrySet().iterator();
- assertSetCount(samples.e0, 0);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@CollectionSize.Require(SEVERAL)
@CollectionFeature.Require(SUPPORTS_REMOVE)
public void testSetCount_threeToZero_supported() {
@@ -394,7 +335,6 @@ public abstract class AbstractMultisetSetCountTester<E>
* assume multisets support duplicates so that the test of {@code
* Multisets.forSet()} can suppress them.
*/
- @GwtIncompatible("reflection")
public static List<Method> getSetCountDuplicateInitializingMethods() {
return Arrays.asList(
getMethod("testSetCount_threeToThree_removeSupported"),
@@ -402,8 +342,7 @@ public abstract class AbstractMultisetSetCountTester<E>
getMethod("testSetCount_threeToOne_supported"));
}
- @GwtIncompatible("reflection")
private static Method getMethod(String methodName) {
- return Helpers.getMethod(AbstractMultisetSetCountTester.class, methodName);
+ return Platform.getMethod(AbstractMultisetSetCountTester.class, methodName);
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/BiMapClearTester.java b/guava-testlib/src/com/google/common/collect/testing/google/BiMapClearTester.java
deleted file mode 100644
index 5d0d7a5..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/BiMapClearTester.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.features.MapFeature;
-
-/**
- * Tester for {@code BiMap.clear}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class BiMapClearTester<K, V> extends AbstractBiMapTester<K, V> {
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testClearClearsInverse() {
- BiMap<V, K> inv = getMap().inverse();
- getMap().clear();
- assertTrue(getMap().isEmpty());
- assertTrue(inv.isEmpty());
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testKeySetClearClearsInverse() {
- BiMap<V, K> inv = getMap().inverse();
- getMap().keySet().clear();
- assertTrue(getMap().isEmpty());
- assertTrue(inv.isEmpty());
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testValuesClearClearsInverse() {
- BiMap<V, K> inv = getMap().inverse();
- getMap().values().clear();
- assertTrue(getMap().isEmpty());
- assertTrue(inv.isEmpty());
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testClearInverseClears() {
- BiMap<V, K> inv = getMap().inverse();
- inv.clear();
- assertTrue(getMap().isEmpty());
- assertTrue(inv.isEmpty());
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testClearInverseKeySetClears() {
- BiMap<V, K> inv = getMap().inverse();
- inv.keySet().clear();
- assertTrue(getMap().isEmpty());
- assertTrue(inv.isEmpty());
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testClearInverseValuesClears() {
- BiMap<V, K> inv = getMap().inverse();
- inv.values().clear();
- assertTrue(getMap().isEmpty());
- assertTrue(inv.isEmpty());
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/BiMapGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/BiMapGenerators.java
index db19baa..987ae9c 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/BiMapGenerators.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/BiMapGenerators.java
@@ -16,11 +16,18 @@
package com.google.common.collect.testing.google;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.TestMapEntrySetGenerator;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
/**
* Generators of various {@link com.google.common.collect.BiMap}s and derived
@@ -31,13 +38,82 @@ import java.util.Map.Entry;
*/
@GwtCompatible
public class BiMapGenerators {
- public static class ImmutableBiMapGenerator extends TestStringBiMapGenerator {
- @Override protected BiMap<String, String> create(Entry<String, String>[] entries) {
- ImmutableBiMap.Builder<String, String> builder = ImmutableBiMap.builder();
+
+ public static class ImmutableBiMapKeySetGenerator
+ extends TestStringSetGenerator {
+ @Override protected Set<String> create(String[] elements) {
+ Map<String, Integer> map = Maps.newLinkedHashMap();
+ for (int i = 0; i < elements.length; i++) {
+ map.put(elements[i], i);
+ }
+ return ImmutableBiMap.copyOf(map).keySet();
+ }
+ }
+
+ public static class ImmutableBiMapValuesGenerator
+ extends TestStringSetGenerator {
+ @Override protected Set<String> create(String[] elements) {
+ Map<Integer, String> map = Maps.newLinkedHashMap();
+ for (int i = 0; i < elements.length; i++) {
+ map.put(i, elements[i]);
+ }
+ return ImmutableBiMap.copyOf(map).values();
+ }
+ }
+
+ public static class ImmutableBiMapInverseEntrySetGenerator
+ extends TestMapEntrySetGenerator<String, String> {
+
+ public ImmutableBiMapInverseEntrySetGenerator() {
+ super(new SampleElements.Strings(), new SampleElements.Strings());
+ }
+ @Override public Set<Entry<String, String>> createFromEntries(
+ Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newLinkedHashMap();
+ for (Entry<String, String> entry : entries) {
+ checkNotNull(entry);
+ map.put(entry.getValue(), entry.getKey());
+ }
+ return ImmutableBiMap.copyOf(map).inverse().entrySet();
+ }
+ }
+
+ public static class ImmutableBiMapInverseKeySetGenerator
+ extends TestStringSetGenerator {
+ @Override protected Set<String> create(String[] elements) {
+ Map<Integer, String> map = Maps.newLinkedHashMap();
+ for (int i = 0; i < elements.length; i++) {
+ map.put(i, elements[i]);
+ }
+ return ImmutableBiMap.copyOf(map).inverse().keySet();
+ }
+ }
+
+ public static class ImmutableBiMapInverseValuesGenerator
+ extends TestStringSetGenerator {
+ @Override protected Set<String> create(String[] elements) {
+ Map<String, Integer> map = Maps.newLinkedHashMap();
+ for (int i = 0; i < elements.length; i++) {
+ map.put(elements[i], i);
+ }
+ return ImmutableBiMap.copyOf(map).inverse().values();
+ }
+ }
+
+ public static class ImmutableBiMapEntrySetGenerator
+ extends TestMapEntrySetGenerator<String, String> {
+
+ public ImmutableBiMapEntrySetGenerator() {
+ super(new SampleElements.Strings(), new SampleElements.Strings());
+ }
+ @Override public Set<Entry<String, String>> createFromEntries(
+ Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newLinkedHashMap();
for (Entry<String, String> entry : entries) {
- builder.put(entry.getKey(), entry.getValue());
+ checkNotNull(entry);
+ map.put(entry.getKey(), entry.getValue());
}
- return builder.build();
+ return ImmutableBiMap.copyOf(map).entrySet();
}
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/BiMapInverseTester.java b/guava-testlib/src/com/google/common/collect/testing/google/BiMapInverseTester.java
deleted file mode 100644
index c7cdbf9..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/BiMapInverseTester.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.testing.SerializableTester;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for the {@code inverse} view of a BiMap.
- *
- * <p>This assumes that {@code bimap.inverse().inverse() == bimap}, which is not technically
- * required but is fulfilled by all current implementations.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BiMapInverseTester<K, V> extends AbstractBiMapTester<K, V> {
-
- public void testInverseSame() {
- assertSame(getMap(), getMap().inverse().inverse());
- }
-
- @CollectionFeature.Require(SERIALIZABLE)
- public void testInverseSerialization() {
- BiMapPair<K, V> pair = new BiMapPair<K, V>(getMap());
- BiMapPair<K, V> copy = SerializableTester.reserialize(pair);
- assertEquals(pair.forward, copy.forward);
- assertEquals(pair.backward, copy.backward);
- assertSame(copy.backward, copy.forward.inverse());
- assertSame(copy.forward, copy.backward.inverse());
- }
-
- private static class BiMapPair<K, V> implements Serializable {
- final BiMap<K, V> forward;
- final BiMap<V, K> backward;
-
- BiMapPair(BiMap<K, V> original) {
- this.forward = original;
- this.backward = original.inverse();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns {@link Method} instances for the tests that assume that the inverse will be the same
- * after serialization.
- */
- @GwtIncompatible("reflection")
- public static List<Method> getInverseSameAfterSerializingMethods() {
- return Collections.singletonList(getMethod("testInverseSerialization"));
- }
-
- @GwtIncompatible("reflection")
- private static Method getMethod(String methodName) {
- return Helpers.getMethod(BiMapInverseTester.class, methodName);
- }
-
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/BiMapPutTester.java b/guava-testlib/src/com/google/common/collect/testing/google/BiMapPutTester.java
deleted file mode 100644
index 8c31aa3..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/BiMapPutTester.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-/**
- * Tester for {@code BiMap.put} and {@code BiMap.forcePut}.
- */
-@GwtCompatible
-public class BiMapPutTester<K, V> extends AbstractBiMapTester<K, V> {
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(ZERO)
- public void testPutWithSameValueFails() {
- K k0 = samples.e0.getKey();
- K k1 = samples.e1.getKey();
- V v0 = samples.e0.getValue();
- getMap().put(k0, v0);
- try {
- getMap().put(k1, v0);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- // verify that the bimap is unchanged
- expectAdded(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(ZERO)
- public void testPutPresentKeyDifferentValue() {
- K k0 = samples.e0.getKey();
- V v0 = samples.e0.getValue();
- V v1 = samples.e1.getValue();
- getMap().put(k0, v0);
- getMap().put(k0, v1);
- // verify that the bimap is changed, and that the old inverse mapping
- // from v1 -> v0 is deleted
- expectContents(Helpers.mapEntry(k0, v1));
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(ZERO)
- public void putDistinctKeysDistinctValues() {
- getMap().put(samples.e0.getKey(), samples.e0.getValue());
- getMap().put(samples.e1.getKey(), samples.e1.getValue());
- expectAdded(samples.e0, samples.e1);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(ZERO)
- public void testForcePutOverwritesOldValueEntry() {
- K k0 = samples.e0.getKey();
- K k1 = samples.e1.getKey();
- V v0 = samples.e0.getValue();
- getMap().put(k0, v0);
- getMap().forcePut(k1, v0);
- // verify that the bimap is unchanged
- expectAdded(Helpers.mapEntry(k1, v0));
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(ZERO)
- public void testInversePut() {
- K k0 = samples.e0.getKey();
- V v0 = samples.e0.getValue();
- K k1 = samples.e1.getKey();
- V v1 = samples.e1.getValue();
- getMap().put(k0, v0);
- getMap().inverse().put(v1, k1);
- expectAdded(samples.e0, samples.e1);
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/BiMapRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/google/BiMapRemoveTester.java
deleted file mode 100644
index fe3893b..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/BiMapRemoveTester.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.lang.reflect.Method;
-import java.util.Iterator;
-
-/**
- * Tester for {@code BiMap.remove}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BiMapRemoveTester<K, V> extends AbstractBiMapTester<K, V> {
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveKeyRemovesFromInverse() {
- getMap().remove(samples.e0.getKey());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveKeyFromKeySetRemovesFromInverse() {
- getMap().keySet().remove(samples.e0.getKey());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromValuesRemovesFromInverse() {
- getMap().values().remove(samples.e0.getValue());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromInverseRemovesFromForward() {
- getMap().inverse().remove(samples.e0.getValue());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromInverseKeySetRemovesFromForward() {
- getMap().inverse().keySet().remove(samples.e0.getValue());
- expectMissing(samples.e0);
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveFromInverseValuesRemovesFromInverse() {
- getMap().inverse().values().remove(samples.e0.getKey());
- expectMissing(samples.e0);
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testKeySetIteratorRemove() {
- int initialSize = getNumElements();
- Iterator<K> iterator = getMap().keySet().iterator();
- iterator.next();
- iterator.remove();
- assertEquals(initialSize - 1, getMap().size());
- assertEquals(initialSize - 1, getMap().inverse().size());
- }
-
- /**
- * Returns the {@link Method} instance for
- * {@link #testKeySetIteratorRemove()} so that tests of
- * {@code Maps.filterEntries(BiMap, Predicate)} can suppress
- * it with {@code FeatureSpecificTestSuiteBuilder.suppressing()}.
- */
- @GwtIncompatible("reflection")
- public static Method getKeySetIteratorRemoveMethod() {
- return Helpers.getMethod(BiMapRemoveTester.class, "testKeySetIteratorRemove");
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java
deleted file mode 100644
index 30ffdaa..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/BiMapTestSuiteBuilder.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.PerCollectionSizeTestSuiteBuilder;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.DerivedGoogleCollectionGenerators.BiMapValueSetGenerator;
-import com.google.common.collect.testing.google.DerivedGoogleCollectionGenerators.InverseBiMapGenerator;
-import com.google.common.collect.testing.google.DerivedGoogleCollectionGenerators.MapGenerator;
-import com.google.common.collect.testing.testers.SetCreationTester;
-
-import junit.framework.TestSuite;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests a {@code BiMap}
- * implementation.
- *
- * @author Louis Wasserman
- */
-public class BiMapTestSuiteBuilder<K, V>
- extends PerCollectionSizeTestSuiteBuilder<BiMapTestSuiteBuilder<K, V>,
- TestBiMapGenerator<K, V>, BiMap<K, V>, Map.Entry<K, V>> {
- public static <K, V> BiMapTestSuiteBuilder<K, V> using(TestBiMapGenerator<K, V> generator) {
- return new BiMapTestSuiteBuilder<K, V>().usingGenerator(generator);
- }
-
- @Override
- protected List<Class<? extends AbstractTester>> getTesters() {
- List<Class<? extends AbstractTester>> testers =
- new ArrayList<Class<? extends AbstractTester>>();
- testers.add(BiMapPutTester.class);
- testers.add(BiMapInverseTester.class);
- testers.add(BiMapRemoveTester.class);
- testers.add(BiMapClearTester.class);
- return testers;
- }
-
- enum NoRecurse implements Feature<Void> {
- INVERSE;
-
- @Override
- public Set<Feature<? super Void>> getImpliedFeatures() {
- return Collections.emptySet();
- }
- }
-
- @Override
- protected
- List<TestSuite>
- createDerivedSuites(
- FeatureSpecificTestSuiteBuilder<?,
- ? extends OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>>> parentBuilder) {
- List<TestSuite> derived = super.createDerivedSuites(parentBuilder);
- // TODO(cpovirk): consider using this approach (derived suites instead of extension) in
- // ListTestSuiteBuilder, etc.?
- derived.add(MapTestSuiteBuilder
- .using(new MapGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(parentBuilder.getFeatures())
- .named(parentBuilder.getName() + " [Map]")
- .suppressing(parentBuilder.getSuppressedTests())
- .suppressing(SetCreationTester.class.getMethods())
- // BiMap.entrySet() duplicate-handling behavior is too confusing for SetCreationTester
- .createTestSuite());
- /*
- * TODO(cpovirk): the Map tests duplicate most of this effort by using a
- * CollectionTestSuiteBuilder on values(). It would be nice to avoid that
- */
- derived.add(SetTestSuiteBuilder
- .using(new BiMapValueSetGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeValuesSetFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + " values [Set]")
- .suppressing(parentBuilder.getSuppressedTests())
- .suppressing(SetCreationTester.class.getMethods())
- // BiMap.values() duplicate-handling behavior is too confusing for SetCreationTester
- .createTestSuite());
- if (!parentBuilder.getFeatures().contains(NoRecurse.INVERSE)) {
- derived.add(BiMapTestSuiteBuilder
- .using(new InverseBiMapGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeInverseFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + " inverse")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
-
- return derived;
- }
-
- private static Set<Feature<?>> computeInverseFeatures(Set<Feature<?>> mapFeatures) {
- Set<Feature<?>> inverseFeatures = new HashSet<Feature<?>>(mapFeatures);
-
- boolean nullKeys = inverseFeatures.remove(MapFeature.ALLOWS_NULL_KEYS);
- boolean nullValues = inverseFeatures.remove(MapFeature.ALLOWS_NULL_VALUES);
-
- if (nullKeys) {
- inverseFeatures.add(MapFeature.ALLOWS_NULL_VALUES);
- }
- if (nullValues) {
- inverseFeatures.add(MapFeature.ALLOWS_NULL_KEYS);
- }
-
- inverseFeatures.add(NoRecurse.INVERSE);
- inverseFeatures.remove(CollectionFeature.KNOWN_ORDER);
- inverseFeatures.add(MapFeature.REJECTS_DUPLICATES_AT_CREATION);
-
- return inverseFeatures;
- }
-
- // TODO(user): can we eliminate the duplication from MapTestSuiteBuilder here?
-
- private static Set<Feature<?>> computeValuesSetFeatures(
- Set<Feature<?>> mapFeatures) {
- Set<Feature<?>> valuesCollectionFeatures =
- computeCommonDerivedCollectionFeatures(mapFeatures);
- valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
-
- if (mapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) {
- valuesCollectionFeatures.add(CollectionFeature.ALLOWS_NULL_VALUES);
- }
-
- valuesCollectionFeatures.add(CollectionFeature.REJECTS_DUPLICATES_AT_CREATION);
-
- return valuesCollectionFeatures;
- }
-
- private static Set<Feature<?>> computeCommonDerivedCollectionFeatures(
- Set<Feature<?>> mapFeatures) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- if (mapFeatures.contains(MapFeature.SUPPORTS_REMOVE)) {
- derivedFeatures.add(CollectionFeature.SUPPORTS_REMOVE);
- }
- if (mapFeatures.contains(MapFeature.REJECTS_DUPLICATES_AT_CREATION)) {
- derivedFeatures.add(CollectionFeature.REJECTS_DUPLICATES_AT_CREATION);
- }
- // add the intersection of CollectionSize.values() and mapFeatures
- for (CollectionSize size : CollectionSize.values()) {
- if (mapFeatures.contains(size)) {
- derivedFeatures.add(size);
- }
- }
- return derivedFeatures;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java
deleted file mode 100644
index e3178b4..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/DerivedGoogleCollectionGenerators.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.DerivedGenerator;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestMapGenerator;
-import com.google.common.collect.testing.TestSetGenerator;
-import com.google.common.collect.testing.TestSubjectGenerator;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Derived suite generators for Guava collection interfaces, split out of the suite builders so that
- * they are available to GWT.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public final class DerivedGoogleCollectionGenerators {
- public static class MapGenerator<K, V> implements TestMapGenerator<K, V>, DerivedGenerator {
-
- private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
-
- public MapGenerator(
- OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
- this.generator = oneSizeTestContainerGenerator;
- }
-
- @Override
- public SampleElements<Map.Entry<K, V>> samples() {
- return generator.samples();
- }
-
- @Override
- public Map<K, V> create(Object... elements) {
- return generator.create(elements);
- }
-
- @Override
- public Map.Entry<K, V>[] createArray(int length) {
- return generator.createArray(length);
- }
-
- @Override
- public Iterable<Map.Entry<K, V>> order(List<Map.Entry<K, V>> insertionOrder) {
- return generator.order(insertionOrder);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public K[] createKeyArray(int length) {
- return (K[]) new Object[length];
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public V[] createValueArray(int length) {
- return (V[]) new Object[length];
- }
-
- public TestSubjectGenerator<?> getInnerGenerator() {
- return generator;
- }
- }
-
- public static class InverseBiMapGenerator<K, V>
- implements TestBiMapGenerator<V, K>, DerivedGenerator {
-
- private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
-
- public InverseBiMapGenerator(
- OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
- this.generator = oneSizeTestContainerGenerator;
- }
-
- @Override
- public SampleElements<Map.Entry<V, K>> samples() {
- SampleElements<Entry<K, V>> samples = generator.samples();
- return new SampleElements<Map.Entry<V, K>>(reverse(samples.e0), reverse(samples.e1),
- reverse(samples.e2), reverse(samples.e3), reverse(samples.e4));
- }
-
- private Map.Entry<V, K> reverse(Map.Entry<K, V> entry) {
- return Helpers.mapEntry(entry.getValue(), entry.getKey());
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public BiMap<V, K> create(Object... elements) {
- Entry[] entries = new Entry[elements.length];
- for (int i = 0; i < elements.length; i++) {
- entries[i] = reverse((Entry<K, V>) elements[i]);
- }
- return generator.create((Object[]) entries).inverse();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Map.Entry<V, K>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<V, K>> order(List<Entry<V, K>> insertionOrder) {
- return insertionOrder;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public V[] createKeyArray(int length) {
- return (V[]) new Object[length];
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public K[] createValueArray(int length) {
- return (K[]) new Object[length];
- }
-
- public TestSubjectGenerator<?> getInnerGenerator() {
- return generator;
- }
- }
-
- public static class BiMapValueSetGenerator<K, V>
- implements TestSetGenerator<V>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<BiMap<K, V>, Map.Entry<K, V>>
- mapGenerator;
- private final SampleElements<V> samples;
-
- public BiMapValueSetGenerator(
- OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator) {
- this.mapGenerator = mapGenerator;
- final SampleElements<Map.Entry<K, V>> mapSamples =
- this.mapGenerator.samples();
- this.samples = new SampleElements<V>(
- mapSamples.e0.getValue(),
- mapSamples.e1.getValue(),
- mapSamples.e2.getValue(),
- mapSamples.e3.getValue(),
- mapSamples.e4.getValue());
- }
-
- @Override
- public SampleElements<V> samples() {
- return samples;
- }
-
- @Override
- public Set<V> create(Object... elements) {
- @SuppressWarnings("unchecked")
- V[] valuesArray = (V[]) elements;
-
- // Start with a suitably shaped collection of entries
- Collection<Map.Entry<K, V>> originalEntries =
- mapGenerator.getSampleElements(elements.length);
-
- // Create a copy of that, with the desired value for each value
- Collection<Map.Entry<K, V>> entries =
- new ArrayList<Entry<K, V>>(elements.length);
- int i = 0;
- for (Map.Entry<K, V> entry : originalEntries) {
- entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
- }
-
- return mapGenerator.create(entries.toArray()).values();
- }
-
- @Override
- public V[] createArray(int length) {
- final V[] vs = ((TestBiMapGenerator<K, V>) mapGenerator.getInnerGenerator())
- .createValueArray(length);
- return vs;
- }
-
- @Override
- public Iterable<V> order(List<V> insertionOrder) {
- return insertionOrder;
- }
-
- public TestSubjectGenerator<?> getInnerGenerator() {
- return mapGenerator;
- }
- }
-
- private DerivedGoogleCollectionGenerators() {}
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/ListGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/ListGenerators.java
index fb14416..e0b7691 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/ListGenerators.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/ListGenerators.java
@@ -20,15 +20,12 @@ import static java.util.Arrays.asList;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.testing.TestCharacterListGenerator;
+import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.testing.TestListGenerator;
import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.TestUnhashableCollectionGenerator;
import com.google.common.collect.testing.UnhashableObject;
-import com.google.common.primitives.Chars;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -50,7 +47,7 @@ public final class ListGenerators {
public static class BuilderAddListGenerator extends TestStringListGenerator {
@Override protected List<String> create(String[] elements) {
- ImmutableList.Builder<String> builder = ImmutableList.<String>builder();
+ Builder<String> builder = ImmutableList.<String>builder();
for (String element : elements) {
builder.add(element);
}
@@ -66,7 +63,7 @@ public final class ListGenerators {
.build();
}
}
-
+
public static class BuilderReversedListGenerator
extends TestStringListGenerator {
@Override protected List<String> create(String[] elements) {
@@ -116,24 +113,6 @@ public final class ListGenerators {
}
}
- public static class CharactersOfStringGenerator
- extends TestCharacterListGenerator {
- @Override public List<Character> create(Character[] elements) {
- char[] chars = Chars.toArray(Arrays.asList(elements));
- return Lists.charactersOf(String.copyValueOf(chars));
- }
- }
-
- public static class CharactersOfCharSequenceGenerator
- extends TestCharacterListGenerator {
- @Override public List<Character> create(Character[] elements) {
- char[] chars = Chars.toArray(Arrays.asList(elements));
- StringBuilder str = new StringBuilder();
- str.append(chars);
- return Lists.charactersOf(str);
- }
- }
-
private abstract static class TestUnhashableListGenerator
extends TestUnhashableCollectionGenerator<List<UnhashableObject>>
implements TestListGenerator<UnhashableObject> {
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutAllTester.java b/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutAllTester.java
deleted file mode 100644
index 228d61d..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutAllTester.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.copyToList;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Testers for {@link ListMultimap#putAll(Object, Iterable)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class ListMultimapPutAllTester<K, V> extends AbstractListMultimapTester<K, V> {
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAllAddsAtEndInOrder() {
- @SuppressWarnings("unchecked")
- List<V> values = Arrays.asList(
- sampleValues().e3,
- sampleValues().e1,
- sampleValues().e4);
-
- for (K k : sampleKeys()) {
- resetContainer();
-
- List<V> expectedValues = copyToList(multimap().get(k));
-
- multimap().putAll(k, values);
- expectedValues.addAll(values);
-
- assertGet(k, expectedValues);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutTester.java b/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutTester.java
deleted file mode 100644
index 2941612..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapPutTester.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.copyToList;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.List;
-import java.util.Map.Entry;
-
-/**
- * Testers for {@link ListMultimap#put(Object, Object)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class ListMultimapPutTester<K, V> extends AbstractListMultimapTester<K, V> {
- // MultimapPutTester tests non-duplicate values, but ignores ordering
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAddsValueAtEnd() {
- for (K key : sampleKeys()) {
- for (V value : sampleValues()) {
- resetContainer();
-
- List<V> values = multimap().get(key);
- List<V> expectedValues = Helpers.copyToList(values);
-
- multimap().put(key, value);
- expectedValues.add(value);
-
- assertGet(key, expectedValues);
- assertEquals(value, values.get(values.size() - 1));
- }
- }
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutDuplicateValue() {
- List<Entry<K, V>> entries = copyToList(multimap().entries());
-
- for (Entry<K, V> entry : entries) {
- resetContainer();
-
- K k = entry.getKey();
- V v = entry.getValue();
-
- List<V> values = multimap().get(k);
- List<V> expectedValues = copyToList(values);
-
- assertTrue(multimap().put(k, v));
- expectedValues.add(v);
- assertGet(k, expectedValues);
- assertEquals(v, values.get(values.size() - 1));
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapRemoveTester.java
deleted file mode 100644
index 18f9b3a..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapRemoveTester.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.copyToList;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Testers for {@link ListMultimap#remove(Object, Object)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class ListMultimapRemoveTester<K, V> extends AbstractListMultimapTester<K, V> {
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(SEVERAL)
- public void testMultimapRemoveDeletesFirstOccurrence() {
- K k = sampleKeys().e0;
- V v0 = sampleValues().e0;
- V v1 = sampleValues().e2;
- resetContainer(mapEntry(k, v0), mapEntry(k, v1), mapEntry(k, v0));
-
- List<V> list = multimap().get(k);
- multimap().remove(k, v0);
- ASSERT.that(list).has().allOf(v1, v0).inOrder();
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(SEVERAL)
- public void testRemoveAtIndexFromGetPropagates() {
- K k = sampleKeys().e0;
- V v0 = sampleValues().e0;
- V v1 = sampleValues().e2;
- List<V> values = Arrays.asList(v0, v1, v0);
-
- for (int i = 0; i < 3; i++) {
- resetContainer(mapEntry(k, v0), mapEntry(k, v1), mapEntry(k, v0));
- List<V> expectedValues = copyToList(values);
-
- multimap().get(k).remove(i);
- expectedValues.remove(i);
-
- assertGet(k, expectedValues);
- }
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(SEVERAL)
- public void testRemoveAtIndexFromAsMapPropagates() {
- K k = sampleKeys().e0;
- V v0 = sampleValues().e0;
- V v1 = sampleValues().e2;
- List<V> values = Arrays.asList(v0, v1, v0);
-
- for (int i = 0; i < 3; i++) {
- resetContainer(mapEntry(k, v0), mapEntry(k, v1), mapEntry(k, v0));
- List<V> expectedValues = copyToList(values);
-
- List<V> asMapValue = (List<V>) multimap().asMap().get(k);
- asMapValue.remove(i);
- expectedValues.remove(i);
-
- assertGet(k, expectedValues);
- }
- }
-
- @SuppressWarnings("unchecked")
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(SEVERAL)
- public void testRemoveAtIndexFromAsMapEntrySetPropagates() {
- K k = sampleKeys().e0;
- V v0 = sampleValues().e0;
- V v1 = sampleValues().e2;
- List<V> values = Arrays.asList(v0, v1, v0);
-
- for (int i = 0; i < 3; i++) {
- resetContainer(mapEntry(k, v0), mapEntry(k, v1), mapEntry(k, v0));
- List<V> expectedValues = copyToList(values);
-
- Map.Entry<K, Collection<V>> asMapEntry = multimap().asMap().entrySet().iterator().next();
- List<V> asMapValue = (List<V>) asMapEntry.getValue();
- asMapValue.remove(i);
- expectedValues.remove(i);
-
- assertGet(k, expectedValues);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapReplaceValuesTester.java b/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapReplaceValuesTester.java
deleted file mode 100644
index b7551af..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapReplaceValuesTester.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Testers for {@link ListMultimap#replaceValues(Object, Iterable)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class ListMultimapReplaceValuesTester<K, V> extends AbstractListMultimapTester<K, V> {
- @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
- public void testReplaceValuesPreservesOrder() {
- @SuppressWarnings("unchecked")
- List<V> values = Arrays.asList(
- sampleValues().e3,
- sampleValues().e1,
- sampleValues().e4);
-
- for (K k : sampleKeys()) {
- resetContainer();
- multimap().replaceValues(k, values);
- assertGet(k, values);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapTestSuiteBuilder.java
deleted file mode 100644
index 87f84d6..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/ListMultimapTestSuiteBuilder.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.TestListGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.features.ListFeature;
-
-import junit.framework.TestSuite;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests
- * a {@code ListMultimap} implementation.
- *
- * @author Louis Wasserman
- */
-public class ListMultimapTestSuiteBuilder<K, V> extends
- MultimapTestSuiteBuilder<K, V, ListMultimap<K, V>> {
-
- public static <K, V> ListMultimapTestSuiteBuilder<K, V> using(
- TestListMultimapGenerator<K, V> generator) {
- ListMultimapTestSuiteBuilder<K, V> result = new ListMultimapTestSuiteBuilder<K, V>();
- result.usingGenerator(generator);
- return result;
- }
-
- @Override protected List<Class<? extends AbstractTester>> getTesters() {
- List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
- testers.add(ListMultimapPutTester.class);
- testers.add(ListMultimapPutAllTester.class);
- testers.add(ListMultimapRemoveTester.class);
- testers.add(ListMultimapReplaceValuesTester.class);
- return testers;
- }
-
- @Override
- TestSuite computeMultimapGetTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ? extends
- OneSizeTestContainerGenerator<ListMultimap<K, V>, Entry<K, V>>> parentBuilder) {
- return ListTestSuiteBuilder.using(
- new MultimapGetGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".get[key]")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- @Override
- Set<Feature<?>> computeMultimapGetFeatures(
- Set<Feature<?>> multimapFeatures) {
- Set<Feature<?>> derivedFeatures = super.computeMultimapGetFeatures(multimapFeatures);
- if (derivedFeatures.contains(CollectionFeature.SUPPORTS_ADD)) {
- derivedFeatures.add(ListFeature.SUPPORTS_ADD_WITH_INDEX);
- }
- if (derivedFeatures.contains(CollectionFeature.GENERAL_PURPOSE)) {
- derivedFeatures.add(ListFeature.GENERAL_PURPOSE);
- }
- return derivedFeatures;
- }
-
- private static class MultimapGetGenerator<K, V>
- extends MultimapTestSuiteBuilder.MultimapGetGenerator<K, V, ListMultimap<K, V>>
- implements TestListGenerator<V> {
- public MultimapGetGenerator(
- OneSizeTestContainerGenerator<ListMultimap<K, V>, Entry<K, V>> multimapGenerator) {
- super(multimapGenerator);
- }
-
- @Override
- public List<V> create(Object... elements) {
- return (List<V>) super.create(elements);
- }
-
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java
index fa4b91d..2dd9f54 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MapGenerators.java
@@ -16,26 +16,23 @@
package com.google.common.collect.testing.google;
-import static com.google.common.collect.testing.Helpers.mapEntry;
+import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.testing.AnEnum;
+import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestEnumMapGenerator;
+import com.google.common.collect.testing.TestCollectionGenerator;
import com.google.common.collect.testing.TestListGenerator;
-import com.google.common.collect.testing.TestStringListGenerator;
-import com.google.common.collect.testing.TestStringMapGenerator;
+import com.google.common.collect.testing.TestMapEntrySetGenerator;
+import com.google.common.collect.testing.TestStringSetGenerator;
import com.google.common.collect.testing.TestUnhashableCollectionGenerator;
import com.google.common.collect.testing.UnhashableObject;
import java.util.Collection;
-import java.util.EnumMap;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
/**
* Generators of different types of map and related collections, such as
@@ -45,121 +42,105 @@ import java.util.Map.Entry;
*/
@GwtCompatible
public class MapGenerators {
- public static class ImmutableMapGenerator
- extends TestStringMapGenerator {
- @Override protected Map<String, String> create(Entry<String, String>[] entries) {
- ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
- for (Entry<String, String> entry : entries) {
- builder.put(entry.getKey(), entry.getValue());
+
+ public static class ImmutableMapKeySetGenerator
+ extends TestStringSetGenerator {
+ @Override protected Set<String> create(String[] elements) {
+ Builder<String, Integer> builder = ImmutableMap.builder();
+ for (String key : elements) {
+ builder.put(key, 4);
}
- return builder.build();
+ return builder.build().keySet();
}
}
- public static class ImmutableMapUnhashableValuesGenerator
- extends TestUnhashableCollectionGenerator<Collection<UnhashableObject>> {
+ public static class ImmutableMapValuesGenerator
+ implements TestCollectionGenerator<String> {
- @Override public Collection<UnhashableObject> create(
- UnhashableObject[] elements) {
- ImmutableMap.Builder<Integer, UnhashableObject> builder = ImmutableMap.builder();
- int key = 1;
- for (UnhashableObject value : elements) {
- builder.put(key++, value);
+ @Override
+ public SampleElements<String> samples() {
+ return new SampleElements.Strings();
+ }
+
+ @Override
+ public Collection<String> create(Object... elements) {
+ Builder<Object, String> builder = ImmutableMap.builder();
+ for (Object key : elements) {
+ builder.put(key, String.valueOf(key));
}
return builder.build().values();
}
- }
- public static class ImmutableMapKeyListGenerator extends TestStringListGenerator {
@Override
- public List<String> create(String[] elements) {
- ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
- for (int i = 0; i < elements.length; i++) {
- builder.put(elements[i], i);
- }
- return builder.build().keySet().asList();
+ public String[] createArray(int length) {
+ return new String[length];
}
- }
- public static class ImmutableMapValueListGenerator extends TestStringListGenerator {
@Override
- public List<String> create(String[] elements) {
- ImmutableMap.Builder<Integer, String> builder = ImmutableMap.builder();
- for (int i = 0; i < elements.length; i++) {
- builder.put(i, elements[i]);
- }
- return builder.build().values().asList();
+ public List<String> order(List<String> insertionOrder) {
+ return insertionOrder;
}
}
- public static class ImmutableMapEntryListGenerator
- implements TestListGenerator<Entry<String, Integer>> {
+ public static class ImmutableMapUnhashableValuesGenerator
+ extends TestUnhashableCollectionGenerator<Collection<UnhashableObject>> {
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- mapEntry("foo", 5),
- mapEntry("bar", 3),
- mapEntry("baz", 17),
- mapEntry("quux", 1),
- mapEntry("toaster", -2));
+ @Override public Collection<UnhashableObject> create(
+ UnhashableObject[] elements) {
+ Builder<Integer, UnhashableObject> builder = ImmutableMap.builder();
+ int key = 1;
+ for (UnhashableObject value : elements) {
+ builder.put(key++, value);
+ }
+ return builder.build().values();
}
+ }
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, Integer>[] createArray(int length) {
- return new Entry[length];
- }
+ public static class ImmutableMapEntrySetGenerator
+ extends TestMapEntrySetGenerator<String, String> {
- @Override
- public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) {
- return insertionOrder;
+ public ImmutableMapEntrySetGenerator() {
+ super(new SampleElements.Strings(), new SampleElements.Strings());
}
- @Override
- public List<Entry<String, Integer>> create(Object... elements) {
- ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) o;
- builder.put(entry);
+ @Override public Set<Entry<String, String>> createFromEntries(
+ Entry<String, String>[] entries) {
+ Builder<String, String> builder = ImmutableMap.builder();
+ for (Entry<String, String> entry : entries) {
+ // This null-check forces NPE to be thrown for tests with null
+ // elements. Those tests aren't useful in testing entry sets
+ // because entry sets never have null elements.
+ checkNotNull(entry);
+ builder.put(entry.getKey(), entry.getValue());
}
- return builder.build().entrySet().asList();
+ return builder.build().entrySet();
}
}
- public static class ImmutableEnumMapGenerator extends TestEnumMapGenerator {
+ public static class ImmutableMapValueListGenerator
+ implements TestListGenerator<String> {
@Override
- protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) {
- Map<AnEnum, String> map = Maps.newHashMap();
- for (Entry<AnEnum, String> entry : entries) {
- // checkArgument(!map.containsKey(entry.getKey()));
- map.put(entry.getKey(), entry.getValue());
- }
- return Maps.immutableEnumMap(map);
+ public SampleElements<String> samples() {
+ return new SampleElements.Strings();
}
- }
- public static class ImmutableMapCopyOfEnumMapGenerator extends TestEnumMapGenerator {
@Override
- protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) {
- EnumMap<AnEnum, String> map = new EnumMap<AnEnum, String>(AnEnum.class);
- for (Entry<AnEnum, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
+ public List<String> create(Object... elements) {
+ Builder<Integer, String> builder = ImmutableMap.builder();
+ for (int i = 0; i < elements.length; i++) {
+ builder.put(i, toStringOrNull(elements[i]));
}
- return ImmutableMap.copyOf(map);
+ return builder.build().values().asList();
}
@Override
- public Iterable<Entry<AnEnum, String>> order(List<Entry<AnEnum, String>> insertionOrder) {
- return new Ordering<Entry<AnEnum, String>>() {
-
- @Override
- public int compare(Entry<AnEnum, String> left, Entry<AnEnum, String> right) {
- return left.getKey().compareTo(right.getKey());
- }
+ public String[] createArray(int length) {
+ return new String[length];
+ }
- }.sortedCopy(insertionOrder);
+ @Override
+ public Iterable<String> order(List<String> insertionOrder) {
+ return insertionOrder;
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsEntryTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsEntryTester.java
deleted file mode 100644
index aeabd99..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsEntryTester.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-/**
- * Tester for {@link Multimap#containsEntry}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapContainsEntryTester<K, V>
- extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @CollectionSize.Require(absent = ZERO)
- public void testContainsEntryYes() {
- assertTrue(multimap().containsEntry(sampleKeys().e0, sampleValues().e0));
- }
-
- public void testContainsEntryNo() {
- assertFalse(multimap().containsEntry(sampleKeys().e3, sampleValues().e3));
- }
-
- public void testContainsEntryAgreesWithGet() {
- for (K k : sampleKeys()) {
- for (V v : sampleValues()) {
- assertEquals(multimap().get(k).contains(v),
- multimap().containsEntry(k, v));
- }
- }
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require({ ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES })
- public void testContainsEntryNullYes() {
- initMultimapWithNullKeyAndValue();
- assertTrue(multimap().containsEntry(null, null));
- }
-
- @MapFeature.Require(ALLOWS_NULL_QUERIES)
- public void testContainsEntryNullNo() {
- assertFalse(multimap().containsEntry(null, null));
- }
-
- @MapFeature.Require(absent = ALLOWS_NULL_QUERIES)
- public void testContainsEntryNullDisallowed() {
- try {
- multimap().containsEntry(null, null);
- fail("Expected NullPointerException");
- } catch (NullPointerException expected) {
- // success
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsKeyTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsKeyTester.java
deleted file mode 100644
index 1d2e7d9..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsKeyTester.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-/**
- * Tester for the {@code containsKey} methods of {@code Multimap} and its {@code asMap()} view.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapContainsKeyTester<K, V>
- extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @CollectionSize.Require(absent = ZERO)
- public void testContainsKeyYes() {
- assertTrue(multimap().containsKey(sampleKeys().e0));
- }
-
- public void testContainsKeyNo() {
- assertFalse(multimap().containsKey(sampleKeys().e3));
- }
-
- public void testContainsKeysFromKeySet() {
- for (K k : multimap().keySet()) {
- assertTrue(multimap().containsKey(k));
- }
- }
-
- public void testContainsKeyAgreesWithGet() {
- for (K k : sampleKeys()) {
- assertEquals(!multimap().get(k).isEmpty(), multimap().containsKey(k));
- }
- }
-
- public void testContainsKeyAgreesWithAsMap() {
- for (K k : sampleKeys()) {
- assertEquals(multimap().containsKey(k), multimap().asMap().containsKey(k));
- }
- }
-
- public void testContainsKeyAgreesWithKeySet() {
- for (K k : sampleKeys()) {
- assertEquals(multimap().containsKey(k), multimap().keySet().contains(k));
- }
- }
-
- @MapFeature.Require(ALLOWS_NULL_KEYS)
- @CollectionSize.Require(absent = ZERO)
- public void testContainsKeyNullPresent() {
- initMultimapWithNullKey();
- assertTrue(multimap().containsKey(null));
- }
-
- @MapFeature.Require(ALLOWS_NULL_QUERIES)
- public void testContainsKeyNullAbsent() {
- assertFalse(multimap().containsKey(null));
- }
-
- @MapFeature.Require(absent = ALLOWS_NULL_QUERIES)
- public void testContainsKeyNullDisallowed() {
- try {
- multimap().containsKey(null);
- fail("Expected NullPointerException");
- } catch (NullPointerException expected) {
- // success
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsValueTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsValueTester.java
deleted file mode 100644
index 4b0d51a..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapContainsValueTester.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-/**
- * Tester for {@link Multimap#containsValue}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapContainsValueTester<K, V>
- extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @CollectionSize.Require(absent = ZERO)
- public void testContainsValueYes() {
- assertTrue(multimap().containsValue(sampleValues().e0));
- }
-
- public void testContainsValueNo() {
- assertFalse(multimap().containsValue(sampleValues().e3));
- }
-
- @MapFeature.Require(ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testContainsNullValueYes() {
- initMultimapWithNullValue();
- assertTrue(multimap().containsValue(null));
- }
-
- @MapFeature.Require(ALLOWS_NULL_QUERIES)
- public void testContainsNullValueNo() {
- assertFalse(multimap().containsValue(null));
- }
-
- @MapFeature.Require(absent = ALLOWS_NULL_QUERIES)
- public void testContainsNullValueFails() {
- try {
- multimap().containsValue(null);
- fail("Expected NullPointerException");
- } catch (NullPointerException expected) {
- // success
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapGetTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapGetTester.java
deleted file mode 100644
index f57928a..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapGetTester.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.assertContentsAnyOrder;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Collection;
-
-/**
- * Tests for {@link Multimap#get(Object)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapGetTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- public void testGetEmpty() {
- Collection<V> result = multimap().get(sampleKeys().e3);
- assertTrue(result.isEmpty());
- assertEquals(0, result.size());
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testGetNonEmpty() {
- Collection<V> result = multimap().get(sampleKeys().e0);
- assertFalse(result.isEmpty());
- assertContentsAnyOrder(result, sampleValues().e0);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testGetPropagatesRemove() {
- Collection<V> result = multimap().get(sampleKeys().e0);
- assertTrue(result.remove(sampleValues().e0));
- assertFalse(multimap().containsKey(sampleKeys().e0));
- assertTrue(result.isEmpty());
- assertTrue(multimap().get(sampleKeys().e0).isEmpty());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require({ SUPPORTS_REMOVE, SUPPORTS_PUT })
- public void testGetRemoveThenAddPropagates() {
- int oldSize = getNumElements();
-
- K k0 = sampleKeys().e0;
- V v0 = sampleValues().e0;
-
- Collection<V> result = multimap().get(k0);
- assertTrue(result.remove(v0));
-
- assertFalse(multimap().containsKey(k0));
- assertFalse(multimap().containsEntry(k0, v0));
- ASSERT.that(result).isEmpty();
-
- V v1 = sampleValues().e1;
- V v2 = sampleValues().e2;
-
- assertTrue(result.add(v1));
- assertTrue(result.add(v2));
-
- ASSERT.that(result).has().allOf(v1, v2);
- ASSERT.that(multimap().get(k0)).has().allOf(v1, v2);
- assertTrue(multimap().containsKey(k0));
- assertFalse(multimap().containsEntry(k0, v0));
- assertTrue(multimap().containsEntry(k0, v2));
- assertEquals(oldSize + 1, multimap().size());
- }
-
- @MapFeature.Require(ALLOWS_NULL_KEYS)
- @CollectionSize.Require(absent = ZERO)
- public void testGetNullPresent() {
- initMultimapWithNullKey();
- ASSERT.that(multimap().get(null)).has().item(getValueForNullKey());
- }
-
- @MapFeature.Require(ALLOWS_NULL_QUERIES)
- public void testGetNullAbsent() {
- ASSERT.that(multimap().get(null)).isEmpty();
- }
-
- @MapFeature.Require(absent = ALLOWS_NULL_QUERIES)
- public void testGetNullForbidden() {
- try {
- multimap().get(null);
- fail("Expected NullPointerException");
- } catch (NullPointerException expected) {
- // success
- }
- }
-
- @MapFeature.Require(ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
- public void testGetWithNullValue() {
- initMultimapWithNullValue();
- ASSERT.that(multimap().get(getKeyForNullValue()))
- .has().item(null);
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapPutIterableTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapPutIterableTester.java
deleted file mode 100644
index 39acf99..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapPutIterableTester.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Collections;
-import java.util.Iterator;
-
-/**
- * Tests for {@link Multimap#putAll(Object, Iterable)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapPutIterableTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAllNonEmptyOnPresentKey() {
- multimap().putAll(sampleKeys().e0, new Iterable<V>() {
- @Override
- public Iterator<V> iterator() {
- return Lists.newArrayList(sampleValues().e3, sampleValues().e4).iterator();
- }
- });
- assertGet(sampleKeys().e0, sampleValues().e0, sampleValues().e3, sampleValues().e4);
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAllNonEmptyOnAbsentKey() {
- multimap().putAll(sampleKeys().e3, new Iterable<V>() {
- @Override
- public Iterator<V> iterator() {
- return Lists.newArrayList(sampleValues().e3, sampleValues().e4).iterator();
- }
- });
- assertGet(sampleKeys().e3, sampleValues().e3, sampleValues().e4);
- }
-
- private static final Object[] EMPTY = new Object[0];
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAllEmptyIterableOnAbsentKey() {
- Iterable<V> iterable = Collections.emptyList();
-
- multimap().putAll(sampleKeys().e3, iterable);
- expectUnchanged();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutAllEmptyIterableOnPresentKey() {
- multimap().putAll(sampleKeys().e0, Collections.<V>emptyList());
- expectUnchanged();
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapPutTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapPutTester.java
deleted file mode 100644
index 9e113cf..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapPutTester.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-
-/**
- * Tester for {@link Multimap#put}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapPutTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutEmpty() {
- int size = getNumElements();
-
- K key = sampleKeys().e3;
- V value = sampleValues().e3;
-
- assertGet(key, ImmutableList.<V>of());
-
- assertTrue(multimap().put(key, value));
-
- assertGet(key, value);
- assertEquals(size + 1, multimap().size());
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutPresent() {
- int size = getNumElements();
-
- K key = sampleKeys().e0;
- V oldValue = sampleValues().e0;
- V newValue = sampleValues().e3;
-
- assertGet(key, oldValue);
-
- assertTrue(multimap().put(key, newValue));
-
- assertGet(key, oldValue, newValue);
- assertEquals(size + 1, multimap().size());
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutTwoElements() {
- int size = getNumElements();
-
- K key = sampleKeys().e0;
- V v1 = sampleValues().e3;
- V v2 = sampleValues().e4;
-
- List<V> values = Helpers.copyToList(multimap().get(key));
-
- assertTrue(multimap().put(key, v1));
- assertTrue(multimap().put(key, v2));
-
- values.add(v1);
- values.add(v2);
-
- assertGet(key, values);
- assertEquals(size + 2, multimap().size());
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
- public void testPutNullValue() {
- int size = getNumElements();
-
- multimap().put(sampleKeys().e3, null);
-
- assertGet(sampleKeys().e3, Lists.newArrayList((V)null)); // ImmutableList.of can't take null.
- assertEquals(size + 1, multimap().size());
- }
-
- @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
- public void testPutNullKey() {
- int size = getNumElements();
-
- multimap().put(null, sampleValues().e3);
-
- assertGet(null, sampleValues().e3);
- assertEquals(size + 1, multimap().size());
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testPutNotPresentKeyPropagatesToGet() {
- int size = getNumElements();
- Collection<V> collection = multimap().get(sampleKeys().e3);
- ASSERT.that(collection).isEmpty();
- multimap().put(sampleKeys().e3, sampleValues().e3);
- ASSERT.that(collection).has().item(sampleValues().e3);
- assertEquals(size + 1, multimap().size());
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutPresentKeyPropagatesToGet() {
- List<K> keys = Helpers.copyToList(multimap().keySet());
- for (K key : keys) {
- resetContainer();
-
- int size = getNumElements();
-
- Collection<V> collection = multimap().get(key);
- Collection<V> expectedCollection = Helpers.copyToList(collection);
-
- multimap().put(key, sampleValues().e3);
- expectedCollection.add(sampleValues().e3);
- ASSERT.that(collection).has().allFrom(expectedCollection);
- assertEquals(size + 1, multimap().size());
- }
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutPresentKeyPropagatesToAsMapGet() {
- List<K> keys = Helpers.copyToList(multimap().keySet());
- for (K key : keys) {
- resetContainer();
-
- int size = getNumElements();
-
- Collection<V> collection = multimap().asMap().get(key);
- assertNotNull(collection);
- Collection<V> expectedCollection = Helpers.copyToList(collection);
-
- multimap().put(key, sampleValues().e3);
- expectedCollection.add(sampleValues().e3);
- ASSERT.that(collection).has().allFrom(expectedCollection);
- assertEquals(size + 1, multimap().size());
- }
- }
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutPresentKeyPropagatesToAsMapEntrySet() {
- List<K> keys = Helpers.copyToList(multimap().keySet());
- for (K key : keys) {
- resetContainer();
-
- int size = getNumElements();
-
- Iterator<Entry<K, Collection<V>>> asMapItr = multimap().asMap().entrySet().iterator();
- Collection<V> collection = null;
- while (asMapItr.hasNext()) {
- Entry<K, Collection<V>> asMapEntry = asMapItr.next();
- if (key.equals(asMapEntry.getKey())) {
- collection = asMapEntry.getValue();
- break;
- }
- }
- assertNotNull(collection);
- Collection<V> expectedCollection = Helpers.copyToList(collection);
-
- multimap().put(key, sampleValues().e3);
- expectedCollection.add(sampleValues().e3);
- ASSERT.that(collection).has().allFrom(expectedCollection);
- assertEquals(size + 1, multimap().size());
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveAllTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveAllTester.java
deleted file mode 100644
index 7c209a7..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveAllTester.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Collection;
-
-/**
- * Tests for {@link Multimap#removeAll(Object)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapRemoveAllTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveAllAbsentKey() {
- ASSERT.that(multimap().removeAll(sampleKeys().e3)).isEmpty();
- expectUnchanged();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveAllPresentKey() {
- ASSERT.that(multimap().removeAll(sampleKeys().e0))
- .has().allOf(sampleValues().e0).inOrder();
- expectMissing(samples.e0);
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveAllPropagatesToGet() {
- Collection<V> getResult = multimap().get(sampleKeys().e0);
-
- multimap().removeAll(sampleKeys().e0);
-
- ASSERT.that(getResult).isEmpty();
- expectMissing(samples.e0);
- }
-
- @CollectionSize.Require(SEVERAL)
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveAllMultipleValues() {
- resetContainer(
- Helpers.mapEntry(sampleKeys().e0, sampleValues().e0),
- Helpers.mapEntry(sampleKeys().e0, sampleValues().e1),
- Helpers.mapEntry(sampleKeys().e0, sampleValues().e2));
-
- ASSERT.that(multimap().removeAll(sampleKeys().e0))
- .has().allOf(sampleValues().e0, sampleValues().e1, sampleValues().e2);
- assertTrue(multimap().isEmpty());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_KEYS })
- public void testRemoveAllNullKeyPresent() {
- initMultimapWithNullKey();
-
- ASSERT.that(multimap().removeAll(null)).has().allOf(getValueForNullKey()).inOrder();
-
- expectMissing(Helpers.mapEntry((K) null, getValueForNullKey()));
- }
-
- @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES })
- public void testRemoveAllNullKeyAbsent() {
- ASSERT.that(multimap().removeAll(null)).isEmpty();
- expectUnchanged();
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveEntryTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveEntryTester.java
deleted file mode 100644
index 7245f77..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapRemoveEntryTester.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-
-/**
- * Tests for {@link Multimap#remove(Object, Object)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapRemoveEntryTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveAbsent() {
- assertFalse(multimap().remove(sampleKeys().e0, sampleValues().e1));
- expectUnchanged();
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(SUPPORTS_REMOVE)
- public void testRemovePresent() {
- assertTrue(multimap().remove(sampleKeys().e0, sampleValues().e0));
-
- expectMissing(samples.e0);
- assertGet(sampleKeys().e0, ImmutableList.<V>of());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_KEYS })
- public void testRemoveNullKeyPresent() {
- initMultimapWithNullKey();
-
- assertTrue(multimap().remove(null, getValueForNullKey()));
-
- expectMissing(Helpers.mapEntry((K) null, getValueForNullKey()));
- assertGet(getKeyForNullValue(), ImmutableList.<V>of());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_VALUES })
- public void testRemoveNullValuePresent() {
- initMultimapWithNullValue();
-
- assertTrue(multimap().remove(getKeyForNullValue(), null));
-
- expectMissing(Helpers.mapEntry(getKeyForNullValue(), (V) null));
- assertGet(getKeyForNullValue(), ImmutableList.<V>of());
- }
-
- @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
- public void testRemoveNullKeyAbsent() {
- assertFalse(multimap().remove(null, sampleValues().e0));
- expectUnchanged();
- }
-
- @MapFeature.Require({ SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
- public void testRemoveNullValueAbsent() {
- assertFalse(multimap().remove(sampleKeys().e0, null));
- expectUnchanged();
- }
-
- @MapFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_QUERIES)
- public void testRemoveNullValueForbidden() {
- try {
- multimap().remove(sampleKeys().e0, null);
- fail("Expected NullPointerException");
- } catch (NullPointerException expected) {
- // success
- }
- expectUnchanged();
- }
-
- @MapFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_QUERIES)
- public void testRemoveNullKeyForbidden() {
- try {
- multimap().remove(null, sampleValues().e0);
- fail("Expected NullPointerException");
- } catch (NullPointerException expected) {
- // success
- }
- expectUnchanged();
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemovePropagatesToGet() {
- List<Entry<K, V>> entries = Helpers.copyToList(multimap().entries());
- for (Entry<K, V> entry : entries) {
- resetContainer();
-
- K key = entry.getKey();
- V value = entry.getValue();
- Collection<V> collection = multimap().get(key);
- assertNotNull(collection);
- Collection<V> expectedCollection = Helpers.copyToList(collection);
-
- multimap().remove(key, value);
- expectedCollection.remove(value);
-
- ASSERT.that(collection).has().allFrom(expectedCollection);
- assertEquals(!expectedCollection.isEmpty(), multimap().containsKey(key));
- }
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemovePropagatesToAsMap() {
- List<Entry<K, V>> entries = Helpers.copyToList(multimap().entries());
- for (Entry<K, V> entry : entries) {
- resetContainer();
-
- K key = entry.getKey();
- V value = entry.getValue();
- Collection<V> collection = multimap().asMap().get(key);
- assertNotNull(collection);
- Collection<V> expectedCollection = Helpers.copyToList(collection);
-
- multimap().remove(key, value);
- expectedCollection.remove(value);
-
- ASSERT.that(collection).has().allFrom(expectedCollection);
- assertEquals(!expectedCollection.isEmpty(), multimap().containsKey(key));
- }
- }
-
- @MapFeature.Require(SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testRemovePropagatesToAsMapEntrySet() {
- List<Entry<K, V>> entries = Helpers.copyToList(multimap().entries());
- for (Entry<K, V> entry : entries) {
- resetContainer();
-
- K key = entry.getKey();
- V value = entry.getValue();
-
- Iterator<Entry<K, Collection<V>>> asMapItr = multimap().asMap().entrySet().iterator();
- Collection<V> collection = null;
- while (asMapItr.hasNext()) {
- Entry<K, Collection<V>> asMapEntry = asMapItr.next();
- if (key.equals(asMapEntry.getKey())) {
- collection = asMapEntry.getValue();
- break;
- }
- }
- assertNotNull(collection);
- Collection<V> expectedCollection = Helpers.copyToList(collection);
-
- multimap().remove(key, value);
- expectedCollection.remove(value);
-
- ASSERT.that(collection).has().allFrom(expectedCollection);
- assertEquals(!expectedCollection.isEmpty(), multimap().containsKey(key));
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapReplaceValuesTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapReplaceValuesTester.java
deleted file mode 100644
index 85dc6b9..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapReplaceValuesTester.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Tests for {@link Multimap#replaceValues(Object, Iterable)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapReplaceValuesTester<K, V>
- extends AbstractMultimapTester<K, V, Multimap<K, V>> {
- @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
- public void testReplaceEmptyValues() {
- int size = multimap().size();
- K key = sampleKeys().e3;
- @SuppressWarnings("unchecked")
- List<V> values = Arrays.asList(sampleValues().e0, sampleValues().e2, sampleValues().e3);
- multimap().replaceValues(key, values);
- assertGet(key, values);
- assertEquals(size + values.size(), multimap().size());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
- public void testReplaceNonEmptyValues() {
- List<K> keys = Helpers.copyToList(multimap().keySet());
- @SuppressWarnings("unchecked")
- List<V> values = Arrays.asList(sampleValues().e0, sampleValues().e2, sampleValues().e3);
-
- for (K k : keys) {
- resetContainer();
-
- int size = multimap().size();
- Collection<V> oldKeyValues = Helpers.copyToList(multimap().get(k));
- multimap().replaceValues(k, values);
- assertGet(k, values);
- assertEquals(size + values.size() - oldKeyValues.size(), multimap().size());
- }
- }
-
- @MapFeature.Require(absent = SUPPORTS_REMOVE)
- @CollectionSize.Require(absent = ZERO)
- public void testReplaceValuesRemoveNotSupported() {
- List<V> values = Collections.singletonList(sampleValues().e3);
- try {
- multimap().replaceValues(sampleKeys().e0, values);
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException expected) {
- // success
- }
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
- public void testReplaceValuesPutNotSupported() {
- List<V> values = Collections.singletonList(sampleValues().e3);
- try {
- multimap().replaceValues(sampleKeys().e0, values);
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException expected) {
- // success
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapSizeTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapSizeTester.java
deleted file mode 100644
index 0f63789..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapSizeTester.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.mapEntry;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Collection;
-import java.util.Map.Entry;
-
-/**
- * Tester for the {@code size} methods of {@code Multimap} and its views.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MultimapSizeTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> {
-
- public void testSize() {
- int expectedSize = getNumElements();
- Multimap<K, V> multimap = multimap();
- assertEquals(expectedSize, multimap.size());
-
- int size = 0;
- for (Entry<K, V> entry : multimap.entries()) {
- assertTrue(multimap.containsEntry(entry.getKey(), entry.getValue()));
- size++;
- }
- assertEquals(expectedSize, size);
-
- int size2 = 0;
- for (Entry<K, Collection<V>> entry2 : multimap.asMap().entrySet()) {
- size2 += entry2.getValue().size();
- }
- assertEquals(expectedSize, size2);
- }
-
- @CollectionSize.Require(ZERO)
- public void testIsEmptyYes() {
- assertTrue(multimap().isEmpty());
- }
-
- @CollectionSize.Require(absent = ZERO)
- public void testIsEmptyNo() {
- assertFalse(multimap().isEmpty());
- }
-
- @CollectionSize.Require(absent = ZERO)
- @MapFeature.Require(ALLOWS_NULL_KEYS)
- public void testSizeNullEntry() {
- initMultimapWithNullKey();
- assertEquals(getNumElements(), multimap().size());
- assertFalse(multimap().isEmpty());
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testSizeMultipleValues() {
- resetContainer(
- mapEntry(sampleKeys().e0, sampleValues().e0),
- mapEntry(sampleKeys().e0, sampleValues().e1),
- mapEntry(sampleKeys().e0, sampleValues().e2));
-
- assertEquals(3, multimap().size());
- assertEquals(3, multimap().entries().size());
- assertEquals(3, multimap().keys().size());
-
- assertEquals(1, multimap().keySet().size());
- assertEquals(1, multimap().asMap().size());
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java
deleted file mode 100644
index b3886cb..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultimapTestSuiteBuilder.java
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.CollectionTestSuiteBuilder;
-import com.google.common.collect.testing.DerivedGenerator;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.PerCollectionSizeTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestCollectionGenerator;
-import com.google.common.collect.testing.TestMapGenerator;
-import com.google.common.collect.testing.TestSubjectGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestSuite;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests
- * a {@code Multimap} implementation.
- *
- * @author Louis Wasserman
- */
-public class MultimapTestSuiteBuilder<K, V, M extends Multimap<K, V>> extends
- PerCollectionSizeTestSuiteBuilder<
- MultimapTestSuiteBuilder<K, V, M>,
- TestMultimapGenerator<K, V, M>, M, Map.Entry<K, V>> {
-
- public static <K, V, M extends Multimap<K, V>> MultimapTestSuiteBuilder<K, V, M> using(
- TestMultimapGenerator<K, V, M> generator) {
- return new MultimapTestSuiteBuilder<K, V, M>().usingGenerator(generator);
- }
-
- // Class parameters must be raw.
- @Override
- protected List<Class<? extends AbstractTester>> getTesters() {
- return ImmutableList.<Class<? extends AbstractTester>> of(
- MultimapSizeTester.class,
- MultimapContainsKeyTester.class,
- MultimapContainsValueTester.class,
- MultimapContainsEntryTester.class,
- MultimapGetTester.class,
- MultimapPutTester.class,
- MultimapPutIterableTester.class,
- MultimapReplaceValuesTester.class,
- MultimapRemoveEntryTester.class,
- MultimapRemoveAllTester.class);
- }
-
- @Override
- protected List<TestSuite> createDerivedSuites(
- FeatureSpecificTestSuiteBuilder<
- ?,
- ? extends OneSizeTestContainerGenerator<M, Map.Entry<K, V>>>
- parentBuilder) {
- // TODO: Once invariant support is added, supply invariants to each of the
- // derived suites, to check that mutations to the derived collections are
- // reflected in the underlying map.
-
- List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder);
-
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(MultimapTestSuiteBuilder.using(
- new ReserializedMultimapGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeReserializedMultimapFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + " reserialized")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
-
- derivedSuites.add(MapTestSuiteBuilder.using(
- new AsMapGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeAsMapFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".asMap")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
-
- derivedSuites.add(computeEntriesTestSuite(parentBuilder));
- derivedSuites.add(computeMultimapGetTestSuite(parentBuilder));
- derivedSuites.add(computeKeysTestSuite(parentBuilder));
-
- return derivedSuites;
- }
-
- TestSuite computeValuesTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ?
- extends OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
- return CollectionTestSuiteBuilder.using(
- new ValuesGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeValuesFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".entries")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- TestSuite computeEntriesTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ?
- extends OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
- return CollectionTestSuiteBuilder.using(
- new EntriesGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeEntriesFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".entries")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- TestSuite computeMultimapGetTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ? extends
- OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
- return CollectionTestSuiteBuilder.using(
- new MultimapGetGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".get[key]")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- TestSuite computeKeysTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ? extends
- OneSizeTestContainerGenerator<M, Map.Entry<K, V>>> parentBuilder) {
- return MultisetTestSuiteBuilder.using(
- new KeysGenerator<K, V, M>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeKeysFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".keys")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- static Set<Feature<?>> computeDerivedCollectionFeatures(Set<Feature<?>> multimapFeatures) {
- Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
- if (!derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- }
- if (derivedFeatures.remove(MapFeature.ALLOWS_NULL_QUERIES)) {
- derivedFeatures.add(CollectionFeature.ALLOWS_NULL_QUERIES);
- }
- if (derivedFeatures.remove(MapFeature.SUPPORTS_REMOVE)) {
- derivedFeatures.add(CollectionFeature.SUPPORTS_REMOVE);
- }
- return derivedFeatures;
- }
-
- static Set<Feature<?>> computeEntriesFeatures(
- Set<Feature<?>> multimapFeatures) {
- return computeDerivedCollectionFeatures(multimapFeatures);
- }
-
- static Set<Feature<?>> computeValuesFeatures(
- Set<Feature<?>> multimapFeatures) {
- return computeDerivedCollectionFeatures(multimapFeatures);
- }
-
- static Set<Feature<?>> computeKeysFeatures(
- Set<Feature<?>> multimapFeatures) {
- Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures);
- if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) {
- result.add(CollectionFeature.ALLOWS_NULL_VALUES);
- }
- return result;
- }
-
- private static Set<Feature<?>> computeReserializedMultimapFeatures(
- Set<Feature<?>> multimapFeatures) {
- Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
- return derivedFeatures;
- }
-
- private static Set<Feature<?>> computeAsMapFeatures(
- Set<Feature<?>> multimapFeatures) {
- Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
- derivedFeatures.remove(MapFeature.GENERAL_PURPOSE);
- derivedFeatures.remove(MapFeature.SUPPORTS_PUT);
- derivedFeatures.remove(MapFeature.ALLOWS_NULL_VALUES);
- derivedFeatures.add(MapFeature.REJECTS_DUPLICATES_AT_CREATION);
- if (!derivedFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- }
- return derivedFeatures;
- }
-
- private static final Multimap<Feature<?>, Feature<?>> GET_FEATURE_MAP = ImmutableMultimap
- .<Feature<?>, Feature<?>> builder()
- .put(
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION)
- .put(MapFeature.GENERAL_PURPOSE, CollectionFeature.GENERAL_PURPOSE)
- .put(MapFeature.ALLOWS_NULL_QUERIES, CollectionFeature.ALLOWS_NULL_QUERIES)
- .put(MapFeature.ALLOWS_NULL_VALUES, CollectionFeature.ALLOWS_NULL_VALUES)
- .put(MapFeature.SUPPORTS_REMOVE, CollectionFeature.SUPPORTS_REMOVE)
- .put(MapFeature.SUPPORTS_PUT, CollectionFeature.SUPPORTS_ADD)
- .build();
-
- Set<Feature<?>> computeMultimapGetFeatures(
- Set<Feature<?>> multimapFeatures) {
- Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures);
- for (Map.Entry<Feature<?>, Feature<?>> entry : GET_FEATURE_MAP.entries()) {
- if (derivedFeatures.contains(entry.getKey())) {
- derivedFeatures.add(entry.getValue());
- }
- }
- if (!derivedFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- }
- derivedFeatures.removeAll(GET_FEATURE_MAP.keySet());
- return derivedFeatures;
- }
-
- private static class AsMapGenerator<K, V, M extends Multimap<K, V>> implements
- TestMapGenerator<K, Collection<V>>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
-
- public AsMapGenerator(
- OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
- this.multimapGenerator = multimapGenerator;
- }
-
- @Override
- public TestSubjectGenerator<?> getInnerGenerator() {
- return multimapGenerator;
- }
-
- private Collection<V> createCollection(V v) {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .createCollection(Collections.singleton(v));
- }
-
- @Override
- public SampleElements<Entry<K, Collection<V>>> samples() {
- SampleElements<K> sampleKeys =
- ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys();
- SampleElements<V> sampleValues =
- ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleValues();
- return new SampleElements<Entry<K, Collection<V>>>(
- mapEntry(sampleKeys.e0, createCollection(sampleValues.e0)),
- mapEntry(sampleKeys.e1, createCollection(sampleValues.e1)),
- mapEntry(sampleKeys.e2, createCollection(sampleValues.e2)),
- mapEntry(sampleKeys.e3, createCollection(sampleValues.e3)),
- mapEntry(sampleKeys.e4, createCollection(sampleValues.e4)));
- }
-
- @Override
- public Map<K, Collection<V>> create(Object... elements) {
- Set<K> keySet = new HashSet<K>();
- List<Map.Entry<K, V>> builder = new ArrayList<Entry<K, V>>();
- for (Object o : elements) {
- Map.Entry<K, Collection<V>> entry = (Entry<K, Collection<V>>) o;
- keySet.add(entry.getKey());
- for (V v : entry.getValue()) {
- builder.add(mapEntry(entry.getKey(), v));
- }
- }
- checkArgument(keySet.size() == elements.length, "Duplicate keys");
- return multimapGenerator.create(builder.toArray()).asMap();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<K, Collection<V>>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<K, Collection<V>>> order(List<Entry<K, Collection<V>>> insertionOrder) {
- Map<K, Collection<V>> map = new HashMap<K, Collection<V>>();
- List<Map.Entry<K, V>> builder = new ArrayList<Entry<K, V>>();
- for (Entry<K, Collection<V>> entry : insertionOrder) {
- for (V v : entry.getValue()) {
- builder.add(mapEntry(entry.getKey(), v));
- }
- map.put(entry.getKey(), entry.getValue());
- }
- Iterable<Map.Entry<K, V>> ordered = multimapGenerator.order(builder);
- LinkedHashMap<K, Collection<V>> orderedMap = new LinkedHashMap<K, Collection<V>>();
- for (Map.Entry<K, V> entry : ordered) {
- orderedMap.put(entry.getKey(), map.get(entry.getKey()));
- }
- return orderedMap.entrySet();
- }
-
- @Override
- public K[] createKeyArray(int length) {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .createKeyArray(length);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Collection<V>[] createValueArray(int length) {
- return new Collection[length];
- }
- }
-
- static class EntriesGenerator<K, V, M extends Multimap<K, V>>
- implements TestCollectionGenerator<Entry<K, V>>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
-
- public EntriesGenerator(
- OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
- this.multimapGenerator = multimapGenerator;
- }
-
- @Override
- public TestSubjectGenerator<?> getInnerGenerator() {
- return multimapGenerator;
- }
-
- @Override
- public SampleElements<Entry<K, V>> samples() {
- return multimapGenerator.samples();
- }
-
- @Override
- public Collection<Entry<K, V>> create(Object... elements) {
- return multimapGenerator.create(elements).entries();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<K, V>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
- return multimapGenerator.order(insertionOrder);
- }
- }
-
- static class ValuesGenerator<K, V, M extends Multimap<K, V>>
- implements TestCollectionGenerator<V> {
- private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
-
- public ValuesGenerator(
- OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
- this.multimapGenerator = multimapGenerator;
- }
-
- @Override
- public SampleElements<V> samples() {
- return
- ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleValues();
- }
-
- @Override
- public Collection<V> create(Object... elements) {
- K k =
- ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys().e0;
- Entry<K, V>[] entries = new Entry[elements.length];
- for (int i = 0; i < elements.length; i++) {
- entries[i] = mapEntry(k, (V) elements[i]);
- }
- return multimapGenerator.create(entries).values();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public V[] createArray(int length) {
- return ((TestMultimapGenerator<K, V, M>)
- multimapGenerator.getInnerGenerator()).createValueArray(length);
- }
-
- @Override
- public Iterable<V> order(List<V> insertionOrder) {
- K k =
- ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys().e0;
- List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
- for (V v : insertionOrder) {
- entries.add(mapEntry(k, v));
- }
- Iterable<Entry<K, V>> ordered = multimapGenerator.order(entries);
- List<V> orderedValues = new ArrayList<V>();
- for (Entry<K, V> entry : ordered) {
- orderedValues.add(entry.getValue());
- }
- return orderedValues;
- }
- }
-
- static class KeysGenerator<K, V, M extends Multimap<K, V>> implements
- TestMultisetGenerator<K>, DerivedGenerator {
- private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
-
- public KeysGenerator(
- OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) {
- this.multimapGenerator = multimapGenerator;
- }
-
- @Override
- public TestSubjectGenerator<?> getInnerGenerator() {
- return multimapGenerator;
- }
-
- @Override
- public SampleElements<K> samples() {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys();
- }
-
- @Override
- public Multiset<K> create(Object... elements) {
- /*
- * This is nasty and complicated, but it's the only way to make sure keys get mapped to enough
- * distinct values.
- */
- Map.Entry[] entries = new Map.Entry[elements.length];
- Map<K, Iterator<V>> valueIterators = new HashMap<K, Iterator<V>>();
- for (int i = 0; i < elements.length; i++) {
- @SuppressWarnings("unchecked")
- K key = (K) elements[i];
-
- Iterator<V> valueItr = valueIterators.get(key);
- if (valueItr == null) {
- valueIterators.put(key, valueItr = sampleValuesIterator());
- }
- entries[i] = mapEntry((K) elements[i], valueItr.next());
- }
- return multimapGenerator.create(entries).keys();
- }
-
- private Iterator<V> sampleValuesIterator() {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator
- .getInnerGenerator()).sampleValues().iterator();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public K[] createArray(int length) {
- return ((TestMultimapGenerator<K, V, M>)
- multimapGenerator.getInnerGenerator()).createKeyArray(length);
- }
-
- @Override
- public Iterable<K> order(List<K> insertionOrder) {
- Iterator<V> valueIter = sampleValuesIterator();
- List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
- for (K k : insertionOrder) {
- entries.add(mapEntry(k, valueIter.next()));
- }
- Iterable<Entry<K, V>> ordered = multimapGenerator.order(entries);
- List<K> orderedValues = new ArrayList<K>();
- for (Entry<K, V> entry : ordered) {
- orderedValues.add(entry.getKey());
- }
- return orderedValues;
- }
- }
-
- static class MultimapGetGenerator<K, V, M extends Multimap<K, V>>
- implements TestCollectionGenerator<V> {
- private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
-
- public MultimapGetGenerator(
- OneSizeTestContainerGenerator<
- M, Map.Entry<K, V>> multimapGenerator) {
- this.multimapGenerator = multimapGenerator;
- }
-
- @Override
- public SampleElements<V> samples() {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .sampleValues();
- }
-
- @Override
- public V[] createArray(int length) {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .createValueArray(length);
- }
-
- @Override
- public Iterable<V> order(List<V> insertionOrder) {
- K k = ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .sampleKeys().e0;
- List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();
- for (V v : insertionOrder) {
- entries.add(mapEntry(k, v));
- }
- Iterable<Entry<K, V>> orderedEntries = multimapGenerator.order(entries);
- List<V> values = new ArrayList<V>();
- for (Entry<K, V> entry : orderedEntries) {
- values.add(entry.getValue());
- }
- return values;
- }
-
- @Override
- public Collection<V> create(Object... elements) {
- Entry<K, V>[] array = multimapGenerator.createArray(elements.length);
- K k = ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .sampleKeys().e0;
- for (int i = 0; i < elements.length; i++) {
- array[i] = mapEntry(k, (V) elements[i]);
- }
- return multimapGenerator.create(array).get(k);
- }
- }
-
- private static class ReserializedMultimapGenerator<K, V, M extends Multimap<K, V>>
- implements TestMultimapGenerator<K, V, M> {
- private final OneSizeTestContainerGenerator<M, Map.Entry<K, V>> multimapGenerator;
-
- public ReserializedMultimapGenerator(
- OneSizeTestContainerGenerator<
- M, Map.Entry<K, V>> multimapGenerator) {
- this.multimapGenerator = multimapGenerator;
- }
-
- @Override
- public SampleElements<Map.Entry<K, V>> samples() {
- return multimapGenerator.samples();
- }
-
- @Override
- public Map.Entry<K, V>[] createArray(int length) {
- return multimapGenerator.createArray(length);
- }
-
- @Override
- public Iterable<Map.Entry<K, V>> order(
- List<Map.Entry<K, V>> insertionOrder) {
- return multimapGenerator.order(insertionOrder);
- }
-
- @Override
- public M create(Object... elements) {
- return SerializableTester.reserialize(((TestMultimapGenerator<K, V, M>) multimapGenerator
- .getInnerGenerator()).create(elements));
- }
-
- @Override
- public K[] createKeyArray(int length) {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .createKeyArray(length);
- }
-
- @Override
- public V[] createValueArray(int length) {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .createValueArray(length);
- }
-
- @Override
- public SampleElements<K> sampleKeys() {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .sampleKeys();
- }
-
- @Override
- public SampleElements<V> sampleValues() {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .sampleValues();
- }
-
- @Override
- public Collection<V> createCollection(Iterable<? extends V> values) {
- return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator())
- .createCollection(values);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultisetIteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultisetIteratorTester.java
index 8f1f70e..63082d5 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultisetIteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MultisetIteratorTester.java
@@ -18,8 +18,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.KNOWN
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.IteratorFeature;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -35,7 +33,7 @@ import java.util.List;
*
* @author Louis Wasserman
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class MultisetIteratorTester<E> extends AbstractMultisetTester<E> {
@SuppressWarnings("unchecked")
@CollectionFeature.Require({SUPPORTS_REMOVE, KNOWN_ORDER})
@@ -95,30 +93,11 @@ public class MultisetIteratorTester<E> extends AbstractMultisetTester<E> {
* Returns {@link Method} instances for the tests that assume multisets support duplicates so that
* the test of {@code Multisets.forSet()} can suppress them.
*/
- @GwtIncompatible("reflection")
public static List<Method> getIteratorDuplicateInitializingMethods() {
return Arrays.asList(
- Helpers.getMethod(MultisetIteratorTester.class, "testIteratorKnownOrder"),
- Helpers.getMethod(MultisetIteratorTester.class, "testIteratorUnknownOrder"),
- Helpers.getMethod(MultisetIteratorTester.class, "testRemovingIteratorKnownOrder"),
- Helpers.getMethod(MultisetIteratorTester.class, "testRemovingIteratorUnknownOrder"));
- }
-
- /**
- * Returns the {@link Method} instance for the test that assumes the multiset iterator supports
- * {@code remove()} so that the test for {@code Multisets.filter} can suppress it.
- */
- @GwtIncompatible("reflection")
- public static Method getIteratorKnownOrderRemoveSupportedMethod() {
- return Helpers.getMethod(MultisetIteratorTester.class, "testRemovingIteratorKnownOrder");
- }
-
- /**
- * Returns the {@link Method} instance for the test that assumes the multiset iterator supports
- * {@code remove()} so that the test for {@code Multisets.filter} can suppress it.
- */
- @GwtIncompatible("reflection")
- public static Method getIteratorUnknownOrderRemoveSupportedMethod() {
- return Helpers.getMethod(MultisetIteratorTester.class, "testRemovingIteratorUnknownOrder");
+ Platform.getMethod(MultisetIteratorTester.class, "testIteratorKnownOrder"),
+ Platform.getMethod(MultisetIteratorTester.class, "testIteratorUnknownOrder"),
+ Platform.getMethod(MultisetIteratorTester.class, "testRemovingIteratorKnownOrder"),
+ Platform.getMethod(MultisetIteratorTester.class, "testRemovingIteratorUnknownOrder"));
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java
index 9c844e8..e817738 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MultisetNavigationTester.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Guava Authors
+ * Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultisetReadsTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultisetReadsTester.java
index 9f1dd9c..c353404 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultisetReadsTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MultisetReadsTester.java
@@ -21,11 +21,9 @@ import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multisets;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionSize;
@@ -40,7 +38,7 @@ import java.util.List;
*
* @author Jared Levy
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class MultisetReadsTester<E> extends AbstractMultisetTester<E> {
public void testCount_0() {
assertEquals("multiset.count(missing) didn't return 0",
@@ -149,9 +147,8 @@ public class MultisetReadsTester<E> extends AbstractMultisetTester<E> {
* support duplicates so that the test of {@code Multisets.forSet()} can
* suppress them.
*/
- @GwtIncompatible("reflection")
public static List<Method> getReadsDuplicateInitializingMethods() {
return Arrays.asList(
- Helpers.getMethod(MultisetReadsTester.class, "testCount_3"));
+ Platform.getMethod(MultisetReadsTester.class, "testCount_3"));
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultisetSerializationTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultisetSerializationTester.java
deleted file mode 100644
index 2a0a633..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultisetSerializationTester.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.testing.SerializableTester;
-
-import java.util.Set;
-
-/**
- * A generic JUnit test which tests multiset-specific serialization. Can't be invoked directly;
- * please see {@link com.google.common.collect.testing.MultisetTestSuiteBuilder}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible // but no-op
-public class MultisetSerializationTester<E> extends AbstractMultisetTester<E> {
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- public void testEntrySetSerialization() {
- Set<Multiset.Entry<E>> expected = getMultiset().entrySet();
- assertEquals(expected, SerializableTester.reserialize(expected));
- }
-
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- public void testElementSetSerialization() {
- Set<E> expected = getMultiset().elementSet();
- assertEquals(expected, SerializableTester.reserialize(expected));
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java
index 1175af9..4bdbaf5 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MultisetTestSuiteBuilder.java
@@ -16,35 +16,12 @@
package com.google.common.collect.testing.google;
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Multiset.Entry;
-import com.google.common.collect.Multisets;
+import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTestSuiteBuilder;
import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.testers.CollectionSerializationEqualTester;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestSuite;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
/**
* Creates, based on your criteria, a JUnit test suite that exhaustively tests
@@ -53,6 +30,7 @@ import java.util.Set;
* @author Jared Levy
* @author Louis Wasserman
*/
+@GwtCompatible
public class MultisetTestSuiteBuilder<E> extends
AbstractCollectionTestSuiteBuilder<MultisetTestSuiteBuilder<E>, E> {
public static <E> MultisetTestSuiteBuilder<E> using(
@@ -60,219 +38,15 @@ public class MultisetTestSuiteBuilder<E> extends
return new MultisetTestSuiteBuilder<E>().usingGenerator(generator);
}
- public enum NoRecurse implements Feature<Void> {
- NO_ENTRY_SET;
-
- @Override
- public Set<Feature<? super Void>> getImpliedFeatures() {
- return Collections.emptySet();
- }
- }
-
@Override protected List<Class<? extends AbstractTester>> getTesters() {
List<Class<? extends AbstractTester>> testers
= Helpers.copyToList(super.getTesters());
- testers.add(CollectionSerializationEqualTester.class);
testers.add(MultisetReadsTester.class);
testers.add(MultisetSetCountConditionallyTester.class);
testers.add(MultisetSetCountUnconditionallyTester.class);
testers.add(MultisetWritesTester.class);
testers.add(MultisetIteratorTester.class);
- testers.add(MultisetSerializationTester.class);
return testers;
}
-
- private static Set<Feature<?>> computeEntrySetFeatures(
- Set<Feature<?>> features) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- derivedFeatures.addAll(features);
- derivedFeatures.remove(CollectionFeature.GENERAL_PURPOSE);
- derivedFeatures.remove(CollectionFeature.SUPPORTS_ADD);
- derivedFeatures.remove(CollectionFeature.ALLOWS_NULL_VALUES);
- derivedFeatures.add(CollectionFeature.REJECTS_DUPLICATES_AT_CREATION);
- if (!derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- }
- return derivedFeatures;
- }
-
- static Set<Feature<?>> computeElementSetFeatures(
- Set<Feature<?>> features) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- derivedFeatures.addAll(features);
- derivedFeatures.remove(CollectionFeature.GENERAL_PURPOSE);
- derivedFeatures.remove(CollectionFeature.SUPPORTS_ADD);
- if (!derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- }
- return derivedFeatures;
- }
-
- private static Set<Feature<?>> computeReserializedMultisetFeatures(
- Set<Feature<?>> features) {
- Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
- derivedFeatures.addAll(features);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
- derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
- return derivedFeatures;
- }
-
- @Override
- protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder<
- ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
- List<TestSuite> derivedSuites = new ArrayList<TestSuite>(
- super.createDerivedSuites(parentBuilder));
-
- derivedSuites.add(createElementSetTestSuite(parentBuilder));
-
- if (!parentBuilder.getFeatures().contains(NoRecurse.NO_ENTRY_SET)) {
- derivedSuites.add(
- SetTestSuiteBuilder.using(new EntrySetGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + ".entrySet")
- .withFeatures(computeEntrySetFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
-
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(MultisetTestSuiteBuilder
- .using(new ReserializedMultisetGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + " reserialized")
- .withFeatures(computeReserializedMultisetFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite());
- }
- return derivedSuites;
- }
-
- TestSuite createElementSetTestSuite(FeatureSpecificTestSuiteBuilder<
- ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
- return SetTestSuiteBuilder
- .using(new ElementSetGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + ".elementSet")
- .withFeatures(computeElementSetFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- static class ElementSetGenerator<E> implements TestSetGenerator<E> {
- final OneSizeTestContainerGenerator<Collection<E>, E> gen;
-
- ElementSetGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
- this.gen = gen;
- }
-
- @Override
- public SampleElements<E> samples() {
- return gen.samples();
- }
-
- @Override
- public Set<E> create(Object... elements) {
- Object[] duplicated = new Object[elements.length * 2];
- for (int i = 0; i < elements.length; i++) {
- duplicated[i] = elements[i];
- duplicated[i + elements.length] = elements[i];
- }
- return ((Multiset<E>) gen.create(duplicated)).elementSet();
- }
-
- @Override
- public E[] createArray(int length) {
- return gen.createArray(length);
- }
-
- @Override
- public Iterable<E> order(List<E> insertionOrder) {
- return gen.order(new ArrayList<E>(new LinkedHashSet<E>(insertionOrder)));
- }
- }
-
- static class EntrySetGenerator<E> implements TestSetGenerator<Multiset.Entry<E>> {
- final OneSizeTestContainerGenerator<Collection<E>, E> gen;
-
- private EntrySetGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
- this.gen = gen;
- }
-
- @Override
- public SampleElements<Multiset.Entry<E>> samples() {
- SampleElements<E> samples = gen.samples();
- return new SampleElements<Multiset.Entry<E>>(
- Multisets.immutableEntry(samples.e0, 3),
- Multisets.immutableEntry(samples.e1, 4),
- Multisets.immutableEntry(samples.e2, 1),
- Multisets.immutableEntry(samples.e3, 5),
- Multisets.immutableEntry(samples.e4, 2));
- }
-
- @Override
- public Set<Multiset.Entry<E>> create(Object... entries) {
- List<Object> contents = new ArrayList<Object>();
- Set<E> elements = new HashSet<E>();
- for (Object o : entries) {
- @SuppressWarnings("unchecked")
- Multiset.Entry<E> entry = (Entry<E>) o;
- checkArgument(elements.add(entry.getElement()),
- "Duplicate keys not allowed in EntrySetGenerator");
- for (int i = 0; i < entry.getCount(); i++) {
- contents.add(entry.getElement());
- }
- }
- return ((Multiset<E>) gen.create(contents.toArray())).entrySet();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Multiset.Entry<E>[] createArray(int length) {
- return new Multiset.Entry[length];
- }
-
- @Override
- public Iterable<Entry<E>> order(List<Entry<E>> insertionOrder) {
- // We mimic the order from gen.
- Map<E, Entry<E>> map = new LinkedHashMap<E, Entry<E>>();
- for (Entry<E> entry : insertionOrder) {
- map.put(entry.getElement(), entry);
- }
-
- Set<E> seen = new HashSet<E>();
- List<Entry<E>> order = new ArrayList<Entry<E>>();
- for (E e : gen.order(new ArrayList<E>(map.keySet()))) {
- if (seen.add(e)) {
- order.add(map.get(e));
- }
- }
- return order;
- }
- }
-
- static class ReserializedMultisetGenerator<E> implements TestMultisetGenerator<E>{
- final OneSizeTestContainerGenerator<Collection<E>, E> gen;
-
- private ReserializedMultisetGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
- this.gen = gen;
- }
-
- @Override
- public SampleElements<E> samples() {
- return gen.samples();
- }
-
- @Override
- public Multiset<E> create(Object... elements) {
- return (Multiset<E>) SerializableTester.reserialize(gen.create(elements));
- }
-
- @Override
- public E[] createArray(int length) {
- return gen.createArray(length);
- }
-
- @Override
- public Iterable<E> order(List<E> insertionOrder) {
- return gen.order(insertionOrder);
- }
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/MultisetWritesTester.java b/guava-testlib/src/com/google/common/collect/testing/google/MultisetWritesTester.java
index cdf7710..9b91cb8 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/MultisetWritesTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/MultisetWritesTester.java
@@ -17,15 +17,16 @@
package com.google.common.collect.testing.google;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_CLEAR;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE_ALL;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_RETAIN_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multisets;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -40,31 +41,25 @@ import java.util.Iterator;
*
* @author Jared Levy
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
/**
* Returns the {@link Method} instance for
* {@link #testEntrySet_iterator()} so that tests of
* classes with unmodifiable iterators can suppress it.
*/
- @GwtIncompatible("reflection")
public static Method getEntrySetIteratorMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
MultisetWritesTester.class, "testEntrySet_iterator");
}
@CollectionFeature.Require(SUPPORTS_ADD)
- public void testAddOccurrencesZero() {
- int originalCount = getMultiset().count(samples.e0);
- assertEquals("old count", originalCount, getMultiset().add(samples.e0, 0));
- expectUnchanged();
- }
-
- @CollectionFeature.Require(SUPPORTS_ADD)
public void testAddOccurrences() {
- int originalCount = getMultiset().count(samples.e0);
- assertEquals("old count", originalCount, getMultiset().add(samples.e0, 2));
- assertEquals("old count", originalCount + 2, getMultiset().count(samples.e0));
+ int oldCount = getMultiset().count(samples.e0);
+ assertEquals("multiset.add(E, int) should return the old count",
+ oldCount, getMultiset().add(samples.e0, 2));
+ assertEquals("multiset.count() incorrect after add(E, int)",
+ oldCount + 2, getMultiset().count(samples.e0));
}
@CollectionFeature.Require(absent = SUPPORTS_ADD)
@@ -75,21 +70,6 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
} catch (UnsupportedOperationException required) {}
}
- @CollectionFeature.Require(SUPPORTS_ADD)
- public void testAdd_occurrences_negative() {
- try {
- getMultiset().add(samples.e0, -1);
- fail("multiset.add(E, -1) didn't throw an exception");
- } catch (IllegalArgumentException required) {}
- }
-
- @CollectionFeature.Require(SUPPORTS_REMOVE)
- public void testRemoveZeroNoOp() {
- int originalCount = getMultiset().count(samples.e0);
- assertEquals("old count", originalCount, getMultiset().remove(samples.e0, 0));
- expectUnchanged();
- }
-
@CollectionSize.Require(absent = ZERO)
@CollectionFeature.Require(SUPPORTS_REMOVE)
public void testRemove_occurrences_present() {
@@ -136,7 +116,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
0, getMultiset().remove(WrongType.VALUE, 1));
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_CLEAR)
public void testEntrySet_clear() {
getMultiset().entrySet().clear();
assertTrue("multiset not empty after entrySet().clear()",
@@ -200,7 +180,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
}
@CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
public void testEntrySet_removeAll_present() {
assertTrue(
"multiset.entrySet.removeAll(presentEntry) returned false",
@@ -212,7 +192,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
}
@CollectionSize.Require(absent = ZERO)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
public void testEntrySet_removeAll_missing() {
assertFalse(
"multiset.entrySet.remove(missingEntry) returned true",
@@ -223,7 +203,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
getMultiset().contains(samples.e0));
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
public void testEntrySet_removeAll_null() {
try {
getMultiset().entrySet().removeAll(null);
@@ -232,7 +212,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
}
@CollectionSize.Require(ONE)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
public void testEntrySet_retainAll_present() {
assertFalse(
"multiset.entrySet.retainAll(presentEntry) returned false",
@@ -244,7 +224,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
}
@CollectionSize.Require(ONE)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
public void testEntrySet_retainAll_missing() {
assertTrue(
"multiset.entrySet.retainAll(missingEntry) returned true",
@@ -255,7 +235,7 @@ public class MultisetWritesTester<E> extends AbstractMultisetTester<E> {
getMultiset().contains(samples.e0));
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
public void testEntrySet_retainAll_null() {
try {
getMultiset().entrySet().retainAll(null);
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/Platform.java b/guava-testlib/src/com/google/common/collect/testing/google/Platform.java
new file mode 100644
index 0000000..45b4166
--- /dev/null
+++ b/guava-testlib/src/com/google/common/collect/testing/google/Platform.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect.testing.google;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import java.lang.reflect.Method;
+
+/**
+ * Methods factored out so that they can be emulated in GWT.
+ *
+ * @author Hayward Chan
+ */
+@GwtCompatible
+class Platform {
+
+ @GwtIncompatible("Class.getMethod, java.lang.reflect.Method")
+ static Method getMethod(Class<?> clazz, String name) {
+ try {
+ return clazz.getMethod(name);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SetGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/SetGenerators.java
index 4e8273a..dee0d41 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/SetGenerators.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/SetGenerators.java
@@ -16,28 +16,19 @@
package com.google.common.collect.testing.google;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Sets.newTreeSet;
import static com.google.common.collect.testing.SampleElements.Strings.AFTER_LAST;
import static com.google.common.collect.testing.SampleElements.Strings.AFTER_LAST_2;
import static com.google.common.collect.testing.SampleElements.Strings.BEFORE_FIRST;
import static com.google.common.collect.testing.SampleElements.Strings.BEFORE_FIRST_2;
-import static junit.framework.Assert.assertEquals;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.ContiguousSet;
-import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
-import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import com.google.common.collect.testing.TestCollectionGenerator;
import com.google.common.collect.testing.TestCollidingSetGenerator;
-import com.google.common.collect.testing.TestIntegerSortedSetGenerator;
import com.google.common.collect.testing.TestSetGenerator;
import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.TestStringSetGenerator;
@@ -54,12 +45,12 @@ import java.util.SortedSet;
/**
* Generators of different types of sets and derived collections from sets.
- *
+ *
* @author Kevin Bourrillion
* @author Jared Levy
* @author Hayward Chan
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class SetGenerators {
public static class ImmutableSetCopyOfGenerator extends TestStringSetGenerator {
@@ -129,18 +120,6 @@ public class SetGenerators {
}
}
- @GwtIncompatible("NavigableSet")
- public static class ImmutableSortedSetDescendingGenerator
- extends TestStringSortedSetGenerator {
- @Override protected SortedSet<String> create(String[] elements) {
- return ImmutableSortedSet
- .<String>reverseOrder()
- .add(elements)
- .build()
- .descendingSet();
- }
- }
-
public static class ImmutableSortedSetExplicitComparator
extends TestStringSetGenerator {
@@ -231,20 +210,6 @@ public class SetGenerators {
}
}
- @GwtIncompatible("NavigableSet")
- public static class ImmutableSortedSetDescendingAsListGenerator
- extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- Comparator<String> comparator = createExplicitComparator(elements).reverse();
- return ImmutableSortedSet
- .orderedBy(comparator)
- .add(elements)
- .build()
- .descendingSet()
- .asList();
- }
- }
-
public static class ImmutableSortedSetAsListSubListGenerator
extends TestStringListGenerator {
@Override protected List<String> create(String[] elements) {
@@ -258,7 +223,7 @@ public class SetGenerators {
}
}
- public static class ImmutableSortedSetSubsetAsListSubListGenerator
+ public static class ImmutableSortedsetSubsetAsListSubListGenerator
extends TestStringListGenerator {
@Override protected List<String> create(String[] elements) {
Comparator<String> comparator = createExplicitComparator(elements);
@@ -280,7 +245,7 @@ public class SetGenerators {
implements TestSetGenerator<UnhashableObject> {
}
- private static Ordering<String> createExplicitComparator(
+ private static Comparator<String> createExplicitComparator(
String[] elements) {
// Collapse equal elements, which Ordering.explicit() doesn't support, while
// maintaining the ordering by first occurrence.
@@ -292,97 +257,4 @@ public class SetGenerators {
elementsPlus.add(AFTER_LAST_2);
return Ordering.explicit(Lists.newArrayList(elementsPlus));
}
-
- /*
- * All the ContiguousSet generators below manually reject nulls here. In principle, we'd like to
- * defer that to Range, since it's ContiguousSet.create() that's used to create the sets. However,
- * that gets messy here, and we already have null tests for Range.
- */
-
- /*
- * These generators also rely on consecutive integer inputs (not necessarily in order, but no
- * holes).
- */
-
- // SetCreationTester has some tests that pass in duplicates. Dedup them.
- private static <E extends Comparable<? super E>> SortedSet<E> nullCheckedTreeSet(E[] elements) {
- SortedSet<E> set = newTreeSet();
- for (E element : elements) {
- // Explicit null check because TreeSet wrongly accepts add(null) when empty.
- set.add(checkNotNull(element));
- }
- return set;
- }
-
- public static class ContiguousSetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- return checkedCreate(nullCheckedTreeSet(elements));
- }
- }
-
- public static class ContiguousSetHeadsetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- SortedSet<Integer> set = nullCheckedTreeSet(elements);
- int tooHigh = (set.isEmpty()) ? 0 : set.last() + 1;
- set.add(tooHigh);
- return checkedCreate(set).headSet(tooHigh);
- }
- }
-
- public static class ContiguousSetTailsetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- SortedSet<Integer> set = nullCheckedTreeSet(elements);
- int tooLow = (set.isEmpty()) ? 0 : set.first() - 1;
- set.add(tooLow);
- return checkedCreate(set).tailSet(tooLow + 1);
- }
- }
-
- public static class ContiguousSetSubsetGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- SortedSet<Integer> set = nullCheckedTreeSet(elements);
- if (set.isEmpty()) {
- /*
- * The (tooLow + 1, tooHigh) arguments below would be invalid because tooLow would be
- * greater than tooHigh.
- */
- return ContiguousSet.create(Range.openClosed(0, 1), DiscreteDomain.integers()).subSet(0, 1);
- }
- int tooHigh = set.last() + 1;
- int tooLow = set.first() - 1;
- set.add(tooHigh);
- set.add(tooLow);
- return checkedCreate(set).subSet(tooLow + 1, tooHigh);
- }
- }
-
- @GwtIncompatible("NavigableSet")
- public static class ContiguousSetDescendingGenerator extends AbstractContiguousSetGenerator {
- @Override protected SortedSet<Integer> create(Integer[] elements) {
- return checkedCreate(nullCheckedTreeSet(elements)).descendingSet();
- }
-
- /** Sorts the elements in reverse natural order. */
- @Override public List<Integer> order(List<Integer> insertionOrder) {
- Collections.sort(insertionOrder, Ordering.natural().reverse());
- return insertionOrder;
- }
- }
-
- private abstract static class AbstractContiguousSetGenerator
- extends TestIntegerSortedSetGenerator {
- protected final ContiguousSet<Integer> checkedCreate(SortedSet<Integer> elementsSet) {
- List<Integer> elements = newArrayList(elementsSet);
- /*
- * A ContiguousSet can't have holes. If a test demands a hole, it should be changed so that it
- * doesn't need one, or it should be suppressed for ContiguousSet.
- */
- for (int i = 0; i < elements.size() - 1; i++) {
- assertEquals(elements.get(i) + 1, (int) elements.get(i + 1));
- }
- Range<Integer> range =
- (elements.isEmpty()) ? Range.closedOpen(0, 0) : Range.encloseAll(elements);
- return ContiguousSet.create(range, DiscreteDomain.integers());
- }
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutAllTester.java b/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutAllTester.java
deleted file mode 100644
index bcc3d50..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutAllTester.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.copyToSet;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for {@link SetMultimap#replaceValues}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class SetMultimapPutAllTester<K, V>
- extends AbstractMultimapTester<K, V, SetMultimap<K, V>> {
-
- @MapFeature.Require(SUPPORTS_PUT)
- public void testReplaceValuesHandlesDuplicates() {
- V v0 = sampleValues().e3;
- V v1 = sampleValues().e2;
- @SuppressWarnings("unchecked")
- List<V> valuesToPut = Arrays.asList(v0, v1, v0);
-
- for (K k : sampleKeys()) {
- resetContainer();
-
- Set<V> expectedValues = copyToSet(multimap().get(k));
-
- multimap().putAll(k, valuesToPut);
- expectedValues.addAll(valuesToPut);
-
- assertGet(k, expectedValues);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutTester.java b/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutTester.java
deleted file mode 100644
index ade18b3..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapPutTester.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.Helpers.copyToList;
-import static com.google.common.collect.testing.Helpers.copyToSet;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Tests for {@link SetMultimap#replaceValues}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class SetMultimapPutTester<K, V>
- extends AbstractMultimapTester<K, V, SetMultimap<K, V>> {
- // Tests for non-duplicate values are in MultimapPutTester
-
- @MapFeature.Require(SUPPORTS_PUT)
- @CollectionSize.Require(absent = ZERO)
- public void testPutDuplicateValue() {
- List<Entry<K, V>> entries = copyToList(multimap().entries());
-
- for (Entry<K, V> entry : entries) {
- resetContainer();
- K k = entry.getKey();
- V v = entry.getValue();
-
- Set<V> values = multimap().get(k);
- Set<V> expectedValues = copyToSet(values);
-
- assertFalse(multimap().put(k, v));
- assertEquals(expectedValues, values);
- assertGet(k, expectedValues);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapReplaceValuesTester.java b/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapReplaceValuesTester.java
deleted file mode 100644
index fa95309..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapReplaceValuesTester.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.testing.features.MapFeature;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@link SetMultimap#replaceValues}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class SetMultimapReplaceValuesTester<K, V>
- extends AbstractMultimapTester<K, V, SetMultimap<K, V>> {
-
- @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
- public void testReplaceValuesHandlesDuplicates() {
- V v0 = sampleValues().e3;
- V v1 = sampleValues().e2;
- @SuppressWarnings("unchecked")
- List<V> values = Arrays.asList(v0, v1, v0);
-
- for (K k : sampleKeys()) {
- resetContainer();
- multimap().replaceValues(k, values);
- assertGet(k, v0, v1);
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapTestSuiteBuilder.java
deleted file mode 100644
index 9a81532..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/SetMultimapTestSuiteBuilder.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestSetGenerator;
-
-import junit.framework.TestSuite;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests
- * a {@code SetMultimap} implementation.
- *
- * @author Louis Wasserman
- */
-public class SetMultimapTestSuiteBuilder<K, V>
- extends MultimapTestSuiteBuilder<K, V, SetMultimap<K, V>> {
-
- public static <K, V> SetMultimapTestSuiteBuilder<K, V> using(
- TestSetMultimapGenerator<K, V> generator) {
- SetMultimapTestSuiteBuilder<K, V> result = new SetMultimapTestSuiteBuilder<K, V>();
- result.usingGenerator(generator);
- return result;
- }
-
- @Override protected List<Class<? extends AbstractTester>> getTesters() {
- List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
- testers.add(SetMultimapPutTester.class);
- testers.add(SetMultimapPutAllTester.class);
- testers.add(SetMultimapReplaceValuesTester.class);
- return testers;
- }
-
- @Override
- TestSuite computeMultimapGetTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ? extends
- OneSizeTestContainerGenerator<SetMultimap<K, V>, Entry<K, V>>> parentBuilder) {
- return SetTestSuiteBuilder.using(
- new MultimapGetGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".get[key]")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- @Override
- TestSuite computeEntriesTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ? extends
- OneSizeTestContainerGenerator<SetMultimap<K, V>, Map.Entry<K, V>>> parentBuilder) {
- return SetTestSuiteBuilder.using(
- new EntriesGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeEntriesFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".entries")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- private static class EntriesGenerator<K, V>
- extends MultimapTestSuiteBuilder.EntriesGenerator<K, V, SetMultimap<K, V>>
- implements TestSetGenerator<Entry<K, V>> {
-
- public EntriesGenerator(
- OneSizeTestContainerGenerator<SetMultimap<K, V>, Entry<K, V>> multimapGenerator) {
- super(multimapGenerator);
- }
-
- @Override
- public Set<Entry<K, V>> create(Object... elements) {
- return (Set<Entry<K, V>>) super.create(elements);
- }
- }
-
- private static class MultimapGetGenerator<K, V>
- extends MultimapTestSuiteBuilder.MultimapGetGenerator<K, V, SetMultimap<K, V>>
- implements TestSetGenerator<V> {
- public MultimapGetGenerator(
- OneSizeTestContainerGenerator<SetMultimap<K, V>, Entry<K, V>> multimapGenerator) {
- super(multimapGenerator);
- }
-
- @Override
- public Set<V> create(Object... elements) {
- return (Set<V>) super.create(elements);
- }
-
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SortedMapGenerators.java b/guava-testlib/src/com/google/common/collect/testing/google/SortedMapGenerators.java
index e37ae5f..6ce5a77 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/SortedMapGenerators.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/SortedMapGenerators.java
@@ -17,19 +17,21 @@
package com.google.common.collect.testing.google;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.testing.Helpers.mapEntry;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.Ordering;
+import com.google.common.collect.ImmutableSortedMap.Builder;
import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestListGenerator;
-import com.google.common.collect.testing.TestStringListGenerator;
-import com.google.common.collect.testing.TestStringSortedMapGenerator;
+import com.google.common.collect.testing.TestCollectionGenerator;
+import com.google.common.collect.testing.TestMapEntrySetGenerator;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
-import java.util.SortedMap;
+import java.util.Set;
/**
* Generators of sorted maps and derived collections.
@@ -38,85 +40,160 @@ import java.util.SortedMap;
* @author Jesse Wilson
* @author Jared Levy
* @author Hayward Chan
- * @author Chris Povirk
- * @author Louis Wasserman
*/
@GwtCompatible
public class SortedMapGenerators {
- public static class ImmutableSortedMapGenerator extends TestStringSortedMapGenerator {
- @Override public SortedMap<String, String> create(Entry<String, String>[] entries) {
- ImmutableSortedMap.Builder<String, String> builder = ImmutableSortedMap.naturalOrder();
- for (Entry<String, String> entry : entries) {
- checkNotNull(entry);
- builder.put(entry.getKey(), entry.getValue());
+
+ public static final Comparator<Entry<String, String>> ENTRY_COMPARATOR
+ = new Comparator<Entry<String, String>>() {
+ @Override
+ public int compare(
+ Entry<String, String> o1, Entry<String, String> o2) {
+ return o1.getKey().compareTo(o2.getKey());
+ }
+ };
+
+ public static class ImmutableSortedMapKeySetGenerator
+ extends TestStringSetGenerator {
+
+ @Override protected Set<String> create(String[] elements) {
+ Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder();
+ for (String key : elements) {
+ builder.put(key, 4);
}
- return builder.build();
+ return builder.build().keySet();
+ }
+ @Override public List<String> order(List<String> insertionOrder) {
+ Collections.sort(insertionOrder);
+ return insertionOrder;
}
}
- public static class ImmutableSortedMapEntryListGenerator
- implements TestListGenerator<Entry<String, Integer>> {
+ public static class ImmutableSortedMapValuesGenerator
+ implements TestCollectionGenerator<String> {
@Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- mapEntry("foo", 5),
- mapEntry("bar", 3),
- mapEntry("baz", 17),
- mapEntry("quux", 1),
- mapEntry("toaster", -2));
+ public SampleElements<String> samples() {
+ return new SampleElements.Strings();
}
- @SuppressWarnings("unchecked")
@Override
- public Entry<String, Integer>[] createArray(int length) {
- return new Entry[length];
+ public Collection<String> create(Object... elements) {
+ Builder<Integer, String> builder = ImmutableSortedMap.naturalOrder();
+ for (int i = 0; i < elements.length; i++) {
+ builder.put(i, toStringOrNull(elements[i]));
+ }
+ return builder.build().values();
}
@Override
- public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) {
- return new Ordering<Entry<String, Integer>>() {
- @Override
- public int compare(Entry<String, Integer> left, Entry<String, Integer> right) {
- return left.getKey().compareTo(right.getKey());
- }
- }.sortedCopy(insertionOrder);
+ public String[] createArray(int length) {
+ return new String[length];
}
@Override
- public List<Entry<String, Integer>> create(Object... elements) {
- ImmutableSortedMap.Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) o;
- builder.put(entry);
+ public List<String> order(List<String> insertionOrder) {
+ return insertionOrder;
+ }
+ }
+
+ public static class ImmutableSortedMapSubMapEntryGenerator
+ extends TestMapEntrySetGenerator<String, String> {
+
+ public ImmutableSortedMapSubMapEntryGenerator() {
+ super(new SampleElements.Strings(), new SampleElements.Strings());
+ }
+
+ @Override public Set<Entry<String, String>> createFromEntries(
+ Entry<String, String>[] entries) {
+ Builder<String, String> builder = ImmutableSortedMap.naturalOrder();
+ builder.put(SampleElements.Strings.BEFORE_FIRST, "begin");
+ builder.put(SampleElements.Strings.AFTER_LAST, "end");
+ for (Entry<String, String> entry : entries) {
+ checkNotNull(entry);
+ builder.put(entry.getKey(), entry.getValue());
+ }
+ return builder.build().subMap(SampleElements.Strings.MIN_ELEMENT,
+ SampleElements.Strings.AFTER_LAST).entrySet();
+ }
+ @Override public List<Entry<String, String>> order(
+ List<Entry<String, String>> insertionOrder) {
+ Collections.sort(insertionOrder, ENTRY_COMPARATOR);
+ return insertionOrder;
+ }
+ }
+
+ public static class ImmutableSortedMapHeadMapKeySetGenerator
+ extends TestStringSetGenerator {
+ @Override protected Set<String> create(String[] elements) {
+ Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder();
+ builder.put(SampleElements.Strings.AFTER_LAST, -1);
+ for (String key : elements) {
+ builder.put(key, 4);
}
- return builder.build().entrySet().asList();
+ return builder.build().headMap(
+ SampleElements.Strings.AFTER_LAST).keySet();
+ }
+ @Override public List<String> order(List<String> insertionOrder) {
+ Collections.sort(insertionOrder);
+ return insertionOrder;
}
}
- public static class ImmutableSortedMapKeyListGenerator extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- ImmutableSortedMap.Builder<String, Integer> builder = ImmutableSortedMap.naturalOrder();
+ public static class ImmutableSortedMapTailMapValuesGenerator
+ implements TestCollectionGenerator<String> {
+
+ @Override
+ public SampleElements<String> samples() {
+ return new SampleElements.Strings();
+ }
+
+ @Override
+ public Collection<String> create(Object... elements) {
+ Builder<Integer, String> builder = ImmutableSortedMap.naturalOrder();
+ builder.put(-1, "begin");
for (int i = 0; i < elements.length; i++) {
- builder.put(elements[i], i);
+ builder.put(i, toStringOrNull(elements[i]));
}
- return builder.build().keySet().asList();
+ return builder.build().tailMap(0).values();
+ }
+
+ @Override
+ public String[] createArray(int length) {
+ return new String[length];
}
@Override
public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
+ return insertionOrder;
}
}
- public static class ImmutableSortedMapValueListGenerator extends TestStringListGenerator {
- @Override protected List<String> create(String[] elements) {
- ImmutableSortedMap.Builder<Integer, String> builder = ImmutableSortedMap.naturalOrder();
- for (int i = 0; i < elements.length; i++) {
- builder.put(i, elements[i]);
+ public static class ImmutableSortedMapEntrySetGenerator
+ extends TestMapEntrySetGenerator<String, String> {
+
+ public ImmutableSortedMapEntrySetGenerator() {
+ super(new SampleElements.Strings(), new SampleElements.Strings());
+ }
+
+ @Override public Set<Entry<String, String>> createFromEntries(
+ Entry<String, String>[] entries) {
+ Builder<String, String> builder = ImmutableSortedMap.naturalOrder();
+ for (Entry<String, String> entry : entries) {
+ checkNotNull(entry);
+ builder.put(entry.getKey(), entry.getValue());
}
- return builder.build().values().asList();
+ return builder.build().entrySet();
+ }
+
+ @Override public List<Entry<String, String>> order(
+ List<Entry<String, String>> insertionOrder) {
+ Collections.sort(insertionOrder, ENTRY_COMPARATOR);
+ return insertionOrder;
}
}
+
+ private static String toStringOrNull(Object o) {
+ return (o == null) ? null : o.toString();
+ }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java
index af79cc2..547ab97 100644
--- a/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java
+++ b/guava-testlib/src/com/google/common/collect/testing/google/SortedMultisetTestSuiteBuilder.java
@@ -1,12 +1,12 @@
/*
- * Copyright (C) 2011 The Guava Authors
- *
+ * Copyright (C) 2011 Google Inc.
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,40 +16,36 @@
package com.google.common.collect.testing.google;
+import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.BoundType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Multiset;
import com.google.common.collect.SortedMultiset;
import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SortedSetTestSuiteBuilder;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.Feature;
-import com.google.common.testing.SerializableTester;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Creates, based on your criteria, a JUnit test suite that exhaustively tests a
* {@code SortedMultiset} implementation.
- *
+ *
* <p><b>Warning</b>: expects that {@code E} is a String.
- *
+ *
* @author Louis Wasserman
*/
+@GwtCompatible
public class SortedMultisetTestSuiteBuilder<E> extends
MultisetTestSuiteBuilder<E> {
public static <E> SortedMultisetTestSuiteBuilder<E> using(
@@ -62,7 +58,6 @@ public class SortedMultisetTestSuiteBuilder<E> extends
@Override
public TestSuite createTestSuite() {
- withFeatures(CollectionFeature.KNOWN_ORDER);
TestSuite suite = super.createTestSuite();
for (TestSuite subSuite : createDerivedSuites(this)) {
suite.addTest(subSuite);
@@ -78,17 +73,6 @@ public class SortedMultisetTestSuiteBuilder<E> extends
return testers;
}
- @Override
- TestSuite createElementSetTestSuite(FeatureSpecificTestSuiteBuilder<
- ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
- return SortedSetTestSuiteBuilder
- .using(new ElementSetGenerator<E>(parentBuilder.getSubjectGenerator()))
- .named(getName() + ".elementSet")
- .withFeatures(computeElementSetFeatures(parentBuilder.getFeatures()))
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
/**
* To avoid infinite recursion, test suites with these marker features won't
* have derived suites created for them.
@@ -117,10 +101,6 @@ public class SortedMultisetTestSuiteBuilder<E> extends
derivedSuites.add(createDescendingSuite(parentBuilder));
}
- if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
- derivedSuites.add(createReserializedSuite(parentBuilder));
- }
-
if (!parentBuilder.getFeatures().contains(NoRecurse.SUBMULTISET)) {
derivedSuites.add(createSubMultisetSuite(parentBuilder, Bound.NO_BOUND,
Bound.EXCLUSIVE));
@@ -149,15 +129,11 @@ public class SortedMultisetTestSuiteBuilder<E> extends
final TestMultisetGenerator<E> delegate =
(TestMultisetGenerator<E>) parentBuilder.getSubjectGenerator();
- Set<Feature<?>> features = new HashSet<Feature<?>>();
+ List<Feature<?>> features = new ArrayList<Feature<?>>();
features.add(NoRecurse.SUBMULTISET);
features.add(CollectionFeature.RESTRICTS_ELEMENTS);
features.addAll(parentBuilder.getFeatures());
- if (!features.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- features.remove(CollectionFeature.SERIALIZABLE);
- }
-
SortedMultiset<E> emptyMultiset = (SortedMultiset<E>) delegate.create();
final Comparator<? super E> comparator = emptyMultiset.comparator();
SampleElements<E> samples = delegate.samples();
@@ -228,7 +204,7 @@ public class SortedMultisetTestSuiteBuilder<E> extends
/**
* Returns an array of four bogus elements that will always be too high or too
* low for the display. This includes two values for each extreme.
- *
+ *
* <p>
* This method (dangerously) assume that the strings {@code "!! a"} and
* {@code "~~ z"} will work for this purpose, which may cause problems for
@@ -248,12 +224,9 @@ public class SortedMultisetTestSuiteBuilder<E> extends
final TestMultisetGenerator<E> delegate =
(TestMultisetGenerator<E>) parentBuilder.getSubjectGenerator();
- Set<Feature<?>> features = new HashSet<Feature<?>>();
+ List<Feature<?>> features = new ArrayList<Feature<?>>();
features.add(NoRecurse.DESCENDING);
features.addAll(parentBuilder.getFeatures());
- if (!features.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) {
- features.remove(CollectionFeature.SERIALIZABLE);
- }
return SortedMultisetTestSuiteBuilder
.using(new ForwardingTestMultisetGenerator<E>(delegate) {
@@ -274,29 +247,6 @@ public class SortedMultisetTestSuiteBuilder<E> extends
.createTestSuite();
}
- private TestSuite createReserializedSuite(
- SortedMultisetTestSuiteBuilder<E> parentBuilder) {
- final TestMultisetGenerator<E> delegate =
- (TestMultisetGenerator<E>) parentBuilder.getSubjectGenerator();
-
- Set<Feature<?>> features = new HashSet<Feature<?>>();
- features.addAll(parentBuilder.getFeatures());
- features.remove(CollectionFeature.SERIALIZABLE);
- features.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
-
- return SortedMultisetTestSuiteBuilder
- .using(new ForwardingTestMultisetGenerator<E>(delegate) {
- @Override
- public SortedMultiset<E> create(Object... entries) {
- return SerializableTester.reserialize(((SortedMultiset<E>) super.create(entries)));
- }
- })
- .named(parentBuilder.getName() + " reserialized")
- .withFeatures(features)
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
private static class ForwardingTestMultisetGenerator<E>
implements TestMultisetGenerator<E> {
private final TestMultisetGenerator<E> delegate;
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapGetTester.java b/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapGetTester.java
deleted file mode 100644
index ee703d8..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapGetTester.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.SortedSetMultimap;
-
-/**
- * Tester for {@link SortedSetMultimap#get(Object)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class SortedSetMultimapGetTester<K, V>
- extends AbstractMultimapTester<K, V, SortedSetMultimap<K, V>> {
- public void testValueComparator() {
- assertEquals(
- multimap().valueComparator(),
- multimap().get(sampleKeys().e0).comparator());
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapTestSuiteBuilder.java b/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapTestSuiteBuilder.java
deleted file mode 100644
index 268069e..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/SortedSetMultimapTestSuiteBuilder.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.testing.AbstractTester;
-import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.OneSizeTestContainerGenerator;
-import com.google.common.collect.testing.SortedSetTestSuiteBuilder;
-import com.google.common.collect.testing.TestSetGenerator;
-
-import junit.framework.TestSuite;
-
-import java.util.Map.Entry;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Creates, based on your criteria, a JUnit test suite that exhaustively tests
- * a {@code SortedSetMultimap} implementation.
- *
- * @author Louis Wasserman
- */
-public class SortedSetMultimapTestSuiteBuilder<K, V>
- extends MultimapTestSuiteBuilder<K, V, SetMultimap<K, V>> {
-
- public static <K, V> SortedSetMultimapTestSuiteBuilder<K, V> using(
- TestSetMultimapGenerator<K, V> generator) {
- SortedSetMultimapTestSuiteBuilder<K, V> result = new SortedSetMultimapTestSuiteBuilder<K, V>();
- result.usingGenerator(generator);
- return result;
- }
-
- @Override protected List<Class<? extends AbstractTester>> getTesters() {
- List<Class<? extends AbstractTester>> testers = Helpers.copyToList(super.getTesters());
- testers.add(SetMultimapPutTester.class);
- testers.add(SetMultimapPutAllTester.class);
- testers.add(SetMultimapReplaceValuesTester.class);
- testers.add(SortedSetMultimapGetTester.class);
- return testers;
- }
-
- @Override
- TestSuite computeMultimapGetTestSuite(
- FeatureSpecificTestSuiteBuilder<?, ? extends
- OneSizeTestContainerGenerator<SetMultimap<K, V>, Entry<K, V>>> parentBuilder) {
- return SortedSetTestSuiteBuilder.using(
- new MultimapGetGenerator<K, V>(parentBuilder.getSubjectGenerator()))
- .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures()))
- .named(parentBuilder.getName() + ".get[key]")
- .suppressing(parentBuilder.getSuppressedTests())
- .createTestSuite();
- }
-
- private static class MultimapGetGenerator<K, V>
- extends MultimapTestSuiteBuilder.MultimapGetGenerator<K, V, SetMultimap<K, V>>
- implements TestSetGenerator<V> {
- public MultimapGetGenerator(
- OneSizeTestContainerGenerator<SetMultimap<K, V>, Entry<K, V>> multimapGenerator) {
- super(multimapGenerator);
- }
-
- @Override
- public Set<V> create(Object... elements) {
- return (Set<V>) super.create(elements);
- }
-
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestBiMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestBiMapGenerator.java
deleted file mode 100644
index a8999e4..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestBiMapGenerator.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.TestContainerGenerator;
-
-import java.util.Map;
-
-/**
- * Creates bimaps, containing sample entries, to be tested.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public interface TestBiMapGenerator<K, V>
- extends TestContainerGenerator<BiMap<K, V>, Map.Entry<K, V>> {
- K[] createKeyArray(int length);
-
- V[] createValueArray(int length);
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestListMultimapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestListMultimapGenerator.java
deleted file mode 100644
index ffc6ab2..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestListMultimapGenerator.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-
-/**
- * A generator for {@code ListMultimap} implementations based on test data.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public interface TestListMultimapGenerator<K, V>
- extends TestMultimapGenerator<K, V, ListMultimap<K, V>> {
-
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestMultimapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestMultimapGenerator.java
deleted file mode 100644
index fe97023..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestMultimapGenerator.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestContainerGenerator;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Creates multimaps, containing sample elements, to be tested.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public interface TestMultimapGenerator<K, V, M extends Multimap<K, V>>
- extends TestContainerGenerator<M, Map.Entry<K, V>> {
-
- K[] createKeyArray(int length);
-
- V[] createValueArray(int length);
-
- SampleElements<K> sampleKeys();
-
- SampleElements<V> sampleValues();
-
- Collection<V> createCollection(Iterable<? extends V> values);
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestSetMultimapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestSetMultimapGenerator.java
deleted file mode 100644
index 8b31084..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestSetMultimapGenerator.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.SetMultimap;
-
-/**
- * A generator for {@code SetMultimap} implementations based on test data.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public interface TestSetMultimapGenerator<K, V>
- extends TestMultimapGenerator<K, V, SetMultimap<K, V>> {
-
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestStringBiMapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestStringBiMapGenerator.java
deleted file mode 100644
index 30f1452..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestStringBiMapGenerator.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.SampleElements;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Implementation helper for {@link TestBiMapGenerator} for use with bimaps of
- * strings.
- *
- * <p>This class is GWT compatible.
- *
- * @author Chris Povirk
- * @author Jared Levy
- * @author George van den Driessche
- * @author Louis Wasserman
- */
-@GwtCompatible
-public abstract class TestStringBiMapGenerator
- implements TestBiMapGenerator<String, String> {
-
- @Override
- public SampleElements<Map.Entry<String, String>> samples() {
- return new SampleElements<Map.Entry<String, String>>(
- Helpers.mapEntry("one", "January"),
- Helpers.mapEntry("two", "February"),
- Helpers.mapEntry("three", "March"),
- Helpers.mapEntry("four", "April"),
- Helpers.mapEntry("five", "May")
- );
- }
-
- @Override
- public final BiMap<String, String> create(Object... entries) {
- @SuppressWarnings("unchecked")
- Entry<String, String>[] array = new Entry[entries.length];
- int i = 0;
- for (Object o : entries) {
- @SuppressWarnings("unchecked")
- Entry<String, String> e = (Entry<String, String>) o;
- array[i++] = e;
- }
- return create(array);
- }
-
- protected abstract BiMap<String, String> create(
- Entry<String, String>[] entries);
-
- @Override
- @SuppressWarnings("unchecked")
- public final Entry<String, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public final String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public final String[] createValueArray(int length) {
- return new String[length];
- }
-
- /** Returns the original element list, unchanged. */
- @Override
- public Iterable<Entry<String, String>> order(
- List<Entry<String, String>> insertionOrder) {
- return insertionOrder;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestStringListMultimapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestStringListMultimapGenerator.java
deleted file mode 100644
index 4f99879..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestStringListMultimapGenerator.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.SampleElements;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * A skeleton generator for a {@code ListMultimap} implementation.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public abstract class TestStringListMultimapGenerator
- implements TestListMultimapGenerator<String, String> {
-
- @Override
- public SampleElements<Map.Entry<String, String>> samples() {
- return new SampleElements<Map.Entry<String, String>>(
- Helpers.mapEntry("one", "January"),
- Helpers.mapEntry("two", "February"),
- Helpers.mapEntry("three", "March"),
- Helpers.mapEntry("four", "April"),
- Helpers.mapEntry("five", "May"));
- }
-
- @Override
- public SampleElements<String> sampleKeys() {
- return new SampleElements<String>("one", "two", "three", "four", "five");
- }
-
- @Override
- public SampleElements<String> sampleValues() {
- return new SampleElements<String>("January", "February", "March", "April", "May");
- }
-
- @Override
- public Collection<String> createCollection(Iterable<? extends String> values) {
- return Helpers.copyToList(values);
- }
-
- @Override
- public final ListMultimap<String, String> create(Object... entries) {
- @SuppressWarnings("unchecked")
- Entry<String, String>[] array = new Entry[entries.length];
- int i = 0;
- for (Object o : entries) {
- @SuppressWarnings("unchecked")
- Entry<String, String> e = (Entry<String, String>) o;
- array[i++] = e;
- }
- return create(array);
- }
-
- protected abstract ListMultimap<String, String> create(
- Entry<String, String>[] entries);
-
- @Override
- @SuppressWarnings("unchecked")
- public final Entry<String, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public final String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public final String[] createValueArray(int length) {
- return new String[length];
- }
-
- /** Returns the original element list, unchanged. */
- @Override
- public Iterable<Entry<String, String>> order(
- List<Entry<String, String>> insertionOrder) {
- return insertionOrder;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/google/TestStringSetMultimapGenerator.java b/guava-testlib/src/com/google/common/collect/testing/google/TestStringSetMultimapGenerator.java
deleted file mode 100644
index f49d4f0..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/google/TestStringSetMultimapGenerator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect.testing.google;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.SampleElements;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * A skeleton generator for a {@code SetMultimap} implementation.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public abstract class TestStringSetMultimapGenerator
- implements TestSetMultimapGenerator<String, String> {
-
- @Override
- public SampleElements<Map.Entry<String, String>> samples() {
- return new SampleElements<Map.Entry<String, String>>(
- Helpers.mapEntry("one", "January"),
- Helpers.mapEntry("two", "February"),
- Helpers.mapEntry("three", "March"),
- Helpers.mapEntry("four", "April"),
- Helpers.mapEntry("five", "May"));
- }
-
- @Override
- public SampleElements<String> sampleKeys() {
- return new SampleElements<String>("one", "two", "three", "four", "five");
- }
-
- @Override
- public SampleElements<String> sampleValues() {
- return new SampleElements<String>("January", "February", "March", "April", "May");
- }
-
- @Override
- public Collection<String> createCollection(Iterable<? extends String> values) {
- return Helpers.copyToSet(values);
- }
-
- @Override
- public final SetMultimap<String, String> create(Object... entries) {
- @SuppressWarnings("unchecked")
- Entry<String, String>[] array = new Entry[entries.length];
- int i = 0;
- for (Object o : entries) {
- @SuppressWarnings("unchecked")
- Entry<String, String> e = (Entry<String, String>) o;
- array[i++] = e;
- }
- return create(array);
- }
-
- protected abstract SetMultimap<String, String> create(
- Entry<String, String>[] entries);
-
- @Override
- @SuppressWarnings("unchecked")
- public final Entry<String, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public final String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public final String[] createValueArray(int length) {
- return new String[length];
- }
-
- /** Returns the original element list, unchanged. */
- @Override
- public Iterable<Entry<String, String>> order(
- List<Entry<String, String>> insertionOrder) {
- return insertionOrder;
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListIndexOfTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListIndexOfTester.java
index 21fff11..af960a5 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListIndexOfTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListIndexOfTester.java
@@ -19,7 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -32,7 +31,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Chris Povirk
*/
-@GwtCompatible
public abstract class AbstractListIndexOfTester<E>
extends AbstractListTester<E> {
/** Override to call {@code indexOf()} or {@code lastIndexOf()}. */
@@ -47,7 +45,7 @@ public abstract class AbstractListIndexOfTester<E>
@CollectionSize.Require(absent = ZERO)
public void testFind_yes() {
assertEquals(getMethodName() + "(firstElement) should return 0",
- 0, find(getOrderedElements().get(0)));
+ 0, find(samples.e0));
}
public void testFind_no() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListTester.java
index 5bebdb3..268022d 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractListTester.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.Helpers;
@@ -30,7 +29,6 @@ import java.util.List;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class AbstractListTester<E> extends AbstractCollectionTester<E> {
/*
* Previously we had a field named list that was initialized to the value of
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractQueueTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractQueueTester.java
index dd6a260..5f7477c 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractQueueTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractQueueTester.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import java.util.Queue;
@@ -28,7 +27,6 @@ import java.util.Queue;
*
* @author Jared Levy
*/
-@GwtCompatible
public class AbstractQueueTester<E> extends AbstractCollectionTester<E> {
protected final Queue<E> getQueue() {
return (Queue<E>) collection;
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractSetTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractSetTester.java
index 544373e..76a5326 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/AbstractSetTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/AbstractSetTester.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import java.util.Set;
@@ -26,7 +25,6 @@ import java.util.Set;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class AbstractSetTester<E> extends AbstractCollectionTester<E> {
/*
* Previously we had a field named set that was initialized to the value of
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddAllTester.java
index 38d5261..b5e3085 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddAllTester.java
@@ -17,23 +17,17 @@
package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static java.util.Collections.singletonList;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import java.lang.reflect.Method;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
import java.util.List;
/**
@@ -47,16 +41,15 @@ import java.util.List;
* @author Kevin Bourrillion
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
public void testAddAll_supportedNothing() {
assertFalse("addAll(nothing) should return false",
collection.addAll(emptyCollection()));
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
+ @CollectionFeature.Require(absent = SUPPORTS_ADD_ALL)
public void testAddAll_unsupportedNothing() {
try {
assertFalse("addAll(nothing) should return false or throw",
@@ -66,14 +59,14 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
public void testAddAll_supportedNonePresent() {
assertTrue("addAll(nonePresent) should return true",
collection.addAll(createDisjointCollection()));
expectAdded(samples.e3, samples.e4);
}
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
+ @CollectionFeature.Require(absent = SUPPORTS_ADD_ALL)
public void testAddAll_unsupportedNonePresent() {
try {
collection.addAll(createDisjointCollection());
@@ -84,7 +77,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e3, samples.e4);
}
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_supportedSomePresent() {
assertTrue("addAll(somePresent) should return true",
@@ -93,7 +86,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
assertTrue("should contain " + samples.e0, collection.contains(samples.e0));
}
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
+ @CollectionFeature.Require(absent = SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_unsupportedSomePresent() {
try {
@@ -104,21 +97,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(absent = ZERO)
- public void testAddAllConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertTrue(collection.addAll(MinimalCollection.of(samples.e3, samples.e0)));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
+ @CollectionFeature.Require(absent = SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_unsupportedAllPresent() {
try {
@@ -129,7 +108,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require(value = {SUPPORTS_ADD,
+ @CollectionFeature.Require(value = {SUPPORTS_ADD_ALL,
ALLOWS_NULL_VALUES}, absent = RESTRICTS_ELEMENTS)
public void testAddAll_nullSupported() {
List<E> containsNull = singletonList(null);
@@ -142,7 +121,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
expectAdded((E) null);
}
- @CollectionFeature.Require(value = SUPPORTS_ADD,
+ @CollectionFeature.Require(value = SUPPORTS_ADD_ALL,
absent = ALLOWS_NULL_VALUES)
public void testAddAll_nullUnsupported() {
List<E> containsNull = singletonList(null);
@@ -156,7 +135,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
"Should not contain null after unsupported addAll(containsNull)");
}
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
public void testAddAll_nullCollectionReference() {
try {
collection.addAll(null);
@@ -172,8 +151,7 @@ public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun
* bug 5045147</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getAddAllNullUnsupportedMethod() {
- return Helpers.getMethod(CollectionAddAllTester.class, "testAddAll_nullUnsupported");
+ return Platform.getMethod(CollectionAddAllTester.class, "testAddAll_nullUnsupported");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddTester.java
index afe276b..1de5b14 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionAddTester.java
@@ -17,21 +17,15 @@
package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import java.lang.reflect.Method;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
/**
* A generic JUnit test which tests {@code add} operations on a collection.
@@ -44,7 +38,6 @@ import java.util.Iterator;
* @author Kevin Bourrillion
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class CollectionAddTester<E> extends AbstractCollectionTester<E> {
@CollectionFeature.Require(SUPPORTS_ADD)
public void testAdd_supportedNotPresent() {
@@ -96,20 +89,6 @@ public class CollectionAddTester<E> extends AbstractCollectionTester<E> {
"Should not contain null after unsupported add(null)");
}
- @CollectionFeature.Require({SUPPORTS_ADD,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(absent = ZERO)
- public void testAddConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertTrue(collection.add(samples.e3));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
/**
* Returns the {@link Method} instance for {@link #testAdd_nullSupported()} so
* that tests of {@link
@@ -122,20 +101,20 @@ public class CollectionAddTester<E> extends AbstractCollectionTester<E> {
* seems more likely that code would depend on that behavior than on the
* other. Thus, we say the bug is in add(), which fails to support null.
*/
- @GwtIncompatible("reflection")
public static Method getAddNullSupportedMethod() {
- return Helpers.getMethod(CollectionAddTester.class, "testAdd_nullSupported");
+ return Platform.getMethod(CollectionAddTester.class, "testAdd_nullSupported");
}
/**
- * Returns the {@link Method} instance for {@link #testAdd_nullSupported()}
- * so that tests of {@link java.util.TreeSet} can suppress it with {@code
- * FeatureSpecificTestSuiteBuilder.suppressing()} until <a
- * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun bug
- * 5045147</a> is fixed.
+ * Returns the {@link Method} instance for {@link #testAdd_nullSupported()} so
+ * that tests of {@link
+ * java.util.Collections#checkedCollection(java.util.Collection, Class)} can
+ * suppress it with {@code FeatureSpecificTestSuiteBuilder.suppressing()}
+ * until <a
+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun
+ * bug 5045147</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getAddNullUnsupportedMethod() {
- return Helpers.getMethod(CollectionAddTester.class, "testAdd_nullUnsupported");
+ return Platform.getMethod(CollectionAddTester.class, "testAdd_nullUnsupported");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionClearTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionClearTester.java
index a417e55..69f1d02 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionClearTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionClearTester.java
@@ -16,19 +16,13 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_CLEAR;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-
/**
* A generic JUnit test which tests {@code clear()} operations on a collection.
* Can't be invoked directly; please see
@@ -38,16 +32,15 @@ import java.util.Iterator;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class CollectionClearTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_CLEAR)
public void testClear() {
collection.clear();
assertTrue("After clear(), a collection should be empty.",
collection.isEmpty());
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_CLEAR)
@CollectionSize.Require(absent = ZERO)
public void testClear_unsupported() {
try {
@@ -59,7 +52,7 @@ public class CollectionClearTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_CLEAR)
@CollectionSize.Require(ZERO)
public void testClear_unsupportedByEmptyCollection() {
try {
@@ -68,22 +61,4 @@ public class CollectionClearTester<E> extends AbstractCollectionTester<E> {
}
expectUnchanged();
}
-
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(SEVERAL)
- public void testClearConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- collection.clear();
- iterator.next();
- /*
- * We prefer for iterators to fail immediately on hasNext, but ArrayList
- * and LinkedList will notably return true on hasNext here!
- */
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsAllTester.java
index 4fd424b..40be02b 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsAllTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.ALLOW
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.WrongType;
@@ -40,7 +39,6 @@ import java.util.Collection;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class CollectionContainsAllTester<E>
extends AbstractCollectionTester<E> {
public void testContainsAll_empty() {
@@ -87,7 +85,6 @@ public class CollectionContainsAllTester<E>
}
@CollectionFeature.Require(ALLOWS_NULL_VALUES)
- @CollectionSize.Require(absent = ZERO)
public void testContainsAll_nullPresent() {
initCollectionWithNullElement();
assertTrue(collection.containsAll(MinimalCollection.of((E) null)));
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsTester.java
index e8f754a..49337c3 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionContainsTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.ALLOW
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -36,7 +35,6 @@ import com.google.common.collect.testing.features.CollectionSize;
* @author Kevin Bourrillion
* @author Chris Povirk
*/
-@GwtCompatible
public class CollectionContainsTester<E> extends AbstractCollectionTester<E> {
@CollectionSize.Require(absent = ZERO)
public void testContains_yes() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionCreationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionCreationTester.java
index 3e7499c..401a0f2 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionCreationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionCreationTester.java
@@ -19,10 +19,7 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -37,7 +34,6 @@ import java.lang.reflect.Method;
*
* @author Chris Povirk
*/
-@GwtCompatible(emulated = true)
public class CollectionCreationTester<E> extends AbstractCollectionTester<E> {
@CollectionFeature.Require(ALLOWS_NULL_VALUES)
@CollectionSize.Require(absent = ZERO)
@@ -66,8 +62,7 @@ public class CollectionCreationTester<E> extends AbstractCollectionTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun
* bug 5045147</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getCreateWithNullUnsupportedMethod() {
- return Helpers.getMethod(CollectionCreationTester.class, "testCreateWithNull_unsupported");
+ return Platform.getMethod(CollectionCreationTester.class, "testCreateWithNull_unsupported");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionEqualsTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionEqualsTester.java
index c59db0a..fe642fc 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionEqualsTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionEqualsTester.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
/**
@@ -26,7 +25,6 @@ import com.google.common.collect.testing.AbstractCollectionTester;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class CollectionEqualsTester<E> extends AbstractCollectionTester<E> {
public void testEquals_self() {
assertTrue("An Object should be equal to itself.",
@@ -45,4 +43,4 @@ public class CollectionEqualsTester<E> extends AbstractCollectionTester<E> {
+ "object that is not a Collection.",
collection.equals("huh?"));
}
-}
+} \ No newline at end of file
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIsEmptyTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIsEmptyTester.java
index 94e2c13..8d11f42 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIsEmptyTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIsEmptyTester.java
@@ -18,7 +18,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.features.CollectionSize;
@@ -31,7 +30,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class CollectionIsEmptyTester<E> extends AbstractCollectionTester<E> {
@CollectionSize.Require(ZERO)
public void testIsEmpty_yes() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java
index 6a8d567..3e54cfc 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionIteratorTester.java
@@ -21,8 +21,6 @@ import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.IteratorFeature;
@@ -48,7 +46,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
*
* @author Chris Povirk
*/
-@GwtCompatible(emulated = true)
public class CollectionIteratorTester<E> extends AbstractCollectionTester<E> {
public void testIterator() {
List<E> iteratorElements = new ArrayList<E>();
@@ -123,9 +120,8 @@ public class CollectionIteratorTester<E> extends AbstractCollectionTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570575">Sun bug
* 6570575</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getIteratorKnownOrderRemoveSupportedMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
CollectionIteratorTester.class, "testIterator_knownOrderRemoveSupported");
}
@@ -134,9 +130,8 @@ public class CollectionIteratorTester<E> extends AbstractCollectionTester<E> {
* {@link #testIterator_unknownOrderRemoveSupported()} so that tests of
* classes with unmodifiable iterators can suppress it.
*/
- @GwtIncompatible("reflection")
public static Method getIteratorUnknownOrderRemoveSupportedMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
CollectionIteratorTester.class, "testIterator_unknownOrderRemoveSupported");
}
@@ -160,9 +155,8 @@ public class CollectionIteratorTester<E> extends AbstractCollectionTester<E> {
* supports {@code remove()} on only the first element, and the iterator
* tester can't handle that.
*/
- @GwtIncompatible("reflection")
public static Method getIteratorKnownOrderRemoveUnsupportedMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
CollectionIteratorTester.class, "testIterator_knownOrderRemoveUnsupported");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveAllTester.java
index f607916..1005307 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveAllTester.java
@@ -18,12 +18,9 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.WrongType;
@@ -31,8 +28,6 @@ import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
/**
* A generic JUnit test which tests {@code removeAll} operations on a
@@ -45,23 +40,22 @@ import java.util.Iterator;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
public void testRemoveAll_emptyCollection() {
assertFalse("removeAll(emptyCollection) should return false",
collection.removeAll(MinimalCollection.of()));
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
public void testRemoveAll_nonePresent() {
assertFalse("removeAll(disjointCollection) should return false",
collection.removeAll(MinimalCollection.of(samples.e3)));
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRemoveAll_allPresent() {
assertTrue("removeAll(intersectingCollection) should return true",
@@ -69,7 +63,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e0);
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRemoveAll_somePresent() {
assertTrue("removeAll(intersectingCollection) should return true",
@@ -77,24 +71,10 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e0);
}
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(SEVERAL)
- public void testRemoveAllSomePresentConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertTrue(collection.removeAll(MinimalCollection.of(samples.e0, samples.e3)));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
/**
* Trigger the other.size() >= this.size() case in AbstractSet.removeAll().
*/
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRemoveAll_somePresentLargeCollectionToRemove() {
assertTrue("removeAll(largeIntersectingCollection) should return true",
@@ -104,7 +84,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e0);
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_REMOVE_ALL)
public void testRemoveAll_unsupportedEmptyCollection() {
try {
assertFalse("removeAll(emptyCollection) should return false or throw "
@@ -115,7 +95,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_REMOVE_ALL)
public void testRemoveAll_unsupportedNonePresent() {
try {
assertFalse("removeAll(disjointCollection) should return false or throw "
@@ -126,7 +106,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRemoveAll_unsupportedPresent() {
try {
@@ -146,7 +126,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
* suppress only the former.
*/
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(ZERO)
public void testRemoveAll_nullCollectionReferenceEmptySubject() {
try {
@@ -156,7 +136,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
}
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRemoveAll_nullCollectionReferenceNonEmptySubject() {
try {
@@ -166,7 +146,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
}
}
- @CollectionFeature.Require(value = SUPPORTS_REMOVE,
+ @CollectionFeature.Require(value = SUPPORTS_REMOVE_ALL,
absent = ALLOWS_NULL_QUERIES)
public void testRemoveAll_containsNullNo() {
MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
@@ -178,7 +158,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
+ @CollectionFeature.Require({SUPPORTS_REMOVE_ALL, ALLOWS_NULL_QUERIES})
public void testRemoveAll_containsNullNoButAllowed() {
MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
assertFalse("removeAll(containsNull) should return false",
@@ -186,7 +166,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
+ @CollectionFeature.Require({SUPPORTS_REMOVE_ALL, ALLOWS_NULL_VALUES})
@CollectionSize.Require(absent = ZERO)
public void testRemoveAll_containsNullYes() {
initCollectionWithNullElement();
@@ -195,7 +175,7 @@ public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
// TODO: make this work with MinimalCollection
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
public void testRemoveAll_containsWrongType() {
try {
assertFalse("removeAll(containsWrongType) should return false or throw",
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveTester.java
index 3818fd9..2d051bc 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRemoveTester.java
@@ -18,18 +18,14 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import java.util.ConcurrentModificationException;
import java.util.Iterator;
/**
@@ -42,7 +38,6 @@ import java.util.Iterator;
* @author George van den Driessche
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class CollectionRemoveTester<E> extends AbstractCollectionTester<E> {
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(absent = ZERO)
@@ -55,20 +50,6 @@ public class CollectionRemoveTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e0);
}
- @CollectionFeature.Require({SUPPORTS_REMOVE,
- FAILS_FAST_ON_CONCURRENT_MODIFICATION})
- @CollectionSize.Require(SEVERAL)
- public void testRemovePresentConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- assertTrue(collection.remove(samples.e0));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@CollectionFeature.Require(SUPPORTS_REMOVE)
public void testRemove_notPresent() {
assertFalse("remove(notPresent) should return false",
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRetainAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRetainAllTester.java
index 693c0b1..fbfd0d8 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRetainAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionRetainAllTester.java
@@ -17,11 +17,10 @@
package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_RETAIN_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -42,7 +41,6 @@ import java.util.List;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
/**
@@ -105,21 +103,21 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(empty)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ZERO)
public void testRetainAll_emptyPreviouslyEmpty() {
expectReturnsFalse(empty);
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ZERO)
public void testRetainAll_emptyPreviouslyEmptyUnsupported() {
expectReturnsFalseOrThrows(empty);
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_emptyPreviouslyNonEmpty() {
expectReturnsTrue(empty);
@@ -127,7 +125,7 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e0, samples.e1, samples.e2);
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_emptyPreviouslyNonEmptyUnsupported() {
expectThrows(empty);
@@ -136,21 +134,21 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(disjoint)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ZERO)
public void testRetainAll_disjointPreviouslyEmpty() {
expectReturnsFalse(disjoint);
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ZERO)
public void testRetainAll_disjointPreviouslyEmptyUnsupported() {
expectReturnsFalseOrThrows(disjoint);
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_disjointPreviouslyNonEmpty() {
expectReturnsTrue(disjoint);
@@ -158,7 +156,7 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
expectMissing(samples.e0, samples.e1, samples.e2);
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_disjointPreviouslyNonEmptyUnsupported() {
expectThrows(disjoint);
@@ -167,13 +165,13 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(superset)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
public void testRetainAll_superset() {
expectReturnsFalse(superset);
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
public void testRetainAll_supersetUnsupported() {
expectReturnsFalseOrThrows(superset);
expectUnchanged();
@@ -181,14 +179,14 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(subset)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_subset() {
expectReturnsTrue(nonEmptyProperSubset);
expectContents(nonEmptyProperSubset.toRetain);
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_subsetUnsupported() {
expectThrows(nonEmptyProperSubset);
@@ -197,13 +195,13 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(sameElements)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
public void testRetainAll_sameElements() {
expectReturnsFalse(sameElements);
expectUnchanged();
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
public void testRetainAll_sameElementsUnsupported() {
expectReturnsFalseOrThrows(sameElements);
expectUnchanged();
@@ -211,14 +209,14 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(partialOverlap)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_partialOverlap() {
expectReturnsTrue(partialOverlap);
expectContents(samples.e2);
}
- @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
+ @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_partialOverlapUnsupported() {
expectThrows(partialOverlap);
@@ -227,14 +225,14 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(containsDuplicates)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ONE)
public void testRetainAll_containsDuplicatesSizeOne() {
expectReturnsFalse(containsDuplicates);
expectContents(samples.e0);
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_containsDuplicatesSizeSeveral() {
expectReturnsTrue(containsDuplicates);
@@ -243,21 +241,21 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// retainAll(nullSingleton)
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ZERO)
public void testRetainAll_nullSingletonPreviouslyEmpty() {
expectReturnsFalse(nullSingleton);
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_nullSingletonPreviouslyNonEmpty() {
expectReturnsTrue(nullSingleton);
expectContents();
}
- @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
+ @CollectionFeature.Require({SUPPORTS_RETAIN_ALL, ALLOWS_NULL_VALUES})
@CollectionSize.Require(ONE)
public void testRetainAll_nullSingletonPreviouslySingletonWithNull() {
initCollectionWithNullElement();
@@ -265,7 +263,7 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
expectContents(createArrayWithNullElement());
}
- @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
+ @CollectionFeature.Require({SUPPORTS_RETAIN_ALL, ALLOWS_NULL_VALUES})
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_nullSingletonPreviouslySeveralWithNull() {
initCollectionWithNullElement();
@@ -275,7 +273,7 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
// nullSingleton.retainAll()
- @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
+ @CollectionFeature.Require({SUPPORTS_RETAIN_ALL, ALLOWS_NULL_VALUES})
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_containsNonNullWithNull() {
initCollectionWithNullElement();
@@ -292,7 +290,7 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
* suppress only the former.
*/
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(ZERO)
public void testRetainAll_nullCollectionReferenceEmptySubject() {
try {
@@ -302,7 +300,7 @@ public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> {
}
}
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = ZERO)
public void testRetainAll_nullCollectionReferenceNonEmptySubject() {
try {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationEqualTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationEqualTester.java
deleted file mode 100644
index 1fbfe26..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationEqualTester.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.testing.SerializableTester;
-
-/**
- * Basic reserialization test for collection types that must preserve {@code equals()} behavior
- * when reserialized. (Sets and Lists, but not bare Collections.)
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class CollectionSerializationEqualTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SERIALIZABLE)
- public void testReserialize() {
- assertEquals(
- actualContents(),
- SerializableTester.reserialize(actualContents()));
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationTester.java
deleted file mode 100644
index bc4470e..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSerializationTester.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractCollectionTester;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.testing.SerializableTester;
-
-/**
- * Basic reserialization test for collections.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class CollectionSerializationTester<E> extends AbstractCollectionTester<E> {
- @CollectionFeature.Require(SERIALIZABLE)
- public void testReserialize() {
- // For a bare Collection, the most we can guarantee is that the elements are preserved.
- Helpers.assertEqualIgnoringOrder(
- actualContents(),
- SerializableTester.reserialize(actualContents()));
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSizeTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSizeTester.java
index 0c9693d..f7fa87b 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSizeTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionSizeTester.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
/**
@@ -28,7 +27,6 @@ import com.google.common.collect.testing.AbstractCollectionTester;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class CollectionSizeTester<E> extends AbstractCollectionTester<E> {
public void testSize() {
assertEquals("size():", getNumElements(), collection.size());
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java
index d7de38b..3d65969 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToArrayTester.java
@@ -19,8 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.WrongType;
@@ -42,7 +40,6 @@ import java.util.List;
* @author Kevin Bourrillion
* @author Chris Povirk
*/
-@GwtCompatible(emulated = true)
public class CollectionToArrayTester<E> extends AbstractCollectionTester<E> {
public void testToArray_noArgs() {
Object[] array = collection.toArray();
@@ -195,8 +192,7 @@ public class CollectionToArrayTester<E> extends AbstractCollectionTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6260652">Sun bug
* 6260652</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getToArrayIsPlainObjectArrayMethod() {
- return Helpers.getMethod(CollectionToArrayTester.class, "testToArray_isPlainObjectArray");
+ return Platform.getMethod(CollectionToArrayTester.class, "testToArray_isPlainObjectArray");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToStringTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToStringTester.java
index 4d93fa9..120a112 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToStringTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/CollectionToStringTester.java
@@ -22,7 +22,6 @@ import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractCollectionTester;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -37,7 +36,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class CollectionToStringTester<E> extends AbstractCollectionTester<E> {
public void testToString_minimal() {
assertNotNull("toString() should not return null",
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllAtIndexTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllAtIndexTester.java
index 1844106..be64b0d 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllAtIndexTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllAtIndexTester.java
@@ -19,10 +19,10 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
+import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_ALL_WITH_INDEX;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
import static java.util.Collections.singletonList;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -40,9 +40,8 @@ import java.util.List;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testAddAllAtIndex_supportedAllPresent() {
assertTrue("addAll(n, allPresent) should return true",
@@ -50,7 +49,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(0, samples.e0);
}
- @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(absent = SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testAddAllAtIndex_unsupportedAllPresent() {
try {
@@ -61,7 +60,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectUnchanged();
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testAddAllAtIndex_supportedSomePresent() {
assertTrue("addAll(n, allPresent) should return true",
@@ -69,7 +68,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(0, samples.e0, samples.e3);
}
- @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(absent = SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testAddAllAtIndex_unsupportedSomePresent() {
try {
@@ -81,14 +80,14 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectMissing(samples.e3);
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
public void testAddAllAtIndex_supportedNothing() {
assertFalse("addAll(n, nothing) should return false",
getList().addAll(0, emptyCollection()));
expectUnchanged();
}
- @ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(absent = SUPPORTS_ADD_ALL_WITH_INDEX)
public void testAddAllAtIndex_unsupportedNothing() {
try {
assertFalse("addAll(n, nothing) should return false or throw",
@@ -98,7 +97,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectUnchanged();
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
public void testAddAllAtIndex_withDuplicates() {
MinimalCollection<E> elementsToAdd
= MinimalCollection.of(samples.e0, samples.e1, samples.e0, samples.e1);
@@ -107,7 +106,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(0, samples.e0, samples.e1, samples.e0, samples.e1);
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionFeature.Require(ALLOWS_NULL_VALUES)
public void testAddAllAtIndex_nullSupported() {
List<E> containsNull = singletonList(null);
@@ -120,7 +119,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(0, (E) null);
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionFeature.Require(absent = ALLOWS_NULL_VALUES)
public void testAddAllAtIndex_nullUnsupported() {
List<E> containsNull = singletonList(null);
@@ -134,7 +133,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
"Should not contain null after unsupported addAll(n, containsNull)");
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testAddAllAtIndex_middle() {
assertTrue("addAll(middle, disjoint) should return true",
@@ -142,7 +141,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(getNumElements() / 2, createDisjointCollection());
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testAddAllAtIndex_end() {
assertTrue("addAll(end, disjoint) should return true",
@@ -150,7 +149,7 @@ public class ListAddAllAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(getNumElements(), createDisjointCollection());
}
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
+ @ListFeature.Require(SUPPORTS_ADD_ALL_WITH_INDEX)
public void testAddAllAtIndex_nullCollectionReference() {
try {
getList().addAll(0, null);
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllTester.java
index f76d5db..3e9cb49 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAllTester.java
@@ -16,10 +16,9 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -34,9 +33,8 @@ import com.google.common.collect.testing.features.CollectionSize;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class ListAddAllTester<E> extends AbstractListTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_supportedAllPresent() {
assertTrue("addAll(allPresent) should return true",
@@ -44,7 +42,7 @@ public class ListAddAllTester<E> extends AbstractListTester<E> {
expectAdded(samples.e0);
}
- @CollectionFeature.Require(absent = SUPPORTS_ADD)
+ @CollectionFeature.Require(absent = SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_unsupportedAllPresent() {
try {
@@ -55,7 +53,7 @@ public class ListAddAllTester<E> extends AbstractListTester<E> {
expectUnchanged();
}
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
public void testAddAll_withDuplicates() {
MinimalCollection<E> elementsToAdd
= MinimalCollection.of(samples.e0, samples.e1, samples.e0, samples.e1);
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAtIndexTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAtIndexTester.java
index ab92dd9..9721393 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAtIndexTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddAtIndexTester.java
@@ -17,21 +17,15 @@
package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
import java.lang.reflect.Method;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
/**
* A generic JUnit test which tests {@code add(int, Object)} operations on a
@@ -43,7 +37,6 @@ import java.util.Iterator;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class ListAddAtIndexTester<E> extends AbstractListTester<E> {
@ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
@@ -73,19 +66,6 @@ public class ListAddAtIndexTester<E> extends AbstractListTester<E> {
expectAdded(0, samples.e3);
}
- @CollectionFeature.Require(FAILS_FAST_ON_CONCURRENT_MODIFICATION)
- @ListFeature.Require(SUPPORTS_ADD_WITH_INDEX)
- public void testAddAtIndexConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- getList().add(0, samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@ListFeature.Require(absent = SUPPORTS_ADD_WITH_INDEX)
public void testAddAtIndex_unsupportedNotPresent() {
try {
@@ -158,9 +138,8 @@ public class ListAddAtIndexTester<E> extends AbstractListTester<E> {
* {@link #testAddAtIndex_nullSupported()} so that tests can suppress it. See
* {@link CollectionAddTester#getAddNullSupportedMethod()} for details.
*/
- @GwtIncompatible("reflection")
public static Method getAddNullSupportedMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
ListAddAtIndexTester.class, "testAddAtIndex_nullSupported");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddTester.java
index d974761..0fc8dd0 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListAddTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListAddTester.java
@@ -20,8 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.ALLOW
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -39,7 +37,6 @@ import java.util.List;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class ListAddTester<E> extends AbstractListTester<E> {
@CollectionFeature.Require(SUPPORTS_ADD)
@CollectionSize.Require(absent = ZERO)
@@ -79,8 +76,7 @@ public class ListAddTester<E> extends AbstractListTester<E> {
* {@link #testAdd_supportedNullPresent()} so that tests can suppress it. See
* {@link CollectionAddTester#getAddNullSupportedMethod()} for details.
*/
- @GwtIncompatible("reflection")
public static Method getAddSupportedNullPresentMethod() {
- return Helpers.getMethod(ListAddTester.class, "testAdd_supportedNullPresent");
+ return Platform.getMethod(ListAddTester.class, "testAdd_supportedNullPresent");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListCreationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListCreationTester.java
index 257ffab..601eea4 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListCreationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListCreationTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.REJEC
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -33,7 +32,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListCreationTester<E> extends AbstractListTester<E> {
@CollectionFeature.Require(absent = REJECTS_DUPLICATES_AT_CREATION)
@CollectionSize.Require(absent = {ZERO, ONE})
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListEqualsTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListEqualsTester.java
index c1adc6a..9e7e13e 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListEqualsTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListEqualsTester.java
@@ -18,7 +18,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.MinimalSet;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -34,12 +33,11 @@ import java.util.List;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class ListEqualsTester<E> extends AbstractListTester<E> {
public void testEquals_otherListWithSameElements() {
assertTrue(
"A List should equal any other List containing the same elements.",
- getList().equals(new ArrayList<E>(getOrderedElements())));
+ getList().equals(new ArrayList<E>(getSampleElements())));
}
@CollectionSize.Require(absent = CollectionSize.ZERO)
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListGetTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListGetTester.java
index eed4112..340e0cb 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListGetTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListGetTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
-
/**
* A generic JUnit test which tests {@code get()} operations on a list. Can't be
* invoked directly; please see
@@ -27,11 +25,10 @@ import com.google.common.annotations.GwtCompatible;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListGetTester<E> extends AbstractListTester<E> {
public void testGet_valid() {
// This calls get() on each index and checks the result:
- expectContents(createOrderedArray());
+ expectContents(createSamplesArray());
}
public void testGet_negative() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListHashCodeTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListHashCodeTester.java
index 30ed6c2..f7f3291 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListHashCodeTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListHashCodeTester.java
@@ -16,10 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
-
import java.lang.reflect.Method;
/**
@@ -29,11 +25,10 @@ import java.lang.reflect.Method;
*
* @author George van den Driessche
*/
-@GwtCompatible(emulated = true)
public class ListHashCodeTester<E> extends AbstractListTester<E> {
public void testHashCode() {
int expectedHashCode = 1;
- for (E element : getOrderedElements()) {
+ for (E element : getSampleElements()) {
expectedHashCode = 31 * expectedHashCode +
((element == null) ? 0 : element.hashCode());
}
@@ -47,8 +42,7 @@ public class ListHashCodeTester<E> extends AbstractListTester<E> {
* list tests on unhashable objects can suppress it with
* {@code FeatureSpecificTestSuiteBuilder.suppressing()}.
*/
- @GwtIncompatible("reflection")
public static Method getHashCodeMethod() {
- return Helpers.getMethod(ListHashCodeTester.class, "testHashCode");
+ return Platform.getMethod(ListHashCodeTester.class, "testHashCode");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListIndexOfTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListIndexOfTester.java
index 5da84e8..4c96c19 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListIndexOfTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListIndexOfTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.REJEC
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -33,7 +32,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListIndexOfTester<E> extends AbstractListIndexOfTester<E> {
@Override protected int find(Object o) {
return getList().indexOf(o);
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListLastIndexOfTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListLastIndexOfTester.java
index 041a22d..a3f9812 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListLastIndexOfTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListLastIndexOfTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.REJEC
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -33,7 +32,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListLastIndexOfTester<E> extends AbstractListIndexOfTester<E> {
@Override protected int find(Object o) {
return getList().lastIndexOf(o);
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListListIteratorTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListListIteratorTester.java
index 438634b..c8c8d6f 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListListIteratorTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListListIteratorTester.java
@@ -24,8 +24,6 @@ import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SE
import static com.google.common.collect.testing.testers.Platform.listListIteratorTesterNumIterations;
import static java.util.Collections.singleton;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.IteratorFeature;
import com.google.common.collect.testing.ListIteratorTester;
@@ -48,7 +46,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
* @author Chris Povirk
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
public class ListListIteratorTester<E> extends AbstractListTester<E> {
// TODO: switch to DerivedIteratorTestSuiteBuilder
@@ -71,7 +68,7 @@ public class ListListIteratorTester<E> extends AbstractListTester<E> {
private void runListIteratorTest(Set<IteratorFeature> features) {
new ListIteratorTester<E>(
listListIteratorTesterNumIterations(), singleton(samples.e4), features,
- Helpers.copyToList(getOrderedElements()), 0) {
+ Helpers.copyToList(getSampleElements()), 0) {
{
// TODO: don't set this universally
stopTestingWhenAddThrowsException();
@@ -117,9 +114,8 @@ public class ListListIteratorTester<E> extends AbstractListTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570575">Sun bug
* 6570575</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getListIteratorFullyModifiableMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
ListListIteratorTester.class, "testListIterator_fullyModifiable");
}
@@ -128,9 +124,8 @@ public class ListListIteratorTester<E> extends AbstractListTester<E> {
* {@link #testListIterator_unmodifiable()} so that it can be suppressed in
* GWT tests.
*/
- @GwtIncompatible("reflection")
public static Method getListIteratorUnmodifiableMethod() {
- return Helpers.getMethod(
+ return Platform.getMethod(
ListListIteratorTester.class, "testListIterator_unmodifiable");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAllTester.java
index 8eb83ec..faeec46 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAllTester.java
@@ -16,11 +16,10 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -35,9 +34,8 @@ import com.google.common.collect.testing.features.CollectionSize;
* @author George van den Driessche
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class ListRemoveAllTester<E> extends AbstractListTester<E> {
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_REMOVE_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRemoveAll_duplicate() {
ArrayWithDuplicate<E> arrayAndDuplicate = createArrayWithDuplicateElement();
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAtIndexTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAtIndexTester.java
index 47c1e95..cb37c67 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAtIndexTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveAtIndexTester.java
@@ -16,19 +16,14 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_REMOVE_WITH_INDEX;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
import java.util.List;
/**
@@ -40,7 +35,6 @@ import java.util.List;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListRemoveAtIndexTester<E> extends AbstractListTester<E> {
@ListFeature.Require(absent = SUPPORTS_REMOVE_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
@@ -85,20 +79,6 @@ public class ListRemoveAtIndexTester<E> extends AbstractListTester<E> {
runRemoveTest(getNumElements() / 2);
}
- @CollectionFeature.Require(FAILS_FAST_ON_CONCURRENT_MODIFICATION)
- @ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
- @CollectionSize.Require(absent = ZERO)
- public void testRemoveAtIndexConcurrentWithIteration() {
- try {
- Iterator<E> iterator = collection.iterator();
- getList().remove(getNumElements() / 2);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@ListFeature.Require(SUPPORTS_REMOVE_WITH_INDEX)
@CollectionSize.Require(absent = ZERO)
public void testRemoveAtIndex_last() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveTester.java
index e338ca0..0094928 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListRemoveTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.SUPPO
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -33,7 +32,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class ListRemoveTester<E> extends AbstractListTester<E> {
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(absent = {ZERO, ONE})
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListRetainAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListRetainAllTester.java
index 872e096..2ede664 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListRetainAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListRetainAllTester.java
@@ -16,12 +16,11 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_RETAIN_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -35,9 +34,8 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListRetainAllTester<E> extends AbstractListTester<E> {
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(absent = {ZERO, ONE})
public void testRetainAll_duplicatesKept() {
E[] array = createSamplesArray();
@@ -49,7 +47,7 @@ public class ListRetainAllTester<E> extends AbstractListTester<E> {
}
@SuppressWarnings("unchecked")
- @CollectionFeature.Require(SUPPORTS_REMOVE)
+ @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
@CollectionSize.Require(SEVERAL)
public void testRetainAll_duplicatesRemoved() {
E[] array = createSamplesArray();
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListSetTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListSetTester.java
index df3b8ad..2b3b7b0 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListSetTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListSetTester.java
@@ -20,9 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.ALLOW
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
@@ -38,7 +35,6 @@ import java.lang.reflect.Method;
*
* @author George van den Driessche
*/
-@GwtCompatible(emulated = true)
public class ListSetTester<E> extends AbstractListTester<E> {
@ListFeature.Require(SUPPORTS_SET)
@CollectionSize.Require(absent = ZERO)
@@ -149,8 +145,7 @@ public class ListSetTester<E> extends AbstractListTester<E> {
* seems more likely that code would depend on that behavior than on the
* other. Thus, we say the bug is in set(), which fails to support null.
*/
- @GwtIncompatible("reflection")
public static Method getSetNullSupportedMethod() {
- return Helpers.getMethod(ListSetTester.class, "testSet_null");
+ return Platform.getMethod(ListSetTester.class, "testSet_null");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListSubListTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListSubListTester.java
index e01dce5..7ba68ba 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListSubListTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListSubListTester.java
@@ -16,8 +16,6 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.Helpers.getMethod;
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS;
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_ADD_WITH_INDEX;
@@ -25,13 +23,9 @@ import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_RE
import static com.google.common.collect.testing.features.ListFeature.SUPPORTS_SET;
import static java.util.Collections.emptyList;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
-import com.google.common.testing.SerializableTester;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -49,7 +43,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class ListSubListTester<E> extends AbstractListTester<E> {
public void testSubList_startNegative() {
try {
@@ -178,7 +171,7 @@ public class ListSubListTester<E> extends AbstractListTester<E> {
List<E> subList = getList().subList(0, 2).subList(1, 2);
assertEquals("subList(0, 2).subList(1, 2) "
+ "should be a single-element list of the element at index 1",
- Collections.singletonList(getOrderedElements().get(1)), subList);
+ Collections.singletonList(samples.e1), subList);
}
@CollectionSize.Require(absent = {ZERO})
@@ -305,22 +298,6 @@ public class ListSubListTester<E> extends AbstractListTester<E> {
-1);
}
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- public void testReserializeWholeSubList() {
- SerializableTester.reserializeAndAssert(getList().subList(0, getNumElements()));
- }
-
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- public void testReserializeEmptySubList() {
- SerializableTester.reserializeAndAssert(getList().subList(0, 0));
- }
-
- @CollectionFeature.Require(SERIALIZABLE_INCLUDING_VIEWS)
- @CollectionSize.Require(absent = {ZERO, ONE})
- public void testReserializeSubList() {
- SerializableTester.reserializeAndAssert(getList().subList(0, 2));
- }
-
/**
* Returns the {@link Method} instance for
* {@link #testSubList_originalListSetAffectsSubList()} so that tests
@@ -329,9 +306,9 @@ public class ListSubListTester<E> extends AbstractListTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570631">Sun bug
* 6570631</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getSubListOriginalListSetAffectsSubListMethod() {
- return getMethod(ListSubListTester.class, "testSubList_originalListSetAffectsSubList");
+ return Platform
+ .getMethod(ListSubListTester.class, "testSubList_originalListSetAffectsSubList");
}
/**
@@ -342,9 +319,10 @@ public class ListSubListTester<E> extends AbstractListTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570631">Sun bug
* 6570631</a> is fixed.
*/
- @GwtIncompatible("reflection")
- public static Method getSubListOriginalListSetAffectsSubListLargeListMethod() {
- return getMethod(ListSubListTester.class, "testSubList_originalListSetAffectsSubListLargeList");
+ public static Method
+ getSubListOriginalListSetAffectsSubListLargeListMethod() {
+ return Platform
+ .getMethod(ListSubListTester.class, "testSubList_originalListSetAffectsSubListLargeList");
}
/**
@@ -355,9 +333,9 @@ public class ListSubListTester<E> extends AbstractListTester<E> {
* href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570575">Sun bug
* 6570575</a> is fixed.
*/
- @GwtIncompatible("reflection")
public static Method getSubListSubListRemoveAffectsOriginalLargeListMethod() {
- return getMethod(ListSubListTester.class, "testSubList_subListRemoveAffectsOriginalLargeList");
+ return Platform.getMethod(
+ ListSubListTester.class, "testSubList_subListRemoveAffectsOriginalLargeList");
}
/*
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/ListToArrayTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/ListToArrayTester.java
index ca11aba..f990ffb 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/ListToArrayTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/ListToArrayTester.java
@@ -18,7 +18,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionSize;
import java.util.Arrays;
@@ -32,27 +31,26 @@ import java.util.Arrays;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class ListToArrayTester<E> extends AbstractListTester<E> {
// CollectionToArrayTester tests everything except ordering.
public void testToArray_noArg() {
Object[] actual = getList().toArray();
assertArrayEquals("toArray() order should match list",
- createOrderedArray(), actual);
+ createSamplesArray(), actual);
}
@CollectionSize.Require(absent = ZERO)
public void testToArray_tooSmall() {
Object[] actual = getList().toArray(new Object[0]);
assertArrayEquals("toArray(tooSmall) order should match list",
- createOrderedArray(), actual);
+ createSamplesArray(), actual);
}
public void testToArray_largeEnough() {
Object[] actual = getList().toArray(new Object[getNumElements()]);
assertArrayEquals("toArray(largeEnough) order should match list",
- createOrderedArray(), actual);
+ createSamplesArray(), actual);
}
private static void assertArrayEquals(String message, Object[] expected,
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapClearTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapClearTester.java
index 2f341ff..302df11 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapClearTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapClearTester.java
@@ -16,20 +16,13 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
+import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_CLEAR;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
/**
* A generic JUnit test which tests {@code clear()} operations on a map.
* Can't be invoked directly; please see
@@ -40,58 +33,15 @@ import java.util.Map.Entry;
* @author George van den Driessche
* @author Chris Povirk
*/
-@GwtCompatible
public class MapClearTester<K, V> extends AbstractMapTester<K, V> {
- @MapFeature.Require(SUPPORTS_REMOVE)
+ @MapFeature.Require(SUPPORTS_CLEAR)
public void testClear() {
getMap().clear();
assertTrue("After clear(), a map should be empty.",
getMap().isEmpty());
}
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_REMOVE})
- @CollectionSize.Require(SEVERAL)
- public void testClearConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
- getMap().clear();
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_REMOVE})
- @CollectionSize.Require(SEVERAL)
- public void testClearConcurrentWithKeySetIteration() {
- try {
- Iterator<K> iterator = getMap().keySet().iterator();
- getMap().clear();
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_REMOVE})
- @CollectionSize.Require(SEVERAL)
- public void testClearConcurrentWithValuesIteration() {
- try {
- Iterator<V> iterator = getMap().values().iterator();
- getMap().clear();
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require(absent = SUPPORTS_REMOVE)
+ @MapFeature.Require(absent = SUPPORTS_CLEAR)
@CollectionSize.Require(absent = ZERO)
public void testClear_unsupported() {
try {
@@ -103,7 +53,7 @@ public class MapClearTester<K, V> extends AbstractMapTester<K, V> {
expectUnchanged();
}
- @MapFeature.Require(absent = SUPPORTS_REMOVE)
+ @MapFeature.Require(absent = SUPPORTS_CLEAR)
@CollectionSize.Require(ZERO)
public void testClear_unsupportedByEmptyCollection() {
try {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsKeyTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsKeyTester.java
index 7a69636..cbfeaf4 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsKeyTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsKeyTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionSize;
@@ -35,7 +34,6 @@ import com.google.common.collect.testing.features.MapFeature;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class MapContainsKeyTester<K, V> extends AbstractMapTester<K, V> {
@CollectionSize.Require(absent = ZERO)
public void testContains_yes() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsValueTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsValueTester.java
index e587f67..7c44040 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsValueTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapContainsValueTester.java
@@ -19,7 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.*;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionSize;
@@ -35,7 +34,6 @@ import com.google.common.collect.testing.features.MapFeature;
* @author George van den Driessche
* @author Chris Povirk
*/
-@GwtCompatible
public class MapContainsValueTester<K, V> extends AbstractMapTester<K, V> {
@CollectionSize.Require(absent = ZERO)
public void testContains_yes() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapCreationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapCreationTester.java
index 499a53b..00f8bfc 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapCreationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapCreationTester.java
@@ -22,14 +22,10 @@ import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.MapFeature.REJECTS_DUPLICATES_AT_CREATION;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
-import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
@@ -44,7 +40,6 @@ import java.util.Map.Entry;
* @author Chris Povirk
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
public class MapCreationTester<K, V> extends AbstractMapTester<K, V> {
@MapFeature.Require(ALLOWS_NULL_KEYS)
@CollectionSize.Require(absent = ZERO)
@@ -126,13 +121,13 @@ public class MapCreationTester<K, V> extends AbstractMapTester<K, V> {
private Entry<K, V>[] getEntriesMultipleNullKeys() {
Entry<K, V>[] entries = createArrayWithNullKey();
- entries[0] = entry(null, entries[0].getValue());
+ entries[0] = entries[getNullLocation()];
return entries;
}
private Entry<K, V>[] getEntriesMultipleNonNullKeys() {
Entry<K, V>[] entries = createSamplesArray();
- entries[0] = entry(samples.e1.getKey(), samples.e0.getValue());
+ entries[0] = samples.e1;
return entries;
}
@@ -143,16 +138,4 @@ public class MapCreationTester<K, V> extends AbstractMapTester<K, V> {
Arrays.asList(entries).subList(1, getNumElements());
expectContents(expectedWithDuplicateRemoved);
}
-
- /**
- * Returns the {@link Method} instance for {@link
- * #testCreateWithNullKeyUnsupported()} so that tests can suppress it
- * with {@code FeatureSpecificTestSuiteBuilder.suppressing()} until <a
- * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun
- * bug 5045147</a> is fixed.
- */
- @GwtIncompatible("reflection")
- public static Method getCreateWithNullKeyUnsupportedMethod() {
- return Helpers.getMethod(MapCreationTester.class, "testCreateWithNullKeyUnsupported");
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapEqualsTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapEqualsTester.java
index b73c523..66b71e7 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapEqualsTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapEqualsTester.java
@@ -19,7 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionSize;
@@ -38,7 +37,6 @@ import java.util.Map.Entry;
* @author George van den Driessche
* @author Chris Povirk
*/
-@GwtCompatible
public class MapEqualsTester<K, V> extends AbstractMapTester<K, V> {
public void testEquals_otherMapWithSameEntries() {
assertTrue(
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapGetTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapGetTester.java
index a1c934d..9860931 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapGetTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapGetTester.java
@@ -20,7 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.ALLOW
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -37,7 +36,6 @@ import com.google.common.collect.testing.features.MapFeature;
* @author Kevin Bourrillion
* @author Chris Povirk
*/
-@GwtCompatible
public class MapGetTester<K, V> extends AbstractMapTester<K, V> {
@CollectionSize.Require(absent = ZERO)
public void testGet_yes() {
@@ -61,7 +59,7 @@ public class MapGetTester<K, V> extends AbstractMapTester<K, V> {
} catch (NullPointerException tolerated) {
}
}
-
+
@MapFeature.Require(ALLOWS_NULL_KEYS)
@CollectionSize.Require(absent = ZERO)
public void testGet_nonNullWhenNullContained() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapHashCodeTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapHashCodeTester.java
index c2483bc..ccfde43 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapHashCodeTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapHashCodeTester.java
@@ -19,7 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
@@ -35,7 +34,6 @@ import java.util.Map;
* @author George van den Driessche
* @author Chris Povirk
*/
-@GwtCompatible
public class MapHashCodeTester<K, V> extends AbstractMapTester<K, V> {
public void testHashCode() {
int expectedHashCode = 0;
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapIsEmptyTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapIsEmptyTester.java
index 8eb31da..8d27eb7 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapIsEmptyTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapIsEmptyTester.java
@@ -18,7 +18,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.features.CollectionSize;
@@ -31,7 +30,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
public class MapIsEmptyTester<K, V> extends AbstractMapTester<K, V> {
@CollectionSize.Require(ZERO)
public void testIsEmpty_yes() {
@@ -42,4 +40,4 @@ public class MapIsEmptyTester<K, V> extends AbstractMapTester<K, V> {
public void testIsEmpty_no() {
assertFalse("isEmpty() should return false", getMap().isEmpty());
}
-}
+} \ No newline at end of file
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapNavigationTester.java
index 26f9918..8c2bf60 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/NavigableMapNavigationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapNavigationTester.java
@@ -31,15 +31,16 @@ import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
+import java.util.NoSuchElementException;
/**
* A generic JUnit test which tests operations on a NavigableMap. Can't be
- * invoked directly; please see {@code NavigableMapTestSuiteBuilder}.
+ * invoked directly; please see {@code MapTestSuiteBuilder}.
*
* @author Jesse Wilson
* @author Louis Wasserman
*/
-public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V> {
+public class MapNavigationTester<K, V> extends AbstractMapTester<K, V> {
private NavigableMap<K, V> navigableMap;
private List<Entry<K, V>> entries;
@@ -78,6 +79,11 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
@CollectionSize.Require(ZERO)
public void testEmptyMapFirst() {
assertNull(navigableMap.firstEntry());
+ try {
+ navigableMap.firstKey();
+ fail();
+ } catch (NoSuchElementException e) {
+ }
}
@MapFeature.Require(SUPPORTS_REMOVE)
@@ -101,7 +107,12 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
@CollectionSize.Require(ZERO)
public void testEmptyMapLast() {
assertNull(navigableMap.lastEntry());
- }
+ try {
+ assertNull(navigableMap.lastKey());
+ fail();
+ } catch (NoSuchElementException e) {
+ }
+ }
@MapFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ZERO)
@@ -112,6 +123,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
@CollectionSize.Require(ONE)
public void testSingletonMapFirst() {
assertEquals(a, navigableMap.firstEntry());
+ assertEquals(a.getKey(), navigableMap.firstKey());
}
@MapFeature.Require(SUPPORTS_REMOVE)
@@ -136,6 +148,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
@CollectionSize.Require(ONE)
public void testSingletonMapLast() {
assertEquals(a, navigableMap.lastEntry());
+ assertEquals(a.getKey(), navigableMap.lastKey());
}
@MapFeature.Require(SUPPORTS_REMOVE)
@@ -148,6 +161,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
@CollectionSize.Require(SEVERAL)
public void testFirst() {
assertEquals(a, navigableMap.firstEntry());
+ assertEquals(a.getKey(), navigableMap.firstKey());
}
@MapFeature.Require(SUPPORTS_REMOVE)
@@ -166,7 +180,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
} catch (UnsupportedOperationException e) {
}
}
-
+
@CollectionSize.Require(SEVERAL)
public void testLower() {
resetWithHole();
@@ -177,7 +191,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
assertEquals(a, navigableMap.lowerEntry(c.getKey()));
assertEquals(a.getKey(), navigableMap.lowerKey(c.getKey()));
}
-
+
@CollectionSize.Require(SEVERAL)
public void testFloor() {
resetWithHole();
@@ -210,12 +224,13 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
assertEquals(null, navigableMap.higherEntry(c.getKey()));
assertEquals(null, navigableMap.higherKey(c.getKey()));
}
-
+
@CollectionSize.Require(SEVERAL)
public void testLast() {
assertEquals(c, navigableMap.lastEntry());
+ assertEquals(c.getKey(), navigableMap.lastKey());
}
-
+
@MapFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(SEVERAL)
public void testPollLast() {
@@ -232,7 +247,7 @@ public class NavigableMapNavigationTester<K, V> extends AbstractMapTester<K, V>
fail();
} catch (UnsupportedOperationException e) {
}
- }
+ }
@CollectionSize.Require(SEVERAL)
public void testDescendingNavigation() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapPutAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapPutAllTester.java
index 41eec75..d36e736 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapPutAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapPutAllTester.java
@@ -19,22 +19,15 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
-import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
+import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT_ALL;
import static java.util.Collections.singletonList;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
-import java.lang.reflect.Method;
import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -51,7 +44,6 @@ import java.util.Map.Entry;
* @author Kevin Bourrillion
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
private List<Entry<K, V>> containsNullKey;
private List<Entry<K, V>> containsNullValue;
@@ -62,13 +54,13 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
containsNullValue = singletonList(entry(samples.e3.getKey(), null));
}
- @MapFeature.Require(SUPPORTS_PUT)
+ @MapFeature.Require(SUPPORTS_PUT_ALL)
public void testPutAll_supportedNothing() {
getMap().putAll(emptyMap());
expectUnchanged();
}
- @MapFeature.Require(absent = SUPPORTS_PUT)
+ @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
public void testPutAll_unsupportedNothing() {
try {
getMap().putAll(emptyMap());
@@ -77,13 +69,13 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
expectUnchanged();
}
- @MapFeature.Require(SUPPORTS_PUT)
+ @MapFeature.Require(SUPPORTS_PUT_ALL)
public void testPutAll_supportedNonePresent() {
putAll(createDisjointCollection());
expectAdded(samples.e3, samples.e4);
}
- @MapFeature.Require(absent = SUPPORTS_PUT)
+ @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
public void testPutAll_unsupportedNonePresent() {
try {
putAll(createDisjointCollection());
@@ -94,28 +86,14 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
expectMissing(samples.e3, samples.e4);
}
- @MapFeature.Require(SUPPORTS_PUT)
+ @MapFeature.Require(SUPPORTS_PUT_ALL)
@CollectionSize.Require(absent = ZERO)
public void testPutAll_supportedSomePresent() {
putAll(MinimalCollection.of(samples.e3, samples.e0));
expectAdded(samples.e3);
}
- @MapFeature.Require({ FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_PUT })
- @CollectionSize.Require(absent = ZERO)
- public void testPutAllSomePresentConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
- putAll(MinimalCollection.of(samples.e3, samples.e0));
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require(absent = SUPPORTS_PUT)
+ @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
@CollectionSize.Require(absent = ZERO)
public void testPutAll_unsupportedSomePresent() {
try {
@@ -126,7 +104,7 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
expectUnchanged();
}
- @MapFeature.Require(absent = SUPPORTS_PUT)
+ @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
@CollectionSize.Require(absent = ZERO)
public void testPutAll_unsupportedAllPresent() {
try {
@@ -136,16 +114,16 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
expectUnchanged();
}
- @MapFeature.Require({SUPPORTS_PUT,
+ @MapFeature.Require({SUPPORTS_PUT_ALL,
ALLOWS_NULL_KEYS})
public void testPutAll_nullKeySupported() {
putAll(containsNullKey);
expectAdded(containsNullKey.get(0));
}
- @MapFeature.Require(value = SUPPORTS_PUT,
+ @MapFeature.Require(value = SUPPORTS_PUT_ALL,
absent = ALLOWS_NULL_KEYS)
- public void testPutAll_nullKeyUnsupported() {
+ public void testAdd_nullKeyUnsupported() {
try {
putAll(containsNullKey);
fail("putAll(containsNullKey) should throw");
@@ -157,16 +135,16 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
"putAll(containsNullKey)");
}
- @MapFeature.Require({SUPPORTS_PUT,
+ @MapFeature.Require({SUPPORTS_PUT_ALL,
ALLOWS_NULL_VALUES})
public void testPutAll_nullValueSupported() {
putAll(containsNullValue);
expectAdded(containsNullValue.get(0));
}
- @MapFeature.Require(value = SUPPORTS_PUT,
+ @MapFeature.Require(value = SUPPORTS_PUT_ALL,
absent = ALLOWS_NULL_VALUES)
- public void testPutAll_nullValueUnsupported() {
+ public void testAdd_nullValueUnsupported() {
try {
putAll(containsNullValue);
fail("putAll(containsNullValue) should throw");
@@ -178,7 +156,7 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
"putAll(containsNullValue)");
}
- @MapFeature.Require(SUPPORTS_PUT)
+ @MapFeature.Require(SUPPORTS_PUT_ALL)
public void testPutAll_nullCollectionReference() {
try {
getMap().putAll(null);
@@ -198,16 +176,4 @@ public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
}
getMap().putAll(map);
}
-
- /**
- * Returns the {@link Method} instance for {@link
- * #testPutAll_nullKeyUnsupported()} so that tests can suppress it with {@code
- * FeatureSpecificTestSuiteBuilder.suppressing()} until <a
- * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun
- * bug 5045147</a> is fixed.
- */
- @GwtIncompatible("reflection")
- public static Method getPutAllNullKeyUnsupportedMethod() {
- return Helpers.getMethod(MapPutAllTester.class, "testPutAll_nullKeyUnsupported");
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapPutTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapPutTester.java
index 7c242d5..69b57ca 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapPutTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapPutTester.java
@@ -19,19 +19,12 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
-import java.lang.reflect.Method;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
@@ -46,7 +39,6 @@ import java.util.Map.Entry;
* @author Kevin Bourrillion
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible(emulated = true)
public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
private Entry<K, V> nullKeyEntry;
private Entry<K, V> nullValueEntry;
@@ -67,45 +59,6 @@ public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
expectAdded(samples.e3);
}
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
- @CollectionSize.Require(absent = ZERO)
- public void testPutAbsentConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
- put(samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
- @CollectionSize.Require(absent = ZERO)
- public void testPutAbsentConcurrentWithKeySetIteration() {
- try {
- Iterator<K> iterator = getMap().keySet().iterator();
- put(samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
- @CollectionSize.Require(absent = ZERO)
- public void testPutAbsentConcurrentWithValueIteration() {
- try {
- Iterator<V> iterator = getMap().values().iterator();
- put(samples.e3);
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@MapFeature.Require(absent = SUPPORTS_PUT)
public void testPut_unsupportedNotPresent() {
try {
@@ -240,17 +193,4 @@ public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
private V put(Map.Entry<K, V> entry) {
return getMap().put(entry.getKey(), entry.getValue());
}
-
- /**
- * Returns the {@link Method} instance for {@link
- * #testPut_nullKeyUnsupported()} so that tests of {@link java.util.TreeMap}
- * can suppress it with {@code FeatureSpecificTestSuiteBuilder.suppressing()}
- * until <a
- * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun bug
- * 5045147</a> is fixed.
- */
- @GwtIncompatible("reflection")
- public static Method getPutNullKeyUnsupportedMethod() {
- return Helpers.getMethod(MapPutTester.class, "testPut_nullKeyUnsupported");
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapRemoveTester.java
index 4a7a5b4..6ba33ce 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapRemoveTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapRemoveTester.java
@@ -16,23 +16,16 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
import com.google.common.collect.testing.WrongType;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.Map.Entry;
-
/**
* A generic JUnit test which tests {@code remove} operations on a map. Can't be
* invoked directly; please see
@@ -44,7 +37,6 @@ import java.util.Map.Entry;
* @author Chris Povirk
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class MapRemoveTester<K, V> extends AbstractMapTester<K, V> {
@MapFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(absent = ZERO)
@@ -57,48 +49,6 @@ public class MapRemoveTester<K, V> extends AbstractMapTester<K, V> {
expectMissing(samples.e0);
}
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_REMOVE})
- @CollectionSize.Require(SEVERAL)
- public void testRemovePresentConcurrentWithEntrySetIteration() {
- try {
- Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
- getMap().remove(samples.e0.getKey());
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_REMOVE})
- @CollectionSize.Require(SEVERAL)
- public void testRemovePresentConcurrentWithKeySetIteration() {
- try {
- Iterator<K> iterator = getMap().keySet().iterator();
- getMap().remove(samples.e0.getKey());
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
- @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- SUPPORTS_REMOVE})
- @CollectionSize.Require(SEVERAL)
- public void testRemovePresentConcurrentWithValuesIteration() {
- try {
- Iterator<V> iterator = getMap().values().iterator();
- getMap().remove(samples.e0.getKey());
- iterator.next();
- fail("Expected ConcurrentModificationException");
- } catch (ConcurrentModificationException expected) {
- // success
- }
- }
-
@MapFeature.Require(SUPPORTS_REMOVE)
public void testRemove_notPresent() {
assertNull("remove(notPresent) should return null",
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapSerializationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapSerializationTester.java
deleted file mode 100644
index 3d5c675..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapSerializationTester.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.testing.SerializableTester;
-
-/**
- * Basic serialization test for maps.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class MapSerializationTester<K, V> extends AbstractMapTester<K, V> {
- @CollectionFeature.Require(SERIALIZABLE)
- public void testReserializeMap() {
- SerializableTester.reserializeAndAssert(getMap());
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/MapSizeTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/MapSizeTester.java
index f3df9f0..6b3439a 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/MapSizeTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/MapSizeTester.java
@@ -16,7 +16,6 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.AbstractMapTester;
/**
@@ -28,9 +27,8 @@ import com.google.common.collect.testing.AbstractMapTester;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class MapSizeTester<K, V> extends AbstractMapTester<K, V> {
public void testSize() {
assertEquals("size():", getNumElements(), getMap().size());
}
-}
+} \ No newline at end of file
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/Platform.java b/guava-testlib/src/com/google/common/collect/testing/testers/Platform.java
index cd3eb84..ba4d3f0 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/Platform.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/Platform.java
@@ -16,17 +16,28 @@
package com.google.common.collect.testing.testers;
-import com.google.common.annotations.GwtCompatible;
+import java.lang.reflect.Method;
/**
* This class is emulated in GWT.
*
* @author Hayward Chan
*/
-@GwtCompatible
class Platform {
/**
+ * Delegate to {@link Class#getMethod(String, Class[])}. Not
+ * usable in GWT.
+ */
+ static Method getMethod(Class<?> clazz, String methodName) {
+ try {
+ return clazz.getMethod(methodName);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Format the template with args, only supports the placeholder
* {@code %s}.
*/
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/QueueElementTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/QueueElementTester.java
index 26570ed..7c5ce41 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/QueueElementTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/QueueElementTester.java
@@ -21,7 +21,6 @@ import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -36,7 +35,6 @@ import java.util.NoSuchElementException;
*
* @author Jared Levy
*/
-@GwtCompatible
public class QueueElementTester<E> extends AbstractQueueTester<E> {
@CollectionSize.Require(ZERO)
public void testElement_empty() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/QueueOfferTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/QueueOfferTester.java
index d9a67ea..f4fa792 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/QueueOfferTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/QueueOfferTester.java
@@ -19,7 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
/**
@@ -32,7 +31,6 @@ import com.google.common.collect.testing.features.CollectionFeature;
* @author Jared Levy
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class QueueOfferTester<E> extends AbstractQueueTester<E> {
@CollectionFeature.Require(SUPPORTS_ADD)
public void testOffer_supportedNotPresent() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/QueuePeekTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/QueuePeekTester.java
index c9c045e..341e68d 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/QueuePeekTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/QueuePeekTester.java
@@ -21,7 +21,6 @@ import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -34,7 +33,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author Jared Levy
*/
-@GwtCompatible
public class QueuePeekTester<E> extends AbstractQueueTester<E> {
@CollectionSize.Require(ZERO)
public void testPeek_empty() {
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/QueuePollTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/QueuePollTester.java
index 14c2803..a447bb0 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/QueuePollTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/QueuePollTester.java
@@ -22,7 +22,6 @@ import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -36,7 +35,6 @@ import com.google.common.collect.testing.features.CollectionSize;
* @author Jared Levy
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class QueuePollTester<E> extends AbstractQueueTester<E> {
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ZERO)
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/QueueRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/QueueRemoveTester.java
index 718f63b..07596f4 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/QueueRemoveTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/QueueRemoveTester.java
@@ -22,7 +22,6 @@ import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -38,7 +37,6 @@ import java.util.NoSuchElementException;
* @author Jared Levy
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class QueueRemoveTester<E> extends AbstractQueueTester<E> {
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ZERO)
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SetAddAllTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetAddAllTester.java
index 638d6ef..0dac713 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SetAddAllTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetAddAllTester.java
@@ -16,10 +16,9 @@
package com.google.common.collect.testing.testers;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD_ALL;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -34,9 +33,8 @@ import com.google.common.collect.testing.features.CollectionSize;
* @author Kevin Bourrillion
*/
@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
-@GwtCompatible
public class SetAddAllTester<E> extends AbstractSetTester<E> {
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_supportedSomePresent() {
assertTrue("add(somePresent) should return true",
@@ -44,7 +42,7 @@ public class SetAddAllTester<E> extends AbstractSetTester<E> {
expectAdded(samples.e3);
}
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
public void testAddAll_withDuplicates() {
MinimalCollection<E> elementsToAdd
= MinimalCollection.of(samples.e3, samples.e4, samples.e3, samples.e4);
@@ -53,7 +51,7 @@ public class SetAddAllTester<E> extends AbstractSetTester<E> {
expectAdded(samples.e3, samples.e4);
}
- @CollectionFeature.Require(SUPPORTS_ADD)
+ @CollectionFeature.Require(SUPPORTS_ADD_ALL)
@CollectionSize.Require(absent = ZERO)
public void testAddAll_supportedAllPresent() {
assertFalse("add(allPresent) should return false",
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SetAddTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetAddTester.java
index 216411e..d9d8601 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SetAddTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetAddTester.java
@@ -20,9 +20,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.ALLOW
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -37,7 +34,6 @@ import java.lang.reflect.Method;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
public class SetAddTester<E> extends AbstractSetTester<E> {
@CollectionFeature.Require(SUPPORTS_ADD)
@CollectionSize.Require(absent = ZERO)
@@ -60,8 +56,7 @@ public class SetAddTester<E> extends AbstractSetTester<E> {
* {@link #testAdd_supportedNullPresent()} so that tests can suppress it. See
* {@link CollectionAddTester#getAddNullSupportedMethod()} for details.
*/
- @GwtIncompatible("reflection")
public static Method getAddSupportedNullPresentMethod() {
- return Helpers.getMethod(SetAddTester.class, "testAdd_supportedNullPresent");
+ return Platform.getMethod(SetAddTester.class, "testAdd_supportedNullPresent");
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SetCreationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetCreationTester.java
index f81314d..50d83c7 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SetCreationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetCreationTester.java
@@ -21,7 +21,6 @@ import static com.google.common.collect.testing.features.CollectionFeature.REJEC
import static com.google.common.collect.testing.features.CollectionSize.ONE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -37,7 +36,6 @@ import java.util.List;
*
* @author Chris Povirk
*/
-@GwtCompatible
public class SetCreationTester<E> extends AbstractSetTester<E> {
@CollectionFeature.Require(value = ALLOWS_NULL_VALUES,
absent = REJECTS_DUPLICATES_AT_CREATION)
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SetEqualsTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetEqualsTester.java
index 9989d2d..a783a44 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SetEqualsTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetEqualsTester.java
@@ -18,7 +18,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.MinimalSet;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -34,7 +33,6 @@ import java.util.Set;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class SetEqualsTester<E> extends AbstractSetTester<E> {
public void testEquals_otherSetWithSameElements() {
assertTrue(
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SetHashCodeTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetHashCodeTester.java
index 09c6f5d..e8fc705 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SetHashCodeTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetHashCodeTester.java
@@ -18,9 +18,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -34,7 +31,6 @@ import java.util.Collection;
*
* @author George van den Driessche
*/
-@GwtCompatible(emulated = true)
public class SetHashCodeTester<E> extends AbstractSetTester<E> {
public void testHashCode() {
int expectedHashCode = 0;
@@ -69,10 +65,9 @@ public class SetHashCodeTester<E> extends AbstractSetTester<E> {
* unhashable objects can suppress it with
* {@code FeatureSpecificTestSuiteBuilder.suppressing()}.
*/
- @GwtIncompatible("reflection")
public static Method[] getHashCodeMethods() {
return new Method[]{
- Helpers.getMethod(SetHashCodeTester.class, "testHashCode"),
- Helpers.getMethod(SetHashCodeTester.class, "testHashCode_containingNull") };
+ Platform.getMethod(SetHashCodeTester.class, "testHashCode"),
+ Platform.getMethod(SetHashCodeTester.class, "testHashCode_containingNull") };
}
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetNavigationTester.java
index 14c6a47..a35595a 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/NavigableSetNavigationTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetNavigationTester.java
@@ -25,22 +25,21 @@ import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NavigableSet;
-import java.util.TreeSet;
+import java.util.NoSuchElementException;
/**
* A generic JUnit test which tests operations on a NavigableSet. Can't be
- * invoked directly; please see {@code NavigableSetTestSuiteBuilder}.
+ * invoked directly; please see {@code SetTestSuiteBuilder}.
*
* @author Jesse Wilson
* @author Louis Wasserman
*/
-public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
+public class SetNavigationTester<E> extends AbstractSetTester<E> {
private NavigableSet<E> navigableSet;
private List<E> values;
@@ -64,7 +63,7 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
}
}
}
-
+
/**
* Resets the contents of navigableSet to have elements a, c, for the
* navigation tests.
@@ -74,6 +73,15 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
navigableSet = (NavigableSet<E>) getSet();
}
+ @CollectionSize.Require(ZERO)
+ public void testEmptySetFirst() {
+ try {
+ navigableSet.first();
+ fail();
+ } catch (NoSuchElementException e) {
+ }
+ }
+
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ZERO)
public void testEmptySetPollFirst() {
@@ -88,12 +96,26 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
assertNull(navigableSet.higher(samples.e0));
}
+ @CollectionSize.Require(ZERO)
+ public void testEmptySetLast() {
+ try {
+ navigableSet.last();
+ fail();
+ } catch (NoSuchElementException e) {
+ }
+ }
+
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ZERO)
public void testEmptySetPollLast() {
assertNull(navigableSet.pollLast());
}
+ @CollectionSize.Require(ONE)
+ public void testSingletonSetFirst() {
+ assertEquals(a, navigableSet.first());
+ }
+
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ONE)
public void testSingletonSetPollFirst() {
@@ -109,6 +131,11 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
assertNull(navigableSet.higher(samples.e0));
}
+ @CollectionSize.Require(ONE)
+ public void testSingletonSetLast() {
+ assertEquals(a, navigableSet.last());
+ }
+
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(ONE)
public void testSingletonSetPollLast() {
@@ -116,6 +143,11 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
assertTrue(navigableSet.isEmpty());
}
+ @CollectionSize.Require(SEVERAL)
+ public void testFirst() {
+ assertEquals(a, navigableSet.first());
+ }
+
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(SEVERAL)
public void testPollFirst() {
@@ -134,15 +166,14 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
}
@CollectionSize.Require(SEVERAL)
- public void testLowerHole() {
+ public void testLower() {
resetWithHole();
assertEquals(null, navigableSet.lower(a));
assertEquals(a, navigableSet.lower(b));
assertEquals(a, navigableSet.lower(c));
}
-
@CollectionSize.Require(SEVERAL)
- public void testFloorHole() {
+ public void testFloor() {
resetWithHole();
assertEquals(a, navigableSet.floor(a));
assertEquals(a, navigableSet.floor(b));
@@ -150,7 +181,7 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
}
@CollectionSize.Require(SEVERAL)
- public void testCeilingHole() {
+ public void testCeiling() {
resetWithHole();
assertEquals(a, navigableSet.ceiling(a));
assertEquals(c, navigableSet.ceiling(b));
@@ -158,44 +189,16 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
}
@CollectionSize.Require(SEVERAL)
- public void testHigherHole() {
+ public void testHigher() {
resetWithHole();
assertEquals(c, navigableSet.higher(a));
assertEquals(c, navigableSet.higher(b));
assertEquals(null, navigableSet.higher(c));
}
- /*
- * TODO(cpovirk): make "too small" and "too large" elements available for better navigation
- * testing. At that point, we may be able to eliminate the "hole" tests, which would mean that
- * ContiguousSet's tests would no longer need to suppress them.
- */
- @CollectionSize.Require(SEVERAL)
- public void testLower() {
- assertEquals(null, navigableSet.lower(a));
- assertEquals(a, navigableSet.lower(b));
- assertEquals(b, navigableSet.lower(c));
- }
-
@CollectionSize.Require(SEVERAL)
- public void testFloor() {
- assertEquals(a, navigableSet.floor(a));
- assertEquals(b, navigableSet.floor(b));
- assertEquals(c, navigableSet.floor(c));
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testCeiling() {
- assertEquals(a, navigableSet.ceiling(a));
- assertEquals(b, navigableSet.ceiling(b));
- assertEquals(c, navigableSet.ceiling(c));
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testHigher() {
- assertEquals(b, navigableSet.higher(a));
- assertEquals(c, navigableSet.higher(b));
- assertEquals(null, navigableSet.higher(c));
+ public void testLast() {
+ assertEquals(c, navigableSet.last());
}
@CollectionFeature.Require(SUPPORTS_REMOVE)
@@ -224,34 +227,4 @@ public class NavigableSetNavigationTester<E> extends AbstractSetTester<E> {
Collections.reverse(descending);
assertEquals(values, descending);
}
-
- public void testEmptySubSet() {
- NavigableSet<E> empty = navigableSet.subSet(samples.e0, false, samples.e0, false);
- assertEquals(new TreeSet<E>(), empty);
- }
-
- /*
- * TODO(cpovirk): more testing of subSet/headSet/tailSet/descendingSet? and/or generate derived
- * suites?
- */
-
- /**
- * Returns the {@link Method} instances for the test methods in this class that create a set with
- * a "hole" in it so that set tests of {@code ContiguousSet} can suppress them with {@code
- * FeatureSpecificTestSuiteBuilder.suppressing()}.
- */
- /*
- * TODO(cpovirk): or we could make HOLES_FORBIDDEN a feature. Or we could declare that
- * implementations are permitted to throw IAE if a hole is requested, and we could update
- * test*Hole to permit IAE. (But might this ignore genuine bugs?) But see the TODO above
- * testLower, which could make this all unnecessary
- */
- public static Method[] getHoleMethods() {
- return new Method[] {
- Helpers.getMethod(NavigableSetNavigationTester.class, "testLowerHole"),
- Helpers.getMethod(NavigableSetNavigationTester.class, "testFloorHole"),
- Helpers.getMethod(NavigableSetNavigationTester.class, "testCeilingHole"),
- Helpers.getMethod(NavigableSetNavigationTester.class, "testHigherHole"),
- };
- }
}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SetRemoveTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SetRemoveTester.java
index ffc5044..1310cff 100644
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SetRemoveTester.java
+++ b/guava-testlib/src/com/google/common/collect/testing/testers/SetRemoveTester.java
@@ -19,7 +19,6 @@ package com.google.common.collect.testing.testers;
import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
@@ -32,7 +31,6 @@ import com.google.common.collect.testing.features.CollectionSize;
*
* @author George van den Driessche
*/
-@GwtCompatible
public class SetRemoveTester<E> extends AbstractSetTester<E> {
@CollectionFeature.Require(SUPPORTS_REMOVE)
@CollectionSize.Require(absent = ZERO)
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SortedMapNavigationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SortedMapNavigationTester.java
deleted file mode 100644
index 9552a41..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SortedMapNavigationTester.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AbstractMapTester;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.SortedMap;
-
-/**
- * A generic JUnit test which tests operations on a SortedMap. Can't be
- * invoked directly; please see {@code SortedMapTestSuiteBuilder}.
- *
- * @author Jesse Wilson
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class SortedMapNavigationTester<K, V> extends AbstractMapTester<K, V> {
-
- private SortedMap<K, V> navigableMap;
- private Entry<K, V> a;
- private Entry<K, V> c;
-
- @Override public void setUp() throws Exception {
- super.setUp();
- navigableMap = (SortedMap<K, V>) getMap();
- List<Entry<K, V>> entries = Helpers.copyToList(getSubjectGenerator().getSampleElements(
- getSubjectGenerator().getCollectionSize().getNumElements()));
- Collections.sort(entries, Helpers.<K, V>entryComparator(navigableMap.comparator()));
-
- // some tests assume SEVERAL == 3
- if (entries.size() >= 1) {
- a = entries.get(0);
- if (entries.size() >= 3) {
- c = entries.get(2);
- }
- }
- }
-
- @CollectionSize.Require(ZERO)
- public void testEmptyMapFirst() {
- try {
- navigableMap.firstKey();
- fail();
- } catch (NoSuchElementException e) {
- }
- }
-
- @CollectionSize.Require(ZERO)
- public void testEmptyMapLast() {
- try {
- assertNull(navigableMap.lastKey());
- fail();
- } catch (NoSuchElementException e) {
- }
- }
-
- @CollectionSize.Require(ONE)
- public void testSingletonMapFirst() {
- assertEquals(a.getKey(), navigableMap.firstKey());
- }
-
- @CollectionSize.Require(ONE)
- public void testSingletonMapLast() {
- assertEquals(a.getKey(), navigableMap.lastKey());
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testFirst() {
- assertEquals(a.getKey(), navigableMap.firstKey());
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testLast() {
- assertEquals(c.getKey(), navigableMap.lastKey());
- }
-}
diff --git a/guava-testlib/src/com/google/common/collect/testing/testers/SortedSetNavigationTester.java b/guava-testlib/src/com/google/common/collect/testing/testers/SortedSetNavigationTester.java
deleted file mode 100644
index b3a52d2..0000000
--- a/guava-testlib/src/com/google/common/collect/testing/testers/SortedSetNavigationTester.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.testers;
-
-import static com.google.common.collect.testing.features.CollectionSize.ONE;
-import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
-import static com.google.common.collect.testing.features.CollectionSize.ZERO;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.SortedSet;
-
-/**
- * A generic JUnit test which tests operations on a SortedSet. Can't be
- * invoked directly; please see {@code SortedSetTestSuiteBuilder}.
- *
- * @author Jesse Wilson
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class SortedSetNavigationTester<E> extends AbstractSetTester<E> {
-
- private SortedSet<E> sortedSet;
- private List<E> values;
- private E a;
- private E b;
- private E c;
-
- @Override public void setUp() throws Exception {
- super.setUp();
- sortedSet = (SortedSet<E>) getSet();
- values = Helpers.copyToList(getSubjectGenerator().getSampleElements(
- getSubjectGenerator().getCollectionSize().getNumElements()));
- Collections.sort(values, sortedSet.comparator());
-
- // some tests assume SEVERAL == 3
- if (values.size() >= 1) {
- a = values.get(0);
- if (values.size() >= 3) {
- b = values.get(1);
- c = values.get(2);
- }
- }
- }
-
- @CollectionSize.Require(ZERO)
- public void testEmptySetFirst() {
- try {
- sortedSet.first();
- fail();
- } catch (NoSuchElementException e) {
- }
- }
-
- @CollectionSize.Require(ZERO)
- public void testEmptySetLast() {
- try {
- sortedSet.last();
- fail();
- } catch (NoSuchElementException e) {
- }
- }
-
- @CollectionSize.Require(ONE)
- public void testSingletonSetFirst() {
- assertEquals(a, sortedSet.first());
- }
-
- @CollectionSize.Require(ONE)
- public void testSingletonSetLast() {
- assertEquals(a, sortedSet.last());
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testFirst() {
- assertEquals(a, sortedSet.first());
- }
-
- @CollectionSize.Require(SEVERAL)
- public void testLast() {
- assertEquals(c, sortedSet.last());
- }
-}
diff --git a/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java b/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java
deleted file mode 100644
index 3e13fa0..0000000
--- a/guava-testlib/src/com/google/common/testing/AbstractPackageSanityTests.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.not;
-import static com.google.common.testing.AbstractPackageSanityTests.Chopper.suffix;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.ClassPath;
-import com.google.common.testing.NullPointerTester.Visibility;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.TreeMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Automatically runs sanity checks against top level classes in the same package of the test that
- * extends {@code AbstractPackageSanityTests}. Currently sanity checks include {@link
- * NullPointerTester}, {@link EqualsTester} and {@link SerializableTester}. For example: <pre>
- * public class PackageSanityTests extends AbstractPackageSanityTests {}
- * </pre>
- *
- * <p>Note that only top-level classes with either a non-private constructor or a non-private static
- * factory method to construct instances can have their instance methods checked. For example: <pre>
- * public class Address {
- * private final String city;
- * private final String state;
- * private final String zipcode;
- *
- * public Address(String city, String state, String zipcode) {...}
- *
- * {@literal @Override} public boolean equals(Object obj) {...}
- * {@literal @Override} public int hashCode() {...}
- * ...
- * }
- * </pre>
- * No cascading checks are performed against the return values of methods unless the method is a
- * static factory method. Neither are semantics of mutation methods such as {@code
- * someList.add(obj)} checked. For more detailed discussion of supported and unsupported cases, see
- * {@link #testEquals}, {@link #testNulls} and {@link #testSerializable}.
- *
- * <p>For testing against the returned instances from a static factory class, such as <pre>
- * interface Book {...}
- * public class Books {
- * public static Book hardcover(String title) {...}
- * public static Book paperback(String title) {...}
- * }
- * </pre>
- * please use {@link ClassSanityTester#forAllPublicStaticMethods}.
- *
- * <p>This class incurs IO because it scans the classpath and reads classpath resources.
- *
- * @author Ben Yu
- * @since 14.0
- */
-@Beta
-// TODO: Switch to JUnit 4 and use @Parameterized and @BeforeClass
-public abstract class AbstractPackageSanityTests extends TestCase {
-
- /* The names of the expected method that tests null checks. */
- private static final ImmutableList<String> NULL_TEST_METHOD_NAMES = ImmutableList.of(
- "testNulls", "testNull",
- "testNullPointers", "testNullPointer",
- "testNullPointerExceptions", "testNullPointerException");
-
- /* The names of the expected method that tests serializable. */
- private static final ImmutableList<String> SERIALIZABLE_TEST_METHOD_NAMES = ImmutableList.of(
- "testSerializable", "testSerialization",
- "testEqualsAndSerializable", "testEqualsAndSerialization");
-
- /* The names of the expected method that tests equals. */
- private static final ImmutableList<String> EQUALS_TEST_METHOD_NAMES = ImmutableList.of(
- "testEquals", "testEqualsAndHashCode",
- "testEqualsAndSerializable", "testEqualsAndSerialization",
- "testEquality");
-
- private static final Chopper TEST_SUFFIX =
- suffix("Test")
- .or(suffix("Tests"))
- .or(suffix("TestCase"))
- .or(suffix("TestSuite"));
-
- private final Logger logger = Logger.getLogger(getClass().getName());
- private final ClassSanityTester tester = new ClassSanityTester();
- private Visibility visibility = Visibility.PACKAGE;
- private Predicate<Class<?>> classFilter = new Predicate<Class<?>>() {
- @Override public boolean apply(Class<?> cls) {
- return visibility.isVisible(cls.getModifiers());
- }
- };
-
- /**
- * Restricts the sanity tests for public API only. By default, package-private API are also
- * covered.
- */
- protected final void publicApiOnly() {
- visibility = Visibility.PUBLIC;
- }
-
- /**
- * Tests all top-level public {@link Serializable} classes in the package. For a serializable
- * Class {@code C}:
- * <ul>
- * <li>If {@code C} explicitly implements {@link Object#equals}, the deserialized instance will be
- * checked to be equal to the instance before serialization.
- * <li>If {@code C} doesn't explicitly implement {@code equals} but instead inherits it from a
- * superclass, no equality check is done on the deserialized instance because it's not clear
- * whether the author intended for the class to be a value type.
- * <li>If a constructor or factory method takes a parameter whose type is interface, a dynamic
- * proxy will be passed to the method. It's possible that the method body expects an instance
- * method of the passed-in proxy to be of a certain value yet the proxy isn't aware of the
- * assumption, in which case the equality check before and after serialization will fail.
- * <li>If the constructor or factory method takes a parameter that {@link
- * AbstractPackageSanityTests} doesn't know how to construct, the test will fail.
- * <li>If there is no public constructor or public static factory method declared by {@code C},
- * {@code C} is skipped for serialization test, even if it implements {@link Serializable}.
- * <li>Serialization test is not performed on method return values unless the method is a public
- * static factory method whose return type is {@code C} or {@code C}'s subtype.
- * </ul>
- *
- * In all cases, if {@code C} needs custom logic for testing serialization, you can add an
- * explicit {@code testSerializable()} test in the corresponding {@code CTest} class, and {@code
- * C} will be excluded from automated serialization test performed by this method.
- */
- @Test
- public void testSerializable() throws Exception {
- // TODO: when we use @BeforeClass, we can pay the cost of class path scanning only once.
- for (Class<?> classToTest
- : findClassesToTest(loadClassesInPackage(), SERIALIZABLE_TEST_METHOD_NAMES)) {
- if (Serializable.class.isAssignableFrom(classToTest)) {
- try {
- Object instance = tester.instantiate(classToTest);
- if (instance != null) {
- if (isEqualsDefined(classToTest)) {
- SerializableTester.reserializeAndAssert(instance);
- } else {
- SerializableTester.reserialize(instance);
- }
- }
- } catch (Throwable e) {
- throw sanityError(classToTest, SERIALIZABLE_TEST_METHOD_NAMES, "serializable test", e);
- }
- }
- }
- }
-
- /**
- * Performs {@link NullPointerTester} checks for all top-level public classes in the package. For
- * a class {@code C}
- * <ul>
- * <li>All public static methods are checked such that passing null for any parameter that's not
- * annotated with {@link javax.annotation.Nullable} should throw {@link NullPointerException}.
- * <li>If there is any public constructor or public static factory method declared by the class,
- * all public instance methods will be checked too using the instance created by invoking the
- * constructor or static factory method.
- * <li>If the constructor or factory method used to construct instance takes a parameter that
- * {@link AbstractPackageSanityTests} doesn't know how to construct, the test will fail.
- * <li>If there is no public constructor or public static factory method declared by {@code C},
- * instance methods are skipped for nulls test.
- * <li>Nulls test is not performed on method return values unless the method is a public static
- * factory method whose return type is {@code C} or {@code C}'s subtype.
- * </ul>
- *
- * In all cases, if {@code C} needs custom logic for testing nulls, you can add an explicit {@code
- * testNulls()} test in the corresponding {@code CTest} class, and {@code C} will be excluded from
- * the automated null tests performed by this method.
- */
- @Test
- public void testNulls() throws Exception {
- for (Class<?> classToTest
- : findClassesToTest(loadClassesInPackage(), NULL_TEST_METHOD_NAMES)) {
- try {
- tester.doTestNulls(classToTest, visibility);
- } catch (Throwable e) {
- throw sanityError(classToTest, NULL_TEST_METHOD_NAMES, "nulls test", e);
- }
- }
- }
-
- /**
- * Tests {@code equals()} and {@code hashCode()} implementations for every top-level public class
- * in the package, that explicitly implements {@link Object#equals}. For a class {@code C}:
- * <ul>
- * <li>The public constructor or public static factory method with the most parameters is used to
- * construct the sample instances. In case of tie, the candidate constructors or factories are
- * tried one after another until one can be used to construct sample instances.
- * <li>For the constructor or static factory method used to construct instances, it's checked that
- * when equal parameters are passed, the result instance should also be equal; and vice versa.
- * <li>Inequality check is not performed against state mutation methods such as {@link List#add},
- * or functional update methods such as {@link com.google.common.base.Joiner#skipNulls}.
- * <li>If the constructor or factory method used to construct instance takes a parameter that
- * {@link AbstractPackageSanityTests} doesn't know how to construct, the test will fail.
- * <li>If there is no public constructor or public static factory method declared by {@code C},
- * {@code C} is skipped for equality test.
- * <li>Equality test is not performed on method return values unless the method is a public static
- * factory method whose return type is {@code C} or {@code C}'s subtype.
- * </ul>
- *
- * In all cases, if {@code C} needs custom logic for testing {@code equals()}, you can add an
- * explicit {@code testEquals()} test in the corresponding {@code CTest} class, and {@code C} will
- * be excluded from the automated {@code equals} test performed by this method.
- */
- @Test
- public void testEquals() throws Exception {
- for (Class<?> classToTest
- : findClassesToTest(loadClassesInPackage(), EQUALS_TEST_METHOD_NAMES)) {
- if (!classToTest.isEnum() && isEqualsDefined(classToTest)) {
- try {
- tester.doTestEquals(classToTest);
- } catch (Throwable e) {
- throw sanityError(classToTest, EQUALS_TEST_METHOD_NAMES, "equals test", e);
- }
- }
- }
- }
-
- /**
- * Sets the default value for {@code type}, when dummy value for a parameter of the same type
- * needs to be created in order to invoke a method or constructor. The default value isn't used in
- * testing {@link Object#equals} because more than one sample instances are needed for testing
- * inequality.
- */
- protected final <T> void setDefault(Class<T> type, T value) {
- tester.setDefault(type, value);
- }
-
- /** Specifies that classes that satisfy the given predicate aren't tested for sanity. */
- protected final void ignoreClasses(Predicate<? super Class<?>> condition) {
- this.classFilter = and(this.classFilter, not(condition));
- }
-
- private static AssertionFailedError sanityError(
- Class<?> cls, List<String> explicitTestNames, String description, Throwable e) {
- String message = String.format(
- "Error in automated %s of %s\n"
- + "If the class is better tested explicitly, you can add %s() to %sTest",
- description, cls, explicitTestNames.get(0), cls.getName());
- AssertionFailedError error = new AssertionFailedError(message);
- error.initCause(e);
- return error;
- }
-
- /**
- * Finds the classes not ending with a test suffix and not covered by an explicit test
- * whose name is {@code explicitTestName}.
- */
- @VisibleForTesting List<Class<?>> findClassesToTest(
- Iterable<? extends Class<?>> classes, Iterable<String> explicitTestNames) {
- // "a.b.Foo" -> a.b.Foo.class
- TreeMap<String, Class<?>> classMap = Maps.newTreeMap();
- for (Class<?> cls : classes) {
- classMap.put(cls.getName(), cls);
- }
- // Foo.class -> [FooTest.class, FooTests.class, FooTestSuite.class, ...]
- Multimap<Class<?>, Class<?>> testClasses = HashMultimap.create();
- LinkedHashSet<Class<?>> candidateClasses = Sets.newLinkedHashSet();
- for (Class<?> cls : classes) {
- Optional<String> testedClassName = TEST_SUFFIX.chop(cls.getName());
- if (testedClassName.isPresent()) {
- Class<?> testedClass = classMap.get(testedClassName.get());
- if (testedClass != null) {
- testClasses.put(testedClass, cls);
- }
- } else {
- candidateClasses.add(cls);
- }
- }
- List<Class<?>> result = Lists.newArrayList();
- NEXT_CANDIDATE: for (Class<?> candidate : Iterables.filter(candidateClasses, classFilter)) {
- for (Class<?> testClass : testClasses.get(candidate)) {
- if (hasTest(testClass, explicitTestNames)) {
- // covered by explicit test
- continue NEXT_CANDIDATE;
- }
- }
- result.add(candidate);
- }
- return result;
- }
-
- private List<Class<?>> loadClassesInPackage() throws IOException {
- List<Class<?>> classes = Lists.newArrayList();
- String packageName = getClass().getPackage().getName();
- for (ClassPath.ClassInfo classInfo
- : ClassPath.from(getClass().getClassLoader()).getTopLevelClasses(packageName)) {
- Class<?> cls;
- try {
- cls = classInfo.load();
- } catch (NoClassDefFoundError e) {
- // In case there were linking problems, this is probably not a class we care to test anyway.
- logger.log(Level.SEVERE, "Cannot load class " + classInfo + ", skipping...", e);
- continue;
- }
- if (!cls.isInterface()) {
- classes.add(cls);
- }
- }
- return classes;
- }
-
- private static boolean hasTest(Class<?> testClass, Iterable<String> testNames) {
- for (String testName : testNames) {
- try {
- testClass.getMethod(testName);
- return true;
- } catch (NoSuchMethodException e) {
- continue;
- }
- }
- return false;
- }
-
- private static boolean isEqualsDefined(Class<?> cls) {
- try {
- return !cls.getDeclaredMethod("equals", Object.class).isSynthetic();
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- static abstract class Chopper {
-
- final Chopper or(final Chopper you) {
- final Chopper i = this;
- return new Chopper() {
- @Override Optional<String> chop(String str) {
- return i.chop(str).or(you.chop(str));
- }
- };
- }
-
- abstract Optional<String> chop(String str);
-
- static Chopper suffix(final String suffix) {
- return new Chopper() {
- @Override Optional<String> chop(String str) {
- if (str.endsWith(suffix)) {
- return Optional.of(str.substring(0, str.length() - suffix.length()));
- } else {
- return Optional.absent();
- }
- }
- };
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java b/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java
deleted file mode 100644
index 4ebcc9a..0000000
--- a/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Charsets;
-import com.google.common.base.Defaults;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Splitter;
-import com.google.common.base.Ticker;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.Constraint;
-import com.google.common.collect.Constraints;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.ImmutableSortedMultiset;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.MapConstraint;
-import com.google.common.collect.MapConstraints;
-import com.google.common.collect.MapDifference;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.PeekingIterator;
-import com.google.common.collect.Range;
-import com.google.common.collect.RowSortedTable;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.collect.SortedMapDifference;
-import com.google.common.collect.SortedMultiset;
-import com.google.common.collect.SortedSetMultimap;
-import com.google.common.collect.Table;
-import com.google.common.collect.Tables;
-import com.google.common.collect.TreeBasedTable;
-import com.google.common.collect.TreeMultimap;
-import com.google.common.primitives.Primitives;
-import com.google.common.primitives.UnsignedInteger;
-import com.google.common.primitives.UnsignedLong;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Serializable;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.LongBuffer;
-import java.nio.ShortBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayDeque;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Currency;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.Queue;
-import java.util.Random;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.MatchResult;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
-
-/**
- * Supplies an arbitrary "default" instance for a wide range of types, often useful in testing
- * utilities.
- *
- * <p>Covers common types defined in {@code java.lang}, {@code java.lang.reflect}, {@code java.io},
- * {@code java.nio}, {@code java.math}, {@code java.util}, {@code java.util.concurrent},
- * {@code java.util.regex}, {@code com.google.common.base}, {@code com.google.common.collect}
- * and {@code com.google.common.primitives}. In addition, any public class that exposes a public
- * parameter-less constructor will be "new"d and returned.
- *
- * <p>All default instances returned by {@link #get} are generics-safe. Clients won't get type
- * errors for using {@code get(Comparator.class)} as a {@code Comparator<Foo>}, for example.
- * Immutable empty instances are returned for collection types; {@code ""} for string;
- * {@code 0} for number types; reasonable default instance for other stateless types. For mutable
- * types, a fresh instance is created each time {@code get()} is called.
- *
- * @author Kevin Bourrillion
- * @author Ben Yu
- * @since 12.0
- */
-@Beta
-public final class ArbitraryInstances {
-
- private static final ClassToInstanceMap<Object> DEFAULTS = ImmutableClassToInstanceMap.builder()
- // primitives
- .put(Object.class, "")
- .put(Number.class, 0)
- .put(UnsignedInteger.class, UnsignedInteger.ZERO)
- .put(UnsignedLong.class, UnsignedLong.ZERO)
- .put(BigInteger.class, BigInteger.ZERO)
- .put(BigDecimal.class, BigDecimal.ZERO)
- .put(CharSequence.class, "")
- .put(String.class, "")
- .put(Pattern.class, Pattern.compile(""))
- .put(MatchResult.class, Pattern.compile("").matcher("").toMatchResult())
- .put(TimeUnit.class, TimeUnit.SECONDS)
- .put(Charset.class, Charsets.UTF_8)
- .put(Currency.class, Currency.getInstance(Locale.US))
- .put(Locale.class, Locale.US)
- // common.base
- .put(CharMatcher.class, CharMatcher.NONE)
- .put(Joiner.class, Joiner.on(','))
- .put(Splitter.class, Splitter.on(','))
- .put(Optional.class, Optional.absent())
- .put(Predicate.class, Predicates.alwaysTrue())
- .put(Equivalence.class, Equivalence.equals())
- .put(Ticker.class, Ticker.systemTicker())
- // io types
- .put(InputStream.class, new ByteArrayInputStream(new byte[0]))
- .put(ByteArrayInputStream.class, new ByteArrayInputStream(new byte[0]))
- .put(Readable.class, new StringReader(""))
- .put(Reader.class, new StringReader(""))
- .put(StringReader.class, new StringReader(""))
- .put(Buffer.class, ByteBuffer.allocate(0))
- .put(CharBuffer.class, CharBuffer.allocate(0))
- .put(ByteBuffer.class, ByteBuffer.allocate(0))
- .put(ShortBuffer.class, ShortBuffer.allocate(0))
- .put(IntBuffer.class, IntBuffer.allocate(0))
- .put(LongBuffer.class, LongBuffer.allocate(0))
- .put(FloatBuffer.class, FloatBuffer.allocate(0))
- .put(DoubleBuffer.class, DoubleBuffer.allocate(0))
- .put(File.class, new File(""))
- // All collections are immutable empty. So safe for any type parameter.
- .put(Iterator.class, Iterators.emptyIterator())
- .put(PeekingIterator.class, Iterators.peekingIterator(Iterators.emptyIterator()))
- .put(ListIterator.class, ImmutableList.of().listIterator())
- .put(Iterable.class, ImmutableSet.of())
- .put(Collection.class, ImmutableList.of())
- .put(ImmutableCollection.class, ImmutableList.of())
- .put(List.class, ImmutableList.of())
- .put(ImmutableList.class, ImmutableList.of())
- .put(Set.class, ImmutableSet.of())
- .put(ImmutableSet.class, ImmutableSet.of())
- .put(SortedSet.class, ImmutableSortedSet.of())
- .put(ImmutableSortedSet.class, ImmutableSortedSet.of())
- .put(NavigableSet.class, Sets.unmodifiableNavigableSet(Sets.newTreeSet()))
- .put(Map.class, ImmutableMap.of())
- .put(ImmutableMap.class, ImmutableMap.of())
- .put(SortedMap.class, ImmutableSortedMap.of())
- .put(ImmutableSortedMap.class, ImmutableSortedMap.of())
- .put(NavigableMap.class, Maps.unmodifiableNavigableMap(Maps.newTreeMap()))
- .put(Multimap.class, ImmutableMultimap.of())
- .put(ImmutableMultimap.class, ImmutableMultimap.of())
- .put(ListMultimap.class, ImmutableListMultimap.of())
- .put(ImmutableListMultimap.class, ImmutableListMultimap.of())
- .put(SetMultimap.class, ImmutableSetMultimap.of())
- .put(ImmutableSetMultimap.class, ImmutableSetMultimap.of())
- .put(SortedSetMultimap.class, Multimaps.unmodifiableSortedSetMultimap(TreeMultimap.create()))
- .put(Multiset.class, ImmutableMultiset.of())
- .put(ImmutableMultiset.class, ImmutableMultiset.of())
- .put(SortedMultiset.class, ImmutableSortedMultiset.of())
- .put(ImmutableSortedMultiset.class, ImmutableSortedMultiset.of())
- .put(BiMap.class, ImmutableBiMap.of())
- .put(ImmutableBiMap.class, ImmutableBiMap.of())
- .put(Table.class, ImmutableTable.of())
- .put(ImmutableTable.class, ImmutableTable.of())
- .put(RowSortedTable.class, Tables.unmodifiableRowSortedTable(TreeBasedTable.create()))
- .put(ClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build())
- .put(ImmutableClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build())
- .put(Comparable.class, ByToString.INSTANCE)
- .put(Comparator.class, AlwaysEqual.INSTANCE)
- .put(Ordering.class, AlwaysEqual.INSTANCE)
- .put(Range.class, Range.all())
- .put(Constraint.class, Constraints.notNull())
- .put(MapConstraint.class, MapConstraints.notNull())
- .put(MapDifference.class, Maps.difference(ImmutableMap.of(), ImmutableMap.of()))
- .put(SortedMapDifference.class,
- Maps.difference(ImmutableSortedMap.of(), ImmutableSortedMap.of()))
- // reflect
- .put(AnnotatedElement.class, Object.class)
- .put(GenericDeclaration.class, Object.class)
- .put(Type.class, Object.class)
- .build();
-
- /**
- * type -> implementation. Inherently mutable interfaces and abstract classes are mapped to their
- * default implementations and are "new"d upon get().
- */
- private static final ConcurrentMap<Class<?>, Class<?>> implementations = Maps.newConcurrentMap();
-
- private static <T> void setImplementation(Class<T> type, Class<? extends T> implementation) {
- checkArgument(type != implementation, "Don't register %s to itself!", type);
- checkArgument(!DEFAULTS.containsKey(type),
- "A default value was already registered for %s", type);
- checkArgument(implementations.put(type, implementation) == null,
- "Implementation for %s was already registered", type);
- }
-
- static {
- setImplementation(Appendable.class, StringBuilder.class);
- setImplementation(BlockingQueue.class, LinkedBlockingDeque.class);
- setImplementation(BlockingDeque.class, LinkedBlockingDeque.class);
- setImplementation(ConcurrentMap.class, ConcurrentHashMap.class);
- setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class);
- setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class);
- setImplementation(Deque.class, ArrayDeque.class);
- setImplementation(OutputStream.class, ByteArrayOutputStream.class);
- setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class);
- setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class);
- setImplementation(Queue.class, ArrayDeque.class);
- setImplementation(Random.class, Dummies.DeterministicRandom.class);
- setImplementation(ScheduledThreadPoolExecutor.class,
- Dummies.DummyScheduledThreadPoolExecutor.class);
- setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class);
- setImplementation(Writer.class, StringWriter.class);
- setImplementation(Runnable.class, Dummies.DummyRunnable.class);
- setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class);
- setImplementation(Executor.class, Dummies.DummyExecutor.class);
- }
-
- @SuppressWarnings("unchecked") // it's a subtype map
- @Nullable
- private static <T> Class<? extends T> getImplementation(Class<T> type) {
- return (Class<? extends T>) implementations.get(type);
- }
-
- private static final Logger logger = Logger.getLogger(ArbitraryInstances.class.getName());
-
- /**
- * Returns an arbitrary value for {@code type} as the null value, or {@code null} if empty-ness is
- * unknown for the type.
- */
- @Nullable public static <T> T get(Class<T> type) {
- T defaultValue = DEFAULTS.getInstance(type);
- if (defaultValue != null) {
- return defaultValue;
- }
- Class<? extends T> implementation = getImplementation(type);
- if (implementation != null) {
- return get(implementation);
- }
- if (type.isEnum()) {
- T[] enumConstants = type.getEnumConstants();
- return (enumConstants.length == 0)
- ? null
- : enumConstants[0];
- }
- if (type.isArray()) {
- return createEmptyArray(type);
- }
- T jvmDefault = Defaults.defaultValue(Primitives.unwrap(type));
- if (jvmDefault != null) {
- return jvmDefault;
- }
- if (Modifier.isAbstract(type.getModifiers()) || !Modifier.isPublic(type.getModifiers())) {
- return null;
- }
- final Constructor<T> constructor;
- try {
- constructor = type.getConstructor();
- } catch (NoSuchMethodException e) {
- return null;
- }
- constructor.setAccessible(true); // accessibility check is too slow
- try {
- return constructor.newInstance();
- } catch (InstantiationException impossible) {
- throw new AssertionError(impossible);
- } catch (IllegalAccessException impossible) {
- throw new AssertionError(impossible);
- } catch (InvocationTargetException e) {
- logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause());
- return null;
- }
- }
-
- @SuppressWarnings("unchecked") // same component type means same array type
- private static <T> T createEmptyArray(Class<T> arrayType) {
- return (T) Array.newInstance(arrayType.getComponentType(), 0);
- }
-
- // Internal implementations of some classes, with public default constructor that get() needs.
- private static final class Dummies {
-
- public static final class InMemoryPrintStream extends PrintStream {
- public InMemoryPrintStream() {
- super(new ByteArrayOutputStream());
- }
- }
-
- public static final class InMemoryPrintWriter extends PrintWriter {
- public InMemoryPrintWriter() {
- super(new StringWriter());
- }
- }
-
- public static final class DeterministicRandom extends Random {
- @SuppressWarnings("unused") // invoked by reflection
- public DeterministicRandom() {
- super(0);
- }
- }
-
- public static final class DummyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
- public DummyScheduledThreadPoolExecutor() {
- super(1);
- }
- }
-
- public static final class DummyCountDownLatch extends CountDownLatch {
- public DummyCountDownLatch() {
- super(0);
- }
- }
-
- public static final class DummyRunnable implements Runnable, Serializable {
- @Override public void run() {}
- }
-
- public static final class DummyThreadFactory implements ThreadFactory, Serializable {
- @Override public Thread newThread(Runnable r) {
- return new Thread(r);
- }
- }
-
- public static final class DummyExecutor implements Executor, Serializable {
- @Override public void execute(Runnable command) {}
- }
- }
-
- // Compare by toString() to satisfy 2 properties:
- // 1. compareTo(null) should throw NullPointerException
- // 2. the order is deterministic and easy to understand, for debugging purpose.
- private static final class ByToString implements Comparable<Object>, Serializable {
- private static final ByToString INSTANCE = new ByToString();
-
- @Override public int compareTo(Object o) {
- return toString().compareTo(o.toString());
- }
-
- @Override public String toString() {
- return "BY_TO_STRING";
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
- }
-
- // Always equal is a valid total ordering. And it works for any Object.
- private static final class AlwaysEqual extends Ordering<Object> implements Serializable {
- private static final AlwaysEqual INSTANCE = new AlwaysEqual();
-
- @Override public int compare(Object o1, Object o2) {
- return 0;
- }
-
- @Override public String toString() {
- return "ALWAYS_EQUAL";
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
- }
-
- private ArbitraryInstances() {}
-}
diff --git a/guava-testlib/src/com/google/common/testing/ClassSanityTester.java b/guava-testlib/src/com/google/common/testing/ClassSanityTester.java
deleted file mode 100644
index 4b273fb..0000000
--- a/guava-testlib/src/com/google/common/testing/ClassSanityTester.java
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MutableClassToInstanceMap;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
-import com.google.common.primitives.Ints;
-import com.google.common.reflect.Invokable;
-import com.google.common.reflect.Parameter;
-import com.google.common.reflect.Reflection;
-import com.google.common.reflect.TypeToken;
-import com.google.common.testing.NullPointerTester.Visibility;
-import com.google.common.testing.RelationshipTester.Item;
-import com.google.common.testing.RelationshipTester.ItemReporter;
-
-import junit.framework.Assert;
-import junit.framework.AssertionFailedError;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Tester that runs automated sanity tests for any given class. A typical use case is to test static
- * factory classes like: <pre>
- * interface Book {...}
- * public class Books {
- * public static Book hardcover(String title) {...}
- * public static Book paperback(String title) {...}
- * }
- * </pre>
- * And all the created {@code Book} instances can be tested with: <pre>
- * new ClassSanityTester()
- * .forAllPublicStaticMethods(Books.class)
- * .thatReturn(Book.class)
- * .testEquals(); // or testNulls(), testSerializable() etc.
- * </pre>
- *
- * @author Ben Yu
- * @since 14.0
- */
-@Beta
-public final class ClassSanityTester {
-
- private static final Ordering<Invokable<?, ?>> BY_METHOD_NAME =
- new Ordering<Invokable<?, ?>>() {
- @Override public int compare(Invokable<?, ?> left, Invokable<?, ?> right) {
- return left.getName().compareTo(right.getName());
- }
- };
-
- private static final Ordering<Invokable<?, ?>> BY_PARAMETERS =
- new Ordering<Invokable<?, ?>>() {
- @Override public int compare(Invokable<?, ?> left, Invokable<?, ?> right) {
- return Ordering.usingToString().compare(left.getParameters(), right.getParameters());
- }
- };
-
- private static final Ordering<Invokable<?, ?>> BY_NUMBER_OF_PARAMETERS =
- new Ordering<Invokable<?, ?>>() {
- @Override public int compare(Invokable<?, ?> left, Invokable<?, ?> right) {
- return Ints.compare(left.getParameters().size(), right.getParameters().size());
- }
- };
-
- private final MutableClassToInstanceMap<Object> defaultValues =
- MutableClassToInstanceMap.create();
- private final ListMultimap<Class<?>, Object> sampleInstances = ArrayListMultimap.create();
- private final NullPointerTester nullPointerTester = new NullPointerTester();
-
- public ClassSanityTester() {
- // TODO(benyu): bake these into ArbitraryInstances.
- setDefault(byte.class, (byte) 1);
- setDefault(Byte.class, (byte) 1);
- setDefault(short.class, (short) 1);
- setDefault(Short.class, (short) 1);
- setDefault(int.class, 1);
- setDefault(Integer.class, 1);
- setDefault(long.class, 1L);
- setDefault(Long.class, 1L);
- setDefault(float.class, 1F);
- setDefault(Float.class, 1F);
- setDefault(double.class, 1D);
- setDefault(Double.class, 1D);
- setDefault(Class.class, Class.class);
- }
-
- /**
- * Sets the default value for {@code type}. The default value isn't used in testing {@link
- * Object#equals} because more than one sample instances are needed for testing inequality.
- * To set sample instances for equality testing, use {@link #setSampleInstances} instead.
- */
- public <T> ClassSanityTester setDefault(Class<T> type, T value) {
- nullPointerTester.setDefault(type, value);
- defaultValues.putInstance(type, value);
- return this;
- }
-
- /**
- * Sets sample instances for {@code type} for purpose of {@code equals} testing, where different
- * values are needed to test inequality.
- *
- * <p>Used for types that {@link ClassSanityTester} doesn't already know how to sample.
- * It's usually necessary to add two unequal instances for each type, with the exception that if
- * the sample instance is to be passed to a {@link Nullable} parameter, one non-null sample is
- * sufficient. Setting an empty list will clear sample instances for {@code type}.
- */
- public <T> ClassSanityTester setSampleInstances(Class<T> type, Iterable<? extends T> instances) {
- ImmutableList<? extends T> samples = ImmutableList.copyOf(instances);
- sampleInstances.putAll(checkNotNull(type), samples);
- if (!samples.isEmpty()) {
- setDefault(type, samples.get(0));
- }
- return this;
- }
-
- /**
- * Tests that {@code cls} properly checks null on all constructor and method parameters that
- * aren't annotated with {@link Nullable}. In details:
- * <ul>
- * <li>All non-private static methods are checked such that passing null for any parameter that's
- * not annotated with {@link javax.annotation.Nullable} should throw {@link
- * NullPointerException}.
- * <li>If there is any non-private constructor or non-private static factory method declared by
- * {@code cls}, all non-private instance methods will be checked too using the instance
- * created by invoking the constructor or static factory method.
- * <li>If there is any non-private constructor or non-private static factory method declared by
- * {@code cls}:
- * <ul>
- * <li>Test will fail if default value for a parameter cannot be determined.
- * <li>Test will fail if the factory method returns null so testing instance methods is
- * impossible.
- * <li>Test will fail if the constructor or factory method throws exception.
- * </ul>
- * <li>If there is no non-private constructor or non-private static factory method declared by
- * {@code cls}, instance methods are skipped for nulls test.
- * <li>Nulls test is not performed on method return values unless the method is a non-private
- * static factory method whose return type is {@code cls} or {@code cls}'s subtype.
- * </ul>
- */
- public void testNulls(Class<?> cls) {
- try {
- doTestNulls(cls, Visibility.PACKAGE);
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
-
- void doTestNulls(Class<?> cls, Visibility visibility)
- throws ParameterNotInstantiableException, IllegalAccessException,
- InvocationTargetException, FactoryMethodReturnsNullException {
- if (!Modifier.isAbstract(cls.getModifiers())) {
- nullPointerTester.testConstructors(cls, visibility);
- }
- nullPointerTester.testStaticMethods(cls, visibility);
- if (hasInstanceMethodToTestNulls(cls, visibility)) {
- Object instance = instantiate(cls);
- if (instance != null) {
- nullPointerTester.testInstanceMethods(instance, visibility);
- }
- }
- }
-
- private boolean hasInstanceMethodToTestNulls(Class<?> c, Visibility visibility) {
- for (Method method : nullPointerTester.getInstanceMethodsToTest(c, visibility)) {
- for (Parameter param : Invokable.from(method).getParameters()) {
- if (!NullPointerTester.isPrimitiveOrNullable(param)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Tests the {@link Object#equals} and {@link Object#hashCode} of {@code cls}. In details:
- * <ul>
- * <li>The non-private constructor or non-private static factory method with the most parameters
- * is used to construct the sample instances. In case of tie, the candidate constructors or
- * factories are tried one after another until one can be used to construct sample instances.
- * <li>For the constructor or static factory method used to construct instances, it's checked that
- * when equal parameters are passed, the result instance should also be equal; and vice versa.
- * <li>If a non-private constructor or non-private static factory method exists: <ul>
- * <li>Test will fail if default value for a parameter cannot be determined.
- * <li>Test will fail if the factory method returns null so testing instance methods is
- * impossible.
- * <li>Test will fail if the constructor or factory method throws exception.
- * </ul>
- * <li>If there is no non-private constructor or non-private static factory method declared by
- * {@code cls}, no test is performed.
- * <li>Equality test is not performed on method return values unless the method is a non-private
- * static factory method whose return type is {@code cls} or {@code cls}'s subtype.
- * <li>Inequality check is not performed against state mutation methods such as {@link List#add},
- * or functional update methods such as {@link com.google.common.base.Joiner#skipNulls}.
- * </ul>
- *
- * <p>Note that constructors taking a builder object cannot be tested effectively because
- * semantics of builder can be arbitrarily complex. Still, a factory class can be created in the
- * test to facilitate equality testing. For example: <pre>
- * public class FooTest {
- *
- * private static class FooFactoryForTest {
- * public static Foo create(String a, String b, int c, boolean d) {
- * return Foo.builder()
- * .setA(a)
- * .setB(b)
- * .setC(c)
- * .setD(d)
- * .build();
- * }
- * }
- *
- * public void testEquals() {
- * new ClassSanityTester()
- * .forAllPublicStaticMethods(FooFactoryForTest.class)
- * .thatReturn(Foo.class)
- * .testEquals();
- * }
- * }
- * </pre>
- * It will test that Foo objects created by the {@code create(a, b, c, d)} factory method with
- * equal parameters are equal and vice versa, thus indirectly tests the builder equality.
- */
- public void testEquals(Class<?> cls) {
- try {
- doTestEquals(cls);
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
-
- void doTestEquals(Class<?> cls)
- throws ParameterNotInstantiableException, IllegalAccessException,
- InvocationTargetException, FactoryMethodReturnsNullException {
- if (cls.isEnum()) {
- return;
- }
- List<? extends Invokable<?, ?>> factories = Lists.reverse(getFactories(TypeToken.of(cls)));
- if (factories.isEmpty()) {
- return;
- }
- int numberOfParameters = factories.get(0).getParameters().size();
- List<ParameterNotInstantiableException> paramErrors = Lists.newArrayList();
- List<InvocationTargetException> instantiationExceptions = Lists.newArrayList();
- List<FactoryMethodReturnsNullException> nullErrors = Lists.newArrayList();
- // Try factories with the greatest number of parameters first.
- for (Invokable<?, ?> factory : factories) {
- if (factory.getParameters().size() == numberOfParameters) {
- try {
- testEqualsUsing(factory);
- return;
- } catch (ParameterNotInstantiableException e) {
- paramErrors.add(e);
- } catch (InvocationTargetException e) {
- instantiationExceptions.add(e);
- } catch (FactoryMethodReturnsNullException e) {
- nullErrors.add(e);
- }
- }
- }
- throwFirst(paramErrors);
- throwFirst(instantiationExceptions);
- throwFirst(nullErrors);
- }
-
- /**
- * Instantiates {@code cls} by invoking one of its non-private constructors or non-private static
- * factory methods with the parameters automatically provided using dummy values.
- *
- * @return The instantiated instance, or {@code null} if the class has no non-private constructor
- * or factory method to be constructed.
- */
- @Nullable <T> T instantiate(Class<T> cls)
- throws ParameterNotInstantiableException, IllegalAccessException,
- InvocationTargetException, FactoryMethodReturnsNullException {
- if (cls.isEnum()) {
- T[] constants = cls.getEnumConstants();
- if (constants.length > 0) {
- return constants[0];
- } else {
- return null;
- }
- }
- TypeToken<T> type = TypeToken.of(cls);
- List<ParameterNotInstantiableException> paramErrors = Lists.newArrayList();
- List<InvocationTargetException> instantiationExceptions = Lists.newArrayList();
- List<FactoryMethodReturnsNullException> nullErrors = Lists.newArrayList();
- for (Invokable<?, ? extends T> factory : getFactories(type)) {
- T instance;
- try {
- instance = instantiate(factory);
- } catch (ParameterNotInstantiableException e) {
- paramErrors.add(e);
- continue;
- } catch (InvocationTargetException e) {
- instantiationExceptions.add(e);
- continue;
- }
- if (instance == null) {
- nullErrors.add(new FactoryMethodReturnsNullException(factory));
- } else {
- return instance;
- }
- }
- throwFirst(paramErrors);
- throwFirst(instantiationExceptions);
- throwFirst(nullErrors);
- return null;
- }
-
- /**
- * Returns an object responsible for performing sanity tests against the return values
- * of all public static methods declared by {@code cls}, excluding superclasses.
- */
- public FactoryMethodReturnValueTester forAllPublicStaticMethods(Class<?> cls) {
- ImmutableList.Builder<Invokable<?, ?>> builder = ImmutableList.builder();
- for (Method method : cls.getDeclaredMethods()) {
- Invokable<?, ?> invokable = Invokable.from(method);
- invokable.setAccessible(true);
- if (invokable.isPublic() && invokable.isStatic() && !invokable.isSynthetic()) {
- builder.add(invokable);
- }
- }
- return new FactoryMethodReturnValueTester(cls, builder.build(), "public static methods");
- }
-
- /** Runs sanity tests against return values of static factory methods declared by a class. */
- public final class FactoryMethodReturnValueTester {
- private final Set<String> packagesToTest = Sets.newHashSet();
- private final Class<?> declaringClass;
- private final ImmutableList<Invokable<?, ?>> factories;
- private final String factoryMethodsDescription;
- private Class<?> returnTypeToTest = Object.class;
-
- private FactoryMethodReturnValueTester(
- Class<?> declaringClass,
- ImmutableList<Invokable<?, ?>> factories,
- String factoryMethodsDescription) {
- this.declaringClass = declaringClass;
- this.factories = factories;
- this.factoryMethodsDescription = factoryMethodsDescription;
- packagesToTest.add(Reflection.getPackageName(declaringClass));
- }
-
- /**
- * Specifies that only the methods that are declared to return {@code returnType} or its subtype
- * are tested.
- *
- * @return this tester object
- */
- public FactoryMethodReturnValueTester thatReturn(Class<?> returnType) {
- this.returnTypeToTest = returnType;
- return this;
- }
-
- /**
- * Tests null checks against the instance methods of the return values, if any.
- *
- * <p>Test fails if default value cannot be determined for a constructor or factory method
- * parameter, or if the constructor or factory method throws exception.
- *
- * @return this tester
- */
- public FactoryMethodReturnValueTester testNulls() throws Exception {
- for (Invokable<?, ?> factory : getFactoriesToTest()) {
- Object instance = instantiate(factory);
- if (instance != null
- && packagesToTest.contains(Reflection.getPackageName(instance.getClass()))) {
- try {
- nullPointerTester.testAllPublicInstanceMethods(instance);
- } catch (AssertionError e) {
- AssertionError error = new AssertionFailedError(
- "Null check failed on return value of " + factory);
- error.initCause(e);
- throw error;
- }
- }
- }
- return this;
- }
-
- /**
- * Tests {@link Object#equals} and {@link Object#hashCode} against the return values of the
- * static methods, by asserting that when equal parameters are passed to the same static method,
- * the return value should also be equal; and vice versa.
- *
- * <p>Test fails if default value cannot be determined for a constructor or factory method
- * parameter, or if the constructor or factory method throws exception.
- *
- * @return this tester
- */
- public FactoryMethodReturnValueTester testEquals() throws Exception {
- for (Invokable<?, ?> factory : getFactoriesToTest()) {
- try {
- testEqualsUsing(factory);
- } catch (FactoryMethodReturnsNullException e) {
- // If the factory returns null, we just skip it.
- }
- }
- return this;
- }
-
- /**
- * Runs serialization test on the return values of the static methods.
- *
- * <p>Test fails if default value cannot be determined for a constructor or factory method
- * parameter, or if the constructor or factory method throws exception.
- *
- * @return this tester
- */
- public FactoryMethodReturnValueTester testSerializable() throws Exception {
- for (Invokable<?, ?> factory : getFactoriesToTest()) {
- Object instance = instantiate(factory);
- if (instance != null) {
- try {
- SerializableTester.reserialize(instance);
- } catch (RuntimeException e) {
- AssertionError error = new AssertionFailedError(
- "Serialization failed on return value of " + factory);
- error.initCause(e.getCause());
- throw error;
- }
- }
- }
- return this;
- }
-
- /**
- * Runs equals and serialization test on the return values.
- *
- * <p>Test fails if default value cannot be determined for a constructor or factory method
- * parameter, or if the constructor or factory method throws exception.
- *
- * @return this tester
- */
- public FactoryMethodReturnValueTester testEqualsAndSerializable() throws Exception {
- for (Invokable<?, ?> factory : getFactoriesToTest()) {
- try {
- testEqualsUsing(factory);
- } catch (FactoryMethodReturnsNullException e) {
- // If the factory returns null, we just skip it.
- }
- Object instance = instantiate(factory);
- if (instance != null) {
- try {
- SerializableTester.reserializeAndAssert(instance);
- } catch (RuntimeException e) {
- AssertionError error = new AssertionFailedError(
- "Serialization failed on return value of " + factory);
- error.initCause(e.getCause());
- throw error;
- } catch (AssertionFailedError e) {
- AssertionError error = new AssertionFailedError(
- "Return value of " + factory + " reserialized to an unequal value");
- error.initCause(e);
- throw error;
- }
- }
- }
- return this;
- }
-
- private ImmutableList<Invokable<?, ?>> getFactoriesToTest() {
- ImmutableList.Builder<Invokable<?, ?>> builder = ImmutableList.builder();
- for (Invokable<?, ?> factory : factories) {
- if (returnTypeToTest.isAssignableFrom(factory.getReturnType().getRawType())) {
- builder.add(factory);
- }
- }
- ImmutableList<Invokable<?, ?>> factoriesToTest = builder.build();
- Assert.assertFalse("No " + factoryMethodsDescription + " that return "
- + returnTypeToTest.getName() + " or subtype are found in "
- + declaringClass + ".",
- factoriesToTest.isEmpty());
- return factoriesToTest;
- }
- }
-
- /**
- * Instantiates using {@code factory}. If {@code factory} is annotated with {@link Nullable} and
- * returns null, null will be returned.
- *
- * @throws ParameterNotInstantiableException if the static methods cannot be invoked because
- * the default value of a parameter cannot be determined.
- * @throws IllegalAccessException if the class isn't public or is nested inside a non-public
- * class, preventing its methods from being accessible.
- * @throws InvocationTargetException if a static method threw exception.
- */
- @Nullable private <T> T instantiate(Invokable<?, ? extends T> factory)
- throws ParameterNotInstantiableException, InvocationTargetException,
- IllegalAccessException {
- return invoke(factory, getDummyArguments(factory));
- }
-
- private void testEqualsUsing(final Invokable<?, ?> factory)
- throws ParameterNotInstantiableException, IllegalAccessException,
- InvocationTargetException, FactoryMethodReturnsNullException {
- List<Parameter> params = factory.getParameters();
- List<FreshValueGenerator> argGenerators = Lists.newArrayListWithCapacity(params.size());
- List<Object> args = Lists.newArrayListWithCapacity(params.size());
- for (Parameter param : params) {
- FreshValueGenerator generator = newFreshValueGenerator();
- argGenerators.add(generator);
- args.add(generateDummyArg(param, generator));
- }
- Object instance = createInstance(factory, args);
- List<Object> equalArgs = generateEqualFactoryArguments(factory, params, args);
- // Each group is a List of items, each item has a list of factory args.
- final List<List<List<Object>>> argGroups = Lists.newArrayList();
- argGroups.add(ImmutableList.of(args, equalArgs));
- EqualsTester tester = new EqualsTester().setItemReporter(new ItemReporter() {
- @Override String reportItem(Item item) {
- List<Object> factoryArgs = argGroups.get(item.groupNumber).get(item.itemNumber);
- return factory.getName() + "(" + Joiner.on(", ").useForNull("null").join(factoryArgs) + ")";
- }
- });
- tester.addEqualityGroup(instance, createInstance(factory, equalArgs));
- for (int i = 0; i < params.size(); i++) {
- List<Object> newArgs = Lists.newArrayList(args);
- Object newArg = argGenerators.get(i).generate(params.get(i).getType().getRawType());
- if (Objects.equal(args.get(i), newArg)) {
- // no value variance, no equality group
- continue;
- }
- newArgs.set(i, newArg);
- tester.addEqualityGroup(createInstance(factory, newArgs));
- argGroups.add(ImmutableList.of(newArgs));
- }
- tester.testEquals();
- }
-
- /**
- * Returns dummy factory arguments that are equal to {@code args} but may be different instances,
- * to be used to construct a second instance of the same equality group.
- */
- private List<Object> generateEqualFactoryArguments(
- Invokable<?, ?> factory, List<Parameter> params, List<Object> args)
- throws ParameterNotInstantiableException, FactoryMethodReturnsNullException,
- InvocationTargetException, IllegalAccessException {
- List<Object> equalArgs = Lists.newArrayList(args);
- for (int i = 0; i < args.size(); i++) {
- Parameter param = params.get(i);
- Object arg = args.get(i);
- // Use new fresh value generator because 'args' were populated with new fresh generator each.
- // Two newFreshValueGenerator() instances should normally generate equal value sequence.
- Object shouldBeEqualArg = generateDummyArg(param, newFreshValueGenerator());
- if (arg != shouldBeEqualArg
- && Objects.equal(arg, shouldBeEqualArg)
- && hashCodeInsensitiveToArgReference(factory, args, i, shouldBeEqualArg)
- && hashCodeInsensitiveToArgReference(
- factory, args, i, generateDummyArg(param, newFreshValueGenerator()))) {
- // If the implementation uses identityHashCode(), referential equality is
- // probably intended. So no point in using an equal-but-different factory argument.
- // We check twice to avoid confusion caused by accidental hash collision.
- equalArgs.set(i, shouldBeEqualArg);
- }
- }
- return equalArgs;
- }
-
- private static boolean hashCodeInsensitiveToArgReference(
- Invokable<?, ?> factory, List<Object> args, int i, Object alternateArg)
- throws FactoryMethodReturnsNullException, InvocationTargetException, IllegalAccessException {
- List<Object> tentativeArgs = Lists.newArrayList(args);
- tentativeArgs.set(i, alternateArg);
- return createInstance(factory, tentativeArgs).hashCode()
- == createInstance(factory, args).hashCode();
- }
-
- // sampleInstances is a type-safe class-values mapping, but we don't have a type-safe data
- // data structure to hold the mappings.
- @SuppressWarnings({"unchecked", "rawtypes"})
- private FreshValueGenerator newFreshValueGenerator() {
- FreshValueGenerator generator = new FreshValueGenerator() {
- @Override Object interfaceMethodCalled(Class<?> interfaceType, Method method) {
- return getDummyValue(TypeToken.of(interfaceType).method(method).getReturnType());
- }
- };
- for (Map.Entry<Class<?>, Collection<Object>> entry : sampleInstances.asMap().entrySet()) {
- generator.addSampleInstances((Class) entry.getKey(), entry.getValue());
- }
- return generator;
- }
-
- private static @Nullable Object generateDummyArg(Parameter param, FreshValueGenerator generator)
- throws ParameterNotInstantiableException {
- if (param.isAnnotationPresent(Nullable.class)) {
- return null;
- }
- Object arg = generator.generate(param.getType());
- if (arg == null) {
- throw new ParameterNotInstantiableException(param);
- }
- return arg;
- }
-
- private static <X extends Throwable> void throwFirst(List<X> exceptions) throws X {
- if (!exceptions.isEmpty()) {
- throw exceptions.get(0);
- }
- }
-
- /** Factories with the least number of parameters are listed first. */
- private static <T> ImmutableList<Invokable<?, ? extends T>> getFactories(TypeToken<T> type) {
- List<Invokable<?, ? extends T>> factories = Lists.newArrayList();
- for (Method method : type.getRawType().getDeclaredMethods()) {
- Invokable<?, ?> invokable = type.method(method);
- if (!invokable.isPrivate()
- && !invokable.isSynthetic()
- && invokable.isStatic()
- && type.isAssignableFrom(invokable.getReturnType())) {
- @SuppressWarnings("unchecked") // guarded by isAssignableFrom()
- Invokable<?, ? extends T> factory = (Invokable<?, ? extends T>) invokable;
- factories.add(factory);
- }
- }
- if (!Modifier.isAbstract(type.getRawType().getModifiers())) {
- for (Constructor<?> constructor : type.getRawType().getDeclaredConstructors()) {
- Invokable<T, T> invokable = type.constructor(constructor);
- if (!invokable.isPrivate() && !invokable.isSynthetic()) {
- factories.add(invokable);
- }
- }
- }
- for (Invokable<?, ?> factory : factories) {
- factory.setAccessible(true);
- }
- // Sorts methods/constructors with least number of parameters first since it's likely easier to
- // fill dummy parameter values for them. Ties are broken by name then by the string form of the
- // parameter list.
- return BY_NUMBER_OF_PARAMETERS.compound(BY_METHOD_NAME).compound(BY_PARAMETERS)
- .immutableSortedCopy(factories);
- }
-
- private List<Object> getDummyArguments(Invokable<?, ?> invokable)
- throws ParameterNotInstantiableException {
- List<Object> args = Lists.newArrayList();
- for (Parameter param : invokable.getParameters()) {
- if (param.isAnnotationPresent(Nullable.class)) {
- args.add(null);
- continue;
- }
- Object defaultValue = getDummyValue(param.getType());
- if (defaultValue == null) {
- throw new ParameterNotInstantiableException(param);
- }
- args.add(defaultValue);
- }
- return args;
- }
-
- private <T> T getDummyValue(TypeToken<T> type) {
- Class<? super T> rawType = type.getRawType();
- @SuppressWarnings("unchecked") // Assume all default values are generics safe.
- T defaultValue = (T) defaultValues.getInstance(rawType);
- if (defaultValue != null) {
- return defaultValue;
- }
- @SuppressWarnings("unchecked") // ArbitraryInstances always returns generics-safe dummies.
- T value = (T) ArbitraryInstances.get(rawType);
- if (value != null) {
- return value;
- }
- if (rawType.isInterface()) {
- return new SerializableDummyProxy(this).newProxy(type);
- }
- return null;
- }
-
- private static <T> T createInstance(Invokable<?, ? extends T> factory, List<?> args)
- throws FactoryMethodReturnsNullException, InvocationTargetException, IllegalAccessException {
- T instance = invoke(factory, args);
- if (instance == null) {
- throw new FactoryMethodReturnsNullException(factory);
- }
- return instance;
- }
-
- @Nullable private static <T> T invoke(Invokable<?, ? extends T> factory, List<?> args)
- throws InvocationTargetException, IllegalAccessException {
- T returnValue = factory.invoke(null, args.toArray());
- if (returnValue == null) {
- Assert.assertTrue(factory + " returns null but it's not annotated with @Nullable",
- factory.isAnnotationPresent(Nullable.class));
- }
- return returnValue;
- }
-
- /**
- * Thrown if the test tries to invoke a constructor or static factory method but failed because
- * the dummy value of a constructor or method parameter is unknown.
- */
- @VisibleForTesting static class ParameterNotInstantiableException extends Exception {
- public ParameterNotInstantiableException(Parameter parameter) {
- super("Cannot determine value for parameter " + parameter
- + " of " + parameter.getDeclaringInvokable());
- }
- }
-
- /**
- * Thrown if the test tries to invoke a static factory method to test instance methods but the
- * factory returned null.
- */
- @VisibleForTesting static class FactoryMethodReturnsNullException extends Exception {
- public FactoryMethodReturnsNullException(Invokable<?, ?> factory) {
- super(factory + " returns null and cannot be used to test instance methods.");
- }
- }
-
- private static final class SerializableDummyProxy extends DummyProxy
- implements Serializable {
-
- private transient final ClassSanityTester tester;
-
- SerializableDummyProxy(ClassSanityTester tester) {
- this.tester = tester;
- }
-
- @Override <R> R dummyReturnValue(TypeToken<R> returnType) {
- return tester.getDummyValue(returnType);
- }
-
- @Override public boolean equals(Object obj) {
- return obj instanceof SerializableDummyProxy;
- }
-
- @Override public int hashCode() {
- return 0;
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/testing/DummyProxy.java b/guava-testlib/src/com/google/common/testing/DummyProxy.java
deleted file mode 100644
index 71017af..0000000
--- a/guava-testlib/src/com/google/common/testing/DummyProxy.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.AbstractInvocationHandler;
-import com.google.common.reflect.Invokable;
-import com.google.common.reflect.Parameter;
-import com.google.common.reflect.TypeToken;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Generates a dummy interface proxy that simply returns a dummy value for each method.
- *
- * @author Ben Yu
- */
-abstract class DummyProxy {
-
- /**
- * Returns a new proxy for {@code interfaceType}. Proxies of the same interface are equal to each
- * other if the {@link DummyProxy} instance that created the proxies are equal.
- */
- final <T> T newProxy(TypeToken<T> interfaceType) {
- Set<Class<?>> interfaceClasses = Sets.newLinkedHashSet();
- interfaceClasses.addAll(interfaceType.getTypes().interfaces().rawTypes());
- // Make the proxy serializable to work with SerializableTester
- interfaceClasses.add(Serializable.class);
- Object dummy = Proxy.newProxyInstance(
- interfaceClasses.iterator().next().getClassLoader(),
- interfaceClasses.toArray(new Class<?>[interfaceClasses.size()]),
- new DummyHandler(interfaceType));
- @SuppressWarnings("unchecked") // interfaceType is T
- T result = (T) dummy;
- return result;
- }
-
- /** Returns the dummy return value for {@code returnType}. */
- abstract <R> R dummyReturnValue(TypeToken<R> returnType);
-
- private class DummyHandler extends AbstractInvocationHandler implements Serializable {
- private final TypeToken<?> interfaceType;
-
- DummyHandler(TypeToken<?> interfaceType) {
- this.interfaceType = interfaceType;
- }
-
- @Override protected Object handleInvocation(
- Object proxy, Method method, Object[] args) {
- Invokable<?, ?> invokable = interfaceType.method(method);
- ImmutableList<Parameter> params = invokable.getParameters();
- for (int i = 0; i < args.length; i++) {
- Parameter param = params.get(i);
- if (!param.isAnnotationPresent(Nullable.class)) {
- checkNotNull(args[i]);
- }
- }
- return dummyReturnValue(interfaceType.resolveType(method.getGenericReturnType()));
- }
-
- @Override public int hashCode() {
- return identity().hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof DummyHandler) {
- DummyHandler that = (DummyHandler) obj;
- return identity().equals(that.identity());
- } else {
- return false;
- }
- }
-
- private DummyProxy identity() {
- return DummyProxy.this;
- }
-
- @Override public String toString() {
- return "Dummy proxy for " + interfaceType;
- }
-
- // Since type variables aren't serializable, reduce the type down to raw type before
- // serialization.
- private Object writeReplace() {
- return new DummyHandler(TypeToken.of(interfaceType.getRawType()));
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/testing/EqualsTester.java b/guava-testlib/src/com/google/common/testing/EqualsTester.java
index 50b58c3..4ee69bf 100644
--- a/guava-testlib/src/com/google/common/testing/EqualsTester.java
+++ b/guava-testlib/src/com/google/common/testing/EqualsTester.java
@@ -47,13 +47,12 @@ import java.util.List;
* <ul>
* <li>comparing each object against itself returns true
* <li>comparing each object against null returns false
- * <li>comparing each object against an instance of an incompatible class
- * returns false
+ * <li>comparing each object an instance of an incompatible class returns false
* <li>comparing each pair of objects within the same equality group returns
* true
* <li>comparing each pair of objects from different equality groups returns
* false
- * <li>the hash codes of any two equal objects are equal
+ * <li>the hash code of any two equal objects are equal
* </ul>
*
* <p>When a test fails, the error message labels the objects involved in
@@ -76,7 +75,6 @@ public final class EqualsTester {
private static final int REPETITIONS = 3;
private final List<List<Object>> equalityGroups = Lists.newArrayList();
- private RelationshipTester.ItemReporter itemReporter = new RelationshipTester.ItemReporter();
/**
* Constructs an empty EqualsTester instance
@@ -112,7 +110,7 @@ public final class EqualsTester {
// RelationshipAssertions in general) accept null inputs?
assertTrue("$ITEM must be unequal to $UNRELATED", !Objects.equal(item, unrelated));
}
- }, itemReporter);
+ });
for (List<Object> group : equalityGroups) {
delegate.addRelatedGroup(group);
}
@@ -123,11 +121,6 @@ public final class EqualsTester {
return this;
}
- EqualsTester setItemReporter(RelationshipTester.ItemReporter reporter) {
- this.itemReporter = checkNotNull(reporter);
- return this;
- }
-
private void testItems() {
for (Object item : Iterables.concat(equalityGroups)) {
assertTrue(item + " must be unequal to null", !item.equals(null));
diff --git a/guava-testlib/src/com/google/common/testing/EquivalenceTester.java b/guava-testlib/src/com/google/common/testing/EquivalenceTester.java
index d74155e..40e5a27 100644
--- a/guava-testlib/src/com/google/common/testing/EquivalenceTester.java
+++ b/guava-testlib/src/com/google/common/testing/EquivalenceTester.java
@@ -47,7 +47,7 @@ import java.util.List;
* </pre>
*
* <p>
- * Note that testing {@link Object#equals(Object)} is more simply done using
+ * Note that testing {@link Objects#equals(Object)} is more simply done using
* the {@link EqualsTester}. It includes an extra test against an instance of an
* arbitrary class without having to explicitly add another equivalence group.
*
diff --git a/guava-testlib/src/com/google/common/testing/FakeTicker.java b/guava-testlib/src/com/google/common/testing/FakeTicker.java
index b4237df..9f32120 100644
--- a/guava-testlib/src/com/google/common/testing/FakeTicker.java
+++ b/guava-testlib/src/com/google/common/testing/FakeTicker.java
@@ -16,8 +16,6 @@
package com.google.common.testing;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Ticker;
@@ -28,9 +26,6 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* A Ticker whose value can be advanced programmatically in test.
* <p>
- * The ticker can be configured so that the time is incremented whenever {@link #read} is called:
- * see {@link #setAutoIncrementStep}.
- * <p>
* This class is thread-safe.
*
* @author Jige Yu
@@ -41,7 +36,6 @@ import java.util.concurrent.atomic.AtomicLong;
public class FakeTicker extends Ticker {
private final AtomicLong nanos = new AtomicLong();
- private volatile long autoIncrementStepNanos;
/** Advances the ticker value by {@code time} in {@code timeUnit}. */
public FakeTicker advance(long time, TimeUnit timeUnit) {
@@ -54,19 +48,7 @@ public class FakeTicker extends Ticker {
return this;
}
- /**
- * Sets the increment applied to the ticker whenever it is queried.
- *
- * <p>The default behavior is to auto increment by zero. i.e: The ticker is left unchanged when
- * queried.
- */
- public FakeTicker setAutoIncrementStep(long autoIncrementStep, TimeUnit timeUnit) {
- checkArgument(autoIncrementStep >= 0, "May not auto-increment by a negative amount");
- this.autoIncrementStepNanos = timeUnit.toNanos(autoIncrementStep);
- return this;
- }
-
@Override public long read() {
- return nanos.getAndAdd(autoIncrementStepNanos);
+ return nanos.get();
}
}
diff --git a/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java b/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java
deleted file mode 100644
index 71d2b1a..0000000
--- a/guava-testlib/src/com/google/common/testing/ForwardingWrapperTester.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.fail;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.google.common.reflect.AbstractInvocationHandler;
-import com.google.common.reflect.Reflection;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Tester to ensure forwarding wrapper works by delegating calls to the corresponding method
- * with the same parameters forwarded and return value forwarded back or exception propagated as is.
- *
- * <p>For example: <pre> {@code
- * new ForwardingWrapperTester().testForwarding(Foo.class, new Function<Foo, Foo>() {
- * public Foo apply(Foo foo) {
- * return new ForwardingFoo(foo);
- * }
- * });}</pre>
- *
- * @author Ben Yu
- * @since 14.0
- */
-@Beta
-public final class ForwardingWrapperTester {
-
- private boolean testsEquals = false;
-
- /**
- * Asks for {@link Object#equals} and {@link Object#hashCode} to be tested.
- * That is, forwarding wrappers of equal instances should be equal.
- */
- public ForwardingWrapperTester includingEquals() {
- this.testsEquals = true;
- return this;
- }
-
- /**
- * Tests that the forwarding wrapper returned by {@code wrapperFunction} properly forwards
- * method calls with parameters passed as is, return value returned as is, and exceptions
- * propagated as is.
- */
- public <T> void testForwarding(
- Class<T> interfaceType, Function<? super T, ? extends T> wrapperFunction) {
- checkNotNull(wrapperFunction);
- checkArgument(interfaceType.isInterface(), "%s isn't an interface", interfaceType);
- Method[] methods = getMostConcreteMethods(interfaceType);
- AccessibleObject.setAccessible(methods, true);
- for (Method method : methods) {
- // The interface could be package-private or private.
- // filter out equals/hashCode/toString
- if (method.getName().equals("equals")
- && method.getParameterTypes().length == 1
- && method.getParameterTypes()[0] == Object.class) {
- continue;
- }
- if (method.getName().equals("hashCode")
- && method.getParameterTypes().length == 0) {
- continue;
- }
- if (method.getName().equals("toString")
- && method.getParameterTypes().length == 0) {
- continue;
- }
- testSuccessfulForwarding(interfaceType, method, wrapperFunction);
- testExceptionPropagation(interfaceType, method, wrapperFunction);
- }
- if (testsEquals) {
- testEquals(interfaceType, wrapperFunction);
- }
- testToString(interfaceType, wrapperFunction);
- }
-
- /** Returns the most concrete public methods from {@code type}. */
- private static Method[] getMostConcreteMethods(Class<?> type) {
- Method[] methods = type.getMethods();
- for (int i = 0; i < methods.length; i++) {
- try {
- methods[i] = type.getMethod(methods[i].getName(), methods[i].getParameterTypes());
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
- return methods;
- }
-
- private static <T> void testSuccessfulForwarding(
- Class<T> interfaceType, Method method, Function<? super T, ? extends T> wrapperFunction) {
- new InteractionTester<T>(interfaceType, method).testInteraction(wrapperFunction);
- }
-
- private static <T> void testExceptionPropagation(
- Class<T> interfaceType, Method method, Function<? super T, ? extends T> wrapperFunction) {
- final RuntimeException exception = new RuntimeException();
- T proxy = Reflection.newProxy(interfaceType, new AbstractInvocationHandler() {
- @Override protected Object handleInvocation(Object p, Method m, Object[] args)
- throws Throwable {
- throw exception;
- }
- });
- T wrapper = wrapperFunction.apply(proxy);
- try {
- method.invoke(wrapper, getParameterValues(method));
- fail(method + " failed to throw exception as is.");
- } catch (InvocationTargetException e) {
- if (exception != e.getCause()) {
- throw new RuntimeException(e);
- }
- } catch (IllegalAccessException e) {
- throw new AssertionError(e);
- }
- }
-
- private static <T> void testEquals(
- Class<T> interfaceType, Function<? super T, ? extends T> wrapperFunction) {
- FreshValueGenerator generator = new FreshValueGenerator();
- T instance = generator.newProxy(interfaceType);
- new EqualsTester()
- .addEqualityGroup(wrapperFunction.apply(instance), wrapperFunction.apply(instance))
- .addEqualityGroup(wrapperFunction.apply(generator.newProxy(interfaceType)))
- // TODO: add an overload to EqualsTester to print custom error message?
- .testEquals();
- }
-
- private static <T> void testToString(
- Class<T> interfaceType, Function<? super T, ? extends T> wrapperFunction) {
- T proxy = new FreshValueGenerator().newProxy(interfaceType);
- assertEquals("toString() isn't properly forwarded",
- proxy.toString(), wrapperFunction.apply(proxy).toString());
- }
-
- private static Object[] getParameterValues(Method method) {
- FreshValueGenerator paramValues = new FreshValueGenerator();
- final List<Object> passedArgs = Lists.newArrayList();
- for (Class<?> paramType : method.getParameterTypes()) {
- passedArgs.add(paramValues.generate(paramType));
- }
- return passedArgs.toArray();
- }
-
- /** Tests a single interaction against a method. */
- private static final class InteractionTester<T> extends AbstractInvocationHandler {
-
- private final Class<T> interfaceType;
- private final Method method;
- private final Object[] passedArgs;
- private final Object returnValue;
- private final AtomicInteger called = new AtomicInteger();
-
- InteractionTester(Class<T> interfaceType, Method method) {
- this.interfaceType = interfaceType;
- this.method = method;
- this.passedArgs = getParameterValues(method);
- this.returnValue = new FreshValueGenerator().generate(method.getReturnType());
- }
-
- @Override protected Object handleInvocation(Object p, Method calledMethod, Object[] args)
- throws Throwable {
- assertEquals(method, calledMethod);
- assertEquals(method + " invoked more than once.", 0, called.get());
- for (int i = 0; i < passedArgs.length; i++) {
- assertEquals("Parameter #" + i + " of " + method + " not forwarded",
- passedArgs[i], args[i]);
- }
- called.getAndIncrement();
- return returnValue;
- }
-
- void testInteraction(Function<? super T, ? extends T> wrapperFunction) {
- T proxy = Reflection.newProxy(interfaceType, this);
- T wrapper = wrapperFunction.apply(proxy);
- try {
- assertEquals("Return value of " + method + " not forwarded", returnValue,
- method.invoke(wrapper, passedArgs));
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- } catch (InvocationTargetException e) {
- throw Throwables.propagate(e.getCause());
- }
- assertEquals("Failed to forward to " + method, 1, called.get());
- }
-
- @Override public String toString() {
- return "dummy " + interfaceType.getSimpleName();
- }
- }
-}
diff --git a/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java b/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java
deleted file mode 100644
index b53edae..0000000
--- a/guava-testlib/src/com/google/common/testing/FreshValueGenerator.java
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Charsets;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-import com.google.common.base.Throwables;
-import com.google.common.base.Ticker;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.ImmutableSortedMultiset;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.LinkedHashMultiset;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.RowSortedTable;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.collect.SortedMultiset;
-import com.google.common.collect.Table;
-import com.google.common.collect.TreeBasedTable;
-import com.google.common.collect.TreeMultiset;
-import com.google.common.primitives.UnsignedInteger;
-import com.google.common.primitives.UnsignedLong;
-import com.google.common.reflect.AbstractInvocationHandler;
-import com.google.common.reflect.Invokable;
-import com.google.common.reflect.Parameter;
-import com.google.common.reflect.Reflection;
-import com.google.common.reflect.TypeToken;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.TypeVariable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.LongBuffer;
-import java.nio.ShortBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Currency;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
-
-/**
- * Generates fresh instances of types that are different from each other (if possible).
- *
- * @author Ben Yu
- */
-class FreshValueGenerator {
-
- private static final ImmutableMap<Class<?>, Method> GENERATORS;
- static {
- ImmutableMap.Builder<Class<?>, Method> builder =
- ImmutableMap.builder();
- for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
- if (method.isAnnotationPresent(Generates.class)) {
- builder.put(method.getReturnType(), method);
- }
- }
- GENERATORS = builder.build();
- }
-
- private final AtomicInteger differentiator = new AtomicInteger(1);
- private final ListMultimap<Class<?>, Object> sampleInstances = ArrayListMultimap.create();
-
- <T> void addSampleInstances(Class<T> type, Iterable<? extends T> instances) {
- sampleInstances.putAll(checkNotNull(type), checkNotNull(instances));
- }
-
- /**
- * Returns a fresh instance for {@code type} if possible. The returned instance could be:
- * <ul>
- * <li>exactly of the given type, including generic type parameters, such as
- * {@code ImmutableList<String>};
- * <li>of the raw type;
- * <li>null if no fresh value can be generated.
- * </ul>
- */
- @Nullable final <T> T generate(TypeToken<T> type) {
- // Not completely safe since sample instances are registered by raw types.
- // But we assume the generic type parameters are mostly unimportant for these dummy values,
- // because what really matters are equals/hashCode.
- @SuppressWarnings("unchecked")
- T result = (T) generateIfPossible(type);
- return result;
- }
-
- @Nullable final <T> T generate(Class<T> type) {
- return generate(TypeToken.of(type));
- }
-
- @Nullable private Object generateIfPossible(TypeToken<?> type) {
- Class<?> rawType = type.getRawType();
- List<Object> samples = sampleInstances.get(rawType);
- Object sample = nextInstance(samples, null);
- if (sample != null) {
- return sample;
- }
- if (rawType.isEnum()) {
- return nextInstance(rawType.getEnumConstants(), null);
- }
- if (type.isArray()) {
- TypeToken<?> componentType = type.getComponentType();
- Object array = Array.newInstance(componentType.getRawType(), 1);
- Array.set(array, 0, generateIfPossible(componentType));
- return array;
- }
- Method generator = GENERATORS.get(rawType);
- if (generator != null) {
- ImmutableList<Parameter> params = Invokable.from(generator).getParameters();
- List<Object> args = Lists.newArrayListWithCapacity(params.size());
- TypeVariable<?>[] typeVars = rawType.getTypeParameters();
- for (int i = 0; i < params.size(); i++) {
- TypeToken<?> paramType = type.resolveType(typeVars[i]);
- // We require all @Generates methods to either be parameter-less or accept non-null
- // fresh values for their generic parameter types.
- Object argValue = generateIfPossible(paramType);
- if (argValue == null) {
- return defaultGenerate(rawType);
- }
- args.add(argValue);
- }
- try {
- return generator.invoke(this, args.toArray());
- } catch (InvocationTargetException e) {
- Throwables.propagate(e.getCause());
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
- return defaultGenerate(rawType);
- }
-
- private Object defaultGenerate(Class<?> rawType) {
- if (rawType.isInterface()) {
- // always create a new proxy
- return newProxy(rawType);
- }
- return ArbitraryInstances.get(rawType);
- }
-
- final <T> T newProxy(final Class<T> interfaceType) {
- return Reflection.newProxy(interfaceType, new FreshInvocationHandler(interfaceType));
- }
-
- private final class FreshInvocationHandler extends AbstractInvocationHandler {
- private final int identity = freshInt();
- private final Class<?> interfaceType;
-
- FreshInvocationHandler(Class<?> interfaceType) {
- this.interfaceType = interfaceType;
- }
-
- @Override protected Object handleInvocation(Object proxy, Method method, Object[] args) {
- return interfaceMethodCalled(interfaceType, method);
- }
-
- @Override public int hashCode() {
- return identity;
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof FreshInvocationHandler) {
- FreshInvocationHandler that = (FreshInvocationHandler) obj;
- return identity == that.identity;
- }
- return false;
- }
-
- @Override public String toString() {
- return paramString(interfaceType, identity);
- }
- }
-
- /** Subclasses can override to provide different return value for proxied interface methods. */
- Object interfaceMethodCalled(
- @SuppressWarnings("unused") Class<?> interfaceType,
- @SuppressWarnings("unused") Method method) {
- throw new UnsupportedOperationException();
- }
-
- private <T> T nextInstance(T[] instances, T defaultValue) {
- return nextInstance(Arrays.asList(instances), defaultValue);
- }
-
- private <T> T nextInstance(Collection<T> instances, T defaultValue) {
- if (instances.isEmpty()) {
- return defaultValue;
- }
- // freshInt() is 1-based.
- return Iterables.get(instances, (freshInt() - 1) % instances.size());
- }
-
- private static String paramString(Class<?> type, int i) {
- return type.getSimpleName() + '@' + i;
- }
-
- /**
- * Annotates a method to be the instance generator of a certain type. The return type is the
- * generated type. The method parameters are non-null fresh values for each method type variable
- * in the same type variable declaration order of the return type.
- */
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- private @interface Generates {}
-
- @Generates private Class<?> freshClass() {
- return nextInstance(
- ImmutableList.of(
- int.class, long.class, void.class,
- Object.class, Object[].class, Iterable.class),
- Object.class);
- }
-
- @Generates private Object freshObject() {
- return freshString();
- }
-
- @Generates private Number freshNumber() {
- return freshInt();
- }
-
- @Generates private int freshInt() {
- return differentiator.getAndIncrement();
- }
-
- @Generates private Integer freshInteger() {
- return new Integer(freshInt());
- }
-
- @Generates private long freshLong() {
- return freshInt();
- }
-
- @Generates private Long freshLongObject() {
- return new Long(freshLong());
- }
-
- @Generates private float freshFloat() {
- return freshInt();
- }
-
- @Generates private Float freshFloatObject() {
- return new Float(freshFloat());
- }
-
- @Generates private double freshDouble() {
- return freshInt();
- }
-
- @Generates private Double freshDoubleObject() {
- return new Double(freshDouble());
- }
-
- @Generates private short freshShort() {
- return (short) freshInt();
- }
-
- @Generates private Short freshShortObject() {
- return new Short(freshShort());
- }
-
- @Generates private byte freshByte() {
- return (byte) freshInt();
- }
-
- @Generates private Byte freshByteObject() {
- return new Byte(freshByte());
- }
-
- @Generates private char freshChar() {
- return freshString().charAt(0);
- }
-
- @Generates private Character freshCharacter() {
- return new Character(freshChar());
- }
-
- @Generates private boolean freshBoolean() {
- return freshInt() % 2 == 0;
- }
-
- @Generates private Boolean freshBooleanObject() {
- return new Boolean(freshBoolean());
- }
-
- @Generates private UnsignedInteger freshUnsignedInteger() {
- return UnsignedInteger.fromIntBits(freshInt());
- }
-
- @Generates private UnsignedLong freshUnsignedLong() {
- return UnsignedLong.fromLongBits(freshLong());
- }
-
- @Generates private BigInteger freshBigInteger() {
- return BigInteger.valueOf(freshInt());
- }
-
- @Generates private BigDecimal freshBigDecimal() {
- return BigDecimal.valueOf(freshInt());
- }
-
- @Generates private CharSequence freshCharSequence() {
- return freshString();
- }
-
- @Generates private String freshString() {
- return Integer.toString(freshInt());
- }
-
- @Generates private Comparable<?> freshComparable() {
- return freshString();
- }
-
- @Generates private Pattern freshPattern() {
- return Pattern.compile(freshString());
- }
-
- @Generates private Charset freshCharset() {
- return nextInstance(Charset.availableCharsets().values(), Charsets.UTF_8);
- }
-
- @Generates private Locale freshLocale() {
- return nextInstance(Locale.getAvailableLocales(), Locale.US);
- }
-
- @Generates private Currency freshCurrency() {
- for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
- Locale locale = freshLocale();
- if (uselessLocales.contains(locale)) { // exhausted all locales
- return Currency.getInstance(Locale.US);
- }
- try {
- return Currency.getInstance(locale);
- } catch (IllegalArgumentException e) {
- uselessLocales.add(locale);
- }
- }
- }
-
- // common.base
- @Generates private Joiner freshJoiner() {
- return Joiner.on(freshString());
- }
-
- @Generates private Splitter freshSplitter() {
- return Splitter.on(freshString());
- }
-
- @Generates private <T> Equivalence<T> freshEquivalence() {
- return new Equivalence<T>() {
- @Override protected boolean doEquivalent(T a, T b) {
- return false;
- }
- @Override protected int doHash(T t) {
- return 0;
- }
- final String string = paramString(Equivalence.class, freshInt());
- @Override public String toString() {
- return string;
- }
- };
- }
-
- @Generates private CharMatcher freshCharMatcher() {
- return new CharMatcher() {
- @Override public boolean matches(char c) {
- return false;
- }
- final String string = paramString(CharMatcher.class, freshInt());
- @Override public String toString() {
- return string;
- }
- };
- }
-
- @Generates private Ticker freshTicker() {
- return new Ticker() {
- @Override public long read() {
- return 0;
- }
- final String string = paramString(Ticker.class, freshInt());
- @Override public String toString() {
- return string;
- }
- };
- }
-
- // collect
- @Generates private <T> Comparator<T> freshComparator() {
- return freshOrdering();
- }
-
- @Generates private <T> Ordering<T> freshOrdering() {
- return new Ordering<T>() {
- @Override public int compare(T left, T right) {
- return 0;
- }
- final String string = paramString(Ordering.class, freshInt());
- @Override public String toString() {
- return string;
- }
- };
- }
-
- @Generates static private <E> Iterable<E> freshIterable(E freshElement) {
- return freshList(freshElement);
- }
-
- @Generates static private <E> Collection<E> freshCollection(E freshElement) {
- return freshList(freshElement);
- }
-
- @Generates static private <E> List<E> freshList(E freshElement) {
- return freshArrayList(freshElement);
- }
-
- @Generates static private <E> ArrayList<E> freshArrayList(E freshElement) {
- ArrayList<E> list = Lists.newArrayList();
- list.add(freshElement);
- return list;
- }
-
- @Generates static private <E> LinkedList<E> freshLinkedList(E freshElement) {
- LinkedList<E> list = Lists.newLinkedList();
- list.add(freshElement);
- return list;
- }
-
- @Generates static private <E> ImmutableList<E> freshImmutableList(E freshElement) {
- return ImmutableList.of(freshElement);
- }
-
- @Generates static private <E> ImmutableCollection<E> freshImmutableCollection(E freshElement) {
- return freshImmutableList(freshElement);
- }
-
- @Generates static private <E> Set<E> freshSet(E freshElement) {
- return freshHashSet(freshElement);
- }
-
- @Generates static private <E> HashSet<E> freshHashSet(E freshElement) {
- return freshLinkedHashSet(freshElement);
- }
-
- @Generates static private <E> LinkedHashSet<E> freshLinkedHashSet(E freshElement) {
- LinkedHashSet<E> set = Sets.newLinkedHashSet();
- set.add(freshElement);
- return set;
- }
-
- @Generates static private <E> ImmutableSet<E> freshImmutableSet(E freshElement) {
- return ImmutableSet.of(freshElement);
- }
-
- @Generates static private <E extends Comparable<? super E>> SortedSet<E>
- freshSortedSet(E freshElement) {
- return freshNavigableSet(freshElement);
- }
-
- @Generates static private <E extends Comparable<? super E>> NavigableSet<E>
- freshNavigableSet(E freshElement) {
- return freshTreeSet(freshElement);
- }
-
- @Generates static private <E extends Comparable<? super E>> TreeSet<E> freshTreeSet(
- E freshElement) {
- TreeSet<E> set = Sets.newTreeSet();
- set.add(freshElement);
- return set;
- }
-
- @Generates static private <E extends Comparable<? super E>> ImmutableSortedSet<E>
- freshImmutableSortedSet(E freshElement) {
- return ImmutableSortedSet.of(freshElement);
- }
-
- @Generates static private <E> Multiset<E> freshMultiset(E freshElement) {
- return freshHashMultiset(freshElement);
- }
-
- @Generates static private <E> HashMultiset<E> freshHashMultiset(E freshElement) {
- HashMultiset<E> multiset = HashMultiset.create();
- multiset.add(freshElement);
- return multiset;
- }
-
- @Generates static private <E> LinkedHashMultiset<E> freshLinkedHashMultiset(E freshElement) {
- LinkedHashMultiset<E> multiset = LinkedHashMultiset.create();
- multiset.add(freshElement);
- return multiset;
- }
-
- @Generates static private <E> ImmutableMultiset<E> freshImmutableMultiset(E freshElement) {
- return ImmutableMultiset.of(freshElement);
- }
-
- @Generates static private <E extends Comparable<E>> SortedMultiset<E> freshSortedMultiset(
- E freshElement) {
- return freshTreeMultiset(freshElement);
- }
-
- @Generates static private <E extends Comparable<E>> TreeMultiset<E> freshTreeMultiset(
- E freshElement) {
- TreeMultiset<E> multiset = TreeMultiset.create();
- multiset.add(freshElement);
- return multiset;
- }
-
- @Generates static private <E extends Comparable<E>> ImmutableSortedMultiset<E>
- freshImmutableSortedMultiset(E freshElement) {
- return ImmutableSortedMultiset.of(freshElement);
- }
-
- @Generates static private <K, V> Map<K, V> freshMap(K key, V value) {
- return freshHashdMap(key, value);
- }
-
- @Generates static private <K, V> HashMap<K, V> freshHashdMap(K key, V value) {
- return freshLinkedHashMap(key, value);
- }
-
- @Generates static private <K, V> LinkedHashMap<K, V> freshLinkedHashMap(K key, V value) {
- LinkedHashMap<K, V> map = Maps.newLinkedHashMap();
- map.put(key, value);
- return map;
- }
-
- @Generates static private <K, V> ImmutableMap<K, V> freshImmutableMap(K key, V value) {
- return ImmutableMap.of(key, value);
- }
-
- @Generates static private <K, V> ConcurrentMap<K, V> freshConcurrentMap(K key, V value) {
- ConcurrentMap<K, V> map = Maps.newConcurrentMap();
- map.put(key, value);
- return map;
- }
-
- @Generates static private <K extends Comparable<? super K>, V> SortedMap<K, V>
- freshSortedMap(K key, V value) {
- return freshNavigableMap(key, value);
- }
-
- @Generates static private <K extends Comparable<? super K>, V> NavigableMap<K, V>
- freshNavigableMap(K key, V value) {
- return freshTreeMap(key, value);
- }
-
- @Generates static private <K extends Comparable<? super K>, V> TreeMap<K, V> freshTreeMap(
- K key, V value) {
- TreeMap<K, V> map = Maps.newTreeMap();
- map.put(key, value);
- return map;
- }
-
- @Generates static private <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
- freshImmutableSortedMap(K key, V value) {
- return ImmutableSortedMap.of(key, value);
- }
-
- @Generates static private <K, V> Multimap<K, V> freshMultimap(K key, V value) {
- return freshListMultimap(key, value);
- }
-
- @Generates static private <K, V> ImmutableMultimap<K, V> freshImmutableMultimap(K key, V value) {
- return ImmutableMultimap.of(key, value);
- }
-
- @Generates static private <K, V> ListMultimap<K, V> freshListMultimap(K key, V value) {
- return freshArrayListMultimap(key, value);
- }
-
- @Generates static private <K, V> ArrayListMultimap<K, V> freshArrayListMultimap(K key, V value) {
- ArrayListMultimap<K, V> multimap = ArrayListMultimap.create();
- multimap.put(key, value);
- return multimap;
- }
-
- @Generates static private <K, V> ImmutableListMultimap<K, V> freshImmutableListMultimap(
- K key, V value) {
- return ImmutableListMultimap.of(key, value);
- }
-
- @Generates static private <K, V> SetMultimap<K, V> freshSetMultimap(K key, V value) {
- return freshLinkedHashMultimap(key, value);
- }
-
- @Generates static private <K, V> HashMultimap<K, V> freshHashMultimap(K key, V value) {
- HashMultimap<K, V> multimap = HashMultimap.create();
- multimap.put(key, value);
- return multimap;
- }
-
- @Generates static private <K, V> LinkedHashMultimap<K, V> freshLinkedHashMultimap(
- K key, V value) {
- LinkedHashMultimap<K, V> multimap = LinkedHashMultimap.create();
- multimap.put(key, value);
- return multimap;
- }
-
- @Generates static private <K, V> ImmutableSetMultimap<K, V> freshImmutableSetMultimap(
- K key, V value) {
- return ImmutableSetMultimap.of(key, value);
- }
-
- @Generates static private <K, V> BiMap<K, V> freshBimap(K key, V value) {
- return freshHashBiMap(key, value);
- }
-
- @Generates static private <K, V> HashBiMap<K, V> freshHashBiMap(K key, V value) {
- HashBiMap<K, V> bimap = HashBiMap.create();
- bimap.put(key, value);
- return bimap;
- }
-
- @Generates static private <K, V> ImmutableBiMap<K, V> freshImmutableBimap(
- K key, V value) {
- return ImmutableBiMap.of(key, value);
- }
-
- @Generates static private <R, C, V> Table<R, C, V> freshTable(R row, C column, V value) {
- return freshHashBasedTable(row, column, value);
- }
-
- @Generates static private <R, C, V> HashBasedTable<R, C, V> freshHashBasedTable(
- R row, C column, V value) {
- HashBasedTable<R, C, V> table = HashBasedTable.create();
- table.put(row, column, value);
- return table;
- }
-
- @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
- @Generates static private <R extends Comparable, C extends Comparable, V> RowSortedTable<R, C, V>
- freshRowSortedTable(R row, C column, V value) {
- return freshTreeBasedTable(row, column, value);
- }
-
- @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
- @Generates static private <R extends Comparable, C extends Comparable, V> TreeBasedTable<R, C, V>
- freshTreeBasedTable(R row, C column, V value) {
- TreeBasedTable<R, C, V> table = TreeBasedTable.create();
- table.put(row, column, value);
- return table;
- }
-
- @Generates static private <R, C, V> ImmutableTable<R, C, V> freshImmutableTable(
- R row, C column, V value) {
- return ImmutableTable.of(row, column, value);
- }
-
- // common.reflect
- @Generates private TypeToken<?> freshTypeToken() {
- return TypeToken.of(freshClass());
- }
-
- // io types
- @Generates private File freshFile() {
- return new File(freshString());
- }
-
- @Generates private static ByteArrayInputStream freshByteArrayInputStream() {
- return new ByteArrayInputStream(new byte[0]);
- }
-
- @Generates private static InputStream freshInputStream() {
- return freshByteArrayInputStream();
- }
-
- @Generates private StringReader freshStringReader() {
- return new StringReader(freshString());
- }
-
- @Generates private Reader freshReader() {
- return freshStringReader();
- }
-
- @Generates private Readable freshReadable() {
- return freshReader();
- }
-
- @Generates private Buffer freshBuffer() {
- return freshCharBuffer();
- }
-
- @Generates private CharBuffer freshCharBuffer() {
- return CharBuffer.allocate(freshInt());
- }
-
- @Generates private ByteBuffer freshByteBuffer() {
- return ByteBuffer.allocate(freshInt());
- }
-
- @Generates private ShortBuffer freshShortBuffer() {
- return ShortBuffer.allocate(freshInt());
- }
-
- @Generates private IntBuffer freshIntBuffer() {
- return IntBuffer.allocate(freshInt());
- }
-
- @Generates private LongBuffer freshLongBuffer() {
- return LongBuffer.allocate(freshInt());
- }
-
- @Generates private FloatBuffer freshFloatBuffer() {
- return FloatBuffer.allocate(freshInt());
- }
-
- @Generates private DoubleBuffer freshDoubleBuffer() {
- return DoubleBuffer.allocate(freshInt());
- }
-}
diff --git a/guava-testlib/src/com/google/common/testing/GcFinalization.java b/guava-testlib/src/com/google/common/testing/GcFinalization.java
index 7942b09..e541793 100644
--- a/guava-testlib/src/com/google/common/testing/GcFinalization.java
+++ b/guava-testlib/src/com/google/common/testing/GcFinalization.java
@@ -57,7 +57,7 @@ import java.util.concurrent.TimeoutException;
* ...
* protected void finalize() { latch.countDown(); ... }
* };
- * x = null; // Hint to the JIT that x is stack-unreachable
+ * x = null; // Hint to the JIT that x is unreachable
* GcFinalization.await(latch);
* }</pre>
*
@@ -73,31 +73,14 @@ import java.util.concurrent.TimeoutException;
* });
* }</pre>
*
- * <p>Even if your non-test code does not use finalization, you can
- * use this class to test for leaks, by ensuring that objects are no
- * longer strongly referenced:
- *
- * <pre> {@code
- * // Helper function keeps victim stack-unreachable.
- * private WeakReference<Foo> fooWeakRef() {
- * Foo x = ....;
- * WeakReference<Foo> weakRef = new WeakReference<Foo>(x);
- * // ... use x ...
- * x = null; // Hint to the JIT that x is stack-unreachable
- * return weakRef;
- * }
- * public void testFooLeak() {
- * GcFinalization.awaitClear(fooWeakRef());
- * }}</pre>
- *
* <p>This class cannot currently be used to test soft references, since this class does not try to
* create the memory pressure required to cause soft references to be cleared.
*
* <p>This class only provides testing utilities. It is not designed for direct use in production
* or for benchmarking.
*
- * @author mike nonemacher
- * @author Martin Buchholz
+ * @author schmoe@google.com (mike nonemacher)
+ * @author martinrb@google.com (Martin Buchholz)
* @since 11.0
*/
@Beta
@@ -261,40 +244,4 @@ public final class GcFinalization {
}
});
}
-
- /**
- * Tries to perform a "full" garbage collection cycle (including processing of weak references
- * and invocation of finalize methods) and waits for it to complete. Ensures that at least one
- * weak reference has been cleared and one {@code finalize} method has been run before this
- * method returns. This method may be useful when testing the garbage collection mechanism
- * itself, or inhibiting a spontaneous GC initiation in subsequent code.
- *
- * <p>In contrast, a plain call to {@link java.lang.System#gc()} does not ensure finalization
- * processing and may run concurrently, for example, if the JVM flag {@code
- * -XX:+ExplicitGCInvokesConcurrent} is used.
- *
- * <p>Whenever possible, it is preferable to test directly for some observable change resulting
- * from GC, as with {@link #awaitClear}. Because there are no guarantees for the order of GC
- * finalization processing, there may still be some unfinished work for the GC to do after this
- * method returns.
- *
- * <p>This method does not create any memory pressure as would be required to cause soft
- * references to be processed.
- *
- * @throws RuntimeException if timed out or interrupted while waiting
- * @since 12.0
- */
- public static void awaitFullGc() {
- final CountDownLatch finalizerRan = new CountDownLatch(1);
- WeakReference<Object> ref = new WeakReference<Object>(
- new Object() {
- @Override protected void finalize() { finalizerRan.countDown(); }
- });
-
- await(finalizerRan);
- awaitClear(ref);
-
- // Hope to catch some stragglers queued up behind our finalizable object
- System.runFinalization();
- }
}
diff --git a/guava-testlib/src/com/google/common/testing/NullPointerTester.java b/guava-testlib/src/com/google/common/testing/NullPointerTester.java
index b643182..1142056 100644
--- a/guava-testlib/src/com/google/common/testing/NullPointerTester.java
+++ b/guava-testlib/src/com/google/common/testing/NullPointerTester.java
@@ -16,149 +16,146 @@
package com.google.common.testing;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.ImmutableList;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.MutableClassToInstanceMap;
-import com.google.common.reflect.Invokable;
-import com.google.common.reflect.Parameter;
-import com.google.common.reflect.Reflection;
-import com.google.common.reflect.TypeToken;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
-import java.util.concurrent.ConcurrentMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
import javax.annotation.Nullable;
/**
- * A test utility that verifies that your methods and constructors throw {@link
- * NullPointerException} or {@link UnsupportedOperationException} whenever null
- * is passed to a parameter that isn't annotated with {@link Nullable}.
- *
- * <p>The tested methods and constructors are invoked -- each time with one
- * parameter being null and the rest not null -- and the test fails if no
- * expected exception is thrown. {@code NullPointerTester} uses best effort to
- * pick non-null default values for many common JDK and Guava types, and also
- * for interfaces and public classes that have public parameter-less
- * constructors. When the non-null default value for a particular parameter type
- * cannot be provided by {@code NullPointerTester}, the caller can provide a
- * custom non-null default value for the parameter type via {@link #setDefault}.
+ * A test utility that verifies that your methods throw {@link
+ * NullPointerException} or {@link UnsupportedOperationException} whenever any
+ * of their parameters are null. To use it, you must first provide valid default
+ * values for the parameter types used by the class.
*
* @author Kevin Bourrillion
* @since 10.0
*/
@Beta
public final class NullPointerTester {
-
- private final ClassToInstanceMap<Object> defaults =
- MutableClassToInstanceMap.create();
+ private final Map<Class<?>, Object> defaults = Maps.newHashMap();
private final List<Member> ignoredMembers = Lists.newArrayList();
+ public NullPointerTester() {
+ setCommonDefaults();
+ }
+
+ private final void setCommonDefaults() {
+ setDefault(Appendable.class, new StringBuilder());
+ setDefault(CharSequence.class, "");
+ setDefault(Class.class, Class.class);
+ setDefault(Collection.class, Collections.emptySet());
+ setDefault(Comparable.class, 0);
+ setDefault(Comparator.class, Collections.reverseOrder());
+ setDefault(Function.class, Functions.identity());
+ setDefault(Integer.class, 0);
+ setDefault(Iterable.class, Collections.emptySet());
+ setDefault(Iterator.class, Iterators.emptyIterator());
+ setDefault(List.class, Collections.emptyList());
+ setDefault(Map.class, Collections.emptyMap());
+ setDefault(Object.class, new Object());
+ setDefault(Object[].class, new Object[0]);
+ setDefault(Pattern.class, Pattern.compile(""));
+ setDefault(Predicate.class, Predicates.alwaysTrue());
+ setDefault(Set.class, Collections.emptySet());
+ setDefault(SortedSet.class, new TreeSet());
+ setDefault(String.class, "");
+ setDefault(Supplier.class, Suppliers.ofInstance(1));
+ setDefault(Throwable.class, new Exception());
+ setDefault(TimeUnit.class, TimeUnit.SECONDS);
+ setDefault(int.class, 0);
+ setDefault(long.class, 0L);
+ setDefault(short.class, (short) 0);
+ setDefault(char.class, 'a');
+ setDefault(byte.class, (byte) 0);
+ setDefault(float.class, 0.0f);
+ setDefault(double.class, 0.0d);
+ setDefault(boolean.class, false);
+ }
+
/**
* Sets a default value that can be used for any parameter of type
* {@code type}. Returns this object.
*/
public <T> NullPointerTester setDefault(Class<T> type, T value) {
- defaults.putInstance(type, checkNotNull(value));
+ defaults.put(type, value);
return this;
}
/**
- * Ignore {@code method} in the tests that follow. Returns this object.
- *
- * @since 13.0
+ * Ignore a member (constructor or method) in testAllXxx methods. Returns
+ * this object.
*/
- public NullPointerTester ignore(Method method) {
- ignoredMembers.add(checkNotNull(method));
+ public NullPointerTester ignore(Member member) {
+ ignoredMembers.add(member);
return this;
}
/**
- * Runs {@link #testConstructor} on every constructor in class {@code c} that
- * has at least {@code minimalVisibility}.
+ * Runs {@link #testConstructor} on every public constructor in class {@code
+ * c}.
*/
- public void testConstructors(Class<?> c, Visibility minimalVisibility) {
+ public void testAllPublicConstructors(Class<?> c) throws Exception {
for (Constructor<?> constructor : c.getDeclaredConstructors()) {
- if (minimalVisibility.isVisible(constructor) && !isIgnored(constructor)) {
+ if (isPublic(constructor) && !isStatic(constructor)
+ && !isIgnored(constructor)) {
testConstructor(constructor);
}
}
}
/**
- * Runs {@link #testConstructor} on every public constructor in class {@code
- * c}.
- */
- public void testAllPublicConstructors(Class<?> c) {
- testConstructors(c, Visibility.PUBLIC);
- }
-
- /**
- * Runs {@link #testMethod} on every static method of class {@code c} that has
- * at least {@code minimalVisibility}, including those "inherited" from
- * superclasses of the same package.
+ * Runs {@link #testMethod} on every public static method in class
+ * {@code c}.
*/
- public void testStaticMethods(Class<?> c, Visibility minimalVisibility) {
- for (Method method : minimalVisibility.getStaticMethods(c)) {
- if (!isIgnored(method)) {
+ public void testAllPublicStaticMethods(Class<?> c) throws Exception {
+ for (Method method : c.getDeclaredMethods()) {
+ if (isPublic(method) && isStatic(method) && !isIgnored(method)) {
testMethod(null, method);
}
}
}
/**
- * Runs {@link #testMethod} on every public static method of class {@code c},
- * including those "inherited" from superclasses of the same package.
- */
- public void testAllPublicStaticMethods(Class<?> c) {
- testStaticMethods(c, Visibility.PUBLIC);
- }
-
- /**
- * Runs {@link #testMethod} on every instance method of the class of
- * {@code instance} with at least {@code minimalVisibility}, including those
- * inherited from superclasses of the same package.
+ * Runs {@link #testMethod} on every public instance method of
+ * {@code instance}.
*/
- public void testInstanceMethods(Object instance, Visibility minimalVisibility) {
- for (Method method : getInstanceMethodsToTest(instance.getClass(), minimalVisibility)) {
- testMethod(instance, method);
- }
- }
-
- ImmutableList<Method> getInstanceMethodsToTest(Class<?> c, Visibility minimalVisibility) {
- ImmutableList.Builder<Method> builder = ImmutableList.builder();
- for (Method method : minimalVisibility.getInstanceMethods(c)) {
- if (!isIgnored(method)) {
- builder.add(method);
+ public void testAllPublicInstanceMethods(Object instance) throws Exception {
+ Class<?> c = instance.getClass();
+ for (Method method : c.getDeclaredMethods()) {
+ if (isPublic(method) && !isStatic(method) && !isIgnored(method)) {
+ testMethod(instance, method);
}
}
- return builder.build();
- }
-
- /**
- * Runs {@link #testMethod} on every public instance method of the class of
- * {@code instance}, including those inherited from superclasses of the same
- * package.
- */
- public void testAllPublicInstanceMethods(Object instance) {
- testInstanceMethods(instance, Visibility.PUBLIC);
}
/**
@@ -169,7 +166,7 @@ public final class NullPointerTester {
* @param instance the instance to invoke {@code method} on, or null if
* {@code method} is static
*/
- public void testMethod(@Nullable Object instance, Method method) {
+ public void testMethod(Object instance, Method method) throws Exception {
Class<?>[] types = method.getParameterTypes();
for (int nullIndex = 0; nullIndex < types.length; nullIndex++) {
testMethodParameter(instance, method, nullIndex);
@@ -181,11 +178,7 @@ public final class NullPointerTester {
* {@link UnsupportedOperationException} whenever <i>any</i> of its
* non-{@link Nullable} parameters are null.
*/
- public void testConstructor(Constructor<?> ctor) {
- Class<?> declaringClass = ctor.getDeclaringClass();
- checkArgument(Modifier.isStatic(declaringClass.getModifiers())
- || declaringClass.getEnclosingClass() == null,
- "Cannot test constructor of non-static inner class: %s", declaringClass.getName());
+ public void testConstructor(Constructor<?> ctor) throws Exception {
Class<?>[] types = ctor.getParameterTypes();
for (int nullIndex = 0; nullIndex < types.length; nullIndex++) {
testConstructorParameter(ctor, nullIndex);
@@ -201,10 +194,25 @@ public final class NullPointerTester {
* @param instance the instance to invoke {@code method} on, or null if
* {@code method} is static
*/
- public void testMethodParameter(
- @Nullable final Object instance, final Method method, int paramIndex) {
+ public void testMethodParameter(Object instance, final Method method,
+ int paramIndex) throws Exception {
method.setAccessible(true);
- testParameter(instance, invokable(instance, method), paramIndex, method.getDeclaringClass());
+ testFunctorParameter(instance, new Functor() {
+ @Override public Class<?>[] getParameterTypes() {
+ return method.getParameterTypes();
+ }
+ @Override public Annotation[][] getParameterAnnotations() {
+ return method.getParameterAnnotations();
+ }
+ @Override public void invoke(Object instance, Object[] params)
+ throws InvocationTargetException, IllegalAccessException {
+ method.invoke(instance, params);
+ }
+ @Override public String toString() {
+ return method.getName()
+ + "(" + Arrays.toString(getParameterTypes()) + ")";
+ }
+ }, paramIndex, method.getDeclaringClass());
}
/**
@@ -213,129 +221,42 @@ public final class NullPointerTester {
* paramIndex} is null. If this parameter is marked {@link Nullable}, this
* method does nothing.
*/
- public void testConstructorParameter(Constructor<?> ctor, int paramIndex) {
+ public void testConstructorParameter(final Constructor<?> ctor,
+ int paramIndex) throws Exception {
ctor.setAccessible(true);
- testParameter(null, Invokable.from(ctor), paramIndex, ctor.getDeclaringClass());
- }
-
- /** Visibility of any method or constructor. */
- public enum Visibility {
-
- PACKAGE {
- @Override boolean isVisible(int modifiers) {
- return !Modifier.isPrivate(modifiers);
- }
- },
-
- PROTECTED {
- @Override boolean isVisible(int modifiers) {
- return Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers);
- }
- },
-
- PUBLIC {
- @Override boolean isVisible(int modifiers) {
- return Modifier.isPublic(modifiers);
- }
- };
-
- abstract boolean isVisible(int modifiers);
-
- /**
- * Returns {@code true} if {@code member} is visible under {@code this}
- * visibility.
- */
- final boolean isVisible(Member member) {
- return isVisible(member.getModifiers());
- }
-
- final Iterable<Method> getStaticMethods(Class<?> cls) {
- ImmutableList.Builder<Method> builder = ImmutableList.builder();
- for (Method method : getVisibleMethods(cls)) {
- if (Invokable.from(method).isStatic()) {
- builder.add(method);
- }
- }
- return builder.build();
- }
-
- final Iterable<Method> getInstanceMethods(Class<?> cls) {
- ConcurrentMap<Signature, Method> map = Maps.newConcurrentMap();
- for (Method method : getVisibleMethods(cls)) {
- if (!Invokable.from(method).isStatic()) {
- map.putIfAbsent(new Signature(method), method);
+ testFunctorParameter(null, new Functor() {
+ @Override public Class<?>[] getParameterTypes() {
+ return ctor.getParameterTypes();
}
- }
- return map.values();
- }
-
- private ImmutableList<Method> getVisibleMethods(Class<?> cls) {
- // Don't use cls.getPackage() because it does nasty things like reading
- // a file.
- String visiblePackage = Reflection.getPackageName(cls);
- ImmutableList.Builder<Method> builder = ImmutableList.builder();
- for (Class<?> type : TypeToken.of(cls).getTypes().classes().rawTypes()) {
- if (!Reflection.getPackageName(type).equals(visiblePackage)) {
- break;
+ @Override public Annotation[][] getParameterAnnotations() {
+ return ctor.getParameterAnnotations();
}
- for (Method method : type.getDeclaredMethods()) {
- if (!method.isSynthetic() && isVisible(method)) {
- builder.add(method);
- }
+ @Override public void invoke(Object instance, Object[] params)
+ throws InvocationTargetException, IllegalAccessException,
+ InstantiationException {
+ ctor.newInstance(params);
}
- }
- return builder.build();
- }
- }
-
- // TODO(benyu): Use labs/reflect/Signature if it graduates.
- private static final class Signature {
- private final String name;
- private final ImmutableList<Class<?>> parameterTypes;
-
- Signature(Method method) {
- this(method.getName(), ImmutableList.copyOf(method.getParameterTypes()));
- }
-
- Signature(String name, ImmutableList<Class<?>> parameterTypes) {
- this.name = name;
- this.parameterTypes = parameterTypes;
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof Signature) {
- Signature that = (Signature) obj;
- return name.equals(that.name)
- && parameterTypes.equals(that.parameterTypes);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return Objects.hashCode(name, parameterTypes);
- }
+ }, paramIndex, ctor.getDeclaringClass());
}
/**
- * Verifies that {@code invokable} produces a {@link NullPointerException} or
+ * Verifies that {@code func} produces a {@link NullPointerException} or
* {@link UnsupportedOperationException} when the parameter in position {@code
* paramIndex} is null. If this parameter is marked {@link Nullable}, this
* method does nothing.
*
- * @param instance the instance to invoke {@code invokable} on, or null if
- * {@code invokable} is static
+ * @param instance the instance to invoke {@code func} on, or null if
+ * {@code func} is static
*/
- private void testParameter(Object instance, Invokable<?, ?> invokable,
- int paramIndex, Class<?> testedClass) {
- if (isPrimitiveOrNullable(invokable.getParameters().get(paramIndex))) {
+ private void testFunctorParameter(Object instance, Functor func,
+ int paramIndex, Class<?> testedClass) throws Exception {
+ if (parameterIsPrimitiveOrNullable(func, paramIndex)) {
return; // there's nothing to test
}
- Object[] params = buildParamList(invokable, paramIndex);
+ Object[] params = buildParamList(func, paramIndex);
try {
- @SuppressWarnings("unchecked") // We'll get a runtime exception if the type is wrong.
- Invokable<Object, ?> unsafe = (Invokable<Object, ?>) invokable;
- unsafe.invoke(instance, params);
- Assert.fail("No exception thrown from " + invokable +
+ func.invoke(instance, params);
+ Assert.fail("No exception thrown from " + func +
Arrays.toString(params) + " for " + testedClass);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
@@ -344,89 +265,54 @@ public final class NullPointerTester {
return;
}
AssertionFailedError error = new AssertionFailedError(
- "wrong exception thrown from " + invokable + ": " + cause);
+ "wrong exception thrown from " + func + ": " + cause);
error.initCause(cause);
throw error;
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
}
}
- private Object[] buildParamList(Invokable<?, ?> invokable, int indexOfParamToSetToNull) {
- ImmutableList<Parameter> params = invokable.getParameters();
- Object[] args = new Object[params.size()];
-
- for (int i = 0; i < args.length; i++) {
- Parameter param = params.get(i);
- if (i != indexOfParamToSetToNull) {
- args[i] = getDefaultValue(param.getType());
- if (!isPrimitiveOrNullable(param)) {
- Assert.assertTrue("No default value found for " + param + " of "+ invokable,
- args[i] != null);
- }
+ private static boolean parameterIsPrimitiveOrNullable(
+ Functor func, int paramIndex) {
+ if (func.getParameterTypes()[paramIndex].isPrimitive()) {
+ return true;
+ }
+ Annotation[] annotations = func.getParameterAnnotations()[paramIndex];
+ for (Annotation annotation : annotations) {
+ if (annotation instanceof Nullable) {
+ return true;
}
}
- return args;
+ return false;
}
- private <T> T getDefaultValue(TypeToken<T> type) {
- // We assume that all defaults are generics-safe, even if they aren't,
- // we take the risk.
- @SuppressWarnings("unchecked")
- T defaultValue = (T) defaults.getInstance(type.getRawType());
- if (defaultValue != null) {
- return defaultValue;
- }
- @SuppressWarnings("unchecked") // All null values are generics-safe
- T nullValue = (T) ArbitraryInstances.get(type.getRawType());
- if (nullValue != null) {
- return nullValue;
- }
- if (type.getRawType() == Class.class) {
- // If parameter is Class<? extends Foo>, we return Foo.class
- @SuppressWarnings("unchecked")
- T defaultClass = (T) getFirstTypeParameter(type.getType()).getRawType();
- return defaultClass;
- }
- if (type.getRawType() == TypeToken.class) {
- // If parameter is TypeToken<? extends Foo>, we return TypeToken<Foo>.
- @SuppressWarnings("unchecked")
- T defaultType = (T) getFirstTypeParameter(type.getType());
- return defaultType;
- }
- if (type.getRawType().isInterface()) {
- return newDefaultReturningProxy(type);
- }
- return null;
- }
+ private Object[] buildParamList(Functor func, int indexOfParamToSetToNull) {
+ Class<?>[] types = func.getParameterTypes();
+ Object[] params = new Object[types.length];
- private static TypeToken<?> getFirstTypeParameter(Type type) {
- if (type instanceof ParameterizedType) {
- return TypeToken.of(
- ((ParameterizedType) type).getActualTypeArguments()[0]);
- } else {
- return TypeToken.of(Object.class);
+ for (int i = 0; i < types.length; i++) {
+ if (i != indexOfParamToSetToNull) {
+ params[i] = defaults.get(types[i]);
+ if (!parameterIsPrimitiveOrNullable(func, i)) {
+ Assert.assertTrue("No default value found for " + types[i].getName(),
+ params[i] != null);
+ }
+ }
}
+ return params;
}
- private <T> T newDefaultReturningProxy(final TypeToken<T> type) {
- return new DummyProxy() {
- @Override <R> R dummyReturnValue(TypeToken<R> returnType) {
- return getDefaultValue(returnType);
- }
- }.newProxy(type);
+ private interface Functor {
+ Class<?>[] getParameterTypes();
+ Annotation[][] getParameterAnnotations();
+ void invoke(Object o, Object[] params) throws Exception;
}
- private static Invokable<?, ?> invokable(@Nullable Object instance, Method method) {
- if (instance == null) {
- return Invokable.from(method);
- } else {
- return TypeToken.of(instance.getClass()).method(method);
- }
+ private static boolean isPublic(Member member) {
+ return Modifier.isPublic(member.getModifiers());
}
- static boolean isPrimitiveOrNullable(Parameter param) {
- return param.getType().getRawType().isPrimitive() || param.isAnnotationPresent(Nullable.class);
+ private static boolean isStatic(Member member) {
+ return Modifier.isStatic(member.getModifiers());
}
private boolean isIgnored(Member member) {
diff --git a/guava-testlib/src/com/google/common/testing/RelationshipTester.java b/guava-testlib/src/com/google/common/testing/RelationshipTester.java
index 97d6c21..88bea63 100644
--- a/guava-testlib/src/com/google/common/testing/RelationshipTester.java
+++ b/guava-testlib/src/com/google/common/testing/RelationshipTester.java
@@ -34,24 +34,11 @@ import java.util.List;
*/
@GwtCompatible
final class RelationshipTester<T> {
-
- static class ItemReporter {
- String reportItem(Item item) {
- return item.toString();
- }
- }
-
private final List<ImmutableList<T>> groups = Lists.newArrayList();
private final RelationshipAssertion<T> assertion;
- private final ItemReporter itemReporter;
-
- RelationshipTester(RelationshipAssertion<T> assertion, ItemReporter itemReporter) {
- this.assertion = checkNotNull(assertion);
- this.itemReporter = checkNotNull(itemReporter);
- }
RelationshipTester(RelationshipAssertion<T> assertion) {
- this(assertion, new ItemReporter());
+ this.assertion = checkNotNull(assertion);
}
public RelationshipTester<T> addRelatedGroup(Iterable<? extends T> group) {
@@ -93,9 +80,8 @@ final class RelationshipTester<T> {
} catch (AssertionFailedError e) {
// TODO(gak): special handling for ComparisonFailure?
throw new AssertionFailedError(e.getMessage()
- .replace("$ITEM", itemReporter.reportItem(new Item(item, groupNumber, itemNumber)))
- .replace("$RELATED",
- itemReporter.reportItem(new Item(related, groupNumber, relatedItemNumber))));
+ .replace("$ITEM", itemString(item, groupNumber, itemNumber))
+ .replace("$RELATED", itemString(related, groupNumber, relatedItemNumber)));
}
}
@@ -108,33 +94,20 @@ final class RelationshipTester<T> {
} catch (AssertionFailedError e) {
// TODO(gak): special handling for ComparisonFailure?
throw new AssertionFailedError(e.getMessage()
- .replace("$ITEM", itemReporter.reportItem(new Item(item, groupNumber, itemNumber)))
- .replace("$UNRELATED", itemReporter.reportItem(
- new Item(unrelated, unrelatedGroupNumber, unrelatedItemNumber))));
+ .replace("$ITEM", itemString(item, groupNumber, itemNumber))
+ .replace("$UNRELATED", itemString(unrelated, unrelatedGroupNumber, unrelatedItemNumber)));
}
}
- static final class Item {
- final Object value;
- final int groupNumber;
- final int itemNumber;
-
- Item(Object value, int groupNumber, int itemNumber) {
- this.value = value;
- this.groupNumber = groupNumber;
- this.itemNumber = itemNumber;
- }
-
- @Override public String toString() {
- return new StringBuilder()
- .append(value)
- .append(" [group ")
- .append(groupNumber + 1)
- .append(", item ")
- .append(itemNumber + 1)
- .append(']')
- .toString();
- }
+ private static String itemString(Object item, int groupNumber, int itemNumber) {
+ return new StringBuilder()
+ .append(item)
+ .append(" [group ")
+ .append(groupNumber + 1)
+ .append(", item ")
+ .append(itemNumber + 1)
+ .append(']')
+ .toString();
}
/**
@@ -146,8 +119,9 @@ final class RelationshipTester<T> {
* item number and group number of the respective item.
*
*/
- static abstract class RelationshipAssertion<T> {
- abstract void assertRelated(T item, T related);
- abstract void assertUnrelated(T item, T unrelated);
+ interface RelationshipAssertion<T> {
+ void assertRelated(T item, T related);
+
+ void assertUnrelated(T item, T unrelated);
}
}
diff --git a/guava-testlib/src/com/google/common/testing/TearDown.java b/guava-testlib/src/com/google/common/testing/TearDown.java
index 68aab68..c64a4f7 100644
--- a/guava-testlib/src/com/google/common/testing/TearDown.java
+++ b/guava-testlib/src/com/google/common/testing/TearDown.java
@@ -40,7 +40,7 @@ public interface TearDown {
*
* <p>tl4j details: For backwards compatibility, {@code
* junit3.TearDownTestCase} currently does not fail a test when an exception
- * is thrown from one of its {@link TearDown} instances, but this is subject to
+ * is thrown from one of its {@link TearDown}s, but this is subject to
* change. Also, {@code junit4.TearDownTestCase} will.
*
* @throws Exception for any reason. {@code TearDownTestCase} ensures that
diff --git a/guava-testlib/src/com/google/common/testing/TearDownStack.java b/guava-testlib/src/com/google/common/testing/TearDownStack.java
index 12f0762..e579d82 100644
--- a/guava-testlib/src/com/google/common/testing/TearDownStack.java
+++ b/guava-testlib/src/com/google/common/testing/TearDownStack.java
@@ -16,8 +16,6 @@
package com.google.common.testing;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
@@ -53,7 +51,7 @@ public class TearDownStack implements TearDownAccepter {
@Override
public final void addTearDown(TearDown tearDown) {
- stack.addFirst(checkNotNull(tearDown));
+ stack.addFirst(tearDown);
}
/**
diff --git a/guava-testlib/src/com/google/common/testing/TestLogHandler.java b/guava-testlib/src/com/google/common/testing/TestLogHandler.java
index cb5bcbd..1d45554 100644
--- a/guava-testlib/src/com/google/common/testing/TestLogHandler.java
+++ b/guava-testlib/src/com/google/common/testing/TestLogHandler.java
@@ -24,8 +24,6 @@ import java.util.List;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
-import javax.annotation.Nullable;
-
/**
* Tests may use this to intercept messages that are logged by the code under
* test. Example:
@@ -63,15 +61,15 @@ public class TestLogHandler extends Handler {
* Adds the most recently logged record to our list.
*/
@Override
- public void publish(@Nullable LogRecord record) {
+ public void publish(LogRecord record) {
list.add(record);
}
@Override
- public void flush() {}
+ public void flush() { }
@Override
- public void close() {}
+ public void close() { }
public void clear() {
list.clear();
diff --git a/guava-testlib/src/com/google/common/testing/package-info.java b/guava-testlib/src/com/google/common/testing/package-info.java
deleted file mode 100644
index 3b2f3b3..0000000
--- a/guava-testlib/src/com/google/common/testing/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This package contains testing utilities.
- * It is a part of the open-source
- * <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package com.google.common.testing;
diff --git a/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java b/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java
deleted file mode 100644
index 4e51d34..0000000
--- a/guava-testlib/src/com/google/common/util/concurrent/testing/TestingExecutors.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent.testing;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
-import com.google.common.primitives.Longs;
-import com.google.common.util.concurrent.AbstractFuture;
-import com.google.common.util.concurrent.AbstractListeningExecutorService;
-import com.google.common.util.concurrent.ListeningScheduledExecutorService;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Delayed;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Factory methods for {@link ExecutorService} for testing.
- *
- * @author Chris Nokleberg
- * @since 14.0
- */
-@Beta
-public final class TestingExecutors {
- private TestingExecutors() {}
-
- /**
- * Returns a {@link ScheduledExecutorService} that never executes anything.
- *
- * <p>The {@code shutdownNow} method of the returned executor always returns an empty list despite
- * the fact that everything is still technically awaiting execution.
- * The {@code getDelay} method of any {@link ScheduledFuture} returned by the executor will always
- * return the max long value instead of the time until the user-specified delay.
- */
- public static ListeningScheduledExecutorService noOpScheduledExecutor() {
- return new NoOpScheduledExecutorService();
- }
-
- private static final class NoOpScheduledExecutorService
- extends AbstractListeningExecutorService implements ListeningScheduledExecutorService {
-
- private volatile boolean shutdown;
-
- @Override public void shutdown() {
- shutdown = true;
- }
-
- @Override public List<Runnable> shutdownNow() {
- shutdown();
- return ImmutableList.of();
- }
-
- @Override public boolean isShutdown() {
- return shutdown;
- }
-
- @Override public boolean isTerminated() {
- return shutdown;
- }
-
- @Override public boolean awaitTermination(long timeout, TimeUnit unit) {
- return true;
- }
-
- @Override public void execute(Runnable runnable) {}
-
- @Override public <V> ScheduledFuture<V> schedule(
- Callable<V> callable, long delay, TimeUnit unit) {
- return NeverScheduledFuture.create();
- }
-
- @Override public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
- return NeverScheduledFuture.create();
- }
-
- @Override public ScheduledFuture<?> scheduleAtFixedRate(
- Runnable command, long initialDelay, long period, TimeUnit unit) {
- return NeverScheduledFuture.create();
- }
-
- @Override public ScheduledFuture<?> scheduleWithFixedDelay(
- Runnable command, long initialDelay, long delay, TimeUnit unit) {
- return NeverScheduledFuture.create();
- }
-
- private static class NeverScheduledFuture<V>
- extends AbstractFuture<V> implements ScheduledFuture<V> {
-
- static <V> NeverScheduledFuture<V> create() {
- return new NeverScheduledFuture<V>();
- }
-
- @Override public long getDelay(TimeUnit unit) {
- return Long.MAX_VALUE;
- }
-
- @Override public int compareTo(Delayed other) {
- return Longs.compare(getDelay(TimeUnit.NANOSECONDS), other.getDelay(TimeUnit.NANOSECONDS));
- }
- }
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java b/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java
deleted file mode 100644
index 2e0d594..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/FeatureSpecificTestSuiteBuilderTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.collect.testing.features.CollectionFeature;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author Max Ross
- */
-public class FeatureSpecificTestSuiteBuilderTest extends TestCase {
-
- static boolean testWasRun;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- testWasRun = false;
- }
-
- public static final class MyAbstractTester extends AbstractTester {
- public void testNothing() {
- testWasRun = true;
- }
- }
-
- private static final class MyTestSuiteBuilder extends
- FeatureSpecificTestSuiteBuilder<MyTestSuiteBuilder, String> {
-
- @Override
- protected List<Class<? extends AbstractTester>> getTesters() {
- return Collections.<Class<? extends AbstractTester>>singletonList(MyAbstractTester.class);
- }
- }
-
- public void testLifecycle() {
- final boolean setUp[] = {false};
- Runnable setUpRunnable = new Runnable() {
- @Override
- public void run() {
- setUp[0] = true;
- }
- };
-
- final boolean tearDown[] = {false};
- Runnable tearDownRunnable = new Runnable() {
- @Override
- public void run() {
- tearDown[0] = true;
- }
- };
-
- MyTestSuiteBuilder builder = new MyTestSuiteBuilder();
- Test test = builder.usingGenerator("yam").named("yam")
- .withFeatures(CollectionFeature.NONE).withSetUp(setUpRunnable)
- .withTearDown(tearDownRunnable).createTestSuite();
- TestResult result = new TestResult();
- test.run(result);
- assertTrue(testWasRun);
- assertTrue(setUp[0]);
- assertTrue(tearDown[0]);
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/HelpersTest.java b/guava-testlib/test/com/google/common/collect/testing/HelpersTest.java
deleted file mode 100644
index 5c1432b..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/HelpersTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.Helpers.NullsBeforeB;
-import static com.google.common.collect.testing.Helpers.testComparator;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test for {@link Helpers}.
- *
- * @author Chris Povirk
- */
-public class HelpersTest extends TestCase {
- public void testNullsBeforeB() {
- testComparator(NullsBeforeB.INSTANCE, "a", "azzzzzz", null, "b", "c");
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/IteratorTesterTest.java b/guava-testlib/test/com/google/common/collect/testing/IteratorTesterTest.java
deleted file mode 100644
index e272ec0..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/IteratorTesterTest.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static java.util.Collections.emptyList;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * Unit test for IteratorTester.
- *
- * @author Mick Killianey
- */
-@SuppressWarnings("serial") // No serialization is used in this test
-public class IteratorTesterTest extends TestCase {
-
- public void testCanCatchDifferentLengthOfIteration() {
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(4, MODIFIABLE, newArrayList(1, 2, 3),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return Lists.newArrayList(1, 2, 3, 4).iterator();
- }
- };
- assertFailure(tester);
- }
-
- public void testCanCatchDifferentContents() {
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(3, MODIFIABLE, newArrayList(1, 2, 3),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return Lists.newArrayList(1, 3, 2).iterator();
- }
- };
- assertFailure(tester);
- }
-
- public void testCanCatchDifferentRemoveBehaviour() {
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(3, MODIFIABLE, newArrayList(1, 2),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return ImmutableList.of(1, 2).iterator();
- }
- };
- assertFailure(tester);
- }
-
- public void testUnknownOrder() {
- new IteratorTester<Integer>(3, MODIFIABLE, newArrayList(1, 2),
- IteratorTester.KnownOrder.UNKNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return newArrayList(2, 1).iterator();
- }
- }.test();
- }
-
- public void testUnknownOrderUnrecognizedElement() {
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(3, MODIFIABLE, newArrayList(1, 2, 50),
- IteratorTester.KnownOrder.UNKNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return newArrayList(2, 1, 3).iterator();
- }
- };
- assertFailure(tester);
- }
-
- /**
- * This Iterator wraps another iterator and gives it a bug found
- * in JDK6.
- *
- * <p>This bug is this: if you create an iterator from a TreeSet
- * and call next() on that iterator when hasNext() is false, so
- * that next() throws a NoSuchElementException, then subsequent
- * calls to remove() will incorrectly throw an IllegalStateException,
- * instead of removing the last element returned.
- *
- * <p>See
- * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6529795">
- * Sun bug 6529795</a>
- */
- static class IteratorWithSunJavaBug6529795<T> implements Iterator<T> {
- Iterator<T> iterator;
- boolean nextThrewException;
- IteratorWithSunJavaBug6529795(Iterator<T> iterator) {
- this.iterator = iterator;
- }
-
- @Override
- public boolean hasNext() {
- return iterator.hasNext();
- }
-
- @Override
- public T next() {
- try {
- return iterator.next();
- } catch (NoSuchElementException e) {
- nextThrewException = true;
- throw e;
- }
- }
-
- @Override
- public void remove() {
- if (nextThrewException) {
- throw new IllegalStateException();
- }
- iterator.remove();
- }
- }
-
- public void testCanCatchSunJavaBug6529795InTargetIterator() {
- try {
- /* Choose 4 steps to get sequence [next, next, next, remove] */
- new IteratorTester<Integer>(4, MODIFIABLE, newArrayList(1, 2),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- Iterator<Integer> iterator = Lists.newArrayList(1, 2).iterator();
- return new IteratorWithSunJavaBug6529795<Integer>(iterator);
- }
- }.test();
- } catch (AssertionFailedError e) {
- return;
- }
- fail("Should have caught jdk6 bug in target iterator");
- }
-
- public void testCanWorkAroundSunJavaBug6529795InTargetIterator() {
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(4, MODIFIABLE, newArrayList(1, 2),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- Iterator<Integer> iterator = Lists.newArrayList(1, 2).iterator();
- return new IteratorWithSunJavaBug6529795<Integer>(iterator);
- }
- };
-
- /*
- * Calling this method on an IteratorTester should avoid flagging
- * the bug exposed by the preceding test.
- */
- tester.ignoreSunJavaBug6529795();
-
- tester.test();
- }
-
- private static final int STEPS = 3;
- static class TesterThatCountsCalls extends IteratorTester<Integer> {
- TesterThatCountsCalls() {
- super(STEPS, MODIFIABLE, newArrayList(1),
- IteratorTester.KnownOrder.KNOWN_ORDER);
- }
- int numCallsToNewTargetIterator;
- int numCallsToVerify;
- @Override protected Iterator<Integer> newTargetIterator() {
- numCallsToNewTargetIterator++;
- return Lists.newArrayList(1).iterator();
- }
- @Override protected void verify(List<Integer> elements) {
- numCallsToVerify++;
- super.verify(elements);
- }
- }
-
- public void testVerifyGetsCalled() {
- TesterThatCountsCalls tester = new TesterThatCountsCalls();
-
- tester.test();
-
- assertEquals("Should have verified once per stimulus executed",
- tester.numCallsToVerify,
- tester.numCallsToNewTargetIterator * STEPS);
- }
-
- public void testVerifyCanThrowAssertionThatFailsTest() {
- final String message = "Important info about why verify failed";
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(1, MODIFIABLE, newArrayList(1, 2, 3),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return Lists.newArrayList(1, 2, 3).iterator();
- }
-
- @Override protected void verify(List<Integer> elements) {
- throw new AssertionFailedError(message);
- }
- };
- AssertionFailedError actual = null;
- try {
- tester.test();
- } catch (AssertionFailedError e) {
- actual = e;
- }
- assertNotNull("verify() should be able to cause test failure", actual);
- assertTrue("AssertionFailedError should have info about why test failed",
- actual.getCause().getMessage().contains(message));
- }
-
- public void testMissingException() {
- List<Integer> emptyList = newArrayList();
-
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(1, MODIFIABLE, emptyList,
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return new Iterator<Integer>() {
- @Override
- public void remove() {
- // We should throw here, but we won't!
- }
- @Override
- public Integer next() {
- // We should throw here, but we won't!
- return null;
- }
- @Override
- public boolean hasNext() {
- return false;
- }
- };
- }
- };
- assertFailure(tester);
- }
-
- public void testUnexpectedException() {
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(1, MODIFIABLE, newArrayList(1),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return new ThrowingIterator<Integer>(new IllegalStateException());
- }
- };
- assertFailure(tester);
- }
-
- public void testSimilarException() {
- List<Integer> emptyList = emptyList();
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(1, MODIFIABLE, emptyList,
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return new Iterator<Integer>() {
- @Override
- public void remove() {
- throw new IllegalStateException() { /* subclass */};
- }
- @Override
- public Integer next() {
- throw new NoSuchElementException() { /* subclass */};
- }
- @Override
- public boolean hasNext() {
- return false;
- }
- };
- }
- };
- tester.test();
- }
-
- public void testMismatchedException() {
- List<Integer> emptyList = emptyList();
- IteratorTester<Integer> tester =
- new IteratorTester<Integer>(1, MODIFIABLE, emptyList,
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return new Iterator<Integer>() {
- @Override
- public void remove() {
- // Wrong exception type.
- throw new IllegalArgumentException();
- }
- @Override
- public Integer next() {
- // Wrong exception type.
- throw new UnsupportedOperationException();
- }
- @Override
- public boolean hasNext() {
- return false;
- }
- };
- }
- };
- assertFailure(tester);
- }
-
- private static void assertFailure(IteratorTester<?> tester) {
- try {
- tester.test();
- fail();
- } catch (AssertionFailedError expected) {
- }
- }
-
- private static final class ThrowingIterator<E> implements Iterator<E> {
- private final RuntimeException ex;
-
- private ThrowingIterator(RuntimeException ex) {
- this.ex = ex;
- }
-
- @Override
- public boolean hasNext() {
- // IteratorTester doesn't expect exceptions for hasNext().
- return true;
- }
-
- @Override
- public E next() {
- ex.fillInStackTrace();
- throw ex;
- }
-
- @Override
- public void remove() {
- ex.fillInStackTrace();
- throw ex;
- }
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java b/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java
deleted file mode 100644
index 43b1983..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/MapTestSuiteBuilderTests.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
-import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.features.MapFeature;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.AbstractMap;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Tests {@link MapTestSuiteBuilder} by using it against maps that have various
- * negative behaviors.
- *
- * @author George van den Driessche
- */
-public final class MapTestSuiteBuilderTests extends TestCase {
- private MapTestSuiteBuilderTests() {}
-
- public static Test suite() {
- TestSuite suite = new TestSuite(
- MapTestSuiteBuilderTests.class.getSimpleName());
- suite.addTest(testsForHashMapNullKeysForbidden());
- suite.addTest(testsForHashMapNullValuesForbidden());
- return suite;
- }
-
- private abstract static class WrappedHashMapGenerator
- extends TestStringMapGenerator {
- @Override protected final Map<String, String> create(
- Map.Entry<String, String>[] entries) {
- HashMap<String, String> map = Maps.newHashMap();
- for (Map.Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- return wrap(map);
- }
-
- abstract Map<String, String> wrap(HashMap<String, String> map);
- }
-
- private static TestSuite wrappedHashMapTests(
- WrappedHashMapGenerator generator, String name, Feature<?>... features) {
- return MapTestSuiteBuilder.using(generator)
- .named(name)
- .withFeatures(Lists.asList(
- MapFeature.GENERAL_PURPOSE, CollectionSize.ANY, features))
- .createTestSuite();
- }
-
- // TODO: consider being null-hostile in these tests
-
- private static Test testsForHashMapNullKeysForbidden() {
- return wrappedHashMapTests(new WrappedHashMapGenerator() {
- @Override Map<String, String> wrap(final HashMap<String, String> map) {
- if (map.containsKey(null)) {
- throw new NullPointerException();
- }
- return new AbstractMap<String, String>() {
- @Override public Set<Map.Entry<String, String>> entrySet() {
- return map.entrySet();
- }
- @Override public String put(String key, String value) {
- checkNotNull(key);
- return map.put(key, value);
- }
- };
- }
- }, "HashMap w/out null keys", ALLOWS_NULL_VALUES);
- }
-
- private static Test testsForHashMapNullValuesForbidden() {
- return wrappedHashMapTests(new WrappedHashMapGenerator() {
- @Override Map<String, String> wrap(final HashMap<String, String> map) {
- if (map.containsValue(null)) {
- throw new NullPointerException();
- }
- return new AbstractMap<String, String>() {
- @Override public Set<Map.Entry<String, String>> entrySet() {
- return map.entrySet();
- }
- @Override public String put(String key, String value) {
- checkNotNull(value);
- return map.put(key, value);
- }
- };
- }
- }, "HashMap w/out null values", ALLOWS_NULL_KEYS);
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/MinimalCollectionTest.java b/guava-testlib/test/com/google/common/collect/testing/MinimalCollectionTest.java
deleted file mode 100644
index c701b63..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/MinimalCollectionTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-
-import java.util.Collection;
-
-/**
- * Unit test for {@link MinimalCollection}.
- *
- * @author Kevin Bourrillion
- */
-public class MinimalCollectionTest extends TestCase {
- public static Test suite() {
- return CollectionTestSuiteBuilder
- .using(new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- // TODO: MinimalCollection should perhaps throw
- for (Object element : elements) {
- if (element == null) {
- throw new NullPointerException();
- }
- }
- return MinimalCollection.of(elements);
- }
- })
- .named("MinimalCollection")
- .withFeatures(
- CollectionFeature.NONE,
- CollectionSize.ANY)
- .createTestSuite();
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/MinimalIterableTest.java b/guava-testlib/test/com/google/common/collect/testing/MinimalIterableTest.java
deleted file mode 100644
index 540237d..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/MinimalIterableTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import junit.framework.TestCase;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Unit test for {@link MinimalIterable}.
- *
- * @author Kevin Bourrillion
- */
-public class MinimalIterableTest extends TestCase {
-
- public void testOf_empty() {
- Iterable<String> iterable = MinimalIterable.<String>of();
- Iterator<String> iterator = iterable.iterator();
- assertFalse(iterator.hasNext());
- try {
- iterator.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- iterable.iterator();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- public void testOf_one() {
- Iterable<String> iterable = MinimalIterable.of("a");
- Iterator<String> iterator = iterable.iterator();
- assertTrue(iterator.hasNext());
- assertEquals("a", iterator.next());
- assertFalse(iterator.hasNext());
- try {
- iterator.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- iterable.iterator();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- public void testFrom_empty() {
- Iterable<String> iterable
- = MinimalIterable.from(Collections.<String>emptySet());
- Iterator<String> iterator = iterable.iterator();
- assertFalse(iterator.hasNext());
- try {
- iterator.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- iterable.iterator();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-
- public void testFrom_one() {
- Iterable<String> iterable
- = MinimalIterable.from(Collections.singleton("a"));
- Iterator<String> iterator = iterable.iterator();
- assertTrue(iterator.hasNext());
- assertEquals("a", iterator.next());
- try {
- iterator.remove();
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- assertFalse(iterator.hasNext());
- try {
- iterator.next();
- fail();
- } catch (NoSuchElementException expected) {
- }
- try {
- iterable.iterator();
- fail();
- } catch (IllegalStateException expected) {
- }
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/MinimalSetTest.java b/guava-testlib/test/com/google/common/collect/testing/MinimalSetTest.java
deleted file mode 100644
index 1d21f13..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/MinimalSetTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-
-import java.util.Set;
-
-/**
- * Unit test for {@link MinimalSet}.
- *
- * @author Regina O'Dell
- */
-public class MinimalSetTest extends TestCase {
- public static Test suite() {
- return SetTestSuiteBuilder
- .using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- return MinimalSet.of(elements);
- }
- })
- .named("MinimalSet")
- .withFeatures(
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.NONE,
- CollectionSize.ANY)
- .createTestSuite();
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6ListTests.java b/guava-testlib/test/com/google/common/collect/testing/OpenJdk6ListTests.java
deleted file mode 100644
index d4cc2f4..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6ListTests.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod;
-import static com.google.common.collect.testing.testers.CollectionToArrayTester.getToArrayIsPlainObjectArrayMethod;
-import static com.google.common.collect.testing.testers.ListAddTester.getAddSupportedNullPresentMethod;
-import static com.google.common.collect.testing.testers.ListListIteratorTester.getListIteratorFullyModifiableMethod;
-import static com.google.common.collect.testing.testers.ListSetTester.getSetNullSupportedMethod;
-import static com.google.common.collect.testing.testers.ListSubListTester.getSubListOriginalListSetAffectsSubListLargeListMethod;
-import static com.google.common.collect.testing.testers.ListSubListTester.getSubListOriginalListSetAffectsSubListMethod;
-import static com.google.common.collect.testing.testers.ListSubListTester.getSubListSubListRemoveAffectsOriginalLargeListMethod;
-
-import com.google.common.collect.testing.testers.CollectionAddTester;
-import com.google.common.collect.testing.testers.ListAddAtIndexTester;
-
-import junit.framework.Test;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Tests the {@link List} implementations of {@link java.util}, suppressing
- * tests that trip known OpenJDK 6 bugs.
- *
- * @author Kevin Bourrillion
- */
-public class OpenJdk6ListTests extends TestsForListsInJavaUtil {
- public static Test suite() {
- return new OpenJdk6ListTests().allTests();
- }
-
- @Override protected Collection<Method> suppressForArraysAsList() {
- return Arrays.asList(
- getToArrayIsPlainObjectArrayMethod());
- }
-
- @Override protected Collection<Method> suppressForCopyOnWriteArrayList() {
- return Arrays.asList(
- getSubListOriginalListSetAffectsSubListMethod(),
- getSubListOriginalListSetAffectsSubListLargeListMethod(),
- getSubListSubListRemoveAffectsOriginalLargeListMethod(),
- getIteratorKnownOrderRemoveSupportedMethod(),
- getListIteratorFullyModifiableMethod());
- }
-
- @Override protected Collection<Method> suppressForCheckedList() {
- return Arrays.asList(
- CollectionAddTester.getAddNullSupportedMethod(),
- getAddSupportedNullPresentMethod(),
- ListAddAtIndexTester.getAddNullSupportedMethod(),
- getSetNullSupportedMethod());
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6MapTests.java b/guava-testlib/test/com/google/common/collect/testing/OpenJdk6MapTests.java
deleted file mode 100644
index a56c77a..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6MapTests.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.testers.CollectionCreationTester.getCreateWithNullUnsupportedMethod;
-import static com.google.common.collect.testing.testers.MapCreationTester.getCreateWithNullKeyUnsupportedMethod;
-import static com.google.common.collect.testing.testers.MapPutAllTester.getPutAllNullKeyUnsupportedMethod;
-import static com.google.common.collect.testing.testers.MapPutTester.getPutNullKeyUnsupportedMethod;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Tests the {@link Map} implementations of {@link java.util}, suppressing
- * tests that trip known OpenJDK 6 bugs.
- *
- * @author Kevin Bourrillion
- */
-public class OpenJdk6MapTests extends TestsForMapsInJavaUtil {
- public static Test suite() {
- return new OpenJdk6MapTests().allTests();
- }
-
- @Override protected Collection<Method> suppressForTreeMapNatural() {
- return Arrays.asList(
- getPutNullKeyUnsupportedMethod(),
- getPutAllNullKeyUnsupportedMethod(),
- getCreateWithNullKeyUnsupportedMethod(),
- getCreateWithNullUnsupportedMethod()); // for keySet
- }
-
- @Override public Test testsForEnumMap() {
- // Do nothing.
- // TODO: work around the reused-entry problem
- // http://bugs.sun.com/view_bug.do?bug_id=6312706
- return new TestSuite();
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6QueueTests.java b/guava-testlib/test/com/google/common/collect/testing/OpenJdk6QueueTests.java
deleted file mode 100644
index 6cc1dd3..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6QueueTests.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.testers.CollectionCreationTester.getCreateWithNullUnsupportedMethod;
-
-import junit.framework.Test;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Queue;
-
-/**
- * Tests the {@link Queue} implementations of {@link java.util}, suppressing
- * tests that trip known OpenJDK 6 bugs.
- *
- * @author Kevin Bourrillion
- */
-public class OpenJdk6QueueTests extends TestsForQueuesInJavaUtil {
- public static Test suite() {
- return new OpenJdk6QueueTests().allTests();
- }
-
- private static final List<Method> PQ_SUPPRESS = Arrays.asList(
- getCreateWithNullUnsupportedMethod());
-
- @Override protected Collection<Method> suppressForPriorityBlockingQueue() {
- return PQ_SUPPRESS;
- }
-
- @Override protected Collection<Method> suppressForPriorityQueue() {
- return PQ_SUPPRESS;
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6SetTests.java b/guava-testlib/test/com/google/common/collect/testing/OpenJdk6SetTests.java
deleted file mode 100644
index 77aa34f..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6SetTests.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static com.google.common.collect.testing.testers.CollectionAddAllTester.getAddAllNullUnsupportedMethod;
-import static com.google.common.collect.testing.testers.CollectionAddTester.getAddNullSupportedMethod;
-import static com.google.common.collect.testing.testers.CollectionAddTester.getAddNullUnsupportedMethod;
-import static com.google.common.collect.testing.testers.CollectionCreationTester.getCreateWithNullUnsupportedMethod;
-import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod;
-import static com.google.common.collect.testing.testers.SetAddTester.getAddSupportedNullPresentMethod;
-
-import junit.framework.Test;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Set;
-
-/**
- * Tests the {@link Set} implementations of {@link java.util}, suppressing
- * tests that trip known OpenJDK 6 bugs.
- *
- * @author Kevin Bourrillion
- */
-public class OpenJdk6SetTests extends TestsForSetsInJavaUtil {
- public static Test suite() {
- return new OpenJdk6SetTests().allTests();
- }
-
- @Override protected Collection<Method> suppressForTreeSetNatural() {
- return Arrays.asList(
- getAddNullUnsupportedMethod(),
- getAddAllNullUnsupportedMethod(),
- getCreateWithNullUnsupportedMethod());
- }
-
- @Override protected Collection<Method> suppressForCopyOnWriteArraySet() {
- return Arrays.asList(
- getIteratorKnownOrderRemoveSupportedMethod());
- }
-
- @Override protected Collection<Method> suppressForCheckedSet() {
- return Arrays.asList(
- getAddNullSupportedMethod(),
- getAddSupportedNullPresentMethod());
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6Tests.java b/guava-testlib/test/com/google/common/collect/testing/OpenJdk6Tests.java
deleted file mode 100644
index ebf93ef..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/OpenJdk6Tests.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Suite of tests for OpenJdk 6 tests. The existence of this class is a hack
- * because the suitebuilder won't pick up the suites directly in the other
- * classes because they don't extend TestCase. Ergh.
- *
- * @author Kevin Bourrillion
- */
-public class OpenJdk6Tests extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(OpenJdk6SetTests.suite());
- suite.addTest(OpenJdk6ListTests.suite());
- suite.addTest(OpenJdk6QueueTests.suite());
- suite.addTest(OpenJdk6MapTests.suite());
- return suite;
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/SafeTreeMapTest.java b/guava-testlib/test/com/google/common/collect/testing/SafeTreeMapTest.java
deleted file mode 100644
index 0532fbf..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/SafeTreeMapTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import static java.util.Collections.sort;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.testing.Helpers.NullsBeforeTwo;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.SortedMap;
-
-/**
- * Tests for SafeTreeMap.
- *
- * @author Louis Wasserman
- */
-public class SafeTreeMapTest extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(SafeTreeMapTest.class);
- suite.addTest(
- NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- NavigableMap<String, String> map =
- new SafeTreeMap<String, String>(Ordering.natural());
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- return map;
- }
- }).withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- MapFeature.ALLOWS_NULL_VALUES, MapFeature.GENERAL_PURPOSE).named(
- "SafeTreeMap with natural comparator").createTestSuite());
- suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- NavigableMap<String, String> map =
- new SafeTreeMap<String, String>(NullsBeforeTwo.INSTANCE);
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- return map;
- }
-
- @Override
- public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) {
- sort(insertionOrder, Helpers.<String, String>entryComparator(NullsBeforeTwo.INSTANCE));
- return insertionOrder;
- }
- }).withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE).named(
- "SafeTreeMap with null-friendly comparator").createTestSuite());
- return suite;
- }
-
- @GwtIncompatible("SerializableTester")
- public void testViewSerialization() {
- Map<String, Integer> map =
- ImmutableSortedMap.of("one", 1, "two", 2, "three", 3);
- SerializableTester.reserializeAndAssert(map.entrySet());
- SerializableTester.reserializeAndAssert(map.keySet());
- assertEquals(Lists.newArrayList(map.values()),
- Lists.newArrayList(SerializableTester.reserialize(map.values())));
- }
-
- @GwtIncompatible("SerializableTester")
- public static class ReserializedMapTests
- extends SortedMapInterfaceTest<String, Integer> {
- ReserializedMapTests() {
- super(false, true, true, true, true);
- }
-
- @Override protected SortedMap<String, Integer> makePopulatedMap() {
- NavigableMap<String, Integer> map = new SafeTreeMap<String, Integer>();
- map.put("one", 1);
- map.put("two", 2);
- map.put("three", 3);
- return SerializableTester.reserialize(map);
- }
-
- @Override protected SortedMap<String, Integer> makeEmptyMap()
- throws UnsupportedOperationException {
- NavigableMap<String, Integer> map = new SafeTreeMap<String, Integer>();
- return SerializableTester.reserialize(map);
- }
-
- @Override protected String getKeyNotInPopulatedMap() {
- return "minus one";
- }
-
- @Override protected Integer getValueNotInPopulatedMap() {
- return -1;
- }
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/SafeTreeSetTest.java b/guava-testlib/test/com/google/common/collect/testing/SafeTreeSetTest.java
deleted file mode 100644
index a03081b..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/SafeTreeSetTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedSet;
-
-public class SafeTreeSetTest extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(SafeTreeSetTest.class);
- suite.addTest(
- NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- return new SafeTreeSet<String>(Arrays.asList(elements));
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
- }
- }).withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE).named(
- "SafeTreeSet with natural comparator").createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- NavigableSet<String> set =
- new SafeTreeSet<String>(Ordering.natural().nullsFirst());
- set.addAll(Arrays.asList(elements));
- return set;
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
- }
- }).withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES)
- .named("SafeTreeSet with null-friendly comparator").createTestSuite());
- return suite;
- }
-
- @GwtIncompatible("SerializableTester")
- public void testViewSerialization() {
- Map<String, Integer> map =
- ImmutableSortedMap.of("one", 1, "two", 2, "three", 3);
- SerializableTester.reserializeAndAssert(map.entrySet());
- SerializableTester.reserializeAndAssert(map.keySet());
- assertEquals(Lists.newArrayList(map.values()),
- Lists.newArrayList(SerializableTester.reserialize(map.values())));
- }
-
- @GwtIncompatible("SerializableTester")
- public void testEmpty_serialization() {
- SortedSet<String> set = new SafeTreeSet<String>();
- SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
- assertEquals(set.comparator(), copy.comparator());
- }
-
- @GwtIncompatible("SerializableTester")
- public void testSingle_serialization() {
- SortedSet<String> set = new SafeTreeSet<String>();
- set.add("e");
- SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
- assertEquals(set.comparator(), copy.comparator());
- }
-
- @GwtIncompatible("SerializableTester")
- public void testSeveral_serialization() {
- SortedSet<String> set = new SafeTreeSet<String>();
- set.add("a");
- set.add("b");
- set.add("c");
- SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
- assertEquals(set.comparator(), copy.comparator());
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/features/FeatureEnumTest.java b/guava-testlib/test/com/google/common/collect/testing/features/FeatureEnumTest.java
deleted file mode 100644
index 394dcd4..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/features/FeatureEnumTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.features;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Method;
-
-/**
- * Since annotations have some reusability issues that force copy and paste
- * all over the place, it's worth having a test to ensure that all our Feature
- * enums have their annotations correctly set up.
- *
- * @author George van den Driessche
- */
-public class FeatureEnumTest extends TestCase {
- private static void assertGoodTesterAnnotation(
- Class<? extends Annotation> annotationClass) {
- assertNotNull(
- String.format("%s must be annotated with @TesterAnnotation.",
- annotationClass),
- annotationClass.getAnnotation(TesterAnnotation.class));
- final Retention retentionPolicy =
- annotationClass.getAnnotation(Retention.class);
- assertNotNull(
- String.format("%s must have a @Retention annotation.", annotationClass),
- retentionPolicy);
- assertEquals(
- String.format("%s must have RUNTIME RetentionPolicy.", annotationClass),
- RetentionPolicy.RUNTIME, retentionPolicy.value());
- assertNotNull(
- String.format("%s must be inherited.", annotationClass),
- annotationClass.getAnnotation(Inherited.class));
-
- for (String propertyName : new String[]{"value", "absent"}) {
- Method method = null;
- try {
- method = annotationClass.getMethod(propertyName);
- } catch (NoSuchMethodException e) {
- fail(String.format("%s must have a property named '%s'.",
- annotationClass, propertyName));
- }
- final Class<?> returnType = method.getReturnType();
- assertTrue(String.format("%s.%s() must return an array.",
- annotationClass, propertyName),
- returnType.isArray());
- assertSame(String.format("%s.%s() must return an array of %s.",
- annotationClass, propertyName, annotationClass.getDeclaringClass()),
- annotationClass.getDeclaringClass(), returnType.getComponentType());
- }
- }
-
- // This is public so that tests for Feature enums we haven't yet imagined
- // can reuse it.
- public static <E extends Enum<?> & Feature<?>> void assertGoodFeatureEnum(
- Class<E> featureEnumClass) {
- final Class<?>[] classes = featureEnumClass.getDeclaredClasses();
- for (Class<?> containedClass : classes) {
- if (containedClass.getSimpleName().equals("Require")) {
- if (containedClass.isAnnotation()) {
- assertGoodTesterAnnotation(asAnnotation(containedClass));
- } else {
- fail(String.format("Feature enum %s contains a class named " +
- "'Require' but it is not an annotation.", featureEnumClass));
- }
- return;
- }
- }
- fail(String.format("Feature enum %s should contain an " +
- "annotation named 'Require'.", featureEnumClass));
- }
-
- @SuppressWarnings("unchecked")
- private static Class<? extends Annotation> asAnnotation(Class<?> clazz) {
- if (clazz.isAnnotation()) {
- return (Class<? extends Annotation>) clazz;
- } else {
- throw new IllegalArgumentException(
- String.format("%s is not an annotation.", clazz));
- }
- }
-
- public void testFeatureEnums() throws Exception {
- assertGoodFeatureEnum(CollectionFeature.class);
- assertGoodFeatureEnum(ListFeature.class);
- assertGoodFeatureEnum(SetFeature.class);
- assertGoodFeatureEnum(CollectionSize.class);
- assertGoodFeatureEnum(MapFeature.class);
- }
-}
diff --git a/guava-testlib/test/com/google/common/collect/testing/features/FeatureUtilTest.java b/guava-testlib/test/com/google/common/collect/testing/features/FeatureUtilTest.java
deleted file mode 100644
index c92c75f..0000000
--- a/guava-testlib/test/com/google/common/collect/testing/features/FeatureUtilTest.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect.testing.features;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * @author George van den Driessche
- */
-// Enum values use constructors with generic varargs.
-@SuppressWarnings("unchecked")
-public class FeatureUtilTest extends TestCase {
- interface ExampleBaseInterface {
- void behave();
- }
-
- interface ExampleDerivedInterface extends ExampleBaseInterface {
- void misbehave();
- }
-
- enum ExampleBaseFeature implements Feature<ExampleBaseInterface> {
- BASE_FEATURE_1,
- BASE_FEATURE_2;
-
- @Override
- public Set<Feature<? super ExampleBaseInterface>> getImpliedFeatures() {
- return Collections.emptySet();
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- @TesterAnnotation
- @interface Require {
- ExampleBaseFeature[] value() default {};
- ExampleBaseFeature[] absent() default {};
- }
- }
-
- enum ExampleDerivedFeature implements Feature<ExampleDerivedInterface>{
- DERIVED_FEATURE_1,
- DERIVED_FEATURE_2(ExampleBaseFeature.BASE_FEATURE_1),
- DERIVED_FEATURE_3,
-
- COMPOUND_DERIVED_FEATURE(
- DERIVED_FEATURE_1,
- DERIVED_FEATURE_2,
- ExampleBaseFeature.BASE_FEATURE_2);
-
- private Set<Feature<? super ExampleDerivedInterface>> implied;
-
- ExampleDerivedFeature(
- Feature<? super ExampleDerivedInterface> ... implied) {
- this.implied = ImmutableSet.copyOf(implied);
- }
-
- @Override
- public Set<Feature<? super ExampleDerivedInterface>> getImpliedFeatures() {
- return implied;
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- @TesterAnnotation
- @interface Require {
- ExampleDerivedFeature[] value() default {};
- ExampleDerivedFeature[] absent() default {};
- }
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @interface NonTesterAnnotation {
- }
-
- @ExampleBaseFeature.Require({ExampleBaseFeature.BASE_FEATURE_1})
- private static abstract class ExampleBaseInterfaceTester extends TestCase {
- protected final void doNotActuallyRunThis() {
- fail("Nobody's meant to actually run this!");
- }
- }
-
- @NonTesterAnnotation
- @ExampleDerivedFeature.Require({ExampleDerivedFeature.DERIVED_FEATURE_2})
- private static class ExampleDerivedInterfaceTester
- extends ExampleBaseInterfaceTester {
- // Exists to test that our framework doesn't run it:
- @SuppressWarnings("unused")
- @ExampleDerivedFeature.Require({
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2})
- public void testRequiringTwoExplicitDerivedFeatures() throws Exception {
- doNotActuallyRunThis();
- }
-
- // Exists to test that our framework doesn't run it:
- @SuppressWarnings("unused")
- @ExampleDerivedFeature.Require({
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_3})
- public void testRequiringAllThreeDerivedFeatures() {
- doNotActuallyRunThis();
- }
-
- // Exists to test that our framework doesn't run it:
- @SuppressWarnings("unused")
- @ExampleBaseFeature.Require(absent = {ExampleBaseFeature.BASE_FEATURE_1})
- public void testRequiringConflictingFeatures() throws Exception {
- doNotActuallyRunThis();
- }
- }
-
- @ExampleDerivedFeature.Require(
- absent = {ExampleDerivedFeature.DERIVED_FEATURE_2})
- private static class ExampleDerivedInterfaceTester_Conflict
- extends ExampleBaseInterfaceTester {
- }
-
- public void testTestFeatureEnums() throws Exception {
- // Haha! Let's test our own test rig!
- FeatureEnumTest.assertGoodFeatureEnum(
- FeatureUtilTest.ExampleBaseFeature.class);
- FeatureEnumTest.assertGoodFeatureEnum(
- FeatureUtilTest.ExampleDerivedFeature.class);
- }
-
- public void testAddImpliedFeatures_returnsSameSetInstance() throws Exception {
- Set<Feature<?>> features = Sets.<Feature<?>>newHashSet(
- ExampleBaseFeature.BASE_FEATURE_1);
- assertSame(features, FeatureUtil.addImpliedFeatures(features));
- }
-
- public void testAddImpliedFeatures_addsImpliedFeatures() throws Exception {
- Set<Feature<?>> features;
-
- features = Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.DERIVED_FEATURE_1);
- ASSERT.that(FeatureUtil.addImpliedFeatures(features)).has().item(
- ExampleDerivedFeature.DERIVED_FEATURE_1);
-
- features = Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.DERIVED_FEATURE_2);
- ASSERT.that(FeatureUtil.addImpliedFeatures(features)).has().allOf(
- ExampleDerivedFeature.DERIVED_FEATURE_2,
- ExampleBaseFeature.BASE_FEATURE_1);
-
- features = Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE);
- ASSERT.that(FeatureUtil.addImpliedFeatures(features)).has().allOf(
- ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE,
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2,
- ExampleBaseFeature.BASE_FEATURE_1,
- ExampleBaseFeature.BASE_FEATURE_2);
- }
-
- public void testImpliedFeatures_returnsNewSetInstance() throws Exception {
- Set<Feature<?>> features = Sets.<Feature<?>>newHashSet(
- ExampleBaseFeature.BASE_FEATURE_1);
- assertNotSame(features, FeatureUtil.impliedFeatures(features));
- }
-
- public void testImpliedFeatures_returnsImpliedFeatures() throws Exception {
- Set<Feature<?>> features;
-
- features = Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.DERIVED_FEATURE_1);
- assertTrue(FeatureUtil.impliedFeatures(features).isEmpty());
-
- features = Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.DERIVED_FEATURE_2);
- ASSERT.that(FeatureUtil.impliedFeatures(features)).has().item(
- ExampleBaseFeature.BASE_FEATURE_1);
-
- features = Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.COMPOUND_DERIVED_FEATURE);
- ASSERT.that(FeatureUtil.impliedFeatures(features)).has().allOf(
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2,
- ExampleBaseFeature.BASE_FEATURE_1,
- ExampleBaseFeature.BASE_FEATURE_2);
- }
-
- public void testBuildTesterRequirements_class() throws Exception {
- assertEquals(FeatureUtil.buildTesterRequirements(
- ExampleBaseInterfaceTester.class),
- new TesterRequirements(
- Sets.<Feature<?>>newHashSet(ExampleBaseFeature.BASE_FEATURE_1),
- Collections.<Feature<?>>emptySet()));
-
- assertEquals(FeatureUtil.buildTesterRequirements(
- ExampleDerivedInterfaceTester.class),
- new TesterRequirements(
- Sets.<Feature<?>>newHashSet(
- ExampleBaseFeature.BASE_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2),
- Collections.<Feature<?>>emptySet()));
- }
-
- public void testBuildTesterRequirements_method() throws Exception {
- assertEquals(FeatureUtil.buildTesterRequirements(
- ExampleDerivedInterfaceTester.class.getMethod(
- "testRequiringTwoExplicitDerivedFeatures")),
- new TesterRequirements(
- Sets.<Feature<?>>newHashSet(
- ExampleBaseFeature.BASE_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2),
- Collections.<Feature<?>>emptySet()));
- assertEquals(FeatureUtil.buildTesterRequirements(
- ExampleDerivedInterfaceTester.class.getMethod(
- "testRequiringAllThreeDerivedFeatures")),
- new TesterRequirements(
- Sets.<Feature<?>>newHashSet(
- ExampleBaseFeature.BASE_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2,
- ExampleDerivedFeature.DERIVED_FEATURE_3),
- Collections.<Feature<?>>emptySet()));
- }
-
- public void testBuildTesterRequirements_classClassConflict()
- throws Exception {
- try {
- FeatureUtil.buildTesterRequirements(
- ExampleDerivedInterfaceTester_Conflict.class);
- fail("Expected ConflictingRequirementsException");
- } catch (ConflictingRequirementsException e) {
- ASSERT.that(e.getConflicts()).has().item(
- ExampleBaseFeature.BASE_FEATURE_1);
- assertEquals(ExampleDerivedInterfaceTester_Conflict.class, e.getSource());
- }
- }
-
- public void testBuildTesterRequirements_methodClassConflict()
- throws Exception {
- final Method method = ExampleDerivedInterfaceTester.class
- .getMethod("testRequiringConflictingFeatures");
- try {
- FeatureUtil.buildTesterRequirements(method);
- fail("Expected ConflictingRequirementsException");
- } catch (ConflictingRequirementsException e) {
- ASSERT.that(e.getConflicts()).has().item(
- ExampleBaseFeature.BASE_FEATURE_1);
- assertEquals(method, e.getSource());
- }
- }
-
- public void testBuildDeclaredTesterRequirements() throws Exception {
- assertEquals(FeatureUtil.buildDeclaredTesterRequirements(
- ExampleDerivedInterfaceTester.class
- .getMethod("testRequiringTwoExplicitDerivedFeatures")),
- new TesterRequirements(FeatureUtil.addImpliedFeatures(
- Sets.<Feature<?>>newHashSet(
- ExampleDerivedFeature.DERIVED_FEATURE_1,
- ExampleDerivedFeature.DERIVED_FEATURE_2)),
- Collections.<Feature<?>>emptySet()));
- }
-
-}
diff --git a/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java b/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java
deleted file mode 100644
index 686e6ae..0000000
--- a/guava-testlib/test/com/google/common/testing/AbstractPackageSanityTestsTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Unit tests for {@link AbstractPackageSanityTests}.
- *
- * @author Ben Yu
- */
-public class AbstractPackageSanityTestsTest extends TestCase {
-
- private final AbstractPackageSanityTests sanityTests = new AbstractPackageSanityTests() {};
-
- public void testFindClassesToTest_testClass() {
- ASSERT.that(findClassesToTest(ImmutableList.of(EmptyTest.class)))
- .isEmpty();
- ASSERT.that(findClassesToTest(ImmutableList.of(EmptyTests.class)))
- .isEmpty();
- ASSERT.that(findClassesToTest(ImmutableList.of(EmptyTestCase.class)))
- .isEmpty();
- ASSERT.that(findClassesToTest(ImmutableList.of(EmptyTestSuite.class)))
- .isEmpty();
- }
-
- public void testFindClassesToTest_noCorrespondingTestClass() {
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class)))
- .has().allOf(Foo.class).inOrder();
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class, Foo2Test.class)))
- .has().allOf(Foo.class).inOrder();
- }
-
- public void testFindClassesToTest_publicApiOnly() {
- sanityTests.publicApiOnly();
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class)))
- .isEmpty();
- ASSERT.that(findClassesToTest(ImmutableList.of(PublicFoo.class))).has().item(PublicFoo.class);
- }
-
- public void testFindClassesToTest_ignoreClasses() {
- sanityTests.ignoreClasses(Predicates.<Object>equalTo(PublicFoo.class));
- ASSERT.that(findClassesToTest(ImmutableList.of(PublicFoo.class)))
- .isEmpty();
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class))).has().item(Foo.class);
- }
-
- public void testFindClassesToTest_withCorrespondingTestClassButNotExplicitlyTested() {
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class, FooTest.class), "testNotThere"))
- .has().allOf(Foo.class).inOrder();
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class, FooTest.class), "testNotPublic"))
- .has().allOf(Foo.class).inOrder();
- }
-
- public void testFindClassesToTest_withCorrespondingTestClassAndExplicitlyTested() {
- ImmutableList<Class<? extends Object>> classes = ImmutableList.of(Foo.class, FooTest.class);
- ASSERT.that(findClassesToTest(classes, "testPublic"))
- .isEmpty();
- ASSERT.that(findClassesToTest(classes, "testNotThere", "testPublic"))
- .isEmpty();
- }
-
- public void testFindClassesToTest_withCorrespondingTestClass_noTestName() {
- ASSERT.that(findClassesToTest(ImmutableList.of(Foo.class, FooTest.class)))
- .has().allOf(Foo.class).inOrder();
- }
-
- static class EmptyTestCase {}
-
- static class EmptyTest {}
-
- static class EmptyTests {}
-
- static class EmptyTestSuite {}
-
- static class Foo {}
-
- public static class PublicFoo {}
-
- static class FooTest {
- @SuppressWarnings("unused") // accessed reflectively
- public void testPublic() {}
- @SuppressWarnings("unused") // accessed reflectively
- void testNotPublic() {}
- }
-
- // Shouldn't be mistaken as Foo's test
- static class Foo2Test {
- @SuppressWarnings("unused") // accessed reflectively
- public void testPublic() {}
- }
-
- private List<Class<?>> findClassesToTest(
- Iterable<? extends Class<?>> classes, String... explicitTestNames) {
- return sanityTests.findClassesToTest(classes, Arrays.asList(explicitTestNames));
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java b/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java
deleted file mode 100644
index a215e7e..0000000
--- a/guava-testlib/test/com/google/common/testing/ArbitraryInstancesTest.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Charsets;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Ticker;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.Constraint;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.MapConstraint;
-import com.google.common.collect.MapDifference;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.PeekingIterator;
-import com.google.common.collect.Range;
-import com.google.common.collect.RowSortedTable;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.SortedMapDifference;
-import com.google.common.collect.SortedMultiset;
-import com.google.common.collect.SortedSetMultimap;
-import com.google.common.collect.Table;
-import com.google.common.primitives.UnsignedInteger;
-import com.google.common.primitives.UnsignedLong;
-import com.google.common.util.concurrent.AtomicDouble;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.LongBuffer;
-import java.nio.ShortBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Currency;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.PriorityQueue;
-import java.util.Queue;
-import java.util.Random;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.DelayQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.MatchResult;
-import java.util.regex.Pattern;
-
-/**
- * Unit test for {@link ArbitraryInstances}.
- *
- * @author Ben Yu
- */
-public class ArbitraryInstancesTest extends TestCase {
-
- public void testGet_primitives() {
- assertNull(ArbitraryInstances.get(void.class));
- assertNull(ArbitraryInstances.get(Void.class));
- assertEquals(Boolean.FALSE, ArbitraryInstances.get(boolean.class));
- assertEquals(Boolean.FALSE, ArbitraryInstances.get(Boolean.class));
- assertEquals(Character.valueOf('\0'), ArbitraryInstances.get(char.class));
- assertEquals(Character.valueOf('\0'), ArbitraryInstances.get(Character.class));
- assertEquals(Byte.valueOf((byte) 0), ArbitraryInstances.get(byte.class));
- assertEquals(Byte.valueOf((byte) 0), ArbitraryInstances.get(Byte.class));
- assertEquals(Short.valueOf((short) 0), ArbitraryInstances.get(short.class));
- assertEquals(Short.valueOf((short) 0), ArbitraryInstances.get(Short.class));
- assertEquals(Integer.valueOf(0), ArbitraryInstances.get(int.class));
- assertEquals(Integer.valueOf(0), ArbitraryInstances.get(Integer.class));
- assertEquals(Long.valueOf(0), ArbitraryInstances.get(long.class));
- assertEquals(Long.valueOf(0), ArbitraryInstances.get(Long.class));
- assertEquals(Float.valueOf(0), ArbitraryInstances.get(float.class));
- assertEquals(Float.valueOf(0), ArbitraryInstances.get(Float.class));
- assertEquals(Double.valueOf(0), ArbitraryInstances.get(double.class));
- assertEquals(Double.valueOf(0), ArbitraryInstances.get(Double.class));
- assertEquals(UnsignedInteger.ZERO, ArbitraryInstances.get(UnsignedInteger.class));
- assertEquals(UnsignedLong.ZERO, ArbitraryInstances.get(UnsignedLong.class));
- assertEquals(0, ArbitraryInstances.get(BigDecimal.class).intValue());
- assertEquals(0, ArbitraryInstances.get(BigInteger.class).intValue());
- assertEquals("", ArbitraryInstances.get(String.class));
- assertEquals("", ArbitraryInstances.get(CharSequence.class));
- assertEquals(TimeUnit.SECONDS, ArbitraryInstances.get(TimeUnit.class));
- assertNotNull(ArbitraryInstances.get(Object.class));
- assertEquals(0, ArbitraryInstances.get(Number.class));
- assertEquals(Charsets.UTF_8, ArbitraryInstances.get(Charset.class));
- }
-
- public void testGet_collections() {
- assertEquals(Iterators.emptyIterator(), ArbitraryInstances.get(Iterator.class));
- assertFalse(ArbitraryInstances.get(PeekingIterator.class).hasNext());
- assertFalse(ArbitraryInstances.get(ListIterator.class).hasNext());
- assertEquals(ImmutableSet.of(), ArbitraryInstances.get(Iterable.class));
- assertEquals(ImmutableSet.of(), ArbitraryInstances.get(Set.class));
- assertEquals(ImmutableSet.of(), ArbitraryInstances.get(ImmutableSet.class));
- assertEquals(ImmutableSortedSet.of(), ArbitraryInstances.get(SortedSet.class));
- assertEquals(ImmutableSortedSet.of(), ArbitraryInstances.get(ImmutableSortedSet.class));
- assertEquals(ImmutableList.of(), ArbitraryInstances.get(Collection.class));
- assertEquals(ImmutableList.of(), ArbitraryInstances.get(ImmutableCollection.class));
- assertEquals(ImmutableList.of(), ArbitraryInstances.get(List.class));
- assertEquals(ImmutableList.of(), ArbitraryInstances.get(ImmutableList.class));
- assertEquals(ImmutableMap.of(), ArbitraryInstances.get(Map.class));
- assertEquals(ImmutableMap.of(), ArbitraryInstances.get(ImmutableMap.class));
- assertEquals(ImmutableSortedMap.of(), ArbitraryInstances.get(SortedMap.class));
- assertEquals(ImmutableSortedMap.of(), ArbitraryInstances.get(ImmutableSortedMap.class));
- assertEquals(ImmutableMultiset.of(), ArbitraryInstances.get(Multiset.class));
- assertEquals(ImmutableMultiset.of(), ArbitraryInstances.get(ImmutableMultiset.class));
- assertTrue(ArbitraryInstances.get(SortedMultiset.class).isEmpty());
- assertEquals(ImmutableMultimap.of(), ArbitraryInstances.get(Multimap.class));
- assertEquals(ImmutableMultimap.of(), ArbitraryInstances.get(ImmutableMultimap.class));
- assertTrue(ArbitraryInstances.get(SortedSetMultimap.class).isEmpty());
- assertEquals(ImmutableTable.of(), ArbitraryInstances.get(Table.class));
- assertEquals(ImmutableTable.of(), ArbitraryInstances.get(ImmutableTable.class));
- assertTrue(ArbitraryInstances.get(RowSortedTable.class).isEmpty());
- assertEquals(ImmutableBiMap.of(), ArbitraryInstances.get(BiMap.class));
- assertEquals(ImmutableBiMap.of(), ArbitraryInstances.get(ImmutableBiMap.class));
- assertTrue(ArbitraryInstances.get(ImmutableClassToInstanceMap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(ClassToInstanceMap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(ListMultimap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(ImmutableListMultimap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(SetMultimap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(ImmutableSetMultimap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(MapDifference.class).areEqual());
- assertTrue(ArbitraryInstances.get(SortedMapDifference.class).areEqual());
- assertEquals(Range.all(), ArbitraryInstances.get(Range.class));
- assertTrue(ArbitraryInstances.get(NavigableSet.class).isEmpty());
- assertTrue(ArbitraryInstances.get(NavigableMap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(LinkedList.class).isEmpty());
- assertTrue(ArbitraryInstances.get(Deque.class).isEmpty());
- assertTrue(ArbitraryInstances.get(Queue.class).isEmpty());
- assertTrue(ArbitraryInstances.get(PriorityQueue.class).isEmpty());
- assertTrue(ArbitraryInstances.get(BitSet.class).isEmpty());
- assertTrue(ArbitraryInstances.get(TreeSet.class).isEmpty());
- assertTrue(ArbitraryInstances.get(TreeMap.class).isEmpty());
- assertFreshInstanceReturned(
- LinkedList.class, Deque.class, Queue.class, PriorityQueue.class, BitSet.class,
- TreeSet.class, TreeMap.class);
- }
-
- public void testGet_misc() {
- assertNotNull(ArbitraryInstances.get(CharMatcher.class));
- assertNotNull(ArbitraryInstances.get(Currency.class).getCurrencyCode());
- assertNotNull(ArbitraryInstances.get(Locale.class));
- ArbitraryInstances.get(Joiner.class).join(ImmutableList.of("a"));
- ArbitraryInstances.get(Splitter.class).split("a,b");
- assertFalse(ArbitraryInstances.get(Optional.class).isPresent());
- ArbitraryInstances.get(Stopwatch.class).start();
- assertNotNull(ArbitraryInstances.get(Ticker.class));
- assertNotNull(ArbitraryInstances.get(Constraint.class));
- assertNotNull(ArbitraryInstances.get(MapConstraint.class));
- assertFreshInstanceReturned(Random.class);
- assertEquals(ArbitraryInstances.get(Random.class).nextInt(),
- ArbitraryInstances.get(Random.class).nextInt());
- }
-
- public void testGet_concurrent() {
- assertTrue(ArbitraryInstances.get(BlockingDeque.class).isEmpty());
- assertTrue(ArbitraryInstances.get(BlockingQueue.class).isEmpty());
- assertTrue(ArbitraryInstances.get(DelayQueue.class).isEmpty());
- assertTrue(ArbitraryInstances.get(SynchronousQueue.class).isEmpty());
- assertTrue(ArbitraryInstances.get(PriorityBlockingQueue.class).isEmpty());
- assertTrue(ArbitraryInstances.get(ConcurrentMap.class).isEmpty());
- assertTrue(ArbitraryInstances.get(ConcurrentNavigableMap.class).isEmpty());
- ArbitraryInstances.get(Executor.class).execute(ArbitraryInstances.get(Runnable.class));
- assertNotNull(ArbitraryInstances.get(ThreadFactory.class));
- assertFreshInstanceReturned(
- BlockingQueue.class, BlockingDeque.class, PriorityBlockingQueue.class,
- DelayQueue.class, SynchronousQueue.class,
- ConcurrentMap.class, ConcurrentNavigableMap.class,
- AtomicReference.class, AtomicBoolean.class,
- AtomicInteger.class, AtomicLong.class, AtomicDouble.class);
- }
-
- @SuppressWarnings("unchecked") // functor classes have no type parameters
- public void testGet_functors() {
- assertEquals(0, ArbitraryInstances.get(Comparator.class).compare("abc", 123));
- assertTrue(ArbitraryInstances.get(Predicate.class).apply("abc"));
- assertTrue(ArbitraryInstances.get(Equivalence.class).equivalent(1, 1));
- assertFalse(ArbitraryInstances.get(Equivalence.class).equivalent(1, 2));
- }
-
- public void testGet_comparable() {
- @SuppressWarnings("unchecked") // The null value can compare with any Object
- Comparable<Object> comparable = ArbitraryInstances.get(Comparable.class);
- assertEquals(0, comparable.compareTo(comparable));
- assertTrue(comparable.compareTo("") > 0);
- try {
- comparable.compareTo(null);
- fail();
- } catch (NullPointerException expected) {}
- }
-
- public void testGet_array() {
- assertEquals(0, ArbitraryInstances.get(int[].class).length);
- assertEquals(0, ArbitraryInstances.get(Object[].class).length);
- assertEquals(0, ArbitraryInstances.get(String[].class).length);
- }
-
- public void testGet_enum() {
- assertNull(ArbitraryInstances.get(EmptyEnum.class));
- assertEquals(Direction.UP, ArbitraryInstances.get(Direction.class));
- }
-
- public void testGet_interface() {
- assertNull(ArbitraryInstances.get(SomeInterface.class));
- }
-
- public void testGet_runnable() {
- ArbitraryInstances.get(Runnable.class).run();
- }
-
- public void testGet_class() {
- assertNull(ArbitraryInstances.get(SomeAbstractClass.class));
- assertNull(ArbitraryInstances.get(WithPrivateConstructor.class));
- assertNull(ArbitraryInstances.get(NoDefaultConstructor.class));
- assertNull(ArbitraryInstances.get(WithExceptionalConstructor.class));
- assertNull(ArbitraryInstances.get(NonPublicClass.class));
- }
-
- public void testGet_mutable() {
- assertEquals(0, ArbitraryInstances.get(ArrayList.class).size());
- assertEquals(0, ArbitraryInstances.get(HashMap.class).size());
- assertEquals("", ArbitraryInstances.get(Appendable.class).toString());
- assertEquals("", ArbitraryInstances.get(StringBuilder.class).toString());
- assertEquals("", ArbitraryInstances.get(StringBuffer.class).toString());
- assertFreshInstanceReturned(
- ArrayList.class, HashMap.class,
- Appendable.class, StringBuilder.class, StringBuffer.class,
- Throwable.class, Exception.class);
- }
-
- public void testGet_io() throws IOException {
- assertEquals(-1, ArbitraryInstances.get(InputStream.class).read());
- assertEquals(-1, ArbitraryInstances.get(ByteArrayInputStream.class).read());
- assertEquals(-1, ArbitraryInstances.get(Readable.class).read(CharBuffer.allocate(1)));
- assertEquals(-1, ArbitraryInstances.get(Reader.class).read());
- assertEquals(-1, ArbitraryInstances.get(StringReader.class).read());
- assertEquals(0, ArbitraryInstances.get(Buffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(CharBuffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(ByteBuffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(ShortBuffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(IntBuffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(LongBuffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(FloatBuffer.class).capacity());
- assertEquals(0, ArbitraryInstances.get(DoubleBuffer.class).capacity());
- ArbitraryInstances.get(PrintStream.class).println("test");
- ArbitraryInstances.get(PrintWriter.class).println("test");
- assertNotNull(ArbitraryInstances.get(File.class));
- assertFreshInstanceReturned(
- ByteArrayOutputStream.class, OutputStream.class,
- Writer.class, StringWriter.class,
- PrintStream.class, PrintWriter.class);
- }
-
- public void testGet_reflect() {
- assertNotNull(ArbitraryInstances.get(Type.class));
- assertNotNull(ArbitraryInstances.get(AnnotatedElement.class));
- assertNotNull(ArbitraryInstances.get(GenericDeclaration.class));
- }
-
- public void testGet_regex() {
- assertEquals(Pattern.compile("").pattern(), ArbitraryInstances.get(Pattern.class).pattern());
- assertEquals(0, ArbitraryInstances.get(MatchResult.class).groupCount());
- }
-
- private static void assertFreshInstanceReturned(Class<?>... mutableClasses) {
- for (Class<?> mutableClass : mutableClasses) {
- Object instance = ArbitraryInstances.get(mutableClass);
- assertNotNull("Expected to return non-null for: " + mutableClass, instance);
- assertNotSame("Expected to return fresh instance for: " + mutableClass,
- instance, ArbitraryInstances.get(mutableClass));
- }
- }
-
- private enum EmptyEnum {}
-
- private enum Direction {
- UP, DOWN
- }
-
- public interface SomeInterface {}
-
- public static abstract class SomeAbstractClass {
- public SomeAbstractClass() {}
- }
-
- static class NonPublicClass {
- public NonPublicClass() {}
- }
-
- private static class WithPrivateConstructor {}
-
- public static class NoDefaultConstructor {
- public NoDefaultConstructor(@SuppressWarnings("unused") int i) {}
- }
-
- public static class WithExceptionalConstructor {
- public WithExceptionalConstructor() {
- throw new RuntimeException();
- }
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java b/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java
deleted file mode 100644
index 8c55790..0000000
--- a/guava-testlib/test/com/google/common/testing/ClassSanityTesterTest.java
+++ /dev/null
@@ -1,1164 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.testing.ClassSanityTester.FactoryMethodReturnsNullException;
-import com.google.common.testing.ClassSanityTester.ParameterNotInstantiableException;
-import com.google.common.testing.NullPointerTester.Visibility;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-/**
- * Unit tests for {@link ClassSanityTester}.
- *
- * @author Ben Yu
- */
-public class ClassSanityTesterTest extends TestCase {
-
- private final ClassSanityTester tester = new ClassSanityTester();
-
- public void testEqualsOnReturnValues_good() throws Exception {
- tester.forAllPublicStaticMethods(GoodEqualsFactory.class).testEquals();
- }
-
- public static class GoodEqualsFactory {
- public static Object good(String a, int b,
- // oneConstantOnly doesn't matter since it's not nullable and can be only 1 value.
- @SuppressWarnings("unused") OneConstantEnum oneConstantOnly,
- // noConstant doesn't matter since it can only be null
- @SuppressWarnings("unused") @Nullable NoConstantEnum noConstant) {
- return new GoodEquals(a, b);
- }
- // instance method ignored
- public Object badIgnored() {
- return new BadEquals();
- }
- // primitive ignored
- public int returnsInt() {
- throw new UnsupportedOperationException();
- }
- // void ignored
- public void voidMethod() {
- throw new UnsupportedOperationException();
- }
- // non-public method ignored
- static Object badButNotPublic() {
- return new BadEquals();
- }
- }
-
- public void testForAllPublicStaticMethods_noPublicStaticMethods() throws Exception {
- try {
- tester.forAllPublicStaticMethods(NoPublicStaticMethods.class).testEquals();
- } catch (AssertionFailedError expected) {
- assertEquals(
- "No public static methods that return java.lang.Object or subtype are found in "
- + NoPublicStaticMethods.class + ".",
- expected.getMessage());
- return;
- }
- fail();
- }
-
- public void testEqualsOnReturnValues_bad() throws Exception {
- try {
- tester.forAllPublicStaticMethods(BadEqualsFactory.class).testEquals();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail();
- }
-
- private static class BadEqualsFactory {
- /** oneConstantOnly matters now since it can be either null or the constant. */
- @SuppressWarnings("unused") // Called by reflection
- public static Object bad(String a, int b,
- @Nullable OneConstantEnum oneConstantOnly) {
- return new GoodEquals(a, b);
- }
- }
-
- public void testNullsOnReturnValues_good() throws Exception {
- tester.forAllPublicStaticMethods(GoodNullsFactory.class).testNulls();
- }
-
- private static class GoodNullsFactory {
- @SuppressWarnings("unused") // Called by reflection
- public static Object good(String s) {
- return new GoodNulls(s);
- }
- }
-
- public void testNullsOnReturnValues_bad() throws Exception {
- try {
- tester
- .forAllPublicStaticMethods(BadNullsFactory.class)
- .thatReturn(Object.class)
- .testNulls();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail();
- }
-
- public void testNullsOnReturnValues_returnTypeFiltered() throws Exception {
- try {
- tester
- .forAllPublicStaticMethods(BadNullsFactory.class)
- .thatReturn(Iterable.class)
- .testNulls();
- } catch (AssertionFailedError expected) {
- assertEquals(
- "No public static methods that return java.lang.Iterable or subtype are found in "
- + BadNullsFactory.class + ".",
- expected.getMessage());
- return;
- }
- fail();
- }
-
- public static class BadNullsFactory {
- public static Object bad(@SuppressWarnings("unused") String a) {
- return new BadNulls();
- }
- }
-
- public void testSerializableOnReturnValues_good() throws Exception {
- tester.forAllPublicStaticMethods(GoodSerializableFactory.class).testSerializable();
- }
-
- public static class GoodSerializableFactory {
- public static Object good(Runnable r) {
- return r;
- }
- public static Object good(AnInterface i) {
- return i;
- }
- }
-
- public void testSerializableOnReturnValues_bad() throws Exception {
- try {
- tester.forAllPublicStaticMethods(BadSerializableFactory.class).testSerializable();
- } catch (AssertionError expected) {
- return;
- }
- fail();
- }
-
- public static class BadSerializableFactory {
- public static Object bad() {
- return new Serializable() {
- @SuppressWarnings("unused")
- private final Object notSerializable = new Object();
- };
- }
- }
-
- public void testEqualsAndSerializableOnReturnValues_equalsIsGoodButNotSerializable()
- throws Exception {
- try {
- tester.forAllPublicStaticMethods(GoodEqualsFactory.class).testEqualsAndSerializable();
- } catch (AssertionError expected) {
- return;
- }
- fail("should have failed");
- }
-
- public void testEqualsAndSerializableOnReturnValues_serializableButNotEquals()
- throws Exception {
- try {
- tester.forAllPublicStaticMethods(GoodSerializableFactory.class).testEqualsAndSerializable();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail("should have failed");
- }
-
- public void testEqualsAndSerializableOnReturnValues_good()
- throws Exception {
- tester.forAllPublicStaticMethods(GoodEqualsAndSerialiableFactory.class)
- .testEqualsAndSerializable();
- }
-
- public static class GoodEqualsAndSerialiableFactory {
- public static Object good(AnInterface s) {
- return Functions.constant(s);
- }
- }
-
- public void testEqualsForReturnValues_factoryReturnsNullButNotAnnotated() throws Exception {
- try {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
- .testEquals();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail();
- }
-
- public void testNullsForReturnValues_factoryReturnsNullButNotAnnotated() throws Exception {
- try {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
- .testNulls();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail();
- }
-
- public void testSerializableForReturnValues_factoryReturnsNullButNotAnnotated() throws Exception {
- try {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
- .testSerializable();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail();
- }
-
- public void testEqualsAndSerializableForReturnValues_factoryReturnsNullButNotAnnotated()
- throws Exception {
- try {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
- .testEqualsAndSerializable();
- } catch (AssertionFailedError expected) {
- return;
- }
- fail();
- }
-
- public static class FactoryThatReturnsNullButNotAnnotated {
- public static Object bad() {
- return null;
- }
- }
-
- public void testEqualsForReturnValues_factoryReturnsNullAndAnnotated() throws Exception {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
- .testEquals();
- }
-
- public void testNullsForReturnValues_factoryReturnsNullAndAnnotated() throws Exception {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
- .testNulls();
- }
-
- public void testSerializableForReturnValues_factoryReturnsNullAndAnnotated() throws Exception {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
- .testSerializable();
- }
-
- public void testEqualsAndSerializableForReturnValues_factoryReturnsNullAndAnnotated()
- throws Exception {
- tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
- .testEqualsAndSerializable();
- }
-
- public static class FactoryThatReturnsNullAndAnnotated {
- @Nullable public static Object bad() {
- return null;
- }
- }
-
- public void testGoodEquals() throws Exception {
- tester.testEquals(GoodEquals.class);
- }
-
- public void testEquals_interface() {
- tester.testEquals(AnInterface.class);
- }
-
- public void testEquals_abstractClass() {
- tester.testEquals(AnAbstractClass.class);
- }
-
- public void testEquals_enum() {
- tester.testEquals(OneConstantEnum.class);
- }
-
- public void testBadEquals() throws Exception {
- try {
- tester.testEquals(BadEquals.class);
- } catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains("create(null)");
- return;
- }
- fail("should have failed");
- }
-
- public void testBadEquals_withParameterizedType() throws Exception {
- try {
- tester.testEquals(BadEqualsWithParameterizedType.class);
- } catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains("create([[1]])");
- return;
- }
- fail("should have failed");
- }
-
- public void testGoodReferentialEqualityComparison() throws Exception {
- tester.testEquals(UsesEnum.class);
- tester.testEquals(UsesReferentialEquality.class);
- tester.testEquals(SameListInstance.class);
- }
-
- public void testEqualsUsingReferentialEquality() throws Exception {
- assertBadUseOfReferentialEquality(SameIntegerInstance.class);
- assertBadUseOfReferentialEquality(SameLongInstance.class);
- assertBadUseOfReferentialEquality(SameFloatInstance.class);
- assertBadUseOfReferentialEquality(SameDoubleInstance.class);
- assertBadUseOfReferentialEquality(SameShortInstance.class);
- assertBadUseOfReferentialEquality(SameByteInstance.class);
- assertBadUseOfReferentialEquality(SameCharacterInstance.class);
- assertBadUseOfReferentialEquality(SameBooleanInstance.class);
- assertBadUseOfReferentialEquality(SameObjectInstance.class);
- assertBadUseOfReferentialEquality(SameStringInstance.class);
- assertBadUseOfReferentialEquality(SameInterfaceInstance.class);
- }
-
- private void assertBadUseOfReferentialEquality(Class<?> cls) throws Exception {
- try {
- tester.testEquals(cls);
- } catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains(cls.getSimpleName() + "(");
- return;
- }
- fail("should have failed");
- }
-
- public void testParameterNotInstantiableForEqualsTest() throws Exception {
- try {
- tester.doTestEquals(ConstructorParameterNotInstantiable.class);
- fail("should have failed");
- } catch (ParameterNotInstantiableException expected) {}
- }
-
- public void testConstructorThrowsForEqualsTest() throws Exception {
- try {
- tester.doTestEquals(ConstructorThrows.class);
- fail("should have failed");
- } catch (InvocationTargetException expected) {}
- }
-
- public void testFactoryMethodReturnsNullForEqualsTest() throws Exception {
- try {
- tester.doTestEquals(FactoryMethodReturnsNullAndAnnotated.class);
- fail("should have failed");
- } catch (FactoryMethodReturnsNullException expected) {}
- }
-
- public void testFactoryMethodReturnsNullButNotAnnotatedInEqualsTest() throws Exception {
- try {
- tester.testEquals(FactoryMethodReturnsNullButNotAnnotated.class);
- } catch (AssertionFailedError expected) {
- return;
- }
- fail("should have failed");
- }
-
- public void testNoEqualsChecksOnEnum() throws Exception {
- tester.testEquals(OneConstantEnum.class);
- tester.testEquals(NoConstantEnum.class);
- tester.testEquals(TimeUnit.class);
- }
-
- public void testNoEqualsChecksOnInterface() throws Exception {
- tester.testEquals(Runnable.class);
- }
-
- public void testNoEqualsChecksOnAnnotation() throws Exception {
- tester.testEquals(Nullable.class);
- }
-
- public void testGoodNulls() throws Exception {
- tester.testNulls(GoodNulls.class);
- }
-
- public void testNoNullCheckNeededDespitNotInstantiable() throws Exception {
- tester.doTestNulls(NoNullCheckNeededDespitNotInstantiable.class, Visibility.PACKAGE);
- }
-
- public void testNulls_interface() {
- tester.testNulls(AnInterface.class);
- }
-
- public void testNulls_abstractClass() {
- tester.testNulls(AnAbstractClass.class);
- }
-
- public void testNulls_enum() throws Exception {
- tester.testNulls(OneConstantEnum.class);
- tester.testNulls(NoConstantEnum.class);
- tester.testNulls(TimeUnit.class);
- }
-
- public void testEnumFailsToCheckNull() throws Exception {
- try {
- tester.testNulls(EnumFailsToCheckNull.class);
- } catch (AssertionFailedError expected) {
- return;
- }
- fail("should have failed");
- }
-
- public void testNoNullChecksOnInterface() throws Exception {
- tester.testNulls(Runnable.class);
- }
-
- public void testNoNullChecksOnAnnotation() throws Exception {
- tester.testNulls(Nullable.class);
- }
-
- public void testBadNulls() throws Exception {
- try {
- tester.testNulls(BadNulls.class);
- } catch (AssertionFailedError expected) {
- return;
- }
- fail("should have failed");
- }
-
- public void testInstantiate_factoryMethodReturnsNullButNotAnnotated() throws Exception {
- try {
- tester.instantiate(FactoryMethodReturnsNullButNotAnnotated.class);
- } catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains("@Nullable");
- return;
- }
- fail("should have failed");
- }
-
- public void testInstantiate_factoryMethodReturnsNullAndAnnotated() throws Exception {
- try {
- tester.instantiate(FactoryMethodReturnsNullAndAnnotated.class);
- fail("should have failed");
- } catch (FactoryMethodReturnsNullException expected) {}
- }
-
- public void testInstantiate_factoryMethodAcceptsNull() throws Exception {
- assertNull(tester.instantiate(FactoryMethodAcceptsNull.class).name);
- }
-
- public void testInstantiate_factoryMethodDoesNotAcceptNull() throws Exception {
- assertNotNull(tester.instantiate(FactoryMethodDoesNotAcceptNull.class).name);
- }
-
- public void testInstantiate_constructorAcceptsNull() throws Exception {
- assertNull(tester.instantiate(ConstructorAcceptsNull.class).name);
- }
-
- public void testInstantiate_constructorDoesNotAcceptNull() throws Exception {
- assertNotNull(tester.instantiate(ConstructorDoesNotAcceptNull.class).name);
- }
-
- public void testInstantiate_notInstantiable() throws Exception {
- assertNull(tester.instantiate(NotInstantiable.class));
- }
-
- public void testInstantiate_noConstantEnum() throws Exception {
- assertNull(tester.instantiate(NoConstantEnum.class));
- }
-
- public void testInstantiate_oneConstantEnum() throws Exception {
- assertEquals(OneConstantEnum.A, tester.instantiate(OneConstantEnum.class));
- }
-
- public void testInstantiate_interface() throws Exception {
- assertNull(tester.instantiate(Runnable.class));
- }
-
- public void testInstantiate_abstractClass() throws Exception {
- assertNull(tester.instantiate(AbstractList.class));
- }
-
- public void testInstantiate_annotation() throws Exception {
- assertNull(tester.instantiate(Nullable.class));
- }
-
- public void testInstantiate_setDefault() throws Exception {
- NotInstantiable x = new NotInstantiable();
- tester.setDefault(NotInstantiable.class, x);
- assertNotNull(tester.instantiate(ConstructorParameterNotInstantiable.class));
- }
-
- public void testInstantiate_setSampleInstances() throws Exception {
- NotInstantiable x = new NotInstantiable();
- tester.setSampleInstances(NotInstantiable.class, ImmutableList.of(x));
- assertNotNull(tester.instantiate(ConstructorParameterNotInstantiable.class));
- }
-
- public void testInstantiate_setSampleInstances_empty() throws Exception {
- tester.setSampleInstances(NotInstantiable.class, ImmutableList.<NotInstantiable>of());
- try {
- tester.instantiate(ConstructorParameterNotInstantiable.class);
- fail();
- } catch (ParameterNotInstantiableException expected) {}
- }
-
- public void testInstantiate_constructorThrows() throws Exception {
- try {
- tester.instantiate(ConstructorThrows.class);
- fail();
- } catch (InvocationTargetException expected) {}
- }
-
- public void testInstantiate_factoryMethodThrows() throws Exception {
- try {
- tester.instantiate(FactoryMethodThrows.class);
- fail();
- } catch (InvocationTargetException expected) {}
- }
-
- public void testInstantiate_constructorParameterNotInstantiable() throws Exception {
- try {
- tester.instantiate(ConstructorParameterNotInstantiable.class);
- fail();
- } catch (ParameterNotInstantiableException expected) {}
- }
-
- public void testInstantiate_factoryMethodParameterNotInstantiable() throws Exception {
- try {
- tester.instantiate(FactoryMethodParameterNotInstantiable.class);
- fail();
- } catch (ParameterNotInstantiableException expected) {}
- }
-
- public void testInstantiate_instantiableFactoryMethodChosen() throws Exception {
- assertEquals("good", tester.instantiate(InstantiableFactoryMethodChosen.class).name);
- }
-
- public void testInterfaceProxySerializable() throws Exception {
- SerializableTester.reserializeAndAssert(tester.instantiate(HasAnInterface.class));
- }
-
- public void testReturnValuesFromAnotherPackageIgnoredForNullTests() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(JdkObjectFactory.class).testNulls();
- }
-
- /** String doesn't check nulls as we expect. But the framework should ignore. */
- private static class JdkObjectFactory {
- @SuppressWarnings("unused") // Called by reflection
- public static Object create() {
- return new ArrayList<String>();
- }
- }
-
- static class HasAnInterface implements Serializable {
- private final AnInterface i;
-
- public HasAnInterface(AnInterface i) {
- this.i = i;
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof HasAnInterface) {
- HasAnInterface that = (HasAnInterface) obj;
- return i.equals(that.i);
- } else {
- return false;
- }
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
- }
-
- static class InstantiableFactoryMethodChosen {
- final String name;
-
- private InstantiableFactoryMethodChosen(String name) {
- this.name = name;
- }
-
- public InstantiableFactoryMethodChosen(NotInstantiable x) {
- checkNotNull(x);
- this.name = "x1";
- }
-
- public static InstantiableFactoryMethodChosen create(NotInstantiable x) {
- return new InstantiableFactoryMethodChosen(x);
- }
-
- public static InstantiableFactoryMethodChosen create(String s) {
- checkNotNull(s);
- return new InstantiableFactoryMethodChosen("good");
- }
- }
-
- public void testInstantiate_instantiableConstructorChosen() throws Exception {
- assertEquals("good", tester.instantiate(InstantiableConstructorChosen.class).name);
- }
-
- static class InstantiableConstructorChosen {
- final String name;
-
- public InstantiableConstructorChosen(String name) {
- checkNotNull(name);
- this.name = "good";
- }
-
- public InstantiableConstructorChosen(NotInstantiable x) {
- checkNotNull(x);
- this.name = "x1";
- }
-
- public static InstantiableFactoryMethodChosen create(NotInstantiable x) {
- return new InstantiableFactoryMethodChosen(x);
- }
- }
-
- static class GoodEquals {
-
- private final String a;
- private final int b;
-
- private GoodEquals(String a, int b) {
- this.a = checkNotNull(a);
- this.b = b;
- }
-
- // ignored by testEquals()
- GoodEquals(@SuppressWarnings("unused") NotInstantiable x) {
- this.a = "x";
- this.b = -1;
- }
-
- // will keep trying
- public GoodEquals(@SuppressWarnings("unused") NotInstantiable x, int b) {
- this.a = "x";
- this.b = b;
- }
-
- // keep trying
- @SuppressWarnings("unused")
- static GoodEquals create(int a, int b) {
- throw new RuntimeException();
- }
-
- // keep trying
- @SuppressWarnings("unused")
- @Nullable public static GoodEquals createMayReturnNull(int a, int b) {
- return null;
- }
-
- // Good!
- static GoodEquals create(String a, int b) {
- return new GoodEquals(a, b);
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof GoodEquals) {
- GoodEquals that = (GoodEquals) obj;
- return a.equals(that.a) && b == that.b;
- } else {
- return false;
- }
- }
-
- @Override public int hashCode() {
- return 0;
- }
- }
-
- static class BadEquals {
-
- public BadEquals() {} // ignored by testEquals() since it has less parameters.
-
- public static BadEquals create(@SuppressWarnings("unused") @Nullable String s) {
- return new BadEquals();
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- return obj instanceof BadEquals;
- }
-
- @Override public int hashCode() {
- return 0;
- }
- }
-
- static class SameIntegerInstance {
- private final Integer i;
-
- public SameIntegerInstance(Integer i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameIntegerInstance) {
- SameIntegerInstance that = (SameIntegerInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameLongInstance {
- private final Long i;
-
- public SameLongInstance(Long i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameLongInstance) {
- SameLongInstance that = (SameLongInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameFloatInstance {
- private final Float i;
-
- public SameFloatInstance(Float i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameFloatInstance) {
- SameFloatInstance that = (SameFloatInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameDoubleInstance {
- private final Double i;
-
- public SameDoubleInstance(Double i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameDoubleInstance) {
- SameDoubleInstance that = (SameDoubleInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameShortInstance {
- private final Short i;
-
- public SameShortInstance(Short i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameShortInstance) {
- SameShortInstance that = (SameShortInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameByteInstance {
- private final Byte i;
-
- public SameByteInstance(Byte i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameByteInstance) {
- SameByteInstance that = (SameByteInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameCharacterInstance {
- private final Character i;
-
- public SameCharacterInstance(Character i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameCharacterInstance) {
- SameCharacterInstance that = (SameCharacterInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameBooleanInstance {
- private final Boolean i;
-
- public SameBooleanInstance(Boolean i) {
- this.i = checkNotNull(i);
- }
-
- @Override public int hashCode() {
- return i.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameBooleanInstance) {
- SameBooleanInstance that = (SameBooleanInstance) obj;
- return i == that.i;
- }
- return false;
- }
- }
-
- static class SameStringInstance {
- private final String s;
-
- public SameStringInstance(String s) {
- this.s = checkNotNull(s);
- }
-
- @Override public int hashCode() {
- return s.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameStringInstance) {
- SameStringInstance that = (SameStringInstance) obj;
- return s == that.s;
- }
- return false;
- }
- }
-
- static class SameObjectInstance {
- private final Object s;
-
- public SameObjectInstance(Object s) {
- this.s = checkNotNull(s);
- }
-
- @Override public int hashCode() {
- return s.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameObjectInstance) {
- SameObjectInstance that = (SameObjectInstance) obj;
- return s == that.s;
- }
- return false;
- }
- }
-
- static class SameInterfaceInstance {
- private final Runnable s;
-
- public SameInterfaceInstance(Runnable s) {
- this.s = checkNotNull(s);
- }
-
- @Override public int hashCode() {
- return s.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameInterfaceInstance) {
- SameInterfaceInstance that = (SameInterfaceInstance) obj;
- return s == that.s;
- }
- return false;
- }
- }
-
- static class SameListInstance {
- private final List<?> s;
-
- public SameListInstance(List<?> s) {
- this.s = checkNotNull(s);
- }
-
- @Override public int hashCode() {
- return System.identityHashCode(s);
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof SameListInstance) {
- SameListInstance that = (SameListInstance) obj;
- return s == that.s;
- }
- return false;
- }
- }
-
- static class UsesReferentialEquality {
- private final ReferentialEquality s;
-
- public UsesReferentialEquality(ReferentialEquality s) {
- this.s = checkNotNull(s);
- }
-
- @Override public int hashCode() {
- return s.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof UsesReferentialEquality) {
- UsesReferentialEquality that = (UsesReferentialEquality) obj;
- return s == that.s;
- }
- return false;
- }
- }
-
- static class UsesEnum {
- private final TimeUnit s;
-
- public UsesEnum(TimeUnit s) {
- this.s = checkNotNull(s);
- }
-
- @Override public int hashCode() {
- return s.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof UsesEnum) {
- UsesEnum that = (UsesEnum) obj;
- return s == that.s;
- }
- return false;
- }
- }
-
- public static class ReferentialEquality {
- public ReferentialEquality() {}
- }
-
- static class BadEqualsWithParameterizedType {
-
- // ignored by testEquals() since it has less parameters.
- public BadEqualsWithParameterizedType() {}
-
- public static BadEqualsWithParameterizedType create(
- @SuppressWarnings("unused") ImmutableList<Iterable<? extends String>> s) {
- return new BadEqualsWithParameterizedType();
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- return obj instanceof BadEqualsWithParameterizedType;
- }
-
- @Override public int hashCode() {
- return 0;
- }
- }
-
- static class GoodNulls {
- public GoodNulls(String s) {
- checkNotNull(s);
- }
-
- public void rejectNull(String s) {
- checkNotNull(s);
- }
- }
-
- public static class BadNulls {
- public void failsToRejectNull(@SuppressWarnings("unused") String s) {}
- }
-
- public static class NoNullCheckNeededDespitNotInstantiable {
-
- public NoNullCheckNeededDespitNotInstantiable(NotInstantiable x) {
- checkNotNull(x);
- }
-
- @SuppressWarnings("unused") // reflected
- void primitiveOnly(int i) {}
-
- @SuppressWarnings("unused") //reflected
- void nullableOnly(@Nullable String s) {}
- public void noParameter() {}
-
- @SuppressWarnings("unused") //reflected
- void primitiveAndNullable(@Nullable String s, int i) {}
- }
-
- static class FactoryMethodReturnsNullButNotAnnotated {
- private FactoryMethodReturnsNullButNotAnnotated() {}
-
- static FactoryMethodReturnsNullButNotAnnotated returnsNull() {
- return null;
- }
- }
-
- static class FactoryMethodReturnsNullAndAnnotated {
- private FactoryMethodReturnsNullAndAnnotated() {}
-
- @Nullable public static FactoryMethodReturnsNullAndAnnotated returnsNull() {
- return null;
- }
- }
-
- static class FactoryMethodAcceptsNull {
-
- final String name;
-
- private FactoryMethodAcceptsNull(String name) {
- this.name = name;
- }
-
- static FactoryMethodAcceptsNull create(@Nullable String name) {
- return new FactoryMethodAcceptsNull(name);
- }
- }
-
- static class FactoryMethodDoesNotAcceptNull {
-
- final String name;
-
- private FactoryMethodDoesNotAcceptNull(String name) {
- this.name = checkNotNull(name);
- }
-
- public static FactoryMethodDoesNotAcceptNull create(String name) {
- return new FactoryMethodDoesNotAcceptNull(name);
- }
- }
-
- static class ConstructorAcceptsNull {
-
- final String name;
-
- public ConstructorAcceptsNull(@Nullable String name) {
- this.name = name;
- }
- }
-
- static class ConstructorDoesNotAcceptNull {
-
- final String name;
-
- ConstructorDoesNotAcceptNull(String name) {
- this.name = checkNotNull(name);
- }
- }
-
- static class ConstructorParameterNotInstantiable {
- public ConstructorParameterNotInstantiable(@SuppressWarnings("unused") NotInstantiable x) {}
- }
-
- static class FactoryMethodParameterNotInstantiable {
-
- private FactoryMethodParameterNotInstantiable() {}
-
- static FactoryMethodParameterNotInstantiable create(
- @SuppressWarnings("unused") NotInstantiable x) {
- return new FactoryMethodParameterNotInstantiable();
- }
- }
-
- static class ConstructorThrows {
- public ConstructorThrows() {
- throw new RuntimeException();
- }
- }
-
- static class FactoryMethodThrows {
- private FactoryMethodThrows() {}
-
- public static FactoryMethodThrows create() {
- throw new RuntimeException();
- }
- }
-
- static class NotInstantiable {
- private NotInstantiable() {}
- }
-
- private enum NoConstantEnum {}
-
- private enum OneConstantEnum {
- A
- }
-
- private enum EnumFailsToCheckNull {
- A;
-
- @SuppressWarnings("unused")
- public void failToCheckNull(String s) {}
- }
-
- private interface AnInterface {}
-
- private static abstract class AnAbstractClass {
- @SuppressWarnings("unused")
- public AnAbstractClass(String s) {}
-
- @SuppressWarnings("unused")
- public void failsToCheckNull(String s) {}
- }
-
- private static class NoPublicStaticMethods {
- static String notPublic() {
- return "";
- }
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/FakeTickerTest.java b/guava-testlib/test/com/google/common/testing/FakeTickerTest.java
deleted file mode 100644
index 5bf7ecd..0000000
--- a/guava-testlib/test/com/google/common/testing/FakeTickerTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import junit.framework.TestCase;
-
-import java.util.EnumSet;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Unit test for {@link FakeTicker}.
- *
- * @author Jige Yu
- */
-@GwtCompatible(emulated = true)
-public class FakeTickerTest extends TestCase {
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicInstanceMethods(new FakeTicker());
- }
-
- public void testAdvance() {
- FakeTicker ticker = new FakeTicker();
- assertEquals(0, ticker.read());
- assertSame(ticker, ticker.advance(10));
- assertEquals(10, ticker.read());
- ticker.advance(1, TimeUnit.MILLISECONDS);
- assertEquals(1000010L, ticker.read());
- }
-
- public void testAutoIncrementStep_returnsSameInstance() {
- FakeTicker ticker = new FakeTicker();
- assertSame(ticker, ticker.setAutoIncrementStep(10, TimeUnit.NANOSECONDS));
- }
-
- public void testAutoIncrementStep_nanos() {
- FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS);
- assertEquals(0, ticker.read());
- assertEquals(10, ticker.read());
- assertEquals(20, ticker.read());
- }
-
- public void testAutoIncrementStep_millis() {
- FakeTicker ticker = new FakeTicker().setAutoIncrementStep(1, TimeUnit.MILLISECONDS);
- assertEquals(0, ticker.read());
- assertEquals(1000000, ticker.read());
- assertEquals(2000000, ticker.read());
- }
-
- public void testAutoIncrementStep_seconds() {
- FakeTicker ticker = new FakeTicker().setAutoIncrementStep(3, TimeUnit.SECONDS);
- assertEquals(0, ticker.read());
- assertEquals(3000000000L, ticker.read());
- assertEquals(6000000000L, ticker.read());
- }
-
- public void testAutoIncrementStep_resetToZero() {
- FakeTicker ticker = new FakeTicker().setAutoIncrementStep(10, TimeUnit.NANOSECONDS);
- assertEquals(0, ticker.read());
- assertEquals(10, ticker.read());
- assertEquals(20, ticker.read());
-
- for (TimeUnit timeUnit : EnumSet.allOf(TimeUnit.class)) {
- ticker.setAutoIncrementStep(0, timeUnit);
- assertEquals(
- "Expected no auto-increment when setting autoIncrementStep to 0 " + timeUnit,
- 30, ticker.read());
- }
- }
-
- public void testAutoIncrement_negative() {
- FakeTicker ticker = new FakeTicker();
- try {
- ticker.setAutoIncrementStep(-1, TimeUnit.NANOSECONDS);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @GwtIncompatible("concurrency")
-
- public void testConcurrentAdvance() throws Exception {
- final FakeTicker ticker = new FakeTicker();
-
- int numberOfThreads = 64;
- runConcurrentTest(numberOfThreads,
- new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- // adds two nanoseconds to the ticker
- ticker.advance(1L);
- Thread.sleep(10);
- ticker.advance(1L);
- return null;
- }
- });
-
- assertEquals(numberOfThreads * 2, ticker.read());
- }
-
- @GwtIncompatible("concurrency")
-
- public void testConcurrentAutoIncrementStep() throws Exception {
- int incrementByNanos = 3;
- final FakeTicker ticker =
- new FakeTicker().setAutoIncrementStep(incrementByNanos, TimeUnit.NANOSECONDS);
-
- int numberOfThreads = 64;
- runConcurrentTest(numberOfThreads,
- new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- ticker.read();
- return null;
- }
- });
-
- assertEquals(incrementByNanos * numberOfThreads, ticker.read());
- }
-
- /**
- * Runs {@code callable} concurrently {@code numberOfThreads} times.
- */
- @GwtIncompatible("concurrency")
- private void runConcurrentTest(int numberOfThreads, final Callable<Void> callable)
- throws Exception {
- ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
- final CountDownLatch startLatch = new CountDownLatch(numberOfThreads);
- final CountDownLatch doneLatch = new CountDownLatch(numberOfThreads);
- for (int i = numberOfThreads; i > 0; i--) {
- executorService.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- startLatch.countDown();
- startLatch.await();
- callable.call();
- doneLatch.countDown();
- return null;
- }
- });
- }
- doneLatch.await();
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/FreshValueGeneratorTest.java b/guava-testlib/test/com/google/common/testing/FreshValueGeneratorTest.java
deleted file mode 100644
index 642e3d4..0000000
--- a/guava-testlib/test/com/google/common/testing/FreshValueGeneratorTest.java
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.base.Ticker;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.ImmutableSortedMultiset;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.LinkedHashMultiset;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.RowSortedTable;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.collect.SortedMultiset;
-import com.google.common.collect.Table;
-import com.google.common.collect.TreeBasedTable;
-import com.google.common.collect.TreeMultiset;
-import com.google.common.primitives.UnsignedInteger;
-import com.google.common.primitives.UnsignedLong;
-import com.google.common.reflect.TypeToken;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.LongBuffer;
-import java.nio.ShortBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Currency;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.MatchResult;
-import java.util.regex.Pattern;
-
-/**
- * Tests for {@link FreshValueGenerator}.
- *
- * @author Ben Yu
- */
-public class FreshValueGeneratorTest extends TestCase {
-
- public void testFreshInstance() {
- assertFreshInstances(
- String.class, CharSequence.class,
- Appendable.class, StringBuffer.class, StringBuilder.class,
- Pattern.class, MatchResult.class,
- Number.class, int.class, Integer.class,
- long.class, Long.class,
- short.class, Short.class,
- byte.class, Byte.class,
- boolean.class, Boolean.class,
- char.class, Character.class,
- int[].class, Object[].class,
- UnsignedInteger.class, UnsignedLong.class,
- BigInteger.class, BigDecimal.class,
- Throwable.class, Error.class, Exception.class, RuntimeException.class,
- Charset.class, Locale.class, Currency.class,
- List.class, Map.Entry.class,
- Object.class,
- Equivalence.class, Predicate.class, Function.class,
- Comparable.class, Comparator.class, Ordering.class,
- Class.class, Type.class, TypeToken.class,
- TimeUnit.class, Ticker.class,
- Joiner.class, Splitter.class, CharMatcher.class,
- InputStream.class, ByteArrayInputStream.class,
- Reader.class, Readable.class, StringReader.class,
- OutputStream.class, ByteArrayOutputStream.class,
- Writer.class, StringWriter.class, File.class,
- Buffer.class, ByteBuffer.class, CharBuffer.class,
- ShortBuffer.class, IntBuffer.class, LongBuffer.class,
- FloatBuffer.class, DoubleBuffer.class,
- String[].class, Object[].class, int[].class);
- }
-
- public void testStringArray() {
- FreshValueGenerator generator = new FreshValueGenerator();
- String[] a1 = generator.generate(String[].class);
- String[] a2 = generator.generate(String[].class);
- assertFalse(a1[0].equals(a2[0]));
- }
-
- public void testPrimitiveArray() {
- FreshValueGenerator generator = new FreshValueGenerator();
- int[] a1 = generator.generate(int[].class);
- int[] a2 = generator.generate(int[].class);
- assertTrue(a1[0] != a2[0]);
- }
-
- public void testImmutableList() {
- assertFreshInstance(new TypeToken<ImmutableList<String>>() {});
- assertValueAndTypeEquals(ImmutableList.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableList<String>>() {}));
- assertValueAndTypeEquals(ImmutableList.of(new FreshValueGenerator().generate(int.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableList<Integer>>() {}));
- assertValueAndTypeEquals(ImmutableList.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableList<?>>() {}));
- assertValueAndTypeEquals(ImmutableList.of(),
- new FreshValueGenerator().generate(new TypeToken<ImmutableList<EmptyEnum>>() {}));
- }
-
- public void testImmutableSet() {
- assertFreshInstance(new TypeToken<ImmutableSet<String>>() {});
- assertValueAndTypeEquals(ImmutableSet.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSet<String>>() {}));
- assertValueAndTypeEquals(ImmutableSet.of(new FreshValueGenerator().generate(Number.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSet<Number>>() {}));
- assertValueAndTypeEquals(ImmutableSet.of(new FreshValueGenerator().generate(Number.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSet<? extends Number>>() {}));
- assertValueAndTypeEquals(ImmutableSet.of(),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSet<EmptyEnum>>() {}));
- }
-
- public void testImmutableSortedSet() {
- assertFreshInstance(new TypeToken<ImmutableSortedSet<String>>() {});
- assertValueAndTypeEquals(
- ImmutableSortedSet.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSortedSet<String>>() {}));
- assertValueAndTypeEquals(ImmutableSortedSet.of(),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSortedSet<EmptyEnum>>() {}));
- }
-
- public void testImmutableMultiset() {
- assertFreshInstance(new TypeToken<ImmutableSortedSet<String>>() {});
- assertValueAndTypeEquals(ImmutableMultiset.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableMultiset<String>>() {}));
- assertValueAndTypeEquals(ImmutableMultiset.of(new FreshValueGenerator().generate(Number.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableMultiset<Number>>() {}));
- assertValueAndTypeEquals(ImmutableMultiset.of(),
- new FreshValueGenerator().generate(new TypeToken<ImmutableMultiset<EmptyEnum>>() {}));
- }
-
- public void testImmutableCollection() {
- assertFreshInstance(new TypeToken<ImmutableCollection<String>>() {});
- assertValueAndTypeEquals(ImmutableList.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableCollection<String>>() {}));
- assertValueAndTypeEquals(ImmutableList.of(),
- new FreshValueGenerator().generate(new TypeToken<ImmutableCollection<EmptyEnum>>() {}));
- }
-
- public void testImmutableMap() {
- assertFreshInstance(new TypeToken<ImmutableMap<String, Integer>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableMap.of(generator.generate(String.class), generator.generate(int.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableMap<String, Integer>>() {}));
- assertValueAndTypeEquals(ImmutableMap.of(),
- new FreshValueGenerator().generate(new TypeToken<ImmutableMap<EmptyEnum, String>>() {}));
- }
-
- public void testImmutableSortedMap() {
- assertFreshInstance(new TypeToken<ImmutableSortedMap<String, Integer>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableSortedMap.of(generator.generate(String.class), generator.generate(int.class)),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableSortedMap<String, Integer>>() {}));
- assertValueAndTypeEquals(ImmutableSortedMap.of(),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableSortedMap<EmptyEnum, String>>() {}));
- }
-
- public void testImmutableMultimap() {
- assertFreshInstance(new TypeToken<ImmutableMultimap<String, Integer>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableMultimap.of(generator.generate(String.class), generator.generate(int.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableMultimap<String, Integer>>() {}));
- assertValueAndTypeEquals(ImmutableMultimap.of(),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableMultimap<EmptyEnum, String>>() {}));
- }
-
- public void testImmutableListMultimap() {
- assertFreshInstance(new TypeToken<ImmutableListMultimap<String, Integer>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableListMultimap.of(generator.generate(String.class), generator.generate(int.class)),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableListMultimap<String, Integer>>() {}));
- assertValueAndTypeEquals(ImmutableListMultimap.of(),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableListMultimap<EmptyEnum, String>>() {}));
- }
-
- public void testImmutableSetMultimap() {
- assertFreshInstance(new TypeToken<ImmutableSetMultimap<String, Integer>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableSetMultimap.of(generator.generate(String.class), generator.generate(int.class)),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableSetMultimap<String, Integer>>() {}));
- assertValueAndTypeEquals(ImmutableSetMultimap.of(),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableSetMultimap<EmptyEnum, String>>() {}));
- }
-
- public void testImmutableBiMap() {
- assertFreshInstance(new TypeToken<ImmutableBiMap<String, Integer>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableBiMap.of(generator.generate(String.class), generator.generate(int.class)),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableBiMap<String, Integer>>() {}));
- assertValueAndTypeEquals(ImmutableBiMap.of(),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableBiMap<EmptyEnum, String>>() {}));
- }
-
- public void testImmutableTable() {
- assertFreshInstance(new TypeToken<ImmutableTable<String, Integer, ImmutableList<String>>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- assertValueAndTypeEquals(
- ImmutableTable.of(
- generator.generate(String.class), generator.generate(int.class),
- generator.generate(new TypeToken<ImmutableList<String>>() {})),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableTable<String, Integer, ImmutableList<String>>>() {}));
- assertValueAndTypeEquals(ImmutableTable.of(),
- new FreshValueGenerator().generate(
- new TypeToken<ImmutableTable<EmptyEnum, String, Integer>>() {}));
- }
-
- public void testList() {
- assertFreshInstance(new TypeToken<List<String>>() {});
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<List<String>>() {}));
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(int.class)),
- new FreshValueGenerator().generate(new TypeToken<List<Integer>>() {}));
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<List<?>>() {}));
- assertFreshInstance(new TypeToken<List<EmptyEnum>>() {});
- }
-
- public void testArrayList() {
- assertFreshInstance(new TypeToken<ArrayList<String>>() {});
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ArrayList<String>>() {}));
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(int.class)),
- new FreshValueGenerator().generate(new TypeToken<ArrayList<Integer>>() {}));
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ArrayList<?>>() {}));
- assertNotNull(new FreshValueGenerator().generate(new TypeToken<ArrayList<EmptyEnum>>() {}));
- }
-
- public void testLinkedList() {
- assertFreshInstance(new TypeToken<LinkedList<String>>() {});
- assertValueAndTypeEquals(newLinkedList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<LinkedList<String>>() {}));
- assertNotNull(new FreshValueGenerator().generate(new TypeToken<LinkedList<EmptyEnum>>() {}));
- }
-
- public void testSet() {
- assertFreshInstance(new TypeToken<Set<String>>() {});
- assertValueAndTypeEquals(
- newLinkedHashSet(new FreshValueGenerator().generate(Number.class)),
- new FreshValueGenerator().generate(new TypeToken<Set<? extends Number>>() {}));
- assertFreshInstance(new TypeToken<Set<EmptyEnum>>() {});
- }
-
- public void testHashSet() {
- assertFreshInstance(new TypeToken<HashSet<String>>() {});
- assertValueAndTypeEquals(
- newLinkedHashSet(new FreshValueGenerator().generate(Number.class)),
- new FreshValueGenerator().generate(new TypeToken<HashSet<? extends Number>>() {}));
- }
-
- public void testLinkedHashSet() {
- assertFreshInstance(new TypeToken<LinkedHashSet<String>>() {});
- assertValueAndTypeEquals(
- newLinkedHashSet(new FreshValueGenerator().generate(Number.class)),
- new FreshValueGenerator().generate(new TypeToken<LinkedHashSet<? extends Number>>() {}));
- assertNotNull(new FreshValueGenerator().generate(new TypeToken<LinkedHashSet<EmptyEnum>>() {}));
- }
-
- public void testTreeSet() {
- assertFreshInstance(new TypeToken<TreeSet<String>>() {});
- TreeSet<String> expected = Sets.newTreeSet();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<TreeSet<? extends CharSequence>>() {}));
- assertNotNull(new FreshValueGenerator().generate(new TypeToken<TreeSet<EmptyEnum>>() {}));
- }
-
- public void testSortedSet() {
- assertFreshInstance(new TypeToken<SortedSet<String>>() {});
- TreeSet<String> expected = Sets.newTreeSet();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<SortedSet<String>>() {}));
- assertFreshInstance(new TypeToken<SortedSet<EmptyEnum>>() {});
- }
-
- public void testNavigableSet() {
- assertFreshInstance(new TypeToken<NavigableSet<String>>() {});
- TreeSet<String> expected = Sets.newTreeSet();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<NavigableSet<String>>() {}));
- assertFreshInstance(new TypeToken<NavigableSet<EmptyEnum>>() {});
- }
-
- public void testMultiset() {
- assertFreshInstance(new TypeToken<Multiset<String>>() {});
- Multiset<String> expected = HashMultiset.create();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<Multiset<String>>() {}));
- assertFreshInstance(new TypeToken<Multiset<EmptyEnum>>() {});
- }
-
- public void testSortedMultiset() {
- assertFreshInstance(new TypeToken<SortedMultiset<String>>() {});
- SortedMultiset<String> expected = TreeMultiset.create();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<SortedMultiset<String>>() {}));
- assertFreshInstance(new TypeToken<Multiset<EmptyEnum>>() {});
- }
-
- public void testHashMultiset() {
- assertFreshInstance(new TypeToken<HashMultiset<String>>() {});
- HashMultiset<String> expected = HashMultiset.create();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<HashMultiset<String>>() {}));
- }
-
- public void testLinkedHashMultiset() {
- assertFreshInstance(new TypeToken<LinkedHashMultiset<String>>() {});
- LinkedHashMultiset<String> expected = LinkedHashMultiset.create();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<LinkedHashMultiset<String>>() {}));
- }
-
- public void testTreeMultiset() {
- assertFreshInstance(new TypeToken<TreeMultiset<String>>() {});
- TreeMultiset<String> expected = TreeMultiset.create();
- expected.add(new FreshValueGenerator().generate(String.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<TreeMultiset<String>>() {}));
- }
-
- public void testImmutableSortedMultiset() {
- assertFreshInstance(new TypeToken<ImmutableSortedMultiset<String>>() {});
- assertValueAndTypeEquals(
- ImmutableSortedMultiset.of(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<ImmutableSortedMultiset<String>>() {}));
- assertFreshInstance(new TypeToken<Multiset<EmptyEnum>>() {});
- }
-
- public void testCollection() {
- assertFreshInstance(new TypeToken<Collection<String>>() {});
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<Collection<String>>() {}));
- assertFreshInstance(new TypeToken<Collection<EmptyEnum>>() {});
- }
-
- public void testIterable() {
- assertFreshInstance(new TypeToken<Iterable<String>>() {});
- assertValueAndTypeEquals(Lists.newArrayList(new FreshValueGenerator().generate(String.class)),
- new FreshValueGenerator().generate(new TypeToken<Iterable<String>>() {}));
- assertFreshInstance(new TypeToken<Iterable<EmptyEnum>>() {});
- }
-
- public void testMap() {
- assertFreshInstance(new TypeToken<Map<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- Map<String, Integer> expected = Maps.newLinkedHashMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<Map<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<Map<EmptyEnum, String>>() {});
- }
-
- public void testHashMap() {
- assertFreshInstance(new TypeToken<HashMap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- HashMap<String, Integer> expected = Maps.newLinkedHashMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<HashMap<String, Integer>>() {}));
- assertNotNull(
- new FreshValueGenerator().generate(new TypeToken<HashMap<EmptyEnum, Integer>>() {}));
- }
-
- public void testLinkedHashMap() {
- assertFreshInstance(new TypeToken<LinkedHashMap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- LinkedHashMap<String, Integer> expected = Maps.newLinkedHashMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<LinkedHashMap<String, Integer>>() {}));
- assertNotNull(
- new FreshValueGenerator().generate(new TypeToken<LinkedHashMap<EmptyEnum, String>>() {}));
- }
-
- public void testTreeMap() {
- assertFreshInstance(new TypeToken<TreeMap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- TreeMap<String, Integer> expected = Maps.newTreeMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<TreeMap<String, Integer>>() {}));
- assertNotNull(new FreshValueGenerator().generate(new TypeToken<LinkedHashSet<EmptyEnum>>() {}));
- }
-
- public void testSortedMap() {
- assertFreshInstance(new TypeToken<SortedMap<?, String>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- TreeMap<String, Integer> expected = Maps.newTreeMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<SortedMap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<SortedMap<EmptyEnum, String>>() {});
- }
-
- public void testNavigableMap() {
- assertFreshInstance(new TypeToken<NavigableMap<?, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- TreeMap<String, Integer> expected = Maps.newTreeMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<NavigableMap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<NavigableMap<EmptyEnum, String>>() {});
- }
-
- public void testConcurrentMap() {
- assertFreshInstance(new TypeToken<ConcurrentMap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- ConcurrentMap<String, Integer> expected = Maps.newConcurrentMap();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<ConcurrentMap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<ConcurrentMap<EmptyEnum, String>>() {});
- }
-
- public void testMultimap() {
- assertFreshInstance(new TypeToken<Multimap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- Multimap<String, Integer> expected = ArrayListMultimap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<Multimap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<Multimap<EmptyEnum, String>>() {});
- }
-
- public void testHashMultimap() {
- assertFreshInstance(new TypeToken<HashMultimap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- HashMultimap<String, Integer> expected = HashMultimap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(new TypeToken<HashMultimap<String, Integer>>() {}));
- }
-
- public void testLinkedHashMultimap() {
- assertFreshInstance(new TypeToken<LinkedHashMultimap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- LinkedHashMultimap<String, Integer> expected = LinkedHashMultimap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<LinkedHashMultimap<String, Integer>>() {}));
- }
-
- public void testListMultimap() {
- assertFreshInstance(new TypeToken<ListMultimap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- ListMultimap<String, Integer> expected = ArrayListMultimap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<ListMultimap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<ListMultimap<EmptyEnum, String>>() {});
- }
-
- public void testArrayListMultimap() {
- assertFreshInstance(new TypeToken<ArrayListMultimap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- ArrayListMultimap<String, Integer> expected = ArrayListMultimap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<ArrayListMultimap<String, Integer>>() {}));
- }
-
- public void testSetMultimap() {
- assertFreshInstance(new TypeToken<SetMultimap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- SetMultimap<String, Integer> expected = LinkedHashMultimap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<SetMultimap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<SetMultimap<EmptyEnum, String>>() {});
- }
-
- public void testBiMap() {
- assertFreshInstance(new TypeToken<BiMap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- BiMap<String, Integer> expected = HashBiMap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<BiMap<String, Integer>>() {}));
- assertFreshInstance(new TypeToken<BiMap<EmptyEnum, String>>() {});
- }
-
- public void testHashBiMap() {
- assertFreshInstance(new TypeToken<HashBiMap<String, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- HashBiMap<String, Integer> expected = HashBiMap.create();
- expected.put(generator.generate(String.class), generator.generate(int.class));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<HashBiMap<String, Integer>>() {}));
- }
-
- public void testTable() {
- assertFreshInstance(new TypeToken<Table<String, ?, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- Table<String, Integer, List<String>> expected = HashBasedTable.create();
- expected.put(generator.generate(String.class), generator.generate(int.class),
- generator.generate(new TypeToken<List<String>>() {}));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<Table<String, Integer, List<String>>>() {}));
- assertFreshInstance(new TypeToken<Table<EmptyEnum, String, Integer>>() {});
- }
-
- public void testHashBasedTable() {
- assertFreshInstance(new TypeToken<HashBasedTable<String, ?, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- HashBasedTable<String, Integer, List<String>> expected = HashBasedTable.create();
- expected.put(generator.generate(String.class), generator.generate(int.class),
- generator.generate(new TypeToken<List<String>>() {}));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<HashBasedTable<String, Integer, List<String>>>() {}));
- }
-
- public void testRowSortedTable() {
- assertFreshInstance(new TypeToken<RowSortedTable<String, ?, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- RowSortedTable<String, Integer, List<String>> expected = TreeBasedTable.create();
- expected.put(generator.generate(String.class), generator.generate(int.class),
- generator.generate(new TypeToken<List<String>>() {}));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<RowSortedTable<String, Integer, List<String>>>() {}));
- assertFreshInstance(new TypeToken<RowSortedTable<EmptyEnum, String, Integer>>() {});
- }
-
- public void testTreeBasedTable() {
- assertFreshInstance(new TypeToken<TreeBasedTable<String, ?, ?>>() {});
- FreshValueGenerator generator = new FreshValueGenerator();
- TreeBasedTable<String, Integer, List<String>> expected = TreeBasedTable.create();
- expected.put(generator.generate(String.class), generator.generate(int.class),
- generator.generate(new TypeToken<List<String>>() {}));
- assertValueAndTypeEquals(expected,
- new FreshValueGenerator().generate(
- new TypeToken<TreeBasedTable<String, Integer, List<String>>>() {}));
- }
-
- public void testObject() {
- assertEquals(new FreshValueGenerator().generate(String.class),
- new FreshValueGenerator().generate(Object.class));
- }
-
- public void testEnums() {
- assertEqualInstance(EmptyEnum.class, null);
- assertEqualInstance(OneConstantEnum.class, OneConstantEnum.CONSTANT1);
- assertFreshInstance(TwoConstantEnum.class);
- }
-
- public void testAddSampleInstances_twoInstances() {
- FreshValueGenerator generator = new FreshValueGenerator();
- generator.addSampleInstances(String.class, ImmutableList.of("a", "b"));
- assertEquals("a", generator.generate(String.class));
- assertEquals("b", generator.generate(String.class));
- assertEquals("a", generator.generate(String.class));
- }
-
- public void testAddSampleInstances_oneInstance() {
- FreshValueGenerator generator = new FreshValueGenerator();
- generator.addSampleInstances(String.class, ImmutableList.of("a"));
- assertEquals("a", generator.generate(String.class));
- assertEquals("a", generator.generate(String.class));
- }
-
- public void testAddSampleInstances_noInstance() {
- FreshValueGenerator generator = new FreshValueGenerator();
- generator.addSampleInstances(String.class, ImmutableList.<String>of());
- assertEquals(new FreshValueGenerator().generate(String.class),
- generator.generate(String.class));
- }
-
- public void testFreshCurrency() {
- FreshValueGenerator generator = new FreshValueGenerator();
- // repeat a few times to make sure we don't stumble upon a bad Locale
- assertNotNull(generator.generate(Currency.class));
- assertNotNull(generator.generate(Currency.class));
- assertNotNull(generator.generate(Currency.class));
- }
-
- public void testNulls() throws Exception {
- new ClassSanityTester()
- .setDefault(Method.class, FreshValueGeneratorTest.class.getDeclaredMethod("testNulls"))
- .testNulls(FreshValueGenerator.class);
- }
-
- private static void assertFreshInstances(Class<?>... types) {
- for (Class<?> type : types) {
- assertFreshInstance(type);
- }
- }
-
- private static <T> void assertFreshInstance(TypeToken<T> type) {
- FreshValueGenerator generator = new FreshValueGenerator();
- T value1 = generator.generate(type);
- T value2 = generator.generate(type);
- assertNotNull("Null returned for " + type, value1);
- assertFalse("Equal instance " + value1 + " returned for " + type, value1.equals(value2));
- }
-
- private static <T> void assertFreshInstance(Class<T> type) {
- assertFreshInstance(TypeToken.of(type));
- }
-
- private static <T> void assertEqualInstance(Class<T> type, T value) {
- FreshValueGenerator generator = new FreshValueGenerator();
- assertEquals(value, generator.generate(type));
- assertEquals(value, generator.generate(type));
- }
-
- private enum EmptyEnum {}
-
- private enum OneConstantEnum {
- CONSTANT1
- }
-
- private enum TwoConstantEnum {
- CONSTANT1, CONSTANT2
- }
-
- private static void assertValueAndTypeEquals(Object expected, Object actual) {
- assertEquals(expected, actual);
- assertEquals(expected.getClass(), actual.getClass());
- }
-
- private static <E> LinkedHashSet<E> newLinkedHashSet(E element) {
- LinkedHashSet<E> set = Sets.newLinkedHashSet();
- set.add(element);
- return set;
- }
-
- private static <E> LinkedList<E> newLinkedList(E element) {
- LinkedList<E> list = Lists.newLinkedList();
- list.add(element);
- return list;
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java b/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
deleted file mode 100644
index ef70b67..0000000
--- a/guava-testlib/test/com/google/common/testing/NullPointerTesterTest.java
+++ /dev/null
@@ -1,1221 +0,0 @@
-/*
- * Copyright (C) 2005 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.ImmutableTable;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Table;
-import com.google.common.reflect.TypeToken;
-import com.google.common.testing.NullPointerTester.Visibility;
-import com.google.common.testing.anotherpackage.SomeClassThatDoesNotUseNullable;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * Unit test for {@link NullPointerTester}.
- *
- * @author Kevin Bourrillion
- * @author Mick Killianey
- */
-public class NullPointerTesterTest extends TestCase {
-
- /** Non-NPE RuntimeException. */
- public static class FooException extends RuntimeException {
- private static final long serialVersionUID = 1L;
- }
-
- /**
- * Class for testing all permutations of static/non-static one-argument
- * methods using methodParameter().
- */
- @SuppressWarnings("unused") // used by reflection
- public static class OneArg {
-
- public static void staticOneArgCorrectlyThrowsNpe(String s) {
- checkNotNull(s); // expect NPE here on null
- }
- public static void staticOneArgThrowsOtherThanNpe(String s) {
- throw new FooException(); // should catch as failure
- }
- public static void staticOneArgShouldThrowNpeButDoesnt(String s) {
- // should catch as failure
- }
- public static void
- staticOneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
- // null? no problem
- }
- public static void
- staticOneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
- throw new FooException(); // ok, as long as it's not NullPointerException
- }
- public static void
- staticOneArgNullableThrowsNPE(@Nullable String s) {
- checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
- }
-
- public void oneArgCorrectlyThrowsNpe(String s) {
- checkNotNull(s); // expect NPE here on null
- }
- public void oneArgThrowsOtherThanNpe(String s) {
- throw new FooException(); // should catch as failure
- }
- public void oneArgShouldThrowNpeButDoesnt(String s) {
- // should catch as failure
- }
- public void oneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
- // null? no problem
- }
- public void oneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
- throw new FooException(); // ok, as long as it's not NullPointerException
- }
- public void oneArgNullableThrowsNPE(@Nullable String s) {
- checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
- }
- }
-
- private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_PASS = {
- "staticOneArgCorrectlyThrowsNpe",
- "staticOneArgNullableCorrectlyDoesNotThrowNPE",
- "staticOneArgNullableCorrectlyThrowsOtherThanNPE",
- "staticOneArgNullableThrowsNPE",
- };
- private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
- "staticOneArgThrowsOtherThanNpe",
- "staticOneArgShouldThrowNpeButDoesnt",
- };
- private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS = {
- "oneArgCorrectlyThrowsNpe",
- "oneArgNullableCorrectlyDoesNotThrowNPE",
- "oneArgNullableCorrectlyThrowsOtherThanNPE",
- "oneArgNullableThrowsNPE",
- };
- private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
- "oneArgThrowsOtherThanNpe",
- "oneArgShouldThrowNpeButDoesnt",
- };
-
- public void testStaticOneArgMethodsThatShouldPass() throws Exception {
- for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_PASS) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- try {
- new NullPointerTester().testMethodParameter(new OneArg(), method, 0);
- } catch (AssertionFailedError unexpected) {
- fail("Should not have flagged method " + methodName);
- }
- }
- }
-
- public void testStaticOneArgMethodsThatShouldFail() throws Exception {
- for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- boolean foundProblem = false;
- try {
- new NullPointerTester().testMethodParameter(new OneArg(), method, 0);
- } catch (AssertionFailedError expected) {
- foundProblem = true;
- }
- assertTrue("Should report error in method " + methodName, foundProblem);
- }
- }
-
- public void testNonStaticOneArgMethodsThatShouldPass() throws Exception {
- OneArg foo = new OneArg();
- for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- try {
- new NullPointerTester().testMethodParameter(foo, method, 0);
- } catch (AssertionFailedError unexpected) {
- fail("Should not have flagged method " + methodName);
- }
- }
- }
-
- public void testNonStaticOneArgMethodsThatShouldFail() throws Exception {
- OneArg foo = new OneArg();
- for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- boolean foundProblem = false;
- try {
- new NullPointerTester().testMethodParameter(foo, method, 0);
- } catch (AssertionFailedError expected) {
- foundProblem = true;
- }
- assertTrue("Should report error in method " + methodName, foundProblem);
- }
- }
-
- /**
- * Class for testing all permutations of nullable/non-nullable two-argument
- * methods using testMethod().
- *
- * normalNormal: two params, neither is Nullable
- * nullableNormal: only first param is Nullable
- * normalNullable: only second param is Nullable
- * nullableNullable: both params are Nullable
- */
- public static class TwoArg {
- /** Action to take on a null param. */
- public enum Action {
- THROW_A_NPE {
- @Override public void act() {
- throw new NullPointerException();
- }
- },
- THROW_OTHER {
- @Override public void act() {
- throw new FooException();
- }
- },
- JUST_RETURN {
- @Override public void act() {}
- };
-
- public abstract void act();
- }
- Action actionWhenFirstParamIsNull;
- Action actionWhenSecondParamIsNull;
-
- public TwoArg(
- Action actionWhenFirstParamIsNull,
- Action actionWhenSecondParamIsNull) {
- this.actionWhenFirstParamIsNull = actionWhenFirstParamIsNull;
- this.actionWhenSecondParamIsNull = actionWhenSecondParamIsNull;
- }
-
- /** Method that decides how to react to parameters. */
- public void reactToNullParameters(Object first, Object second) {
- if (first == null) {
- actionWhenFirstParamIsNull.act();
- }
- if (second == null) {
- actionWhenSecondParamIsNull.act();
- }
- }
-
- /** Two-arg method with no Nullable params. */
- public void normalNormal(String first, Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** Two-arg method with the second param Nullable. */
- public void normalNullable(String first, @Nullable Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** Two-arg method with the first param Nullable. */
- public void nullableNormal(@Nullable String first, Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** Two-arg method with the both params Nullable. */
- public void nullableNullable(
- @Nullable String first, @Nullable Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** To provide sanity during debugging. */
- @Override public String toString() {
- return String.format("Bar(%s, %s)",
- actionWhenFirstParamIsNull, actionWhenSecondParamIsNull);
- }
- }
-
- public void verifyBarPass(Method method, TwoArg bar) {
- try {
- new NullPointerTester().testMethod(bar, method);
- } catch (AssertionFailedError incorrectError) {
- String errorMessage = String.format(
- "Should not have flagged method %s for %s", method.getName(), bar);
- assertNull(errorMessage, incorrectError);
- }
- }
-
- public void verifyBarFail(Method method, TwoArg bar) {
- try {
- new NullPointerTester().testMethod(bar, method);
- } catch (AssertionFailedError expected) {
- return; // good...we wanted a failure
- }
- String errorMessage = String.format(
- "Should have flagged method %s for %s", method.getName(), bar);
- fail(errorMessage);
- }
-
- public void testTwoArgNormalNormal() throws Exception {
- Method method = TwoArg.class.getMethod(
- "normalNormal", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- if (first.equals(TwoArg.Action.THROW_A_NPE)
- && second.equals(TwoArg.Action.THROW_A_NPE)) {
- verifyBarPass(method, bar); // require both params to throw NPE
- } else {
- verifyBarFail(method, bar);
- }
- }
- }
- }
-
- public void testTwoArgNormalNullable() throws Exception {
- Method method = TwoArg.class.getMethod(
- "normalNullable", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- if (first.equals(TwoArg.Action.THROW_A_NPE)) {
- verifyBarPass(method, bar); // only pass if 1st param throws NPE
- } else {
- verifyBarFail(method, bar);
- }
- }
- }
- }
-
- public void testTwoArgNullableNormal() throws Exception {
- Method method = TwoArg.class.getMethod(
- "nullableNormal", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- if (second.equals(TwoArg.Action.THROW_A_NPE)) {
- verifyBarPass(method, bar); // only pass if 2nd param throws NPE
- } else {
- verifyBarFail(method, bar);
- }
- }
- }
- }
-
- public void testTwoArgNullableNullable() throws Exception {
- Method method = TwoArg.class.getMethod(
- "nullableNullable", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- verifyBarPass(method, bar); // All args nullable: anything goes!
- }
- }
- }
-
- /*
- * This next part consists of several sample classes that provide
- * demonstrations of conditions that cause NullPointerTester
- * to succeed/fail.
- */
-
- /** Lots of well-behaved methods. */
- @SuppressWarnings("unused") // used by reflection
- private static class PassObject extends SomeClassThatDoesNotUseNullable {
- public static void doThrow(Object arg) {
- if (arg == null) {
- throw new FooException();
- }
- }
- public void noArg() {}
- public void oneArg(String s) { checkNotNull(s); }
- void packagePrivateOneArg(String s) { checkNotNull(s); }
- protected void protectedOneArg(String s) { checkNotNull(s); }
- public void oneNullableArg(@Nullable String s) {}
- public void oneNullableArgThrows(@Nullable String s) { doThrow(s); }
-
- public void twoArg(String s, Integer i) { checkNotNull(s); i.intValue(); }
- public void twoMixedArgs(String s, @Nullable Integer i) { checkNotNull(s); }
- public void twoMixedArgsThrows(String s, @Nullable Integer i) {
- checkNotNull(s); doThrow(i);
- }
- public void twoMixedArgs(@Nullable Integer i, String s) { checkNotNull(s); }
- public void twoMixedArgsThrows(@Nullable Integer i, String s) {
- checkNotNull(s); doThrow(i);
- }
- public void twoNullableArgs(@Nullable String s,
- @javax.annotation.Nullable Integer i) {}
- public void twoNullableArgsThrowsFirstArg(
- @Nullable String s, @Nullable Integer i) {
- doThrow(s);
- }
- public void twoNullableArgsThrowsSecondArg(
- @Nullable String s, @Nullable Integer i) {
- doThrow(i);
- }
- public static void staticOneArg(String s) { checkNotNull(s); }
- public static void staticOneNullableArg(@Nullable String s) {}
- public static void staticOneNullableArgThrows(@Nullable String s) {
- doThrow(s);
- }
- }
-
- public void testGoodClass() {
- shouldPass(new PassObject());
- }
-
- private static class FailOneArgDoesntThrowNPE extends PassObject {
- @Override public void oneArg(String s) {
- // Fail: missing NPE for s
- }
- }
-
- public void testFailOneArgDoesntThrowNpe() {
- shouldFail(new FailOneArgDoesntThrowNPE());
- }
-
- private static class FailOneArgThrowsWrongType extends PassObject {
- @Override public void oneArg(String s) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- }
- }
-
- public void testFailOneArgThrowsWrongType() {
- shouldFail(new FailOneArgThrowsWrongType());
- }
-
- private static class PassOneNullableArgThrowsNPE extends PassObject {
- @Override public void oneNullableArg(@Nullable String s) {
- checkNotNull(s); // ok to throw NPE
- }
- }
-
- public void testPassOneNullableArgThrowsNPE() {
- shouldPass(new PassOneNullableArgThrowsNPE());
- }
-
- private static class FailTwoArgsFirstArgDoesntThrowNPE extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- // Fail: missing NPE for s
- i.intValue();
- }
- }
-
- public void testFailTwoArgsFirstArgDoesntThrowNPE() {
- shouldFail(new FailTwoArgsFirstArgDoesntThrowNPE());
- }
-
- private static class FailTwoArgsFirstArgThrowsWrongType extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- i.intValue();
- }
- }
-
- public void testFailTwoArgsFirstArgThrowsWrongType() {
- shouldFail(new FailTwoArgsFirstArgThrowsWrongType());
- }
-
- private static class FailTwoArgsSecondArgDoesntThrowNPE extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- checkNotNull(s);
- // Fail: missing NPE for i
- }
- }
-
- public void testFailTwoArgsSecondArgDoesntThrowNPE() {
- shouldFail(new FailTwoArgsSecondArgDoesntThrowNPE());
- }
-
- private static class FailTwoArgsSecondArgThrowsWrongType extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- checkNotNull(s);
- doThrow(i); // Fail: throwing non-NPE exception for null i
- }
- }
-
- public void testFailTwoArgsSecondArgThrowsWrongType() {
- shouldFail(new FailTwoArgsSecondArgThrowsWrongType());
- }
-
- private static class FailTwoMixedArgsFirstArgDoesntThrowNPE
- extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- // Fail: missing NPE for s
- }
- }
-
- public void testFailTwoMixedArgsFirstArgDoesntThrowNPE() {
- shouldFail(new FailTwoMixedArgsFirstArgDoesntThrowNPE());
- }
-
- private static class FailTwoMixedArgsFirstArgThrowsWrongType
- extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- }
- }
-
- public void testFailTwoMixedArgsFirstArgThrowsWrongType() {
- shouldFail(new FailTwoMixedArgsFirstArgThrowsWrongType());
- }
-
- private static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- checkNotNull(s);
- i.intValue(); // ok to throw NPE?
- }
- }
-
- public void testPassTwoMixedArgsNullableArgThrowsNPE() {
- shouldPass(new PassTwoMixedArgsNullableArgThrowsNPE());
- }
-
- private static class PassTwoMixedArgSecondNullableArgThrowsOther
- extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- checkNotNull(s);
- doThrow(i); // ok to throw non-NPE exception for null i
- }
- }
-
- public void testPassTwoMixedArgSecondNullableArgThrowsOther() {
- shouldPass(new PassTwoMixedArgSecondNullableArgThrowsOther());
- }
-
- private static class FailTwoMixedArgsSecondArgDoesntThrowNPE
- extends PassObject {
- @Override public void twoMixedArgs(@Nullable Integer i, String s) {
- // Fail: missing NPE for null s
- }
- }
-
- public void testFailTwoMixedArgsSecondArgDoesntThrowNPE() {
- shouldFail(new FailTwoMixedArgsSecondArgDoesntThrowNPE());
- }
-
- private static class FailTwoMixedArgsSecondArgThrowsWrongType
- extends PassObject {
- @Override public void twoMixedArgs(@Nullable Integer i, String s) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- }
- }
-
- public void testFailTwoMixedArgsSecondArgThrowsWrongType() {
- shouldFail(new FailTwoMixedArgsSecondArgThrowsWrongType());
- }
-
- private static class PassTwoNullableArgsFirstThrowsNPE extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- checkNotNull(s); // ok to throw NPE?
- }
- }
-
- public void testPassTwoNullableArgsFirstThrowsNPE() {
- shouldPass(new PassTwoNullableArgsFirstThrowsNPE());
- }
-
- private static class PassTwoNullableArgsFirstThrowsOther extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- doThrow(s); // ok to throw non-NPE exception for null s
- }
- }
-
- public void testPassTwoNullableArgsFirstThrowsOther() {
- shouldPass(new PassTwoNullableArgsFirstThrowsOther());
- }
-
- private static class PassTwoNullableArgsSecondThrowsNPE extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- i.intValue(); // ok to throw NPE?
- }
- }
-
- public void testPassTwoNullableArgsSecondThrowsNPE() {
- shouldPass(new PassTwoNullableArgsSecondThrowsNPE());
- }
-
- private static class PassTwoNullableArgsSecondThrowsOther extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- doThrow(i); // ok to throw non-NPE exception for null i
- }
- }
-
- public void testPassTwoNullableArgsSecondThrowsOther() {
- shouldPass(new PassTwoNullableArgsSecondThrowsOther());
- }
-
- private static class PassTwoNullableArgsNeitherThrowsAnything
- extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- // ok to do nothing
- }
- }
-
- public void testPassTwoNullableArgsNeitherThrowsAnything() {
- shouldPass(new PassTwoNullableArgsNeitherThrowsAnything());
- }
-
- @SuppressWarnings("unused") // for NullPointerTester
- private static abstract class BaseClassThatFailsToThrow {
- public void oneArg(String s) {}
- }
-
- private static class SubclassWithBadSuperclass
- extends BaseClassThatFailsToThrow {}
-
- public void testSubclassWithBadSuperclass() {
- shouldFail(new SubclassWithBadSuperclass());
- }
-
- @SuppressWarnings("unused") // for NullPointerTester
- private static abstract class BaseClassThatFailsToThrowForPackagePrivate {
- void packagePrivateOneArg(String s) {}
- }
-
- private static class SubclassWithBadSuperclassForPackagePrivate
- extends BaseClassThatFailsToThrowForPackagePrivate {}
-
- public void testSubclassWithBadSuperclassForPackagePrivateMethod() {
- shouldFail(
- new SubclassWithBadSuperclassForPackagePrivate(), Visibility.PACKAGE);
- }
-
- @SuppressWarnings("unused") // for NullPointerTester
- private static abstract class BaseClassThatFailsToThrowForProtected {
- protected void protectedOneArg(String s) {}
- }
-
- private static class SubclassWithBadSuperclassForProtected
- extends BaseClassThatFailsToThrowForProtected {}
-
- public void testSubclassWithBadSuperclassForPackageProtectedMethod() {
- shouldFail(
- new SubclassWithBadSuperclassForProtected(), Visibility.PROTECTED);
- }
-
- private static class SubclassThatOverridesBadSuperclassMethod
- extends BaseClassThatFailsToThrow {
- @Override public void oneArg(@Nullable String s) {}
- }
-
- public void testSubclassThatOverridesBadSuperclassMethod() {
- shouldPass(new SubclassThatOverridesBadSuperclassMethod());
- }
-
- @SuppressWarnings("unused") // for NullPointerTester
- private static class SubclassOverridesTheWrongMethod
- extends BaseClassThatFailsToThrow {
- public void oneArg(@Nullable CharSequence s) {}
- }
-
- public void testSubclassOverridesTheWrongMethod() {
- shouldFail(new SubclassOverridesTheWrongMethod());
- }
-
- @SuppressWarnings("unused") // for NullPointerTester
- private static class ClassThatFailsToThrowForStatic {
- static void staticOneArg(String s) {}
- }
-
- public void testClassThatFailsToThrowForStatic() {
- shouldFail(ClassThatFailsToThrowForStatic.class);
- }
-
- private static class SubclassThatFailsToThrowForStatic
- extends ClassThatFailsToThrowForStatic {}
-
- public void testSubclassThatFailsToThrowForStatic() {
- shouldFail(SubclassThatFailsToThrowForStatic.class);
- }
-
- private static class SubclassThatTriesToOverrideBadStaticMethod
- extends ClassThatFailsToThrowForStatic {
- static void staticOneArg(@Nullable String s) {}
- }
-
- public void testSubclassThatTriesToOverrideBadStaticMethod() {
- shouldFail(SubclassThatTriesToOverrideBadStaticMethod.class);
- }
-
- private static final class HardToCreate {
- private HardToCreate(HardToCreate x) {}
- }
-
- @SuppressWarnings("unused") // used by reflection
- private static class CanCreateDefault {
- public void foo(@Nullable HardToCreate ignored, String required) {
- checkNotNull(required);
- }
- }
-
- public void testCanCreateDefault() {
- shouldPass(new CanCreateDefault());
- }
-
- @SuppressWarnings("unused") // used by reflection
- private static class CannotCreateDefault {
- public void foo(HardToCreate ignored, String required) {
- checkNotNull(ignored);
- checkNotNull(required);
- }
- }
-
- public void testCannotCreateDefault() {
- shouldFail(new CannotCreateDefault());
- }
-
- private static void shouldPass(Object instance, Visibility visibility) {
- new NullPointerTester().testInstanceMethods(instance, visibility);
- }
-
- private static void shouldPass(Object instance) {
- shouldPass(instance, Visibility.PACKAGE);
- shouldPass(instance, Visibility.PROTECTED);
- shouldPass(instance, Visibility.PUBLIC);
- }
-
- // TODO(cpovirk): eliminate surprising Object/Class overloading of shouldFail
-
- private static void shouldFail(Object instance, Visibility visibility) {
- try {
- new NullPointerTester().testInstanceMethods(instance, visibility);
- } catch (AssertionFailedError expected) {
- return;
- }
- fail("Should detect problem in " + instance.getClass().getSimpleName());
- }
-
- private static void shouldFail(Object instance) {
- shouldFail(instance, Visibility.PACKAGE);
- shouldFail(instance, Visibility.PROTECTED);
- shouldFail(instance, Visibility.PUBLIC);
- }
-
- private static void shouldFail(Class<?> cls, Visibility visibility) {
- try {
- new NullPointerTester().testStaticMethods(cls, visibility);
- } catch (AssertionFailedError expected) {
- return;
- }
- fail("Should detect problem in " + cls.getSimpleName());
- }
-
- private static void shouldFail(Class<?> cls) {
- shouldFail(cls, Visibility.PACKAGE);
- }
-
- @SuppressWarnings("unused") // used by reflection
- private static class PrivateClassWithPrivateConstructor {
- private PrivateClassWithPrivateConstructor(@Nullable Integer argument) {}
- }
-
- public void testPrivateClass() {
- NullPointerTester tester = new NullPointerTester();
- for (Constructor<?> constructor
- : PrivateClassWithPrivateConstructor.class.getDeclaredConstructors()) {
- tester.testConstructor(constructor);
- }
- }
-
- private interface Foo<T> {
- void doSomething(T bar, Integer baz);
- }
-
- private static class StringFoo implements Foo<String> {
-
- @Override public void doSomething(String bar, Integer baz) {
- checkNotNull(bar);
- checkNotNull(baz);
- }
- }
-
- public void testBridgeMethodIgnored() {
- new NullPointerTester().testAllPublicInstanceMethods(new StringFoo());
- }
-
- private static abstract class DefaultValueChecker {
-
- private final Map<Integer, Object> arguments = Maps.newHashMap();
-
- final DefaultValueChecker runTester() {
- new NullPointerTester()
- .testInstanceMethods(this, Visibility.PACKAGE);
- return this;
- }
-
- final void assertNonNullValues(Object... expectedValues) {
- assertEquals(expectedValues.length, arguments.size());
- for (int i = 0; i < expectedValues.length; i++) {
- assertEquals("Default value for parameter #" + i,
- expectedValues[i], arguments.get(i));
- }
- }
-
- final Object getDefaultParameterValue(int position) {
- return arguments.get(position);
- }
-
- final void calledWith(Object... args) {
- for (int i = 0; i < args.length; i++) {
- if (args[i] != null) {
- arguments.put(i, args[i]);
- }
- }
- for (Object arg : args) {
- checkNotNull(arg); // to fulfill null check
- }
- }
- }
-
- private enum Gender {
- MALE, FEMALE
- }
-
- private static class AllDefaultValuesChecker extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkDefaultValuesForTheseTypes(
- Gender gender,
- Integer integer, int i,
- String string, CharSequence charSequence,
- List<String> list,
- ImmutableList<Integer> immutableList,
- Map<String, Integer> map,
- ImmutableMap<String, String> immutableMap,
- Set<String> set,
- ImmutableSet<Integer> immutableSet,
- SortedSet<Number> sortedSet,
- ImmutableSortedSet<Number> immutableSortedSet,
- Multiset<String> multiset,
- ImmutableMultiset<Integer> immutableMultiset,
- Multimap<String, Integer> multimap,
- ImmutableMultimap<String, Integer> immutableMultimap,
- Table<String, Integer, Exception> table,
- ImmutableTable<Integer, String, Exception> immutableTable) {
- calledWith(
- gender,
- integer, i,
- string, charSequence,
- list, immutableList,
- map, immutableMap,
- set, immutableSet,
- sortedSet, immutableSortedSet,
- multiset, immutableMultiset,
- multimap, immutableMultimap,
- table, immutableTable);
- }
-
- final void check() {
- runTester().assertNonNullValues(
- Gender.MALE,
- Integer.valueOf(0), 0,
- "", "",
- ImmutableList.of(), ImmutableList.of(),
- ImmutableMap.of(), ImmutableMap.of(),
- ImmutableSet.of(), ImmutableSet.of(),
- ImmutableSortedSet.of(), ImmutableSortedSet.of(),
- ImmutableMultiset.of(), ImmutableMultiset.of(),
- ImmutableMultimap.of(), ImmutableMultimap.of(),
- ImmutableTable.of(), ImmutableTable.of());
- }
- }
-
- public void testDefaultValues() {
- new AllDefaultValuesChecker().check();
- }
-
- private static class ObjectArrayDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(Object[] array, String s) {
- calledWith(array, s);
- }
-
- void check() {
- runTester();
- Object[] defaultArray = (Object[]) getDefaultParameterValue(0);
- assertEquals(0, defaultArray.length);
- }
- }
-
- public void testObjectArrayDefaultValue() {
- new ObjectArrayDefaultValueChecker().check();
- }
-
- private static class StringArrayDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(String[] array, String s) {
- calledWith(array, s);
- }
-
- void check() {
- runTester();
- String[] defaultArray = (String[]) getDefaultParameterValue(0);
- assertEquals(0, defaultArray.length);
- }
- }
-
- public void testStringArrayDefaultValue() {
- new StringArrayDefaultValueChecker().check();
- }
-
- private static class IntArrayDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(int[] array, String s) {
- calledWith(array, s);
- }
-
- void check() {
- runTester();
- int[] defaultArray = (int[]) getDefaultParameterValue(0);
- assertEquals(0, defaultArray.length);
- }
- }
-
- public void testIntArrayDefaultValue() {
- new IntArrayDefaultValueChecker().check();
- }
-
- private enum EmptyEnum {}
-
- private static class EmptyEnumDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(EmptyEnum object, String s) {
- calledWith(object, s);
- }
-
- void check() {
- try {
- runTester();
- } catch (AssertionError expected) {
- return;
- }
- fail("Should have failed because enum has no constant");
- }
- }
-
- public void testEmptyEnumDefaultValue() {
- new EmptyEnumDefaultValueChecker().check();
- }
-
- private static class GenericClassTypeDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(Class<? extends List<?>> cls, String s) {
- calledWith(cls, s);
- }
-
- void check() {
- runTester();
- Class<?> defaultClass = (Class<?>) getDefaultParameterValue(0);
- assertEquals(List.class, defaultClass);
- }
- }
-
- public void testGenericClassDefaultValue() {
- new GenericClassTypeDefaultValueChecker().check();
- }
-
- private static class NonGenericClassTypeDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(@SuppressWarnings("rawtypes") Class cls, String s) {
- calledWith(cls, s);
- }
-
- void check() {
- runTester();
- Class<?> defaultClass = (Class<?>) getDefaultParameterValue(0);
- assertEquals(Object.class, defaultClass);
- }
- }
-
- public void testNonGenericClassDefaultValue() {
- new NonGenericClassTypeDefaultValueChecker().check();
- }
-
- private static class GenericTypeTokenDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(
- TypeToken<? extends List<? super Number>> type, String s) {
- calledWith(type, s);
- }
-
- void check() {
- runTester();
- TypeToken<?> defaultType = (TypeToken<?>) getDefaultParameterValue(0);
- assertTrue(new TypeToken<List<? super Number>>() {}
- .isAssignableFrom(defaultType));
- }
- }
-
- public void testGenericTypeTokenDefaultValue() {
- new GenericTypeTokenDefaultValueChecker().check();
- }
-
- private static class NonGenericTypeTokenDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(
- @SuppressWarnings("rawtypes") TypeToken type, String s) {
- calledWith(type, s);
- }
-
- void check() {
- runTester();
- TypeToken<?> defaultType = (TypeToken<?>) getDefaultParameterValue(0);
- assertEquals(new TypeToken<Object>() {}, defaultType);
- }
- }
-
- public void testNonGenericTypeTokenDefaultValue() {
- new NonGenericTypeTokenDefaultValueChecker().check();
- }
-
- private interface FromTo<F, T> extends Function<F, T> {}
-
- private static class GenericInterfaceDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(FromTo<String, Integer> f, String s) {
- calledWith(f, s);
- }
-
- void check() {
- runTester();
- FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0);
- assertEquals(0, defaultFunction.apply(null));
- }
- }
-
- public void testGenericInterfaceDefaultValue() {
- new GenericInterfaceDefaultValueChecker().check();
- }
-
- private interface NullRejectingFromTo<F, T> extends Function<F, T> {
- @Override public abstract T apply(F from);
- }
-
- private static class NullRejectingInterfaceDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(NullRejectingFromTo<String, Integer> f, String s) {
- calledWith(f, s);
- }
-
- void check() {
- runTester();
- NullRejectingFromTo<?, ?> defaultFunction = (NullRejectingFromTo<?, ?>)
- getDefaultParameterValue(0);
- assertNotNull(defaultFunction);
- try {
- defaultFunction.apply(null);
- fail("Proxy Should have rejected null");
- } catch (NullPointerException expected) {}
- }
- }
-
- public void testNullRejectingInterfaceDefaultValue() {
- new NullRejectingInterfaceDefaultValueChecker().check();
- }
-
- private static class MultipleInterfacesDefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public <T extends FromTo<String, Integer> & Supplier<Long>> void checkArray(
- T f, String s) {
- calledWith(f, s);
- }
-
- void check() {
- runTester();
- FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0);
- assertEquals(0, defaultFunction.apply(null));
- Supplier<?> defaultSupplier = (Supplier<?>) defaultFunction;
- assertEquals(Long.valueOf(0), defaultSupplier.get());
- }
- }
-
- public void testMultipleInterfacesDefaultValue() {
- new MultipleInterfacesDefaultValueChecker().check();
- }
-
- private static class GenericInterface2DefaultValueChecker
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkArray(FromTo<String, FromTo<Integer, String>> f, String s) {
- calledWith(f, s);
- }
-
- void check() {
- runTester();
- FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0);
- FromTo<?, ?> returnValue = (FromTo<?, ?>) defaultFunction.apply(null);
- assertEquals("", returnValue.apply(null));
- }
- }
-
- public void tesGenericInterfaceReturnedByGenericMethod() {
- new GenericInterface2DefaultValueChecker().check();
- }
-
- private static abstract class AbstractGenericDefaultValueChecker<T>
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- public void checkGeneric(T value, String s) {
- calledWith(value, s);
- }
- }
-
- private static class GenericDefaultValueResolvedToStringChecker
- extends AbstractGenericDefaultValueChecker<String> {
- void check() {
- runTester();
- assertEquals("", getDefaultParameterValue(0));
- }
- }
-
- public void testGenericTypeResolvedForDefaultValue() {
- new GenericDefaultValueResolvedToStringChecker().check();
- }
-
- private static abstract
- class AbstractGenericDefaultValueForPackagePrivateMethodChecker<T>
- extends DefaultValueChecker {
-
- @SuppressWarnings("unused") // called by NullPointerTester
- void checkGeneric(T value, String s) {
- calledWith(value, s);
- }
- }
-
- private static
- class DefaultValueForPackagePrivateMethodResolvedToStringChecker
- extends AbstractGenericDefaultValueForPackagePrivateMethodChecker<String>
- {
- void check() {
- runTester();
- assertEquals("", getDefaultParameterValue(0));
- }
- }
-
- public void testDefaultValueResolvedForPackagePrivateMethod() {
- new DefaultValueForPackagePrivateMethodResolvedToStringChecker().check();
- }
-
- private static class VisibilityMethods {
-
- @SuppressWarnings("unused") // Called by reflection
- private void privateMethod() {}
-
- @SuppressWarnings("unused") // Called by reflection
- void packagePrivateMethod() {}
-
- @SuppressWarnings("unused") // Called by reflection
- protected void protectedMethod() {}
-
- @SuppressWarnings("unused") // Called by reflection
- public void publicMethod() {}
- }
-
- public void testVisibility_public() throws Exception {
- assertFalse(Visibility.PUBLIC.isVisible(
- VisibilityMethods.class.getDeclaredMethod("privateMethod")));
- assertFalse(Visibility.PUBLIC.isVisible(
- VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod")));
- assertFalse(Visibility.PUBLIC.isVisible(
- VisibilityMethods.class.getDeclaredMethod("protectedMethod")));
- assertTrue(Visibility.PUBLIC.isVisible(
- VisibilityMethods.class.getDeclaredMethod("publicMethod")));
- }
-
- public void testVisibility_protected() throws Exception {
- assertFalse(Visibility.PROTECTED.isVisible(
- VisibilityMethods.class.getDeclaredMethod("privateMethod")));
- assertFalse(Visibility.PROTECTED.isVisible(
- VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod")));
- assertTrue(Visibility.PROTECTED.isVisible(
- VisibilityMethods.class.getDeclaredMethod("protectedMethod")));
- assertTrue(Visibility.PROTECTED.isVisible(
- VisibilityMethods.class.getDeclaredMethod("publicMethod")));
- }
-
- public void testVisibility_package() throws Exception {
- assertFalse(Visibility.PACKAGE.isVisible(
- VisibilityMethods.class.getDeclaredMethod("privateMethod")));
- assertTrue(Visibility.PACKAGE.isVisible(
- VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod")));
- assertTrue(Visibility.PACKAGE.isVisible(
- VisibilityMethods.class.getDeclaredMethod("protectedMethod")));
- assertTrue(Visibility.PACKAGE.isVisible(
- VisibilityMethods.class.getDeclaredMethod("publicMethod")));
- }
-
- private class Inner {
- public Inner(String s) {
- checkNotNull(s);
- }
- }
-
- public void testNonStaticInnerClass() {
- try {
- new NullPointerTester().testAllPublicConstructors(Inner.class);
- fail();
- } catch (IllegalArgumentException expected) {
- ASSERT.that(expected.getMessage()).contains("inner class");
- }
- }
-
- /*
- *
- * TODO(kevinb): This is only a very small start.
- * Must come back and finish.
- *
- */
-
-}
diff --git a/guava-testlib/test/com/google/common/testing/PackageSanityTests.java b/guava-testlib/test/com/google/common/testing/PackageSanityTests.java
deleted file mode 100644
index a5b329c..0000000
--- a/guava-testlib/test/com/google/common/testing/PackageSanityTests.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-/**
- * Test nulls for the entire package.
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-testlib/test/com/google/common/testing/RelationshipTesterTest.java b/guava-testlib/test/com/google/common/testing/RelationshipTesterTest.java
deleted file mode 100644
index 3c68f09..0000000
--- a/guava-testlib/test/com/google/common/testing/RelationshipTesterTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import com.google.common.testing.RelationshipTester.ItemReporter;
-import com.google.common.testing.RelationshipTester.RelationshipAssertion;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link RelationshipTester}.
- *
- * @author Ben Yu
- */
-public class RelationshipTesterTest extends TestCase {
-
- public void testNulls(){
- new ClassSanityTester()
- .setDefault(RelationshipAssertion.class, new RelationshipAssertion<Object>() {
- @Override void assertRelated(Object item, Object related) {}
- @Override void assertUnrelated(Object item, Object unrelated) {}
- })
- .setDefault(ItemReporter.class, new ItemReporter())
- .testNulls(RelationshipTester.class);
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/anotherpackage/ForwardingWrapperTesterTest.java b/guava-testlib/test/com/google/common/testing/anotherpackage/ForwardingWrapperTesterTest.java
deleted file mode 100644
index f9016d1..0000000
--- a/guava-testlib/test/com/google/common/testing/anotherpackage/ForwardingWrapperTesterTest.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing.anotherpackage;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Equivalence;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Ordering;
-import com.google.common.primitives.UnsignedInteger;
-import com.google.common.primitives.UnsignedLong;
-import com.google.common.testing.ForwardingWrapperTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-
-/**
- * Tests for {@link ForwardingWrapperTester}. Live in a different package to detect reflection
- * access issues, if any.
- *
- * @author Ben Yu
- */
-public class ForwardingWrapperTesterTest extends TestCase {
-
- private final ForwardingWrapperTester tester = new ForwardingWrapperTester();
-
- public void testGoodForwarder() {
- tester.testForwarding(Arithmetic.class,
- new Function<Arithmetic, Arithmetic>() {
- @Override public Arithmetic apply(Arithmetic arithmetic) {
- return new ForwardingArithmetic(arithmetic);
- }
- });
- tester.testForwarding(ParameterTypesDifferent.class,
- new Function<ParameterTypesDifferent, ParameterTypesDifferent>() {
- @Override public ParameterTypesDifferent apply(ParameterTypesDifferent delegate) {
- return new ParameterTypesDifferentForwarder(delegate);
- }
- });
- }
-
- public void testVoidMethodForwarding() {
- tester.testForwarding(Runnable.class,
- new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new ForwardingRunnable(runnable);
- }
- });
- }
-
- public void testToStringForwarding() {
- tester.testForwarding(Runnable.class,
- new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new ForwardingRunnable(runnable) {
- @Override public String toString() {
- return runnable.toString();
- }
- };
- }
- });
- }
-
- public void testFailsToForwardToString() {
- assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new ForwardingRunnable(runnable) {
- @Override public String toString() {
- return "";
- }
- };
- }
- }, "toString()");
- }
-
- public void testFailsToForwardHashCode() {
- tester.includingEquals();
- assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new ForwardingRunnable(runnable) {
- @Override public boolean equals(Object o) {
- if (o instanceof ForwardingRunnable) {
- ForwardingRunnable that = (ForwardingRunnable) o;
- return runnable.equals(that.runnable);
- }
- return false;
- }
- };
- }
- }, "Runnable");
- }
-
- public void testEqualsAndHashCodeForwarded() {
- tester.includingEquals();
- tester.testForwarding(Runnable.class, new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new ForwardingRunnable(runnable) {
- @Override public boolean equals(Object o) {
- if (o instanceof ForwardingRunnable) {
- ForwardingRunnable that = (ForwardingRunnable) o;
- return runnable.equals(that.runnable);
- }
- return false;
- }
- @Override public int hashCode() {
- return runnable.hashCode();
- }
- };
- }
- });
- }
-
- public void testFailsToForwardEquals() {
- tester.includingEquals();
- assertFailure(Runnable.class, new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new ForwardingRunnable(runnable) {
- @Override public int hashCode() {
- return runnable.hashCode();
- }
- };
- }
- }, "Runnable");
- }
-
- public void testFailsToForward() {
- assertFailure(Runnable.class,
- new Function<Runnable, Runnable>() {
- @Override public Runnable apply(Runnable runnable) {
- return new ForwardingRunnable(runnable) {
- @Override public void run() {}
- };
- }
- }, "run()", "Failed to forward");
- }
-
- public void testRedundantForwarding() {
- assertFailure(Runnable.class,
- new Function<Runnable, Runnable>() {
- @Override public Runnable apply(final Runnable runnable) {
- return new Runnable() {
- @Override public void run() {
- runnable.run();
- runnable.run();
- }
- };
- }
- }, "run()", "invoked more than once");
- }
-
- public void testFailsToForwardParameters() {
- assertFailure(Adder.class, new Function<Adder, Adder>() {
- @Override public Adder apply(Adder adder) {
- return new FailsToForwardParameters(adder);
- }
- }, "add(", "Parameter #0");
- }
-
- public void testForwardsToTheWrongMethod() {
- assertFailure(Arithmetic.class, new Function<Arithmetic, Arithmetic>() {
- @Override public Arithmetic apply(Arithmetic adder) {
- return new ForwardsToTheWrongMethod(adder);
- }
- }, "minus");
- }
-
- public void testFailsToForwardReturnValue() {
- assertFailure(Adder.class, new Function<Adder, Adder>() {
- @Override public Adder apply(Adder adder) {
- return new FailsToForwardReturnValue(adder);
- }
- }, "add(", "Return value");
- }
-
- public void testFailsToPropagateException() {
- assertFailure(Adder.class, new Function<Adder, Adder>() {
- @Override public Adder apply(Adder adder) {
- return new FailsToPropagageException(adder);
- }
- }, "add(", "exception");
- }
-
- public void testNotInterfaceType() {
- try {
- new ForwardingWrapperTester().testForwarding(String.class, Functions.<String>identity());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNulls() {
- new NullPointerTester()
- .setDefault(Class.class, Runnable.class)
- .testAllPublicInstanceMethods(new ForwardingWrapperTester());
- }
-
- private <T> void assertFailure(
- Class<T> interfaceType, Function<T, ? extends T> wrapperFunction,
- String... expectedMessages) {
- try {
- tester.testForwarding(interfaceType, wrapperFunction);
- } catch (AssertionError expected) {
- for (String message : expectedMessages) {
- ASSERT.that(expected.getMessage()).contains(message);
- }
- return;
- }
- fail("expected failure not reported");
- }
-
- private class ForwardingRunnable implements Runnable {
-
- private final Runnable runnable;
-
- ForwardingRunnable(Runnable runnable) {
- this.runnable = runnable;
- }
-
- @Override public void run() {
- runnable.run();
- }
-
- @Override public String toString() {
- return runnable.toString();
- }
- }
-
- private interface Adder {
- int add(int a, int b);
- }
-
- private static class ForwardingArithmetic implements Arithmetic {
- private final Arithmetic arithmetic;
-
- public ForwardingArithmetic(Arithmetic arithmetic) {
- this.arithmetic = arithmetic;
- }
-
- @Override public int add(int a, int b) {
- return arithmetic.add(a, b);
- }
-
- @Override public int minus(int a, int b) {
- return arithmetic.minus(a, b);
- }
-
- @Override public String toString() {
- return arithmetic.toString();
- }
- }
-
- private static class FailsToForwardParameters implements Adder {
- private final Adder adder;
-
- FailsToForwardParameters(Adder adder) {
- this.adder = adder;
- }
-
- @Override public int add(int a, int b) {
- return adder.add(b, a);
- }
-
- @Override public String toString() {
- return adder.toString();
- }
- }
-
- private static class FailsToForwardReturnValue implements Adder {
- private final Adder adder;
-
- FailsToForwardReturnValue(Adder adder) {
- this.adder = adder;
- }
-
- @Override public int add(int a, int b) {
- return adder.add(a, b) + 1;
- }
-
- @Override public String toString() {
- return adder.toString();
- }
- }
-
- private static class FailsToPropagageException implements Adder {
- private final Adder adder;
-
- FailsToPropagageException(Adder adder) {
- this.adder = adder;
- }
-
- @Override public int add(int a, int b) {
- try {
- return adder.add(a, b);
- } catch (Exception e) {
- // swallow!
- return 0;
- }
- }
-
- @Override public String toString() {
- return adder.toString();
- }
- }
-
- public interface Arithmetic extends Adder {
- int minus(int a, int b);
- }
-
- private static class ForwardsToTheWrongMethod implements Arithmetic {
- private final Arithmetic arithmetic;
-
- ForwardsToTheWrongMethod(Arithmetic arithmetic) {
- this.arithmetic = arithmetic;
- }
-
- @Override public int minus(int a, int b) { // bad!
- return arithmetic.add(b, a);
- }
-
- @Override public int add(int a, int b) {
- return arithmetic.add(b, a);
- }
-
- @Override public String toString() {
- return arithmetic.toString();
- }
- }
-
- private interface ParameterTypesDifferent {
- void foo(String s, Runnable r, Number n, Iterable<?> it, boolean b, Equivalence<String> eq,
- Exception e, InputStream in, Comparable<?> c, Ordering<Integer> ord,
- Charset charset, TimeUnit unit, Class<?> cls, Joiner joiner,
- Pattern pattern, UnsignedInteger ui, UnsignedLong ul, StringBuilder sb,
- Predicate<?> pred, Function<?, ?> func, Object obj);
- }
-
- private static class ParameterTypesDifferentForwarder implements ParameterTypesDifferent {
- private final ParameterTypesDifferent delegate;
-
- public ParameterTypesDifferentForwarder(ParameterTypesDifferent delegate) {
- this.delegate = delegate;
- }
-
- @Override public void foo(
- String s, Runnable r, Number n, Iterable<?> it, boolean b, Equivalence<String> eq,
- Exception e, InputStream in, Comparable<?> c, Ordering<Integer> ord,
- Charset charset, TimeUnit unit, Class<?> cls, Joiner joiner,
- Pattern pattern, UnsignedInteger ui, UnsignedLong ul, StringBuilder sb,
- Predicate<?> pred, Function<?, ?> func, Object obj) {
- delegate.foo(s,
- r, n, it, b, eq, e, in, c, ord, charset, unit, cls, joiner, pattern,
- ui, ul, sb, pred, func, obj);
- }
-
- @Override public String toString() {
- return delegate.toString();
- }
- }
-
- public void testCovariantReturn() {
- new ForwardingWrapperTester().testForwarding(Sub.class, new Function<Sub, Sub>() {
- @Override public Sub apply(Sub sub) {
- return new ForwardingSub(sub);
- }
- });
- }
-
- interface Base {
- CharSequence getId();
- }
-
- interface Sub extends Base {
- @Override String getId();
- }
-
- private static class ForwardingSub implements Sub {
- private final Sub delegate;
-
- ForwardingSub(Sub delegate) {
- this.delegate = delegate;
- }
-
- @Override public String getId() {
- return delegate.getId();
- }
-
- @Override public String toString() {
- return delegate.toString();
- }
- }
-
- private interface Equals {
- @Override boolean equals(Object obj);
- @Override int hashCode();
- @Override String toString();
- }
-
- private static class NoDelegateToEquals implements Equals {
-
- private static Function<Equals, Equals> WRAPPER = new Function<Equals, Equals>() {
- @Override public NoDelegateToEquals apply(Equals delegate) {
- return new NoDelegateToEquals(delegate);
- }
- };
-
- private final Equals delegate;
-
- NoDelegateToEquals(Equals delegate) {
- this.delegate = delegate;
- }
-
- @Override public String toString() {
- return delegate.toString();
- }
- }
-
- public void testExplicitEqualsAndHashCodeNotDelegatedByDefault() {
- new ForwardingWrapperTester()
- .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
- }
-
- public void testExplicitEqualsAndHashCodeDelegatedWhenExplicitlyAsked() {
- try {
- new ForwardingWrapperTester()
- .includingEquals()
- .testForwarding(Equals.class, NoDelegateToEquals.WRAPPER);
- } catch (AssertionError expected) {
- return;
- }
- fail("Should have failed");
- }
-}
diff --git a/guava-testlib/test/com/google/common/testing/anotherpackage/SomeClassThatDoesNotUseNullable.java b/guava-testlib/test/com/google/common/testing/anotherpackage/SomeClassThatDoesNotUseNullable.java
deleted file mode 100644
index 6a17d1e..0000000
--- a/guava-testlib/test/com/google/common/testing/anotherpackage/SomeClassThatDoesNotUseNullable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing.anotherpackage;
-
-/** Does not check null, but should not matter since it's in a different package. */
-@SuppressWarnings("unused") // For use by NullPointerTester
-public class SomeClassThatDoesNotUseNullable {
-
- void packagePrivateButDoesNotCheckNull(String s) {}
-
- protected void protectedButDoesNotCheckNull(String s) {}
-
- public void publicButDoesNotCheckNull(String s) {}
-
- public static void staticButDoesNotCheckNull(String s) {}
-}
diff --git a/guava-testlib/test/com/google/common/util/concurrent/testing/TestingExecutorsTest.java b/guava-testlib/test/com/google/common/util/concurrent/testing/TestingExecutorsTest.java
deleted file mode 100644
index 4a07967..0000000
--- a/guava-testlib/test/com/google/common/util/concurrent/testing/TestingExecutorsTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent.testing;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.util.concurrent.ListeningScheduledExecutorService;
-
-import junit.framework.TestCase;
-
-import java.lang.InterruptedException;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for TestingExecutors.
- *
- * @author Eric Chang
- */
-public class TestingExecutorsTest extends TestCase {
- private volatile boolean taskDone;
-
- public void testNoOpScheduledExecutor() throws InterruptedException {
- taskDone = false;
- Runnable task = new Runnable() {
- @Override public void run() {
- taskDone = true;
- }
- };
- ScheduledFuture<?> future = TestingExecutors.noOpScheduledExecutor().schedule(
- task, 10, TimeUnit.MILLISECONDS);
- Thread.sleep(20);
- assertFalse(taskDone);
- assertFalse(future.isDone());
- }
-
- public void testNoOpScheduledExecutorShutdown() {
- ListeningScheduledExecutorService executor = TestingExecutors.noOpScheduledExecutor();
- assertFalse(executor.isShutdown());
- assertFalse(executor.isTerminated());
- executor.shutdown();
- assertTrue(executor.isShutdown());
- assertTrue(executor.isTerminated());
- }
-
- public void testNoOpScheduledExecutorInvokeAll() throws ExecutionException, InterruptedException {
- ListeningScheduledExecutorService executor = TestingExecutors.noOpScheduledExecutor();
- taskDone = false;
- Callable<Boolean> task = new Callable<Boolean>() {
- @Override public Boolean call() {
- taskDone = true;
- return taskDone;
- }
- };
- List<Future<Boolean>> futureList = executor.invokeAll(
- ImmutableList.of(task), 10, TimeUnit.MILLISECONDS);
- Future<Boolean> future = futureList.get(0);
- assertFalse(taskDone);
- assertTrue(future.isDone());
- try {
- future.get();
- fail();
- } catch (CancellationException e) {
- // pass
- }
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/AsciiBenchmark.java b/guava-tests/benchmark/com/google/common/base/AsciiBenchmark.java
deleted file mode 100644
index fa92d40..0000000
--- a/guava-tests/benchmark/com/google/common/base/AsciiBenchmark.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Ascii;
-import com.google.common.collect.Lists;
-import com.google.common.primitives.Chars;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Random;
-
-/**
- * Benchmarks for the ASCII class.
- *
- * @author Kevin Bourrillion
- */
-public class AsciiBenchmark extends SimpleBenchmark {
- private static String ALPHA =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- private static String NONALPHA =
- "0123456789`~-_=+[]{}|;:',.<>/?!@#$%^&*()\"\\";
-
- @Param({"20", "2000"}) int size;
- @Param({"2", "20"}) int nonAlphaRatio; // one non-alpha char per this many chars
- @Param boolean noWorkToDo;
-
- Random random;
- String testString;
-
- @Override protected void setUp() {
- random = new Random();
-
- int nonAlpha = size / nonAlphaRatio;
- int alpha = size - nonAlpha;
-
- List<Character> chars = Lists.newArrayListWithCapacity(size);
- for (int i = 0; i < alpha; i++) {
- chars.add(randomAlpha());
- }
- for (int i = 0; i < nonAlpha; i++) {
- chars.add(randomNonAlpha());
- }
- Collections.shuffle(chars, random);
- char[] array = Chars.toArray(chars);
- this.testString = new String(array);
- }
-
- private char randomAlpha() {
- return ALPHA.charAt(random.nextInt(ALPHA.length()));
- }
-
- private char randomNonAlpha() {
- return NONALPHA.charAt(random.nextInt(NONALPHA.length()));
- }
-
- public int timeAsciiToUpperCase(int reps) {
- String string = noWorkToDo
- ? Ascii.toUpperCase(testString)
- : testString;
-
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += Ascii.toUpperCase(string).length();
- }
- return dummy;
- }
-
- public int timeStringToUpperCase1(int reps) {
- String string = noWorkToDo
- ? testString.toUpperCase()
- : testString;
-
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += string.toUpperCase().length();
- }
- return dummy;
- }
-
- public int timeStringToUpperCase2(int reps) {
- String string = noWorkToDo
- ? testString.toUpperCase(Locale.US)
- : testString;
-
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += string.toUpperCase(Locale.US).length();
- }
- return dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(AsciiBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/CharMatcherBenchmark.java b/guava-tests/benchmark/com/google/common/base/CharMatcherBenchmark.java
deleted file mode 100644
index d08ca1b..0000000
--- a/guava-tests/benchmark/com/google/common/base/CharMatcherBenchmark.java
+++ /dev/null
@@ -1,2646 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.BenchmarkHelpers.SampleMatcherConfig;
-import com.google.common.collect.Lists;
-
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Benchmark for the {@link CharMatcher} class.
- *
- * <p>Example of running the benchmark, overriding one parameter:
- *
- *
- * @author David Beaumont
- * @author Kevin Bourrillion
- * @author David Richter
- */
-public class CharMatcherBenchmark extends SimpleBenchmark {
-
- // Caliper injects params automatically
-
- // Overall configuration
- @Param SampleMatcherConfig config;
-
- // Length of string to match against
- @Param({"64", "1024"}) int length;
-
- // Percent of string that the CharMatcher matches
- @Param({"0", "10", "50", "100"}) int percent;
-
- // Whether to use a precomputed CharMatcher
- @Param("true") boolean precomputed;
-
- enum Size {
- DEFAULT,
- SMALL;
- }
-
- @Param Size size;
-
- // Whether to ensure there is a matching character in the first position
- // to force the trimming code to run.
- @Param("false") boolean forceSlow;
-
- // Use web-derived sampler.
- @Param("false") boolean web;
-
- private CharMatcher matcher;
- private String string;
-
- // Caliper invokes setUp() after injecting params
- @Override protected void setUp() {
- this.matcher = precomputed ? config.matcher.precomputed() : config.matcher;
- if (size == Size.SMALL) {
- BitSet tmp = new BitSet();
- matcher.setBits(tmp);
- int matchedCharCount = tmp.cardinality();
- this.matcher = SmallCharMatcher.from(tmp, "");
- }
- this.string = checkString(length, percent, config.matchingChars,
- new Random(), forceSlow, web);
- }
-
- // Caliper recognizes int-parameter methods beginning with "time"
-
- public int timeTrimAndCollapseFromString(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += matcher.trimAndCollapseFrom(string, '!').length();
- }
- return dummy;
- }
-
- public int timeMatches(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += matcher.matches(string.charAt(i % string.length())) ? 1 : 0;
- }
- return dummy;
- }
-
- private static final String NONMATCHING_CHARS =
- "abcdefghijklmnopqrstuvwxyz0123456789";
-
- private static String checkString(int length, int percent,
- String matchingChars, Random rand, boolean forceSlow, boolean web) {
- // Check whether we should ignore everything else and pull from the web.
- if (web) {
- StringBuilder builder = new StringBuilder(length);
- CharSamples sampler = new CharSamples(rand);
- for (int i = 0; i < length; i++) {
- int cp = sampler.nextCodePoint();
- builder.appendCodePoint(cp);
- }
- return builder.toString();
- }
- // Use a shuffled index array to ensure constant percentage of matching
- // characters
- List<Integer> list = Lists.newArrayList();
- for (int i = 0; i < length; i++) {
- list.add(i);
- }
- Collections.shuffle(list, rand);
- if (forceSlow) {
- // Move zero index to front to force a matching character (if percent > 0)
- list.set(list.indexOf(0), list.get(0));
- list.set(0, 0);
- }
- // Get threshold in the range [0, length], rounding up to ensure that non
- // zero percent values result in a non-zero threshold (so we always have at
- // least one matching character).
- int threshold = ((percent * length) + 99) / 100;
- StringBuilder builder = new StringBuilder(length);
- for (int n = 0; n < length; n++) {
- builder.append(randomCharFrom(
- list.get(n) >= threshold ? NONMATCHING_CHARS : matchingChars, rand));
- }
- return builder.toString();
- }
-
- private static char randomCharFrom(String s, Random rand) {
- return s.charAt(rand.nextInt(s.length()));
- }
-
- public static void main(String[] args) {
- Runner.main(CharMatcherBenchmark.class, args);
- }
-
- /**
- * Provides samples on a random distribution derived from the web.
- *
- * Adapted from data provided by Mark Davis.
- *
- * @author Christopher Swenson
- */
- static class CharSamples {
-
- static {
- populateProb1();
- populateProb2();
- populateChars1();
- populateChars2();
- }
-
- private final Random random;
-
- public CharSamples(Random random) {
- this.random = random;
- }
- public int nextCodePoint() {
- int needle = random.nextInt(sum);
- int l = 0;
- int r = prob.length - 1;
- int c = prob.length / 2;
- int lv = prob[l];
- int rv = prob[r];
- int cv = prob[c];
-
- while (true) {
- if (needle == cv) {
- return chars[c - 1];
- } else if ((lv <= needle) && (needle < cv)) {
- return chars[l];
- } else if (needle == rv) {
- return chars[r];
- } else if (needle < cv) {
- rv = cv;
- r = c;
- c = l + (r - l) / 2;
- cv = prob[c];
- } else if (needle == cv) {
- return chars[c];
- } else {
- lv = cv;
- l = c;
- c = l + (r - l) / 2;
- cv = prob[c];
- }
- }
- }
-
- private int sum = 69552218;
- private static int[] prob;
-
- private static void populateProb1() {
- prob = new int[10003];
- int[] temp = new int[] {0, 2998461, 11968276, 18768077, 22489668,
- 25564867, 28566474, 31178037, 33583728, 35906053, 38220254, 40430228,
- 42605383, 44136051, 45417665, 46672307, 46782210, 47875442, 48928896,
- 49849977, 49926463, 50685835, 51384820, 51997588, 52562977, 53114810,
- 53662681, 54154198, 54201051, 54247649, 54709396, 55150464, 55558189,
- 55956271, 56255010, 56537443, 56790560, 57034843, 57274138, 57485651,
- 57690645, 57894136, 58095179, 58290586, 58478703, 58657046, 58833174,
- 58979618, 59118214, 59252316, 59383011, 59511468, 59616000, 59719717,
- 59822765, 59924337, 60018141, 60102715, 60103512, 60111276, 60187497,
- 60261002, 60332050, 60400395, 60463530, 60525044, 60586535, 60592498,
- 60651542, 60708760, 60765356, 60820799, 60876057, 60926360, 60976475,
- 61026421, 61074255, 61118922, 61163456, 61207355, 61251147, 61293399,
- 61334924, 61375951, 61416927, 61457584, 61497222, 61501126, 61539952,
- 61577967, 61615858, 61652895, 61689599, 61726065, 61762110, 61796817,
- 61831379, 61865281, 61898336, 61930814, 61963212, 61995571, 62027746,
- 62059880, 62091953, 62123862, 62155726, 62187494, 62218025, 62247942,
- 62277854, 62307509, 62336275, 62364822, 62393339, 62421575, 62449112,
- 62476556, 62503994, 62531165, 62533882, 62536554, 62563178, 62589569,
- 62615931, 62641977, 62667819, 62670393, 62672941, 62698398, 62723810,
- 62748828, 62773421, 62773660, 62797528, 62820871, 62823180, 62845858,
- 62868387, 62890814, 62913180, 62935449, 62957034, 62978440, 62999686,
- 63020821, 63041849, 63062713, 63082956, 63102958, 63122877, 63142650,
- 63162263, 63181752, 63201214, 63220472, 63239711, 63258362, 63276998,
- 63295503, 63313936, 63332203, 63350395, 63368456, 63386448, 63388247,
- 63405634, 63407359, 63424261, 63441134, 63457698, 63474247, 63490783,
- 63507308, 63523723, 63539975, 63556168, 63572196, 63587834, 63603467,
- 63619061, 63634602, 63650139, 63665668, 63681137, 63696535, 63698072,
- 63713405, 63728710, 63743997, 63759244, 63774378, 63789477, 63804212,
- 63818898, 63833577, 63848192, 63862616, 63877034, 63891215, 63905360,
- 63919315, 63933131, 63946873, 63960526, 63974167, 63987674, 64001139,
- 64014592, 64028011, 64041415, 64054809, 64068126, 64081417, 64094632,
- 64107536, 64120332, 64133044, 64145616, 64158121, 64170496, 64182865,
- 64195233, 64207588, 64219849, 64232094, 64244320, 64256504, 64257719,
- 64269791, 64281807, 64293783, 64305588, 64306765, 64318504, 64330211,
- 64341904, 64353578, 64365252, 64366419, 64378068, 64389716, 64401322,
- 64412871, 64424406, 64425552, 64426689, 64437977, 64449132, 64460284,
- 64471315, 64482340, 64493269, 64503956, 64514601, 64525226, 64535778,
- 64546326, 64556767, 64567140, 64577453, 64587746, 64598011, 64608256,
- 64608358, 64618492, 64628579, 64638653, 64648727, 64658764, 64668799,
- 64678680, 64688543, 64698398, 64708082, 64717757, 64727380, 64736982,
- 64746557, 64756118, 64765654, 64775155, 64784592, 64794024, 64803433,
- 64812780, 64822087, 64831283, 64840465, 64849520, 64858567, 64867599,
- 64876612, 64885585, 64894553, 64903472, 64912373, 64921249, 64930038,
- 64938750, 64947452, 64948320, 64956991, 64965638, 64974277, 64982885,
- 64991466, 65000015, 65008563, 65017094, 65025571, 65033995, 65042379,
- 65050716, 65059035, 65067338, 65075627, 65076455, 65084727, 65092982,
- 65101144, 65109266, 65117373, 65125479, 65133578, 65141657, 65149726,
- 65150531, 65158555, 65166553, 65174472, 65182377, 65190260, 65198136,
- 65205979, 65206763, 65214595, 65222402, 65230135, 65237858, 65245556,
- 65253253, 65260922, 65261686, 65269318, 65276950, 65284569, 65292163,
- 65299687, 65307200, 65307275, 65314762, 65322226, 65329664, 65337073,
- 65344451, 65351800, 65359136, 65366462, 65373775, 65381087, 65388284,
- 65395469, 65402651, 65409830, 65417003, 65424168, 65431331, 65438487,
- 65445595, 65452672, 65459721, 65466766, 65473795, 65480823, 65487847,
- 65494824, 65501797, 65508770, 65515732, 65522693, 65529646, 65536520,
- 65537207, 65537893, 65538579, 65545430, 65552241, 65559039, 65565814,
- 65572562, 65579296, 65586020, 65592716, 65593382, 65600037, 65606605,
- 65613147, 65619640, 65626071, 65632496, 65638918, 65645310, 65645945,
- 65652280, 65652912, 65659168, 65665415, 65671631, 65677833, 65684025,
- 65684641, 65690780, 65696909, 65703021, 65709132, 65715239, 65721340,
- 65727438, 65733535, 65739617, 65745695, 65751753, 65757765, 65763760,
- 65769744, 65775699, 65781646, 65787588, 65793525, 65799461, 65805374,
- 65811283, 65817190, 65823078, 65823666, 65824253, 65830101, 65835942,
- 65841755, 65847563, 65853354, 65859098, 65864810, 65870519, 65876183,
- 65881822, 65887437, 65893045, 65898651, 65904246, 65909707, 65915151,
- 65920583, 65925999, 65931410, 65936817, 65942193, 65947567, 65952934,
- 65958289, 65963637, 65968969, 65974293, 65974825, 65980140, 65985417,
- 65990672, 65995914, 66001153, 66006392, 66011615, 66012137, 66017334,
- 66022528, 66027719, 66032905, 66033422, 66038587, 66043749, 66048910,
- 66054066, 66059218, 66064370, 66069493, 66070005, 66075122, 66080220,
- 66085315, 66090410, 66095497, 66100582, 66105664, 66110746, 66115813,
- 66120879, 66125928, 66130971, 66131475, 66136498, 66141516, 66146527,
- 66151533, 66156526, 66161499, 66166472, 66171429, 66176377, 66181315,
- 66186228, 66186719, 66191625, 66196528, 66196577, 66201473, 66206365,
- 66206854, 66211740, 66216606, 66221467, 66226320, 66231162, 66231645,
- 66236468, 66241285, 66246076, 66250853, 66255621, 66260387, 66265121,
- 66269852, 66274579, 66279293, 66284006, 66288711, 66293414, 66298061,
- 66302706, 66307341, 66311963, 66316582, 66321199, 66325797, 66330382,
- 66334965, 66339540, 66344108, 66348674, 66353233, 66357788, 66362332,
- 66366874, 66371412, 66375949, 66380462, 66384963, 66385008, 66389507,
- 66393988, 66398461, 66402913, 66407358, 66411800, 66416227, 66420650,
- 66421092, 66425506, 66429903, 66434282, 66438657, 66443011, 66447364,
- 66451711, 66456043, 66460374, 66464695, 66469009, 66473318, 66477619,
- 66481905, 66486174, 66490433, 66494685, 66498930, 66503172, 66507405,
- 66511629, 66515843, 66520045, 66524244, 66528437, 66532628, 66536801,
- 66540968, 66545132, 66549288, 66553436, 66557577, 66561711, 66565840,
- 66569963, 66570004, 66574103, 66578201, 66582298, 66582707, 66583115,
- 66587194, 66591270, 66595323, 66599360, 66603386, 66607410, 66611432,
- 66615421, 66619394, 66623366, 66623763, 66627728, 66631691, 66635652,
- 66639601, 66643544, 66647482, 66651390, 66655298, 66659177, 66663029,
- 66666880, 66670725, 66674569, 66678395, 66682219, 66686042, 66689844,
- 66693646, 66697442, 66701236, 66705023, 66708801, 66712574, 66716338,
- 66720099, 66723857, 66727581, 66731302, 66735016, 66738729, 66742440,
- 66746147, 66749838, 66753521, 66757203, 66757571, 66761249, 66764927,
- 66768604, 66772257, 66775909, 66779541, 66783159, 66786773, 66790376,
- 66793962, 66797546, 66801127, 66804703, 66808262, 66811818, 66815367,
- 66818912, 66822449, 66825986, 66829521, 66833055, 66836582, 66840106,
- 66843624, 66847140, 66850656, 66854170, 66857658, 66861130, 66864598,
- 66868064, 66871527, 66874984, 66878430, 66881873, 66885312, 66888746,
- 66892179, 66895608, 66899030, 66902433, 66905822, 66909208, 66912593,
- 66915978, 66919361, 66922743, 66926120, 66929492, 66932854, 66936205,
- 66939548, 66942882, 66946210, 66949528, 66949859, 66953164, 66956467,
- 66959762, 66960091, 66963379, 66966665, 66969950, 66973229, 66976498,
- 66979762, 66983021, 66986279, 66989531, 66992782, 66996030, 66999275,
- 67002518, 67005760, 67008993, 67012220, 67015446, 67018671, 67018993,
- 67022210, 67025425, 67028640, 67031851, 67035058, 67038263, 67041459,
- 67044653, 67047839, 67051016, 67054190, 67057359, 67060524, 67063687,
- 67066836, 67069985, 67073112, 67076238, 67079355, 67082471, 67085585,
- 67088688, 67091790, 67094862, 67095169, 67098228, 67101266, 67101568,
- 67104586, 67107601, 67110615, 67110618, 67110621, 67113616, 67116609,
- 67119594, 67122578, 67125559, 67128533, 67131506, 67134473, 67137436,
- 67140397, 67143358, 67146316, 67149268, 67152216, 67155163, 67158106,
- 67161049, 67163991, 67166929, 67167222, 67170149, 67173074, 67175993,
- 67178907, 67181820, 67184732, 67187640, 67190545, 67193440, 67193729,
- 67196611, 67199490, 67202361, 67205225, 67208088, 67208374, 67211232,
- 67214088, 67216942, 67219795, 67222648, 67225497, 67228341, 67231184,
- 67231468, 67231752, 67234590, 67237424, 67240250, 67243069, 67245884,
- 67248698, 67251505, 67254310, 67257109, 67259903, 67262692, 67265473,
- 67265751, 67268529, 67271305, 67274079, 67276851, 67279620, 67282388,
- 67285155, 67287917, 67290675, 67293433, 67296185, 67298937, 67299212,
- 67301957, 67304700, 67307442, 67310183, 67312919, 67315644, 67318366,
- 67321087, 67323805, 67326518, 67329224, 67331930, 67331957, 67334652,
- 67337347, 67340039, 67342725, 67345383, 67348017, 67350646, 67353274,
- 67355896, 67358502, 67361108, 67363707, 67366305, 67368903, 67371499,
- 67374088, 67376677, 67379265, 67381850, 67384431, 67384689, 67387266,
- 67389841, 67392403, 67394964, 67397525, 67397781, 67400338, 67402890,
- 67405435, 67407979, 67410522, 67413058, 67415590, 67418115, 67420637,
- 67423158, 67423410, 67425925, 67428434, 67430942, 67433448, 67435952,
- 67438456, 67440953, 67443448, 67445941, 67446190, 67446439, 67448925,
- 67451408, 67453886, 67456359, 67458828, 67461289, 67463747, 67466201,
- 67468640, 67471077, 67473514, 67475948, 67478379, 67478622, 67481044,
- 67483466, 67485887, 67488300, 67488541, 67490945, 67493342, 67495737,
- 67498130, 67500519, 67502886, 67505248, 67507610, 67509969, 67512326,
- 67514681, 67514916, 67517263, 67519605, 67521947, 67524283, 67526618,
- 67528949, 67531278, 67533606, 67535931, 67538254, 67540576, 67542898,
- 67545217, 67547535, 67549852, 67552168, 67554484, 67556799, 67559112,
- 67561425, 67563731, 67566034, 67566057, 67568355, 67570651, 67570880,
- 67573165, 67575449, 67577733, 67580011, 67582284, 67584546, 67586803,
- 67589060, 67591315, 67593569, 67595817, 67598064, 67600303, 67602540,
- 67604776, 67607003, 67609227, 67611449, 67613666, 67615878, 67616099,
- 67618306, 67620513, 67622701, 67624888, 67627074, 67629256, 67631437,
- 67631655, 67633831, 67635996, 67636212, 67638368, 67640522, 67642669,
- 67644814, 67646957, 67649094, 67651228, 67653359, 67655488, 67657613,
- 67659737, 67659949, 67660161, 67662279, 67664392, 67666501, 67668609,
- 67670712, 67670733, 67672832, 67674930, 67677025, 67679119, 67679328,
- 67681415, 67683499, 67685582, 67685790, 67687869, 67689943, 67692016,
- 67692223, 67694292, 67696359, 67698420, 67700476, 67702531, 67704585,
- 67704790, 67706839, 67708886, 67710931, 67712976, 67715019, 67717058,
- 67719096, 67721131, 67723166, 67723369, 67725396, 67727421, 67729443,
- 67731464, 67733480, 67735496, 67737505, 67737507, 67739505, 67741499,
- 67743493, 67745487, 67747480, 67749473, 67749672, 67749871, 67751859,
- 67753842, 67755823, 67757804, 67758002, 67759979, 67761956, 67763927,
- 67765898, 67767867, 67769836, 67771802, 67773766, 67775729, 67775925,
- 67777878, 67779822, 67781765, 67783706, 67785645, 67787584, 67789521,
- 67791457, 67793391, 67795324, 67797256, 67799187, 67801112, 67803035,
- 67804948, 67805139, 67807046, 67808951, 67810850, 67812744, 67814625,
- 67814813, 67815001, 67816875, 67818748, 67820620, 67822492, 67822679,
- 67824547, 67826413, 67828276, 67830137, 67830323, 67832181, 67834039,
- 67835895, 67837751, 67839606, 67841460, 67843311, 67845160, 67847008,
- 67848856, 67850698, 67850882, 67852720, 67854558, 67856395, 67856578,
- 67858405, 67860227, 67862048, 67862230, 67862412, 67864231, 67866048,
- 67867865, 67869682, 67871486, 67873285, 67875082, 67876877, 67878672,
- 67880467, 67882261, 67884054, 67885846, 67887635, 67889422, 67891209,
- 67892994, 67894775, 67896550, 67898323, 67900092, 67901854, 67902030,
- 67903781, 67905532, 67905707, 67907456, 67909203, 67910949, 67912682,
- 67914411, 67916139, 67917864, 67919589, 67921312, 67923034, 67924755,
- 67926471, 67928182, 67928353, 67930062, 67931771, 67933479, 67935181,
- 67936882, 67936899, 67938598, 67940294, 67941990, 67943685, 67945378,
- 67947063, 67948746, 67950429, 67952112, 67953785, 67955453, 67955619,
- 67957277, 67958934, 67960587, 67962238, 67962403, 67962568, 67962733,
- 67964382, 67966030, 67967676, 67969322, 67970966, 67972608, 67974249,
- 67974413, 67976046, 67977677, 67977840, 67979467, 67981094, 67982720,
- 67984338, 67985950, 67987561, 67987722, 67989331, 67990939, 67992547,
- 67994154, 67995761, 67997368, 67998971, 68000573, 68002174, 68002190,
- 68003789, 68005388, 68006985, 68008581, 68010176, 68011768, 68013356,
- 68014940, 68016522, 68016680, 68016838, 68018416, 68019994, 68021571,
- 68023147, 68024723, 68026296, 68027868, 68029439, 68029596, 68031162,
- 68032724, 68034286, 68034442, 68034598, 68036157, 68037716, 68039273,
- 68040827, 68042380, 68043932, 68045481, 68047024, 68048567, 68050106,
- 68051641, 68051794, 68053323, 68054849, 68056374, 68057898, 68059417,
- 68060934, 68062451, 68063967, 68065480, 68066991, 68067142, 68068651,
- 68070157, 68071660, 68071675, 68071690, 68073187, 68074678, 68074827,
- 68076316, 68077805, 68079293, 68080780, 68082265, 68083750, 68085232,
- 68086713, 68088194, 68089673, 68091149, 68092623, 68094096, 68095568,
- 68095715, 68095862, 68097331, 68098796, 68100261, 68101726, 68103190,
- 68104654, 68106116, 68107575, 68109033, 68110490, 68111945, 68113396,
- 68114845, 68116294, 68117741, 68119184, 68119328, 68120765, 68122201,
- 68123633, 68125064, 68125207, 68126633, 68128059, 68129483, 68130906,
- 68132328, 68133749, 68135154, 68135168, 68136567, 68137966, 68139365,
- 68140762, 68142156, 68143550, 68144943, 68146336, 68147729, 68149120,
- 68150511, 68151902, 68152041, 68153429, 68154816, 68156203, 68157588,
- 68158970, 68160352, 68161731, 68163110, 68164486, 68165861, 68167233,
- 68167370, 68168738, 68168874, 68170229, 68171584, 68172937, 68174282,
- 68175625, 68176966, 68177100, 68177234, 68177368, 68177502, 68178839,
- 68180175, 68181511, 68182844, 68184177, 68185509, 68186838, 68188166,
- 68189493, 68190819, 68192144, 68193466, 68194788, 68196109, 68197427,
- 68198744, 68200060, 68201375, 68202688, 68204000, 68205311, 68205442,
- 68205573, 68206880, 68208187, 68209491, 68210794, 68212097, 68213398,
- 68214697, 68215996, 68217293, 68218589, 68219885, 68221180, 68222474,
- 68223766, 68223895, 68225183, 68226470, 68227755, 68229040, 68230324,
- 68231607, 68232889, 68234167, 68235443, 68236719, 68237994, 68239269,
- 68240543, 68241817, 68243090, 68244362, 68245634, 68246903, 68248172,
- 68249441, 68250709, 68251977, 68253245, 68254509, 68255772, 68257035,
- 68258296, 68259555, 68260813, 68262068, 68263322, 68264576, 68265829,
- 68267082, 68268335, 68269587, 68270836, 68272083, 68273330, 68274574,
- 68275817, 68277060, 68278302, 68279543, 68280781, 68282018, 68283253,
- 68284485, 68285714, 68286943, 68288171, 68289393, 68290615, 68291836,
- 68293055, 68294272, 68295488, 68296702, 68297916, 68299129, 68300341,
- 68300462, 68301669, 68302873, 68304077, 68305281, 68306485, 68307687,
- 68308888, 68310089, 68311290, 68311302, 68312501, 68313699, 68314897,
- 68316094, 68317291, 68318486, 68318605, 68319793, 68320981, 68322168,
- 68323354, 68324539, 68325724, 68326909, 68328093, 68329275, 68330457,
- 68331639, 68331757, 68332935, 68334112, 68335289, 68336466, 68337640,
- 68338813, 68339982, 68341148, 68342313, 68343474, 68343590, 68344749,
- 68345908, 68347065, 68348221, 68349377, 68350532, 68351686, 68352840,
- 68353992, 68354107, 68354222, 68355370, 68356516, 68357654, 68358792,
- 68359926, 68361053, 68362179, 68363301, 68364423, 68365544, 68366659,
- 68367772, 68368884, 68368995, 68369106, 68370215, 68371323, 68372430,
- 68373537, 68374643, 68375749, 68376852, 68377953, 68379052, 68380151,
- 68381249, 68382346, 68383442, 68384537, 68385632, 68386726, 68387820,
- 68388913, 68390006, 68391099, 68392191, 68393280, 68394368, 68395455,
- 68396542, 68397626, 68398710, 68399794, 68400877, 68401959, 68403041,
- 68404123, 68405204, 68406285, 68407366, 68408447, 68409528, 68409636,
- 68409744, 68410822, 68411900, 68412978, 68414051, 68415123, 68416192,
- 68417259, 68418325, 68419391, 68420452, 68421513, 68422572, 68423631,
- 68424690, 68425749, 68426808, 68427867, 68428924, 68429981, 68431037,
- 68432093, 68433147, 68434200, 68435249, 68436298, 68437346, 68438394,
- 68439442, 68440489, 68441533, 68442576, 68443619, 68444657, 68445694,
- 68446730, 68447764, 68447867, 68447970, 68448998, 68450025, 68451052,
- 68452077, 68453102, 68454125, 68455147, 68456169, 68457187, 68458205,
- 68459223, 68460241, 68461258, 68462274, 68463289, 68464303, 68465317,
- 68466329, 68466430, 68466531, 68467540, 68468548, 68469555, 68470560,
- 68471565, 68472568, 68473570, 68474572, 68475574, 68475575, 68475576,
- 68476575, 68477573, 68478570, 68479566, 68480562, 68481557, 68482551,
- 68483545, 68484539, 68484638, 68484737, 68484836, 68485825, 68486811,
- 68487796, 68488777, 68488875, 68488973, 68489952, 68490931, 68491908,
- 68492884, 68493859, 68494834, 68495809, 68496783, 68497756, 68498728,
- 68498825, 68498922, 68499890, 68500858, 68501825, 68502791, 68503757,
- 68504720, 68505683, 68506645, 68506741, 68507700, 68508658, 68509611,
- 68510562, 68511513, 68512464, 68513415, 68514366, 68515317, 68515412,
- 68515507, 68515602, 68515697, 68515792, 68515887, 68516836, 68517785,
- 68518734, 68519683, 68520631, 68521578, 68522525, 68523470, 68524413,
- 68525354, 68526295, 68527236, 68528173, 68529109, 68530045, 68530981,
- 68531915, 68532849, 68533781, 68534713, 68535645, 68536576, 68537507,
- 68537600, 68537693, 68538622, 68539550, 68540476, 68541399, 68542320,
- 68542412, 68542504, 68543423, 68544342, 68545260, 68546176, 68547092,
- 68548007, 68548922, 68549834, 68550745, 68551656, 68551747, 68552655,
- 68553560, 68554465, 68555370, 68556274, 68557177, 68558080, 68558982,
- 68559883, 68560784, 68561685, 68561694, 68562592, 68563490, 68564388,
- 68565285, 68566181, 68567077, 68567973, 68568869, 68569765, 68570659,
- 68571552, 68572444, 68573336, 68574228, 68575120, 68576011, 68576902,
- 68576991, 68577880, 68578768, 68579655, 68580541, 68581427, 68582313,
- 68583196, 68584078, 68584960, 68585841, 68585929, 68586808, 68587685,
- 68588561, 68589437, 68590313, 68591189, 68592065, 68592940, 68593027,
- 68593894, 68594760, 68595626, 68596492, 68597356, 68598218, 68599077,
- 68599936, 68600795, 68601652, 68602508, 68603363, 68604217, 68605070,
- 68605922, 68606774, 68607626, 68608477, 68608562, 68609411, 68610260,
- 68611107, 68611954, 68612800, 68613646, 68614491, 68615336, 68616179,
- 68617021, 68617862, 68618703, 68618787, 68618871, 68619710, 68620548,
- 68621386, 68622222, 68623058, 68623893, 68624728, 68625563, 68626397,
- 68627231, 68628064, 68628896, 68629728, 68630559, 68631390, 68632219,
- 68633047, 68633875, 68634702, 68635529, 68636356, 68637183, 68638009,
- 68638833, 68639656, 68640478, 68641299, 68642120, 68642202, 68643021,
- 68643840, 68644659, 68645477, 68646294, 68647111, 68647927, 68648743,
- 68649559, 68650373, 68651187, 68651998, 68652803, 68653607, 68654410,
- 68655213, 68656016, 68656818, 68657620, 68657628, 68658427, 68659226,
- 68660024, 68660822, 68661620, 68662417, 68663214, 68664010, 68664806,
- 68665601, 68666395, 68667189, 68667982, 68668774, 68669565, 68670356,
- 68671147, 68671935, 68672723, 68673509, 68674295, 68675079, 68675862,
- 68675940, 68676719, 68677498, 68678275, 68679051, 68679826, 68680601,
- 68681375, 68682149, 68682922, 68683694, 68684466, 68685237, 68685314,
- 68685391, 68686160, 68686929, 68687697, 68688464, 68689230, 68689996,
- 68690760, 68691523, 68692285, 68693046, 68693122, 68693198, 68693956,
- 68694713, 68695468, 68696222, 68696976, 68697730, 68698483, 68699235,
- 68699986, 68700737, 68701486, 68702235, 68702984, 68703732, 68704480,
- 68705226, 68705972, 68706718, 68707463, 68708208, 68708953, 68709697,
- 68710440, 68711183, 68711926, 68712667, 68713408, 68714145, 68714882,
- 68715618, 68716354, 68717090, 68717825, 68718559, 68719292, 68720024,
- 68720753, 68721482, 68722209, 68722935, 68723660, 68724384, 68725108,
- 68725832, 68726555, 68727278, 68728001, 68728723, 68728795, 68729514,
- 68730233, 68730951, 68731669, 68732385, 68733101, 68733816, 68734528,
- 68735240, 68735951, 68736022, 68736093, 68736164, 68736235, 68736944,
- 68737653, 68738362, 68739069, 68739775, 68740481, 68741187, 68741892,
- 68742597, 68743301, 68744005, 68744707, 68745409, 68746110, 68746811,
- 68746818, 68746825, 68747524, 68748223, 68748922, 68749620, 68750315,
- 68751009, 68751703, 68752397, 68753090, 68753783, 68754474, 68755165,
- 68755856, 68755925, 68755994, 68756683, 68757371, 68758059, 68758746,
- 68759433, 68760119, 68760805, 68761488, 68762171, 68762852, 68763533,
- 68764214, 68764893, 68765572, 68766251, 68766930, 68767608, 68768286,
- 68768963, 68769640, 68770316, 68770992, 68771667, 68772342, 68773015,
- 68773688, 68774360, 68775032, 68775703, 68776374, 68776441, 68777110,
- 68777777, 68778444, 68779111, 68779778, 68780444, 68781110, 68781776,
- 68782441, 68783106, 68783770, 68784432, 68785094, 68785755, 68786416,
- 68786482, 68786548, 68787207, 68787866, 68788524, 68789182, 68789840,
- 68790497, 68791154, 68791810, 68792466, 68793122, 68793777, 68794432,
- 68795087, 68795741, 68796395, 68797048, 68797700, 68798352, 68799004,
- 68799656, 68800307, 68800372, 68800437, 68801086, 68801735, 68802384,
- 68803033, 68803681, 68804329, 68804976, 68805621, 68806265, 68806908,
- 68807551, 68808194, 68808836, 68809477, 68810118, 68810759, 68811400,
- 68811464, 68811528, 68811592, 68812230, 68812868, 68813506, 68814141,
- 68814776, 68815411, 68816045, 68816679, 68817311, 68817943, 68818571,
- 68819199, 68819826, 68820452, 68821078, 68821704, 68822329, 68822954,
- 68823579, 68824203, 68824826, 68825449, 68826071, 68826133, 68826195,
- 68826257, 68826319, 68826381, 68827000, 68827619, 68828237, 68828855,
- 68829473, 68830090, 68830707, 68831323, 68831938, 68832553, 68833167,
- 68833781, 68834395, 68835008, 68835621, 68836233, 68836842, 68837450,
- 68838057, 68838663, 68839269, 68839874, 68840479, 68841084, 68841689,
- 68842293, 68842897, 68843501, 68844105, 68844708, 68845310, 68845912,
- 68845918, 68845924, 68845930, 68845936, 68846535, 68847134, 68847733,
- 68848332, 68848930, 68849527, 68850124, 68850720, 68851315, 68851909,
- 68852503, 68853096, 68853688, 68854280, 68854872, 68855464, 68856056,
- 68856115, 68856174, 68856233, 68856822, 68857411, 68858000, 68858589,
- 68859178, 68859766, 68860353, 68860939, 68861523, 68862107, 68862691,
- 68863274, 68863857, 68864438, 68865019, 68865600, 68865658, 68866237,
- 68866816, 68867395, 68867973, 68868551, 68869129, 68869706, 68870283,
- 68870860, 68871437, 68872013, 68872589, 68873164, 68873739, 68874313,
- 68874887, 68875461, 68876035, 68876609, 68877183, 68877756, 68878329,
- 68878901, 68879473, 68880045, 68880617, 68881188, 68881759, 68882328,
- 68882897, 68883465, 68884033, 68884601, 68885169, 68885735, 68886301,
- 68886865, 68887428, 68887991, 68888554, 68889116, 68889678, 68890239,
- 68890295, 68890854, 68891412, 68891969, 68892526, 68893083, 68893639,
- 68894195, 68894751, 68895307, 68895862, 68896416, 68896970, 68897524,
- 68898078, 68898631, 68899182, 68899733, 68900284, 68900835, 68901386,
- 68901937, 68902488, 68902543, 68902598, 68902653, 68902708, 68903257,
- 68903806, 68904354, 68904902, 68905450, 68905996, 68906540, 68907084,
- 68907628, 68908172, 68908716, 68909260, 68909803, 68910345, 68910887,
- 68911429, 68911971, 68912512, 68913053, 68913594, 68913648, 68914187,
- 68914725, 68915262, 68915798, 68916334, 68916870, 68917406, 68917941,
- 68918475, 68919009, 68919543, 68920076, 68920608, 68921140, 68921672,
- 68922204, 68922735, 68923266, 68923797, 68924328, 68924859, 68925390,
- 68925919, 68926448, 68926975, 68927502, 68928029, 68928555, 68929081,
- 68929606, 68930131, 68930656, 68931180, 68931703, 68932226, 68932749,
- 68933271, 68933792, 68934313, 68934365, 68934884, 68935403, 68935922,
- 68936440, 68936957, 68937474, 68937991, 68938507, 68939023, 68939538,
- 68940053, 68940567, 68941081, 68941595, 68942108, 68942621, 68943133,
- 68943645, 68944157, 68944669, 68945180, 68945231, 68945282, 68945333,
- 68945842, 68946351, 68946860, 68947369, 68947877, 68948385, 68948893,
- 68949400, 68949906, 68950412, 68950918, 68951424, 68951929, 68952434,
- 68952938, 68953441, 68953944, 68954447, 68954949, 68955450, 68955949,
- 68956448, 68956947, 68957445, 68957943, 68958441, 68958938, 68959435,
- 68959932, 68960429, 68960926, 68961422, 68961917, 68962412, 68962907,
- 68963401, 68963894, 68964387, 68964880, 68965373, 68965866, 68966359,
- 68966852, 68967345, 68967837, 68968329, 68968821, 68968870, 68968919,
- 68968968, 68969457, 68969945, 68970432, 68970919, 68971405, 68971891,
- 68972376, 68972861, 68973346, 68973831, 68974315, 68974797, 68975278,
- 68975759, 68976240, 68976288, 68976336, 68976815, 68977294, 68977772,
- 68978250, 68978727, 68979204, 68979680, 68980156, 68980632, 68981108,
- 68981583, 68982057, 68982530, 68983003, 68983475, 68983947, 68984419,
- 68984891, 68985363, 68985834, 68986305, 68986352, 68986399, 68986868,
- 68987337, 68987806, 68988275, 68988743, 68989211, 68989679, 68990147,
- 68990615, 68991082, 68991549, 68992016, 68992482, 68992948, 68993414,
- 68993879, 68994344, 68994809, 68995274, 68995739, 68996203, 68996667,
- 68997131, 68997595, 68998058, 68998521, 68998983, 68999444, 68999905,
- 69000366, 69000827, 69001288, 69001746, 69002204, 69002661, 69003118,
- 69003575, 69004032, 69004488, 69004944, 69005400, 69005855, 69006310,
- 69006765, 69007220, 69007674, 69008128, 69008582, 69009036, 69009489,
- 69009942, 69010395, 69010847, 69011299, 69011751, 69012203, 69012655,
- 69013106, 69013557, 69013602, 69013647, 69014096, 69014545, 69014993,
- 69015441, 69015889, 69016337, 69016785, 69017232, 69017679, 69018126,
- 69018573, 69019019, 69019465, 69019911, 69020357, 69020802, 69021247,
- 69021692, 69022137, 69022581, 69023025, 69023469, 69023913, 69024356,
- 69024798, 69025240, 69025682, 69026124, 69026565, 69027006, 69027447,
- 69027491, 69027929, 69028366, 69028803, 69029238, 69029673, 69030108,
- 69030543, 69030977, 69031410, 69031843, 69032275, 69032318, 69032361,
- 69032404, 69032447, 69032876, 69033305, 69033734, 69034163, 69034592,
- 69035020, 69035448, 69035876, 69036302, 69036727, 69037152, 69037577,
- 69038002, 69038427, 69038852, 69039276, 69039699, 69040121, 69040543,
- 69040964, 69041385, 69041806, 69042227, 69042648, 69042690, 69043109,
- 69043528, 69043947, 69044366, 69044785, 69045203, 69045619, 69046034,
- 69046449, 69046863, 69047275, 69047687, 69048099, 69048511, 69048923,
- 69049335, 69049746, 69050157, 69050198, 69050239, 69050280, 69050689,
- 69051098, 69051507, 69051916, 69052323, 69052730, 69053137, 69053544,
- 69053950, 69054356, 69054761, 69055166, 69055570, 69055974, 69056377,
- 69056780, 69057183, 69057586, 69057989, 69058392, 69058795, 69059197,
- 69059599, 69060000, 69060401, 69060802, 69061203, 69061600, 69061997,
- 69062394, 69062790, 69063186, 69063582, 69063978, 69064373, 69064768,
- 69065163, 69065558, 69065953, 69066348, 69066742, 69067136, 69067530,
- 69067924, 69068317, 69068710, 69069102, 69069493, 69069884, 69070275,
- 69070314, 69070353, 69070392, 69070431, 69070820, 69071209, 69071597,
- 69071985, 69072373, 69072760, 69073146, 69073531, 69073916, 69074301,
- 69074685, 69075069, 69075453, 69075836, 69076219, 69076602, 69076984,
- 69077365, 69077746, 69078127, 69078165, 69078203, 69078241, 69078620,
- 69078999, 69079378, 69079757, 69080136, 69080514, 69080892, 69081270,
- 69081648, 69082026, 69082404, 69082782, 69083160, 69083538, 69083915,
- 69084292, 69084669, 69085046, 69085422, 69085798, 69086174, 69086550,
- 69086925, 69087300, 69087675, 69088050, 69088424, 69088798, 69089172,
- 69089545, 69089918, 69090291, 69090664, 69091037, 69091409, 69091781,
- 69092153, 69092525, 69092896, 69093267, 69093638, 69094009, 69094046,
- 69094083, 69094120, 69094157, 69094194, 69094231, 69094600, 69094969,
- 69095337, 69095705, 69096073, 69096441, 69096809, 69097177, 69097545,
- 69097912, 69098279, 69098645, 69099011, 69099377, 69099742, 69100107,
- 69100472, 69100837, 69101201, 69101565, 69101928, 69102291, 69102654,
- 69103016, 69103378, 69103740, 69104101, 69104462, 69104823, 69105184,
- 69105220, 69105256, 69105292, 69105651, 69106010, 69106369, 69106728,
- 69107087, 69107446, 69107805, 69108163, 69108521, 69108879, 69109237,
- 69109595, 69109952, 69110309, 69110666, 69111023, 69111380, 69111736,
- 69112092, 69112448, 69112803, 69113158, 69113513, 69113867, 69114221,
- 69114574, 69114927, 69115280, 69115633, 69115985, 69116337, 69116689,
- 69117040, 69117075, 69117110, 69117145, 69117180, 69117215, 69117564,
- 69117913, 69118262, 69118611, 69118959, 69119307, 69119654, 69120001,
- 69120348, 69120695, 69121041, 69121387, 69121733, 69122078, 69122422,
- 69122766, 69123109, 69123452, 69123794, 69124136, 69124478, 69124819,
- 69125160, 69125501, 69125842, 69126183, 69126217, 69126251, 69126285,
- 69126319, 69126353, 69126692, 69127031, 69127370, 69127709, 69128047,
- 69128385, 69128723, 69129060, 69129397, 69129734, 69130070, 69130406,
- 69130742, 69131077, 69131411, 69131745, 69132079, 69132413, 69132746,
- 69133079, 69133411, 69133743, 69134075, 69134406, 69134737, 69135068,
- 69135101, 69135134, 69135167, 69135200, 69135233, 69135266, 69135299,
- 69135628, 69135957, 69136286, 69136615, 69136944, 69137272, 69137600,
- 69137927, 69138254, 69138581, 69138908, 69139234, 69139560, 69139886,
- 69140212, 69140538, 69140863, 69141188, 69141513, 69141838, 69142162,
- 69142486, 69142810, 69143134, 69143457, 69143780, 69144103, 69144425,
- 69144747, 69145069, 69145391, 69145713, 69146034, 69146355, 69146676,
- 69146997, 69147029, 69147061, 69147093, 69147125, 69147157, 69147476,
- 69147794, 69148112, 69148430, 69148748, 69149066, 69149383, 69149700,
- 69150017, 69150334, 69150650, 69150966, 69151281, 69151596, 69151911,
- 69152226, 69152540, 69152854, 69153168, 69153482, 69153796, 69154110,
- 69154422, 69154734, 69155046, 69155358, 69155670, 69155981, 69156292,
- 69156603, 69156634, 69156665, 69156696, 69157005, 69157314, 69157623,
- 69157932, 69158240, 69158548, 69158856, 69159164, 69159472, 69159780,
- 69160087, 69160394, 69160701, 69161007, 69161313, 69161619, 69161925,
- 69162230, 69162535, 69162840, 69163145, 69163449, 69163753, 69164057,
- 69164360, 69164663, 69164966, 69165269, 69165572, 69165875, 69166177,
- 69166479, 69166781, 69167083, 69167385, 69167687, 69167989, 69168291,
- 69168593, 69168895, 69169196, 69169497, 69169798, 69170099, 69170400,
- 69170701, 69170704, 69170707, 69170710, 69171009, 69171308, 69171607,
- 69171905, 69172203, 69172501, 69172798, 69173095, 69173392, 69173688,
- 69173984, 69174280, 69174576, 69174872, 69175168, 69175463, 69175758,
- 69176053, 69176348, 69176643, 69176938, 69177233, 69177528, 69177823,
- 69178117, 69178411, 69178704, 69178997, 69179290, 69179583, 69179876,
- 69180168, 69180460, 69180752, 69181044, 69181335, 69181364, 69181393,
- 69181682, 69181971, 69182260, 69182548, 69182836, 69183124, 69183412,
- 69183700, 69183988, 69184276, 69184563, 69184850, 69185137, 69185424,
- 69185711, 69185998, 69186284, 69186570, 69186856, 69187142, 69187428,
- 69187713, 69187998, 69188283, 69188568, 69188853, 69189138, 69189423,
- 69189708, 69189993, 69190277, 69190561, 69190845, 69191128, 69191411,
- 69191693, 69191975, 69192257, 69192539, 69192820, 69193101, 69193382,
- 69193663, 69193944, 69194225, 69194506, 69194534, 69194562, 69194590,
- 69194869, 69195148, 69195427, 69195706, 69195985, 69196264, 69196542,
- 69196820, 69197098, 69197376, 69197653, 69197930, 69198207, 69198484,
- 69198761, 69199038, 69199314, 69199590, 69199866, 69200140, 69200414,
- 69200688, 69200962, 69201235, 69201508, 69201781, 69202054, 69202326,
- 69202598, 69202870, 69203142, 69203414, 69203686, 69203958, 69204230,
- 69204501, 69204772, 69205043, 69205314, 69205341, 69205368, 69205395,
- 69205422, 69205449, 69205718, 69205987, 69206256, 69206525, 69206794,
- 69207063, 69207332, 69207601, 69207869, 69208137, 69208405, 69208672,
- 69208939, 69209206, 69209473, 69209740, 69210006, 69210272, 69210538,
- 69210804, 69211070, 69211336, 69211602, 69211867, 69212132, 69212397,
- 69212662, 69212927, 69213191, 69213455, 69213719, 69213983, 69214247,
- 69214511, 69214775, 69215038, 69215301, 69215564, 69215827, 69216089,
- 69216351, 69216613, 69216875, 69217136, 69217397, 69217658, 69217919,
- 69218180, 69218441, 69218702, 69218963, 69218989, 69219015, 69219041,
- 69219067, 69219093, 69219352, 69219611, 69219870, 69220129, 69220387,
- 69220645, 69220903, 69221161, 69221419, 69221677, 69221935, 69222193,
- 69222450, 69222707, 69222964, 69223221, 69223478, 69223735, 69223991,
- 69224247, 69224502, 69224757, 69225012, 69225267, 69225522, 69225777,
- 69226032, 69226287, 69226542, 69226797, 69227051, 69227305, 69227559,
- 69227812, 69228065, 69228318, 69228571, 69228824, 69229077, 69229330,
- 69229582, 69229834, 69230086, 69230338, 69230590, 69230842, 69231094,
- 69231346, 69231597, 69231848, 69232099, 69232350, 69232601, 69232852,
- 69232877, 69232902, 69232927, 69232952, 69232977, 69233002, 69233251,
- 69233500, 69233748, 69233996, 69234244, 69234492, 69234739, 69234986,
- 69235233, 69235480, 69235727, 69235974, 69236220, 69236466, 69236711,
- 69236956, 69237201, 69237446, 69237690, 69237934, 69238178, 69238421,
- 69238663, 69238905, 69239147, 69239389, 69239631, 69239873, 69240114,
- 69240355, 69240596, 69240837, 69241078, 69241319, 69241560, 69241801,
- 69241825, 69241849, 69241873, 69241897, 69241921, 69241945, 69242184,
- 69242423, 69242662, 69242901, 69243140, 69243379, 69243618, 69243856,
- 69244094, 69244332, 69244570, 69244808, 69245045, 69245282, 69245519,
- 69245756, 69245992, 69246228, 69246463, 69246698, 69246933, 69247168,
- 69247403, 69247637, 69247871, 69248105, 69248339, 69248573, 69248807,
- 69249041, 69249275, 69249509, 69249742, 69249975, 69250208, 69250441,
- 69250674, 69250907, 69251140, 69251372, 69251604, 69251836, 69252068,
- 69252300, 69252532, 69252764, 69252996, 69253228, 69253460, 69253692,
- 69253924, 69254155, 69254386, 69254617, 69254848, 69255079, 69255310,
- 69255541, 69255772, 69256003, 69256234, 69256257, 69256280, 69256303,
- 69256326, 69256349, 69256372, 69256395, 69256418, 69256647, 69256876,
- 69257105, 69257333, 69257561, 69257789, 69258016, 69258243, 69258470,
- 69258697, 69258924, 69259150, 69259376, 69259602, 69259828, 69260054,
- 69260279, 69260504, 69260729, 69260954, 69261179, 69261404, 69261629,
- 69261853, 69262077, 69262301, 69262525, 69262749, 69262973, 69263196,
- 69263419, 69263642, 69263865, 69264088, 69264311, 69264534, 69264757,
- 69264979, 69265201, 69265423, 69265645, 69265867, 69266089, 69266311,
- 69266533, 69266754, 69266975, 69267196, 69267417, 69267439, 69267461,
- 69267483, 69267505, 69267527, 69267549, 69267768, 69267987, 69268206,
- 69268424, 69268642, 69268860, 69269077, 69269294, 69269511, 69269728,
- 69269944, 69270160, 69270376, 69270592, 69270808, 69271024, 69271240,
- 69271456, 69271672, 69271887, 69272102, 69272317, 69272532, 69272747,
- 69272962, 69273176, 69273390, 69273604, 69273818, 69274032, 69274246,
- 69274460, 69274674, 69274888, 69275101, 69275314, 69275527, 69275740,
- 69275953, 69276166, 69276379, 69276592, 69276805, 69277018, 69277231,
- 69277443, 69277655, 69277867, 69278078, 69278289, 69278500, 69278711,
- 69278922, 69279133, 69279344, 69279555, 69279766, 69279977, 69279998,
- 69280019, 69280040, 69280061, 69280082, 69280103, 69280312, 69280521,
- 69280730, 69280939, 69281148, 69281356, 69281564, 69281772, 69281980,
- 69282188, 69282396, 69282604, 69282812, 69283020, 69283228, 69283435,
- 69283642, 69283849, 69284056, 69284263, 69284470, 69284676, 69284882,
- 69285087, 69285291, 69285495, 69285698, 69285901, 69286104, 69286307,
- 69286510, 69286713, 69286915, 69287117, 69287319, 69287521, 69287723,
- 69287925, 69288127, 69288329, 69288531, 69288732, 69288933, 69289134,
- 69289335, 69289536, 69289737, 69289938, 69290139, 69290141, 69290143,
- 69290342, 69290541, 69290740, 69290939, 69291138, 69291337, 69291535,
- 69291733, 69291931, 69292128, 69292325, 69292522, 69292719, 69292916,
- 69293113, 69293310, 69293507, 69293703, 69293899, 69294095, 69294291,
- 69294487, 69294683, 69294879, 69295075, 69295270, 69295465, 69295660,
- 69295855, 69296050, 69296245, 69296440, 69296635, 69296830, 69297024,
- 69297218, 69297412, 69297606, 69297800, 69297994, 69298188, 69298381,
- 69298574, 69298767, 69298960, 69299153, 69299346, 69299539, 69299731,
- 69299923, 69300115, 69300307, 69300498, 69300689, 69300880, 69301071,
- 69301262, 69301453, 69301644, 69301835, 69302026, 69302217, 69302236,
- 69302255, 69302274, 69302293, 69302312, 69302501, 69302690, 69302879,
- 69303068, 69303257, 69303446, 69303635, 69303823, 69304011, 69304199,
- 69304387, 69304575, 69304763, 69304951, 69305139, 69305327, 69305514,
- 69305701, 69305888, 69306075, 69306262, 69306449, 69306636, 69306823,
- 69307009, 69307195, 69307381, 69307567, 69307753, 69307939, 69308125,
- 69308310, 69308495, 69308680, 69308865, 69309050, 69309235, 69309420,
- 69309604, 69309788, 69309972, 69310156, 69310340, 69310524, 69310708,
- 69310892, 69311076, 69311260, 69311444, 69311628, 69311811, 69311994,
- 69312177, 69312360, 69312543, 69312726, 69312909, 69313092, 69313275,
- 69313458, 69313641, 69313823, 69314005, 69314187, 69314369, 69314551,
- 69314733, 69314915, 69315097, 69315279, 69315460, 69315478, 69315496,
- 69315514, 69315532, 69315550, 69315568, 69315586, 69315604, 69315783,
- 69315962, 69316141, 69316320, 69316499, 69316678, 69316857, 69317036,
- 69317215, 69317393, 69317571, 69317749, 69317927, 69318105, 69318283,
- 69318461, 69318639, 69318817, 69318995, 69319173, 69319351, 69319528,
- 69319705, 69319882, 69320059, 69320236, 69320413, 69320590, 69320767,
- 69320944, 69321121, 69321298, 69321475, 69321651, 69321827, 69322003,
- 69322178, 69322353, 69322528, 69322703, 69322878, 69323053, 69323228,
- 69323403, 69323578, 69323752, 69323926, 69324100, 69324274, 69324448,
- 69324622, 69324796, 69324970, 69325144, 69325318, 69325491, 69325664,
- 69325837, 69326010, 69326183, 69326356, 69326529, 69326702, 69326875,
- 69327048, 69327221, 69327393, 69327565, 69327737, 69327909, 69328081,
- 69328253, 69328425, 69328596, 69328767, 69328938, 69329109, 69329280,
- 69329451, 69329622, 69329793, 69329964, 69329981, 69329998, 69330015,
- 69330032, 69330049, 69330066, 69330083, 69330100, 69330117, 69330286,
- 69330455, 69330624, 69330793, 69330962, 69331131, 69331300, 69331468,
- 69331636, 69331804, 69331972, 69332139, 69332306, 69332473, 69332640,
- 69332807, 69332974, 69333140, 69333306, 69333472, 69333638, 69333804,
- 69333970, 69334136, 69334301, 69334466, 69334631, 69334796, 69334961,
- 69335126, 69335291, 69335456, 69335621, 69335786, 69335951, 69336116,
- 69336281, 69336446, 69336611, 69336775, 69336939, 69337103, 69337267,
- 69337431, 69337595, 69337759, 69337922, 69338085, 69338248, 69338411,
- 69338574, 69338736, 69338898, 69339060, 69339222, 69339384, 69339546,
- 69339708, 69339870, 69340032, 69340194, 69340356, 69340518, 69340680,
- 69340841, 69341002, 69341163, 69341324, 69341485, 69341646, 69341807,
- 69341968, 69342129, 69342290, 69342306, 69342322, 69342338, 69342354,
- 69342370, 69342386, 69342402, 69342418, 69342434, 69342593, 69342752,
- 69342911, 69343070, 69343229, 69343388, 69343547, 69343705, 69343863,
- 69344021, 69344179, 69344337, 69344495, 69344652, 69344809, 69344966,
- 69345123, 69345280, 69345437, 69345594, 69345751, 69345908, 69346065,
- 69346222, 69346378, 69346534, 69346690, 69346846, 69347002, 69347158,
- 69347314, 69347470, 69347626, 69347782, 69347938, 69348094, 69348249,
- 69348404, 69348559, 69348714, 69348869, 69349024, 69349179, 69349334,
- 69349489, 69349644, 69349798, 69349952, 69350106, 69350260, 69350414,
- 69350568, 69350722, 69350876, 69351030, 69351184, 69351338, 69351492,
- 69351646, 69351800, 69351953, 69352106, 69352259, 69352412, 69352565,
- 69352718, 69352871, 69353023, 69353175, 69353327, 69353479, 69353631,
- 69353783, 69353935, 69354087, 69354238, 69354389, 69354540, 69354691,
- 69354842, 69354993, 69355144, 69355159, 69355174, 69355189, 69355204,
- 69355219, 69355234, 69355249, 69355264, 69355279, 69355428, 69355577,
- 69355726, 69355875, 69356024, 69356173, 69356322, 69356471, 69356620,
- 69356769, 69356918, 69357067, 69357216, 69357365, 69357514, 69357663,
- 69357811, 69357959, 69358107, 69358255, 69358403, 69358551, 69358699,
- 69358847, 69358994, 69359141, 69359288, 69359435, 69359582, 69359729,
- 69359876, 69360023, 69360170, 69360317, 69360464, 69360611, 69360758,
- 69360905, 69361052, 69361199, 69361346, 69361492, 69361638, 69361784,
- 69361930, 69362076, 69362222, 69362368, 69362514, 69362659, 69362804,
- 69362949, 69363094, 69363239, 69363384, 69363529, 69363674, 69363819,
- 69363964, 69364109, 69364254, 69364399, 69364543, 69364687, 69364831,
- 69364975, 69365119, 69365263, 69365407, 69365551, 69365695, 69365839,
- 69365983, 69366126, 69366269, 69366412, 69366555, 69366698, 69366841,
- 69366984, 69367127, 69367269, 69367411, 69367553, 69367695, 69367837,
- 69367979, 69368121, 69368263, 69368405, 69368547, 69368688, 69368829,
- 69368970, 69369111, 69369252, 69369393, 69369534, 69369675, 69369816,
- 69369957, 69370098, 69370112, 69370126, 69370140, 69370154, 69370168,
- 69370182, 69370196, 69370335, 69370474, 69370613, 69370752, 69370891,
- 69371030, 69371169, 69371308, 69371447, 69371585, 69371723, 69371861,
- 69371999, 69372137, 69372275, 69372412, 69372549, 69372686, 69372823,
- 69372960, 69373097, 69373234, 69373371, 69373508, 69373645, 69373782,
- 69373919, 69374056, 69374193, 69374330, 69374467, 69374604, 69374741,
- 69374878, 69375015, 69375151, 69375287, 69375423, 69375559, 69375695,
- 69375831, 69375967, 69376103, 69376239, 69376375, 69376511, 69376646,
- 69376781, 69376916, 69377051, 69377186, 69377321, 69377456, 69377591,
- 69377726, 69377861, 69377996, 69378131, 69378266, 69378400, 69378534,
- 69378668, 69378802, 69378936, 69379070, 69379204, 69379338, 69379472,
- 69379605, 69379738, 69379871, 69380004, 69380137, 69380270, 69380403,
- 69380536, 69380669, 69380802, 69380935, 69381067, 69381199, 69381331,
- 69381463, 69381595, 69381727, 69381859, 69381990, 69382121, 69382252,
- 69382383, 69382514, 69382645, 69382776, 69382907, 69383038, 69383051,
- 69383064, 69383077, 69383090, 69383103, 69383116, 69383129, 69383142,
- 69383155, 69383168, 69383181, 69383194, 69383207, 69383336, 69383465,
- 69383594, 69383723, 69383852, 69383981, 69384110, 69384239, 69384368,
- 69384497, 69384625, 69384753, 69384881, 69385009, 69385137, 69385265,
- 69385392, 69385519, 69385646, 69385773, 69385900, 69386027, 69386154,
- 69386281, 69386408, 69386535, 69386662, 69386789, 69386915, 69387041,
- 69387167, 69387293, 69387419, 69387545, 69387671, 69387797, 69387923,
- 69388049, 69388175, 69388301, 69388427, 69388553, 69388678, 69388803,
- 69388928, 69389053, 69389178, 69389303, 69389428, 69389553, 69389678,
- 69389803, 69389928, 69390053, 69390178, 69390303, 69390428, 69390553,
- 69390678, 69390803, 69390927, 69391051, 69391175, 69391299, 69391423,
- 69391547, 69391671, 69391795, 69391919, 69392042, 69392165, 69392288,
- 69392411, 69392534, 69392657, 69392780, 69392903, 69393026, 69393149,
- 69393272, 69393395, 69393518, 69393640, 69393762, 69393884, 69394006,
- 69394128, 69394250, 69394372, 69394494, 69394616, 69394738, 69394860,
- 69394982, 69395104, 69395225, 69395346, 69395467, 69395588, 69395709,
- 69395830, 69395951, 69396072, 69396193, 69396314, 69396435, 69396556,
- 69396677, 69396798, 69396810, 69396822, 69396834, 69396846, 69396858,
- 69396870, 69396989, 69397108, 69397227, 69397346, 69397465, 69397584,
- 69397703, 69397822, 69397941, 69398060, 69398179, 69398297, 69398415,
- 69398533, 69398651, 69398769, 69398887, 69399005, 69399123, 69399241,
- 69399359, 69399477, 69399595, 69399712, 69399829, 69399946, 69400063,
- 69400180, 69400297, 69400414, 69400531, 69400648, 69400765, 69400882,
- 69400998, 69401114, 69401230, 69401346, 69401462, 69401578, 69401694,
- 69401810, 69401926, 69402042, 69402158, 69402273, 69402388, 69402503,
- 69402618, 69402733, 69402848, 69402963, 69403078, 69403193, 69403308,
- 69403422, 69403536, 69403650, 69403764, 69403878, 69403992, 69404106,
- 69404220, 69404334, 69404447, 69404560, 69404673, 69404786, 69404899,
- 69405012, 69405125, 69405238, 69405351, 69405464, 69405577, 69405690,
- 69405803, 69405915, 69406027, 69406139, 69406251, 69406363, 69406475,
- 69406587, 69406699, 69406811, 69406923, 69407035, 69407147, 69407259,
- 69407371, 69407483, 69407595, 69407707, 69407818, 69407929, 69408040,
- 69408151, 69408262, 69408373, 69408484, 69408595, 69408706, 69408817,
- 69408928, 69409039, 69409150, 69409161, 69409172, 69409183, 69409194,
- 69409205, 69409216, 69409227, 69409238, 69409347, 69409456, 69409565,
- 69409674, 69409783, 69409892, 69410001, 69410110, 69410219, 69410328,
- 69410437, 69410546, 69410655, 69410764, 69410873, 69410982, 69411091,
- 69411200, 69411309, 69411418, 69411526, 69411634, 69411742, 69411850,
- 69411958, 69412066, 69412174, 69412282, 69412390, 69412498, 69412606,
- 69412714, 69412822, 69412930, 69413037, 69413144, 69413251, 69413358,
- 69413465, 69413572, 69413679, 69413786, 69413893, 69414000, 69414106,
- 69414212, 69414318, 69414424, 69414530, 69414636, 69414742, 69414848,
- 69414954, 69415060, 69415166, 69415272, 69415378, 69415483, 69415588,
- 69415693, 69415798, 69415903, 69416008, 69416113, 69416218, 69416323,
- 69416428, 69416533, 69416638, 69416743, 69416847, 69416951, 69417055,
- 69417159, 69417263, 69417367, 69417471, 69417575, 69417679, 69417783,
- 69417887, 69417991, 69418095, 69418198, 69418301, 69418404, 69418507,
- 69418610, 69418713, 69418816, 69418919, 69419022, 69419125, 69419228,
- 69419331, 69419433, 69419535, 69419637, 69419739, 69419841, 69419943,
- 69420045, 69420147, 69420249, 69420351, 69420453, 69420555, 69420657,
- 69420759, 69420860, 69420961, 69421062, 69421163, 69421264, 69421365,
- 69421466, 69421567, 69421668, 69421769, 69421870, 69421971, 69422072,
- 69422173, 69422274, 69422375, 69422376, 69422377, 69422378, 69422379,
- 69422380, 69422381, 69422382, 69422383, 69422384, 69422385, 69422386,
- 69422387, 69422388, 69422389, 69422390, 69422391, 69422490, 69422589,
- 69422688, 69422787, 69422886, 69422985, 69423084, 69423183, 69423282,
- 69423381, 69423480, 69423579, 69423678, 69423777, 69423876, 69423975,
- 69424073, 69424171, 69424269, 69424367, 69424465, 69424563, 69424661,
- 69424759, 69424857, 69424954, 69425051, 69425148, 69425245, 69425342,
- 69425439, 69425536, 69425633, 69425730, 69425827, 69425924, 69426021,
- 69426118, 69426214, 69426310, 69426406, 69426502, 69426598, 69426694,
- 69426790, 69426886, 69426982, 69427078, 69427174, 69427270, 69427366,
- 69427462, 69427558, 69427653, 69427748, 69427843, 69427938, 69428033,
- 69428128, 69428223, 69428318, 69428413, 69428508, 69428603, 69428698,
- 69428793, 69428888, 69428982, 69429076, 69429170, 69429264, 69429358,
- 69429452, 69429546, 69429640, 69429734, 69429828, 69429922, 69430016,
- 69430110, 69430204, 69430298, 69430392, 69430486, 69430580, 69430673,
- 69430766, 69430859, 69430952, 69431045, 69431138, 69431231, 69431324,
- 69431417, 69431510, 69431603, 69431696, 69431789, 69431882, 69431975,
- 69432068, 69432161, 69432254, 69432347, 69432439, 69432531, 69432623,
- 69432715, 69432807, 69432899, 69432991, 69433083, 69433175, 69433267,
- 69433359, 69433450, 69433541, 69433632, 69433723, 69433814, 69433905,
- 69433996, 69434087, 69434178, 69434269, 69434360, 69434451, 69434542,
- 69434633, 69434724, 69434733, 69434742, 69434751, 69434760, 69434769,
- 69434778, 69434787, 69434796, 69434805, 69434814, 69434823, 69434912,
- 69435001, 69435090, 69435179, 69435268, 69435357, 69435446, 69435535,
- 69435624, 69435713, 69435801, 69435889, 69435977, 69436065, 69436153,
- 69436241, 69436329, 69436417, 69436505, 69436593, 69436681, 69436769,
- 69436857, 69436944, 69437031, 69437118, 69437205, 69437292, 69437379,
- 69437466, 69437553, 69437640, 69437727, 69437814, 69437901, 69437988,
- 69438075, 69438161, 69438247, 69438333, 69438419, 69438505, 69438591,
- 69438677, 69438763, 69438849, 69438935, 69439021, 69439107, 69439193,
- 69439278, 69439363, 69439448, 69439533, 69439618, 69439703, 69439788,
- 69439873, 69439958, 69440043, 69440128, 69440213, 69440298, 69440382,
- 69440466, 69440550, 69440634, 69440718, 69440802, 69440886, 69440970,
- 69441054, 69441138, 69441222, 69441306, 69441390, 69441474, 69441557,
- 69441640, 69441723, 69441806, 69441889, 69441972, 69442055, 69442138,
- 69442221, 69442304, 69442387, 69442470, 69442553, 69442636, 69442719,
- 69442802, 69442885, 69442967, 69443049, 69443131, 69443213, 69443295,
- 69443377, 69443459, 69443541, 69443623, 69443705, 69443787, 69443869,
- 69443951, 69444033, 69444115, 69444197, 69444279, 69444361, 69444443,
- 69444524, 69444605, 69444686, 69444767, 69444848, 69444929, 69445010,
- 69445091, 69445172, 69445253, 69445334, 69445415, 69445496, 69445577,
- 69445585, 69445593, 69445601, 69445609, 69445617, 69445625, 69445633,
- 69445641, 69445649, 69445657, 69445665, 69445673, 69445681, 69445689,
- 69445697, 69445705, 69445713, 69445721, 69445729, 69445737, 69445816,
- 69445895, 69445974, 69446053, 69446132, 69446211, 69446290, 69446369,
- 69446448, 69446527, 69446606, 69446685, 69446764, 69446843, 69446922,
- 69447001, 69447080, 69447159, 69447238, 69447317, 69447396, 69447475,
- 69447553, 69447631, 69447709, 69447787, 69447865, 69447943, 69448021,
- 69448099, 69448177, 69448255, 69448333, 69448411, 69448489, 69448567,
- 69448645, 69448722, 69448799, 69448876, 69448953, 69449030, 69449107,
- 69449184, 69449261, 69449338, 69449415, 69449492, 69449569, 69449646,
- 69449723, 69449800, 69449876, 69449952, 69450028, 69450104, 69450180,
- 69450256, 69450332, 69450408, 69450484, 69450560, 69450636, 69450712,
- 69450788, 69450864, 69450940, 69451016, 69451092, 69451168, 69451244,
- 69451320, 69451395, 69451470, 69451545, 69451620, 69451695, 69451770,
- 69451845, 69451920, 69451995, 69452070, 69452145, 69452220, 69452295,
- 69452370, 69452445, 69452520, 69452595, 69452670, 69452745, 69452820,
- 69452895, 69452970, 69453044, 69453118, 69453192, 69453266, 69453340,
- 69453414, 69453488, 69453562, 69453636, 69453710, 69453784, 69453858,
- 69453932, 69454006, 69454080, 69454154, 69454228, 69454302, 69454376,
- 69454450, 69454524, 69454598, 69454671, 69454744, 69454817, 69454890,
- 69454963, 69455036, 69455109, 69455182, 69455255, 69455328, 69455401,
- 69455474, 69455547, 69455620, 69455693, 69455766, 69455839, 69455912,
- 69455985, 69456058, 69456130, 69456202, 69456274, 69456346, 69456418,
- 69456490, 69456562, 69456634, 69456706, 69456778, 69456850, 69456922,
- 69456994, 69457066, 69457138, 69457210, 69457281, 69457352, 69457423,
- 69457494, 69457565, 69457636, 69457707, 69457778, 69457849, 69457920,
- 69457991, 69458062, 69458133, 69458204, 69458275, 69458346, 69458417,
- 69458488, 69458559, 69458630, 69458701, 69458772, 69458843, 69458850,
- 69458857, 69458864, 69458871, 69458878, 69458885, 69458892, 69458899,
- 69458906, 69458913, 69458920, 69458927, 69458934, 69458941, 69459010,
- 69459079, 69459148, 69459217, 69459286, 69459355, 69459424, 69459493,
- 69459562, 69459631, 69459700, 69459769, 69459838, 69459907, 69459976,
- 69460045, 69460114, 69460183, 69460252, 69460321, 69460390, 69460459,
- 69460528, 69460596, 69460664, 69460732, 69460800, 69460868, 69460936};
- System.arraycopy(temp, 0, prob, 0, temp.length);
- }
-
- private static void populateProb2() {
- int[] temp = new int[] {
- 69461004, 69461072, 69461140, 69461208, 69461276, 69461344, 69461412,
- 69461480, 69461548, 69461616, 69461684, 69461751, 69461818, 69461885,
- 69461952, 69462019, 69462086, 69462153, 69462220, 69462287, 69462354,
- 69462421, 69462488, 69462555, 69462622, 69462689, 69462756, 69462823,
- 69462889, 69462955, 69463021, 69463087, 69463153, 69463219, 69463285,
- 69463351, 69463417, 69463483, 69463549, 69463615, 69463681, 69463747,
- 69463813, 69463879, 69463945, 69464011, 69464077, 69464143, 69464209,
- 69464275, 69464341, 69464407, 69464473, 69464539, 69464605, 69464670,
- 69464735, 69464800, 69464865, 69464930, 69464995, 69465060, 69465125,
- 69465190, 69465255, 69465320, 69465385, 69465450, 69465515, 69465580,
- 69465645, 69465710, 69465775, 69465840, 69465905, 69465969, 69466033,
- 69466097, 69466161, 69466225, 69466289, 69466353, 69466417, 69466481,
- 69466545, 69466609, 69466673, 69466737, 69466801, 69466864, 69466927,
- 69466990, 69467053, 69467116, 69467179, 69467242, 69467305, 69467368,
- 69467431, 69467494, 69467557, 69467620, 69467683, 69467746, 69467809,
- 69467872, 69467935, 69467998, 69468061, 69468124, 69468187, 69468250,
- 69468313, 69468375, 69468437, 69468499, 69468561, 69468623, 69468685,
- 69468747, 69468809, 69468871, 69468933, 69468995, 69469057, 69469119,
- 69469181, 69469243, 69469305, 69469366, 69469427, 69469488, 69469549,
- 69469610, 69469671, 69469732, 69469793, 69469854, 69469915, 69469976,
- 69470037, 69470098, 69470159, 69470220, 69470281, 69470342, 69470403,
- 69470464, 69470525, 69470586, 69470647, 69470708, 69470714, 69470720,
- 69470726, 69470732, 69470738, 69470744, 69470750, 69470756, 69470762,
- 69470768, 69470774, 69470780, 69470786, 69470792, 69470798, 69470804,
- 69470810, 69470816, 69470822, 69470828, 69470834, 69470840, 69470846,
- 69470852, 69470858, 69470864, 69470870, 69470876, 69470882, 69470888,
- 69470894, 69470900, 69470959, 69471018, 69471077, 69471136, 69471195,
- 69471254, 69471313, 69471372, 69471431, 69471490, 69471549, 69471608,
- 69471667, 69471726, 69471785, 69471844, 69471903, 69471962, 69472021,
- 69472080, 69472139, 69472197, 69472255, 69472313, 69472371, 69472429,
- 69472487, 69472545, 69472603, 69472661, 69472719, 69472777, 69472835,
- 69472893, 69472951, 69473009, 69473067, 69473125, 69473183, 69473241,
- 69473299, 69473357, 69473415, 69473473, 69473531, 69473589, 69473647,
- 69473705, 69473762, 69473819, 69473876, 69473933, 69473990, 69474047,
- 69474104, 69474161, 69474218, 69474275, 69474332, 69474389, 69474446,
- 69474503, 69474560, 69474617, 69474674, 69474731, 69474788, 69474845,
- 69474902, 69474959, 69475016, 69475072, 69475128, 69475184, 69475240,
- 69475296, 69475352, 69475408, 69475464, 69475520, 69475576, 69475632,
- 69475688, 69475744, 69475800, 69475856, 69475912, 69475968, 69476024,
- 69476080, 69476136, 69476192, 69476248, 69476304, 69476360, 69476416,
- 69476471, 69476526, 69476581, 69476636, 69476691, 69476746, 69476801,
- 69476856, 69476911, 69476966, 69477021, 69477076, 69477131, 69477186,
- 69477241, 69477296, 69477351, 69477406, 69477461, 69477516, 69477571,
- 69477626, 69477681, 69477736, 69477791, 69477846, 69477901, 69477956,
- 69478010, 69478064, 69478118, 69478172, 69478226, 69478280, 69478334,
- 69478388, 69478442, 69478496, 69478550, 69478604, 69478658, 69478712,
- 69478766, 69478820, 69478874, 69478928, 69478982, 69479036, 69479090,
- 69479144, 69479197, 69479250, 69479303, 69479356, 69479409, 69479462,
- 69479515, 69479568, 69479621, 69479674, 69479727, 69479780, 69479833,
- 69479886, 69479939, 69479992, 69480045, 69480098, 69480151, 69480204,
- 69480257, 69480310, 69480363, 69480416, 69480468, 69480520, 69480572,
- 69480624, 69480676, 69480728, 69480780, 69480832, 69480884, 69480936,
- 69480988, 69481040, 69481092, 69481144, 69481196, 69481248, 69481300,
- 69481352, 69481404, 69481456, 69481508, 69481560, 69481612, 69481664,
- 69481716, 69481768, 69481820, 69481872, 69481924, 69481976, 69482028,
- 69482080, 69482132, 69482184, 69482236, 69482288, 69482339, 69482390,
- 69482441, 69482492, 69482543, 69482594, 69482645, 69482696, 69482747,
- 69482798, 69482849, 69482900, 69482951, 69483002, 69483053, 69483104,
- 69483155, 69483206, 69483257, 69483308, 69483359, 69483410, 69483461,
- 69483512, 69483563, 69483614, 69483665, 69483716, 69483767, 69483772,
- 69483777, 69483782, 69483787, 69483792, 69483797, 69483802, 69483807,
- 69483812, 69483817, 69483822, 69483827, 69483832, 69483837, 69483842,
- 69483847, 69483852, 69483857, 69483862, 69483867, 69483872, 69483877,
- 69483926, 69483975, 69484024, 69484073, 69484122, 69484171, 69484220,
- 69484269, 69484318, 69484367, 69484416, 69484465, 69484514, 69484563,
- 69484612, 69484661, 69484710, 69484759, 69484808, 69484857, 69484906,
- 69484955, 69485004, 69485053, 69485102, 69485151, 69485200, 69485249,
- 69485298, 69485347, 69485396, 69485445, 69485494, 69485543, 69485592,
- 69485641, 69485690, 69485739, 69485788, 69485837, 69485886, 69485935,
- 69485984, 69486033, 69486082, 69486131, 69486180, 69486229, 69486278,
- 69486326, 69486374, 69486422, 69486470, 69486518, 69486566, 69486614,
- 69486662, 69486710, 69486758, 69486806, 69486854, 69486902, 69486950,
- 69486998, 69487046, 69487094, 69487142, 69487190, 69487238, 69487286,
- 69487333, 69487380, 69487427, 69487474, 69487521, 69487568, 69487615,
- 69487662, 69487709, 69487756, 69487803, 69487850, 69487897, 69487944,
- 69487991, 69488038, 69488085, 69488132, 69488179, 69488226, 69488273,
- 69488320, 69488366, 69488412, 69488458, 69488504, 69488550, 69488596,
- 69488642, 69488688, 69488734, 69488780, 69488826, 69488872, 69488918,
- 69488964, 69489010, 69489056, 69489102, 69489148, 69489194, 69489240,
- 69489286, 69489332, 69489378, 69489424, 69489470, 69489516, 69489562,
- 69489608, 69489654, 69489700, 69489746, 69489792, 69489837, 69489882,
- 69489927, 69489972, 69490017, 69490062, 69490107, 69490152, 69490197,
- 69490242, 69490287, 69490332, 69490377, 69490422, 69490467, 69490512,
- 69490557, 69490602, 69490647, 69490692, 69490737, 69490782, 69490827,
- 69490872, 69490917, 69490962, 69491007, 69491052, 69491097, 69491142,
- 69491187, 69491232, 69491277, 69491322, 69491367, 69491411, 69491455,
- 69491499, 69491543, 69491587, 69491631, 69491675, 69491719, 69491763,
- 69491807, 69491851, 69491895, 69491939, 69491983, 69492027, 69492071,
- 69492115, 69492159, 69492203, 69492247, 69492291, 69492335, 69492379,
- 69492423, 69492467, 69492511, 69492555, 69492599, 69492643, 69492686,
- 69492729, 69492772, 69492815, 69492858, 69492901, 69492944, 69492987,
- 69493030, 69493073, 69493116, 69493159, 69493202, 69493245, 69493288,
- 69493331, 69493374, 69493417, 69493460, 69493503, 69493546, 69493589,
- 69493632, 69493675, 69493718, 69493761, 69493804, 69493847, 69493890,
- 69493933, 69493976, 69494019, 69494062, 69494105, 69494148, 69494191,
- 69494234, 69494277, 69494320, 69494363, 69494406, 69494449, 69494492,
- 69494535, 69494577, 69494619, 69494661, 69494703, 69494745, 69494787,
- 69494829, 69494871, 69494913, 69494955, 69494997, 69495039, 69495081,
- 69495123, 69495165, 69495207, 69495249, 69495291, 69495333, 69495375,
- 69495417, 69495459, 69495501, 69495543, 69495585, 69495627, 69495669,
- 69495711, 69495753, 69495795, 69495837, 69495879, 69495921, 69495963,
- 69496005, 69496047, 69496089, 69496131, 69496172, 69496213, 69496254,
- 69496295, 69496336, 69496377, 69496418, 69496459, 69496500, 69496541,
- 69496582, 69496623, 69496664, 69496705, 69496746, 69496787, 69496828,
- 69496869, 69496910, 69496951, 69496992, 69497033, 69497074, 69497115,
- 69497156, 69497197, 69497238, 69497279, 69497320, 69497361, 69497402,
- 69497443, 69497484, 69497525, 69497566, 69497607, 69497648, 69497689,
- 69497693, 69497697, 69497701, 69497705, 69497709, 69497713, 69497717,
- 69497721, 69497725, 69497729, 69497733, 69497737, 69497741, 69497745,
- 69497749, 69497753, 69497757, 69497761, 69497765, 69497769, 69497773,
- 69497777, 69497781, 69497785, 69497789, 69497793, 69497797, 69497801,
- 69497805, 69497809, 69497813, 69497817, 69497821, 69497825, 69497829,
- 69497868, 69497907, 69497946, 69497985, 69498024, 69498063, 69498102,
- 69498141, 69498180, 69498219, 69498258, 69498297, 69498336, 69498375,
- 69498414, 69498453, 69498492, 69498531, 69498570, 69498609, 69498648,
- 69498687, 69498726, 69498765, 69498804, 69498843, 69498882, 69498921,
- 69498960, 69498999, 69499038, 69499077, 69499116, 69499155, 69499193,
- 69499231, 69499269, 69499307, 69499345, 69499383, 69499421, 69499459,
- 69499497, 69499535, 69499573, 69499611, 69499649, 69499687, 69499725,
- 69499763, 69499801, 69499839, 69499877, 69499915, 69499953, 69499991,
- 69500029, 69500067, 69500105, 69500143, 69500181, 69500219, 69500257,
- 69500295, 69500333, 69500371, 69500409, 69500447, 69500484, 69500521,
- 69500558, 69500595, 69500632, 69500669, 69500706, 69500743, 69500780,
- 69500817, 69500854, 69500891, 69500928, 69500965, 69501002, 69501039,
- 69501076, 69501113, 69501150, 69501187, 69501224, 69501261, 69501298,
- 69501335, 69501372, 69501409, 69501446, 69501483, 69501520, 69501557,
- 69501594, 69501631, 69501667, 69501703, 69501739, 69501775, 69501811,
- 69501847, 69501883, 69501919, 69501955, 69501991, 69502027, 69502063,
- 69502099, 69502135, 69502171, 69502207, 69502243, 69502279, 69502315,
- 69502351, 69502387, 69502423, 69502459, 69502495, 69502531, 69502567,
- 69502603, 69502639, 69502675, 69502711, 69502747, 69502783, 69502819,
- 69502855, 69502891, 69502927, 69502963, 69502999, 69503035, 69503071,
- 69503107, 69503143, 69503179, 69503214, 69503249, 69503284, 69503319,
- 69503354, 69503389, 69503424, 69503459, 69503494, 69503529, 69503564,
- 69503599, 69503634, 69503669, 69503704, 69503739, 69503774, 69503809,
- 69503844, 69503879, 69503914, 69503949, 69503984, 69504019, 69504054,
- 69504089, 69504124, 69504159, 69504194, 69504229, 69504264, 69504299,
- 69504334, 69504369, 69504404, 69504439, 69504474, 69504509, 69504544,
- 69504579, 69504614, 69504649, 69504684, 69504719, 69504754, 69504789,
- 69504824, 69504859, 69504894, 69504929, 69504964, 69504999, 69505034,
- 69505068, 69505102, 69505136, 69505170, 69505204, 69505238, 69505272,
- 69505306, 69505340, 69505374, 69505408, 69505442, 69505476, 69505510,
- 69505544, 69505578, 69505612, 69505646, 69505680, 69505714, 69505748,
- 69505782, 69505816, 69505850, 69505884, 69505918, 69505952, 69505986,
- 69506020, 69506054, 69506088, 69506122, 69506156, 69506190, 69506224,
- 69506258, 69506292, 69506326, 69506360, 69506394, 69506427, 69506460,
- 69506493, 69506526, 69506559, 69506592, 69506625, 69506658, 69506691,
- 69506724, 69506757, 69506790, 69506823, 69506856, 69506889, 69506922,
- 69506955, 69506988, 69507021, 69507054, 69507087, 69507120, 69507153,
- 69507186, 69507219, 69507252, 69507285, 69507318, 69507351, 69507384,
- 69507417, 69507450, 69507483, 69507516, 69507549, 69507582, 69507615,
- 69507648, 69507681, 69507714, 69507747, 69507780, 69507813, 69507846,
- 69507879, 69507912, 69507945, 69507978, 69508011, 69508044, 69508077,
- 69508110, 69508143, 69508176, 69508209, 69508242, 69508275, 69508308,
- 69508341, 69508373, 69508405, 69508437, 69508469, 69508501, 69508533,
- 69508565, 69508597, 69508629, 69508661, 69508693, 69508725, 69508757,
- 69508789, 69508821, 69508853, 69508885, 69508917, 69508949, 69508981,
- 69509013, 69509045, 69509077, 69509109, 69509141, 69509173, 69509205,
- 69509237, 69509269, 69509301, 69509333, 69509365, 69509397, 69509429,
- 69509461, 69509493, 69509525, 69509557, 69509589, 69509621, 69509653,
- 69509685, 69509717, 69509748, 69509779, 69509810, 69509841, 69509872,
- 69509903, 69509934, 69509965, 69509996, 69510027, 69510058, 69510089,
- 69510120, 69510151, 69510182, 69510213, 69510244, 69510275, 69510306,
- 69510337, 69510368, 69510399, 69510430, 69510461, 69510492, 69510523,
- 69510554, 69510585, 69510616, 69510647, 69510678, 69510709, 69510740,
- 69510771, 69510802, 69510833, 69510864, 69510895, 69510926, 69510957,
- 69510988, 69511019, 69511050, 69511053, 69511056, 69511059, 69511062,
- 69511065, 69511068, 69511071, 69511074, 69511077, 69511080, 69511083,
- 69511086, 69511089, 69511092, 69511095, 69511098, 69511101, 69511104,
- 69511107, 69511110, 69511113, 69511116, 69511119, 69511122, 69511125,
- 69511128, 69511131, 69511134, 69511137, 69511140, 69511143, 69511146,
- 69511149, 69511152, 69511155, 69511158, 69511161, 69511164, 69511167,
- 69511170, 69511173, 69511176, 69511179, 69511182, 69511185, 69511188,
- 69511191, 69511194, 69511197, 69511200, 69511203, 69511206, 69511209,
- 69511212, 69511241, 69511270, 69511299, 69511328, 69511357, 69511386,
- 69511415, 69511444, 69511473, 69511502, 69511531, 69511560, 69511589,
- 69511618, 69511647, 69511676, 69511705, 69511734, 69511763, 69511792,
- 69511821, 69511850, 69511879, 69511908, 69511937, 69511966, 69511995,
- 69512024, 69512053, 69512082, 69512111, 69512140, 69512169, 69512198,
- 69512227, 69512256, 69512285, 69512314, 69512343, 69512372, 69512401,
- 69512430, 69512459, 69512488, 69512517, 69512545, 69512573, 69512601,
- 69512629, 69512657, 69512685, 69512713, 69512741, 69512769, 69512797,
- 69512825, 69512853, 69512881, 69512909, 69512937, 69512965, 69512993,
- 69513021, 69513049, 69513077, 69513105, 69513133, 69513161, 69513189,
- 69513217, 69513245, 69513273, 69513301, 69513329, 69513357, 69513385,
- 69513413, 69513441, 69513469, 69513497, 69513525, 69513553, 69513581,
- 69513609, 69513637, 69513665, 69513693, 69513721, 69513749, 69513777,
- 69513805, 69513833, 69513861, 69513889, 69513916, 69513943, 69513970,
- 69513997, 69514024, 69514051, 69514078, 69514105, 69514132, 69514159,
- 69514186, 69514213, 69514240, 69514267, 69514294, 69514321, 69514348,
- 69514375, 69514402, 69514429, 69514456, 69514483, 69514510, 69514537,
- 69514564, 69514591, 69514618, 69514645, 69514672, 69514699, 69514726,
- 69514753, 69514780, 69514807, 69514834, 69514861, 69514888, 69514915,
- 69514942, 69514969, 69514996, 69515023, 69515050, 69515077, 69515104,
- 69515131, 69515158, 69515185, 69515212, 69515239, 69515266, 69515293,
- 69515320, 69515347, 69515374, 69515401, 69515428, 69515455, 69515482,
- 69515509, 69515536, 69515563, 69515590, 69515617, 69515644, 69515670,
- 69515696, 69515722, 69515748, 69515774, 69515800, 69515826, 69515852,
- 69515878, 69515904, 69515930, 69515956, 69515982, 69516008, 69516034,
- 69516060, 69516086, 69516112, 69516138, 69516164, 69516190, 69516216,
- 69516242, 69516268, 69516294, 69516320, 69516346, 69516372, 69516398,
- 69516424, 69516450, 69516476, 69516502, 69516528, 69516554, 69516580,
- 69516606, 69516632, 69516658, 69516684, 69516710, 69516736, 69516762,
- 69516788, 69516814, 69516840, 69516866, 69516892, 69516918, 69516944,
- 69516970, 69516996, 69517022, 69517048, 69517074, 69517100, 69517126,
- 69517152, 69517178, 69517204, 69517230, 69517256, 69517282, 69517308,
- 69517334, 69517359, 69517384, 69517409, 69517434, 69517459, 69517484,
- 69517509, 69517534, 69517559, 69517584, 69517609, 69517634, 69517659,
- 69517684, 69517709, 69517734, 69517759, 69517784, 69517809, 69517834,
- 69517859, 69517884, 69517909, 69517934, 69517959, 69517984, 69518009,
- 69518034, 69518059, 69518084, 69518109, 69518134, 69518159, 69518184,
- 69518209, 69518234, 69518259, 69518284, 69518309, 69518334, 69518359,
- 69518384, 69518409, 69518434, 69518459, 69518484, 69518509, 69518534,
- 69518559, 69518584, 69518609, 69518634, 69518659, 69518684, 69518709,
- 69518734, 69518759, 69518784, 69518809, 69518834, 69518859, 69518884,
- 69518909, 69518934, 69518958, 69518982, 69519006, 69519030, 69519054,
- 69519078, 69519102, 69519126, 69519150, 69519174, 69519198, 69519222,
- 69519246, 69519270, 69519294, 69519318, 69519342, 69519366, 69519390,
- 69519414, 69519438, 69519462, 69519486, 69519510, 69519534, 69519558,
- 69519582, 69519606, 69519630, 69519654, 69519678, 69519702, 69519726,
- 69519750, 69519774, 69519798, 69519822, 69519846, 69519870, 69519894,
- 69519918, 69519942, 69519966, 69519990, 69520014, 69520038, 69520062,
- 69520086, 69520110, 69520134, 69520158, 69520182, 69520206, 69520230,
- 69520254, 69520278, 69520302, 69520326, 69520350, 69520374, 69520398,
- 69520422, 69520446, 69520470, 69520494, 69520518, 69520542, 69520566,
- 69520590, 69520614, 69520638, 69520662, 69520686, 69520710, 69520734,
- 69520758, 69520781, 69520804, 69520827, 69520850, 69520873, 69520896,
- 69520919, 69520942, 69520965, 69520988, 69521011, 69521034, 69521057,
- 69521080, 69521103, 69521126, 69521149, 69521172, 69521195, 69521218,
- 69521241, 69521264, 69521287, 69521310, 69521333, 69521356, 69521379,
- 69521402, 69521425, 69521448, 69521471, 69521494, 69521517, 69521540,
- 69521563, 69521586, 69521609, 69521632, 69521655, 69521678, 69521701,
- 69521724, 69521747, 69521770, 69521793, 69521816, 69521839, 69521862,
- 69521885, 69521908, 69521931, 69521954, 69521977, 69522000, 69522023,
- 69522046, 69522069, 69522092, 69522115, 69522138, 69522160, 69522182,
- 69522204, 69522226, 69522248, 69522270, 69522292, 69522314, 69522336,
- 69522358, 69522380, 69522402, 69522424, 69522446, 69522468, 69522490,
- 69522512, 69522534, 69522556, 69522578, 69522600, 69522622, 69522644,
- 69522666, 69522688, 69522710, 69522732, 69522754, 69522776, 69522798,
- 69522820, 69522842, 69522864, 69522886, 69522908, 69522930, 69522952,
- 69522974, 69522996, 69523018, 69523040, 69523062, 69523084, 69523106,
- 69523128, 69523150, 69523172, 69523194, 69523216, 69523238, 69523260,
- 69523282, 69523304, 69523326, 69523348, 69523370, 69523392, 69523414,
- 69523436, 69523458, 69523480, 69523502, 69523524, 69523546, 69523568,
- 69523590, 69523612, 69523634, 69523656, 69523678, 69523700, 69523722,
- 69523744, 69523765, 69523786, 69523807, 69523828, 69523849, 69523870,
- 69523891, 69523912, 69523933, 69523954, 69523975, 69523996, 69524017,
- 69524038, 69524059, 69524080, 69524101, 69524122, 69524143, 69524164,
- 69524185, 69524206, 69524227, 69524248, 69524269, 69524290, 69524311,
- 69524332, 69524353, 69524374, 69524395, 69524416, 69524437, 69524458,
- 69524479, 69524500, 69524521, 69524542, 69524563, 69524584, 69524605,
- 69524626, 69524647, 69524668, 69524689, 69524710, 69524731, 69524752,
- 69524773, 69524794, 69524815, 69524836, 69524857, 69524878, 69524899,
- 69524920, 69524941, 69524962, 69524983, 69525004, 69525025, 69525046,
- 69525067, 69525088, 69525109, 69525130, 69525151, 69525172, 69525193,
- 69525214, 69525235, 69525256, 69525277, 69525298, 69525319, 69525340,
- 69525361, 69525382, 69525403, 69525424, 69525445, 69525466, 69525487,
- 69525508, 69525529, 69525550, 69525571, 69525592, 69525594, 69525596,
- 69525598, 69525600, 69525602, 69525604, 69525606, 69525608, 69525610,
- 69525612, 69525614, 69525616, 69525618, 69525620, 69525622, 69525624,
- 69525626, 69525628, 69525630, 69525632, 69525634, 69525636, 69525638,
- 69525640, 69525642, 69525644, 69525646, 69525648, 69525650, 69525652,
- 69525654, 69525656, 69525658, 69525660, 69525662, 69525664, 69525666,
- 69525668, 69525670, 69525672, 69525674, 69525676, 69525678, 69525680,
- 69525682, 69525684, 69525686, 69525688, 69525690, 69525692, 69525694,
- 69525696, 69525698, 69525700, 69525702, 69525704, 69525706, 69525708,
- 69525710, 69525712, 69525714, 69525716, 69525718, 69525720, 69525722,
- 69525724, 69525726, 69525728, 69525730, 69525732, 69525734, 69525736,
- 69525738, 69525740, 69525742, 69525744, 69525746, 69525748, 69525750,
- 69525752, 69525754, 69525756, 69525758, 69525760, 69525762, 69525764,
- 69525766, 69525768, 69525770, 69525772, 69525774, 69525776, 69525778,
- 69525780, 69525782, 69525784, 69525786, 69525788, 69525790, 69525792,
- 69525794, 69525796, 69525815, 69525834, 69525853, 69525872, 69525891,
- 69525910, 69525929, 69525948, 69525967, 69525986, 69526005, 69526024,
- 69526043, 69526062, 69526081, 69526100, 69526119, 69526138, 69526157,
- 69526176, 69526195, 69526214, 69526233, 69526252, 69526271, 69526290,
- 69526309, 69526328, 69526347, 69526366, 69526385, 69526404, 69526423,
- 69526442, 69526461, 69526480, 69526499, 69526518, 69526537, 69526556,
- 69526575, 69526594, 69526613, 69526632, 69526651, 69526670, 69526689,
- 69526708, 69526727, 69526746, 69526765, 69526784, 69526803, 69526822,
- 69526841, 69526860, 69526879, 69526898, 69526917, 69526936, 69526955,
- 69526974, 69526993, 69527012, 69527031, 69527050, 69527069, 69527088,
- 69527107, 69527126, 69527145, 69527164, 69527183, 69527202, 69527221,
- 69527240, 69527259, 69527278, 69527297, 69527316, 69527335, 69527354,
- 69527373, 69527392, 69527411, 69527429, 69527447, 69527465, 69527483,
- 69527501, 69527519, 69527537, 69527555, 69527573, 69527591, 69527609,
- 69527627, 69527645, 69527663, 69527681, 69527699, 69527717, 69527735,
- 69527753, 69527771, 69527789, 69527807, 69527825, 69527843, 69527861,
- 69527879, 69527897, 69527915, 69527933, 69527951, 69527969, 69527987,
- 69528005, 69528023, 69528041, 69528059, 69528077, 69528095, 69528113,
- 69528131, 69528149, 69528167, 69528185, 69528203, 69528221, 69528239,
- 69528257, 69528275, 69528293, 69528311, 69528329, 69528347, 69528365,
- 69528383, 69528401, 69528419, 69528437, 69528455, 69528473, 69528491,
- 69528509, 69528527, 69528545, 69528563, 69528581, 69528599, 69528617,
- 69528635, 69528653, 69528671, 69528689, 69528707, 69528725, 69528743,
- 69528761, 69528779, 69528797, 69528814, 69528831, 69528848, 69528865,
- 69528882, 69528899, 69528916, 69528933, 69528950, 69528967, 69528984,
- 69529001, 69529018, 69529035, 69529052, 69529069, 69529086, 69529103,
- 69529120, 69529137, 69529154, 69529171, 69529188, 69529205, 69529222,
- 69529239, 69529256, 69529273, 69529290, 69529307, 69529324, 69529341,
- 69529358, 69529375, 69529392, 69529409, 69529426, 69529443, 69529460,
- 69529477, 69529494, 69529511, 69529528, 69529545, 69529562, 69529579,
- 69529596, 69529613, 69529630, 69529647, 69529664, 69529681, 69529698,
- 69529715, 69529732, 69529749, 69529766, 69529783, 69529800, 69529817,
- 69529834, 69529851, 69529868, 69529885, 69529902, 69529919, 69529936,
- 69529953, 69529970, 69529987, 69530004, 69530021, 69530038, 69530055,
- 69530072, 69530089, 69530106, 69530123, 69530140, 69530157, 69530174,
- 69530191, 69530208, 69530225, 69530242, 69530259, 69530276, 69530293,
- 69530310, 69530327, 69530344, 69530361, 69530378, 69530395, 69530412,
- 69530429, 69530446, 69530463, 69530480, 69530497, 69530514, 69530531,
- 69530548, 69530565, 69530582, 69530599, 69530616, 69530633, 69530650,
- 69530666, 69530682, 69530698, 69530714, 69530730, 69530746, 69530762,
- 69530778, 69530794, 69530810, 69530826, 69530842, 69530858, 69530874,
- 69530890, 69530906, 69530922, 69530938, 69530954, 69530970, 69530986,
- 69531002, 69531018, 69531034, 69531050, 69531066, 69531082, 69531098,
- 69531114, 69531130, 69531146, 69531162, 69531178, 69531194, 69531210,
- 69531226, 69531242, 69531258, 69531274, 69531290, 69531306, 69531322,
- 69531338, 69531354, 69531370, 69531386, 69531402, 69531418, 69531434,
- 69531450, 69531466, 69531482, 69531498, 69531514, 69531530, 69531546,
- 69531562, 69531578, 69531594, 69531610, 69531626, 69531642, 69531658,
- 69531674, 69531690, 69531706, 69531722, 69531738, 69531754, 69531770,
- 69531786, 69531802, 69531818, 69531834, 69531850, 69531866, 69531882,
- 69531898, 69531914, 69531930, 69531946, 69531962, 69531978, 69531994,
- 69532010, 69532026, 69532042, 69532058, 69532074, 69532090, 69532106,
- 69532122, 69532138, 69532154, 69532170, 69532186, 69532202, 69532218,
- 69532234, 69532250, 69532266, 69532282, 69532298, 69532314, 69532330,
- 69532346, 69532362, 69532378, 69532394, 69532410, 69532426, 69532442,
- 69532458, 69532474, 69532490, 69532506, 69532522, 69532538, 69532554,
- 69532569, 69532584, 69532599, 69532614, 69532629, 69532644, 69532659,
- 69532674, 69532689, 69532704, 69532719, 69532734, 69532749, 69532764,
- 69532779, 69532794, 69532809, 69532824, 69532839, 69532854, 69532869,
- 69532884, 69532899, 69532914, 69532929, 69532944, 69532959, 69532974,
- 69532989, 69533004, 69533019, 69533034, 69533049, 69533064, 69533079,
- 69533094, 69533109, 69533124, 69533139, 69533154, 69533169, 69533184,
- 69533199, 69533214, 69533229, 69533244, 69533259, 69533274, 69533289,
- 69533304, 69533319, 69533334, 69533349, 69533364, 69533379, 69533394,
- 69533409, 69533424, 69533439, 69533454, 69533469, 69533484, 69533499,
- 69533514, 69533529, 69533544, 69533559, 69533574, 69533589, 69533604,
- 69533619, 69533634, 69533649, 69533664, 69533679, 69533694, 69533709,
- 69533724, 69533739, 69533754, 69533769, 69533784, 69533799, 69533814,
- 69533829, 69533844, 69533859, 69533874, 69533889, 69533904, 69533919,
- 69533934, 69533949, 69533964, 69533979, 69533994, 69534009, 69534024,
- 69534039, 69534054, 69534069, 69534084, 69534099, 69534114, 69534129,
- 69534144, 69534159, 69534174, 69534189, 69534204, 69534219, 69534233,
- 69534247, 69534261, 69534275, 69534289, 69534303, 69534317, 69534331,
- 69534345, 69534359, 69534373, 69534387, 69534401, 69534415, 69534429,
- 69534443, 69534457, 69534471, 69534485, 69534499, 69534513, 69534527,
- 69534541, 69534555, 69534569, 69534583, 69534597, 69534611, 69534625,
- 69534639, 69534653, 69534667, 69534681, 69534695, 69534709, 69534723,
- 69534737, 69534751, 69534765, 69534779, 69534793, 69534807, 69534821,
- 69534835, 69534849, 69534863, 69534877, 69534891, 69534905, 69534919,
- 69534933, 69534947, 69534961, 69534975, 69534989, 69535003, 69535017,
- 69535031, 69535045, 69535059, 69535073, 69535087, 69535101, 69535115,
- 69535129, 69535143, 69535157, 69535171, 69535185, 69535199, 69535213,
- 69535227, 69535241, 69535255, 69535269, 69535283, 69535297, 69535311,
- 69535325, 69535339, 69535353, 69535367, 69535381, 69535395, 69535409,
- 69535423, 69535437, 69535451, 69535465, 69535479, 69535493, 69535507,
- 69535521, 69535535, 69535549, 69535563, 69535577, 69535591, 69535605,
- 69535619, 69535633, 69535647, 69535661, 69535675, 69535689, 69535703,
- 69535717, 69535731, 69535744, 69535757, 69535770, 69535783, 69535796,
- 69535809, 69535822, 69535835, 69535848, 69535861, 69535874, 69535887,
- 69535900, 69535913, 69535926, 69535939, 69535952, 69535965, 69535978,
- 69535991, 69536004, 69536017, 69536030, 69536043, 69536056, 69536069,
- 69536082, 69536095, 69536108, 69536121, 69536134, 69536147, 69536160,
- 69536173, 69536186, 69536199, 69536212, 69536225, 69536238, 69536251,
- 69536264, 69536277, 69536290, 69536303, 69536316, 69536329, 69536342,
- 69536355, 69536368, 69536381, 69536394, 69536407, 69536420, 69536433,
- 69536446, 69536459, 69536472, 69536485, 69536498, 69536511, 69536524,
- 69536537, 69536550, 69536563, 69536576, 69536589, 69536602, 69536615,
- 69536628, 69536641, 69536654, 69536667, 69536680, 69536693, 69536706,
- 69536719, 69536732, 69536745, 69536758, 69536771, 69536784, 69536797,
- 69536810, 69536823, 69536836, 69536849, 69536862, 69536875, 69536888,
- 69536901, 69536914, 69536927, 69536940, 69536953, 69536966, 69536979,
- 69536992, 69537005, 69537018, 69537031, 69537044, 69537057, 69537070,
- 69537083, 69537096, 69537109, 69537122, 69537135, 69537148, 69537161,
- 69537174, 69537187, 69537200, 69537213, 69537226, 69537239, 69537252,
- 69537265, 69537278, 69537291, 69537304, 69537317, 69537330, 69537343,
- 69537356, 69537369, 69537381, 69537393, 69537405, 69537417, 69537429,
- 69537441, 69537453, 69537465, 69537477, 69537489, 69537501, 69537513,
- 69537525, 69537537, 69537549, 69537561, 69537573, 69537585, 69537597,
- 69537609, 69537621, 69537633, 69537645, 69537657, 69537669, 69537681,
- 69537693, 69537705, 69537717, 69537729, 69537741, 69537753, 69537765,
- 69537777, 69537789, 69537801, 69537813, 69537825, 69537837, 69537849,
- 69537861, 69537873, 69537885, 69537897, 69537909, 69537921, 69537933,
- 69537945, 69537957, 69537969, 69537981, 69537993, 69538005, 69538017,
- 69538029, 69538041, 69538053, 69538065, 69538077, 69538089, 69538101,
- 69538113, 69538125, 69538137, 69538149, 69538161, 69538173, 69538185,
- 69538197, 69538209, 69538221, 69538233, 69538245, 69538257, 69538269,
- 69538281, 69538293, 69538305, 69538317, 69538329, 69538341, 69538353,
- 69538365, 69538377, 69538389, 69538401, 69538413, 69538425, 69538437,
- 69538449, 69538461, 69538473, 69538485, 69538497, 69538509, 69538521,
- 69538533, 69538545, 69538557, 69538569, 69538581, 69538593, 69538605,
- 69538617, 69538629, 69538641, 69538653, 69538665, 69538677, 69538689,
- 69538701, 69538713, 69538725, 69538737, 69538749, 69538761, 69538773,
- 69538785, 69538797, 69538809, 69538821, 69538833, 69538845, 69538857,
- 69538869, 69538881, 69538893, 69538904, 69538915, 69538926, 69538937,
- 69538948, 69538959, 69538970, 69538981, 69538992, 69539003, 69539014,
- 69539025, 69539036, 69539047, 69539058, 69539069, 69539080, 69539091,
- 69539102, 69539113, 69539124, 69539135, 69539146, 69539157, 69539168,
- 69539179, 69539190, 69539201, 69539212, 69539223, 69539234, 69539245,
- 69539256, 69539267, 69539278, 69539289, 69539300, 69539311, 69539322,
- 69539333, 69539344, 69539355, 69539366, 69539377, 69539388, 69539399,
- 69539410, 69539421, 69539432, 69539443, 69539454, 69539465, 69539476,
- 69539487, 69539498, 69539509, 69539520, 69539531, 69539542, 69539553,
- 69539564, 69539575, 69539586, 69539597, 69539608, 69539619, 69539630,
- 69539641, 69539652, 69539663, 69539674, 69539685, 69539696, 69539707,
- 69539718, 69539729, 69539740, 69539751, 69539762, 69539773, 69539784,
- 69539795, 69539806, 69539817, 69539828, 69539839, 69539850, 69539861,
- 69539872, 69539883, 69539894, 69539905, 69539916, 69539927, 69539938,
- 69539949, 69539960, 69539971, 69539982, 69539993, 69540004, 69540015,
- 69540026, 69540037, 69540048, 69540059, 69540070, 69540081, 69540092,
- 69540103, 69540114, 69540125, 69540136, 69540147, 69540158, 69540169,
- 69540180, 69540191, 69540202, 69540213, 69540224, 69540235, 69540246,
- 69540257, 69540268, 69540279, 69540290, 69540301, 69540312, 69540323,
- 69540334, 69540345, 69540356, 69540367, 69540378, 69540389, 69540400,
- 69540411, 69540422, 69540433, 69540444, 69540455, 69540466, 69540477,
- 69540488, 69540499, 69540510, 69540521, 69540532, 69540543, 69540554,
- 69540565, 69540576, 69540587, 69540598, 69540609, 69540620, 69540631,
- 69540642, 69540653, 69540664, 69540675, 69540686, 69540697, 69540698,
- 69540699, 69540700, 69540701, 69540702, 69540703, 69540704, 69540705,
- 69540706, 69540707, 69540708, 69540709, 69540710, 69540711, 69540712,
- 69540713, 69540714, 69540715, 69540716, 69540717, 69540718, 69540719,
- 69540720, 69540721, 69540722, 69540723, 69540724, 69540725, 69540726,
- 69540727, 69540728, 69540729, 69540730, 69540731, 69540732, 69540733,
- 69540734, 69540735, 69540736, 69540737, 69540738, 69540739, 69540740,
- 69540741, 69540742, 69540743, 69540744, 69540745, 69540746, 69540747,
- 69540748, 69540749, 69540750, 69540751, 69540752, 69540753, 69540754,
- 69540755, 69540756, 69540757, 69540758, 69540759, 69540760, 69540761,
- 69540762, 69540763, 69540764, 69540765, 69540766, 69540767, 69540768,
- 69540769, 69540770, 69540771, 69540772, 69540773, 69540774, 69540775,
- 69540776, 69540777, 69540778, 69540779, 69540780, 69540781, 69540782,
- 69540783, 69540784, 69540785, 69540786, 69540787, 69540788, 69540789,
- 69540790, 69540791, 69540792, 69540793, 69540794, 69540795, 69540796,
- 69540797, 69540798, 69540799, 69540800, 69540801, 69540802, 69540803,
- 69540804, 69540805, 69540806, 69540807, 69540808, 69540809, 69540810,
- 69540811, 69540812, 69540813, 69540814, 69540815, 69540816, 69540817,
- 69540818, 69540819, 69540820, 69540821, 69540822, 69540823, 69540824,
- 69540825, 69540826, 69540827, 69540828, 69540829, 69540830, 69540831,
- 69540832, 69540833, 69540834, 69540835, 69540836, 69540837, 69540838,
- 69540839, 69540840, 69540841, 69540842, 69540843, 69540844, 69540845,
- 69540846, 69540847, 69540848, 69540849, 69540850, 69540851, 69540852,
- 69540853, 69540854, 69540855, 69540856, 69540857, 69540858, 69540859,
- 69540860, 69540861, 69540862, 69540863, 69540864, 69540865, 69540866,
- 69540867, 69540868, 69540869, 69540870, 69540871, 69540872, 69540873,
- 69540874, 69540875, 69540876, 69540877, 69540878, 69540879, 69540880,
- 69540881, 69540882, 69540891, 69540900, 69540909, 69540918, 69540927,
- 69540936, 69540945, 69540954, 69540963, 69540972, 69540981, 69540990,
- 69540999, 69541008, 69541017, 69541026, 69541035, 69541044, 69541053,
- 69541062, 69541071, 69541080, 69541089, 69541098, 69541107, 69541116,
- 69541125, 69541134, 69541143, 69541152, 69541161, 69541170, 69541179,
- 69541188, 69541197, 69541206, 69541215, 69541224, 69541233, 69541242,
- 69541251, 69541260, 69541269, 69541278, 69541287, 69541296, 69541305,
- 69541314, 69541323, 69541332, 69541341, 69541350, 69541359, 69541368,
- 69541377, 69541386, 69541395, 69541404, 69541413, 69541422, 69541431,
- 69541440, 69541449, 69541458, 69541467, 69541476, 69541485, 69541494,
- 69541503, 69541512, 69541521, 69541530, 69541539, 69541548, 69541557,
- 69541566, 69541575, 69541584, 69541593, 69541602, 69541611, 69541620,
- 69541629, 69541638, 69541647, 69541656, 69541665, 69541674, 69541683,
- 69541692, 69541701, 69541710, 69541719, 69541728, 69541737, 69541746,
- 69541755, 69541764, 69541773, 69541782, 69541791, 69541800, 69541809,
- 69541818, 69541827, 69541836, 69541845, 69541854, 69541863, 69541872,
- 69541881, 69541890, 69541899, 69541908, 69541917, 69541926, 69541935,
- 69541944, 69541953, 69541962, 69541971, 69541980, 69541989, 69541998,
- 69542007, 69542016, 69542025, 69542034, 69542043, 69542052, 69542061,
- 69542070, 69542079, 69542088, 69542097, 69542106, 69542115, 69542124,
- 69542133, 69542142, 69542151, 69542160, 69542169, 69542178, 69542187,
- 69542196, 69542205, 69542214, 69542223, 69542232, 69542241, 69542250,
- 69542259, 69542268, 69542277, 69542286, 69542295, 69542304, 69542313,
- 69542322, 69542331, 69542340, 69542349, 69542358, 69542367, 69542376,
- 69542385, 69542394, 69542403, 69542412, 69542421, 69542430, 69542439,
- 69542448, 69542457, 69542466, 69542475, 69542484, 69542493, 69542502,
- 69542511, 69542520, 69542529, 69542538, 69542547, 69542556, 69542565,
- 69542574, 69542583, 69542592, 69542601, 69542610, 69542619, 69542628,
- 69542637, 69542646, 69542655, 69542664, 69542673, 69542682, 69542691,
- 69542700, 69542709, 69542718, 69542727, 69542736, 69542745, 69542753,
- 69542761, 69542769, 69542777, 69542785, 69542793, 69542801, 69542809,
- 69542817, 69542825, 69542833, 69542841, 69542849, 69542857, 69542865,
- 69542873, 69542881, 69542889, 69542897, 69542905, 69542913, 69542921,
- 69542929, 69542937, 69542945, 69542953, 69542961, 69542969, 69542977,
- 69542985, 69542993, 69543001, 69543009, 69543017, 69543025, 69543033,
- 69543041, 69543049, 69543057, 69543065, 69543073, 69543081, 69543089,
- 69543097, 69543105, 69543113, 69543121, 69543129, 69543137, 69543145,
- 69543153, 69543161, 69543169, 69543177, 69543185, 69543193, 69543201,
- 69543209, 69543217, 69543225, 69543233, 69543241, 69543249, 69543257,
- 69543265, 69543273, 69543281, 69543289, 69543297, 69543305, 69543313,
- 69543321, 69543329, 69543337, 69543345, 69543353, 69543361, 69543369,
- 69543377, 69543385, 69543393, 69543401, 69543409, 69543417, 69543425,
- 69543433, 69543441, 69543449, 69543457, 69543465, 69543473, 69543481,
- 69543489, 69543497, 69543505, 69543513, 69543521, 69543529, 69543537,
- 69543545, 69543553, 69543561, 69543569, 69543577, 69543585, 69543593,
- 69543601, 69543609, 69543617, 69543625, 69543633, 69543641, 69543649,
- 69543657, 69543665, 69543673, 69543681, 69543689, 69543697, 69543705,
- 69543713, 69543721, 69543729, 69543737, 69543745, 69543753, 69543761,
- 69543769, 69543777, 69543785, 69543793, 69543801, 69543809, 69543817,
- 69543825, 69543833, 69543841, 69543849, 69543857, 69543865, 69543873,
- 69543881, 69543889, 69543897, 69543905, 69543913, 69543921, 69543929,
- 69543937, 69543945, 69543953, 69543961, 69543969, 69543977, 69543985,
- 69543993, 69544001, 69544009, 69544017, 69544025, 69544033, 69544041,
- 69544049, 69544057, 69544065, 69544073, 69544081, 69544089, 69544097,
- 69544105, 69544113, 69544121, 69544129, 69544137, 69544145, 69544153,
- 69544161, 69544169, 69544177, 69544185, 69544193, 69544201, 69544209,
- 69544217, 69544225, 69544233, 69544241, 69544249, 69544257, 69544265,
- 69544273, 69544281, 69544289, 69544297, 69544305, 69544313, 69544321,
- 69544329, 69544337, 69544345, 69544353, 69544361, 69544369, 69544377,
- 69544385, 69544393, 69544401, 69544409, 69544417, 69544425, 69544433,
- 69544441, 69544449, 69544457, 69544465, 69544473, 69544481, 69544489,
- 69544497, 69544505, 69544513, 69544521, 69544529, 69544537, 69544545,
- 69544553, 69544561, 69544569, 69544577, 69544585, 69544593, 69544601,
- 69544609, 69544617, 69544625, 69544633, 69544641, 69544649, 69544657,
- 69544665, 69544673, 69544681, 69544689, 69544697, 69544705, 69544713,
- 69544721, 69544729, 69544737, 69544745, 69544753, 69544761, 69544769,
- 69544777, 69544785, 69544793, 69544800, 69544807, 69544814, 69544821,
- 69544828, 69544835, 69544842, 69544849, 69544856, 69544863, 69544870,
- 69544877, 69544884, 69544891, 69544898, 69544905, 69544912, 69544919,
- 69544926, 69544933, 69544940, 69544947, 69544954, 69544961, 69544968,
- 69544975, 69544982, 69544989, 69544996, 69545003, 69545010, 69545017,
- 69545024, 69545031, 69545038, 69545045, 69545052, 69545059, 69545066,
- 69545073, 69545080, 69545087, 69545094, 69545101, 69545108, 69545115,
- 69545122, 69545129, 69545136, 69545143, 69545150, 69545157, 69545164,
- 69545171, 69545178, 69545185, 69545192, 69545199, 69545206, 69545213,
- 69545220, 69545227, 69545234, 69545241, 69545248, 69545255, 69545262,
- 69545269, 69545276, 69545283, 69545290, 69545297, 69545304, 69545311,
- 69545318, 69545325, 69545332, 69545339, 69545346, 69545353, 69545360,
- 69545367, 69545374, 69545381, 69545388, 69545395, 69545402, 69545409,
- 69545416, 69545423, 69545430, 69545437, 69545444, 69545451, 69545458,
- 69545465, 69545472, 69545479, 69545486, 69545493, 69545500, 69545507,
- 69545514, 69545521, 69545528, 69545535, 69545542, 69545549, 69545556,
- 69545563, 69545570, 69545577, 69545584, 69545591, 69545598, 69545605,
- 69545612, 69545619, 69545626, 69545633, 69545640, 69545647, 69545654,
- 69545661, 69545668, 69545675, 69545682, 69545689, 69545696, 69545703,
- 69545710, 69545717, 69545724, 69545731, 69545738, 69545745, 69545752,
- 69545759, 69545766, 69545773, 69545780, 69545787, 69545794, 69545801,
- 69545808, 69545815, 69545822, 69545829, 69545836, 69545843, 69545850,
- 69545857, 69545864, 69545871, 69545878, 69545885, 69545892, 69545899,
- 69545906, 69545913, 69545920, 69545927, 69545934, 69545941, 69545948,
- 69545955, 69545962, 69545969, 69545976, 69545983, 69545990, 69545997,
- 69546004, 69546011, 69546018, 69546025, 69546032, 69546039, 69546046,
- 69546053, 69546060, 69546067, 69546074, 69546081, 69546088, 69546095,
- 69546102, 69546109, 69546116, 69546123, 69546130, 69546137, 69546144,
- 69546151, 69546158, 69546165, 69546172, 69546179, 69546186, 69546193,
- 69546200, 69546207, 69546214, 69546221, 69546228, 69546235, 69546242,
- 69546249, 69546256, 69546263, 69546270, 69546277, 69546284, 69546291,
- 69546298, 69546305, 69546312, 69546319, 69546326, 69546333, 69546340,
- 69546347, 69546354, 69546361, 69546368, 69546375, 69546382, 69546389,
- 69546396, 69546403, 69546410, 69546417, 69546424, 69546431, 69546438,
- 69546445, 69546452, 69546459, 69546466, 69546473, 69546480, 69546487,
- 69546494, 69546501, 69546508, 69546515, 69546522, 69546529, 69546536,
- 69546543, 69546550, 69546557, 69546564, 69546571, 69546578, 69546585,
- 69546592, 69546599, 69546605, 69546611, 69546617, 69546623, 69546629,
- 69546635, 69546641, 69546647, 69546653, 69546659, 69546665, 69546671,
- 69546677, 69546683, 69546689, 69546695, 69546701, 69546707, 69546713,
- 69546719, 69546725, 69546731, 69546737, 69546743, 69546749, 69546755,
- 69546761, 69546767, 69546773, 69546779, 69546785, 69546791, 69546797,
- 69546803, 69546809, 69546815, 69546821, 69546827, 69546833, 69546839,
- 69546845, 69546851, 69546857, 69546863, 69546869, 69546875, 69546881,
- 69546887, 69546893, 69546899, 69546905, 69546911, 69546917, 69546923,
- 69546929, 69546935, 69546941, 69546947, 69546953, 69546959, 69546965,
- 69546971, 69546977, 69546983, 69546989, 69546995, 69547001, 69547007,
- 69547013, 69547019, 69547025, 69547031, 69547037, 69547043, 69547049,
- 69547055, 69547061, 69547067, 69547073, 69547079, 69547085, 69547091,
- 69547097, 69547103, 69547109, 69547115, 69547121, 69547127, 69547133,
- 69547139, 69547145, 69547151, 69547157, 69547163, 69547169, 69547175,
- 69547181, 69547187, 69547193, 69547199, 69547205, 69547211, 69547217,
- 69547223, 69547229, 69547235, 69547241, 69547247, 69547253, 69547259,
- 69547265, 69547271, 69547277, 69547283, 69547289, 69547295, 69547301,
- 69547307, 69547313, 69547319, 69547325, 69547331, 69547337, 69547343,
- 69547349, 69547355, 69547361, 69547367, 69547373, 69547379, 69547385,
- 69547391, 69547397, 69547403, 69547409, 69547415, 69547421, 69547427,
- 69547433, 69547439, 69547445, 69547451, 69547457, 69547463, 69547469,
- 69547475, 69547481, 69547487, 69547493, 69547499, 69547505, 69547511,
- 69547517, 69547523, 69547529, 69547535, 69547541, 69547547, 69547553,
- 69547559, 69547565, 69547571, 69547577, 69547583, 69547589, 69547595,
- 69547601, 69547607, 69547613, 69547619, 69547625, 69547631, 69547637,
- 69547643, 69547649, 69547655, 69547661, 69547667, 69547673, 69547679,
- 69547685, 69547691, 69547697, 69547703, 69547709, 69547715, 69547721,
- 69547727, 69547733, 69547739, 69547745, 69547751, 69547757, 69547763,
- 69547769, 69547775, 69547781, 69547787, 69547793, 69547799, 69547805,
- 69547811, 69547817, 69547823, 69547829, 69547835, 69547841, 69547847,
- 69547853, 69547859, 69547865, 69547871, 69547877, 69547883, 69547889,
- 69547895, 69547901, 69547907, 69547913, 69547919, 69547925, 69547931,
- 69547937, 69547943, 69547949, 69547955, 69547961, 69547967, 69547973,
- 69547979, 69547985, 69547991, 69547997, 69548003, 69548009, 69548015,
- 69548021, 69548027, 69548033, 69548039, 69548045, 69548051, 69548057,
- 69548063, 69548069, 69548075, 69548081, 69548087, 69548093, 69548099,
- 69548105, 69548111, 69548117, 69548123, 69548129, 69548135, 69548141,
- 69548147, 69548153, 69548159, 69548165, 69548171, 69548177, 69548183,
- 69548189, 69548195, 69548201, 69548207, 69548213, 69548219, 69548225,
- 69548231, 69548237, 69548243, 69548249, 69548255, 69548261, 69548267,
- 69548273, 69548279, 69548285, 69548291, 69548297, 69548303, 69548309,
- 69548315, 69548321, 69548327, 69548333, 69548339, 69548345, 69548351,
- 69548357, 69548363, 69548369, 69548375, 69548381, 69548387, 69548393,
- 69548399, 69548405, 69548411, 69548416, 69548421, 69548426, 69548431,
- 69548436, 69548441, 69548446, 69548451, 69548456, 69548461, 69548466,
- 69548471, 69548476, 69548481, 69548486, 69548491, 69548496, 69548501,
- 69548506, 69548511, 69548516, 69548521, 69548526, 69548531, 69548536,
- 69548541, 69548546, 69548551, 69548556, 69548561, 69548566, 69548571,
- 69548576, 69548581, 69548586, 69548591, 69548596, 69548601, 69548606,
- 69548611, 69548616, 69548621, 69548626, 69548631, 69548636, 69548641,
- 69548646, 69548651, 69548656, 69548661, 69548666, 69548671, 69548676,
- 69548681, 69548686, 69548691, 69548696, 69548701, 69548706, 69548711,
- 69548716, 69548721, 69548726, 69548731, 69548736, 69548741, 69548746,
- 69548751, 69548756, 69548761, 69548766, 69548771, 69548776, 69548781,
- 69548786, 69548791, 69548796, 69548801, 69548806, 69548811, 69548816,
- 69548821, 69548826, 69548831, 69548836, 69548841, 69548846, 69548851,
- 69548856, 69548861, 69548866, 69548871, 69548876, 69548881, 69548886,
- 69548891, 69548896, 69548901, 69548906, 69548911, 69548916, 69548921,
- 69548926, 69548931, 69548936, 69548941, 69548946, 69548951, 69548956,
- 69548961, 69548966, 69548971, 69548976, 69548981, 69548986, 69548991,
- 69548996, 69549001, 69549006, 69549011, 69549016, 69549021, 69549026,
- 69549031, 69549036, 69549041, 69549046, 69549051, 69549056, 69549061,
- 69549066, 69549071, 69549076, 69549081, 69549086, 69549091, 69549096,
- 69549101, 69549106, 69549111, 69549116, 69549121, 69549126, 69549131,
- 69549136, 69549141, 69549146, 69549151, 69549156, 69549161, 69549166,
- 69549171, 69549176, 69549181, 69549186, 69549191, 69549196, 69549201,
- 69549206, 69549211, 69549216, 69549221, 69549226, 69549231, 69549236,
- 69549241, 69549246, 69549251, 69549256, 69549261, 69549266, 69549271,
- 69549276, 69549281, 69549286, 69549291, 69549296, 69549301, 69549306,
- 69549311, 69549316, 69549321, 69549326, 69549331, 69549336, 69549341,
- 69549346, 69549351, 69549356, 69549361, 69549366, 69549371, 69549376,
- 69549381, 69549386, 69549391, 69549396, 69549401, 69549406, 69549411,
- 69549416, 69549421, 69549426, 69549431, 69549436, 69549441, 69549446,
- 69549451, 69549456, 69549461, 69549466, 69549471, 69549476, 69549481,
- 69549486, 69549491, 69549496, 69549501, 69549506, 69549511, 69549516,
- 69549521, 69549526, 69549531, 69549536, 69549541, 69549546, 69549551,
- 69549556, 69549561, 69549566, 69549571, 69549576, 69549581, 69549586,
- 69549591, 69549596, 69549601, 69549606, 69549611, 69549616, 69549621,
- 69549626, 69549631, 69549636, 69549641, 69549646, 69549651, 69549656,
- 69549661, 69549666, 69549671, 69549676, 69549681, 69549686, 69549691,
- 69549696, 69549701, 69549706, 69549711, 69549716, 69549721, 69549726,
- 69549731, 69549736, 69549741, 69549746, 69549751, 69549756, 69549761,
- 69549766, 69549771, 69549776, 69549781, 69549786, 69549791, 69549796,
- 69549801, 69549806, 69549811, 69549816, 69549821, 69549826, 69549831,
- 69549836, 69549841, 69549846, 69549851, 69549856, 69549861, 69549866,
- 69549871, 69549876, 69549881, 69549886, 69549891, 69549896, 69549901,
- 69549906, 69549911, 69549916, 69549921, 69549926, 69549931, 69549936,
- 69549941, 69549946, 69549951, 69549956, 69549961, 69549966, 69549971,
- 69549976, 69549981, 69549986, 69549991, 69549996, 69550001, 69550006,
- 69550011, 69550016, 69550021, 69550026, 69550031, 69550036, 69550041,
- 69550046, 69550051, 69550056, 69550061, 69550066, 69550071, 69550076,
- 69550081, 69550086, 69550091, 69550096, 69550101, 69550106, 69550111,
- 69550116, 69550121, 69550126, 69550131, 69550136, 69550141, 69550146,
- 69550151, 69550156, 69550161, 69550166, 69550171, 69550176, 69550181,
- 69550186, 69550191, 69550196, 69550201, 69550206, 69550211, 69550216,
- 69550221, 69550226, 69550231, 69550236, 69550241, 69550246, 69550251,
- 69550256, 69550261, 69550266, 69550271, 69550276, 69550281, 69550286,
- 69550291, 69550296, 69550301, 69550306, 69550311, 69550316, 69550321,
- 69550326, 69550331, 69550336, 69550341, 69550346, 69550351, 69550356,
- 69550361, 69550366, 69550371, 69550376, 69550381, 69550386, 69550390,
- 69550394, 69550398, 69550402, 69550406, 69550410, 69550414, 69550418,
- 69550422, 69550426, 69550430, 69550434, 69550438, 69550442, 69550446,
- 69550450, 69550454, 69550458, 69550462, 69550466, 69550470, 69550474,
- 69550478, 69550482, 69550486, 69550490, 69550494, 69550498, 69550502,
- 69550506, 69550510, 69550514, 69550518, 69550522, 69550526, 69550530,
- 69550534, 69550538, 69550542, 69550546, 69550550, 69550554, 69550558,
- 69550562, 69550566, 69550570, 69550574, 69550578, 69550582, 69550586,
- 69550590, 69550594, 69550598, 69550602, 69550606, 69550610, 69550614,
- 69550618, 69550622, 69550626, 69550630, 69550634, 69550638, 69550642,
- 69550646, 69550650, 69550654, 69550658, 69550662, 69550666, 69550670,
- 69550674, 69550678, 69550682, 69550686, 69550690, 69550694, 69550698,
- 69550702, 69550706, 69550710, 69550714, 69550718, 69550722, 69550726,
- 69550730, 69550734, 69550738, 69550742, 69550746, 69550750, 69550754,
- 69550758, 69550762, 69550766, 69550770, 69550774, 69550778, 69550782,
- 69550786, 69550790, 69550794, 69550798, 69550802, 69550806, 69550810,
- 69550814, 69550818, 69550822, 69550826, 69550830, 69550834, 69550838,
- 69550842, 69550846, 69550850, 69550854, 69550858, 69550862, 69550866,
- 69550870, 69550874, 69550878, 69550882, 69550886, 69550890, 69550894,
- 69550898, 69550902, 69550906, 69550910, 69550914, 69550918, 69550922,
- 69550926, 69550930, 69550934, 69550938, 69550942, 69550946, 69550950,
- 69550954, 69550958, 69550962, 69550966, 69550970, 69550974, 69550978,
- 69550982, 69550986, 69550990, 69550994, 69550998, 69551002, 69551006,
- 69551010, 69551014, 69551018, 69551022, 69551026, 69551030, 69551034,
- 69551038, 69551042, 69551046, 69551050, 69551054, 69551058, 69551062,
- 69551066, 69551070, 69551074, 69551078, 69551082, 69551086, 69551090,
- 69551094, 69551098, 69551102, 69551106, 69551110, 69551114, 69551118,
- 69551122, 69551126, 69551130, 69551134, 69551138, 69551142, 69551146,
- 69551150, 69551154, 69551158, 69551162, 69551166, 69551170, 69551174,
- 69551178, 69551182, 69551186, 69551190, 69551194, 69551198, 69551202,
- 69551206, 69551210, 69551214, 69551218, 69551222, 69551226, 69551230,
- 69551234, 69551238, 69551242, 69551246, 69551250, 69551254, 69551258,
- 69551262, 69551266, 69551270, 69551274, 69551278, 69551282, 69551286,
- 69551290, 69551294, 69551298, 69551302, 69551306, 69551310, 69551314,
- 69551318, 69551322, 69551326, 69551330, 69551334, 69551338, 69551342,
- 69551346, 69551350, 69551354, 69551358, 69551362, 69551366, 69551370,
- 69551374, 69551378, 69551382, 69551386, 69551390, 69551394, 69551398,
- 69551402, 69551406, 69551410, 69551414, 69551418, 69551422, 69551426,
- 69551430, 69551434, 69551438, 69551442, 69551446, 69551450, 69551454,
- 69551458, 69551462, 69551466, 69551470, 69551474, 69551478, 69551482,
- 69551486, 69551490, 69551494, 69551498, 69551502, 69551506, 69551510,
- 69551514, 69551518, 69551522, 69551526, 69551530, 69551534, 69551538,
- 69551542, 69551546, 69551550, 69551554, 69551558, 69551562, 69551566,
- 69551570, 69551574, 69551578, 69551582, 69551586, 69551590, 69551594,
- 69551598, 69551602, 69551606, 69551610, 69551614, 69551618, 69551622,
- 69551626, 69551630, 69551634, 69551638, 69551642, 69551646, 69551650,
- 69551654, 69551658, 69551662, 69551666, 69551670, 69551674, 69551678,
- 69551682, 69551686, 69551690, 69551694, 69551698, 69551702, 69551706,
- 69551710, 69551714, 69551718, 69551722, 69551726, 69551730, 69551734,
- 69551738, 69551742, 69551746, 69551750, 69551754, 69551758, 69551762,
- 69551766, 69551770, 69551774, 69551778, 69551782, 69551786, 69551790,
- 69551794, 69551798, 69551802, 69551806, 69551810, 69551814, 69551818,
- 69551822, 69551826, 69551830, 69551834, 69551838, 69551842, 69551846,
- 69551850, 69551854, 69551858, 69551862, 69551866, 69551870, 69551874,
- 69551878, 69551882, 69551886, 69551890, 69551894, 69551898, 69551902,
- 69551906, 69551910, 69551914, 69551918, 69551922, 69551926, 69551930,
- 69551934, 69551938, 69551942, 69551946, 69551950, 69551954, 69551958,
- 69551962, 69551966, 69551970, 69551974, 69551978, 69551982, 69551986,
- 69551990, 69551994, 69551998, 69552002, 69552006, 69552010, 69552014,
- 69552018, 69552022, 69552026, 69552030, 69552034, 69552038, 69552042,
- 69552046, 69552050, 69552054, 69552058, 69552062, 69552066, 69552070,
- 69552074, 69552078, 69552082, 69552086, 69552090, 69552094, 69552098,
- 69552102, 69552106, 69552110, 69552114, 69552118, 69552122, 69552126,
- 69552130, 69552134, 69552138, 69552142, 69552146, 69552150, 69552154,
- 69552158, 69552162, 69552166, 69552170, 69552174, 69552178, 69552182,
- 69552186, 69552190, 69552194, 69552198, 69552202, 69552206, 69552210,
- 69552214, 69552218};
- System.arraycopy(temp, 0, prob, prob.length - temp.length, temp.length);
- }
-
- private static int[] chars;
- private static void populateChars1() {
- chars = new int[10002];
- int[] temp = new int[] {32, 9, 10, 101, 97, 13, 105, 111,
- 110, 116, 114, 115, 108, 100, 99, 117, 109, 104, 112, 103, 48, 46,
- 98, 49, 160, 102, 50, 118, 121, 107, 44, 119, 45, 58, 51, 53, 52,
- 57, 56, 106, 54, 122, 55, 47, 41, 40, 124, 120, 1103, 1072, 1086,
- 113, 1080, 1575, 1077, 1085, 1090, 12540, 1088, 12398, 95, 1089, 39,
- 1604, 33, 233, 12290, 30340, 1083, 1074, 12289, 12531, 1082, 12356,
- 34, 3634, 91, 93, 63, 62, 1076, 225, 1605, 1084, 3609, 1610, 12395,
- 12375, 1585, 1087, 1608, 12391, 12488, 3619, 1091, 12390, 243, 12377,
- 1606, 61, 3629, 12473, 1578, 12427, 42, 12394, 12452, 12483, 12383,
- 12539, 3656, 12392, 3648, 12434, 3585, 12414, 12399, 237, 38, 19968,
- 12523, 1075, 20154, 12463, 252, 3617, 305, 3657, 3591, 59, 12364,
- 1073, 1583, 1099, 1079, 1576, 20013, 224, 3633, 12363, 26085, 1607,
- 43, 228, 12522, 12435, 12521, 12426, 12387, 22823, 3623, 24180, 231,
- 12450, 3621, 3618, 26377, 1100, 3604, 1081, 1587, 1593, 29992, 3637,
- 12425, 37, 246, 26032, 3588, 19981, 3626, 12373, 12418, 26159, 12371,
- 60, 21697, 22312, 26376, 3607, 12464, 3636, 3610, 1095, 12471, 12525,
- 2366, 19978, 12362, 126, 12358, 187, 12503, 227, 12479, 12428, 1577,
- 3627, 1093, 25105, 12524, 12367, 3605, 945, 20998, 20250, 12489, 26412,
- 12501, 183, 23398, 12467, 22269, 29983, 1601, 273, 3021, 8220, 8221,
- 20316, 1602, 1603, 35, 25991, 12472, 20102, 12513, 64, 3632, 12354,
- 12502, 12365, 22320, 20986, 34892, 23376, 32593, 51060, 21457, 12459,
- 21517, 8230, 2381, 19979, 1497, 12384, 2352, 1493, 36, 1078, 12486,
- 1740, 12510, 23567, 8226, 32773, 1600, 1588, 234, 26041, 959, 26368,
- 3611, 26102, 12496, 12469, 1094, 23478, 1581, 3405, 20837, 3614, 3649,
- 250, 22238, 964, 20010, 24773, 20844, 24066, 20197, 29702, 953, 1609,
- 1110, 21512, 949, 34920, 12461, 351, 20840, 21069, 35201, 20107, 33258,
- 12424, 1580, 232, 1101, 20214, 12481, 12300, 3652, 26009, 3586, 25163,
- 12301, 3592, 21644, 21487, 33021, 12304, 12451, 21830, 8211, 322,
- 1096, 2325, 12305, 22825, 25104, 12369, 39640, 21152, 12512, 3660,
- 12385, 241, 20026, 3639, 20869, 23450, 20449, 1092, 4304, 22909, 25968,
- 37329, 22810, 12458, 26469, 3640, 30005, 21040, 27861, 24037, 19994,
- 957, 4312, 12381, 3641, 26426, 30475, 37096, 26178, 2375, 24515, 169,
- 12491, 92, 3594, 32654, 31532, 12388, 24615, 12517, 28857, 12454,
- 21306, 2344, 36890, 12415, 65533, 12379, 244, 1492, 1377, 12499, 963,
- 2367, 28961, 20027, 26399, 32034, 45796, 35770, 255, 432, 12487, 12456,
- 22899, 20182, 25152, 29289, 12519, 44592, 3277, 1102, 12515, 1582,
- 226, 1589, 20307, 1586, 30011, 2360, 31995, 353, 29256, 229, 12393,
- 20851, 21160, 36947, 38388, 1571, 1500, 20110, 8212, 39029, 961, 26126,
- 12417, 27700, 12360, 2965, 3650, 30456, 36825, 12497, 3651, 26684,
- 28023, 3149, 1512, 31038, 24230, 24215, 20870, 22577, 1514, 12475,
- 22270, 12420, 30331, 12511, 30446, 94, 12372, 38754, 26381, 30693,
- 12431, 25945, 21518, 22806, 26356, 954, 21451, 23665, 35211, 2340,
- 27880, 21205, 3007, 960, 2350, 21270, 23433, 1591, 2368, 29305, 20301,
- 20320, 12490, 39064, 32463, 21147, 31034, 51648, 20135, 21033, 23601,
- 24687, 38382, 19977, 37117, 24335, 44032, 951, 4308, 2354, 21153,
- 3655, 21516, 12509, 269, 21271, 7841, 8364, 9733, 25237, 31449, 12480,
- 20204, 2980, 38291, 20445, 1502, 21496, 51032, 3009, 49828, 20803,
- 36164, 281, 2351, 45716, 12506, 20140, 24403, 36865, 21495, 20043,
- 20351, 38598, 235, 12474, 7871, 23545, 49324, 24847, 27425, 236, 20195,
- 24471, 956, 26908, 347, 1488, 31185, 47196, 261, 2346, 1489, 12441,
- 24320, 171, 20385, 32447, 54616, 35352, 380, 38480, 125, 27963, 50640,
- 287, 23458, 3635, 1097, 7879, 123, 3263, 22120, 12484, 7843, 601,
- 955, 19982, 12527, 31561, 39318, 12493, 36710, 31649, 20215, 30495,
- 20132, 35828, 22914, 27491, 12408, 1398, 21407, 22580, 1590, 25552,
- 35328, 44256, 21046, 962, 2357, 27671, 2379, 35199, 965, 3248, 257,
- 20108, 49884, 382, 20063, 36807, 20040, 1513, 51064, 24863, 35780,
- 23481, 47532, 12455, 26524, 51088, 25216, 2306, 245, 29616, 24314,
- 35013, 21335, 21462, 29255, 26597, 31572, 37325, 19987, 33394, 54620,
- 1705, 12465, 21578, 4320, 25151, 35299, 38899, 20170, 21475, 12495,
- 24179, 31243, 31354, 25253, 21839, 12500, 31934, 30528, 2361, 26989,
- 35270, 20854, 37324, 27969, 23383, 12514, 12376, 28216, 25910, 24433,
- 30476, 4153, 3262, 35774, 19975, 2986, 1408, 32852, 22411, 12477,
- 48372, 22797, 21450, 12419, 23454, 36827, 39135, 9632, 253, 9658,
- 4321, 259, 25628, 36335, 12460, 240, 2990, 45768, 20687, 32771, 3391,
- 37327, 21326, 21488, 12507, 248, 223, 24605, 38651, 96, 20855, 12429,
- 12397, 35745, 3349, 31435, 24819, 49436, 2992, 24191, 24341, 3120,
- 22522, 51012, 21592, 1400, 50500, 25509, 24212, 12505, 38271, 24405,
- 7897, 26080, 24030, 24120, 33457, 20809, 22478, 12298, 20876, 27714,
- 1504, 20184, 7899, 35831, 12299, 3612, 20309, 32423, 3134, 20048,
- 27665, 36733, 20379, 19990, 28040, 26481, 1574, 3606, 26360, 3135,
- 23453, 30000, 26415, 7845, 3006, 28982, 24744, 21435, 176, 2750, 1501,
- 36215, 31070, 30330, 27604, 25512, 36824, 22330, 19996, 30007, 230,
- 38306, 27231, 51221, 1381, 27005, 2975, 22363, 4317, 21482, 20808,
- 25345, 35777, 3137, 36523, 32946, 36554, 36817, 21307, 31867, 38376,
- 51068, 25918, 26143, 947, 3265, 25143, 23637, 26435, 7889, 242, 50612,
- 12468, 33521, 38498, 26631, 943, 31295, 12400, 35239, 12449, 2342,
- 24086, 1506, 3368, 21338, 12504, 37682, 20070, 21313, 249, 23569,
- 25351, 35805, 27809, 30740, 29233, 25903, 49688, 1491, 7901, 7853,
- 46020, 26408, 24067, 1573, 20171, 37197, 2369, 1594, 2327, 263, 26465,
- 45824, 25171, 25919, 3603, 28909, 32780, 31456, 28304, 948, 7873,
- 24460, 26495, 3376, 51204, 37027, 30333, 26696, 3240, 38283, 24456,
- 12508, 940, 51228, 20877, 30334, 39057, 3624, 4315, 3390, 49345, 238,
- 36153, 30721, 24029, 9734, 32622, 20225, 20849, 21463, 53944, 22235,
- 21161, 21543, 36796, 26657, 51008, 25110, 30028, 2332, 27492, 21608,
- 34255, 20889, 2997, 3221, 21521, 4314, 12494, 30001, 24555, 27004,
- 27743, 21476, 22770, 30452, 2494, 417, 1495, 969, 46972, 24050, 1569,
- 3112, 1579, 28779, 1508, 2994, 12409, 2985, 31119, 20219, 21333, 12457,
- 26053, 165, 44536, 32004, 2348, 35760, 22791, 36899, 3595, 23558,
- 22240, 9830, 35373, 3615, 31181, 20160, 1511, 35441, 12466, 36141,
- 3223, 3122, 22763, 1584, 38263, 32769, 12470, 7911, 29579, 4305, 22303,
- 1199, 21442, 50896, 51452, 20462, 28165, 20256, 35821, 45208, 20813,
- 24418, 972, 32479, 26448, 39118, 35413, 1387, 3270, 21021, 21015,
- 46300, 23436, 3608, 3238, 31350, 36895, 1570, 24072, 7875, 35813,
- 3074, 22768, 1499, 21002, 21253, 1548, 34987, 37326, 4316, 1662, 20303,
- 3393, 26679, 7847, 4152, 35797, 50836, 38750, 26395, 36896, 21508,
- 26131, 35835, 3236, 35486, 2335, 24517, 21035, 21029, 44172, 21453,
- 29699, 12378, 44396, 30149, 39321, 3638, 46041, 7883, 1711, 29694,
- 12423, 3364, 4140, 32032, 3616, 8222, 3250, 27835, 59179, 36229, 3093,
- 23627, 25506, 7907, 27468, 54868, 22836, 941, 8594, 22826, 23550,
- 20491, 23460, 30707, 3256, 27454, 32467, 9679, 20581, 27668, 20415,
- 31246, 33391, 25165, 26410, 20116, 36873, 3654, 36816, 1410, 12442,
- 36074, 49457, 38500, 1505, 21019, 25307, 36716, 2480, 21619, 54644,
- 3625, 24049, 25490, 30701, 47484, 2330, 3016, 2736, 191, 21729, 1257,
- 1098, 30041, 49548, 25103, 48708, 20570, 31080, 21151, 37202, 31169,
- 20174, 27169, 49888, 20123, 51109, 25454, 32929, 35215, 4309, 32080,
- 25972, 25913, 180, 2970, 50689, 38738, 20294, 12302, 2991, 21345,
- 20104, 32218, 35443, 12403, 23455, 215, 20999, 23548, 31215, 32473,
- 30058, 30465, 23384, 48512, 28145, 12303, 4307, 47928, 24859, 26519,
- 2995, 33410, 50857, 24535, 12516, 39564, 32452, 36148, 942, 20004,
- 27096, 3370, 38988, 36617, 38405, 26149, 28436, 29366, 23798, 38450,
- 36984, 24635, 21360, 35336, 8250, 966, 24110, 32048, 36820, 2509,
- 24247, 36861, 3253, 3378, 174, 163, 186, 26449, 36719, 12416, 254,
- 51080, 36009, 23616, 47560, 1396, 32454, 29031, 31639, 29575, 3597,
- 3246, 33853, 38395, 2503, 36136, 54924, 35265, 24182, 2622, 24352,
- 23621, 48120, 2358, 22987, 7885, 44277, 36039, 31505, 3202, 50668,
- 24425, 4145, 20987, 35268, 952, 25773, 251, 967, 3128, 12411, 7909,
- 283, 23494, 47564, 32476, 33616, 3851, 2728, 30010, 20799, 33829,
- 49464, 3375, 24378, 44397, 4323, 4322, 22788, 1749, 2337, 3359, 36023,
- 9834, 299, 1496, 24590, 31859, 25522, 38144, 7891, 26354, 12462, 36798,
- 20080, 47924, 26045, 275, 7903, 337, 1391, 22253, 12498, 1490, 32844,
- 44060, 38656, 21464, 22905, 35843, 7921, 7913, 8251, 2309, 8218, 35758,
- 20540, 51004, 35753, 50724, 32534, 21209, 38451, 21363, 4096, 44284,
- 324, 46308, 20139, 239, 20302, 2495, 22495, 22793, 2765, 2759, 8224,
- 45236, 35069, 3114, 21150, 31616, 3125, 36275, 345, 1112, 44221, 29987,
- 3247, 33267, 23130, 3384, 21315, 161, 7855, 31163, 40644, 27494, 30424,
- 36234, 28201, 21806, 22242, 20363, 39532, 3330, 4311, 35501, 25214,
- 29260, 25226, 2993, 28207, 35748, 3381, 36208, 27599, 20856, 4121,
- 50976, 24102, 40857, 26223, 35814, 31216, 25928, 35759, 8482, 51312,
- 35266, 3242, 35937, 24459, 44544, 21448, 3108, 2752, 27833, 25112,
- 2472, 27770, 23646, 20248, 51652, 27979, 29609, 20934, 30524, 4143,
- 24195, 2370, 35782, 24453, 4141, 3374, 1735, 50672, 2608, 2984, 32418,
- 1592, 36942, 12370, 39033, 1510, 4112, 24540, 1397, 54252, 34880,
- 38463, 27426, 30003, 26413, 8203, 27827, 50864, 36135, 20915, 26222,
- 36830, 25252, 9670, 31687, 30906, 35272, 3118, 1407, 167, 44288, 12518,
- 20843, 3377, 33647, 7919, 20845, 39365, 4100, 8249, 53552, 35810,
- 27515, 26666, 20811, 31665, 25353, 8722, 23500, 35469, 1503, 31574,
- 4306, 26144, 51077, 21322, 21916, 47784, 22336, 21490, 47732, 29577,
- 38918, 38469, 24231, 26031, 26089, 7917, 1111, 24503, 12406, 12368,
- 22659, 946, 24220, 27773, 28858, 23572, 21629, 26681, 32232, 3762,
- 12402, 33322, 27573, 40657, 26512, 26174, 279, 20891, 31278, 48169,
- 24577, 26371, 39764, 23427, 33402, 21452, 24211, 12374, 34915, 3110,
- 1179, 35789, 26494, 35542, 9472, 29615, 27982, 26029, 1614, 9474,
- 30332, 21834, 50504, 33041, 22812, 2734, 35874, 7893, 23041, 12293,
- 39080, 9500, 50868, 21548, 27874, 32068, 21382, 3737, 21334, 24052,
- 20122, 50948, 20241, 25511, 22855, 36939, 36130, 32500, 50556, 22686,
- 33879, 30382, 3103, 20061, 26446, 20505, 177, 3119, 973, 24065, 31614,
- 32066, 28246, 25289, 32856, 32154, 20064, 25215, 21547, 28608, 54617,
- 9660, 33268, 2339, 22833, 181, 26680, 31227, 39044, 32676, 2349, 48148,
- 37319, 339, 1114, 164, 27597, 36948, 36578, 32887, 27490, 54840, 8225,
- 32076, 39030, 38134, 23713, 20960, 20030, 47308, 4117, 35282, 20181,
- 2343, 53356, 21513, 25293, 170, 35519, 19969, 20117, 2709, 50629,
- 178, 3095, 36092, 24076, 36814, 44368, 38190, 2453, 1405, 21527, 53440,
- 26063, 1108, 25442, 36131, 35895, 51201, 2616, 20805, 54408, 2376,
- 51473, 51020, 24613, 39006, 25126, 26397, 22871, 49373, 3257, 33324,
- 38065, 20892, 24565, 20221, 3379, 54532, 46356, 2319, 23578, 37038,
- 27493, 49440, 49845, 1406, 12422, 22259, 47588, 27983, 23448, 22827,
- 30830, 1105, 27611, 3244, 22290, 24235, 36755, 26816, 35768, 22799,
- 2310, 34899, 30053, 2741, 3251, 21312, 26500, 20778, 21507, 9829,
- 35746, 32862, 4313, 20859, 31036, 24494, 3231, 38142, 12401, 39208,
- 31881, 20037, 23487, 2631, 1494, 8240, 22343, 35910, 22283, 1670,
- 371, 39046, 25925, 1392, 32057, 38431, 3233, 24178, 34903, 28459,
- 38272, 51076, 3398, 33590, 182, 47112, 19971, 22530, 2476, 32178,
- 24046, 2763, 27531, 3143, 27915, 3147, 35273, 12366, 2359, 36739,
- 2724, 21319, 51116, 44228, 2690, 36753, 49892, 25658, 20113, 45380,
- 20114, 52380, 2326, 52824, 24207, 47749, 1116, 35500, 24111, 21738,
- 6098, 21942, 22996, 38590, 32207, 1388, 29486, 33756, 21387, 2488,
- 33487, 48516, 2623, 24375, 30103, 2479, 7863, 46321, 9675, 36949,
- 44144, 1118, 38609, 49885, 20041, 52852, 23626, 28010, 39134, 54028,
- 3658, 23416, 36793, 28082, 7915, 49328, 25209, 3015, 21017, 3105,
- 47785, 45936, 52404, 28168, 29275, 22521, 23475, 30772, 363, 23425,
- 53664, 1567, 50900, 33865, 51089, 21048, 54633, 33539, 172, 2624,
- 4334, 45432, 22856, 23395, 4123, 52628, 44036, 21095, 24213, 3098,
- 31471, 27941, 21378, 1744, 30410, 29677, 21177, 29420, 28120, 4116,
- 39280, 47084, 25240, 23401, 974, 27721, 50752, 38555, 1107, 28385,
- 23470, 33310, 38442, 402, 47932, 36187, 36027, 38957, 2744, 20917,
- 20633, 23429, 27801, 27010, 3271, 21542, 26379, 24651, 39340, 38477,
- 33609, 3403, 12476, 21355, 36914, 26234, 21336, 35703, 4328, 35838,
- 25915, 27849, 27704, 38543, 26044, 25321, 25563, 2341, 26497, 35430,
- 28155, 20284, 21010, 32905, 9473, 23822, 27927, 54032, 31508, 45800,
- 38169, 35531, 36938, 12532, 21320, 3784, 39443, 184, 22885, 31192,
- 4126, 47197, 38597, 38745, 3354, 20339, 24198, 20358, 44163, 4129,
- 33509, 36259, 24107, 2751, 2482, 36913, 162, 31168, 3142, 31105, 1115,
- 54665, 20029, 20381, 12520, 4124, 35686, 31179, 21028, 24038, 2313,
- 20852, 44552, 2598, 3785, 3136, 35757, 2979, 2581, 2478, 33719, 31461,
- 2311, 25805, 19988, 21491, 35222, 21704, 35785, 20146, 20853, 50696,
- 34276, 51200, 1119, 12353, 20105, 36866, 21439, 27966, 19997, 32422,
- 2730, 38634, 38505, 32493, 39636, 48156, 2600, 20083, 36828, 24237,
- 23554, 39000, 20919, 3014, 9492, 1385, 22870, 6070, 21892, 47700,
- 7887, 21709, 38632, 24202, 26862, 2949, 24373, 36848, 8213, 2738,
- 188, 47000, 24441, 36889, 38889, 34701, 21454, 46104, 53685, 44053,
- 12405, 23089, 33464, 35775, 1379, 45224, 27431, 36864, 38081, 45348,
- 24800, 24184, 36125, 34955, 37504, 35848, 3713, 27178, 49353, 2347,
- 35468, 31361, 32461, 31199, 54000, 20848, 25285, 9633, 32972, 25588,
- 2404, 26522, 23618, 27602, 22920, 4154, 44148, 54624, 44160, 38556,
- 4101, 26434, 22830, 52572, 1409, 38468, 24448, 20551, 33775, 35752,
- 1729, 20418, 39302, 25147, 2474, 35802, 22323, 32599, 48264, 35527,
- 49444, 7877, 168, 36731, 20142, 38795, 2951, 48376, 36319, 30828,
- 38472, 30171, 21602, 45908, 3363, 52264, 27083, 21215, 21183, 20826,
- 3228, 2468, 4318, 23612, 1380, 1113, 27744, 48176, 8206, 21327, 32508,
- 30151, 25144, 20247, 21364, 1384, 8658, 20234, 38917, 36794, 28288,
- 23432, 26641, 3593, 36766, 30002, 23556, 45684, 21560, 21016, 38913,
- 3116, 7881, 36855, 65279, 25668, 20943, 29190, 1106, 30431, 23519,
- 3399, 54168, 8195, 48152, 32102, 175, 26800, 32440, 1746, 25391, 9650,
- 23186, 355, 21628, 21047, 25705, 40635, 20313, 52636, 189, 1616, 32426,
- 30097, 32026, 32435, 37240, 166, 45817, 26230, 27508, 54788, 21051,
- 24907, 2996, 35251, 27954, 1611, 22359, 26723, 48660, 33145, 20020,
- 27719, 26202, 32455, 31309, 37070, 38596, 30274, 2613, 9482, 54588,
- 32722, 2735, 3732, 50669, 28789, 21672, 2596, 3275, 26411, 30417,
- 20253, 20196, 7849, 27850, 36884, 20165, 38050, 22260, 1412, 26550,
- 25480, 27841, 25173, 20260, 21213, 31777, 27497, 38663, 26367, 28783,
- 48277, 35834, 35841, 54980, 958, 23492, 39184, 3353, 2610, 24449,
- 52397, 20572, 38706, 44608, 35696, 50630, 3757, 23681, 22266, 27161,
- 6042, 38647, 3776, 38522, 26790, 20185, 32456, 33287, 3019, 37444,
- 2617, 23707, 23459, 2753, 8595, 20516, 25239, 48260, 27211, 32477,
- 38761, 20498, 32933, 25955, 32763, 24187, 3613, 29399, 21531, 53076,
- 24149, 35388, 34917, 36196, 367, 35762, 27663, 3266, 50577, 21344,
- 29105, 361, 4330, 30427, 31569, 47476, 27036, 38215, 25551, 40658,
- 44048, 22992, 37239, 12619, 12382, 36969, 51649, 29238, 772, 22294,
- 3351, 4325, 2969, 2602, 3226, 21483, 36149, 38989, 35342, 24481, 24536,
- 4156, 47140, 26432, 3100, 23553, 27810, 24746, 36008, 34013, 36935,
- 31186, 4097, 4324, 38626, 3366, 3719, 33510, 38364, 20304, 48124,
- 4151, 3264, 36152, 24322, 7867, 29483, 47568, 9608, 23614, 39154,
- 23452, 33655, 38470, 27177, 29664, 27507, 3630, 21367, 190, 34382,
- 2463, 29872, 26579, 51665, 32511, 22971, 26619, 39592, 21103, 2635,
- 23613, 21478, 27442, 54540, 20202, 36611, 27996, 38381, 28310, 28286,
- 32113, 32321, 25976, 20493, 3394, 179, 32097, 12412, 3761, 44620,
- 950, 38138, 25343, 45784, 40670, 36879, 20912, 1394, 26893, 23653,
- 2606, 28988, 21733, 25937, 47141, 21106, 1617, 21018, 44208, 51333,
- 21477, 357, 2497, 36127, 23431, 247, 33050, 25774, 33303, 2492, 24444,
- 2716, 1378, 51216, 3138, 1726, 3751, 22721, 31821, 48149, 24188, 22969,
- 8593, 25246, 3018, 6035, 29790, 38914, 20006, 49569, 38386, 29087,
- 24040, 1402, 40060, 1241, 1615, 49549, 35498, 36175, 54364, 2312,
- 7851, 44428, 2604, 35242, 30343, 1187, 25176, 54664, 27888, 2672,
- 28814, 53468, 26152, 24930, 378, 32932, 21381, 38544, 2364, 23566,
- 25033, 22243, 38047, 31069, 20908, 27138, 26292, 22280, 32681, 34507,
- 32819, 1171, 23721, 28151, 20016, 27993, 23381, 12389, 3745, 31383,
- 33337, 48652, 24133, 3235, 2562, 21494, 34220, 39035, 2726, 32013,
- 20419, 21809, 48320, 20816, 31359, 21220, 3942, 23457, 28526, 25324,
- 20914, 32025, 21862, 30064, 20055, 3254, 44305, 21361, 26757, 35672,
- 732, 26366, 36339, 185, 29066, 20005, 23546, 3372, 24109, 38627, 35611,
- 51656, 54632, 3760, 4155, 710, 20276, 31680, 38236, 20497, 2336, 2588,
- 24466, 3738, 20839, 46108, 1572, 2745, 3205, 53412, 32147, 50557,
- 35946, 2958, 3077, 3765, 36001, 24693, 53580, 1618, 26576, 33073,
- 50872, 38996, 21050, 4310, 4157, 27598, 31958, 21551, 23631, 23064,
- 24310, 24039, 38646, 32858, 24656, 50808, 26087, 6036, 22025, 24618,
- 20896, 35377, 20315, 26472, 23565, 49900, 303, 22815, 32451, 4332,
- 50632, 1498, 20081, 12380, 36062, 4146, 26007, 50508, 20065, 20874,
- 36996, 35442, 33016, 24739, 22919, 35338, 28006, 20992, 20474, 2620,
- 30342, 32487, 6016, 2719, 54805, 37089, 24196, 29378, 24489, 21402,
- 7865, 32039, 46160, 48373, 3530, 36317, 6040, 21066, 20652, 54872,
- 25484, 20729, 25505, 39740, 36024, 20966, 31689, 20024, 297, 47336,
- 39034, 31526, 32908, 29359, 40092, 2711, 32043, 2732, 23560, 24112,
- 2507, 39278, 36032, 39069, 6047, 45733, 20861, 36000, 39038, 50528,
- 25191, 2470, 32117, 51592, 25554, 27402, 52488, 25346, 35823, 12541,
- 27798, 24576, 25645, 21024, 24351, 26263, 35613, 4122, 31481, 2331,
- 26477, 21332, 26332, 3600, 48324, 44201, 4106, 38867, 22902, 3356,
- 4142, 1734, 26725, 39304, 3749, 28020, 36129, 36842, 33180, 7895,
- 33635, 25630, 36991, 44033, 32000, 33026, 44540, 36012, 55176, 35302,
- 3906, 22679, 23544, 25463, 25311, 24093, 20159, 23447, 26463, 48520,
- 47728, 3392, 38281, 52293, 21776, 7869, 34394, 28895, 3255, 9671,
- 35036, 52376, 46412, 26997, 45804, 22995, 49496, 29273, 295, 36718,
- 12534, 28966, 26479, 20511, 40575, 27873, 21109, 22256, 29976, 22352,
- 3129, 32701, 32431, 30784, 8801, 33014, 12316, 2673, 333, 27605, 47536,
- 8470, 326, 1404, 3659, 32993, 29356, 22918, 24059, 21073, 30070, 1389,
- 44553, 3954, 26124, 20025, 36028, 25935, 24778, 45572, 3008, 2455,
- 22609, 12492, 32260, 24464, 51613, 369, 4326, 2742, 2439, 3010, 30563,
- 23506, 2460, 23792, 50892, 30142, 12478, 8730, 26262, 7857, 30436,
- 39131, 3333, 32842, 36605, 39749, 36035, 3144, 32570, 3274, 37073,
- 24895, 49465, 26588, 25276, 39178, 12413, 46988, 21058, 48143, 31085,
- 36305, 40664, 33080, 22307, 36805, 50506, 46993, 21171, 26071, 32784,
- 22818, 50728, 26082, 32884, 1709, 53804, 49696, 2625, 35914, 30561,
- 23485, 21127, 29986, 27784, 23615, 54856, 40165, 38452, 28204, 23551,
- 54217, 3538, 28771, 318, 3754, 32988, 23467, 3921, 3771, 31454, 25361,
- 9678, 32618, 35506, 7929, 24377, 45812, 21311, 28187, 35799, 20465,
- 20596, 45320, 34399, 3964, 9516, 30423, 26242, 21621, 54637, 39068,
- 33288, 38520, 35387, 12421, 38024, 33150, 46021, 34429, 35504, 21191,
- 26716, 34180, 26691, 54876, 52964, 24115, 35370, 35379, 29123, 28193,
- 24402, 3505, 25688, 26480, 36213, 1383, 25481, 26639, 23547, 45216,
- 9618, 52768, 28369, 32990, 22635, 28287, 26106, 38534, 47492, 38752,
- 48155, 54200, 36882, 45813, 3385, 8592, 20210, 38542, 52286, 23526,
- 37636, 49352, 23439, 33945, 50977, 27905, 47549, 1399, 52712, 45212,
- 6031, 20489, 36960, 21414, 20180, 4139, 24537, 3735, 32118, 36664,
- 21218, 35023, 25265, 3245, 51339, 24369, 36557, 27973, 44400, 20001,
- 27794, 27193, 38538, 49437, 25244, 35793, 28595, 30719, 48177, 4150,
- 20046, 21917, 24694, 20161, 1390, 21556, 38525, 4102, 23736, 34101,
- 50732, 39277, 28070, 21561, 22362, 29482, 49692, 51456, 3361, 3127,
- 29645, 52285, 32020, 53364, 52292, 39746, 47448, 36870, 27503, 2953,
- 3239, 2721, 2371, 25439, 12359, 20961, 20129, 38911, 40481, 48288,
- 47144, 22612, 31283, 45843, 20860, 21934, 32650, 39770, 53469, 24681,
- 3383, 32244, 8734, 37030, 34411, 3590, 20804, 54596, 35079, 25317,
- 3382, 22258, 28798, 40845, 53945, 2566, 4327, 23562, 50416, 50501,
- 20598, 27427, 48513, 24748, 8804, 28872, 22338, 1722, 9507, 31455,
- 3926, 38075, 39537, 1739, 54869, 20057, 30913, 26195, 3725, 2489,
- 25187, 19976, 21063, 37266, 40784, 23456, 25201, 25731, 32210, 24597,
- 44057, 46976, 24291, 1742, 26580, 30418, 22863, 6020, 1736, 40614,
- 31478, 54256, 28784, 35226, 4144, 12407, 32553, 40736, 20648, 40065,
- 20882, 12396, 45376, 47672, 23039, 23380, 20262, 21169, 21807, 22937,
- 316, 28129, 36786, 30435, 36151, 31563, 50676, 33740, 35009, 20928,
- 22841, 20255, 24785, 2447, 47548, 27578, 50616, 35044, 45912, 3777,
- 39151, 32005, 35422, 47480, 24935, 36650, 24452, 20249, 28072, 54056,
- 4118, 22278, 33437, 2328, 20405, 32536, 25138, 20439, 36067, 22351,
- 20384, 26157, 2338, 2583, 23517, 3000, 2438, 3342, 25277, 9488, 28903,
- 1382, 29392, 23559, 35465, 20173, 49332, 29978, 23142, 36020, 28014,
- 52828, 22622, 23156, 6043, 63243, 26792, 3755, 20964, 3126, 968, 1958,
- 28271, 24525, 32925, 23385, 23486, 40763, 9642, 1201, 12453, 8805,
- 8776, 9478, 47566, 3620, 28363, 26564, 24499, 9553, 12307, 32047,
- 38321, 22681, 31062, 3661, 37322, 39550, 8745, 44152, 38145, 26700,
- 35786, 20559, 36763, 25196, 26417, 38548, 47200, 21734, 25569, 23610,
- 26286, 26970, 29748, 27683, 22311, 2486, 34966, 2305, 20280, 24658,
- 1403, 21162, 27818, 33109, 26834, 1688, 36973, 30952, 9617, 8231,
- 49468, 2465, 37109, 1507, 8208, 28079, 35386, 25964, 38920, 52280,
- 21092, 32879, 32489, 21416, 33136, 3938, 22805, 54744, 52840, 22524,
- 33298, 35206, 49660, 49849, 20685, 3207, 55148, 25250, 26228, 28418,
- 30422, 33459, 51208, 3520, 36681, 36134, 38972, 20272, 9576, 26364,
- 38772, 48128, 52629, 20659, 46304, 35712, 26118, 2626, 2694, 29287,
- 2714, 2565, 30496, 54693, 31077, 32094, 23244, 27785, 48036, 2693,
- 40599, 23435, 9600, 36867, 27530, 33891, 46608, 2725, 54021, 26333,
- 2586, 47088, 9578, 29572, 27931, 24754, 33033, 34907, 33104, 26753,
- 9524, 23563, 3272, 21746, 9619, 33778, 28716, 3400, 26391, 2950, 25581,
- 22696, 45720, 3631, 24598, 32724, 24080, 22346, 3764, 23043, 3733,
- 38378, 36741, 49340, 20426, 3739, 23110, 25235, 1401, 25499, 6086,
- 28508, 38936, 9552, 31890, 36190, 52992, 29980, 29942, 29240, 21009,
- 32173, 30284, 27839, 3923, 3482, 52980, 21331, 21568, 38915, 21484,
- 28392, 20599, 44600, 2377, 26611, 2380, 33495, 33151, 58853, 36829,
- 36133, 38182, 3206, 25313, 32791, 36951, 38454, 31558, 38712, 30246,
- 2591, 22727, 12685, 63688, 3908, 40636, 1109, 8704, 2355, 47581, 36186,
- 24321, 24509, 32340, 33618, 24544, 46384, 1169, 48624, 4222, 40723,
- 33707, 4171, 3512, 3111, 36963, 24745, 2496, 44061, 35037, 23652,
- 3602, 9496, 27901, 30690, 2723, 2727, 31245, 48337, 38518, 32937,
- 3535, 54140, 3514, 8811, 63242, 26059, 25954, 32943, 33832, 36341,
- 3714, 1968, 33406, 25340, 3716, 2458, 12404, 25269, 20206, 50472,
- 25140, 20693, 3214, 4331, 21172, 9604, 24594, 32854, 2632, 2595, 28009,
- 28041, 9532, 6071, 22068, 6033, 33395, 27934, 32302, 35889, 12355,
- 47792, 32974, 3767, 4244, 20975, 24125, 54889, 3515, 38083, 6038,
- 27171, 25193, 3117, 28431, 20663, 33713, 26690, 25613, 6041, 20391,
- 47004, 28139, 44200, 6091, 30722, 33261, 38459, 50644, 29141, 3628,
- 35330, 22900, 30059, 22865, 37347, 328, 2333, 20035, 37101, 36797,
- 29436, 51217, 30805, 4113, 47100, 34913, 3501, 35029, 20271, 45367,
- 40479, 36575, 33673, 44192, 3742, 36880, 24382, 20134, 3146, 31348,
- 50620, 28096, 37341, 3079, 27687, 2324, 26086, 38322, 35064, 3956,
- 49552, 20094, 38453, 2972, 27748, 711, 28342, 3599, 33694, 27735,
- 51676, 3371, 39854, 23703, 3373, 46973, 30908, 27807, 3380, 23696,
- 25973, 30123, 32441, 44760, 8207, 20989, 8236, 35477, 22618, 8451,
- 39039, 33489, 38155, 26460, 3367, 36104, 3936, 4329, 34588, 50756,
- 20841, 3115, 3402, 9572, 22934, 28809, 33455, 34425, 29827, 25514,
- 9312, 44508, 40836, 24518, 37492, 29554, 52509, 34214, 28818, 27946,
- 6021, 31206, 30130, 28511, 8319, 39166, 13217, 46028, 20223, 2582,
- 2733, 23019, 20940, 33126, 26694, 2459, 29028, 3335, 26781, 23233,
- 36857, 26575, 36745, 33836, 28404, 20044, 38642, 32966, 9565, 25106,
- 36300, 33804, 38428, 27583, 54609, 28034, 27877, 2477, 32963, 9571,
- 3358, 32209, 30636, 26538, 31908, 34385, 3722, 28748, 44204, 33576,
- 35731, 29618, 51096, 26216, 3209, 25299, 2703, 38108, 6072, 3789,
- 9313, 23068, 27396, 35264, 3078, 25429, 4239, 55092, 32442, 9557,
- 27542, 24324, 29245, 47561, 25381, 9563, 38360, 32531, 26441, 2434,
- 26628, 20056, 37857, 9564, 3665, 25331, 4017, 34389, 12297, 20957,
- 25298, 52384, 47553, 25943, 3523, 36367, 48276, 21097, 29916, 32626,
- 3598, 22633, 25308, 3540, 28176, 31807, 28845, 25026, 52649, 33747,
- 51313, 47049, 28248, 3334, 21330, 3769, 36843, 1962, 38485, 47803,
- 1657, 26194, 3962, 36742, 26172, 23588, 30127, 38177, 36214, 32959,
- 32882, 20982, 36992, 40802, 20179, 27424, 20018, 28450, 25932, 24674,
- 27745, 9475, 20740, 29627, 48292, 33146, 3928, 32764, 36941, 1927,
- 32318, 26421, 35722, 35010, 3939, 21193, 44264, 26525, 22296, 3107,
- 39569, 39658, 2637, 22615, 19992, 28171, 37034, 31684, 39575, 2454,
- 26609, 26825, 24736, 9559, 6081, 32317, 33529, 20126, 24223, 21365,
- 31726, 50880, 25130, 21247, 35041, 33293, 22868, 25975, 24422, 38929,
- 8242, 24500, 32439, 4120, 2715, 34218, 32291, 28330, 27298, 3720,
- 25671, 1509, 36933, 38928, 12296, 4757, 37291, 26132, 51105, 289,
- 37228, 24062, 32420, 3302, 25233, 50520, 35261, 9569, 6076, 27713,
- 21943, 27155, 35033, 37428, 8976, 24163, 12530, 25142, 26049, 12306,
- 9580, 24069, 36194, 24467, 32958, 54861, 54952, 23531, 45712, 22369,
- 21368, 49325, 291, 26092, 9654, 25286, 27284, 32645, 8706, 32224,
- 21170, 36981, 36965, 39376, 24189, 9508, 7923, 24140, 2710, 30416,
- 26705, 20420, 37969, 4160, 53216, 33777, 47161, 35657, 32153, 25014,
- 26119, 28860, 25424, 36986, 30244, 2334, 9568, 3780, 28378, 1613,
- 26001, 24478, 9562, 8729, 4114, 28902, 2696, 23542, 38149, 21654,
- 9495, 31049, 49836, 51600, 34678, 31895, 27489, 30086, 21696, 54844,
- 49800, 9567, 21682, 30473, 9661, 50688, 27627, 23396, 9561, 21427,
- 21443, 3601, 21570, 48380, 29943, 29467, 54728, 27475, 36321, 34349,
- 3779, 27891, 31896, 48736, 31281, 8194, 3237, 1960, 22218, 27882,
- 24323, 34183, 33538, 40654, 2451, 6075, 27875, 36724, 32928, 30862,
- 30555, 3853, 36393, 44275, 36235, 33900, 21576, 36771, 2329, 24742,
- 33108, 22374, 21514, 29595, 25402, 9574, 38684, 28797, 20937, 23476,
- 38515, 36801, 32433, 26165, 3123, 32472, 28580, 33256, 50613, 39511,
- 51316, 29038, 24490, 34269, 12308, 1964, 30899, 24796, 24033, 9577,
- 29239, 36180, 12361, 20818, 25644, 24708, 23507, 23529, 45576, 3517,
- 775, 12309, 12640, 21741, 26361, 44480, 23731, 22985, 24551, 36291,
- 29926, 2323, 23576, 8359, 23449, 25720, 8718, 50529, 28611, 20237,
- 30196, 2475, 6082, 44257, 22922, 2731, 35258, 22982, 23389, 23195,
- 21857, 9555, 36776, 36328, 25136, 20141, 2754, 37057, 9484, 25670,
- 34081, 34923, 28781, 32736, 38517, 24815, 8992, 22475, 2437, 24713,
- 26885, 53080, 1922, 24344, 50980, 30879, 35859, 49844, 30021, 47592,
- 39048, 35825, 47101, 31570, 6044, 30865, 23574, 36192, 2603, 33714,
- 33976, 9558, 2962, 36920, 24904, 8993, 51460, 3086, 20387, 2471, 1683,
- 33075, 9575, 20239, 9566, 22766, 21223, 48393, 36777, 8721, 3503,
- 34746, 33738, 9651, 23490, 35492, 3243, 26093, 30887, 7905, 4147,
- 20538, 9825, 25200, 2441, 23305, 7927, 24573, 29157, 26187, 38519,
- 23888, 22443, 20607, 47016, 26612, 6050, 9570, 29017, 9612, 36132,
- 36182, 25195, 9616, 9556, 47533, 21202, 267, 37707, 47582, 32954,
- 24118, 27836, 9579, 21520, 33251, 51901, 27987, 24190, 2567, 30140,
- 21098, 35480, 2307, 3508, 6026, 26088, 24735, 2593, 9573, 27867, 36655,
- 38971, 38613, 32918, 54801, 8978, 26020, 1393, 26827, 24185, 29923,
- 12357, 39336, 31379, 53588, 28422, 37749, 22661, 26012, 1203, 25369,
- 35351, 39514, 31911, 21305, 731, 3081, 20124, 1672, 22402, 20820,
- 4335, 26627, 2406, 28856, 24259, 51256, 44537, 20296, 3758, 35488,
- 8747, 32416, 40643, 30408, 53596, 51061, 38160, 12622, 8233, 8810,
- 29454, 8710, 32899, 22859, 44068, 23035, 28059, 32257, 51328, 30406,
- 25830, 22519, 37002, 46112, 22675, 29747, 32202, 39063, 8201, 22857,
- 32938, 45436, 47673, 34503, 50773, 47800, 25198, 39536, 2487, 25159,
- 35980, 48268, 29468, 36784, 37111, 20542, 54060, 21966, 53448, 23611,
- 1386, 24609, 39128, 25366, 2739, 49905, 2568, 39542, 52880, 3778,
- 9560, 47017, 25475, 12444, 23815, 21908, 3222, 25806, 20096, 729,
- 33328, 28388, 36774, 34562, 24171, 37628, 31389, 50420, 39023, 25302,
- 36394, 1415, 22730, 21931, 1411, 28092, 38599, 7859, 33883, 31282,
- 50920, 32716, 35832, 38686, 24910, 48296, 54253, 38640, 33311, 8214,
- 6039, 33039, 22378, 47116, 54812, 21083, 49912, 35806, 38560, 31946,
- 3267, 31957, 9314, 32768, 52268, 54925, 8202, 26842, 24265, 49492,
- 8561, 46377, 35433, 1413, 20801, 20625, 49910, 8235, 32982, 24357,
- 36154, 35576, 26799, 30462, 53441, 271, 26438, 24443, 9554, 32822,
- 25080, 52272, 45453, 6084, 39438, 54045, 35380, 22528, 311, 21767,
- 36637, 38109, 2743, 22654, 25300, 32437, 34928, 25169, 20047, 35856,
- 30990, 4725, 38506, 2469, 20973, 50628, 37257, 21544, 40527, 24724,
- 30742, 24070, 25496, 24330, 32893, 46121, 21566, 25758, 38592, 29151,
- 25259, 22771, 26247, 36713, 728, 36093, 8712, 6023, 34909, 38901,
- 36712, 28415, 20208, 22958, 6017, 29611, 3304, 40511, 31232, 37679,
- 38400, 33289, 1748, 54413, 35426, 31292, 26647, 51025, 4245, 21351,
- 6030, 20932, 28504, 45944, 52395, 24950, 39015, 47001, 31918, 2534,
- 53584, 22561, 2407, 23004, 20976, 32602, 26894, 29246, 38152, 25958,
- 49689, 26447, 37666, 3768, 2408, 33889, 27133, 47676, 45328, 32874,
- 33167, 31661, 53444, 1777, 31048, 50883, 36493, 38512, 28900, 33633,
- 1632, 24505, 21861, 23725, 23229, 27738, 22403, 30165, 47111, 12643,
- 40718, 28846, 38401, 51340, 22334, 3337, 27893, 2605, 25166, 47579,
- 44040, 37995, 38393, 40372, 39364, 27972, 63731, 24524, 50937, 51697,
- 37011, 21350, 50837, 21091, 26607, 51137, 32483, 21563, 31452, 28085,
- 30896, 53433, 3545, 26257, 3773, 22993, 1563, 54984, 27450, 50526,
- 31609, 33452, 27852, 34174, 25206, 29808, 28687, 23047, 33294, 40483,
- 20661, 34972, 23528, 32396, 20658, 22842, 33678, 1769, 24942, 28938,
- 20667, 20523, 49901, 38617, 23777, 28107, 36891, 52265, 23624, 21449,
- 54504, 50743, 23849, 3524, 23527, 44867, 35851, 29788, 33292, 23072,
- 21780, 1717, 51596, 35930, 2707, 3924, 24266, 26704, 24840, 20817,
- 21674, 32541, 25320, 31298, 4127, 28866, 35440, 27233, 3495, 27974,
- 22043, 49772, 25539, 23159, 33796, 33988, 24288, 24680, 20918, 25312,
- 23002, 8743, 3647, 24193, 27779, 30290, 32186, 44596, 4170, 4018,
- 32466, 40831, 20329, 35676, 1959, 27844, 12310, 23660, 23581, 51424,
- 22534, 35347, 38577, 24358, 40634, 31258, 20806, 24944, 45149, 47540,
- 3395, 52968, 1633, 22616, 34989, 4223, 32469, 24685, 27185, 28382,
- 39547, 51104, 12311, 35868, 25562, 26517, 20052, 27589, 12410, 8764,
- 39366, 52432, 26224, 33831, 63246, 33469, 20736, 3546, 29422, 19985,
- 3663, 3094, 3763, 37051, 21195, 25040, 24931, 32922, 36924, 29376,
- 36898, 37559, 38563, 31150, 34253, 32445, 28113, 36628, 26685, 33485,
- 28843, 36785, 36143, 20399, 21574, 20002, 1929, 24808, 2467, 25799,
- 6078, 32190, 1395, 38739, 3218, 29401, 21460, 38666, 50516, 8229,
- 36212, 27965, 30526, 23273, 38568, 25885, 23391, 32490, 28192, 36808,
- 1612, 33922, 28357, 6018, 20341, 32501, 733, 6032, 32023, 23608, 36831,
- 4637, 2569, 50984, 23330, 21208, 33805, 9835, 20175, 26742, 45336,
- 52860, 3484, 51453, 23884, 9792, 9794, 31351, 39759, 22435, 24676,
- 40169, 31992, 1923, 3666, 45769, 28024, 24432, 27465, 25220, 1707,
- 25802, 33178, 30044, 970, 22915, 24917, 44404, 45815, 44984, 47029,
- 20011, 27511, 36139, 4653, 36156, 24429, 28142, 3664, 45440, 30168,
- 26689, 34109, 52769, 25764, 38499, 54756, 36629, 34945, 40180, 22570,
- 35997, 29425, 2695, 33274, 29301, 29421, 33446, 53011, 48716, 34092,
- 33683, 38307, 34030, 38654, 9674, 28057, 22079, 26801, 44049, 21897,
- 30861, 24339, 45909, 39292, 29081, 38570, 26097, 29417, 22467, 9426,
- 25448, 21890, 53360, 46319, 21346, 34900, 28393, 50725, 40560, 28331,
- 29518, 25342, 3740, 53560, 50772, 50521, 24367, 20767, 1685, 34430,
- 21340, 36424, 52789, 35698, 36744, 20941, 26197, 38035, 6025, 39164,
- 2999, 8727, 29237, 25996, 36893, 54400, 21385, 32156, 23067, 63728,
- 32294, 54260, 32368, 24801, 32434, 33993, 20911, 44417, 20285, 36362,
- 34277, 8719, 32705, 36649, 2536, 4661, 22882, 29756, 21525, 24616,
- 27472, 21155, 37255, 24677, 28516, 34924, 48388, 54016, 2535, 29228,
- 45458, 28548, 25273, 36974, 29539, 39554, 37941, 30827, 51704, 55141,
- 35947, 20597, 20534, 25135, 3536, 27585, 22739, 4098, 33931, 45180,
- 25377, 39062, 24085, 20923, 37782, 21280, 34384, 20613, 25243, 52392};
- System.arraycopy(temp, 0, chars, 0, temp.length);
- }
- private static void populateChars2() {
- int[] temp = new int[] {
- 49472, 54732, 38391, 51669, 49556, 20266, 46024, 32617, 21898, 36930,
- 36600, 25746, 24858, 38620, 36015, 9668, 33550, 23518, 26528, 36562,
- 50685, 30871, 24311, 32789, 55192, 4148, 4840, 45772, 2652, 47168,
- 25407, 1926, 50780, 49380, 4621, 35880, 35582, 36066, 21246, 54392,
- 31844, 1690, 3109, 4224, 29408, 9315, 22916, 47215, 54536, 20670,
- 3365, 22287, 23014, 32592, 30789, 64257, 27922, 22888, 37528, 37066,
- 30079, 32191, 4632, 25818, 30033, 29738, 38728, 46989, 24034, 53952,
- 1784, 63743, 36203, 2974, 27703, 47456, 29544, 23617, 30095, 46301,
- 25197, 26820, 54036, 33144, 24764, 25242, 1928, 26280, 27675, 1660,
- 50536, 26539, 730, 28639, 33541, 4768, 34311, 19993, 28316, 37912,
- 36172, 50648, 37237, 3001, 1211, 27688, 25776, 30683, 50024, 28448,
- 45392, 32518, 4813, 2959, 21497, 45803, 22904, 46244, 34886, 32564,
- 34809, 27506, 27754, 3276, 52236, 4704, 50684, 3350, 33970, 28525,
- 8260, 26352, 28381, 1414, 20995, 53084, 24841, 23947, 48712, 53948,
- 26114, 53461, 26898, 2599, 33382, 48317, 3346, 50040, 35803, 29281,
- 54841, 8800, 39540, 1634, 25042, 21472, 27631, 25856, 29282, 29226,
- 1665, 21187, 3303, 21163, 21796, 20786, 25304, 3232, 25745, 8243,
- 20513, 12542, 28180, 25582, 4616, 21703, 28322, 32465, 50952, 9758,
- 21400, 38125, 32930, 50997, 349, 2697, 4333, 54785, 34560, 38797,
- 46307, 24343, 20390, 36171, 54589, 50517, 39578, 12291, 38397, 4773,
- 32085, 38742, 20984, 1934, 36002, 29004, 37238, 26420, 52896, 30591,
- 1673, 3746, 40493, 24055, 36910, 33218, 24825, 36161, 39588, 6034,
- 52972, 21371, 24088, 26543, 38290, 24043, 19995, 20054, 38062, 37670,
- 21034, 47589, 50532, 29369, 48279, 49832, 21681, 44512, 33030, 30067,
- 33433, 38669, 21273, 25384, 20111, 36158, 33821, 20467, 51608, 22894,
- 6048, 23194, 32330, 21535, 9827, 21693, 38136, 29492, 26179, 34676,
- 21676, 39442, 29642, 26039, 24688, 6087, 28655, 8234, 25260, 4845,
- 48744, 37198, 45264, 27832, 26127, 49244, 31056, 28500, 4119, 38464,
- 37129, 2373, 31067, 45459, 21078, 28189, 39729, 30137, 20305, 54047,
- 21683, 12295, 30450, 3734, 33235, 51069, 36007, 47605, 8756, 26635,
- 28044, 22372, 31579, 38041, 51276, 28169, 63729, 3539, 47788, 63730,
- 33351, 25836, 23403, 32670, 25417, 2717, 49397, 52237, 8739, 21123,
- 23828, 24217, 21388, 32960, 32737, 29128, 46496, 47160, 24789, 32011,
- 40863, 35961, 25010, 49512, 3510, 25380, 26151, 20240, 27733, 32160,
- 24604, 20167, 20605, 24700, 20677, 32114, 265, 29508, 27819, 3937,
- 47353, 33624, 39282, 24161, 33152, 48400, 32568, 3986, 34542, 46523,
- 24417, 49604, 26643, 21688, 3461, 20365, 28514, 36874, 4709, 21523,
- 31966, 48731, 38420, 3669, 1776, 45285, 3139, 37122, 21129, 29229,
- 7861, 27498, 2791, 24868, 28147, 25447, 37549, 23071, 39041, 36752,
- 20136, 45789, 36795, 53416, 38886, 30643, 44260, 54057, 30399, 22963,
- 35850, 3208, 2575, 33909, 33980, 38203, 3215, 33192, 38665, 22949,
- 37806, 20553, 4149, 22353, 45797, 36138, 285, 33540, 26729, 39281,
- 20282, 30697, 35186, 25153, 50865, 20711, 24501, 28417, 36059, 22533,
- 3087, 54792, 32923, 31515, 21049, 38614, 3930, 50656, 33181, 33519,
- 21093, 8560, 46500, 25088, 21912, 36887, 4133, 28911, 1779, 3905,
- 25292, 3080, 33086, 37233, 25788, 22942, 32499, 21481, 30385, 1758,
- 25335, 33290, 36735, 1932, 47952, 6096, 12615, 2314, 35987, 8362,
- 25793, 36011, 52825, 24833, 47113, 29312, 24962, 31096, 20698, 22602,
- 54224, 31109, 28792, 35207, 27695, 33426, 45000, 31520, 21855, 22132,
- 40548, 33606, 37204, 44844, 36758, 22816, 33034, 22285, 27224, 31528,
- 4720, 48157, 27054, 53581, 46096, 22890, 51320, 31291, 22941, 39378,
- 22952, 52492, 35475, 32566, 53328, 35598, 3904, 26954, 26217, 21248,
- 28921, 32752, 29006, 30897, 51092, 25998, 39567, 22774, 25970, 22040,
- 4232, 30460, 64258, 23541, 23477, 28810, 2960, 27225, 33995, 35776,
- 21555, 44845, 31909, 36923, 22586, 33032, 48164, 8467, 45397, 32709,
- 4752, 30776, 32380, 9664, 31712, 21705, 20028, 1635, 24908, 10146,
- 30770, 4125, 23451, 1931, 3934, 23020, 30967, 22368, 3782, 33018,
- 27249, 24307, 3224, 50641, 33139, 44648, 21410, 3804, 28907, 35772,
- 3662, 8711, 53556, 47680, 4843, 32233, 36330, 1920, 3910, 28879, 35920,
- 3148, 25096, 24807, 40607, 21038, 22122, 35998, 12641, 37772, 36530,
- 1778, 53748, 38695, 27815, 3667, 54848, 52632, 40441, 49789, 28183,
- 39173, 28291, 30162, 33721, 35408, 21895, 20022, 40517, 40335, 2412,
- 45433, 32331, 22581, 28212, 20857, 26976, 21534, 22075, 28317, 38553,
- 40667, 25674, 30959, 34442, 22564, 37045, 46076, 27778, 33098, 25309,
- 38053, 31363, 4755, 21999, 4103, 35784, 33905, 45347, 2712, 12445,
- 36031, 32363, 53456, 31209, 2790, 47551, 47805, 25797, 54784, 53224,
- 34028, 36016, 24428, 3548, 35885, 33131, 33392, 20137, 28976, 20457,
- 1961, 54268, 20007, 38748, 46392, 4336, 20985, 32961, 39165, 44054,
- 23466, 47148, 36720, 2498, 54172, 1936, 26531, 9316, 6077, 20828,
- 26775, 47704, 33419, 33453, 48064, 6080, 38476, 33334, 37231, 38208,
- 25513, 12446, 33733, 45927, 8562, 22839, 40509, 3772, 47751, 30703,
- 27387, 32027, 22317, 38639, 22365, 22247, 52832, 31302, 24245, 28170,
- 21321, 33031, 29814, 34593, 34468, 1686, 25172, 32610, 36386, 21860,
- 2464, 37259, 20521, 28577, 51396, 21710, 53020, 38025, 20725, 21329,
- 54001, 9672, 48165, 20754, 365, 49104, 38156, 51677, 54645, 27760,
- 30733, 25334, 2963, 36877, 21467, 1641, 52845, 38343, 24392, 29298,
- 32544, 47217, 29138, 38593, 3347, 34299, 2409, 4161, 8857, 33564,
- 37041, 37509, 38383, 10084, 23219, 39662, 30174, 40232, 24035, 36126,
- 1637, 44050, 22291, 39449, 50741, 3343, 36538, 33769, 40179, 22082,
- 31548, 30185, 26847, 9763, 28460, 37320, 20392, 39556, 24222, 22925,
- 26623, 30522, 31237, 20901, 24248, 30922, 25436, 38085, 47204, 24717,
- 23609, 2411, 21375, 38057, 23016, 46888, 24218, 30433, 25615, 23515,
- 25379, 8629, 49704, 35878, 33216, 35463, 12599, 28251, 36852, 45225,
- 44340, 25022, 20098, 50473, 21843, 53372, 2584, 54648, 46168, 25684,
- 29791, 28641, 9702, 29705, 25114, 2415, 25238, 32177, 20062, 25079,
- 1933, 30126, 2720, 36195, 34203, 1669, 33579, 12443, 33735, 21650,
- 3747, 48197, 30928, 23472, 30294, 31805, 63736, 32110, 1681, 54764,
- 31967, 23663, 34432, 2878, 21754, 3352, 25594, 36042, 25993, 26000,
- 47352, 29993, 47021, 22196, 46504, 33795, 39894, 21465, 8806, 1640,
- 25545, 4319, 23648, 29563, 23534, 48729, 31929, 28493, 29503, 38587,
- 37489, 37340, 8210, 34583, 49452, 28103, 37474, 20632, 4848, 50885,
- 1373, 39047, 2636, 35738, 22777, 28799, 30849, 22887, 34217, 21679,
- 33203, 20254, 21557, 21295, 33147, 22092, 52524, 3653, 51593, 33184,
- 38902, 25812, 27146, 50631, 53457, 4162, 1636, 32624, 31623, 1706,
- 47691, 48709, 4635, 28100, 912, 31165, 25387, 36556, 45228, 48537,
- 33225, 31364, 8807, 59115, 26028, 52981, 31883, 39635, 29242, 1741,
- 27682, 26646, 32283, 31469, 27792, 27572, 1930, 37664, 53097, 22756,
- 34893, 22217, 32016, 25423, 51232, 25001, 24278, 32829, 12636, 33593,
- 26283, 34957, 20872, 38392, 37218, 47280, 21643, 22840, 55120, 47085,
- 21397, 21254, 45929, 59017, 1639, 45240, 2607, 22549, 49453, 21947,
- 24799, 6085, 24359, 2597, 22846, 50633, 24999, 25654, 54008, 40486,
- 39686, 9080, 31293, 6037, 35140, 4853, 25199, 4877, 48150, 37048,
- 32903, 26771, 21214, 48757, 54635, 30813, 36452, 20431, 31487, 23596,
- 2543, 3766, 30571, 2321, 25405, 30008, 25605, 35695, 21000, 25161,
- 32462, 40665, 2755, 28195, 1638, 45209, 32597, 39192, 28528, 51667,
- 55064, 4619, 4872, 26586, 6083, 26829, 37230, 21149, 32896, 53092,
- 10003, 20945, 48121, 27331, 52377, 29432, 2410, 48420, 46907, 37507,
- 314, 1924, 3668, 37467, 40629, 34521, 36804, 53916, 3227, 45828, 32051,
- 8834, 1043333, 28572, 35845, 4186, 24041, 38662, 981, 22434, 27575,
- 47576, 52644, 22484, 39171, 32299, 37676, 23633, 49500, 4776, 38275,
- 33102, 29863, 26021, 34523, 29734, 25778, 4175, 45230, 51081, 21485,
- 22869, 44161, 23830, 24427, 34223, 30036, 4134, 20979, 38622, 3984,
- 37323, 36926, 46832, 38931, 8209, 2952, 29640, 27899, 4733, 3415,
- 33899, 3305, 31204, 6089, 34509, 20322, 48127, 30050, 49368, 26837,
- 40680, 39472, 3805, 28073, 1305, 32227, 25325, 32827, 27679, 39295,
- 38991, 44732, 33436, 3216, 34935, 54592, 27985, 22576, 35065, 35948,
- 3920, 27085, 30338, 1417, 44052, 52489, 38048, 24426, 44628, 54144,
- 22750, 28790, 20864, 26869, 23604, 2537, 51229, 37165, 23094, 39072,
- 51468, 3925, 21769, 3499, 28888, 34433, 23493, 25666, 29076, 24809,
- 27900, 39286, 2539, 54017, 25472, 1468, 26310, 49341, 28136, 39129,
- 34196, 20621, 34315, 40637, 28487, 38054, 35854, 35449, 23561, 35875,
- 37039, 36106, 20314, 39551, 12533, 33948, 30447, 32673, 31391, 12386,
- 4723, 37723, 38829, 26365, 4019, 30535, 27131, 3219, 51079, 1921,
- 20177, 26198, 20323, 27694, 45257, 9824, 341, 38567, 36051, 54156,
- 25296, 12482, 359, 40594, 2499, 35617, 21564, 32781, 26803, 63250,
- 4648, 51236, 33806, 26025, 36084, 8600, 31177, 34395, 36225, 4651,
- 34074, 53668, 46405, 23113, 21756, 23532, 52252, 50432, 23234, 2864,
- 4656, 29279, 37247, 26122, 29477, 27463, 35853, 9487, 32180, 36176,
- 31108, 49399, 21486, 51564, 27766, 33008, 23835, 30631, 20900, 49334,
- 46272, 31166, 22604, 20522, 40613, 21290, 8901, 49240, 20955, 37284,
- 37049, 27197, 25995, 26388, 34067, 45196, 49933, 26632, 51664, 32058,
- 21059, 33465, 2760, 27667, 21927, 26805, 26530, 47931, 30164, 37026,
- 27308, 20360, 27495, 31373, 28954, 20446, 55121, 38982, 2457, 12963,
- 4808, 29241, 21647, 34121, 35088, 3090, 30358, 37112, 47213, 20977,
- 22030, 65104, 52983, 33492, 4707, 24936, 21633, 2538, 39423, 31783,
- 20050, 33841, 2794, 44272, 21914, 24051, 28389, 21764, 26278, 33545,
- 28905, 26454, 2413, 53420, 31072, 2795, 29802, 36276, 26943, 33833,
- 28068, 32902, 32239, 35558, 29033, 37009, 33029, 8741, 36767, 30889,
- 26329, 49100, 38389, 45448, 4781, 21936, 12430, 1207, 29509, 3458,
- 27838, 37085, 45924, 30270, 44852, 33296, 27512, 38582, 36137, 61984,
- 21980, 50619, 52856, 21577, 38533, 45132, 54804, 22013, 22931, 33729,
- 1042487, 24420, 22047, 29840, 1185, 22781, 34249, 38055, 39076, 2462,
- 32428, 12849, 34802, 38604, 2433, 35320, 2837, 32333, 39745, 36145,
- 3935, 9742, 10047, 34584, 52393, 26311, 3490, 32362, 27726, 26797,
- 2792, 30116, 21133, 47708, 9499, 24208, 29632, 34453, 39348, 26708,
- 31545, 1785, 29100, 33674, 3307, 21281, 33589, 4613, 38678, 35223,
- 21930, 29022, 9317, 45128, 31735, 28467, 33639, 25386, 3096, 39037,
- 23622, 12596, 40655, 48180, 30031, 2414, 24282, 37832, 30917, 25749,
- 38043, 2893, 29995, 40778, 22986, 36481, 27741, 22645, 33046, 25318,
- 30355, 3497, 33631, 4238, 29560, 55137, 47329, 22496, 8744, 3336,
- 28844, 45516, 2320, 37686, 33067, 30494, 49483, 55124, 39717, 26963,
- 28689, 51247, 51480, 31397, 36168, 29781, 28657, 28891, 3999, 47092,
- 34164, 6073, 1463, 52270, 2589, 1464, 21880, 3913, 34722, 2579, 39791,
- 45140, 53665, 8746, 38619, 23784, 25597, 35584, 27728, 23521, 37221,
- 33659, 1374, 46980, 45256, 27060, 21505, 29956, 2542, 30702, 28760,
- 21237, 1524, 20238, 2796, 539, 23706, 36064, 2691, 38180, 27896, 24661,
- 2510, 21673, 20506, 38997, 31353, 25327, 25438, 3473, 25375, 22350,
- 22862, 40660, 19998, 26592, 31446, 1251, 36711, 23803, 28796, 1177,
- 35586, 25487, 36953, 44316, 37304, 30192, 31377, 3909, 35122, 53681,
- 8660, 39748, 21727, 35090, 34638, 21515, 27264, 45349, 4234, 10065,
- 25874, 27526, 30699, 21610, 2353, 48764, 20008, 47609, 8758, 27012,
- 20183, 33307, 50670, 22234, 28179, 24871, 38146, 9491, 9699, 54004,
- 21585, 1781, 45210, 36983, 38930, 36159, 9698, 37145, 48141, 31398,
- 35028, 31491, 40077, 9644, 1460, 27712, 21380, 29071, 4240, 28949,
- 31161, 20051, 20871, 8757, 38449, 1966, 33620, 27975, 33398, 9480,
- 31581, 39056, 46497, 36420, 4111, 40801, 3306, 21250, 3671, 35359,
- 30860, 31407, 29306, 44636, 45124, 29792, 38583, 22366, 35609, 9582,
- 32495, 24794, 21742, 25329, 19984, 36101, 28507, 47337, 35829, 2954,
- 3670, 31319, 20166, 46385, 34224, 3642, 3525, 22880, 1043296, 34281,
- 30072, 31459, 29787, 3672, 29053, 21589, 9788, 8786, 46120, 28629,
- 27014, 34398, 59009, 33125, 32728, 31337, 46181, 331, 47896, 27204,
- 39180, 51021, 22151, 36245, 33329, 20846, 31869, 21137, 40251, 26999,
- 9483, 38175, 1041703, 29042, 50584, 2540, 25765, 26023, 26848, 30520,
- 20336, 1782, 1780, 48145, 27803, 31229, 3452, 38416, 54204, 28210,
- 55184, 32478, 47019, 28372, 31095, 50424, 34126, 31601, 30219, 2887,
- 36838, 24758, 30529, 9786, 30505, 23241, 3521, 27777, 26791, 6090,
- 21815, 29380, 25844, 59114, 21888, 32986, 23081, 6088, 24290, 31964,
- 33368, 37336, 40858, 28472, 38753, 23649, 48316, 20518, 45916, 31378,
- 27813, 35070, 48960, 31402, 36090, 28263, 38887, 38501, 23994, 48533,
- 1456, 28919, 24101, 51536, 4677, 37275, 36468, 22066, 21653, 9547,
- 25950, 22769, 2879, 23682, 30221, 20398, 39042, 44618, 32438, 31903,
- 55036, 33099, 30113, 32512, 37210, 47131, 34219, 27953, 38262, 31162,
- 12828, 26928, 29831, 22107, 33286, 24608, 3308, 37413, 28466, 34850,
- 9700, 45940, 28065, 2405, 9477, 15142, 9836, 309, 37232, 50476, 45324,
- 2587, 2541, 21700, 31914, 38446, 30606, 57348, 22404, 28552, 1523,
- 25504, 21185, 36466, 50812, 3344, 20463, 2456, 45776, 35766, 3088,
- 4779, 40595, 38082, 22687, 12485, 36077, 31925, 37756, 29712, 61472,
- 28346, 3673, 22593, 6092, 34157, 26274, 30596, 59131, 40568, 31840,
- 537, 55180, 3309, 48261, 39381, 33276, 25414, 4115, 23045, 23044,
- 30691, 38209, 25032, 36249, 26279, 29211, 53300, 35424, 30651, 25170,
- 29786, 38660, 35363, 37226, 38907, 2592, 29590, 52884, 32865, 1700,
- 36198, 1965, 20355, 9318, 47156, 31143, 28149, 46609, 34434, 4941,
- 38230, 33559, 39274, 27579, 38046, 32070, 31296, 47157, 34633, 46164,
- 28478, 3234, 4196, 28003, 4771, 33009, 3091, 3858, 32920, 21325, 29746,
- 25771, 26464, 22114, 29254, 24103, 3549, 4225, 23591, 21736, 54760,
- 30590, 4226, 4829, 21899, 3454, 32504, 38078, 21737, 21992, 12609,
- 6112, 25441, 1042486, 28558, 31339, 30637, 3106, 38191, 35059, 8563,
- 36783, 2764, 1940, 27837, 47716, 32680, 28122, 22124, 35269, 45580,
- 28851, 39881, 34107, 30585, 9581, 3504, 1783, 33592, 2856, 23087,
- 52897, 33445, 24977, 29614, 22065, 30129, 3587, 28373, 53489, 8736,
- 5222, 36958, 21104, 33530, 21128, 3940, 4672, 21596, 23077, 30251,
- 25234, 20045, 3919, 46263, 50694, 21713, 4634, 32735, 30710, 38713,
- 46629, 30634, 26629, 39539, 35535, 35167, 2570, 6024, 63735, 47693,
- 28822, 23776, 25622, 48656, 24974, 45229, 20904, 38289, 22383, 8735,
- 36255, 12553, 21941, 47925, 21235, 3404, 48391, 32831, 23421, 21987,
- 4004, 37613, 46992, 32907, 26289, 39822, 38605, 24162, 38067, 45734,
- 29634, 26342, 25074, 65103, 32548, 28435, 24013, 59066, 36988, 31811,
- 29750, 20887, 33760, 39558, 30307, 36527, 33670, 28953, 29730, 24465,
- 32517, 8232, 12613, 59100, 44285, 31672, 26577, 22367, 29733, 58566,
- 38013, 26313, 4901, 20332, 21584, 24867, 30566, 24730, 23679, 26429,
- 21932, 30802, 59162, 59130, 23344, 28414, 1939, 21359, 3596, 54196,
- 45588, 26207, 33802, 50967, 3675, 9701, 51222, 38221, 2860, 5509,
- 6022, 4221, 33643, 44176, 33285, 39045, 38181, 8759, 40104, 9787,
- 6093, 9655, 28937, 27167, 31499, 49899, 47956, 24246, 55128, 47212,
- 24803, 38539, 2793, 20502, 25619, 48044, 22057, 59120, 31637, 12529,
- 3589, 4158, 30414, 45252, 23267, 26133, 9584, 33012, 2946, 27986,
- 24853, 47120, 3310, 6103, 31716, 1041647, 53132, 9685, 9602, 4851,
- 35060, 48848, 35607, 32838, 40158, 27048, 49916, 27788, 48389, 38379,
- 50912, 24315, 45937, 31636, 31809, 32509, 28670, 1808, 38746, 1041734,
- 38588, 32251, 12294, 53272, 32834, 37108, 29749, 32532, 50136, 37321,
- 24328, 34656, 32121, 44220, 30115, 21891, 28925, 30300, 50715, 51684,
- 3872, 36757, 57344, 31961, 65109, 53188, 32474, 46027, 29649, 37351,
- 4659, 44145, 25703, 35809, 34321, 32453, 38394, 21822, 27029, 35674,
- 44988, 3230, 39899, 28698, 20448, 2872, 312, 24005, 31406, 20873,
- 29522, 39269, 35566, 30741, 20130, 34444, 21766, 51260, 38968, 35513,
- 7952, 28181, 2852, 51082, 21777, 29309, 27814, 27544, 28186, 20308,
- 32948, 25305, 51117, 31047, 31040, 36286, 49920, 38471, 30544, 2504,
- 30207, 53812, 25578, 32406, 49632, 34122, 22418, 8054, 4163, 33308,
- 1043286, 39548, 50745, 25203, 26840, 28359, 44992, 24976, 8835, 7936,
- 44788, 45244, 38475, 28218, 26462, 53413, 12593, 47585, 40132, 23394,
- 51687, 24646, 33300, 35565, 21348, 4623, 36764, 2576, 40434, 25850,
- 23630, 24319, 30732, 4609, 33043, 4936, 29060, 59161, 25098, 45787,
- 36142, 39493, 8228, 22930, 23724, 1013, 26241, 21242, 44415, 4811,
- 49847, 9319, 21632, 23013, 34649, 58979, 21076, 31041, 22697, 24623,
- 900, 30428, 31401, 38414, 34662, 47736, 49455, 52040, 29234, 2880,
- 3453, 52452, 8481, 26214, 30094, 25947, 39608, 13213, 30977, 22204,
- 1937, 46524, 8599, 24409, 48140, 36454, 38536, 20814, 50505, 28153,
- 59091, 25443, 22179, 39290, 27516, 28865, 2551, 26355, 23386, 52196,
- 53808, 32494, 27088, 4896, 38064, 9756, 2862, 35641, 24275, 49744,
- 36144, 37758, 25031, 9320, 33302, 29822, 27243, 38225, 29481, 4169,
- 23913, 57474, 32687, 33275, 22022, 23388, 35715, 30610, 3743, 50560,
- 59098, 30315, 1925, 21957, 25524, 31264, 46364, 44263, 36264, 24287,
- 24653, 38255, 31311, 28234, 45331, 46161, 9737, 22039, 25884, 26786,
- 6027, 26874, 20133, 35438, 37196, 34875, 3311, 32203, 25287, 31001,
- 20939, 35773, 32608, 54736, 21519, 770, 36174, 28609, 2873, 9635,
- 9122, 32033, 462, 4250, 8361, 25458, 3463, 39912, 2722, 48596, 35876,
- 32957, 52740, 22778, 36943, 27774, 29471, 32880, 2947, 4168, 971,
- 20432, 29557, 22438, 30420, 21971, 51094, 28037, 34914, 52656, 3522,
- 4824, 25722, 4962, 10070, 20885, 51086, 4617, 47105, 32629, 4650,
- 59011, 31607, 24458, 22764, 45805, 27194, 9605, 40140, 29277, 8765,
- 61623, 30439, 51210, 33499, 21474, 51075, 23697, 24439, 3465, 24347,
- 38816, 23495, 36060, 51788, 49714, 3793, 46944, 39533, 36676, 27945,
- 32349, 45544, 27603, 35837, 35808, 49356, 31983, 36845, 32371, 25854,
- 27099, 24472, 28335, 28205, 26191, 3929, 44624, 1724, 52888, 34103,
- 38774, 27584, 26880, 4165, 26806, 30519, 6113, 27696, 2797, 28196,
- 33040, 50928, 30872, 29200, 24264, 28654, 36111, 29785, 32098, 12601,
- 32359, 27513, 22666, 38491, 21256, 25370, 31496, 8200, 9479, 29494,
- 50740, 32314, 36726, 20278, 47497, 37292, 25410, 22953, 39620, 30133,
- 36244, 31893, 39052, 23413, 25314, 54049, 38124, 38115, 37586, 27978,
- 50549, 54663, 1942, 38308, 49707, 33527, 40860, 44216, 5123, 29764,
- 36010, 3542, 38675, 21480, 31014, 63724, 27580, 22103, 30970, 28154,
- 3931, 32533, 20451, 37706, 36703, 20406, 45377, 6028, 50519, 40100,
- 25735, 25794, 30068, 36140, 28051, 477, 1043254, 31482, 28828, 4875,
- 39050, 32745, 45130, 8855, 26604, 28825, 27147, 36781, 31568, 9504,
- 21671, 36869, 30504, 39347, 1042479, 24691, 30178, 50734, 35178, 22684,
- 26865, 55193, 22852, 30208, 21719, 65102, 33515, 23308, 37276, 9585,
- 6114, 61607, 63732, 2799, 21866, 25602, 28889, 31975, 47344, 22446,
- 25341, 36049, 24336, 47449, 24971, 33333, 40573, 29701, 35114, 32824,
- 36994, 50028, 47452, 33688, 22108, 22275, 38643, 25601, 32010, 25358,
- 39031, 23786, 32538, 38342, 52308, 27527, 4614, 31098, 54660, 38607,
- 1042482, 50545, 33162, 36995, 21702, 26103, 20440, 21489, 33134, 61550,
- 3488, 21627, 20031, 22974, 23092, 1041718, 37193, 33463, 29020, 33400,
- 4173, 8056, 53888, 36929, 24396, 38192, 21874, 609, 26974, 46036,
- 33706, 769, 4722, 25139, 26485, 23629, 3873, 4167, 53672, 2858, 26726,
- 33743, 37168, 48977, 29696, 46316, 59106, 4164, 59116, 28780, 27103,
- 51469, 39607, 26505, 24832, 4763, 8238, 33213, 5251, 25134, 6049,
- 44081, 36635, 22956, 26866, 22732, 39719, 39314, 24709, 30415, 54943,
- 3451, 27902, 57347, 45785, 50544, 35905, 23125, 30511, 34003, 32521,
- 3462, 30361, 26406, 23673, 4001, 34532, 54729, 35435, 20461, 1042478,
- 48976, 53680, 45143, 3360, 24684, 28053, 35709, 44188, 4961, 24092,
- 25942, 63348, 23791, 21652, 32843, 38130, 25376, 21827, 8223, 21571,
- 39285, 34241, 47569, 4726, 32399, 34581, 36070, 8869, 25282, 31310,
- 21283, 38635, 4209, 9607, 28904, 2798, 27863, 28437, 30403, 2508,
- 25078, 38808, 33187, 20642, 39301, 37389, 53304, 28465, 8166, 26099,
- 8853, 25892, 12432, 48184, 2818, 3874, 39387, 35516, 26552, 39464,
- 1465, 2594, 33491, 2866, 6055, 31388, 34837, 39654, 29344, 36746,
- 37799, 36447, 59016, 54176, 25810, 26326, 8596, 34690, 57361, 23167,
- 27762, 32806, 25769, 36978, 1263, 27278, 39612, 5125, 65105, 32697,
- 44413, 6100, 39059, 55136, 33828, 29835, 6079, 34631, 49480, 45806,
- 39243, 8239, 35763, 27609, 27859, 22821, 52244, 61548, 24816, 54169,
- 39108, 28586, 21234, 2761, 21949, 29864, 29001, 35970, 4009, 26161,
- 46748, 46763, 491, 37619, 37159, 28173, 4850, 23100, 34261, 44191,
- 39156, 8564, 29096, 821, 20731, 39187, 49709, 1963, 12610, 40779,
- 52841, 5314, 22767, 33105, 21816, 32666, 59111, 26707, 39621, 33304,
- 55152, 40786, 40687, 3507, 4197, 13212, 30202, 38990, 5198, 3741,
- 59109, 22121, 25530, 37675, 59101, 39853, 32485, 12570, 26751, 1941,
- 44151, 32554, 25467, 3467, 48521, 1042480, 24407, 20369, 30187, 21032,
- 28711, 31330, 28751, 38788, 1967, 37274, 44180, 9321, 23536, 31820,
- 40201, 4770, 9523, 5130, 20760, 30757, 39848, 32526, 46360, 21421,
- 29158, 715, 24199, 45573, 21978, 29824, 25000, 26238, 4826, 20993,
- 40557, 23254, 1821, 4251, 28699, 31167, 3220, 27022, 62047, 40120,
- 20490, 57477, 4622, 30179, 22831, 4728, 49481, 8750, 32187, 34065,
- 6074, 46416, 63685, 47577, 1648, 53472, 21658, 33247, 24119, 4925,
- 38056, 34153, 46317, 46749, 1175, 4629, 28132, 47960, 44292, 28198,
- 28340, 39562, 21413, 38179, 25662, 4023, 22999, 4814, 37195, 25294,
- 33011, 32999, 24958, 21441, 24811, 29796, 38197, 28861, 25102, 21536,
- 34093, 31267, 23480, 31382, 22016, 1043331, 54800, 50564, 12583, 28416,
- 28293, 59125, 21617, 63248, 31686, 33725, 47020, 12575, 32341, 33253,
- 1043212, 699, 24398, 53301, 34137, 32386, 59037, 25087, 36993, 20319,
- 2891, 7925, 33503, 30201, 1042485, 24571, 4721, 32671, 31252, 21884,
- 33722, 9837, 52041, 4654, 34691, 32996, 39519, 26578, 23162, 36461,
- 34811, 466, 47495, 31933, 38170, 24361, 28479, 27018, 30633, 4193,
- 40442, 9688, 9603, 32503, 21648, 22707, 26570, 20689, 32639, 26541,
- 36184, 26946, 8048, 35126, 34115, 29626, 3099, 32305, 29801, 37638,
- 31117, 34071, 3020, 39559, 55016, 25225, 12616, 47104, 61656, 3476,
- 29184, 36799, 38112, 22021, 25179, 44273, 48173, 20458, 36524, 63234,
- 57360, 35781, 27292, 48727, 37569, 23522, 4899, 13115, 27607, 47688,
- 54988, 31513, 37610, 1462, 40367, 37445, 32350, 3338, 31998, 658,
- 38956, 10006, 52412, 25527, 31713, 9839, 34152, 49296, 23525, 48282,
- 10048, 34310, 33479, 28156, 818, 45356, 3911, 1816, 22829, 23625,
- 40633, 32718, 35032, 35538, 24130, 20504, 28644, 25100, 4675, 25248,
- 55113, 40485, 59020, 31171, 4772, 33454, 31751, 28160, 6063, 2854,
- 31368, 33580, 26925, 9606, 49939, 32458, 38045, 21553, 4819, 33418,
- 23143, 36671, 44403, 9501, 20291, 47340, 54029, 25600, 35692, 2863,
- 8255, 21591, 50969, 5335, 9583, 54184, 33005, 30105, 38497, 28640,
- 44861, 25319, 29440, 23729, 40284, 4810, 4166, 13095, 30328, 3944,
- 59113, 8016, 30048, 20970, 12317, 23769, 773, 33502, 24421, 2466,
- 801, 24760, 50956, 53040, 31627, 27769, 30347, 21526, 48192, 33240,
- 20120, 54077, 30239, 31174, 34619, 24920, 53428, 59184, 40515, 40023,
- 3794, 44051, 26112, 20812, 3584, 34558, 24413, 47945, 4821, 26654,
- 39568, 36294, 30938, 8182, 54044, 27035, 37213, 9643, 24996, 54996,
- 32519, 23853, 19999, 23700, 38417, 54548, 28297, 35109, 9117, 45068,
- 44202, 31118, 3797, 21878, 28108, 25488, 27179, 32633, 9476, 44217,
- 2881, 24822, 26389, 46916, 1719, 55072, 36620, 9438, 38189, 30640,
- 34645, 4189, 9744, 47926, 28353, 28071, 9728, 25413, 39130, 4706,
- 28867, 39661, 38893, 1042481, 34986, 36956, 34083, 31629, 20991, 25744,
- 33100, 30249, 9481, 27742, 40522, 29409, 1470, 22329, 25371, 8601,
- 39479, 26348, 20060, 52313, 23046, 20916, 31968, 31224, 1723, 36162,
- 30629, 20433, 53244, 29771, 20273, 33586, 20348, 20478, 32641, 1281,
- 22134, 3622, 33137, 59087, 20312, 9120, 35427, 32690, 63738, 38126,
- 33936, 1040426, 65117, 28063, 50784, 28626, 34396, 39535, 4649, 21638,
- 63727, 27964, 36381, 4638, 51500, 37530, 29605, 30153, 30233, 30910,
- 22241, 47364, 3511, 31659, 54945, 46388, 59054, 33399, 32496, 21426,
- 23445, 30717, 45188, 22199, 1041584, 59107, 28174, 36299, 23461, 1826,
- 9515, 45934, 27595, 4846, 3788, 30090, 28102, 38671, 30746, 47493,
- 40499, 34367, 4194, 44555, 1041705, 10063, 20356, 23996, 25571, 63723,
- 1663, 23568, 1461, 1731, 15104, 4618, 617, 28074, 29723, 31146, 21537,
- 37261, 48981, 27189, 26665, 48195, 12631, 9116, 51692, 46769, 33575,
- 9119, 27084, 29313, 26185, 23146, 29922, 21646, 53553, 45740, 3203,
- 2461, 45012, 25653, 40300, 12318, 29469, 63725, 20525, 10004, 46896,
- 21937, 30778, 21828, 44637, 38086, 27586, 44860, 25212, 28847, 25004,
- 37150, 6120, 32024, 61647, 31560, 23157, 48374, 33585, 28458, 46280,
- 33255, 30186, 511, 34506, 63734, 39237, 3210, 9115, 21422, 37397,
- 50659, 29662, 39545, 8838, 27648, 1042484, 34870, 30844, 47610, 714,
- 8815, 4213, 21657, 33940, 44557, 24951, 25898, 46357, 4220, 37264,
- 22718, 45713, 27553, 9531, 59097, 53485, 54072, 33179, 4219, 48852,
- 39138, 30933, 51900, 39563, 21990, 8814, 34769, 33603, 3104, 36989,
- 21792, 28540, 26624, 49456, 9539, 21533, 47464, 53431, 44611, 1840,
- 49256, 4658, 38859, 30180, 12595, 27280, 8150, 53000, 2435, 464, 32104,
- 4669, 9689, 30518, 38346, 12584, 20500, 5229, 28197, 48307, 40285,
- 31584, 2844, 27739, 3991, 65118, 29935, 47502, 5456, 28544, 36894,
- 59104, 33640, 39311, 20472, 29243, 24488, 8052, 20565, 21714, 31899,
- 21501, 3082, 25824, 27323, 40495, 21269, 9118, 54411, 4003, 3474,
- 30106, 991, 1042483, 35728, 27028, 28046, 441, 22036, 44865, 32427,
- 38173, 5319, 12336, 33215, 38133, 20191, 31729, 26727, 53476, 25421,
- 34905, 27453, 34670, 3355, 28651, 21545, 25944, 34388, 25912, 31384,
- 59112, 12433, 45235, 38111, 25119, 61501, 28463, 59021, 27053, 38892,
- 23805, 36944, 21550, 24091, 33660, 26613, 34943, 48904, 12618, 8569,
- 35892, 24561, 3795, 12579, 31207, 33421, 50277, 35203, 23218, 34851,
- 46037, 712, 23919, 24596, 592, 31260, 23158, 31806, 335, 34201, 3073,
- 20149, 31074, 1043330, 2839, 4765, 32286, 65106, 301, 36732, 37532,
- 22070, 35815, 30655, 37021, 47701, 5200, 38309, 35867, 59108, 61485,
- 5333, 44225, 31692, 31414, 51132, 22391, 3852, 21473, 63687, 20106,
- 27529, 39110, 32129, 4135, 25754, 7823, 30923, 12555, 28977, 4627,
- 54607, 771, 33862, 27016, 21985, 21599, 36487, 30545, 37624, 30154,
- 9641, 20147, 34383, 32660, 27822, 32482, 25531, 44751, 8565, 31565,
- 1825, 33750, 5507, 27994, 20034, 45700, 46433, 35819, 34427, 45227,
- 12623, 38504, 30597, 38171, 33071, 20834, 3792, 29280, 53220, 20127,
- 8134, 34597, 29854, 52507, 57503, 44900, 39307, 30109, 8254, 59110,
- 12526, 51796, 23831, 38253, 31725, 30609, 38076, 30352, 28078, 26248,
- 4231, 25803, 34527, 22948, 33450, 20898, 65110, 1661, 38039, 27067,
- 27320, 21606, 40550, 561, 20653, 4753, 9601, 49564, 25880, 59126,
- 36779, 32792, 1041701, 21595, 25891, 15360, 34993, 9332, 30318, 34579,
- 21342, 32361, 1824, 48531, 50052, 1811, 34407, 34770, 29989, 26855,
- 21799, 24817, 2384, 52996, 40569, 29165, 40840, 25520, 4708, 34543,
- 28327, 35331, 25303, 9831, 35183, 38935, 1371, 4108, 31381, 44405,
- 1041586, 2315, 38425, 35916, 59140, 24698, 36837, 38771, 1041721,
- 59185, 50489, 29722, 36405, 700, 44749, 24469, 4756, 29599, 1843,
- 3537, 21119, 46176, 8494, 38107, 32652, 29990, 24812, 24331, 4657,
- 29898, 596, 22775, 20396, 21582, 22165, 25315, 277, 21894, 47469,
- 38210, 59025, 39201, 31921, 51219, 23579, 8733, 26212, 40480, 37300,
- 1041634, 21417, 34829, 24473, 39851, 27795, 23011, 30136, 23138, 40521,
- 63237, 24257, 53077, 31721, 23018, 20469, 32714, 36418, 36841, 48724,
- 9711, 38000, 22754, 38924, 3988, 36324, 21173, 1813, 34996, 46516,
- 34191, 34085, 1043234, 1954, 373, 14592, 3993, 22007, 23059, 25420,
- 45460, 50924, 29403, 23437, 1949, 7984, 4705, 21670, 47128, 25291,
- 293, 63238, 49438, 36802, 20164, 34885, 4827, 23270, 30169, 35791,
- 35881, 13214, 28712, 35884, 34814, 4620, 29088, 28402, 36426, 35866,
- 50687, 63281, 36761, 30822, 1836, 21310, 26964, 24682, 54148, 31087,
- 23860, 4873, 46400, 39003, 3502, 50493, 38722, 4777, 32631, 23462,
- 39995, 4841, 24061, 54161, 55129, 22158, 35098, 50025, 21675, 25431,
- 3348, 1834, 23408, 30232, 35830, 3881, 24340, 44613, 28805, 9832,
- 49788, 40107, 35039, 36068, 48139, 23869, 32491, 9760, 53459, 4864,
- 53960, 38094, 28457, 20608, 31153, 30768, 8050, 4963, 23620, 35559,
- 9333, 51144, 23789, 29336, 62018, 32997, 35563, 4869, 27462, 1659,
- 4633, 15872, 33081, 6019, 45139, 50143, 38026, 31824, 4939, 27617,
- 25344, 23997, 1043188, 28126, 32557, 27781, 1770, 1245, 28167, 49913,
- 50893, 29641, 27263, 38128, 39253, 28222, 9662, 1789, 4243, 1473,
- 1679, 45184, 30241, 20800, 28140, 31061, 34015, 4214, 49396, 9130,
- 28672, 1041707, 4782, 25494, 34568, 31042, 5205, 25558, 29996, 46892,
- 25326, 1042451, 4758, 4611, 5316, 48730, 50044, 593, 1676, 36955,
- 33222, 25466, 39342, 8709, 1042391, 21698, 21668, 22244, 32044, 35131,
- 23628, 1790, 51329, 40063, 38331, 36036, 24813, 29113, 53237, 53568,
- 37406, 36968, 50760, 48159, 831, 36368, 39089, 63631, 23075, 3092,
- 33983, 30758, 23504, 31308, 1620, 4192, 24447, 37510, 5285, 39333,
- 54187, 23781, 57345, 30183, 59094, 37007, 2698, 4608, 25549, 37742,
- 33193, 22002, 3229, 1946, 33784, 3796, 26686, 35548, 1728, 28407,
- 5503, 52868, 28625, 9681, 35635, 44641, 4849, 27825, 58999, 21708,
- 9680, 34758, 26551, 3674, 603, 39087, 29145, 4006, 7747, 33636, 36460,
- 5290, 22160, 4828, 20769, 38541, 25062, 29179, 65532, 37043, 13199,
- 31668, 34068, 39600, 20295, 12556, 30394, 1938, 30305, 1195, 24726,
- 29619, 9586, 51789, 865, 1771, 37555, 45823, 63686, 35057, 26728,
- 52152, 22809, 28088, 54396, 33600, 24826, 40702, 40848, 47129, 1644,
- 32703, 22137, 51334, 28227, 24756, 34451, 58980, 4624, 8902, 1041617,
- 713, 21913, 29462, 22874, 26891, 1658, 63309, 31567, 38358, 44079,
- 28753, 21863, 6115, 49344, 31071, 515, 53217, 375, 45798, 28228, 31858,
- 52180, 21277, 1956, 9352, 9125, 3362, 27355, 21655, 21872, 47607,
- 39825, 52899, 33094, 1209, 25772, 9613, 808, 59038, 21522, 58865,
- 24980, 45253, 58636, 57346, 23810, 22427, 33449, 50491, 24913, 633,
- 34417, 38894, 21994, 30402, 38552, 53484, 1945, 24527, 22257, 10877,
- 48072, 9828, 468, 21057, 32609, 44452, 57812, 8215, 29461, 25711,
- 37648, 2544, 35988, 21405, 22178, 33323, 26015, 26584, 32753, 62139,
- 3102, 28000, 33583, 25084, 1041200, 1042433, 3943, 39361, 31434, 720,
- 9512, 35820, 26487, 35616, 28425, 33107, 24792, 21240, 49808, 22221,
- 26164, 2849, 2870, 33096, 36040, 20807, 23882, 28538, 33210, 39711,
- 53825, 1643, 49108, 33615, 59403, 61626, 49928, 2757, 33355, 22139,
- 4203, 51428, 33205, 28356, 27673, 23005, 33477, 44866, 35924, 53597,
- 38323, 26003, 34946, 20367, 34022, 38466, 37709, 27153, 59095, 29384,
- 32761, 34282, 27523, 32381, 9774, 12571, 34314, 26851, 2718, 4132,
- 28532, 22136, 34728, 33669, 25034, 4673, 35764, 36490, 28950, 37502,
- 20643, 45231, 27904, 11520, 23090, 26199, 59390, 36343, 30684, 25077,
- 34784, 8198, 30568, 34044, 29134, 39123, 38150, 30775, 59057, 22163,
- 37393, 8001, 4645, 49677, 37200, 54747, 33686, 39553, 37219, 25721,
- 45957, 44361, 320, 37434, 38589, 27821, 5359, 1041223, 34847, 26107,
- 57759, 21939, 29852, 34612, 34360, 22159, 36409, 618, 39627, 50771,
- 32475, 4172, 32412, 37001, 15616, 52843, 61483, 26503, 29355, 59023,
- 31255, 38068, 31103, 28510, 36022, 34948, 63719, 21294, 61372, 61664,
- 40150, 36163, 12617, 50753, 30820, 1810, 33007, 8566, 28325, 33129,
- 24186, 59119, 48333, 1041648, 23057, 9745, 12850, 35973, 24124, 21804,
- 29502, 33074, 48281, 24581, 25642, 51673, 29674, 39850, 35543, 34949,
- 32181, 26244, 25115, 20112, 4652, 34615, 26017, 33338, 48737, 25620,
- 26196, 59138, 63333, 23825, 21317, 26839, 45600, 35578, 3075, 9998,
- 31142, 4710, 6066, 22349, 26719, 44169, 4874, 31428, 59175, 45321,
- 38096, 58971, 34479, 35754, 39509, 19989, 49567, 21970, 32774, 40157,
- 2847, 647, 34739, 34496, 40766, 38012, 4809, 1689, 2822, 39993, 8771,
- 39221, 33894, 9428, 20515, 36347, 4130, 49520, 28497, 50276, 52258,
- 36759, 31959, 21117, 26965, 2842, 1041702, 977, 58552, 814, 63681,
- 6116, 24012, 1127, 24337, 49679, 25523, 38649, 34541, 22744, 27311,
- 30562, 65111, 51923, 31104, 30442, 34647, 28951, 6095, 31786, 10026,
- 1042476, 29678, 40605, 653, 7956, 61558, 34502, 21707, 24949, 49093,
- 10061, 25474, 38670, 27075, 34578, 4667, 28593, 36834, 21757, 34553,
- 307, 21636, 34635, 48528, 38069, 25616, 3801, 2888, 20456, 34222,
- 21243, 29030, 4731, 507, 21005, 343, 4678, 3799, 4636, 27988, 4938,
- 36155, 33914, 4965, 25160, 30821, 9334, 5328, 61614, 49360, 58773,
- 35014, 34563, 59157, 13568, 52405, 23346, 38148, 63683, 4008, 33390,
- 1041720, 21988, 1649, 32353, 2580, 31418, 40639, 21867, 20762, 52853,
- 2821, 8568, 32901, 31658, 36961, 26249, 27315, 37036, 4216, 37476,
- 59032, 3544, 35174, 38051, 4241, 29855, 47943, 31923, 12620, 63233,
- 21499, 4923, 39589, 27647, 513, 39634, 21541, 22702, 25306, 34623,
- 1043235, 4013, 35074, 51792, 52600, 38718, 9322, 26722, 25462, 1832,
- 12319, 766, 20375, 4920, 44621, 23896, 35855, 30874, 30759, 29351,
- 32942, 57350, 20850, 21500, 26407, 65125, 24751, 1042460, 6121, 22063,
- 58637, 39214, 36667, 31063, 49573, 63684, 65123, 32679, 40133, 32365,
- 3489, 39255, 38335, 24380, 12032, 3800, 62719, 38256, 38765, 47159,
- 21972, 39631, 1041202, 8960, 28396, 26917, 24258, 63682, 38938, 30242,
- 39405, 30883, 26188, 21471, 21902, 29690, 27001, 32046, 8598, 4230,
- 49961, 2560, 21085, 59096, 38034, 4754, 29934, 7969, 3798, 32029,
- 36425, 45845, 1815, 30679, 44609, 24900, 27192, 33830, 63329, 27079,
- 21558, 38178, 10066, 21510, 22313, 23265, 29744, 63739, 31494, 33065,
- 40617, 26991, 63337, 22209, 63737, 33907, 28451, 21691, 8895, 53095,
- 46895, 50032, 35826, 31800, 1040824, 39250, 32184, 501, 20558, 4878,
- 28821, 26166, 27421, 2025, 4797, 22003, 59191, 23833, 27166, 39557,
- 63726, 30091, 33630, 59036, 37350, 3879, 54973, 30780, 25288, 3487,
- 20822, 39582, 25332, 12551, 23539, 20389, 5234, 30818, 27872, 1123,
- 57720, 39122, 23105, 36495, 30604, 23782, 32236, 995, 26638, 1835,
- 58942, 35594, 5206, 40843, 34193, 13076, 33335, 30817, 1846, 23418,
- 944, 39675, 40141, 26688, 59117, 21833, 1715, 39079, 36346, 34978,
- 8707, 25082, 29647, 48856, 61692, 30071, 37728, 5418, 34552, 35461,
- 37891, 63280, 3121, 36427, 40510, 26171, 22741, 30777, 44740, 29394,
- 20721, 12594, 34952, 39585, 47028, 50739, 29317, 52645, 26296, 33848,
- 28095, 30045, 3916, 45480, 20547, 22462, 38217, 37970, 51674, 25373,
- 1041680, 3880, 47719, 35628, 58841, 29322, 9519, 24675, 329, 12621,
- 1043241, 29736, 1104, 44808, 50567, 28270, 36856, 58991, 20486, 36076,
- 2365, 36479, 9493, 57480, 28635, 21669, 34199, 46375, 21087, 61627,
- 29029, 23723, 35084, 34108, 37312, 25899, 6102, 58998, 1645, 26060,
- 25035, 2861, 37225, 9587, 29807, 22592, 53104, 21068, 1043185, 23735,
- 3787, 40482, 39319, 29136, 30306, 11056, 34849, 824, 8366, 63282,
- 26137, 49668, 29999, 40748, 36382, 33682, 30652, 29484, 28152, 36740,
- 49343, 24806, 36118, 4242, 35912, 34162, 28386, 30738, 32377, 23301,
- 51609, 4917, 8614, 26075, 8748, 34510, 28390, 31546, 33588, 28583,
- 35357, 28734, 50137, 24814, 50144, 1042399, 36489, 2876, 1763, 28408,
- 4099, 29130, 31059, 31657, 52240, 5354, 20956, 29166, 25661, 38747,
- 35281, 30857, 26978, 32895, 21886, 45072, 45352, 47103, 4907, 51908,
- 8680, 21549, 30350, 22024, 54749, 31631, 62017, 4674, 4612, 39053,
- 45656, 37396, 38737, 32619, 37032, 31709, 33985, 33393, 37716, 9527,
- 28399, 50433, 1858, 613, 26717, 37169, 27710, 63289, 27628, 14848,
- 32552, 33476, 33003, 37000, 22575, 4854, 28061, 46904, 9335, 9424,
- 46616, 35811, 3875, 58974, 27386, 48289, 52908, 29977, 38967, 59178,
- 39699, 20594, 26979, 36706, 1042404, 24779, 1042468, 7717, 1458, 9743,
- 24530, 30663, 35749, 38601, 61669, 21343, 34306, 59201, 27537, 34001,
- 27887, 776, 30472, 24774, 29585, 20925, 25540, 9615, 39309, 28693,
- 23049, 28598, 4904, 45339, 30855, 30087, 28766, 49941, 2704, 59018,
- 28610, 6060, 8725, 38408, 21604, 24575, 32537, 8567, 27929, 30344,
- 45825, 13312, 1181, 1040826, 34047, 36019, 38860, 37826, 22376, 58661,
- 32945, 36146, 32171, 58732, 30782, 7779, 12559, 26697, 31287, 37561,
- 38356, 22138, 39757, 25736, 38224, 38514, 25503, 37711, 25775, 3328,
- 37928, 1596, 49816, 24665, 33537, 38398, 38328, 52320, 35575, 21981};
- System.arraycopy(temp, 0, chars, chars.length - temp.length, temp.length);
- }
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/JoinerBenchmark.java b/guava-tests/benchmark/com/google/common/base/JoinerBenchmark.java
deleted file mode 100644
index 1e50408..0000000
--- a/guava-tests/benchmark/com/google/common/base/JoinerBenchmark.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-/**
- * Benchmarks {@link Joiner} against some common implementations of delimiter-based
- * string joining.
- *
- * @author Adomas Paltanavicius
- */
-public class JoinerBenchmark extends SimpleBenchmark {
-
- private static final String DELIMITER_STRING = ",";
- private static final char DELIMITER_CHARACTER = ',';
-
- private static final Joiner JOINER_ON_STRING = Joiner.on(DELIMITER_STRING);
- private static final Joiner JOINER_ON_CHARACTER = Joiner.on(DELIMITER_CHARACTER);
-
- @Param({"3", "30", "300"}) int count;
- @Param({"0", "1", "16", "32", "100"}) int componentLength;
-
- private Iterable<String> components;
-
- @Override
- protected void setUp() {
- String component = Strings.repeat("a", componentLength);
- String[] raw = new String[count];
- Arrays.fill(raw, component);
- components = Arrays.asList(raw);
- }
-
- /**
- * {@link Joiner} with a string delimiter.
- */
- public int timeJoinerWithStringDelimiter(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy ^= JOINER_ON_STRING.join(components).length();
- }
- return dummy;
- }
-
- /**
- * {@link Joiner} with a character delimiter.
- */
- public int timeJoinerWithCharacterDelimiter(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy ^= JOINER_ON_CHARACTER.join(components).length();
- }
- return dummy;
- }
-
- /**
- * Mimics what the {@link Joiner} class does internally when no extra options like
- * ignoring {@code null} values are used.
- */
- public int timeJoinerInlined(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- StringBuilder sb = new StringBuilder();
- Iterator<String> iterator = components.iterator();
- if (iterator.hasNext()) {
- sb.append(iterator.next().toString());
- while (iterator.hasNext()) {
- sb.append(DELIMITER_STRING);
- sb.append(iterator.next());
- }
- }
- dummy ^= sb.toString().length();
- }
- return dummy;
- }
-
- /**
- * Only appends delimiter if the accumulated string is non-empty.
- * Note: this isn't a candidate implementation for Joiner since it fails on leading
- * empty components.
- */
- public int timeStringBuilderIsEmpty(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- StringBuilder sb = new StringBuilder();
- for (String comp : components) {
- if (sb.length() > 0) {
- sb.append(DELIMITER_STRING);
- }
- sb.append(comp);
- }
- dummy ^= sb.toString().length();
- }
- return dummy;
- }
-
- /**
- * Similar to the above, but keeps a boolean flag rather than checking for the string
- * accumulated so far being empty. As a result, it does not have the above-mentioned bug.
- */
- public int timeBooleanIfFirst(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- StringBuilder sb = new StringBuilder();
- boolean append = false;
- for (String comp : components) {
- if (append) {
- sb.append(DELIMITER_STRING);
- }
- sb.append(comp);
- append = true;
- }
- dummy ^= sb.toString().length();
- }
- return dummy;
- }
-
- /**
- * Starts with an empty delimiter and changes to the desired value at the end of the
- * iteration.
- */
- public int timeAssignDelimiter(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- StringBuilder sb = new StringBuilder();
- String delim = "";
- for (String comp : components) {
- sb.append(delim);
- sb.append(comp);
- delim = DELIMITER_STRING;
- }
- dummy ^= sb.toString().length();
- }
- return dummy;
- }
-
- /**
- * Always append the delimiter after the component, and in the very end shortens the buffer
- * to get rid of the extra trailing delimiter.
- */
- public int timeAlwaysAppendThenBackUp(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- StringBuilder sb = new StringBuilder();
- for (String comp : components) {
- sb.append(comp);
- sb.append(DELIMITER_STRING);
- }
- if (sb.length() > 0) {
- sb.setLength(sb.length() - DELIMITER_STRING.length());
- }
- dummy ^= sb.toString().length();
- }
- return dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(JoinerBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/ObjectsBenchmark.java b/guava-tests/benchmark/com/google/common/base/ObjectsBenchmark.java
deleted file mode 100644
index 642abb2..0000000
--- a/guava-tests/benchmark/com/google/common/base/ObjectsBenchmark.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Objects;
-
-/**
- * Some microbenchmarks for the {@link Objects} class.
- *
- * @author Ben L. Titzer
- */
-public class ObjectsBenchmark extends SimpleBenchmark {
-
- private static final Integer I0 = -45;
- private static final Integer I1 = -1;
- private static final Integer I2 = 3;
- private static final String S0 = "3";
- private static final String S1 = "Ninety five";
- private static final String S2 = "44 one million";
- private static final String S3 = "Lowly laundry lefties";
- private static final String S4 = "89273487U#*&#";
- private static final Double D0 = 9.234d;
- private static final Double D1 = -1.2e55;
-
- public int timeHashString_2(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += Objects.hashCode(S0, S1);
- }
- return dummy;
- }
-
- public int timeHashString_3(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += Objects.hashCode(S0, S1, S2);
- }
- return dummy;
- }
-
- public int timeHashString_4(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += Objects.hashCode(S0, S1, S2, S3);
- }
- return dummy;
- }
-
- public int timeHashString_5(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += Objects.hashCode(S0, S1, S2, S3, S4);
- }
- return dummy;
- }
-
- public int timeHashMixed_5(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += Objects.hashCode(I2, S1, D1, S2, I0);
- dummy += Objects.hashCode(D0, I1, S3, I2, S0);
- }
- return dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(ObjectsBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/SplitterBenchmark.java b/guava-tests/benchmark/com/google/common/base/SplitterBenchmark.java
deleted file mode 100644
index 50ece1a..0000000
--- a/guava-tests/benchmark/com/google/common/base/SplitterBenchmark.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.Iterables;
-
-/**
- * Microbenchmark for {@link Splitter#on} with char vs String with length == 1.
- *
- * @author Paul Lindner
- */
-public class SplitterBenchmark extends SimpleBenchmark {
- // overall size of string
- @Param({"1", "10", "100", "1000"}) int length;
- // Number of matching strings
- @Param({"xxxx", "xxXx", "xXxX", "XXXX"}) String text;
-
- private String input;
-
- private static final Splitter CHAR_SPLITTER = Splitter.on('X');
- private static final Splitter STRING_SPLITTER = Splitter.on("X");
-
- @Override protected void setUp() {
- input = Strings.repeat(text, length);
- }
-
- public void timeCharSplitter(int reps) {
- int total = 0;
-
- for (int i = 0; i < reps; i++) {
- total += Iterables.size(CHAR_SPLITTER.split(input));
- }
- }
-
- public void timeStringSplitter(int reps) {
- int total = 0;
-
- for (int i = 0; i < reps; i++) {
- total += Iterables.size(STRING_SPLITTER.split(input));
- }
- }
-
- public static void main(String[] args) {
- Runner.main(SplitterBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/StopwatchBenchmark.java b/guava-tests/benchmark/com/google/common/base/StopwatchBenchmark.java
deleted file mode 100644
index f651052..0000000
--- a/guava-tests/benchmark/com/google/common/base/StopwatchBenchmark.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Stopwatch;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Simple benchmark: create, start, read. This does not currently report the
- * most useful result because it's ambiguous to what extent the stopwatch
- * benchmark is being affected by GC.
- *
- * @author Kevin Bourrillion
- */
-public class StopwatchBenchmark extends SimpleBenchmark {
- public long timeStopwatch(int reps) {
- long total = 0;
- for (int i = 0; i < reps; i++) {
- Stopwatch s = new Stopwatch().start();
- // here is where you would do something
- total += s.elapsed(TimeUnit.NANOSECONDS);
- }
- return total;
- }
-
- public long timeManual(int reps) {
- long total = 0;
- for (int i = 0; i < reps; i++) {
- long start = System.nanoTime();
- // here is where you would do something
- total += (System.nanoTime() - start);
- }
- return total;
- }
-
- public static void main(String[] args) {
- Runner.main(StopwatchBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java b/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java
deleted file mode 100644
index 776f7e9..0000000
--- a/guava-tests/benchmark/com/google/common/base/StringsRepeatBenchmark.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Strings;
-
-/**
- * Microbenchmark for {@link Strings#repeat}
- *
- * @author Mike Cripps
- */
-public class StringsRepeatBenchmark extends SimpleBenchmark {
- @Param({"1", "5", "25", "125"}) int count;
- @Param({"1", "10"}) int length;
-
- private String originalString;
-
- @Override protected void setUp() {
- originalString = Strings.repeat("x", length);
- }
-
- public void timeOldRepeat(int reps) {
- for (int i = 0; i < reps; i++) {
- String x = oldRepeat(originalString, count);
- if (x.length() != (originalString.length() * count)) {
- throw new RuntimeException("Wrong length: "+x);
- }
- }
- }
- public void timeMikeRepeat(int reps) {
- for (int i = 0; i < reps; i++) {
- String x = mikeRepeat(originalString, count);
- if (x.length() != (originalString.length() * count)) {
- throw new RuntimeException("Wrong length: "+x);
- }
- }
- }
- public void timeMartinRepeat(int reps) {
- for (int i = 0; i < reps; i++) {
- String x = martinRepeat(originalString, count);
- if (x.length() != (originalString.length() * count)) {
- throw new RuntimeException("Wrong length: "+x);
- }
- }
- }
-
- private static final String mikeRepeat(String string, int count) {
- final int len = string.length();
- char[] strCopy = new char[len * Integer.highestOneBit(count)];
- string.getChars(0, len, strCopy, 0);
-
- char[] array = new char[len * count];
-
- int strCopyLen = len;
- int pos = 0;
- while (count != 0) {
- if ((count & 1) != 0) {
- System.arraycopy(strCopy, 0, array, pos,strCopyLen);
- pos += strCopyLen;
- }
- count >>= 1;
- if (count != 0) {
- System.arraycopy(strCopy, 0, strCopy, strCopyLen, strCopyLen);
- strCopyLen <<= 1;
- }
- }
- return new String(array);
- }
-
- private static final String oldRepeat(String string, int count) {
- // If this multiplication overflows, a NegativeArraySizeException or
- // OutOfMemoryError is not far behind
- final int len = string.length();
- final int size = len * count;
- char[] array = new char[size];
- for (int i = 0; i < size; i+=len) {
- string.getChars(0, len, array, i);
- }
- return new String(array);
- }
-
- private static final String martinRepeat(String string, int count) {
- final int len = string.length();
- final int size = len * count;
- final char[] array = new char[size];
- string.getChars(0, len, array, 0);
- int n;
- for (n = len; n < size - n; n <<= 1) {
- System.arraycopy(array, 0, array, n, n);
- }
- System.arraycopy(array, 0, array, n, size - n);
- return new String(array);
- }
-
- public static void main(String[] args) {
- Runner.main(StringsRepeatBenchmark.class, args);
- }
-
-}
diff --git a/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java b/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java
deleted file mode 100644
index 02d8997..0000000
--- a/guava-tests/benchmark/com/google/common/base/ToStringHelperBenchmark.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-/**
- * Some microbenchmarks for the {@link Objects.ToStringHelper} class.
- *
- * @author Osvaldo Doederlein
- */
-public class ToStringHelperBenchmark extends SimpleBenchmark {
-
- @Param({"0", "2", "5", "10"}) int dataSize;
- private static final String NAME = "abcdefgh";
- private static final String NAME3 = Strings.repeat(NAME, 3);
-
- private static void addEntries(Objects.ToStringHelper helper) {
- helper
- .add(NAME, 10)
- .addValue(10L)
- .add(NAME, 3.14f)
- .addValue(3.14d)
- .add(NAME3, false)
- .add(NAME3, NAME3)
- .add(NAME3, 'x');
- }
-
- public int timeToString(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- Objects.ToStringHelper helper = Objects.toStringHelper("klass").omitNullValues();
- for (int j = 0; j < dataSize; ++j) {
- addEntries(helper);
- }
- dummy ^= helper
- .toString().hashCode();
- }
- return dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(ToStringHelperBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java b/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java
deleted file mode 100644
index 5614bc8..0000000
--- a/guava-tests/benchmark/com/google/common/cache/ChainBenchmark.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.cache.LocalCache.ReferenceEntry;
-import com.google.common.cache.LocalCache.Segment;
-
-/**
- * Benchmark for {@code LocalCache.Segment.removeEntryFromChain}.
- *
- * @author Charles Fry
- */
-public class ChainBenchmark extends SimpleBenchmark {
-
- @Param({"1", "2", "3", "4", "5", "6"}) int length;
-
- private Segment<Object, Object> segment;
- private ReferenceEntry<Object, Object> head;
- private ReferenceEntry<Object, Object> chain;
-
- @Override
- protected void setUp() {
- LocalCache<Object, Object> cache = new LocalCache<Object, Object>(
- CacheBuilder.newBuilder()
- .concurrencyLevel(1), null);
- segment = cache.segments[0];
- chain = null;
- for (int i = 0; i < length; i++) {
- Object key = new Object();
- chain = segment.newEntry(key, cache.hash(key), chain);
- if (i == 0) {
- head = chain;
- }
- }
- }
-
- public int time(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- segment.removeEntryFromChain(chain, head);
- dummy += segment.count;
- }
- return dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(ChainBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/cache/LoadingCacheSingleThreadBenchmark.java b/guava-tests/benchmark/com/google/common/cache/LoadingCacheSingleThreadBenchmark.java
deleted file mode 100644
index 85e6bad..0000000
--- a/guava-tests/benchmark/com/google/common/cache/LoadingCacheSingleThreadBenchmark.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.primitives.Ints;
-
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Single-threaded benchmark for {@link LoadingCache}.
- *
- * @author Charles Fry
- */
-public class LoadingCacheSingleThreadBenchmark extends SimpleBenchmark {
- @Param({"1000", "2000"}) int maximumSize;
- @Param("5000") int distinctKeys;
- @Param("4") int segments;
-
- // 1 means uniform likelihood of keys; higher means some keys are more popular
- // tweak this to control hit rate
- @Param("2.5") double concentration;
-
- Random random = new Random();
-
- LoadingCache<Integer, Integer> cache;
-
- int max;
-
- static AtomicLong requests = new AtomicLong(0);
- static AtomicLong misses = new AtomicLong(0);
-
- @Override protected void setUp() {
- // random integers will be generated in this range, then raised to the
- // power of (1/concentration) and floor()ed
- max = Ints.checkedCast((long) Math.pow(distinctKeys, concentration));
-
- cache = CacheBuilder.newBuilder()
- .concurrencyLevel(segments)
- .maximumSize(maximumSize)
- .build(
- new CacheLoader<Integer, Integer>() {
- @Override public Integer load(Integer from) {
- return (int) misses.incrementAndGet();
- }
- });
-
- // To start, fill up the cache.
- // Each miss both increments the counter and causes the map to grow by one,
- // so until evictions begin, the size of the map is the greatest return
- // value seen so far
- while (cache.getUnchecked(nextRandomKey()) < maximumSize) {}
-
- requests.set(0);
- misses.set(0);
- }
-
- public int time(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += cache.getUnchecked(nextRandomKey());
- }
- requests.addAndGet(reps);
- return dummy;
- }
-
- private int nextRandomKey() {
- int a = random.nextInt(max);
-
- /*
- * For example, if concentration=2.0, the following takes the square root of
- * the uniformly-distributed random integer, then truncates any fractional
- * part, so higher integers would appear (in this case linearly) more often
- * than lower ones.
- */
- return (int) Math.pow(a, 1.0 / concentration);
- }
-
- @Override protected void tearDown() {
- double req = requests.get();
- double hit = req - misses.get();
-
- // Currently, this is going into /dev/null, but I'll fix that
- System.out.println("hit rate: " + hit / req);
- }
-
- public static void main(String[] args) {
- Runner.main(LoadingCacheSingleThreadBenchmark.class, args);
- }
-
- // for proper distributions later:
- // import JSci.maths.statistics.ProbabilityDistribution;
- // int key = (int) dist.inverse(random.nextDouble());
-}
diff --git a/guava-tests/benchmark/com/google/common/cache/MapMakerComparisonBenchmark.java b/guava-tests/benchmark/com/google/common/cache/MapMakerComparisonBenchmark.java
deleted file mode 100644
index ba0ff50..0000000
--- a/guava-tests/benchmark/com/google/common/cache/MapMakerComparisonBenchmark.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.MapMaker;
-
-import java.util.Map;
-
-/**
- * Compare CacheBuilder and MapMaker performance, ensuring that they remain on par with each other.
- *
- * @author Nikita Sidorov
- */
-public class MapMakerComparisonBenchmark extends SimpleBenchmark {
- private static final String TEST_KEY = "test key";
- private static final String TEST_VALUE = "test value";
-
- private static final Function<Object, Object> IDENTITY = Functions.identity();
-
- // Loading/computing versions:
- private final Map<Object, Object> computingMap = new MapMaker().makeComputingMap(IDENTITY);
- private final LoadingCache<Object, Object> loadingCache =
- CacheBuilder.newBuilder().recordStats().build(CacheLoader.from(IDENTITY));
- private final LoadingCache<Object, Object> loadingCacheNoStats =
- CacheBuilder.newBuilder().build(CacheLoader.from(IDENTITY));
-
- // Non-loading versions:
- private final Map<Object, Object> map = new MapMaker().makeMap(); // Returns ConcurrentHashMap
- private final Cache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build();
- private final Cache<Object, Object> cacheNoStats = CacheBuilder.newBuilder().build();
-
- @Override
- public void setUp() {
- map.put(TEST_KEY, TEST_VALUE);
- cache.put(TEST_KEY, TEST_VALUE);
- cacheNoStats.put(TEST_KEY, TEST_VALUE);
- }
-
- public void timeComputingMapMaker(int rep) {
- for (int i = 0; i < rep; i++) {
- computingMap.get(TEST_KEY);
- }
- }
-
- public void timeLoadingCacheBuilder_stats(int rep) {
- for (int i = 0; i < rep; i++) {
- loadingCache.getUnchecked(TEST_KEY);
- }
- }
-
- public void timeLoadingCacheBuilder(int rep) {
- for (int i = 0; i < rep; i++) {
- loadingCacheNoStats.getUnchecked(TEST_KEY);
- }
- }
-
- public void timeConcurrentHashMap(int rep) {
- for (int i = 0; i < rep; i++) {
- map.get(TEST_KEY);
- }
- }
-
- public void timeCacheBuilder_stats(int rep) {
- for (int i = 0; i < rep; i++) {
- cache.getIfPresent(TEST_KEY);
- }
- }
-
- public void timeCacheBuilder(int rep) {
- for (int i = 0; i < rep; i++) {
- cacheNoStats.getIfPresent(TEST_KEY);
- }
- }
-
- public static void main(String[] args) {
- Runner.main(MapMakerComparisonBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java b/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java
deleted file mode 100644
index 6109897..0000000
--- a/guava-tests/benchmark/com/google/common/cache/SegmentBenchmark.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.cache.LocalCache.ReferenceEntry;
-import com.google.common.cache.LocalCache.Segment;
-
-import java.util.concurrent.atomic.AtomicReferenceArray;
-
-/**
- * Benchmark for {@code LocalCache.Segment.expand()}.
- *
- * @author Charles Fry
- */
-public class SegmentBenchmark extends SimpleBenchmark {
-
- @Param({"16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192"}) int capacity;
-
- private Segment<Object, Object> segment;
-
- @Override
- protected void setUp() {
- LocalCache<Object, Object> cache = new LocalCache<Object, Object>(
- CacheBuilder.newBuilder()
- .concurrencyLevel(1)
- .initialCapacity(capacity), null);
- checkState(cache.segments.length == 1);
- segment = cache.segments[0];
- checkState(segment.table.length() == capacity);
- for (int i = 0; i < segment.threshold; i++) {
- cache.put(new Object(), new Object());
- }
- checkState(segment.table.length() == capacity);
- }
-
- public int time(int reps) {
- int dummy = 0;
- AtomicReferenceArray<ReferenceEntry<Object, Object>> oldTable = segment.table;
- for (int i = 0; i < reps; i++) {
- segment.expand();
- segment.table = oldTable;
- dummy += segment.count;
- }
- return dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(SegmentBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java b/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java
deleted file mode 100644
index 52c55b2..0000000
--- a/guava-tests/benchmark/com/google/common/collect/ConcurrentHashMultisetBenchmark.java
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.Multisets.checkNonnegative;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.primitives.Ints;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import javax.annotation.Nullable;
-
-/**
- * Benchmarks for {@link ConcurrentHashMultiset}.
- *
- * @author mike nonemacher
- */
-public class ConcurrentHashMultisetBenchmark extends SimpleBenchmark {
- @Param({"1", "2", "4", "8"}) int threads;
- @Param({"3", "30", "300"}) int size;
- @Param MultisetSupplier implSupplier;
-
- private Multiset<Integer> multiset;
- private ImmutableList<Integer> keys;
- private ExecutorService threadPool;
-
- @Override protected void setUp() throws Exception {
- super.setUp();
- multiset = implSupplier.get();
- ImmutableList.Builder<Integer> builder = ImmutableList.builder();
- for (int i = 0; i < size; i++) {
- builder.add(i);
- }
- keys = builder.build();
- threadPool =
- Executors.newFixedThreadPool(threads, new ThreadFactoryBuilder().setDaemon(true).build());
- }
-
- public long timeAdd(final int reps) throws ExecutionException, InterruptedException {
- return doMultithreadedLoop(
- new Callable<Long>() {
- @Override public Long call() {
- return runAddSingleThread(reps);
- }
- });
- }
-
- public long timeAddRemove(final int reps) throws ExecutionException, InterruptedException {
- return doMultithreadedLoop(
- new Callable<Long>() {
- @Override public Long call() {
- return runAddRemoveSingleThread(reps);
- }
- });
- }
-
- private long doMultithreadedLoop(Callable<Long> task)
- throws InterruptedException, ExecutionException {
-
- List<Future<Long>> futures = Lists.newArrayListWithCapacity(threads);
- for (int i = 0; i < threads; i++) {
- futures.add(threadPool.submit(task));
- }
- long total = 0;
- for (Future<Long> future : futures) {
- total += future.get();
- }
- return total;
- }
-
- private long runAddSingleThread(int reps) {
- Random random = new Random();
- int nKeys = keys.size();
- long blah = 0;
- for (int i = 0; i < reps; i++) {
- Integer key = keys.get(random.nextInt(nKeys));
- int delta = random.nextInt(5);
- blah += delta;
- multiset.add(key, delta);
- }
- return blah;
- }
-
- private long runAddRemoveSingleThread(int reps) {
- Random random = new Random();
- int nKeys = keys.size();
- long blah = 0;
- for (int i = 0; i < reps; i++) {
- Integer key = keys.get(random.nextInt(nKeys));
- // This range is [-5, 4] - slight negative bias so we often hit zero, which brings the
- // auto-removal of zeroes into play.
- int delta = random.nextInt(10) - 5;
- blah += delta;
- if (delta >= 0) {
- multiset.add(key, delta);
- } else {
- multiset.remove(key, -delta);
- }
- }
- return blah;
- }
-
- public static void main(String[] args) {
- Runner.main(ConcurrentHashMultisetBenchmark.class, args);
- }
-
- private enum MultisetSupplier {
- CONCURRENT_HASH_MULTISET() {
- @Override Multiset<Integer> get() {
- return ConcurrentHashMultiset.create();
- }
- },
- BOXED_ATOMIC_REPLACE() {
- @Override Multiset<Integer> get() {
- return OldConcurrentHashMultiset.create();
- }
- },
- SYNCHRONIZED_MULTISET() {
- @Override Multiset<Integer> get() {
- return Synchronized.multiset(HashMultiset.<Integer>create(), null);
- }
- },
- ;
-
- abstract Multiset<Integer> get();
- }
-
- /**
- * Duplication of the old version of ConcurrentHashMultiset (with some unused stuff removed, like
- * serialization code) which used a map with boxed integers for the values.
- */
- private static final class OldConcurrentHashMultiset<E> extends AbstractMultiset<E> {
- /** The number of occurrences of each element. */
- private final transient ConcurrentMap<E, Integer> countMap;
-
- /**
- * Creates a new, empty {@code OldConcurrentHashMultiset} using the default
- * initial capacity, load factor, and concurrency settings.
- */
- public static <E> OldConcurrentHashMultiset<E> create() {
- return new OldConcurrentHashMultiset<E>(new ConcurrentHashMap<E, Integer>());
- }
-
- @VisibleForTesting OldConcurrentHashMultiset(ConcurrentMap<E, Integer> countMap) {
- checkArgument(countMap.isEmpty());
- this.countMap = countMap;
- }
-
- // Query Operations
-
- /**
- * Returns the number of occurrences of {@code element} in this multiset.
- *
- * @param element the element to look for
- * @return the nonnegative number of occurrences of the element
- */
- @Override public int count(@Nullable Object element) {
- try {
- return unbox(countMap.get(element));
- } catch (NullPointerException e) {
- return 0;
- } catch (ClassCastException e) {
- return 0;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>If the data in the multiset is modified by any other threads during this
- * method, it is undefined which (if any) of these modifications will be
- * reflected in the result.
- */
- @Override public int size() {
- long sum = 0L;
- for (Integer value : countMap.values()) {
- sum += value;
- }
- return Ints.saturatedCast(sum);
- }
-
- /*
- * Note: the superclass toArray() methods assume that size() gives a correct
- * answer, which ours does not.
- */
-
- @Override public Object[] toArray() {
- return snapshot().toArray();
- }
-
- @Override public <T> T[] toArray(T[] array) {
- return snapshot().toArray(array);
- }
-
- /*
- * We'd love to use 'new ArrayList(this)' or 'list.addAll(this)', but
- * either of these would recurse back to us again!
- */
- private List<E> snapshot() {
- List<E> list = Lists.newArrayListWithExpectedSize(size());
- for (Multiset.Entry<E> entry : entrySet()) {
- E element = entry.getElement();
- for (int i = entry.getCount(); i > 0; i--) {
- list.add(element);
- }
- }
- return list;
- }
-
- // Modification Operations
-
- /**
- * Adds a number of occurrences of the specified element to this multiset.
- *
- * @param element the element to add
- * @param occurrences the number of occurrences to add
- * @return the previous count of the element before the operation; possibly
- * zero
- * @throws IllegalArgumentException if {@code occurrences} is negative, or if
- * the resulting amount would exceed {@link Integer#MAX_VALUE}
- */
- @Override public int add(E element, int occurrences) {
- if (occurrences == 0) {
- return count(element);
- }
- checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
-
- while (true) {
- int current = count(element);
- if (current == 0) {
- if (countMap.putIfAbsent(element, occurrences) == null) {
- return 0;
- }
- } else {
- checkArgument(occurrences <= Integer.MAX_VALUE - current,
- "Overflow adding %s occurrences to a count of %s",
- occurrences, current);
- int next = current + occurrences;
- if (countMap.replace(element, current, next)) {
- return current;
- }
- }
- // If we're still here, there was a race, so just try again.
- }
- }
-
- /**
- * Removes a number of occurrences of the specified element from this
- * multiset. If the multiset contains fewer than this number of occurrences to
- * begin with, all occurrences will be removed.
- *
- * @param element the element whose occurrences should be removed
- * @param occurrences the number of occurrences of the element to remove
- * @return the count of the element before the operation; possibly zero
- * @throws IllegalArgumentException if {@code occurrences} is negative
- */
- @Override public int remove(@Nullable Object element, int occurrences) {
- if (occurrences == 0) {
- return count(element);
- }
- checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
-
- while (true) {
- int current = count(element);
- if (current == 0) {
- return 0;
- }
- if (occurrences >= current) {
- if (countMap.remove(element, current)) {
- return current;
- }
- } else {
- // We know it's an "E" because it already exists in the map.
- @SuppressWarnings("unchecked")
- E casted = (E) element;
-
- if (countMap.replace(casted, current, current - occurrences)) {
- return current;
- }
- }
- // If we're still here, there was a race, so just try again.
- }
- }
-
- /**
- * Removes <b>all</b> occurrences of the specified element from this multiset.
- * This method complements {@link Multiset#remove(Object)}, which removes only
- * one occurrence at a time.
- *
- * @param element the element whose occurrences should all be removed
- * @return the number of occurrences successfully removed, possibly zero
- */
- private int removeAllOccurrences(@Nullable Object element) {
- try {
- return unbox(countMap.remove(element));
- } catch (NullPointerException e) {
- return 0;
- } catch (ClassCastException e) {
- return 0;
- }
- }
-
- /**
- * Removes exactly the specified number of occurrences of {@code element}, or
- * makes no change if this is not possible.
- *
- * <p>This method, in contrast to {@link #remove(Object, int)}, has no effect
- * when the element count is smaller than {@code occurrences}.
- *
- * @param element the element to remove
- * @param occurrences the number of occurrences of {@code element} to remove
- * @return {@code true} if the removal was possible (including if {@code
- * occurrences} is zero)
- */
- public boolean removeExactly(@Nullable Object element, int occurrences) {
- if (occurrences == 0) {
- return true;
- }
- checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
-
- while (true) {
- int current = count(element);
- if (occurrences > current) {
- return false;
- }
- if (occurrences == current) {
- if (countMap.remove(element, occurrences)) {
- return true;
- }
- } else {
- @SuppressWarnings("unchecked") // it's in the map, must be an "E"
- E casted = (E) element;
- if (countMap.replace(casted, current, current - occurrences)) {
- return true;
- }
- }
- // If we're still here, there was a race, so just try again.
- }
- }
-
- /**
- * Adds or removes occurrences of {@code element} such that the {@link #count}
- * of the element becomes {@code count}.
- *
- * @return the count of {@code element} in the multiset before this call
- * @throws IllegalArgumentException if {@code count} is negative
- */
- @Override public int setCount(E element, int count) {
- checkNonnegative(count, "count");
- return (count == 0)
- ? removeAllOccurrences(element)
- : unbox(countMap.put(element, count));
- }
-
- /**
- * Sets the number of occurrences of {@code element} to {@code newCount}, but
- * only if the count is currently {@code oldCount}. If {@code element} does
- * not appear in the multiset exactly {@code oldCount} times, no changes will
- * be made.
- *
- * @return {@code true} if the change was successful. This usually indicates
- * that the multiset has been modified, but not always: in the case that
- * {@code oldCount == newCount}, the method will return {@code true} if
- * the condition was met.
- * @throws IllegalArgumentException if {@code oldCount} or {@code newCount} is
- * negative
- */
- @Override public boolean setCount(E element, int oldCount, int newCount) {
- checkNonnegative(oldCount, "oldCount");
- checkNonnegative(newCount, "newCount");
- if (newCount == 0) {
- if (oldCount == 0) {
- // No change to make, but must return true if the element is not present
- return !countMap.containsKey(element);
- } else {
- return countMap.remove(element, oldCount);
- }
- }
- if (oldCount == 0) {
- return countMap.putIfAbsent(element, newCount) == null;
- }
- return countMap.replace(element, oldCount, newCount);
- }
-
- // Views
-
- @Override Set<E> createElementSet() {
- final Set<E> delegate = countMap.keySet();
- return new ForwardingSet<E>() {
- @Override protected Set<E> delegate() {
- return delegate;
- }
- @Override public boolean remove(Object object) {
- try {
- return delegate.remove(object);
- } catch (NullPointerException e) {
- return false;
- } catch (ClassCastException e) {
- return false;
- }
- }
- };
- }
-
- private transient EntrySet entrySet;
-
- @Override public Set<Multiset.Entry<E>> entrySet() {
- EntrySet result = entrySet;
- if (result == null) {
- entrySet = result = new EntrySet();
- }
- return result;
- }
-
- @Override int distinctElements() {
- return countMap.size();
- }
-
- @Override public boolean isEmpty() {
- return countMap.isEmpty();
- }
-
- @Override Iterator<Entry<E>> entryIterator() {
- final Iterator<Map.Entry<E, Integer>> backingIterator =
- countMap.entrySet().iterator();
- return new Iterator<Entry<E>>() {
- @Override public boolean hasNext() {
- return backingIterator.hasNext();
- }
-
- @Override public Multiset.Entry<E> next() {
- Map.Entry<E, Integer> backingEntry = backingIterator.next();
- return Multisets.immutableEntry(backingEntry.getKey(),
- backingEntry.getValue());
- }
-
- @Override public void remove() {
- backingIterator.remove();
- }
- };
- }
-
- @Override public void clear() {
- countMap.clear();
- }
-
- private class EntrySet extends AbstractMultiset<E>.EntrySet {
- @Override Multiset<E> multiset() {
- return OldConcurrentHashMultiset.this;
- }
-
- /*
- * Note: the superclass toArray() methods assume that size() gives a correct
- * answer, which ours does not.
- */
-
- @Override public Object[] toArray() {
- return snapshot().toArray();
- }
-
- @Override public <T> T[] toArray(T[] array) {
- return snapshot().toArray(array);
- }
-
- private List<Multiset.Entry<E>> snapshot() {
- List<Multiset.Entry<E>> list = Lists.newArrayListWithExpectedSize(size());
- // not Iterables.addAll(list, this), because that'll forward back here
- Iterators.addAll(list, iterator());
- return list;
- }
-
- @Override public boolean remove(Object object) {
- if (object instanceof Multiset.Entry) {
- Multiset.Entry<?> entry = (Multiset.Entry<?>) object;
- Object element = entry.getElement();
- int entryCount = entry.getCount();
- return countMap.remove(element, entryCount);
- }
- return false;
- }
-
- /**
- * The hash code is the same as countMap's, though the objects aren't equal.
- */
- @Override public int hashCode() {
- return countMap.hashCode();
- }
- }
-
- /**
- * We use a special form of unboxing that treats null as zero.
- */
- private static int unbox(@Nullable Integer i) {
- return (i == null) ? 0 : i;
- }
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/HashMultisetAddPresentBenchmark.java b/guava-tests/benchmark/com/google/common/collect/HashMultisetAddPresentBenchmark.java
deleted file mode 100644
index 1e654ec..0000000
--- a/guava-tests/benchmark/com/google/common/collect/HashMultisetAddPresentBenchmark.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.Multiset;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Benchmark for HashMultiset.add for an already-present element.
- *
- * @author Louis Wasserman
- */
-public class HashMultisetAddPresentBenchmark extends SimpleBenchmark {
- private static final int ARRAY_MASK = 0x0ffff;
- private static final int ARRAY_SIZE = 0x10000;
- List<Multiset<Integer>> multisets = new ArrayList<Multiset<Integer>>(0x10000);
- int[] queries = new int[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- Random random = new Random();
- multisets.clear();
- for (int i = 0; i < ARRAY_SIZE; i++) {
- HashMultiset<Integer> multiset = HashMultiset.<Integer>create();
- multisets.add(multiset);
- queries[i] = random.nextInt();
- multiset.add(queries[i]);
- }
- }
-
- public int timeAdd(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += multisets.get(j).add(queries[j], 4);
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(HashMultisetAddPresentBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/ImmutableListCreationBenchmark.java b/guava-tests/benchmark/com/google/common/collect/ImmutableListCreationBenchmark.java
deleted file mode 100644
index 77ae7b1..0000000
--- a/guava-tests/benchmark/com/google/common/collect/ImmutableListCreationBenchmark.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.List;
-
-/**
- * Benchmark for various ways to create an {@code ImmutableList}.
- *
- * @author Louis Wasserman
- */
-public class ImmutableListCreationBenchmark extends SimpleBenchmark {
-
- @Param({"10", "1000", "1000000"})
- int size;
-
- private static final Object OBJECT = new Object();
-
- public int timeBuilderAdd(int reps) {
- int size = this.size;
- int dummy = 0;
- for (int rep = 0; rep < reps; rep++) {
- ImmutableList.Builder<Object> builder = ImmutableList.builder();
- for (int i = 0; i < size; i++) {
- builder.add(OBJECT);
- }
- dummy += builder.build().size();
- }
- return dummy;
- }
-
- public int timePreSizedBuilderAdd(int reps) {
- int size = this.size;
- int dummy = 0;
- for (int rep = 0; rep < reps; rep++) {
- ImmutableList.Builder<Object> builder = new ImmutableList.Builder<Object>(size);
- for (int i = 0; i < size; i++) {
- builder.add(OBJECT);
- }
- dummy += builder.build().size();
- }
- return dummy;
- }
-
- public int timeCopyArrayList(int reps) {
- int size = this.size;
- int dummy = 0;
- for (int rep = 0; rep < reps; rep++) {
- List<Object> builder = Lists.newArrayList();
- for (int i = 0; i < size; i++) {
- builder.add(OBJECT);
- }
- dummy += ImmutableList.copyOf(builder).size();
- }
- return dummy;
- }
-
- public int timeCopyPreSizedArrayList(int reps) {
- int size = this.size;
- int tmp = 0;
- for (int rep = 0; rep < reps; rep++) {
- List<Object> builder = Lists.newArrayListWithCapacity(size);
- for (int i = 0; i < size; i++) {
- builder.add(OBJECT);
- }
- tmp += ImmutableList.copyOf(builder).size();
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(ImmutableListCreationBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/ImmutableMapCreationBenchmark.java b/guava-tests/benchmark/com/google/common/collect/ImmutableMapCreationBenchmark.java
deleted file mode 100644
index 6c79e56..0000000
--- a/guava-tests/benchmark/com/google/common/collect/ImmutableMapCreationBenchmark.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * A Caliper benchmark used to track Builder performance. Currently supports:
- * ImmutableMap's copyOf and addAll methods.
- *
- * @author Paul Lindner
- */
-public class ImmutableMapCreationBenchmark extends SimpleBenchmark {
-
- @Param({"0", "1", "5", "50", "500", "5000", "50000"}) private int size;
-
- /** Holds testdata that is inserted into the Builder, populated by setUp() */
- Map<String, String> testData = Maps.newHashMap();
-
- /** A map we insert into, in class scope to keep the JVM from optimizing local references */
- ImmutableMap<String, String> testMap;
-
- // Preinitialize these to keep them out of the inner benchmark loop
- public static final Map<String, String> SINGLETON_MAP = Collections.singletonMap("1", "1");
- public static final Map<String, String> EMPTY_MAP = Collections.emptyMap();
-
- @Override
- public void setUp() {
- if (size == 0) {
- testData = EMPTY_MAP;
- } else if (size == 1) {
- testData = SINGLETON_MAP;
- } else {
- testData = Maps.newHashMap();
- for (int i = 0; i < size; i++) {
- String number = Integer.toString(i);
- testData.put(number, number);
- }
- }
- }
-
- /**
- * Test performance of ImmutableMap.copyOf()
- *
- * @param reps repetitions (used by Caliper)
- * @return a dummy string to ensure that the JVM does not optimize our code
- */
- public String timeCopyOf(int reps) {
- for (int i = 0; i < reps; i++) {
- testMap = ImmutableMap.copyOf(testData);
- }
- return testMap.get("");
- }
-
- /**
- * Test performance of the ImmutableMap.Builder putAll method.
- *
- * @param reps repetitions (used by Caliper)
- * @return a dummy string to ensure that the JVM does not optimize our code
- */
- public String timeBuilder(int reps) {
- for (int i = 0; i < reps; i++) {
- ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
- testMap = builder.putAll(testData).build();
- }
- return testMap.get("");
- }
-
- public static void main(String[] args) {
- Runner.main(ImmutableMapCreationBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/InternersBenchmark.java b/guava-tests/benchmark/com/google/common/collect/InternersBenchmark.java
deleted file mode 100644
index 85a3579..0000000
--- a/guava-tests/benchmark/com/google/common/collect/InternersBenchmark.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-/**
- * Benchmarking interners.
- *
- * @author Dimitris Andreou
- */
-public class InternersBenchmark extends SimpleBenchmark {
- public int timeWeakInterner(int reps) {
- Interner<String> interner = Interners.newWeakInterner();
- for (int i = 0; i < reps; i++) {
- interner.intern(Double.toHexString(Math.random()));
- }
- return reps;
- }
-
- public int timeStrongInterner(int reps) {
- Interner<String> interner = Interners.newStrongInterner();
- for (int i = 0; i < reps; i++) {
- interner.intern(Double.toHexString(Math.random()));
- }
- return reps;
- }
-
- @SuppressWarnings("ReturnValueIgnored")
- public int timeStringIntern(int reps) {
- for (int i = 0; i < reps; i++) {
- Double.toHexString(Math.random()).intern();
- }
- return reps;
- }
-
- public static void main(String[] args) {
- Runner.main(InternersBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/IteratorBenchmark.java b/guava-tests/benchmark/com/google/common/collect/IteratorBenchmark.java
deleted file mode 100644
index 2703dcd..0000000
--- a/guava-tests/benchmark/com/google/common/collect/IteratorBenchmark.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-
-/**
- * Tests the speed of iteration of different iteration methods for collections.
- *
- * @author David Richter
- */
-public class IteratorBenchmark extends SimpleBenchmark {
- @Param({"0", "1", "16", "256", "4096", "65536"}) int size;
-
- // use concrete classes to remove any possible polymorphic overhead?
- Object[] array;
- ArrayList<Object> arrayList;
- LinkedList<Object> linkedList;
-
- @Override protected void setUp() {
- array = new Object[size];
- arrayList = Lists.newArrayListWithCapacity(size);
- linkedList = Lists.newLinkedList();
-
- for (int i = 0; i < size; i++) {
- Object value = new Object();
- array[i] = value;
- arrayList.add(value);
- linkedList.add(value);
- }
- }
-
- public int timeArrayIndexed(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (int index = 0; index < size; index++) {
- sum += array[index].hashCode();
- }
- }
- return sum;
- }
-
- public int timeArrayIndexedLength(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (int index = 0; index < array.length; index++) {
- sum += array[index].hashCode();
- }
- }
- return sum;
- }
-
- public int timeArrayFor(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : array) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public int timeArrayListIndexed(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (int index = 0; index < size; index++) {
- sum += arrayList.get(index).hashCode();
- }
- }
- return sum;
- }
-
- public int timeArrayListIndexedLength(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (int index = 0; index < arrayList.size(); index++) {
- sum += arrayList.get(index).hashCode();
- }
- }
- return sum;
- }
-
- public int timeArrayListFor(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : arrayList) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public int timeArrayListToArrayFor(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : arrayList.toArray()) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public int timeLinkedListFor(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : linkedList) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public int timeLinkedListToArrayFor(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : linkedList.toArray()) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public static void main(String[] args) {
- Runner.main(IteratorBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java b/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java
deleted file mode 100644
index 47098eb..0000000
--- a/guava-tests/benchmark/com/google/common/collect/MapBenchmark.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.CollectionBenchmarkSampleData.Element;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-
-/**
- * A microbenchmark that tests the performance of get() on various map
- * implementations. Forked from {@link SetContainsBenchmark}.
- *
- * @author Nicholaus Shupe
- */
-public class MapBenchmark extends SimpleBenchmark {
- @Param({"Hash", "LinkedHM", "MapMaker1", "Immutable"})
- private Impl impl;
-
- public enum Impl {
- Hash {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map = Maps.newHashMap();
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- LinkedHM {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map = Maps.newLinkedHashMap();
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- UnmodHM {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- return Collections.unmodifiableMap(Hash.create(keys));
- }
- },
- SyncHM {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- return Collections.synchronizedMap(Hash.create(keys));
- }
- },
- Tree {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map = Maps.newTreeMap();
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- SkipList {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map = new ConcurrentSkipListMap<Element, Element>();
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- ConcurrentHM1 {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map =
- new ConcurrentHashMap<Element, Element>(keys.size(), 0.75f, 1);
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- ConcurrentHM16 {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map =
- new ConcurrentHashMap<Element, Element>(keys.size(), 0.75f, 16);
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- MapMaker1 {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map = new MapMaker()
- .concurrencyLevel(1)
- .makeMap();
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- MapMaker16 {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- Map<Element, Element> map = new MapMaker()
- .concurrencyLevel(16)
- .makeMap();
- for (Element element: keys) {
- map.put(element, element);
- }
- return map;
- }
- },
- Immutable {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- ImmutableMap.Builder<Element, Element> builder = ImmutableMap.builder();
- for (Element element : keys) {
- builder.put(element, element);
- }
- return builder.build();
- }
- },
- ImmutableSorted {
- @Override Map<Element, Element> create(Collection<Element> keys) {
- ImmutableSortedMap.Builder<Element, Element> builder =
- ImmutableSortedMap.naturalOrder();
- for (Element element : keys) {
- builder.put(element, element);
- }
- return builder.build();
- }
- };
-
- abstract Map<Element, Element> create(Collection<Element> contents);
- }
-
- @Param({"5", "50", "500", "5000", "50000"})
- private int size;
-
- // TODO: look at exact (==) hits vs. equals() hits?
- @Param("0.9")
- private double hitRate;
-
- @Param("true")
- private boolean isUserTypeFast;
-
- // "" means no fixed seed
- @Param("")
- private SpecialRandom random;
-
- @Param("false")
- private boolean sortedData;
-
- // the following must be set during setUp
- private Element[] queries;
- private Map<Element, Element> mapToTest;
-
- private Collection<Element> values;
-
- @Override public void setUp() {
- CollectionBenchmarkSampleData sampleData =
- new CollectionBenchmarkSampleData(
- isUserTypeFast, random, hitRate, size);
-
- if (sortedData) {
- List<Element> valueList = Lists.newArrayList(sampleData.getValuesInSet());
- Collections.sort(valueList);
- values = valueList;
- } else {
- values = sampleData.getValuesInSet();
- }
- this.mapToTest = impl.create(values);
- this.queries = sampleData.getQueries();
- }
-
- public boolean timeGet(int reps) {
- // Paranoia: acting on hearsay that accessing fields might be slow
- // Should write a benchmark to test that!
- Map<Element, Element> map = mapToTest;
- Element[] queries = this.queries;
-
- // Allows us to use & instead of %, acting on hearsay that division
- // operators (/%) are disproportionately expensive; should test this too!
- int mask = queries.length - 1;
-
- boolean dummy = false;
- for (int i = 0; i < reps; i++) {
- dummy ^= map.get(queries[i & mask]) != null;
- }
- return dummy;
- }
-
- public int timeCreateAndPopulate(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += impl.create(values).size();
- }
- return dummy;
- }
-
- public static void main(String[] args) throws Exception {
- Runner.main(MapBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/MapMakerSingleThreadBenchmark.java b/guava-tests/benchmark/com/google/common/collect/MapMakerSingleThreadBenchmark.java
deleted file mode 100644
index b6c3e30..0000000
--- a/guava-tests/benchmark/com/google/common/collect/MapMakerSingleThreadBenchmark.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Function;
-import com.google.common.collect.MapMaker;
-import com.google.common.primitives.Ints;
-
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Simple single-threaded benchmark for a computing map with maximum size.
- *
- * @author Charles Fry
- */
-public class MapMakerSingleThreadBenchmark extends SimpleBenchmark {
- @Param({"1000", "2000"}) int maximumSize;
- @Param("5000") int distinctKeys;
- @Param("4") int segments;
-
- // 1 means uniform likelihood of keys; higher means some keys are more popular
- // tweak this to control hit rate
- @Param("2.5") double concentration;
-
- Random random = new Random();
-
- Map<Integer, Integer> cache;
-
- int max;
-
- static AtomicLong requests = new AtomicLong(0);
- static AtomicLong misses = new AtomicLong(0);
-
- @Override protected void setUp() {
- // random integers will be generated in this range, then raised to the
- // power of (1/concentration) and floor()ed
- max = Ints.checkedCast((long) Math.pow(distinctKeys, concentration));
-
- cache = new MapMaker()
- .concurrencyLevel(segments)
- .maximumSize(maximumSize)
- .makeComputingMap(
- new Function<Integer, Integer>() {
- @Override public Integer apply(Integer from) {
- return (int) misses.incrementAndGet();
- }
- });
-
- // To start, fill up the cache.
- // Each miss both increments the counter and causes the map to grow by one,
- // so until evictions begin, the size of the map is the greatest return
- // value seen so far
- while (cache.get(nextRandomKey()) < maximumSize) {}
-
- requests.set(0);
- misses.set(0);
- }
-
- public int time(int reps) {
- int dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy += cache.get(nextRandomKey());
- }
- requests.addAndGet(reps);
- return dummy;
- }
-
- private int nextRandomKey() {
- int a = random.nextInt(max);
-
- /*
- * For example, if concentration=2.0, the following takes the square root of
- * the uniformly-distributed random integer, then truncates any fractional
- * part, so higher integers would appear (in this case linearly) more often
- * than lower ones.
- */
- return (int) Math.pow(a, 1.0 / concentration);
- }
-
- @Override protected void tearDown() {
- double req = requests.get();
- double hit = req - misses.get();
-
- // Currently, this is going into /dev/null, but I'll fix that
- System.out.println("hit rate: " + hit / req);
- }
-
- public static void main(String[] args) {
- Runner.main(MapMakerSingleThreadBenchmark.class, args);
- }
-
- // for proper distributions later:
- // import JSci.maths.statistics.ProbabilityDistribution;
- // int key = (int) dist.inverse(random.nextDouble());
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/MinMaxPriorityQueueBenchmark.java b/guava-tests/benchmark/com/google/common/collect/MinMaxPriorityQueueBenchmark.java
deleted file mode 100644
index 4c022cc..0000000
--- a/guava-tests/benchmark/com/google/common/collect/MinMaxPriorityQueueBenchmark.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Function;
-import com.google.common.collect.ForwardingQueue;
-import com.google.common.collect.MinMaxPriorityQueue;
-import com.google.common.collect.Ordering;
-
-import java.math.BigInteger;
-import java.util.Comparator;
-import java.util.PriorityQueue;
-import java.util.Queue;
-import java.util.Random;
-
-/**
- * Benchmarks to compare performance of MinMaxPriorityQueue and PriorityQueue.
- *
- * @author Sverre Sundsdal
- */
-public class MinMaxPriorityQueueBenchmark extends SimpleBenchmark {
- @Param private ComparatorType comparator;
-
- // TODO(kevinb): add 1000000 back when we have the ability to throw
- // NotApplicableException in the expensive comparator case.
- @Param({"100", "10000"}) private int size;
-
- @Param private HeapType heap;
-
- private Queue<Integer> queue;
-
- private final Random random = new Random();
-
- @Override public void setUp() {
- queue = heap.create(comparator.get());
- for (int i = 0; i < size; i++) {
- queue.add(random.nextInt());
- }
- }
-
- public void timePollAndAdd(int reps) {
- for (int i = 0; i < reps; i++) {
- // TODO(kevinb): precompute random #s?
- queue.add(queue.poll() ^ random.nextInt());
- }
- }
-
- public void timePopulate(int reps) {
- for (int i = 0; i < reps; i++) {
- queue.clear();
- for (int j = 0; j < size; j++) {
- // TODO(kevinb): precompute random #s?
- queue.add(random.nextInt());
- }
- }
- }
-
- /**
- * Implementation of the InvertedMinMaxPriorityQueue which forwards all calls to
- * a MinMaxPriorityQueue, except poll, which is forwarded to pollMax. That way
- * we can benchmark pollMax using the same code that benchmarks poll.
- */
- static final class InvertedMinMaxPriorityQueue <T> extends ForwardingQueue<T> {
- MinMaxPriorityQueue<T> mmHeap;
- public InvertedMinMaxPriorityQueue(Comparator<T> comparator) {
- mmHeap = MinMaxPriorityQueue.orderedBy(comparator).create();
- }
-
- @Override
- protected Queue<T> delegate() {
- return mmHeap;
- }
-
- @Override
- public T poll() {
- return mmHeap.pollLast();
- }
-
- }
-
- public enum HeapType {
- MIN_MAX {
- @Override public Queue<Integer> create(Comparator<Integer> comparator) {
- return MinMaxPriorityQueue.orderedBy(comparator).create();
- }
- },
- PRIORITY_QUEUE {
- @Override public Queue<Integer> create(Comparator<Integer> comparator) {
- return new PriorityQueue<Integer>(11, comparator);
- }
- },
- INVERTED_MIN_MAX {
- @Override public Queue<Integer> create(Comparator<Integer> comparator) {
- return new InvertedMinMaxPriorityQueue<Integer>(comparator);
- }
- };
-
- public abstract Queue<Integer> create(Comparator<Integer> comparator);
- }
-
- /**
- * Does a CPU intensive operation on Integer and returns a BigInteger
- * Used to implement an ordering that spends a lot of cpu.
- */
- static class ExpensiveComputation implements Function<Integer, BigInteger> {
- @Override
- public BigInteger apply(Integer from) {
- BigInteger v = BigInteger.valueOf(from);
- // Math.sin is very slow for values outside 4*pi
- // Need to take absolute value to avoid inverting the value.
- for (double i = 0; i < 100; i += 20) {
- v = v.add(v.multiply(
- BigInteger.valueOf(
- ((Double) Math.abs(Math.sin(i) * 10.0)).longValue())));
- }
- return v;
- }
- }
-
- public enum ComparatorType {
- CHEAP {
- @Override public Comparator<Integer> get() {
- return Ordering.natural();
- }
- },
- EXPENSIVE {
- @Override public Comparator<Integer> get() {
- return Ordering.natural().onResultOf(new ExpensiveComputation());
- }
- };
- public abstract Comparator<Integer> get();
- }
-
- public static void main(String [] args) {
- Runner.main(MinMaxPriorityQueueBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/MultisetIteratorBenchmark.java b/guava-tests/benchmark/com/google/common/collect/MultisetIteratorBenchmark.java
deleted file mode 100644
index 03492a4..0000000
--- a/guava-tests/benchmark/com/google/common/collect/MultisetIteratorBenchmark.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.base.Preconditions;
-
-import java.util.Random;
-
-/**
- * Tests the speed of iteration of different iteration methods for collections.
- *
- * @author David Richter
- */
-public class MultisetIteratorBenchmark extends SimpleBenchmark {
- @Param({"0", "1", "16", "256", "4096", "65536"}) int size;
-
- LinkedHashMultiset<Object> linkedHashMultiset;
- HashMultiset<Object> hashMultiset;
-
- // TreeMultiset requires a Comparable element.
- TreeMultiset<Integer> treeMultiset;
-
- @Override protected void setUp() {
- hashMultiset = HashMultiset.create(size);
- linkedHashMultiset = LinkedHashMultiset.create(size);
- treeMultiset = TreeMultiset.create();
-
- Random random = new Random();
-
- int sizeRemaining = size;
-
- // TODO(kevinb): generate better test contents for multisets
- for (int i = 0; sizeRemaining > 0; i++) {
- // The JVM will return interned values for small ints.
- Integer value = random.nextInt(1000) + 128;
- int count = Math.min(random.nextInt(10) + 1, sizeRemaining);
- sizeRemaining -= count;
- hashMultiset.add(value, count);
- linkedHashMultiset.add(value, count);
- treeMultiset.add(value, count);
- }
-
- //TODO(kevinb): convert to assert once benchmark tests enable asserts by default
- Preconditions.checkState(hashMultiset.size() == size);
- }
-
- public int timeHashMultiset(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : hashMultiset) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public int timeLinkedHashMultiset(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : linkedHashMultiset) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public int timeTreeMultiset(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Object value : treeMultiset) {
- sum += value.hashCode();
- }
- }
- return sum;
- }
-
- public static void main(String[] args) {
- Runner.main(MultisetIteratorBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/PowerSetBenchmark.java b/guava-tests/benchmark/com/google/common/collect/PowerSetBenchmark.java
deleted file mode 100644
index 1816e43..0000000
--- a/guava-tests/benchmark/com/google/common/collect/PowerSetBenchmark.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.DiscreteDomain.integers;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Set;
-
-/**
- * Very simple powerSet iteration benchmark.
- *
- * @author Kevin Bourrillion
- */
-public class PowerSetBenchmark extends SimpleBenchmark {
- @Param({"2", "4", "8", "16"}) int elements;
-
- Set<Set<Integer>> powerSet;
-
- @Override protected void setUp() {
- Set<Integer> set = Range.closed(1, elements).asSet(integers());
- powerSet = Sets.powerSet(set);
- }
-
- public int timeIteration(int reps) {
- int sum = 0;
- for (int i = 0; i < reps; i++) {
- for (Set<Integer> subset : powerSet) {
- for (Integer value : subset) {
- sum += value;
- }
- }
- }
- return sum;
- }
-
- public static void main(String[] args) {
- Runner.main(PowerSetBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/SetContainsBenchmark.java b/guava-tests/benchmark/com/google/common/collect/SetContainsBenchmark.java
deleted file mode 100644
index aa5593d..0000000
--- a/guava-tests/benchmark/com/google/common/collect/SetContainsBenchmark.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.BenchmarkHelpers.SetImpl;
-import com.google.common.collect.CollectionBenchmarkSampleData.Element;
-
-import java.util.Set;
-
-/**
- * A microbenchmark that tests the performance of contains() on various Set
- * implementations.
- *
- * @author Kevin Bourrillion
- */
-public class SetContainsBenchmark extends SimpleBenchmark {
- // Start at 4.88 then multiply by 2*2^phi <evil cackle> - The goal is be uniform
- // yet visit a variety of "values-relative-to-the-next-power-of-2"
- @Param({"5", "30", "180", "1100", "6900", "43000", "260000"}) // "1600000", "9800000"
- private int size;
-
- // TODO(kevinb): look at exact (==) hits vs. equals() hits?
- @Param({"0.2", "0.8"})
- private double hitRate;
-
- @Param("true")
- private boolean isUserTypeFast;
-
- // "" means no fixed seed
- @Param("")
- private SpecialRandom random;
-
- @Param({"Hash", "Immutable"})
- private SetImpl impl;
-
- // the following must be set during setUp
- private Element[] queries;
- private Set<Element> setToTest;
-
- @Override public void setUp() {
- CollectionBenchmarkSampleData sampleData =
- new CollectionBenchmarkSampleData(
- isUserTypeFast, random, hitRate, size);
-
- this.setToTest = impl.create(sampleData.getValuesInSet());
- this.queries = sampleData.getQueries();
- }
-
- public boolean timeContains(int reps) {
- // Paranoia: acting on hearsay that accessing fields might be slow
- // Should write a benchmark to test that!
- Set<Element> set = setToTest;
- Element[] queries = this.queries;
-
- int mask = queries.length - 1;
-
- boolean dummy = false;
- for (int i = 0; i < reps; i++) {
- dummy ^= set.contains(queries[i & mask]);
- }
- return dummy;
- }
-
- public static void main(String[] args) throws Exception {
- Runner.main(SetContainsBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/SetCreationBenchmark.java b/guava-tests/benchmark/com/google/common/collect/SetCreationBenchmark.java
deleted file mode 100644
index faf4472..0000000
--- a/guava-tests/benchmark/com/google/common/collect/SetCreationBenchmark.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.BenchmarkHelpers.SetImpl;
-
-/**
- * This is meant to be used with {@code --measureMemory} to measure the memory
- * usage of various {@code Set} implementations.
- *
- * @author Christopher Swenson
- */
-public class SetCreationBenchmark extends SimpleBenchmark {
- @Param({ "3", "6", "11", "23", "45", "91", "181", "362", "724", "1448",
- "2896", "5793", "11585", "23170", "46341", "92682", "185364", "370728",
- "741455", "1482910", "2965821", "5931642"})
- private int size;
-
- // "" means no fixed seed
- @Param("1234")
- private SpecialRandom random;
-
- @Param({"Immutable", "Hash"})
- private SetImpl impl;
-
- // the following must be set during setUp
- private CollectionBenchmarkSampleData sampleData;
-
- @Override public void setUp() {
- sampleData = new CollectionBenchmarkSampleData(true, random, 0.8, size);
- }
-
- public int timeCreation(int reps) {
- int x = 0;
- for (int i = 0; i < reps; i++) {
- x ^= System.identityHashCode(impl.create(sampleData.getValuesInSet()));
- }
- return x;
- }
-
- public static void main(String[] args) throws Exception {
- Runner.main(SetCreationBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/collect/SetIterationBenchmark.java b/guava-tests/benchmark/com/google/common/collect/SetIterationBenchmark.java
deleted file mode 100644
index 1585eed..0000000
--- a/guava-tests/benchmark/com/google/common/collect/SetIterationBenchmark.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.collect.BenchmarkHelpers.SetImpl;
-import com.google.common.collect.CollectionBenchmarkSampleData.Element;
-
-import java.util.Set;
-
-/**
- * Test iteration speed at various size for {@link Set} instances.
- *
- * @author Christopher Swenson
- */
-public class SetIterationBenchmark extends SimpleBenchmark {
- @Param({ "3", "6", "11", "23", "45", "91", "181", "362", "724", "1448",
- "2896", "5793", "11585", "23170", "46341", "92682", "185364", "370728",
- "741455", "1482910", "2965821", "5931642"})
- private int size;
-
- // "" means no fixed seed
- @Param("1234")
- private SpecialRandom random;
-
- @Param({"Immutable", "Hash"})
- private SetImpl impl;
-
- // the following must be set during setUp
- private Set<Element> setToTest;
-
- @Override public void setUp() {
- CollectionBenchmarkSampleData sampleData =
- new CollectionBenchmarkSampleData(true, random, 0.8, size);
- setToTest = impl.create(sampleData.getValuesInSet());
- }
-
- public int timeIteration(int reps) {
- int x = 0;
-
- for (int i = 0; i < reps; i++) {
- for (Element y : setToTest) {
- x ^= System.identityHashCode(y);
- }
- }
- return x;
- }
-
- public static void main(String[] args) throws Exception {
- Runner.main(SetIterationBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/hash/ChecksumBenchmark.java b/guava-tests/benchmark/com/google/common/hash/ChecksumBenchmark.java
deleted file mode 100644
index 28dba53..0000000
--- a/guava-tests/benchmark/com/google/common/hash/ChecksumBenchmark.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Random;
-import java.util.zip.Adler32;
-import java.util.zip.CRC32;
-import java.util.zip.Checksum;
-
-/**
- * Benchmarks for comparing {@link Checksum}s and {@link HashFunction}s that wrap {@link Checksum}s.
- *
- * <p>Parameters for the benchmark are: <ul> <li>size: The length of the byte array to hash. </ul>
- *
- * @author Colin Decker
- */
-public class ChecksumBenchmark extends SimpleBenchmark {
-
- // Use a constant seed for all of the benchmarks to ensure apples to apples comparisons.
- private static final int RANDOM_SEED = new Random().nextInt();
-
- @Param({"10", "1000", "100000", "1000000"})
- private int size;
-
- private byte[] testBytes;
-
- @Override
- public void setUp() {
- testBytes = new byte[size];
- new Random(RANDOM_SEED).nextBytes(testBytes);
- }
-
- // CRC32
-
- public byte timeCrc32HashFunction(int reps) {
- return runHashFunction(reps, Hashing.crc32());
- }
-
- public byte timeCrc32Checksum(int reps) throws Exception {
- byte result = 0x01;
- for (int i = 0; i < reps; i++) {
- CRC32 checksum = new CRC32();
- checksum.update(testBytes);
- result ^= checksum.getValue();
- }
- return result;
- }
-
- // Adler32
-
- public byte timeAdler32HashFunction(int reps) {
- return runHashFunction(reps, Hashing.adler32());
- }
-
- public byte timeAdler32Checksum(int reps) throws Exception {
- byte result = 0x01;
- for (int i = 0; i < reps; i++) {
- Adler32 checksum = new Adler32();
- checksum.update(testBytes);
- result ^= checksum.getValue();
- }
- return result;
- }
-
- // Helpers + main
-
- private byte runHashFunction(int reps, HashFunction hashFunction) {
- byte result = 0x01;
- // Trick the JVM to prevent it from using the hash function non-polymorphically
- result ^= Hashing.crc32().hashInt(reps).asBytes()[0];
- result ^= Hashing.adler32().hashInt(reps).asBytes()[0];
- for (int i = 0; i < reps; i++) {
- result ^= hashFunction.hashBytes(testBytes).asBytes()[0];
- }
- return result;
- }
-
- public static void main(String[] args) {
- Runner.main(ChecksumBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/hash/HashBenchmark.java b/guava-tests/benchmark/com/google/common/hash/HashBenchmark.java
deleted file mode 100644
index 2027218..0000000
--- a/guava-tests/benchmark/com/google/common/hash/HashBenchmark.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Random;
-
-/**
- * Benchmarks for hashing functions. This class benchmarks various hasing functions for a range of
- * sizes of byte array. The input data is generated by a call to {@link Random#nextBytes}.
- *
- * <p>Parameters for the benchmark are:
- * <ul>
- * <li>size: The length of the byte array to hash.
- * <li>function: The name of the function(s) to test (eg, "goodFastHash32" or "murmur3_32")
- * </ul>
- *
- * @author David Beaumont
- */
-public class HashBenchmark extends SimpleBenchmark {
-
- @Param({"10", "1000", "1000000"})
- private int size;
-
- @Param private HashType function;
-
- private enum HashType {
- goodFastHash32() {
- @Override public long hash(byte[] data) {
- return Hashing.goodFastHash(32).hashBytes(data).asInt();
- }
- },
- goodFastHash64() {
- @Override public long hash(byte[] data) {
- return Hashing.goodFastHash(64).hashBytes(data).asLong();
- }
- },
- murmur32() {
- @Override public long hash(byte[] data) {
- return Hashing.murmur3_32().hashBytes(data).asInt();
- }
- },
- murmur128() {
- @Override public long hash(byte[] data) {
- return Hashing.murmur3_128().hashBytes(data).asLong();
- }
- },
- md5() {
- @Override public long hash(byte[] data) {
- return Hashing.md5().hashBytes(data).asLong();
- }
- };
- public abstract long hash(byte[] data);
- }
-
- private byte[] testData;
-
- @Override
- protected void setUp() {
- testData = new byte[size];
- new Random().nextBytes(testData);
- }
-
- public int timeHashFunction(int reps) {
- long dummy = 0;
- for (int i = 0; i < reps; i++) {
- dummy ^= function.hash(testData);
- }
- return (int) dummy;
- }
-
- public static void main(String[] args) {
- Runner.main(HashBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/hash/HashFunctionBenchmark.java b/guava-tests/benchmark/com/google/common/hash/HashFunctionBenchmark.java
deleted file mode 100644
index 92a8cf3..0000000
--- a/guava-tests/benchmark/com/google/common/hash/HashFunctionBenchmark.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-
-import java.util.Random;
-
-/**
- * Benchmarks for comparing the various {@link HashFunction functions} that we provide.
- *
- * <p>Parameters for the benchmark are:
- * <ul>
- * <li>size: The length of the byte array to hash.
- * </ul>
- *
- * @author Kurt Alfred Kluever
- */
-public class HashFunctionBenchmark extends SimpleBenchmark {
-
- // Use a constant seed for all of the benchmarks to ensure apples to apples comparisons.
- private static final int RANDOM_SEED = new Random().nextInt();
-
- @Param({"10", "1000", "100000", "1000000"})
- private int size;
-
- private byte[] testBytes;
-
- @Override public void setUp() {
- testBytes = new byte[size];
- new Random(RANDOM_SEED).nextBytes(testBytes);
- }
-
- public int timeMurmur32HashFunction(int reps) {
- return runHashFunction(reps, Hashing.murmur3_32());
- }
-
- public int timeMurmur128HashFunction(int reps) {
- return runHashFunction(reps, Hashing.murmur3_128());
- }
-
- public int timeMd5HashFunction(int reps) {
- return runHashFunction(reps, Hashing.md5());
- }
-
- public int timeSha1HashFunction(int reps) {
- return runHashFunction(reps, Hashing.sha1());
- }
-
- public int timeSha256HashFunction(int reps) {
- return runHashFunction(reps, Hashing.sha256());
- }
-
- public int timeSha512HashFunction(int reps) {
- return runHashFunction(reps, Hashing.sha512());
- }
-
- private int runHashFunction(int reps, HashFunction hashFunction) {
- int result = 37;
- for (int i = 0; i < reps; i++) {
- result ^= hashFunction.hashBytes(testBytes).asInt();
- }
- return result;
- }
-
- public static void main(String[] args) {
- Runner.main(HashFunctionBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/hash/MessageDigestAlgorithmBenchmark.java b/guava-tests/benchmark/com/google/common/hash/MessageDigestAlgorithmBenchmark.java
deleted file mode 100644
index bef6e63..0000000
--- a/guava-tests/benchmark/com/google/common/hash/MessageDigestAlgorithmBenchmark.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hashing;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import java.util.Random;
-
-/**
- * Benchmarks for comparing {@link MessageDigest}s and {@link HashFunction}s that wrap
- * {@link MessageDigest}s.
- *
- * <p>Parameters for the benchmark are:
- * <ul>
- * <li>size: The length of the byte array to hash.
- * <li>algorithm: the algorithm to hash with (e.g. MD5, SHA1, etc.).
- * <li>hashMethod: how to hash the data (using the Hashing API or the MessageDigest API).
- * </ul>
- *
- * @author Kurt Alfred Kluever
- */
-public class MessageDigestAlgorithmBenchmark extends SimpleBenchmark {
- @Param({"10", "1000", "100000", "1000000"}) int size;
- @Param Algorithm algorithm;
- @Param HashMethod hashMethod;
-
- private enum HashMethod {
- MESSAGE_DIGEST_API() {
- @Override public byte[] hash(Algorithm algorithm, byte[] input) {
- MessageDigest md = algorithm.getMessageDigest();
- md.update(input);
- return md.digest();
- }
- },
- HASH_FUNCTION_API() {
- @Override public byte[] hash(Algorithm algorithm, byte[] input) {
- return algorithm.getHashFunction().hashBytes(input).asBytes();
- }
- };
- public abstract byte[] hash(Algorithm algorithm, byte[] input);
- }
-
- private enum Algorithm {
- MD5("MD5", Hashing.md5()),
- SHA_1("SHA-1", Hashing.sha1()),
- SHA_256("SHA-256", Hashing.sha256()),
- SHA_512("SHA-512", Hashing.sha512());
-
- private final String algorithmName;
- private final HashFunction hashFn;
- Algorithm(String algorithmName, HashFunction hashFn) {
- this.algorithmName = algorithmName;
- this.hashFn = hashFn;
- }
- public MessageDigest getMessageDigest() {
- try {
- return MessageDigest.getInstance(algorithmName);
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
- public HashFunction getHashFunction() {
- return hashFn;
- }
- }
-
- // Use a constant seed for all of the benchmarks to ensure apples to apples comparisons.
- private static final int RANDOM_SEED = new Random().nextInt();
-
- private byte[] testBytes;
-
- @Override public void setUp() {
- testBytes = new byte[size];
- new Random(RANDOM_SEED).nextBytes(testBytes);
- }
-
- public byte timeHashing(int reps) {
- byte result = 0x01;
- HashMethod hashMethod = this.hashMethod;
- Algorithm algorithm = this.algorithm;
- for (int i = 0; i < reps; i++) {
- result ^= hashMethod.hash(algorithm, testBytes)[0];
- }
- return result;
- }
-
- public static void main(String[] args) {
- Runner.main(MessageDigestAlgorithmBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/hash/MessageDigestCreationBenchmark.java b/guava-tests/benchmark/com/google/common/hash/MessageDigestCreationBenchmark.java
deleted file mode 100644
index 1adfd1d..0000000
--- a/guava-tests/benchmark/com/google/common/hash/MessageDigestCreationBenchmark.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.security.MessageDigest;
-
-/**
- * Benchmarks for comparing instance creation of {@link MessageDigest}s.
- *
- * @author Kurt Alfred Kluever
- */
-public class MessageDigestCreationBenchmark extends SimpleBenchmark {
-
- @Param({"MD5", "SHA-1", "SHA-256", "SHA-512"})
- private String algorithm;
-
- private MessageDigest md;
-
- public void setUp() throws Exception {
- md = MessageDigest.getInstance(algorithm);
- }
-
- public int timeGetInstance(int reps) throws Exception {
- int retValue = 0;
- for (int i = 0; i < reps; i++) {
- retValue ^= MessageDigest.getInstance(algorithm).getDigestLength();
- }
- return retValue;
- }
-
- public int timeClone(int reps) throws Exception {
- int retValue = 0;
- for (int i = 0; i < reps; i++) {
- retValue ^= ((MessageDigest) md.clone()).getDigestLength();
- }
- return retValue;
- }
-
- public static void main(String[] args) {
- Runner.main(MessageDigestCreationBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/ApacheBenchmark.java b/guava-tests/benchmark/com/google/common/math/ApacheBenchmark.java
deleted file mode 100644
index 7580058..0000000
--- a/guava-tests/benchmark/com/google/common/math/ApacheBenchmark.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static com.google.common.math.MathBenchmarking.randomBigInteger;
-import static com.google.common.math.MathBenchmarking.randomNonNegativeBigInteger;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.DoubleMath;
-import com.google.common.math.IntMath;
-import com.google.common.math.LongMath;
-
-/**
- * Benchmarks against the Apache Commons Math utilities.
- *
- * <p>Note: the Apache benchmarks are not open sourced to avoid the extra dependency.
- *
- * @author Louis Wasserman
- */
-public class ApacheBenchmark extends SimpleBenchmark {
- private enum Impl {
- GUAVA {
- @Override
- public double factorialDouble(int n) {
- return DoubleMath.factorial(n);
- }
-
- @Override
- public int gcdInt(int a, int b) {
- return IntMath.gcd(a, b);
- }
-
- @Override
- public long gcdLong(long a, long b) {
- return LongMath.gcd(a, b);
- }
-
- @Override
- public long binomialCoefficient(int n, int k) {
- return LongMath.binomial(n, k);
- }
-
- @Override
- public boolean noAddOverflow(int a, int b) {
- try {
- IntMath.checkedAdd(a, b);
- return true;
- } catch (ArithmeticException e) {
- return false;
- }
- }
-
- @Override
- public boolean noAddOverflow(long a, long b) {
- try {
- LongMath.checkedAdd(a, b);
- return true;
- } catch (ArithmeticException e) {
- return false;
- }
- }
-
- @Override
- public boolean noMulOverflow(int a, int b) {
- try {
- IntMath.checkedMultiply(a, b);
- return true;
- } catch (ArithmeticException e) {
- return false;
- }
- }
-
- @Override
- public boolean noMulOverflow(long a, long b) {
- try {
- LongMath.checkedMultiply(a, b);
- return true;
- } catch (ArithmeticException e) {
- return false;
- }
- }
- };
-
- public abstract double factorialDouble(int n);
-
- public abstract long binomialCoefficient(int n, int k);
-
- public abstract int gcdInt(int a, int b);
-
- public abstract long gcdLong(long a, long b);
-
- public abstract boolean noAddOverflow(int a, int b);
-
- public abstract boolean noAddOverflow(long a, long b);
-
- public abstract boolean noMulOverflow(int a, int b);
-
- public abstract boolean noMulOverflow(long a, long b);
- }
-
- private final int[] factorials = new int[ARRAY_SIZE];
- private final int[][] binomials = new int[ARRAY_SIZE][2];
- private final int[][] nonnegInt = new int[ARRAY_SIZE][2];
- private final long[][] nonnegLong = new long[ARRAY_SIZE][2];
- private final int[][] intsToAdd = new int[ARRAY_SIZE][2];
- private final int[][] intsToMul = new int[ARRAY_SIZE][2];
- private final long[][] longsToAdd = new long[ARRAY_SIZE][2];
- private final long[][] longsToMul = new long[ARRAY_SIZE][2];
-
- @Param({"APACHE", "GUAVA"})
- Impl impl;
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- factorials[i] = RANDOM_SOURCE.nextInt(200);
- for (int j = 0; j < 2; j++) {
- nonnegInt[i][j] = randomNonNegativeBigInteger(Integer.SIZE - 2).intValue();
- nonnegLong[i][j] = randomNonNegativeBigInteger(Long.SIZE - 2).longValue();
- }
- do {
- for (int j = 0; j < 2; j++) {
- intsToAdd[i][j] = randomBigInteger(Integer.SIZE - 2).intValue();
- }
- } while (!Impl.GUAVA.noAddOverflow(intsToAdd[i][0], intsToAdd[i][1]));
- do {
- for (int j = 0; j < 2; j++) {
- longsToAdd[i][j] = randomBigInteger(Long.SIZE - 2).longValue();
- }
- } while (!Impl.GUAVA.noAddOverflow(longsToAdd[i][0], longsToAdd[i][1]));
- do {
- for (int j = 0; j < 2; j++) {
- intsToMul[i][j] = randomBigInteger(Integer.SIZE - 2).intValue();
- }
- } while (!Impl.GUAVA.noMulOverflow(intsToMul[i][0], intsToMul[i][1]));
- do {
- for (int j = 0; j < 2; j++) {
- longsToMul[i][j] = randomBigInteger(Long.SIZE - 2).longValue();
- }
- } while (!Impl.GUAVA.noMulOverflow(longsToMul[i][0], longsToMul[i][1]));
-
- int k = binomials[i][1] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials.length);
- binomials[i][0] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials[k] - k) + k;
- }
- }
-
- public long timeFactorialDouble(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += Double.doubleToRawLongBits(impl.factorialDouble(factorials[j]));
- }
- return tmp;
- }
-
- public int timeIntGCD(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += impl.gcdInt(nonnegInt[j][0], nonnegInt[j][1]);
- }
- return tmp;
- }
-
- public long timeLongGCD(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += impl.gcdLong(nonnegLong[j][0], nonnegLong[j][1]);
- }
- return tmp;
- }
-
- public long timeBinomialCoefficient(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += impl.binomialCoefficient(binomials[j][0], binomials[j][1]);
- }
- return tmp;
- }
-
- public int timeIntAddOverflow(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- if (impl.noAddOverflow(intsToAdd[j][0], intsToAdd[j][1])) {
- tmp++;
- }
- }
- return tmp;
- }
-
- public int timeLongAddOverflow(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- if (impl.noAddOverflow(longsToAdd[j][0], longsToAdd[j][1])) {
- tmp++;
- }
- }
- return tmp;
- }
-
- public int timeIntMulOverflow(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- if (impl.noMulOverflow(intsToMul[j][0], intsToMul[j][1])) {
- tmp++;
- }
- }
- return tmp;
- }
-
- public int timeLongMulOverflow(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- if (impl.noMulOverflow(longsToMul[j][0], longsToMul[j][1])) {
- tmp++;
- }
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(ApacheBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/BigIntegerMathBenchmark.java b/guava-tests/benchmark/com/google/common/math/BigIntegerMathBenchmark.java
deleted file mode 100644
index 71095e5..0000000
--- a/guava-tests/benchmark/com/google/common/math/BigIntegerMathBenchmark.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static java.math.RoundingMode.CEILING;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.BigIntegerMath;
-import com.google.common.math.IntMath;
-import com.google.common.math.LongMath;
-
-import java.math.BigInteger;
-
-/**
- * Benchmarks for the non-rounding methods of {@code BigIntegerMath}.
- *
- * @author Louis Wasserman
- */
-public class BigIntegerMathBenchmark extends SimpleBenchmark {
- private static final int[] factorials = new int[ARRAY_SIZE];
- private static final int[] slowFactorials = new int[ARRAY_SIZE];
- private static final int[] binomials = new int[ARRAY_SIZE];
-
- @Param({"50", "1000", "10000"})
- int factorialBound;
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- factorials[i] = RANDOM_SOURCE.nextInt(factorialBound);
- slowFactorials[i] = RANDOM_SOURCE.nextInt(factorialBound);
- binomials[i] = RANDOM_SOURCE.nextInt(factorials[i] + 1);
- }
- }
-
- /**
- * Previous version of BigIntegerMath.factorial, kept for timing purposes.
- */
- private static BigInteger slowFactorial(int n) {
- if (n <= 20) {
- return BigInteger.valueOf(LongMath.factorial(n));
- } else {
- int k = 20;
- return BigInteger.valueOf(LongMath.factorial(k)).multiply(slowFactorial(k, n));
- }
- }
-
- /**
- * Returns the product of {@code n1} exclusive through {@code n2} inclusive.
- */
- private static BigInteger slowFactorial(int n1, int n2) {
- assert n1 <= n2;
- if (IntMath.log2(n2, CEILING) * (n2 - n1) < Long.SIZE - 1) {
- // the result will definitely fit into a long
- long result = 1;
- for (int i = n1 + 1; i <= n2; i++) {
- result *= i;
- }
- return BigInteger.valueOf(result);
- }
-
- /*
- * We want each multiplication to have both sides with approximately the same number of digits.
- * Currently, we just divide the range in half.
- */
- int mid = (n1 + n2) >>> 1;
- return slowFactorial(n1, mid).multiply(slowFactorial(mid, n2));
- }
-
- public int timeSlowFactorial(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += slowFactorial(slowFactorials[j]).intValue();
- }
- return tmp;
- }
-
- public int timeFactorial(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += BigIntegerMath.factorial(factorials[j]).intValue();
- }
- return tmp;
- }
-
- public int timeBinomial(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & 0xffff;
- tmp += BigIntegerMath.binomial(factorials[j], binomials[j]).intValue();
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(BigIntegerMathBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java b/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java
deleted file mode 100644
index c7b7df5..0000000
--- a/guava-tests/benchmark/com/google/common/math/BigIntegerMathRoundingBenchmark.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.randomNonZeroBigInteger;
-import static com.google.common.math.MathBenchmarking.randomPositiveBigInteger;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.BigIntegerMath;
-
-import java.math.BigInteger;
-import java.math.RoundingMode;
-
-/**
- * Benchmarks for the rounding methods of {@code BigIntegerMath}.
- *
- * @author Louis Wasserman
- */
-public class BigIntegerMathRoundingBenchmark extends SimpleBenchmark {
- private static final BigInteger[] nonzero1 = new BigInteger[ARRAY_SIZE];
- private static final BigInteger[] nonzero2 = new BigInteger[ARRAY_SIZE];
- private static final BigInteger[] positive = new BigInteger[ARRAY_SIZE];
-
- @Param({"DOWN", "UP", "FLOOR", "CEILING", "HALF_EVEN", "HALF_UP", "HALF_DOWN"})
- RoundingMode mode;
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- positive[i] = randomPositiveBigInteger(1024);
- nonzero1[i] = randomNonZeroBigInteger(1024);
- nonzero2[i] = randomNonZeroBigInteger(1024);
- }
- }
-
- public int timeLog2(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += BigIntegerMath.log2(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeLog10(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += BigIntegerMath.log10(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeSqrt(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += BigIntegerMath.sqrt(positive[j], mode).intValue();
- }
- return tmp;
- }
-
- public int timeDivide(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += BigIntegerMath.divide(nonzero1[j], nonzero2[j], mode).intValue();
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(BigIntegerMathRoundingBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/DoubleMathBenchmark.java b/guava-tests/benchmark/com/google/common/math/DoubleMathBenchmark.java
deleted file mode 100644
index 12e24a3..0000000
--- a/guava-tests/benchmark/com/google/common/math/DoubleMathBenchmark.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static com.google.common.math.MathBenchmarking.randomDouble;
-import static com.google.common.math.MathBenchmarking.randomPositiveDouble;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-/**
- * Tests for the non-rounding methods of {@code DoubleMath}.
- *
- * @author Louis Wasserman
- */
-public class DoubleMathBenchmark extends SimpleBenchmark {
- private static final double[] positiveDoubles = new double[ARRAY_SIZE];
- private static final int[] factorials = new int[ARRAY_SIZE];
- private static final double [] doubles = new double[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- positiveDoubles[i] = randomPositiveDouble();
- doubles[i] = randomDouble(Long.SIZE);
- factorials[i] = RANDOM_SOURCE.nextInt(100);
- }
- }
-
- public long timeLog2(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += Double.doubleToRawLongBits(DoubleMath.log2(positiveDoubles[j]));
- }
- return tmp;
- }
-
- public long timeFactorial(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += Double.doubleToRawLongBits(DoubleMath.factorial(factorials[j]));
- }
- return tmp;
- }
-
- public int timeIsMathematicalInteger(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- if (DoubleMath.isMathematicalInteger(doubles[j])) {
- tmp++;
- }
- }
- return tmp;
- }
-
- public int timeIsPowerOfTwo(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- if (DoubleMath.isPowerOfTwo(doubles[j])) {
- tmp++;
- }
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(DoubleMathBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/DoubleMathRoundingBenchmark.java b/guava-tests/benchmark/com/google/common/math/DoubleMathRoundingBenchmark.java
deleted file mode 100644
index daafb94..0000000
--- a/guava-tests/benchmark/com/google/common/math/DoubleMathRoundingBenchmark.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.randomDouble;
-import static com.google.common.math.MathBenchmarking.randomPositiveDouble;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.DoubleMath;
-
-import java.math.RoundingMode;
-
-/**
- * Benchmarks for the rounding methods of {@code DoubleMath}.
- *
- * @author Louis Wasserman
- */
-public class DoubleMathRoundingBenchmark extends SimpleBenchmark {
- private static final double[] doubleInIntRange = new double[ARRAY_SIZE];
- private static final double[] doubleInLongRange = new double[ARRAY_SIZE];
- private static final double[] positiveDoubles = new double[ARRAY_SIZE];
-
- @Param({"DOWN", "UP", "FLOOR", "CEILING", "HALF_EVEN", "HALF_UP", "HALF_DOWN"})
- RoundingMode mode;
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- doubleInIntRange[i] = randomDouble(Integer.SIZE - 2);
- doubleInLongRange[i] = randomDouble(Long.SIZE - 2);
- positiveDoubles[i] = randomPositiveDouble();
- }
- }
-
- public int timeRoundToInt(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += DoubleMath.roundToInt(doubleInIntRange[j], mode);
- }
- return tmp;
- }
-
- public long timeRoundToLong(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += DoubleMath.roundToLong(doubleInLongRange[j], mode);
- }
- return tmp;
- }
-
- public int timeRoundToBigInteger(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += DoubleMath.roundToBigInteger(positiveDoubles[j], mode).intValue();
- }
- return tmp;
- }
-
- public int timeLog2Round(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += DoubleMath.log2(positiveDoubles[j], mode);
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(DoubleMathRoundingBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/IntMathBenchmark.java b/guava-tests/benchmark/com/google/common/math/IntMathBenchmark.java
deleted file mode 100644
index 9f439b4..0000000
--- a/guava-tests/benchmark/com/google/common/math/IntMathBenchmark.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static com.google.common.math.MathBenchmarking.randomExponent;
-import static com.google.common.math.MathBenchmarking.randomNonNegativeBigInteger;
-import static com.google.common.math.MathBenchmarking.randomPositiveBigInteger;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.IntMath;
-
-/**
- * Benchmarks for the non-rounding methods of {@code IntMath}.
- *
- * @author Louis Wasserman
- */
-public class IntMathBenchmark extends SimpleBenchmark {
- private static int[] exponent = new int[ARRAY_SIZE];
- private static int[] factorial = new int[ARRAY_SIZE];
- private static int[] binomial = new int[ARRAY_SIZE];
- private static final int[] positive = new int[ARRAY_SIZE];
- private static final int[] nonnegative = new int[ARRAY_SIZE];
- private static final int[] ints = new int[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- exponent[i] = randomExponent();
- factorial[i] = RANDOM_SOURCE.nextInt(50);
- binomial[i] = RANDOM_SOURCE.nextInt(factorial[i] + 1);
- positive[i] = randomPositiveBigInteger(Integer.SIZE - 2).intValue();
- nonnegative[i] = randomNonNegativeBigInteger(Integer.SIZE - 2).intValue();
- ints[i] = RANDOM_SOURCE.nextInt();
- }
- }
-
- public int timePow(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.pow(positive[j], exponent[j]);
- }
- return tmp;
- }
-
- public int timeMod(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.mod(ints[j], positive[j]);
- }
- return tmp;
- }
-
- public int timeGCD(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.gcd(nonnegative[j], positive[j]);
- }
- return tmp;
- }
-
- public int timeFactorial(int reps){
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.factorial(factorial[j]);
- }
- return tmp;
- }
-
- public int timeBinomial(int reps){
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.binomial(factorial[j], binomial[j]);
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(IntMathBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/IntMathRoundingBenchmark.java b/guava-tests/benchmark/com/google/common/math/IntMathRoundingBenchmark.java
deleted file mode 100644
index 1bbefbe..0000000
--- a/guava-tests/benchmark/com/google/common/math/IntMathRoundingBenchmark.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static com.google.common.math.MathBenchmarking.randomNonZeroBigInteger;
-import static com.google.common.math.MathBenchmarking.randomPositiveBigInteger;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.IntMath;
-
-import java.math.RoundingMode;
-
-/**
- * Benchmarks for the rounding methods of {@code IntMath}.
- *
- * @author Louis Wasserman
- */
-public class IntMathRoundingBenchmark extends SimpleBenchmark {
- private static final int[] positive = new int[ARRAY_SIZE];
- private static final int[] nonzero = new int[ARRAY_SIZE];
- private static final int[] ints = new int[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- positive[i] = randomPositiveBigInteger(Integer.SIZE - 2).intValue();
- nonzero[i] = randomNonZeroBigInteger(Integer.SIZE - 2).intValue();
- ints[i] = RANDOM_SOURCE.nextInt();
- }
- }
-
- @Param({"DOWN", "UP", "FLOOR", "CEILING", "HALF_EVEN", "HALF_UP", "HALF_DOWN"})
- RoundingMode mode;
-
- public int timeLog2(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.log2(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeLog10(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.log10(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeSqrt(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.sqrt(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeDivide(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += IntMath.divide(ints[j], nonzero[j], mode);
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(IntMathRoundingBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/LongMathBenchmark.java b/guava-tests/benchmark/com/google/common/math/LongMathBenchmark.java
deleted file mode 100644
index 3a25a47..0000000
--- a/guava-tests/benchmark/com/google/common/math/LongMathBenchmark.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static com.google.common.math.MathBenchmarking.randomExponent;
-import static com.google.common.math.MathBenchmarking.randomNonNegativeBigInteger;
-import static com.google.common.math.MathBenchmarking.randomPositiveBigInteger;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.LongMath;
-
-/**
- * Benchmarks for the non-rounding methods of {@code LongMath}.
- *
- * @author Louis Wasserman
- */
-public class LongMathBenchmark extends SimpleBenchmark {
- private static final int[] exponents = new int[ARRAY_SIZE];
- private static final int[] factorialArguments = new int[ARRAY_SIZE];
- private static final int[][] binomialArguments = new int[ARRAY_SIZE][2];
- private static final long[] positive = new long[ARRAY_SIZE];
- private static final long[] nonnegative = new long[ARRAY_SIZE];
- private static final long[] longs = new long[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- exponents[i] = randomExponent();
- positive[i] = randomPositiveBigInteger(Long.SIZE - 2).longValue();
- nonnegative[i] = randomNonNegativeBigInteger(Long.SIZE - 2).longValue();
- longs[i] = RANDOM_SOURCE.nextLong();
- factorialArguments[i] = RANDOM_SOURCE.nextInt(30);
- binomialArguments[i][1] = RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials.length);
- int k = binomialArguments[i][1];
- binomialArguments[i][0] =
- RANDOM_SOURCE.nextInt(MathBenchmarking.biggestBinomials[k] - k) + k;
- }
- }
-
- public int timePow(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.pow(positive[j], exponents[j]);
- }
- return tmp;
- }
-
- public int timeMod(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.mod(longs[j], positive[j]);
- }
- return tmp;
- }
-
- public int timeGCD(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.mod(nonnegative[j], positive[j]);
- }
- return tmp;
- }
-
- public int timeFactorial(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.factorial(factorialArguments[j]);
- }
- return tmp;
- }
-
- public int timeBinomial(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.binomial(binomialArguments[j][0], binomialArguments[j][1]);
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(LongMathBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/math/LongMathRoundingBenchmark.java b/guava-tests/benchmark/com/google/common/math/LongMathRoundingBenchmark.java
deleted file mode 100644
index d859d35..0000000
--- a/guava-tests/benchmark/com/google/common/math/LongMathRoundingBenchmark.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import static com.google.common.math.MathBenchmarking.ARRAY_MASK;
-import static com.google.common.math.MathBenchmarking.ARRAY_SIZE;
-import static com.google.common.math.MathBenchmarking.RANDOM_SOURCE;
-import static com.google.common.math.MathBenchmarking.randomNonZeroBigInteger;
-import static com.google.common.math.MathBenchmarking.randomPositiveBigInteger;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-import com.google.common.math.LongMath;
-
-import java.math.RoundingMode;
-
-/**
- * Benchmarks for the rounding methods of {@code LongMath}.
- *
- * @author Louis Wasserman
- */
-public class LongMathRoundingBenchmark extends SimpleBenchmark {
- @Param({"DOWN", "UP", "FLOOR", "CEILING", "HALF_EVEN", "HALF_UP", "HALF_DOWN"})
- RoundingMode mode;
-
- private static final long[] positive = new long[ARRAY_SIZE];
- private static final long[] nonzero = new long[ARRAY_SIZE];
- private static final long[] longs = new long[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- positive[i] = randomPositiveBigInteger(Long.SIZE - 2).longValue();
- nonzero[i] = randomNonZeroBigInteger(Long.SIZE - 2).longValue();
- longs[i] = RANDOM_SOURCE.nextLong();
- }
- }
-
- public int timeLog2(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.log2(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeLog10(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.log10(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeSqrt(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.sqrt(positive[j], mode);
- }
- return tmp;
- }
-
- public int timeDivide(int reps) {
- int tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += LongMath.divide(longs[j], nonzero[j], mode);
- }
- return tmp;
- }
-
- public static void main(String[] args) {
- Runner.main(LongMathRoundingBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java b/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java
deleted file mode 100644
index eb874f6..0000000
--- a/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.primitives;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Random;
-
-/**
- * Microbenchmark for {@link UnsignedBytes}.
- *
- * @author Hiroshi Yamauchi
- */
-public class UnsignedBytesBenchmark extends SimpleBenchmark {
-
- private byte[] ba1;
- private byte[] ba2;
- private byte[] ba3;
- private byte[] ba4;
- private Comparator<byte[]> javaImpl;
- private Comparator<byte[]> unsafeImpl;
-
- // 4, 8, 64, 1K, 1M, 1M (unaligned), 64M, 64M (unaligned)
- //@Param({"4", "8", "64", "1024", "1048576", "1048577", "6710884", "6710883"})
- @Param({"4", "8", "64", "1024" })
- private int length;
-
- @Override
- protected void setUp() throws Exception {
- Random r = new Random();
- ba1 = new byte[length];
- r.nextBytes(ba1);
- ba2 = Arrays.copyOf(ba1, ba1.length);
- // Differ at the last element
- ba3 = Arrays.copyOf(ba1, ba1.length);
- ba4 = Arrays.copyOf(ba1, ba1.length);
- ba3[ba1.length - 1] = (byte) 43;
- ba4[ba1.length - 1] = (byte) 42;
-
- javaImpl = UnsignedBytes.lexicographicalComparatorJavaImpl();
- unsafeImpl =
- UnsignedBytes.LexicographicalComparatorHolder.UnsafeComparator.INSTANCE;
- }
-
- public void timeLongEqualJava(int reps) {
- for (int i = 0; i < reps; ++i) {
- if (javaImpl.compare(ba1, ba2) != 0) {
- throw new Error(); // deoptimization
- }
- }
- }
-
- public void timeLongEqualUnsafe(int reps) {
- for (int i = 0; i < reps; ++i) {
- if (unsafeImpl.compare(ba1, ba2) != 0) {
- throw new Error(); // deoptimization
- }
- }
- }
-
- public void timeDiffLastJava(int reps) {
- for (int i = 0; i < reps; ++i) {
- if (javaImpl.compare(ba3, ba4) == 0) {
- throw new Error(); // deoptimization
- }
- }
- }
-
- public void timeDiffLastUnsafe(int reps) {
- for (int i = 0; i < reps; ++i) {
- if (unsafeImpl.compare(ba3, ba4) == 0) {
- throw new Error(); // deoptimization
- }
- }
- }
-
- public static void main(String[] args) {
- /*
- try {
- UnsignedBytesBenchmark bench = new UnsignedBytesBenchmark();
- bench.length = 1024;
- bench.setUp();
- bench.timeUnsafe(100000);
- } catch (Exception e) {
- }*/
- Runner.main(UnsignedBytesBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/primitives/UnsignedLongsBenchmark.java b/guava-tests/benchmark/com/google/common/primitives/UnsignedLongsBenchmark.java
deleted file mode 100644
index 0820bc0..0000000
--- a/guava-tests/benchmark/com/google/common/primitives/UnsignedLongsBenchmark.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.primitives;
-
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Random;
-
-/**
- * Benchmarks for certain methods of {@code UnsignedLongs}.
- *
- * @author Eamonn McManus
- */
-public class UnsignedLongsBenchmark extends SimpleBenchmark {
- private static final int ARRAY_SIZE = 0x10000;
- private static final int ARRAY_MASK = 0x0ffff;
- private static final Random RANDOM_SOURCE = new Random(314159265358979L);
- private static final long[] longs = new long[ARRAY_SIZE];
- private static final long[] divisors = new long[ARRAY_SIZE];
- private static final String[] decimalStrings = new String[ARRAY_SIZE];
- private static final String[] binaryStrings = new String[ARRAY_SIZE];
- private static final String[] hexStrings = new String[ARRAY_SIZE];
- private static final String[] prefixedHexStrings = new String[ARRAY_SIZE];
-
- @Override
- protected void setUp() {
- for (int i = 0; i < ARRAY_SIZE; i++) {
- longs[i] = random();
- divisors[i] = randomDivisor(longs[i]);
- decimalStrings[i] = UnsignedLongs.toString(longs[i]);
- binaryStrings[i] = UnsignedLongs.toString(longs[i], 2);
- hexStrings[i] = UnsignedLongs.toString(longs[i], 16);
- prefixedHexStrings[i] = "0x" + hexStrings[i];
- }
- }
-
- public long timeDivide(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += UnsignedLongs.divide(longs[j], divisors[j]);
- }
- return tmp;
- }
-
- public long timeRemainder(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += UnsignedLongs.remainder(longs[j], divisors[j]);
- }
- return tmp;
- }
-
- public long timeParseUnsignedLong(int reps) {
- long tmp = 0;
- // Given that we make three calls per pass, we scale reps down in order
- // to do a comparable amount of work to other measurements.
- int scaledReps = reps / 3 + 1;
- for (int i = 0; i < scaledReps; i++) {
- int j = i & ARRAY_MASK;
- tmp += UnsignedLongs.parseUnsignedLong(decimalStrings[j]);
- tmp += UnsignedLongs.parseUnsignedLong(hexStrings[j], 16);
- tmp += UnsignedLongs.parseUnsignedLong(binaryStrings[j], 2);
- }
- return tmp;
- }
-
- public long timeParseDecode10(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += UnsignedLongs.decode(decimalStrings[j]);
- }
- return tmp;
- }
-
- public long timeParseDecode16(int reps) {
- long tmp = 0;
- for (int i = 0; i < reps; i++) {
- int j = i & ARRAY_MASK;
- tmp += UnsignedLongs.decode(prefixedHexStrings[j]);
- }
- return tmp;
- }
-
- public int timeToString(int reps) {
- int tmp = 0;
- // Given that we make three calls per pass, we scale reps down in order
- // to do a comparable amount of work to other measurements.
- int scaledReps = reps / 3 + 1;
- for (int i = 0; i < scaledReps; i++) {
- int j = i & ARRAY_MASK;
- long x = longs[j];
- tmp += UnsignedLongs.toString(x).length();
- tmp += UnsignedLongs.toString(x, 16).length();
- tmp += UnsignedLongs.toString(x, 2).length();
- }
- return tmp;
- }
-
- private static long random() {
- return RANDOM_SOURCE.nextLong();
- }
-
- // A random value that cannot be 0 and that is unsigned-less-than or equal
- // to the given dividend, so that we don't have half of our divisions being
- // trivial because the divisor is bigger than the dividend.
- // Using remainder here does not give us a uniform distribution but it should
- // not have a big impact on the measurement.
- private static long randomDivisor(long dividend) {
- long r = RANDOM_SOURCE.nextLong();
- if (dividend == -1) {
- return r;
- } else {
- return UnsignedLongs.remainder(r, dividend + 1);
- }
- }
-
- public static void main(String[] args) {
- Runner.main(UnsignedLongsBenchmark.class, args);
- }
-}
diff --git a/guava-tests/benchmark/com/google/common/util/concurrent/CycleDetectingLockFactoryBenchmark.java b/guava-tests/benchmark/com/google/common/util/concurrent/CycleDetectingLockFactoryBenchmark.java
deleted file mode 100644
index 6935f64..0000000
--- a/guava-tests/benchmark/com/google/common/util/concurrent/CycleDetectingLockFactoryBenchmark.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Benchmarks for {@link CycleDetectingLockFactory}.
- *
- * @author Darick Tong
- */
-public class CycleDetectingLockFactoryBenchmark extends SimpleBenchmark {
-
- @Param({"2","3","4","5","10"}) int lockNestingDepth;
-
- CycleDetectingLockFactory factory;
- private Lock[] plainLocks;
- private Lock[] detectingLocks;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- this.factory = CycleDetectingLockFactory.newInstance(
- CycleDetectingLockFactory.Policies.WARN);
- this.plainLocks = new Lock[lockNestingDepth];
- for (int i = 0; i < lockNestingDepth; i++) {
- plainLocks[i] = new ReentrantLock();
- }
- this.detectingLocks = new Lock[lockNestingDepth];
- for (int i = 0; i < lockNestingDepth; i++) {
- detectingLocks[i] = factory.newReentrantLock("Lock" + i);
- }
- }
-
- public void timeUnorderedPlainLocks(int reps) {
- lockAndUnlock(new ReentrantLock(), reps);
- }
-
- public void timeUnorderedCycleDetectingLocks(int reps) {
- lockAndUnlock(factory.newReentrantLock("foo"), reps);
- }
-
- private void lockAndUnlock(Lock lock, int reps) {
- for (int i = 0; i < reps; i++) {
- lock.lock();
- lock.unlock();
- }
- }
-
- public void timeOrderedPlainLocks(int reps) {
- lockAndUnlockNested(plainLocks, reps);
- }
-
- public void timeOrderedCycleDetectingLocks(int reps) {
- lockAndUnlockNested(detectingLocks, reps);
- }
-
- private void lockAndUnlockNested(Lock[] locks, int reps) {
- for (int i = 0; i < reps; i++) {
- for (int j = 0; j < locks.length; j++) {
- locks[j].lock();
- }
- for (int j = locks.length - 1; j >= 0; j--) {
- locks[j].unlock();
- }
- }
- }
-
- public static void main(String[] args) {
- Runner.main(CycleDetectingLockFactoryBenchmark.class, args);
- }
-
-}
diff --git a/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBenchmark.java b/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBenchmark.java
deleted file mode 100644
index 47e193f..0000000
--- a/guava-tests/benchmark/com/google/common/util/concurrent/MonitorBenchmark.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.lang.reflect.Constructor;
-import java.util.concurrent.BlockingQueue;
-
-/**
- * Benchmarks for {@link Monitor}.
- *
- * @author Justin T. Sampson
- */
-public class MonitorBenchmark extends SimpleBenchmark {
-
- @Param({"10", "100", "1000"}) int capacity;
- @Param({"Array", "Priority"}) String queueType;
- @Param boolean useMonitor;
-
- private BlockingQueue<String> queue;
- private String[] strings;
-
- @Override
- @SuppressWarnings("unchecked")
- protected void setUp() throws Exception {
- String prefix =
- (useMonitor ? "com.google.common.util.concurrent.MonitorBased" : "java.util.concurrent.");
- String className = prefix + queueType + "BlockingQueue";
- Constructor<?> constructor = Class.forName(className).getConstructor(int.class);
- queue = (BlockingQueue<String>) constructor.newInstance(capacity);
-
- strings = new String[capacity];
- for (int i = 0; i < capacity; i++) {
- strings[i] = String.valueOf(Math.random());
- }
- }
-
- public void timeAddsAndRemoves(int reps) {
- int capacity = this.capacity;
- BlockingQueue<String> queue = this.queue;
- String[] strings = this.strings;
- for (int i = 0; i < reps; i++) {
- for (int j = 0; j < capacity; j++) {
- queue.add(strings[j]);
- }
- for (int j = 0; j < capacity; j++) {
- queue.remove();
- }
- }
- }
-
- public static void main(String[] args) {
- Runner.main(MonitorBenchmark.class, args);
- }
-
-}
diff --git a/guava-tests/lib/libtruth-gwt.jar b/guava-tests/lib/libtruth-gwt.jar
new file mode 100644
index 0000000..5d61f52
--- /dev/null
+++ b/guava-tests/lib/libtruth-gwt.jar
Binary files differ
diff --git a/guava-tests/lib/libtruth.jar b/guava-tests/lib/libtruth.jar
new file mode 100644
index 0000000..a2ee08d
--- /dev/null
+++ b/guava-tests/lib/libtruth.jar
Binary files differ
diff --git a/guava-tests/pom.xml b/guava-tests/pom.xml
index c7256ff..ba0c62a 100644
--- a/guava-tests/pom.xml
+++ b/guava-tests/pom.xml
@@ -5,23 +5,17 @@
<parent>
<groupId>com.google.guava</groupId>
<artifactId>guava-parent</artifactId>
- <version>14.0.1</version>
+ <version>11.0.2</version>
</parent>
<artifactId>guava-tests</artifactId>
<name>Guava Unit Tests</name>
<description>
- The unit tests for the Guava libraries - separated into a
+ The unit tests for the Guava libraries - separated into a
separate artifact to allow for the testlibs to depend on guava
itself.
</description>
<dependencies>
<dependency>
- <groupId>com.google.code.findbugs</groupId>
- <artifactId>jsr305</artifactId>
- <version>1.3.9</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>${project.groupId}</groupId>
<artifactId>guava-testlib</artifactId>
<version>${project.version}</version>
@@ -40,62 +34,33 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>1.8.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.truth0</groupId>
+ <groupId>org.junit.contrib</groupId>
<artifactId>truth</artifactId>
- <version>0.10</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.google.caliper</groupId>
- <artifactId>caliper</artifactId>
- <version>0.5-rc1</version>
- <scope>test</scope>
+ <version>0.5.0-beta1</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/lib/libtruth.jar</systemPath>
</dependency>
</dependencies>
+ <repositories>
+ <repository>
+ <releases><enabled>true</enabled></releases>
+ <snapshots><enabled>false</enabled></snapshots>
+ <id>truth-github</id>
+ <name>Truth Github Repository</name>
+ <url>https://raw.github.com/truth0/repo/master</url>
+ </repository>
+ </repositories>
<build>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
+ <source>1.5</source>
+ <target>1.5</target>
</configuration>
</plugin>
- <plugin>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.1.2</version>
- <executions>
- <execution>
- <id>attach-test-sources</id>
- <phase>post-integration-test</phase>
- <goals><goal>test-jar</goal></goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <id>add-benchmark-sources</id>
- <phase>generate-test-sources</phase>
- <goals><goal>add-test-source</goal></goals>
- <configuration>
- <sources>
- <source>benchmark</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
<testResources>
<testResource>
diff --git a/guava-tests/test/com/google/common/base/BenchmarkHelpers.java b/guava-tests/test/com/google/common/base/BenchmarkHelpers.java
deleted file mode 100644
index 791c115..0000000
--- a/guava-tests/test/com/google/common/base/BenchmarkHelpers.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.base;
-
-/**
- * Common benchmarking utilities.
- *
- * @author Christopher Swenson
- * @author Louis Wasserman
- */
-class BenchmarkHelpers {
- private static final String WHITESPACE_CHARACTERS =
- "\u00a0\u180e\u202f\t\n\013\f\r \u0085"
- + "\u1680\u2028\u2029\u205f\u3000\u2000\u2001\u2002\u2003\u2004\u2005"
- + "\u2006\u2007\u2008\u2009\u200a";
- private static final String ASCII_CHARACTERS;
- static {
- int spaceInAscii = 32;
- int sevenBitAsciiMax = 128;
- StringBuilder sb = new StringBuilder(sevenBitAsciiMax - spaceInAscii);
- for (int ch = spaceInAscii; ch < sevenBitAsciiMax; ch++) {
- sb.append((char) ch);
- }
- ASCII_CHARACTERS = sb.toString();
- }
-
- private static final String ALL_DIGITS;
- static {
- StringBuilder sb = new StringBuilder();
- String zeros =
- "0\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66\u0be6\u0c66"
- + "\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810\u1946"
- + "\u19d0\u1b50\u1bb0\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10";
- for (char base : zeros.toCharArray()) {
- for (int offset = 0; offset < 10; offset++) {
- sb.append((char) (base + offset));
- }
- }
- ALL_DIGITS = sb.toString();
- }
-
- /**
- * Sample CharMatcher instances for benchmarking.
- */
- public enum SampleMatcherConfig {
- WHITESPACE(CharMatcher.WHITESPACE, WHITESPACE_CHARACTERS),
- HASH(CharMatcher.is('#'), "#"),
- ASCII(CharMatcher.ASCII, ASCII_CHARACTERS),
- WESTERN_DIGIT("0123456789"),
- ALL_DIGIT(CharMatcher.DIGIT, ALL_DIGITS),
- OPS_5("+-*/%"),
- HEX_16(CharMatcher.inRange('0', '9').or(CharMatcher.inRange('A', 'F')), "0123456789ABCDEF"),
- HEX_22(CharMatcher.inRange('0', '9')
- .or(CharMatcher.inRange('A', 'F')).or(CharMatcher.inRange('a', 'f')),
- "0123456789ABCDEFabcdef"),
- GERMAN_59(CharMatcher.inRange('a', 'z')
- .or(CharMatcher.inRange('A', 'Z')).or(CharMatcher.anyOf("äöüßÄÖÜ")),
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüßÄÖÜ");
-
- public final CharMatcher matcher;
- public final String matchingChars;
-
- SampleMatcherConfig(String matchingChars) {
- this(CharMatcher.anyOf(matchingChars), matchingChars);
- }
-
- SampleMatcherConfig(CharMatcher matcher, String matchingChars) {
- this.matcher = matcher;
- this.matchingChars = matchingChars;
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/base/CaseFormatTest.java b/guava-tests/test/com/google/common/base/CaseFormatTest.java
index d42bfc4..daabfa3 100644
--- a/guava-tests/test/com/google/common/base/CaseFormatTest.java
+++ b/guava-tests/test/com/google/common/base/CaseFormatTest.java
@@ -23,8 +23,6 @@ import static com.google.common.base.CaseFormat.UPPER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -33,7 +31,7 @@ import junit.framework.TestCase;
*
* @author Mike Bostock
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class CaseFormatTest extends TestCase {
public void testIdentity() {
@@ -46,13 +44,15 @@ public class CaseFormatTest extends TestCase {
}
}
- @GwtIncompatible("NullPointerTester")
- public void testNullArguments() {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicStaticMethods(CaseFormat.class);
- for (CaseFormat format : CaseFormat.values()) {
- tester.testAllPublicInstanceMethods(format);
- }
+ public void testNullPointer() {
+ try {
+ LOWER_CAMEL.to(null, "");
+ fail();
+ } catch (NullPointerException expected) {}
+ try {
+ LOWER_CAMEL.to(LOWER_HYPHEN, null);
+ fail();
+ } catch (NullPointerException expected) {}
}
public void testLowerHyphenToLowerHyphen() {
diff --git a/guava-tests/test/com/google/common/base/CharMatcherTest.java b/guava-tests/test/com/google/common/base/CharMatcherTest.java
index 9bdd200..5fe5662 100644
--- a/guava-tests/test/com/google/common/base/CharMatcherTest.java
+++ b/guava-tests/test/com/google/common/base/CharMatcherTest.java
@@ -25,18 +25,11 @@ import static com.google.common.base.CharMatcher.noneOf;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.Sets;
import com.google.common.testing.NullPointerTester;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.HashSet;
-import java.util.Random;
-import java.util.Set;
-
/**
* Unit test for {@link CharMatcher}.
*
@@ -75,7 +68,7 @@ public class CharMatcherTest extends TestCase {
assertSame(WHATEVER, CharMatcher.NONE.or(WHATEVER));
}
- // The rest of the behavior of ANY and DEFAULT will be covered in the tests for
+ // The rest of the behavior of ANY and NONE will be covered in the tests for
// the text processing methods below.
// The next tests require ICU4J and have, at least for now, been sliced out
@@ -89,6 +82,8 @@ public class CharMatcherTest extends TestCase {
}
}
+ // There's no way to test LEGACY_WHITESPACE, really; it just is what it is.
+
// Omitting tests for the rest of the JAVA_* constants as these are defined
// as extremely straightforward pass-throughs to the JDK methods.
@@ -99,34 +94,6 @@ public class CharMatcherTest extends TestCase {
// method, but by overall "scenario". Also, the variety of actual tests we
// do borders on absurd overkill. Better safe than sorry, though?
- @GwtIncompatible("java.util.BitSet")
- public void testSetBits() {
- doTestSetBits(CharMatcher.ANY);
- doTestSetBits(CharMatcher.NONE);
- doTestSetBits(is('a'));
- doTestSetBits(isNot('a'));
- doTestSetBits(anyOf(""));
- doTestSetBits(anyOf("x"));
- doTestSetBits(anyOf("xy"));
- doTestSetBits(anyOf("CharMatcher"));
- doTestSetBits(noneOf("CharMatcher"));
- doTestSetBits(inRange('n', 'q'));
- doTestSetBits(forPredicate(Predicates.equalTo('c')));
- doTestSetBits(CharMatcher.ASCII);
- doTestSetBits(CharMatcher.DIGIT);
- doTestSetBits(CharMatcher.INVISIBLE);
- doTestSetBits(inRange('A', 'Z').and(inRange('F', 'K').negate()));
- }
-
- @GwtIncompatible("java.util.BitSet")
- private void doTestSetBits(CharMatcher matcher) {
- BitSet bitset = new BitSet();
- matcher.setBits(bitset);
- for (int i = Character.MIN_VALUE; i <= Character.MAX_VALUE; i++) {
- assertEquals(matcher.matches((char) i), bitset.get(i));
- }
- }
-
public void testEmpty() throws Exception {
doTestEmpty(CharMatcher.ANY);
doTestEmpty(CharMatcher.NONE);
@@ -372,11 +339,14 @@ public class CharMatcherTest extends TestCase {
assertFalse(matcher.matchesAllOf(s));
assertTrue(matcher.matchesNoneOf(s));
- assertSame(s, matcher.removeFrom(s));
- assertSame(s, matcher.replaceFrom(s, 'z'));
- assertSame(s, matcher.replaceFrom(s, "ZZ"));
- assertSame(s, matcher.trimFrom(s));
- assertSame(0, matcher.countIn(s));
+ // Note: only 'assertEquals' is promised by the API. Although they could
+ // have been assertSame() on the server side, they have to be assertEquals
+ // in GWT, because of GWT issue 4491.
+ assertEquals(s, matcher.removeFrom(s));
+ assertEquals(s, matcher.replaceFrom(s, 'z'));
+ assertEquals(s, matcher.replaceFrom(s, "ZZ"));
+ assertEquals(s, matcher.trimFrom(s));
+ assertEquals(0, matcher.countIn(s));
}
private void reallyTestMatchThenNoMatch(CharMatcher matcher, String s) {
@@ -411,23 +381,10 @@ public class CharMatcherTest extends TestCase {
assertEquals(1, matcher.countIn(s));
}
- /**
- * Checks that expected is equals to out, and further, if in is
- * equals to expected, then out is successfully optimized to be
- * identical to in, i.e. that "in" is simply returned.
- */
- private void assertEqualsSame(String expected, String in, String out) {
- if (expected.equals(in)) {
- assertSame(in, out);
- } else {
- assertEquals(expected, out);
- }
- }
-
// Test collapse() a little differently than the rest, as we really want to
// cover lots of different configurations of input text
public void testCollapse() {
- // collapsing groups of '-' into '_' or '-'
+ // collapsing groups of - into _
doTestCollapse("-", "_");
doTestCollapse("x-", "x_");
doTestCollapse("-x", "_x");
@@ -454,29 +411,30 @@ public class CharMatcherTest extends TestCase {
private void doTestCollapse(String in, String out) {
// Try a few different matchers which all match '-' and not 'x'
- // Try replacement chars that both do and do not change the value.
- for (char replacement : new char[] { '_', '-' }) {
- String expected = out.replace('_', replacement);
- assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));
- assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));
- assertEqualsSame(expected, in, is('-').or(is('#')).collapseFrom(in, replacement));
- assertEqualsSame(expected, in, isNot('x').collapseFrom(in, replacement));
- assertEqualsSame(expected, in, is('x').negate().collapseFrom(in, replacement));
- assertEqualsSame(expected, in, anyOf("-").collapseFrom(in, replacement));
- assertEqualsSame(expected, in, anyOf("-#").collapseFrom(in, replacement));
- assertEqualsSame(expected, in, anyOf("-#123").collapseFrom(in, replacement));
- }
+ assertEquals(out, is('-').collapseFrom(in, '_'));
+ assertEquals(out, is('-').or(is('#')).collapseFrom(in, '_'));
+ assertEquals(out, isNot('x').collapseFrom(in, '_'));
+ assertEquals(out, is('x').negate().collapseFrom(in, '_'));
+ assertEquals(out, anyOf("-").collapseFrom(in, '_'));
+ assertEquals(out, anyOf("-#").collapseFrom(in, '_'));
+ assertEquals(out, anyOf("-#123").collapseFrom(in, '_'));
}
private void doTestCollapseWithNoChange(String inout) {
- assertSame(inout, is('-').collapseFrom(inout, '_'));
- assertSame(inout, is('-').or(is('#')).collapseFrom(inout, '_'));
- assertSame(inout, isNot('x').collapseFrom(inout, '_'));
- assertSame(inout, is('x').negate().collapseFrom(inout, '_'));
- assertSame(inout, anyOf("-").collapseFrom(inout, '_'));
- assertSame(inout, anyOf("-#").collapseFrom(inout, '_'));
- assertSame(inout, anyOf("-#123").collapseFrom(inout, '_'));
- assertSame(inout, CharMatcher.NONE.collapseFrom(inout, '_'));
+ /*
+ * Note: assertSame(), not promised by the spec, happens to work with the
+ * current implementation because String.toString() promises to return
+ * |this|. However, GWT bug 4491 keeps it from working there, so we stick
+ * with assertEquals().
+ */
+ assertEquals(inout, is('-').collapseFrom(inout, '_'));
+ assertEquals(inout, is('-').or(is('#')).collapseFrom(inout, '_'));
+ assertEquals(inout, isNot('x').collapseFrom(inout, '_'));
+ assertEquals(inout, is('x').negate().collapseFrom(inout, '_'));
+ assertEquals(inout, anyOf("-").collapseFrom(inout, '_'));
+ assertEquals(inout, anyOf("-#").collapseFrom(inout, '_'));
+ assertEquals(inout, anyOf("-#123").collapseFrom(inout, '_'));
+ assertEquals(inout, CharMatcher.NONE.collapseFrom(inout, '_'));
}
public void testCollapse_any() {
@@ -590,9 +548,7 @@ public class CharMatcherTest extends TestCase {
}
public void testTrimAndCollapse() {
- // collapsing groups of '-' into '_' or '-'
- doTestTrimAndCollapse("", "");
- doTestTrimAndCollapse("x", "x");
+ // collapsing groups of - into _
doTestTrimAndCollapse("-", "");
doTestTrimAndCollapse("x-", "x");
doTestTrimAndCollapse("-x", "x");
@@ -615,16 +571,13 @@ public class CharMatcherTest extends TestCase {
private void doTestTrimAndCollapse(String in, String out) {
// Try a few different matchers which all match '-' and not 'x'
- for (char replacement : new char[] { '_', '-' }) {
- String expected = out.replace('_', replacement);
- assertEqualsSame(expected, in, is('-').trimAndCollapseFrom(in, replacement));
- assertEqualsSame(expected, in, is('-').or(is('#')).trimAndCollapseFrom(in, replacement));
- assertEqualsSame(expected, in, isNot('x').trimAndCollapseFrom(in, replacement));
- assertEqualsSame(expected, in, is('x').negate().trimAndCollapseFrom(in, replacement));
- assertEqualsSame(expected, in, anyOf("-").trimAndCollapseFrom(in, replacement));
- assertEqualsSame(expected, in, anyOf("-#").trimAndCollapseFrom(in, replacement));
- assertEqualsSame(expected, in, anyOf("-#123").trimAndCollapseFrom(in, replacement));
- }
+ assertEquals(out, is('-').trimAndCollapseFrom(in, '_'));
+ assertEquals(out, is('-').or(is('#')).trimAndCollapseFrom(in, '_'));
+ assertEquals(out, isNot('x').trimAndCollapseFrom(in, '_'));
+ assertEquals(out, is('x').negate().trimAndCollapseFrom(in, '_'));
+ assertEquals(out, anyOf("-").trimAndCollapseFrom(in, '_'));
+ assertEquals(out, anyOf("-#").trimAndCollapseFrom(in, '_'));
+ assertEquals(out, anyOf("-#123").trimAndCollapseFrom(in, '_'));
}
public void testReplaceFrom() {
@@ -641,107 +594,14 @@ public class CharMatcherTest extends TestCase {
// build a precomputed version.
CharMatcher m1 = is('x');
assertSame(m1, m1.precomputed());
- assertSame(m1.toString(), m1.precomputed().toString());
CharMatcher m2 = anyOf("Az");
assertSame(m2, m2.precomputed());
- assertSame(m2.toString(), m2.precomputed().toString());
CharMatcher m3 = inRange('A', 'Z');
assertSame(m3, m3.precomputed());
- assertSame(m3.toString(), m3.precomputed().toString());
assertSame(CharMatcher.NONE, CharMatcher.NONE.precomputed());
assertSame(CharMatcher.ANY, CharMatcher.ANY.precomputed());
}
-
- @GwtIncompatible("java.util.BitSet")
- private static BitSet bitSet(String chars) {
- return bitSet(chars.toCharArray());
- }
-
- @GwtIncompatible("java.util.BitSet")
- private static BitSet bitSet(char[] chars) {
- BitSet tmp = new BitSet();
- for (int i = 0; i < chars.length; i++) {
- tmp.set(chars[i]);
- }
- return tmp;
- }
-
- @GwtIncompatible("java.util.Random, java.util.BitSet")
- public void testSmallCharMatcher() {
- CharMatcher len1 = SmallCharMatcher.from(bitSet("#"), "#");
- CharMatcher len2 = SmallCharMatcher.from(bitSet("ab"), "ab");
- CharMatcher len3 = SmallCharMatcher.from(bitSet("abc"), "abc");
- CharMatcher len4 = SmallCharMatcher.from(bitSet("abcd"), "abcd");
- assertTrue(len1.matches('#'));
- assertFalse(len1.matches('!'));
- assertTrue(len2.matches('a'));
- assertTrue(len2.matches('b'));
- for (char c = 'c'; c < 'z'; c++) {
- assertFalse(len2.matches(c));
- }
- assertTrue(len3.matches('a'));
- assertTrue(len3.matches('b'));
- assertTrue(len3.matches('c'));
- for (char c = 'd'; c < 'z'; c++) {
- assertFalse(len3.matches(c));
- }
- assertTrue(len4.matches('a'));
- assertTrue(len4.matches('b'));
- assertTrue(len4.matches('c'));
- assertTrue(len4.matches('d'));
- for (char c = 'e'; c < 'z'; c++) {
- assertFalse(len4.matches(c));
- }
-
- Random rand = new Random(1234);
- for (int testCase = 0; testCase < 100; testCase++) {
- char[] chars = randomChars(rand, rand.nextInt(63) + 1);
- CharMatcher m = SmallCharMatcher.from(bitSet(chars), new String(chars));
- checkExactMatches(m, chars);
- }
- }
-
- static void checkExactMatches(CharMatcher m, char[] chars) {
- Set<Character> positive = Sets.newHashSetWithExpectedSize(chars.length);
- for (int i = 0; i < chars.length; i++) {
- positive.add(chars[i]);
- }
- for (int c = 0; c <= Character.MAX_VALUE; c++) {
- assertFalse(positive.contains(new Character((char) c)) ^ m.matches((char) c));
- }
- }
-
- static char[] randomChars(Random rand, int size) {
- Set<Character> chars = new HashSet<Character>(size);
- for (int i = 0; i < size; i++) {
- char c;
- while (true) {
- c = (char) rand.nextInt(Character.MAX_VALUE - Character.MIN_VALUE + 1);
- if (!chars.contains(c)) {
- break;
- }
- }
- chars.add(c);
- }
- char[] retValue = new char[chars.size()];
- int i = 0;
- for (char c : chars) {
- retValue[i++] = c;
- }
- Arrays.sort(retValue);
- return retValue;
- }
-
- public void testToString() {
- assertEquals("CharMatcher.NONE", CharMatcher.anyOf("").toString());
- assertEquals("CharMatcher.is('\\u0031')", CharMatcher.anyOf("1").toString());
- assertEquals("CharMatcher.anyOf(\"\\u0031\\u0032\")", CharMatcher.anyOf("12").toString());
- assertEquals("CharMatcher.anyOf(\"\\u0031\\u0032\\u0033\")",
- CharMatcher.anyOf("321").toString());
- assertEquals("CharMatcher.inRange('\\u0031', '\\u0033')",
- CharMatcher.inRange('1', '3').toString());
- }
}
diff --git a/guava-tests/test/com/google/common/base/CharsetsTest.java b/guava-tests/test/com/google/common/base/CharsetsTest.java
index e58bba6..67f2b07 100644
--- a/guava-tests/test/com/google/common/base/CharsetsTest.java
+++ b/guava-tests/test/com/google/common/base/CharsetsTest.java
@@ -16,9 +16,6 @@
package com.google.common.base;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
import junit.framework.TestCase;
import java.nio.charset.Charset;
@@ -28,15 +25,11 @@ import java.nio.charset.Charset;
*
* @author Mike Bostock
*/
-@GwtCompatible(emulated = true)
public class CharsetsTest extends TestCase {
-
- @GwtIncompatible("Non-UTF-8 Charset")
public void testUsAscii() {
assertEquals(Charset.forName("US-ASCII"), Charsets.US_ASCII);
}
- @GwtIncompatible("Non-UTF-8 Charset")
public void testIso88591() {
assertEquals(Charset.forName("ISO-8859-1"), Charsets.ISO_8859_1);
}
@@ -45,17 +38,14 @@ public class CharsetsTest extends TestCase {
assertEquals(Charset.forName("UTF-8"), Charsets.UTF_8);
}
- @GwtIncompatible("Non-UTF-8 Charset")
public void testUtf16be() {
assertEquals(Charset.forName("UTF-16BE"), Charsets.UTF_16BE);
}
- @GwtIncompatible("Non-UTF-8 Charset")
public void testUtf16le() {
assertEquals(Charset.forName("UTF-16LE"), Charsets.UTF_16LE);
}
- @GwtIncompatible("Non-UTF-8 Charset")
public void testUtf16() {
assertEquals(Charset.forName("UTF-16"), Charsets.UTF_16);
}
diff --git a/guava-tests/test/com/google/common/base/EnumsTest.java b/guava-tests/test/com/google/common/base/EnumsTest.java
index 473df7d..142833b 100644
--- a/guava-tests/test/com/google/common/base/EnumsTest.java
+++ b/guava-tests/test/com/google/common/base/EnumsTest.java
@@ -24,10 +24,6 @@ import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Field;
-
/**
* Tests for {@link Enums}.
*
@@ -58,7 +54,7 @@ public class EnumsTest extends TestCase {
assertNull(function.apply("poodlE"));
}
- public void testValueOfFunction_nullWhenNoMatchingConstant() {
+ public void testValueOfFunction_nullWhenNotMatchingConstant() {
Function<String, TestEnum> function = Enums.valueOfFunction(TestEnum.class);
assertNull(function.apply("WOMBAT"));
}
@@ -77,52 +73,9 @@ public class EnumsTest extends TestCase {
SerializableTester.reserializeAndAssert(function);
}
- public void testGetIfPresent() {
- assertEquals(Optional.of(TestEnum.CHEETO), Enums.getIfPresent(TestEnum.class, "CHEETO"));
- assertEquals(Optional.of(TestEnum.HONDA), Enums.getIfPresent(TestEnum.class, "HONDA"));
- assertEquals(Optional.of(TestEnum.POODLE), Enums.getIfPresent(TestEnum.class, "POODLE"));
-
- assertTrue(Enums.getIfPresent(TestEnum.class, "CHEETO").isPresent());
- assertTrue(Enums.getIfPresent(TestEnum.class, "HONDA").isPresent());
- assertTrue(Enums.getIfPresent(TestEnum.class, "POODLE").isPresent());
-
- assertEquals(TestEnum.CHEETO, Enums.getIfPresent(TestEnum.class, "CHEETO").get());
- assertEquals(TestEnum.HONDA, Enums.getIfPresent(TestEnum.class, "HONDA").get());
- assertEquals(TestEnum.POODLE, Enums.getIfPresent(TestEnum.class, "POODLE").get());
- }
-
- public void testGetIfPresent_caseSensitive() {
- assertFalse(Enums.getIfPresent(TestEnum.class, "cHEETO").isPresent());
- assertFalse(Enums.getIfPresent(TestEnum.class, "Honda").isPresent());
- assertFalse(Enums.getIfPresent(TestEnum.class, "poodlE").isPresent());
- }
-
- public void testGetIfPresent_whenNoMatchingConstant() {
- assertEquals(Optional.absent(), Enums.getIfPresent(TestEnum.class, "WOMBAT"));
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Enums.class);
}
-
- @Retention(RetentionPolicy.RUNTIME)
- private @interface ExampleAnnotation {}
-
- private enum AnEnum {
- @ExampleAnnotation FOO,
- BAR
- }
-
- @GwtIncompatible("reflection")
- public void testGetField() {
- Field foo = Enums.getField(AnEnum.FOO);
- assertEquals("FOO", foo.getName());
- assertTrue(foo.isAnnotationPresent(ExampleAnnotation.class));
-
- Field bar = Enums.getField(AnEnum.BAR);
- assertEquals("BAR", bar.getName());
- assertFalse(bar.isAnnotationPresent(ExampleAnnotation.class));
- }
}
diff --git a/guava-tests/test/com/google/common/base/EquivalenceTest.java b/guava-tests/test/com/google/common/base/EquivalenceTest.java
index cced838..877aa67 100644
--- a/guava-tests/test/com/google/common/base/EquivalenceTest.java
+++ b/guava-tests/test/com/google/common/base/EquivalenceTest.java
@@ -18,11 +18,9 @@ package com.google.common.base;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.EquivalenceTester;
-import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
@@ -37,7 +35,7 @@ public class EquivalenceTest extends TestCase {
@SuppressWarnings("unchecked") // Iterable<String>...
public void testPairwiseEquivalent() {
- EquivalenceTester.of(Equivalence.equals().<String>pairwise())
+ EquivalenceTester.of(Equivalences.equals().<String>pairwise())
.addEquivalenceGroup(ImmutableList.<String>of())
.addEquivalenceGroup(ImmutableList.of("a"))
.addEquivalenceGroup(ImmutableList.of("b"))
@@ -47,8 +45,8 @@ public class EquivalenceTest extends TestCase {
public void testPairwiseEquivalent_equals() {
new EqualsTester()
- .addEqualityGroup(Equivalence.equals().pairwise(), Equivalence.equals().pairwise())
- .addEqualityGroup(Equivalence.identity().pairwise())
+ .addEqualityGroup(Equivalences.equals().pairwise(), Equivalences.equals().pairwise())
+ .addEqualityGroup(Equivalences.identity().pairwise())
.testEquals();
}
@@ -60,7 +58,7 @@ public class EquivalenceTest extends TestCase {
}
}
- private static final Equivalence<String> LENGTH_EQUIVALENCE = Equivalence.equals()
+ private static final Equivalence<String> LENGTH_EQUIVALENCE = Equivalences.equals()
.onResultOf(LengthFunction.INSTANCE);
public void testWrap() {
@@ -75,22 +73,14 @@ public class EquivalenceTest extends TestCase {
.addEqualityGroup(
LENGTH_EQUIVALENCE.wrap(null),
LENGTH_EQUIVALENCE.wrap(null))
- .addEqualityGroup(Equivalence.equals().wrap("hello"))
- .addEqualityGroup(Equivalence.equals().wrap(null))
+ .addEqualityGroup(Equivalences.equals().wrap("hello"))
+ .addEqualityGroup(Equivalences.equals().wrap(null))
.testEquals();
}
- public void testWrap_get() {
- String test = "test";
- Wrapper<String> wrapper = LENGTH_EQUIVALENCE.wrap(test);
- assertSame(test, wrapper.get());
- }
-
@GwtIncompatible("SerializableTester")
- public void testSerialization() {
+ public void testWrapSerialization() {
SerializableTester.reserializeAndAssert(LENGTH_EQUIVALENCE.wrap("hello"));
- SerializableTester.reserializeAndAssert(Equivalence.equals());
- SerializableTester.reserializeAndAssert(Equivalence.identity());
}
private static class IntValue {
@@ -106,7 +96,7 @@ public class EquivalenceTest extends TestCase {
}
public void testOnResultOf() {
- EquivalenceTester.of(Equivalence.equals().onResultOf(Functions.toStringFunction()))
+ EquivalenceTester.of(Equivalences.equals().onResultOf(Functions.toStringFunction()))
.addEquivalenceGroup(new IntValue(1), new IntValue(1))
.addEquivalenceGroup(new IntValue(2))
.test();
@@ -115,55 +105,27 @@ public class EquivalenceTest extends TestCase {
public void testOnResultOf_equals() {
new EqualsTester()
.addEqualityGroup(
- Equivalence.identity().onResultOf(Functions.toStringFunction()),
- Equivalence.identity().onResultOf(Functions.toStringFunction()))
- .addEqualityGroup(Equivalence.equals().onResultOf(Functions.toStringFunction()))
- .addEqualityGroup(Equivalence.identity().onResultOf(Functions.identity()))
+ Equivalences.identity().onResultOf(Functions.toStringFunction()),
+ Equivalences.identity().onResultOf(Functions.toStringFunction()))
+ .addEqualityGroup(Equivalences.equals().onResultOf(Functions.toStringFunction()))
+ .addEqualityGroup(Equivalences.identity().onResultOf(Functions.identity()))
.testEquals();
}
public void testEquivalentTo() {
- Predicate<Object> equalTo1 = Equivalence.equals().equivalentTo("1");
+ Predicate<Object> equalTo1 = Equivalences.equals().equivalentTo("1");
assertTrue(equalTo1.apply("1"));
assertFalse(equalTo1.apply("2"));
assertFalse(equalTo1.apply(null));
- Predicate<Object> isNull = Equivalence.equals().equivalentTo(null);
+ Predicate<Object> isNull = Equivalences.equals().equivalentTo(null);
assertFalse(isNull.apply("1"));
assertFalse(isNull.apply("2"));
assertTrue(isNull.apply(null));
new EqualsTester()
- .addEqualityGroup(equalTo1, Equivalence.equals().equivalentTo("1"))
+ .addEqualityGroup(equalTo1, Equivalences.equals().equivalentTo("1"))
.addEqualityGroup(isNull)
- .addEqualityGroup(Equivalence.identity().equivalentTo("1"))
+ .addEqualityGroup(Equivalences.identity().equivalentTo("1"))
.testEquals();
}
- public void testEqualsEquivalent() {
- EquivalenceTester.of(Equivalence.equals())
- .addEquivalenceGroup(new Integer(42), 42)
- .addEquivalenceGroup("a")
- .test();
- }
-
- public void testIdentityEquivalent() {
- EquivalenceTester.of(Equivalence.identity())
- .addEquivalenceGroup(new Integer(42))
- .addEquivalenceGroup(new Integer(42))
- .addEquivalenceGroup("a")
- .test();
- }
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(Equivalence.equals(), Equivalence.equals())
- .addEqualityGroup(Equivalence.identity(), Equivalence.identity())
- .testEquals();
- }
-
- @GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Equivalence.class);
- new NullPointerTester().testAllPublicInstanceMethods(Equivalence.equals());
- new NullPointerTester().testAllPublicInstanceMethods(Equivalence.identity());
- }
}
diff --git a/guava-tests/test/com/google/common/base/EquivalencesTest.java b/guava-tests/test/com/google/common/base/EquivalencesTest.java
new file mode 100644
index 0000000..41d9fd0
--- /dev/null
+++ b/guava-tests/test/com/google/common/base/EquivalencesTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * diOBJECTibuted under the License is diOBJECTibuted on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.EquivalenceTester;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link Equivalences}.
+ *
+ * @author Kurt Alfred Kluever
+ * @author Jige Yu
+ */
+@GwtCompatible(emulated = true)
+public class EquivalencesTest extends TestCase {
+
+ public void testEqualsEquivalent() {
+ EquivalenceTester.of(Equivalences.equals())
+ .addEquivalenceGroup(new Integer(42), 42)
+ .addEquivalenceGroup("a")
+ .test();
+ }
+
+ public void testIdentityEquivalent() {
+ EquivalenceTester.of(Equivalences.identity())
+ .addEquivalenceGroup(new Integer(42))
+ .addEquivalenceGroup(new Integer(42))
+ .addEquivalenceGroup("a")
+ .test();
+ }
+
+ public void testEquality() {
+ new EqualsTester()
+ .addEqualityGroup(Equivalences.equals(), Equivalences.equals())
+ .addEqualityGroup(Equivalences.identity(), Equivalences.identity())
+ .testEquals();
+ }
+
+ @GwtIncompatible("SerializableTester")
+ public void testSerialization() {
+ SerializableTester.reserializeAndAssert(Equivalences.equals());
+ SerializableTester.reserializeAndAssert(Equivalences.identity());
+ }
+}
diff --git a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java
deleted file mode 100644
index 7582300..0000000
--- a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2005 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.testing.GcFinalization;
-import java.io.Closeable;
-
-import junit.framework.TestCase;
-
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.security.Permission;
-import java.security.Policy;
-import java.security.ProtectionDomain;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Tests that the {@code ClassLoader} of {@link FinalizableReferenceQueue} can be unloaded. These
- * tests are separate from {@link FinalizableReferenceQueueTest} so that they can be excluded from
- * coverage runs, as the coverage system interferes with them.
- *
- * @author Eamonn McManus
- */
-public class FinalizableReferenceQueueClassLoaderUnloadingTest extends TestCase {
-
- /*
- * The following tests check that the use of FinalizableReferenceQueue does not prevent the
- * ClassLoader that loaded that class from later being garbage-collected. If anything continues
- * to reference the FinalizableReferenceQueue class then its ClassLoader cannot be
- * garbage-collected, even if there are no more instances of FinalizableReferenceQueue itself.
- * The code in FinalizableReferenceQueue goes to considerable trouble to ensure that there are
- * no such references and the tests here check that that trouble has not been in vain.
- *
- * When we reference FinalizableReferenceQueue in this test, we are referencing a class that is
- * loaded by this test and that will obviously remain loaded for as long as the test is running.
- * So in order to check ClassLoader garbage collection we need to create a new ClassLoader and
- * make it load its own version of FinalizableReferenceQueue. Then we need to interact with that
- * parallel version through reflection in order to exercise the parallel
- * FinalizableReferenceQueue, and then check that the parallel ClassLoader can be
- * garbage-collected after that.
- */
-
- public static class MyFinalizableWeakReference extends FinalizableWeakReference<Object> {
- public MyFinalizableWeakReference(Object x, FinalizableReferenceQueue queue) {
- super(x, queue);
- }
-
- public void finalizeReferent() {
- }
- }
-
- private static class PermissivePolicy extends Policy {
- @Override
- public boolean implies(ProtectionDomain pd, Permission perm) {
- return true;
- }
- }
-
- private WeakReference<ClassLoader> useFrqInSeparateLoader() throws Exception {
- final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader();
- final URL[] urls = myLoader.getURLs();
- URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());
- // sepLoader is the loader that we will use to load the parallel FinalizableReferenceQueue (FRQ)
- // and friends, and that we will eventually expect to see garbage-collected. The assumption
- // is that the ClassLoader of this test is a URLClassLoader, and that it loads FRQ itself
- // rather than delegating to a parent ClassLoader. If this assumption is violated the test will
- // fail and will need to be rewritten.
-
- Class<?> frqC = FinalizableReferenceQueue.class;
- Class<?> sepFrqC = sepLoader.loadClass(frqC.getName());
- assertNotSame(frqC, sepFrqC);
- // Check the assumptions above.
-
- // FRQ tries to load the Finalizer class (for the reference-collecting thread) in a few ways.
- // If the class is accessible to the system ClassLoader (ClassLoader.getSystemClassLoader())
- // then FRQ does not bother to load Finalizer.class through a separate ClassLoader. That happens
- // in our test environment, which foils the purpose of this test, so we disable the logic for
- // our test by setting a static field. We are changing the field in the parallel version of FRQ
- // and each test creates its own one of those, so there is no test interference here.
- Class<?> sepFrqSystemLoaderC =
- sepLoader.loadClass(FinalizableReferenceQueue.SystemLoader.class.getName());
- Field disabled = sepFrqSystemLoaderC.getDeclaredField("disabled");
- disabled.setAccessible(true);
- disabled.set(null, true);
-
- // Now make a parallel FRQ and an associated FinalizableWeakReference to an object, in order to
- // exercise some classes from the parallel ClassLoader.
- AtomicReference<Object> sepFrqA = new AtomicReference<Object>(sepFrqC.newInstance());
- @SuppressWarnings("unchecked")
- Class<? extends WeakReference<?>> sepFwrC = (Class<? extends WeakReference<?>>)
- sepLoader.loadClass(MyFinalizableWeakReference.class.getName());
- Constructor<? extends WeakReference<?>> sepFwrCons =
- sepFwrC.getConstructor(Object.class, sepFrqC);
- // The object that we will wrap in FinalizableWeakReference is a Stopwatch.
- Class<?> sepStopwatchC = sepLoader.loadClass(Stopwatch.class.getName());
- assertSame(sepLoader, sepStopwatchC.getClassLoader());
- AtomicReference<Object> sepStopwatchA =
- new AtomicReference<Object>(sepStopwatchC.newInstance());
- AtomicReference<WeakReference<?>> sepStopwatchRef =
- new AtomicReference<WeakReference<?>>(
- sepFwrCons.newInstance(sepStopwatchA.get(), sepFrqA.get()));
- assertNotNull(sepStopwatchA.get());
- // Clear all references to the Stopwatch and wait for it to be gc'd.
- sepStopwatchA.set(null);
- GcFinalization.awaitClear(sepStopwatchRef.get());
- // Return a weak reference to the parallel ClassLoader. This is the reference that should
- // eventually become clear if there are no other references to the ClassLoader.
- return new WeakReference<ClassLoader>(sepLoader);
- }
-
- private void doTestUnloadable() throws Exception {
- WeakReference<ClassLoader> loaderRef = useFrqInSeparateLoader();
- GcFinalization.awaitClear(loaderRef);
- }
-
- public void testUnloadableWithoutSecurityManager() throws Exception {
- // Test that the use of a FinalizableReferenceQueue does not subsequently prevent the
- // loader of that class from being garbage-collected.
- SecurityManager oldSecurityManager = System.getSecurityManager();
- try {
- System.setSecurityManager(null);
- doTestUnloadable();
- } finally {
- System.setSecurityManager(oldSecurityManager);
- }
- }
-
- public void testUnloadableWithSecurityManager() throws Exception {
- // Test that the use of a FinalizableReferenceQueue does not subsequently prevent the
- // loader of that class from being garbage-collected even if there is a SecurityManager.
- // The SecurityManager environment makes such leaks more likely because when you create
- // a URLClassLoader with a SecurityManager, the creating code's AccessControlContext is
- // captured, and that references the creating code's ClassLoader.
- Policy oldPolicy = Policy.getPolicy();
- SecurityManager oldSecurityManager = System.getSecurityManager();
- try {
- Policy.setPolicy(new PermissivePolicy());
- System.setSecurityManager(new SecurityManager());
- doTestUnloadable();
- } finally {
- System.setSecurityManager(oldSecurityManager);
- Policy.setPolicy(oldPolicy);
- }
- }
-
- public static class FrqUser implements Callable<WeakReference<Object>> {
- public static FinalizableReferenceQueue frq = new FinalizableReferenceQueue();
- public static final Semaphore finalized = new Semaphore(0);
-
- @Override
- public WeakReference<Object> call() {
- WeakReference<Object> wr = new FinalizableWeakReference<Object>(new Integer(23), frq) {
- @Override
- public void finalizeReferent() {
- finalized.release();
- }
- };
- return wr;
- }
- }
-
- public void testUnloadableInStaticFieldIfClosed() throws Exception {
- Policy oldPolicy = Policy.getPolicy();
- SecurityManager oldSecurityManager = System.getSecurityManager();
- try {
- Policy.setPolicy(new PermissivePolicy());
- System.setSecurityManager(new SecurityManager());
- WeakReference<ClassLoader> loaderRef = doTestUnloadableInStaticFieldIfClosed();
- GcFinalization.awaitClear(loaderRef);
- } finally {
- System.setSecurityManager(oldSecurityManager);
- Policy.setPolicy(oldPolicy);
- }
- }
-
- // If you have a FinalizableReferenceQueue that is a static field of one of the classes of your
- // app (like the FrqUser class above), then the app's ClassLoader will never be gc'd. The reason
- // is that we attempt to run a thread in a separate ClassLoader that will detect when the FRQ
- // is no longer referenced, meaning that the app's ClassLoader has been gc'd, and when that
- // happens. But the thread's supposedly separate ClassLoader actually has a reference to the app's
- // ClasLoader via its AccessControlContext. It does not seem to be possible to make a
- // URLClassLoader without capturing this reference, and it probably would not be desirable for
- // security reasons anyway. Therefore, the FRQ.close() method provides a way to stop the thread
- // explicitly. This test checks that calling that method does allow an app's ClassLoader to be
- // gc'd even if there is a still a FinalizableReferenceQueue in a static field. (Setting the field
- // to null would also work, but only if there are no references to the FRQ anywhere else.)
- private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throws Exception {
- final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader();
- final URL[] urls = myLoader.getURLs();
- URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());
-
- Class<?> frqC = FinalizableReferenceQueue.class;
- Class<?> sepFrqC = sepLoader.loadClass(frqC.getName());
- assertNotSame(frqC, sepFrqC);
-
- Class<?> sepFrqSystemLoaderC =
- sepLoader.loadClass(FinalizableReferenceQueue.SystemLoader.class.getName());
- Field disabled = sepFrqSystemLoaderC.getDeclaredField("disabled");
- disabled.setAccessible(true);
- disabled.set(null, true);
-
- Class<?> frqUserC = FrqUser.class;
- Class<?> sepFrqUserC = sepLoader.loadClass(frqUserC.getName());
- assertNotSame(frqUserC, sepFrqUserC);
- assertSame(sepLoader, sepFrqUserC.getClassLoader());
-
- @SuppressWarnings("unchecked")
- Callable<WeakReference<Object>> sepFrqUser =
- (Callable<WeakReference<Object>>) sepFrqUserC.newInstance();
- WeakReference<Object> finalizableWeakReference = sepFrqUser.call();
-
- GcFinalization.awaitClear(finalizableWeakReference);
-
- Field sepFrqUserFinalizedF = sepFrqUserC.getField("finalized");
- Semaphore finalizeCount = (Semaphore) sepFrqUserFinalizedF.get(null);
- boolean finalized = finalizeCount.tryAcquire(5, TimeUnit.SECONDS);
- assertTrue(finalized);
-
- Field sepFrqUserFrqF = sepFrqUserC.getField("frq");
- Closeable frq = (Closeable) sepFrqUserFrqF.get(null);
- frq.close();
-
- return new WeakReference<ClassLoader>(sepLoader);
- }
-}
diff --git a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java
index 883aa7f..c6f7248 100644
--- a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java
+++ b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java
@@ -17,7 +17,6 @@
package com.google.common.base;
import com.google.common.base.internal.Finalizer;
-import com.google.common.testing.GcFinalization;
import junit.framework.TestCase;
@@ -41,14 +40,19 @@ public class FinalizableReferenceQueueTest extends TestCase {
}
public void testFinalizeReferentCalled() {
- final MockReference reference = new MockReference(
+ MockReference reference = new MockReference(
frq = new FinalizableReferenceQueue());
-
- GcFinalization.awaitDone(new GcFinalization.FinalizationPredicate() {
- public boolean isDone() {
- return reference.finalizeReferentCalled;
- }
- });
+ // wait up to 5s
+ for (int i = 0; i < 500; i++) {
+ if (reference.finalizeReferentCalled) {
+ return;
+ }
+ try {
+ System.gc();
+ Thread.sleep(10);
+ } catch (InterruptedException e) { /* ignore */ }
+ }
+ fail();
}
static class MockReference extends FinalizableWeakReference<Object> {
@@ -74,7 +78,18 @@ public class FinalizableReferenceQueueTest extends TestCase {
public void testThatFinalizerStops() {
weaklyReferenceQueue();
- GcFinalization.awaitClear(queueReference);
+
+ // wait up to 5s
+ for (int i = 0; i < 500; i++) {
+ if (queueReference.get() == null) {
+ return;
+ }
+ try {
+ System.gc();
+ Thread.sleep(10);
+ } catch (InterruptedException e) { /* ignore */ }
+ }
+ fail();
}
/**
diff --git a/guava-tests/test/com/google/common/base/FunctionsTest.java b/guava-tests/test/com/google/common/base/FunctionsTest.java
index cc7b4f2..e74f622 100644
--- a/guava-tests/test/com/google/common/base/FunctionsTest.java
+++ b/guava-tests/test/com/google/common/base/FunctionsTest.java
@@ -20,7 +20,6 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
-import com.google.common.testing.ClassSanityTester;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -79,7 +78,7 @@ public class FunctionsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Functions.class);
}
@@ -386,14 +385,14 @@ public class FunctionsTest extends TestCase {
implements Supplier<Integer>, Serializable {
private static final long serialVersionUID = 0;
-
+
private int value;
@Override
public Integer get() {
return ++value;
}
-
+
@Override
public boolean equals(Object obj) {
if (obj instanceof CountingSupplier) {
@@ -401,7 +400,7 @@ public class FunctionsTest extends TestCase {
}
return false;
}
-
+
@Override
public int hashCode() {
return value;
@@ -414,7 +413,7 @@ public class FunctionsTest extends TestCase {
assertEquals(1, (int) function.apply(null));
assertEquals(2, (int) function.apply("foo"));
-
+
new EqualsTester()
.addEqualityGroup(function, Functions.forSupplier(supplier))
.addEqualityGroup(Functions.forSupplier(new CountingSupplier()))
@@ -428,18 +427,8 @@ public class FunctionsTest extends TestCase {
checkCanReserialize(Functions.forSupplier(new CountingSupplier()));
}
- @GwtIncompatible("reflection")
- public void testNulls() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(Functions.class).testNulls();
- }
-
- @GwtIncompatible("reflection")
- public void testEqualsAndSerializable() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(Functions.class).testEqualsAndSerializable();
- }
-
@GwtIncompatible("SerializableTester")
- private static <Y> void checkCanReserialize(Function<? super Integer, Y> f) {
+ private <Y> void checkCanReserialize(Function<? super Integer, Y> f) {
Function<? super Integer, Y> g = SerializableTester.reserializeAndAssert(f);
for (int i = 1; i < 5; i++) {
// convoluted way to check that the same result happens from each
@@ -459,7 +448,7 @@ public class FunctionsTest extends TestCase {
}
@GwtIncompatible("SerializableTester")
- private static <Y> void checkCanReserializeSingleton(Function<? super String, Y> f) {
+ private <Y> void checkCanReserializeSingleton(Function<? super String, Y> f) {
Function<? super String, Y> g = SerializableTester.reserializeAndAssert(f);
assertSame(f, g);
for (Integer i = 1; i < 5; i++) {
diff --git a/guava-tests/test/com/google/common/base/JoinerTest.java b/guava-tests/test/com/google/common/base/JoinerTest.java
index d7f5855..1b6bbc5 100644
--- a/guava-tests/test/com/google/common/base/JoinerTest.java
+++ b/guava-tests/test/com/google/common/base/JoinerTest.java
@@ -220,7 +220,7 @@ public class JoinerTest extends TestCase {
Joiner zeroForNull = J.useForNull("0");
checkIterableIterator(zeroForNull, "1-2-3-4");
}
-
+
private static void checkIterableIterator(Joiner joiner, String expected) {
assertEquals(expected, joiner.join(new IterableIterator()));
@@ -254,7 +254,7 @@ public class JoinerTest extends TestCase {
public void test_useForNull_skipNulls() {
Joiner j = Joiner.on("x").useForNull("y");
try {
- j = j.skipNulls();
+ j.skipNulls();
fail();
} catch (UnsupportedOperationException expected) {
}
@@ -263,7 +263,7 @@ public class JoinerTest extends TestCase {
public void test_skipNulls_useForNull() {
Joiner j = Joiner.on("x").skipNulls();
try {
- j = j.useForNull("y");
+ j.useForNull("y");
fail();
} catch (UnsupportedOperationException expected) {
}
@@ -272,7 +272,7 @@ public class JoinerTest extends TestCase {
public void test_useForNull_twice() {
Joiner j = Joiner.on("x").useForNull("y");
try {
- j = j.useForNull("y");
+ j.useForNull("y");
fail();
} catch (UnsupportedOperationException expected) {
}
@@ -338,7 +338,6 @@ public class JoinerTest extends TestCase {
assertEquals("1:2;1:3;3:4;5:6;5:10", sb2.toString());
}
- @SuppressWarnings("ReturnValueIgnored")
public void test_skipNulls_onMap() {
Joiner j = Joiner.on(",").skipNulls();
try {
@@ -397,17 +396,17 @@ public class JoinerTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
- NullPointerTester tester = new NullPointerTester()
- // This is necessary because of the generics hackery we have to temporarily support
- // parameters which implement both Iterator and Iterable.;
- .setDefault(Object.class, Iterators.emptyIterator());
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(StringBuilder.class, new StringBuilder());
+ // This is necessary because of the generics hackery we have to temporarily support parameters
+ // which implement both Iterator and Iterable.
+ tester.setDefault(Object.class, Iterators.emptyIterator());
tester.testAllPublicStaticMethods(Joiner.class);
- tester.testInstanceMethods(Joiner.on(","), NullPointerTester.Visibility.PACKAGE);
- tester.testInstanceMethods(Joiner.on(",").skipNulls(), NullPointerTester.Visibility.PACKAGE);
- tester.testInstanceMethods(
- Joiner.on(",").useForNull("x"), NullPointerTester.Visibility.PACKAGE);
- tester.testInstanceMethods(
- Joiner.on(",").withKeyValueSeparator("="), NullPointerTester.Visibility.PACKAGE);
+ tester.testAllPublicInstanceMethods(Joiner.on(","));
+ tester.testAllPublicInstanceMethods(Joiner.on(",").skipNulls());
+ tester.testAllPublicInstanceMethods(Joiner.on(",").useForNull("x"));
+ tester.testAllPublicInstanceMethods(
+ Joiner.on(",").withKeyValueSeparator("="));
}
}
diff --git a/guava-tests/test/com/google/common/base/ObjectsTest.java b/guava-tests/test/com/google/common/base/ObjectsTest.java
index f5d0899..7b1f47b 100644
--- a/guava-tests/test/com/google/common/base/ObjectsTest.java
+++ b/guava-tests/test/com/google/common/base/ObjectsTest.java
@@ -78,7 +78,7 @@ public class ObjectsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Objects.class);
}
diff --git a/guava-tests/test/com/google/common/base/OptionalTest.java b/guava-tests/test/com/google/common/base/OptionalTest.java
index 602b7c7..5a0b765 100644
--- a/guava-tests/test/com/google/common/base/OptionalTest.java
+++ b/guava-tests/test/com/google/common/base/OptionalTest.java
@@ -16,11 +16,10 @@
package com.google.common.base;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -94,15 +93,15 @@ public final class OptionalTest extends TestCase {
assertEquals("default", Optional.absent().or("default"));
}
- public void testOr_supplier_present() {
+ public void testOr_Supplier_present() {
assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback")));
}
- public void testOr_supplier_absent() {
+ public void testOr_Supplier_absent() {
assertEquals("fallback", Optional.absent().or(Suppliers.ofInstance("fallback")));
}
- public void testOr_nullSupplier_absent() {
+ public void testOr_NullSupplier_absent() {
Supplier<Object> nullSupplier = Suppliers.ofInstance(null);
Optional<Object> absentOptional = Optional.absent();
try {
@@ -112,11 +111,6 @@ public final class OptionalTest extends TestCase {
}
}
- public void testOr_nullSupplier_present() {
- Supplier<String> nullSupplier = Suppliers.ofInstance(null);
- assertEquals("a", Optional.of("a").or(nullSupplier));
- }
-
public void testOr_Optional_present() {
assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback")));
}
@@ -132,16 +126,16 @@ public final class OptionalTest extends TestCase {
public void testOrNull_absent() {
assertNull(Optional.absent().orNull());
}
-
+
public void testAsSet_present() {
Set<String> expected = Collections.singleton("a");
assertEquals(expected, Optional.of("a").asSet());
}
-
+
public void testAsSet_absent() {
assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty());
}
-
+
public void testAsSet_presentIsImmutable() {
Set<String> presentAsSet = Optional.of("a").asSet();
try {
@@ -160,42 +154,6 @@ public final class OptionalTest extends TestCase {
}
}
- public void testTransform_absent() {
- assertEquals(Optional.absent(), Optional.absent().transform(Functions.identity()));
- assertEquals(Optional.absent(), Optional.absent().transform(Functions.toStringFunction()));
- }
-
- public void testTransform_presentIdentity() {
- assertEquals(Optional.of("a"), Optional.of("a").transform(Functions.identity()));
- }
-
- public void testTransform_presentToString() {
- assertEquals(Optional.of("42"), Optional.of(42).transform(Functions.toStringFunction()));
- }
-
- public void testTransform_present_functionReturnsNull() {
- try {
- Optional.of("a").transform(
- new Function<String, String>() {
- @Override public String apply(String input) {
- return null;
- }
- });
- fail("Should throw if Function returns null.");
- } catch (NullPointerException expected) {
- }
- }
-
- public void testTransform_abssent_functionReturnsNull() {
- assertEquals(Optional.absent(),
- Optional.absent().transform(
- new Function<Object, Object>() {
- @Override public Object apply(Object input) {
- return null;
- }
- }));
- }
-
// TODO(kevinb): use EqualsTester
public void testEqualsAndHashCode_absent() {
@@ -221,71 +179,27 @@ public final class OptionalTest extends TestCase {
public void testPresentInstances_allPresent() {
List<Optional<String>> optionals =
ImmutableList.of(Optional.of("a"), Optional.of("b"), Optional.of("c"));
- ASSERT.that(Optional.presentInstances(optionals)).iteratesOverSequence("a", "b", "c");
+ ASSERT.that(Optional.presentInstances(optionals)).hasContentsInOrder("a", "b", "c");
}
-
+
public void testPresentInstances_allAbsent() {
List<Optional<Object>> optionals =
ImmutableList.of(Optional.absent(), Optional.absent());
ASSERT.that(Optional.presentInstances(optionals)).isEmpty();
}
-
+
public void testPresentInstances_somePresent() {
List<Optional<String>> optionals =
ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c"));
- ASSERT.that(Optional.presentInstances(optionals)).iteratesOverSequence("a", "c");
+ ASSERT.that(Optional.presentInstances(optionals)).hasContentsInOrder("a", "c");
}
-
+
public void testPresentInstances_callingIteratorTwice() {
List<Optional<String>> optionals =
ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c"));
Iterable<String> onlyPresent = Optional.presentInstances(optionals);
- ASSERT.that(onlyPresent).iteratesOverSequence("a", "c");
- ASSERT.that(onlyPresent).iteratesOverSequence("a", "c");
- }
-
- public void testPresentInstances_wildcards() {
- List<Optional<? extends Number>> optionals =
- ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2));
- Iterable<Number> onlyPresent = Optional.presentInstances(optionals);
- ASSERT.that(onlyPresent).iteratesOverSequence(2);
- }
-
- private static Optional<Integer> getSomeOptionalInt() {
- return Optional.of(1);
- }
-
- private static FluentIterable<? extends Number> getSomeNumbers() {
- return FluentIterable.from(ImmutableList.<Number>of());
- }
-
- /*
- * The following tests demonstrate the shortcomings of or() and test that the casting workaround
- * mentioned in the method Javadoc does in fact compile.
- */
-
- public void testSampleCodeError1() {
- Optional<Integer> optionalInt = getSomeOptionalInt();
- // Number value = optionalInt.or(0.5); // error
- }
-
- public void testSampleCodeError2() {
- FluentIterable<? extends Number> numbers = getSomeNumbers();
- Optional<? extends Number> first = numbers.first();
- // Number value = first.or(0.5); // error
- }
-
- @SuppressWarnings("unchecked") // safe covariant cast
- public void testSampleCodeFine1() {
- Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
- Number value = optionalInt.or(0.5); // fine
- }
-
- @SuppressWarnings("unchecked") // safe covariant cast
- public void testSampleCodeFine2() {
- FluentIterable<? extends Number> numbers = getSomeNumbers();
- Optional<Number> first = (Optional) numbers.first();
- Number value = first.or(0.5); // fine
+ ASSERT.that(onlyPresent).hasContentsInOrder("a", "c");
+ ASSERT.that(onlyPresent).hasContentsInOrder("a", "c");
}
@GwtIncompatible("SerializableTester")
@@ -295,7 +209,7 @@ public final class OptionalTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester npTester = new NullPointerTester();
npTester.testAllPublicConstructors(Optional.class);
npTester.testAllPublicStaticMethods(Optional.class);
diff --git a/guava-tests/test/com/google/common/base/PackageSanityTests.java b/guava-tests/test/com/google/common/base/PackageSanityTests.java
deleted file mode 100644
index 6a356ec..0000000
--- a/guava-tests/test/com/google/common/base/PackageSanityTests.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Basic sanity tests for classes in {@code common.base}.
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- // package private classes like FunctionalEquivalence are tested through the public API.
- publicApiOnly();
- }
-}
diff --git a/guava-tests/test/com/google/common/base/PreconditionsTest.java b/guava-tests/test/com/google/common/base/PreconditionsTest.java
index c3f8c98..8f19d40 100644
--- a/guava-tests/test/com/google/common/base/PreconditionsTest.java
+++ b/guava-tests/test/com/google/common/base/PreconditionsTest.java
@@ -340,7 +340,7 @@ public class PreconditionsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Preconditions.class);
}
diff --git a/guava-tests/test/com/google/common/base/PredicatesTest.java b/guava-tests/test/com/google/common/base/PredicatesTest.java
index 8aeebdc..c256c71 100644
--- a/guava-tests/test/com/google/common/base/PredicatesTest.java
+++ b/guava-tests/test/com/google/common/base/PredicatesTest.java
@@ -21,7 +21,6 @@ import static com.google.common.base.CharMatcher.WHITESPACE;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet;
-import com.google.common.testing.ClassSanityTester;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -597,15 +596,15 @@ public class PredicatesTest extends TestCase {
public void testIsInstanceOf_serialization() {
checkSerialization(Predicates.instanceOf(Integer.class));
}
-
+
@GwtIncompatible("Predicates.assignableFrom")
public void testIsAssignableFrom_apply() {
Predicate<Class<?>> isInteger = Predicates.assignableFrom(Integer.class);
assertTrue(isInteger.apply(Integer.class));
assertFalse(isInteger.apply(Float.class));
-
- try {
+
+ try {
isInteger.apply(null);
fail();
} catch(NullPointerException expected) {}
@@ -641,7 +640,7 @@ public class PredicatesTest extends TestCase {
@GwtIncompatible("Predicates.assignableFrom, SerializableTester")
public void testIsAssignableFrom_serialization() {
- Predicate<Class<?>> predicate =
+ Predicate<Class<?>> predicate =
Predicates.assignableFrom(Integer.class);
Predicate<Class<?>> reserialized =
SerializableTester.reserializeAndAssert(predicate);
@@ -764,7 +763,7 @@ public class PredicatesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Predicates.class);
}
@@ -909,22 +908,12 @@ public class PredicatesTest extends TestCase {
assertEqualHashCode(
Predicates.or(p1, p2),
Predicates.or(p1, p2));
-
+
// While not a contractual requirement, we'd like the hash codes for ands
- // & ors of the same predicates to not collide.
+ // & ors of the same predicates to not collide.
assertTrue(Predicates.and(p1, p2).hashCode() != Predicates.or(p1, p2).hashCode());
}
- @GwtIncompatible("reflection")
- public void testNulls() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(Predicates.class).testNulls();
- }
-
- @GwtIncompatible("reflection")
- public void testEqualsAndSerializable() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(Predicates.class).testEqualsAndSerializable();
- }
-
private static void assertEvalsToTrue(Predicate<? super Integer> predicate) {
assertTrue(predicate.apply(0));
assertTrue(predicate.apply(1));
diff --git a/guava-tests/test/com/google/common/base/SplitterTest.java b/guava-tests/test/com/google/common/base/SplitterTest.java
index 57e44b0..25e963f 100644
--- a/guava-tests/test/com/google/common/base/SplitterTest.java
+++ b/guava-tests/test/com/google/common/base/SplitterTest.java
@@ -16,7 +16,7 @@
package com.google.common.base;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -51,49 +51,43 @@ public class SplitterTest extends TestCase {
public void testCharacterSimpleSplit() {
String simple = "a,b,c";
Iterable<String> letters = COMMA_SPLITTER.split(simple);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
- }
-
- public void testToString() {
- assertEquals("[]", Splitter.on(',').split("").toString());
- assertEquals("[a, b, c]", Splitter.on(',').split("a,b,c").toString());
- assertEquals("[yam, bam, jam, ham]", Splitter.on(", ").split("yam, bam, jam, ham").toString());
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
public void testCharacterSimpleSplitWithNoDelimiter() {
String simple = "a,b,c";
Iterable<String> letters = Splitter.on('.').split(simple);
- ASSERT.that(letters).iteratesOverSequence("a,b,c");
+ ASSERT.that(letters).hasContentsInOrder("a,b,c");
}
public void testCharacterSplitWithDoubleDelimiter() {
String doubled = "a,,b,c";
Iterable<String> letters = COMMA_SPLITTER.split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", "b", "c");
}
public void testCharacterSplitWithDoubleDelimiterAndSpace() {
String doubled = "a,, b,c";
Iterable<String> letters = COMMA_SPLITTER.split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", " b", "c");
}
public void testCharacterSplitWithTrailingDelimiter() {
String trailing = "a,b,c,";
Iterable<String> letters = COMMA_SPLITTER.split(trailing);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
}
public void testCharacterSplitWithLeadingDelimiter() {
String leading = ",a,b,c";
Iterable<String> letters = COMMA_SPLITTER.split(leading);
- ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
}
public void testCharacterSplitWithMulitpleLetters() {
Iterable<String> testCharacteringMotto = Splitter.on('-').split(
"Testing-rocks-Debugging-sucks");
- ASSERT.that(testCharacteringMotto).iteratesOverSequence(
+ ASSERT.that(testCharacteringMotto).hasContentsInOrder(
"Testing", "rocks", "Debugging", "sucks");
}
@@ -101,7 +95,7 @@ public class SplitterTest extends TestCase {
Iterable<String> testCharacteringMotto = Splitter
.on(CharMatcher.WHITESPACE)
.split("Testing\nrocks\tDebugging sucks");
- ASSERT.that(testCharacteringMotto).iteratesOverSequence(
+ ASSERT.that(testCharacteringMotto).hasContentsInOrder(
"Testing", "rocks", "Debugging", "sucks");
}
@@ -109,26 +103,26 @@ public class SplitterTest extends TestCase {
String doubled = "a..b.c";
Iterable<String> letters = Splitter.on('.')
.omitEmptyStrings().split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
public void testCharacterSplitEmptyToken() {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on('.').trimResults()
.split(emptyToken);
- ASSERT.that(letters).iteratesOverSequence("a", "", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", "c");
}
public void testCharacterSplitEmptyTokenOmitEmptyStrings() {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on('.')
.omitEmptyStrings().trimResults().split(emptyToken);
- ASSERT.that(letters).iteratesOverSequence("a", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "c");
}
public void testCharacterSplitOnEmptyString() {
Iterable<String> nothing = Splitter.on('.').split("");
- ASSERT.that(nothing).iteratesOverSequence("");
+ ASSERT.that(nothing).hasContentsInOrder("");
}
public void testCharacterSplitOnEmptyStringOmitEmptyStrings() {
@@ -137,7 +131,7 @@ public class SplitterTest extends TestCase {
public void testCharacterSplitOnOnlyDelimiter() {
Iterable<String> blankblank = Splitter.on('.').split(".");
- ASSERT.that(blankblank).iteratesOverSequence("", "");
+ ASSERT.that(blankblank).hasContentsInOrder("", "");
}
public void testCharacterSplitOnOnlyDelimitersOmitEmptyStrings() {
@@ -151,97 +145,97 @@ public class SplitterTest extends TestCase {
Iterable<String> family = COMMA_SPLITTER
.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE))
.split(jacksons);
- ASSERT.that(family).iteratesOverSequence(
+ ASSERT.that(family).hasContentsInOrder(
"(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)");
}
public void testStringSimpleSplit() {
String simple = "a,b,c";
- Iterable<String> letters = Splitter.on(',').split(simple);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ Iterable<String> letters = Splitter.on(",").split(simple);
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
public void testStringSimpleSplitWithNoDelimiter() {
String simple = "a,b,c";
- Iterable<String> letters = Splitter.on('.').split(simple);
- ASSERT.that(letters).iteratesOverSequence("a,b,c");
+ Iterable<String> letters = Splitter.on(".").split(simple);
+ ASSERT.that(letters).hasContentsInOrder("a,b,c");
}
public void testStringSplitWithDoubleDelimiter() {
String doubled = "a,,b,c";
- Iterable<String> letters = Splitter.on(',').split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c");
+ Iterable<String> letters = Splitter.on(",").split(doubled);
+ ASSERT.that(letters).hasContentsInOrder("a", "", "b", "c");
}
public void testStringSplitWithDoubleDelimiterAndSpace() {
String doubled = "a,, b,c";
- Iterable<String> letters = Splitter.on(',').split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c");
+ Iterable<String> letters = Splitter.on(",").split(doubled);
+ ASSERT.that(letters).hasContentsInOrder("a", "", " b", "c");
}
public void testStringSplitWithTrailingDelimiter() {
String trailing = "a,b,c,";
- Iterable<String> letters = Splitter.on(',').split(trailing);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
+ Iterable<String> letters = Splitter.on(",").split(trailing);
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
}
public void testStringSplitWithLeadingDelimiter() {
String leading = ",a,b,c";
- Iterable<String> letters = Splitter.on(',').split(leading);
- ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
+ Iterable<String> letters = Splitter.on(",").split(leading);
+ ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
}
public void testStringSplitWithMultipleLetters() {
- Iterable<String> testStringingMotto = Splitter.on('-').split(
+ Iterable<String> testStringingMotto = Splitter.on("-").split(
"Testing-rocks-Debugging-sucks");
- ASSERT.that(testStringingMotto).iteratesOverSequence(
+ ASSERT.that(testStringingMotto).hasContentsInOrder(
"Testing", "rocks", "Debugging", "sucks");
}
public void testStringSplitWithDoubleDelimiterOmitEmptyStrings() {
String doubled = "a..b.c";
- Iterable<String> letters = Splitter.on('.')
+ Iterable<String> letters = Splitter.on(".")
.omitEmptyStrings().split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
public void testStringSplitEmptyToken() {
String emptyToken = "a. .c";
- Iterable<String> letters = Splitter.on('.').trimResults()
+ Iterable<String> letters = Splitter.on(".").trimResults()
.split(emptyToken);
- ASSERT.that(letters).iteratesOverSequence("a", "", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", "c");
}
public void testStringSplitEmptyTokenOmitEmptyStrings() {
String emptyToken = "a. .c";
- Iterable<String> letters = Splitter.on('.')
+ Iterable<String> letters = Splitter.on(".")
.omitEmptyStrings().trimResults().split(emptyToken);
- ASSERT.that(letters).iteratesOverSequence("a", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "c");
}
public void testStringSplitWithLongDelimiter() {
String longDelimiter = "a, b, c";
Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
public void testStringSplitWithLongLeadingDelimiter() {
String longDelimiter = ", a, b, c";
Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
- ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
}
public void testStringSplitWithLongTrailingDelimiter() {
String longDelimiter = "a, b, c, ";
Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
}
public void testStringSplitWithDelimiterSubstringInValue() {
String fourCommasAndFourSpaces = ",,,, ";
Iterable<String> threeCommasThenThreeSpaces = Splitter.on(", ").split(
fourCommasAndFourSpaces);
- ASSERT.that(threeCommasThenThreeSpaces).iteratesOverSequence(",,,", " ");
+ ASSERT.that(threeCommasThenThreeSpaces).hasContentsInOrder(",,,", " ");
}
public void testStringSplitWithEmptyString() {
@@ -253,31 +247,31 @@ public class SplitterTest extends TestCase {
}
public void testStringSplitOnEmptyString() {
- Iterable<String> notMuch = Splitter.on('.').split("");
- ASSERT.that(notMuch).iteratesOverSequence("");
+ Iterable<String> notMuch = Splitter.on(".").split("");
+ ASSERT.that(notMuch).hasContentsInOrder("");
}
public void testStringSplitOnEmptyStringOmitEmptyString() {
- ASSERT.that(Splitter.on('.').omitEmptyStrings().split("")).isEmpty();
+ ASSERT.that(Splitter.on(".").omitEmptyStrings().split("")).isEmpty();
}
public void testStringSplitOnOnlyDelimiter() {
- Iterable<String> blankblank = Splitter.on('.').split(".");
- ASSERT.that(blankblank).iteratesOverSequence("", "");
+ Iterable<String> blankblank = Splitter.on(".").split(".");
+ ASSERT.that(blankblank).hasContentsInOrder("", "");
}
public void testStringSplitOnOnlyDelimitersOmitEmptyStrings() {
- Iterable<String> empty = Splitter.on('.').omitEmptyStrings().split("...");
+ Iterable<String> empty = Splitter.on(".").omitEmptyStrings().split("...");
ASSERT.that(empty).isEmpty();
}
public void testStringSplitWithTrim() {
String jacksons = "arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, "
+ "ofar(Jemaine), aff(Tito)";
- Iterable<String> family = Splitter.on(',')
+ Iterable<String> family = Splitter.on(",")
.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE))
.split(jacksons);
- ASSERT.that(family).iteratesOverSequence(
+ ASSERT.that(family).hasContentsInOrder(
"(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)");
}
@@ -285,42 +279,42 @@ public class SplitterTest extends TestCase {
public void testPatternSimpleSplit() {
String simple = "a,b,c";
Iterable<String> letters = Splitter.onPattern(",").split(simple);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSimpleSplitWithNoDelimiter() {
String simple = "a,b,c";
Iterable<String> letters = Splitter.onPattern("foo").split(simple);
- ASSERT.that(letters).iteratesOverSequence("a,b,c");
+ ASSERT.that(letters).hasContentsInOrder("a,b,c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithDoubleDelimiter() {
String doubled = "a,,b,c";
Iterable<String> letters = Splitter.onPattern(",").split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", "b", "c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithDoubleDelimiterAndSpace() {
String doubled = "a,, b,c";
Iterable<String> letters = Splitter.onPattern(",").split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", " b", "c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithTrailingDelimiter() {
String trailing = "a,b,c,";
Iterable<String> letters = Splitter.onPattern(",").split(trailing);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithLeadingDelimiter() {
String leading = ",a,b,c";
Iterable<String> letters = Splitter.onPattern(",").split(leading);
- ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
}
// TODO(kevinb): the name of this method suggests it might not actually be testing what it
@@ -329,7 +323,7 @@ public class SplitterTest extends TestCase {
public void testPatternSplitWithMultipleLetters() {
Iterable<String> testPatterningMotto = Splitter.onPattern("-").split(
"Testing-rocks-Debugging-sucks");
- ASSERT.that(testPatterningMotto).iteratesOverSequence("Testing", "rocks", "Debugging", "sucks");
+ ASSERT.that(testPatterningMotto).hasContentsInOrder("Testing", "rocks", "Debugging", "sucks");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -342,30 +336,14 @@ public class SplitterTest extends TestCase {
String doubled = "a..b.c";
Iterable<String> letters = Splitter.on(literalDotPattern())
.omitEmptyStrings().split(doubled);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
- }
-
- @GwtIncompatible("java.util.regex.Pattern")
- public void testPatternSplitLookBehind() {
- String toSplit = ":foo::barbaz:";
- String regexPattern = "(?<=:)";
- Iterable<String> split = Splitter.onPattern(regexPattern).split(toSplit);
- ASSERT.that(split).iteratesOverSequence(":", "foo:", ":", "barbaz:");
- // splits into chunks ending in :
- }
-
- @GwtIncompatible("java.util.regex.Pattern")
- public void testPatternSplitWordBoundary() {
- String string = "foo<bar>bletch";
- Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);
- ASSERT.that(words).iteratesOverSequence("foo", "<", "bar", ">", "bletch");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
public void testPatternSplitEmptyToken() {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on(literalDotPattern()).trimResults().split(emptyToken);
- ASSERT.that(letters).iteratesOverSequence("a", "", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -373,14 +351,14 @@ public class SplitterTest extends TestCase {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on(literalDotPattern())
.omitEmptyStrings().trimResults().split(emptyToken);
- ASSERT.that(letters).iteratesOverSequence("a", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
public void testPatternSplitOnOnlyDelimiter() {
Iterable<String> blankblank = Splitter.on(literalDotPattern()).split(".");
- ASSERT.that(blankblank).iteratesOverSequence("", "");
+ ASSERT.that(blankblank).hasContentsInOrder("", "");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -395,7 +373,7 @@ public class SplitterTest extends TestCase {
String longDelimiter = "a, b, c";
Iterable<String> letters = Splitter.on(Pattern.compile(",\\s*"))
.split(longDelimiter);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -403,7 +381,7 @@ public class SplitterTest extends TestCase {
String longDelimiter = ", a, b, c";
Iterable<String> letters = Splitter.on(Pattern.compile(", "))
.split(longDelimiter);
- ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
+ ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -411,7 +389,7 @@ public class SplitterTest extends TestCase {
String longDelimiter = "a, b, c/ ";
Iterable<String> letters = Splitter.on(Pattern.compile("[,/]\\s"))
.split(longDelimiter);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -430,7 +408,7 @@ public class SplitterTest extends TestCase {
Iterable<String> family = Splitter.on(Pattern.compile(","))
.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE))
.split(jacksons);
- ASSERT.that(family).iteratesOverSequence(
+ ASSERT.that(family).hasContentsInOrder(
"(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)");
}
@@ -439,7 +417,7 @@ public class SplitterTest extends TestCase {
}
public void testSplitterIterableIsUnmodifiable_string() {
- assertIteratorIsUnmodifiable(Splitter.on(',').split("a,b").iterator());
+ assertIteratorIsUnmodifiable(Splitter.on(",").split("a,b").iterator());
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -462,7 +440,7 @@ public class SplitterTest extends TestCase {
}
public void testSplitterIterableIsLazy_string() {
- assertSplitterIterableIsLazy(Splitter.on(','));
+ assertSplitterIterableIsLazy(Splitter.on(","));
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -488,47 +466,47 @@ public class SplitterTest extends TestCase {
assertFalse(iterator.hasNext());
}
- public void testFixedLengthSimpleSplit() {
+ public void testAtEachSimpleSplit() {
String simple = "abcde";
Iterable<String> letters = Splitter.fixedLength(2).split(simple);
- ASSERT.that(letters).iteratesOverSequence("ab", "cd", "e");
+ ASSERT.that(letters).hasContentsInOrder("ab", "cd", "e");
}
- public void testFixedLengthSplitEqualChunkLength() {
+ public void testAtEachSplitEqualChunkLength() {
String simple = "abcdef";
Iterable<String> letters = Splitter.fixedLength(2).split(simple);
- ASSERT.that(letters).iteratesOverSequence("ab", "cd", "ef");
+ ASSERT.that(letters).hasContentsInOrder("ab", "cd", "ef");
}
- public void testFixedLengthSplitOnlyOneChunk() {
+ public void testAtEachSplitOnlyOneChunk() {
String simple = "abc";
Iterable<String> letters = Splitter.fixedLength(3).split(simple);
- ASSERT.that(letters).iteratesOverSequence("abc");
+ ASSERT.that(letters).hasContentsInOrder("abc");
}
- public void testFixedLengthSplitSmallerString() {
+ public void testAtEachSplitSmallerString() {
String simple = "ab";
Iterable<String> letters = Splitter.fixedLength(3).split(simple);
- ASSERT.that(letters).iteratesOverSequence("ab");
+ ASSERT.that(letters).hasContentsInOrder("ab");
}
- public void testFixedLengthSplitEmptyString() {
+ public void testAtEachSplitEmptyString() {
String simple = "";
Iterable<String> letters = Splitter.fixedLength(3).split(simple);
- ASSERT.that(letters).iteratesOverSequence("");
+ ASSERT.that(letters).hasContentsInOrder("");
}
- public void testFixedLengthSplitEmptyStringWithOmitEmptyStrings() {
+ public void testAtEachSplitEmptyStringWithOmitEmptyStrings() {
ASSERT.that(Splitter.fixedLength(3).omitEmptyStrings().split("")).isEmpty();
}
- public void testFixedLengthSplitIntoChars() {
+ public void testAtEachSplitIntoChars() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).split(simple);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "d");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "d");
}
- public void testFixedLengthSplitZeroChunkLen() {
+ public void testAtEachSplitZeroChunkLen() {
try {
Splitter.fixedLength(0);
fail();
@@ -536,7 +514,7 @@ public class SplitterTest extends TestCase {
}
}
- public void testFixedLengthSplitNegativeChunkLen() {
+ public void testAtEachSplitNegativeChunkLen() {
try {
Splitter.fixedLength(-1);
fail();
@@ -547,73 +525,73 @@ public class SplitterTest extends TestCase {
public void testLimitLarge() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).limit(100).split(simple);
- ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "d");
+ ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "d");
}
public void testLimitOne() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).limit(1).split(simple);
- ASSERT.that(letters).iteratesOverSequence("abcd");
+ ASSERT.that(letters).hasContentsInOrder("abcd");
}
public void testLimitFixedLength() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).limit(2).split(simple);
- ASSERT.that(letters).iteratesOverSequence("a", "bcd");
+ ASSERT.that(letters).hasContentsInOrder("a", "bcd");
}
public void testLimitSeparator() {
String simple = "a,b,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(2).split(simple);
- ASSERT.that(items).iteratesOverSequence("a", "b,c,d");
+ ASSERT.that(items).hasContentsInOrder("a", "b,c,d");
}
public void testLimitExtraSeparators() {
String text = "a,,,b,,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(2).split(text);
- ASSERT.that(items).iteratesOverSequence("a", ",,b,,c,d");
+ ASSERT.that(items).hasContentsInOrder("a", ",,b,,c,d");
}
public void testLimitExtraSeparatorsOmitEmpty() {
String text = "a,,,b,,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().split(text);
- ASSERT.that(items).iteratesOverSequence("a", "b,,c,d");
+ ASSERT.that(items).hasContentsInOrder("a", "b,,c,d");
}
public void testLimitExtraSeparatorsOmitEmpty3() {
String text = "a,,,b,,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().split(text);
- ASSERT.that(items).iteratesOverSequence("a", "b", "c,d");
+ ASSERT.that(items).hasContentsInOrder("a", "b", "c,d");
}
public void testLimitExtraSeparatorsTrim() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().trimResults().split(text);
- ASSERT.that(items).iteratesOverSequence("a", "b ,, c,d");
+ ASSERT.that(items).hasContentsInOrder("a", "b ,, c,d");
}
public void testLimitExtraSeparatorsTrim3() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().trimResults().split(text);
- ASSERT.that(items).iteratesOverSequence("a", "b", "c,d");
+ ASSERT.that(items).hasContentsInOrder("a", "b", "c,d");
}
public void testLimitExtraSeparatorsTrim1() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(1).omitEmptyStrings().trimResults().split(text);
- ASSERT.that(items).iteratesOverSequence("a,, , b ,, c,d");
+ ASSERT.that(items).hasContentsInOrder("a,, , b ,, c,d");
}
public void testLimitExtraSeparatorsTrim1NoOmit() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(1).trimResults().split(text);
- ASSERT.that(items).iteratesOverSequence(",,a,, , b ,, c,d");
+ ASSERT.that(items).hasContentsInOrder(",,a,, , b ,, c,d");
}
public void testLimitExtraSeparatorsTrim1Empty() {
String text = "";
Iterable<String> items = COMMA_SPLITTER.limit(1).split(text);
- ASSERT.that(items).iteratesOverSequence("");
+ ASSERT.that(items).hasContentsInOrder("");
}
public void testLimitExtraSeparatorsTrim1EmptyOmit() {
@@ -622,7 +600,6 @@ public class SplitterTest extends TestCase {
ASSERT.that(items).isEmpty();
}
- @SuppressWarnings("ReturnValueIgnored")
public void testInvalidZeroLimit() {
try {
COMMA_SPLITTER.limit(0);
@@ -632,11 +609,11 @@ public class SplitterTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Splitter.class);
- tester.testAllPublicInstanceMethods(Splitter.on(','));
- tester.testAllPublicInstanceMethods(Splitter.on(',').trimResults());
+ tester.testAllPublicInstanceMethods(Splitter.on(","));
+ tester.testAllPublicInstanceMethods(Splitter.on(",").trimResults());
}
private static <E> List<E> asList(Collection<E> collection){
@@ -685,19 +662,6 @@ public class SplitterTest extends TestCase {
ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet()));
}
- public void testMapSplitter_CharacterSeparator() {
- // try different delimiters.
- Map<String, String> m = Splitter
- .on(",")
- .withKeyValueSeparator(':')
- .split("boy:tom,girl:tina,cat:kitty,dog:tommy");
- ImmutableMap<String, String> expected =
- ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");
-
- ASSERT.that(m).isEqualTo(expected);
- ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet()));
- }
-
public void testMapSplitter_multiCharacterSeparator() {
// try different delimiters.
Map<String, String> m = Splitter
@@ -711,7 +675,6 @@ public class SplitterTest extends TestCase {
ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet()));
}
- @SuppressWarnings("ReturnValueIgnored")
public void testMapSplitter_emptySeparator() {
try {
COMMA_SPLITTER.withKeyValueSeparator("");
@@ -729,27 +692,27 @@ public class SplitterTest extends TestCase {
}
public void testMapSplitter_orderedResults() {
- Map<String, String> m = Splitter.on(',')
+ Map<String, String> m = Splitter.on(",")
.withKeyValueSeparator(":")
.split("boy:tom,girl:tina,cat:kitty,dog:tommy");
- ASSERT.that(m.keySet()).iteratesOverSequence("boy", "girl", "cat", "dog");
+ ASSERT.that(m.keySet()).hasContentsInOrder("boy", "girl", "cat", "dog");
ASSERT.that(m).isEqualTo(
ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));
// try in a different order
- m = Splitter.on(',')
+ m = Splitter.on(",")
.withKeyValueSeparator(":")
.split("girl:tina,boy:tom,dog:tommy,cat:kitty");
- ASSERT.that(m.keySet()).iteratesOverSequence("girl", "boy", "dog", "cat");
+ ASSERT.that(m.keySet()).hasContentsInOrder("girl", "boy", "dog", "cat");
ASSERT.that(m).isEqualTo(
ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));
}
public void testMapSplitter_duplicateKeys() {
try {
- Splitter.on(',').withKeyValueSeparator(":").split("a:1,b:2,a:3");
+ Splitter.on(",").withKeyValueSeparator(":").split("a:1,b:2,a:3");
fail();
} catch (IllegalArgumentException expected) {
}
diff --git a/guava-tests/test/com/google/common/base/StopwatchTest.java b/guava-tests/test/com/google/common/base/StopwatchTest.java
index da4f15b..33e8fb0 100644
--- a/guava-tests/test/com/google/common/base/StopwatchTest.java
+++ b/guava-tests/test/com/google/common/base/StopwatchTest.java
@@ -39,7 +39,7 @@ public class StopwatchTest extends TestCase {
public void testInitialState() {
assertFalse(stopwatch.isRunning());
- assertEquals(0, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
}
public void testStart() {
@@ -88,43 +88,43 @@ public class StopwatchTest extends TestCase {
stopwatch.reset();
assertFalse(stopwatch.isRunning());
ticker.advance(2);
- assertEquals(0, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
stopwatch.start();
ticker.advance(3);
- assertEquals(3, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(3, stopwatch.elapsedTime(NANOSECONDS));
}
public void testReset_whileRunning() {
ticker.advance(1);
stopwatch.start();
- assertEquals(0, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
ticker.advance(2);
- assertEquals(2, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(2, stopwatch.elapsedTime(NANOSECONDS));
stopwatch.reset();
assertFalse(stopwatch.isRunning());
ticker.advance(3);
- assertEquals(0, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
}
- public void testElapsed_whileRunning() {
+ public void testElapsedTime_whileRunning() {
ticker.advance(78);
stopwatch.start();
- assertEquals(0, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
ticker.advance(345);
- assertEquals(345, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(345, stopwatch.elapsedTime(NANOSECONDS));
}
- public void testElapsed_notRunning() {
+ public void testElapsedTime_notRunning() {
ticker.advance(1);
stopwatch.start();
ticker.advance(4);
stopwatch.stop();
ticker.advance(9);
- assertEquals(4, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(4, stopwatch.elapsedTime(NANOSECONDS));
}
- public void testElapsed_multipleSegments() {
+ public void testElapsedTime_multipleSegments() {
stopwatch.start();
ticker.advance(9);
stopwatch.stop();
@@ -132,46 +132,46 @@ public class StopwatchTest extends TestCase {
ticker.advance(16);
stopwatch.start();
- assertEquals(9, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(9, stopwatch.elapsedTime(NANOSECONDS));
ticker.advance(25);
- assertEquals(34, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(34, stopwatch.elapsedTime(NANOSECONDS));
stopwatch.stop();
ticker.advance(36);
- assertEquals(34, stopwatch.elapsed(NANOSECONDS));
+ assertEquals(34, stopwatch.elapsedTime(NANOSECONDS));
}
- public void testElapsed_micros() {
+ public void testElapsedTime_micros() {
stopwatch.start();
ticker.advance(999);
- assertEquals(0, stopwatch.elapsed(MICROSECONDS));
+ assertEquals(0, stopwatch.elapsedTime(MICROSECONDS));
ticker.advance(1);
- assertEquals(1, stopwatch.elapsed(MICROSECONDS));
+ assertEquals(1, stopwatch.elapsedTime(MICROSECONDS));
}
- public void testElapsed_millis() {
+ public void testElapsedTime_millis() {
stopwatch.start();
ticker.advance(999999);
- assertEquals(0, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(0, stopwatch.elapsedTime(MILLISECONDS));
ticker.advance(1);
- assertEquals(1, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(1, stopwatch.elapsedTime(MILLISECONDS));
}
public void testElapsedMillis() {
stopwatch.start();
ticker.advance(999999);
- assertEquals(0, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(0, stopwatch.elapsedMillis());
ticker.advance(1);
- assertEquals(1, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(1, stopwatch.elapsedMillis());
}
public void testElapsedMillis_whileRunning() {
ticker.advance(78000000);
stopwatch.start();
- assertEquals(0, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(0, stopwatch.elapsedMillis());
ticker.advance(345000000);
- assertEquals(345, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(345, stopwatch.elapsedMillis());
}
public void testElapsedMillis_notRunning() {
@@ -180,7 +180,7 @@ public class StopwatchTest extends TestCase {
ticker.advance(4000000);
stopwatch.stop();
ticker.advance(9000000);
- assertEquals(4, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(4, stopwatch.elapsedMillis());
}
public void testElapsedMillis_multipleSegments() {
@@ -191,13 +191,13 @@ public class StopwatchTest extends TestCase {
ticker.advance(16000000);
stopwatch.start();
- assertEquals(9, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(9, stopwatch.elapsedMillis());
ticker.advance(25000000);
- assertEquals(34, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(34, stopwatch.elapsedMillis());
stopwatch.stop();
ticker.advance(36000000);
- assertEquals(34, stopwatch.elapsed(MILLISECONDS));
+ assertEquals(34, stopwatch.elapsedMillis());
}
@GwtIncompatible("String.format()")
@@ -224,4 +224,11 @@ public class StopwatchTest extends TestCase {
assertEquals("5.000 s", stopwatch.toString());
}
+ @GwtIncompatible("GWT is at millisecond granularity")
+ public void testDefault() {
+ // By default System.nanoTime() is used as the time source
+ long value = new Stopwatch().start().elapsedTime(NANOSECONDS);
+ assertTrue(value > 0);
+ // There isn't much else we can test about this
+ }
}
diff --git a/guava-tests/test/com/google/common/base/StringsTest.java b/guava-tests/test/com/google/common/base/StringsTest.java
index fb6ff1c..f97c288 100644
--- a/guava-tests/test/com/google/common/base/StringsTest.java
+++ b/guava-tests/test/com/google/common/base/StringsTest.java
@@ -221,7 +221,7 @@ public class StringsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Strings.class);
}
diff --git a/guava-tests/test/com/google/common/base/SuppliersTest.java b/guava-tests/test/com/google/common/base/SuppliersTest.java
index 6e6ea9c..7b4b8b9 100644
--- a/guava-tests/test/com/google/common/base/SuppliersTest.java
+++ b/guava-tests/test/com/google/common/base/SuppliersTest.java
@@ -21,8 +21,7 @@ import static com.google.common.testing.SerializableTester.reserialize;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Lists;
-import com.google.common.testing.ClassSanityTester;
-import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -392,35 +391,9 @@ public class SuppliersTest extends TestCase {
Suppliers.synchronizedSupplier(Suppliers.ofInstance(5))).get());
}
- @GwtIncompatible("reflection")
- public void testSuppliersNullChecks() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(Suppliers.class)
- .testNulls();
- }
-
- @GwtIncompatible("reflection")
- public void testSuppliersSerializable() throws Exception {
- new ClassSanityTester().forAllPublicStaticMethods(Suppliers.class)
- .testSerializable();
- }
-
- public void testOfInstance_equals() {
- new EqualsTester()
- .addEqualityGroup(
- Suppliers.ofInstance("foo"), Suppliers.ofInstance("foo"))
- .addEqualityGroup(Suppliers.ofInstance("bar"))
- .testEquals();
- }
-
- public void testCompose_equals() {
- new EqualsTester()
- .addEqualityGroup(
- Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("foo")),
- Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("foo")))
- .addEqualityGroup(
- Suppliers.compose(Functions.constant(2), Suppliers.ofInstance("foo")))
- .addEqualityGroup(
- Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("bar")))
- .testEquals();
+ @GwtIncompatible("NullPointerTest")
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicStaticMethods(Suppliers.class);
}
}
diff --git a/guava-tests/test/com/google/common/base/ThrowablesTest.java b/guava-tests/test/com/google/common/base/ThrowablesTest.java
index 53a6f2c..1abd1ff 100644
--- a/guava-tests/test/com/google/common/base/ThrowablesTest.java
+++ b/guava-tests/test/com/google/common/base/ThrowablesTest.java
@@ -31,9 +31,9 @@ import java.util.List;
/**
* Unit test for {@link Throwables}.
*
- * @author Kevin Bourrillion
+ * @author Kevin Bourrillion
*/
-@SuppressWarnings("serial") // this warning is silly for exceptions in tests
+@SuppressWarnings("serial") // this warning is silly for exceptions in tests
public class ThrowablesTest extends TestCase {
public void testPropagateIfPossible_NoneDeclared_NoneThrown() {
Sample sample = new Sample() {
@@ -442,6 +442,7 @@ public class ThrowablesTest extends TestCase {
assertSame(cause, Throwables.getRootCause(exception));
}
+ private static class SomeThrowable extends Throwable {}
private static class SomeError extends Error {}
private static class SomeCheckedException extends Exception {}
private static class SomeOtherCheckedException extends Exception {}
@@ -523,7 +524,10 @@ public class ThrowablesTest extends TestCase {
}
}
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(Throwables.class);
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Throwable.class, new SomeCheckedException());
+ tester.setDefault(Class.class, SomeCheckedException.class);
+ tester.testAllPublicStaticMethods(Throwables.class);
}
}
diff --git a/guava-tests/test/com/google/common/base/ToStringHelperTest.java b/guava-tests/test/com/google/common/base/ToStringHelperTest.java
index 7817c4d..32ba19f 100644
--- a/guava-tests/test/com/google/common/base/ToStringHelperTest.java
+++ b/guava-tests/test/com/google/common/base/ToStringHelperTest.java
@@ -324,113 +324,6 @@ public class ToStringHelperTest extends TestCase {
assertTrue(result, result.matches(expected));
}
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_oneField() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .add("field1", null)
- .toString();
- assertEquals("TestClass{}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_manyFieldsFirstNull() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .add("field1", null)
- .add("field2", "Googley")
- .add("field3", "World")
- .toString();
- assertEquals("TestClass{field2=Googley, field3=World}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_manyFieldsOmitAfterNull() {
- String toTest = Objects.toStringHelper(new TestClass())
- .add("field1", null)
- .add("field2", "Googley")
- .add("field3", "World")
- .omitNullValues()
- .toString();
- assertEquals("TestClass{field2=Googley, field3=World}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_manyFieldsLastNull() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .add("field1", "Hello")
- .add("field2", "Googley")
- .add("field3", null)
- .toString();
- assertEquals("TestClass{field1=Hello, field2=Googley}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_oneValue() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .addValue(null)
- .toString();
- assertEquals("TestClass{}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_manyValuesFirstNull() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .addValue(null)
- .addValue("Googley")
- .addValue("World")
- .toString();
- assertEquals("TestClass{Googley, World}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_manyValuesLastNull() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .addValue("Hello")
- .addValue("Googley")
- .addValue(null)
- .toString();
- assertEquals("TestClass{Hello, Googley}", toTest);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_differentOrder() {
- String expected = "TestClass{field1=Hello, field2=Googley, field3=World}";
- String toTest1 = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .add("field1", "Hello")
- .add("field2", "Googley")
- .add("field3", "World")
- .toString();
- String toTest2 = Objects.toStringHelper(new TestClass())
- .add("field1", "Hello")
- .add("field2", "Googley")
- .omitNullValues()
- .add("field3", "World")
- .toString();
- assertEquals(expected, toTest1);
- assertEquals(expected, toTest2);
- }
-
- @GwtIncompatible("Class names are obfuscated in GWT")
- public void testToStringOmitNullValues_canBeCalledManyTimes() {
- String toTest = Objects.toStringHelper(new TestClass())
- .omitNullValues()
- .omitNullValues()
- .add("field1", "Hello")
- .omitNullValues()
- .add("field2", "Googley")
- .omitNullValues()
- .add("field3", "World")
- .toString();
- assertEquals("TestClass{field1=Hello, field2=Googley, field3=World}",
- toTest);
- }
-
/**
* Test class for testing formatting of inner classes.
*/
diff --git a/guava-tests/test/com/google/common/cache/AbstractCacheTest.java b/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
index 0cb6d1c..46e2a9e 100644
--- a/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
+++ b/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
@@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
import junit.framework.TestCase;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -40,6 +41,12 @@ public class AbstractCacheTest extends TestCase {
public Object getIfPresent(Object key) {
return valueRef.get();
}
+
+ @Override
+ public Object get(Object key) throws ExecutionException {
+ throw new UnsupportedOperationException();
+ }
+
};
assertNull(cache.getIfPresent(new Object()));
@@ -53,7 +60,12 @@ public class AbstractCacheTest extends TestCase {
final List<Object> invalidated = Lists.newArrayList();
Cache<Integer, Integer> cache = new AbstractCache<Integer, Integer>() {
@Override
- public Integer getIfPresent(Object key) {
+ public Integer getIfPresent(Integer key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Integer get(Integer key) throws ExecutionException {
throw new UnsupportedOperationException();
}
diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java
deleted file mode 100644
index b93db3f..0000000
--- a/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.testing.FakeTicker;
-
-import junit.framework.TestCase;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test suite for {@link CacheBuilder}.
- * TODO(cpovirk): merge into CacheBuilderTest?
- *
- * @author Jon Donovan
- */
-@GwtCompatible
-public class CacheBuilderGwtTest extends TestCase {
-
- private FakeTicker fakeTicker;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- fakeTicker = new FakeTicker();
- }
-
- public void testLoader() throws ExecutionException {
-
- final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .build();
-
- Callable<Integer> loader = new Callable<Integer>() {
- private int i = 0;
-
- @Override
- public Integer call() throws Exception {
- return ++i;
- }
- };
-
- cache.put(0, 10);
-
- assertEquals(Integer.valueOf(10), cache.get(0, loader));
- assertEquals(Integer.valueOf(1), cache.get(20, loader));
- assertEquals(Integer.valueOf(2), cache.get(34, loader));
-
- cache.invalidate(0);
- assertEquals(Integer.valueOf(3), cache.get(0, loader));
-
- cache.put(0, 10);
- cache.invalidateAll();
- assertEquals(Integer.valueOf(4), cache.get(0, loader));
- }
-
- public void testSizeConstraint() {
- final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .maximumSize(4)
- .build();
-
- cache.put(1, 10);
- cache.put(2, 20);
- cache.put(3, 30);
- cache.put(4, 40);
- cache.put(5, 50);
-
- assertEquals(null, cache.getIfPresent(10));
- // Order required to remove dependence on acces order / write order constraint.
- assertEquals(Integer.valueOf(20), cache.getIfPresent(2));
- assertEquals(Integer.valueOf(30), cache.getIfPresent(3));
- assertEquals(Integer.valueOf(40), cache.getIfPresent(4));
- assertEquals(Integer.valueOf(50), cache.getIfPresent(5));
-
- cache.put(1, 10);
- assertEquals(Integer.valueOf(10), cache.getIfPresent(1));
- assertEquals(Integer.valueOf(30), cache.getIfPresent(3));
- assertEquals(Integer.valueOf(40), cache.getIfPresent(4));
- assertEquals(Integer.valueOf(50), cache.getIfPresent(5));
- assertEquals(null, cache.getIfPresent(2));
- }
-
- public void testLoadingCache() throws ExecutionException {
- CacheLoader<Integer, Integer> loader = new CacheLoader<Integer, Integer>() {
- int i = 0;
- @Override
- public Integer load(Integer key) throws Exception {
- return i++;
- }
-
- };
-
- LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .build(loader);
-
- cache.put(10, 20);
-
- Map<Integer, Integer> map = cache.getAll(ImmutableList.of(10, 20, 30, 54, 443, 1));
-
- assertEquals(Integer.valueOf(20), map.get(10));
- assertEquals(Integer.valueOf(0), map.get(20));
- assertEquals(Integer.valueOf(1), map.get(30));
- assertEquals(Integer.valueOf(2), map.get(54));
- assertEquals(Integer.valueOf(3), map.get(443));
- assertEquals(Integer.valueOf(4), map.get(1));
- assertEquals(Integer.valueOf(5), cache.get(6));
- assertEquals(Integer.valueOf(6), cache.apply(7));
- }
-
- public void testExpireAfterAccess() {
- final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterAccess(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(0, 10);
- cache.put(2, 30);
-
- fakeTicker.advance(999, TimeUnit.MILLISECONDS);
- assertEquals(Integer.valueOf(30), cache.getIfPresent(2));
- fakeTicker.advance(1, TimeUnit.MILLISECONDS);
- assertEquals(Integer.valueOf(30), cache.getIfPresent(2));
- fakeTicker.advance(1000, TimeUnit.MILLISECONDS);
- assertEquals(null, cache.getIfPresent(0));
- }
-
- public void testExpireAfterWrite() {
- final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 100);
- cache.put(20, 200);
- cache.put(4, 2);
-
- fakeTicker.advance(999, TimeUnit.MILLISECONDS);
- assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
- assertEquals(Integer.valueOf(2), cache.getIfPresent(4));
-
- fakeTicker.advance(2, TimeUnit.MILLISECONDS);
- assertEquals(null, cache.getIfPresent(10));
- assertEquals(null, cache.getIfPresent(20));
- assertEquals(null, cache.getIfPresent(4));
-
- cache.put(10, 20);
- assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
-
- fakeTicker.advance(1000, TimeUnit.MILLISECONDS);
- assertEquals(null, cache.getIfPresent(10));
- }
-
- public void testExpireAfterWriteAndAccess() {
- final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .expireAfterAccess(500, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 100);
- cache.put(20, 200);
- cache.put(4, 2);
-
- fakeTicker.advance(499, TimeUnit.MILLISECONDS);
- assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
-
- fakeTicker.advance(2, TimeUnit.MILLISECONDS);
- assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
- assertEquals(null, cache.getIfPresent(4));
-
- fakeTicker.advance(499, TimeUnit.MILLISECONDS);
- assertEquals(null, cache.getIfPresent(10));
- assertEquals(null, cache.getIfPresent(20));
-
- cache.put(10, 20);
- assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
-
- fakeTicker.advance(500, TimeUnit.MILLISECONDS);
- assertEquals(null, cache.getIfPresent(10));
- }
-
- public void testMapMethods() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .build();
-
- ConcurrentMap<Integer, Integer> asMap = cache.asMap();
-
- cache.put(10, 100);
- cache.put(2, 52);
-
- asMap.replace(2, 79);
- asMap.replace(3, 60);
-
- assertEquals(null, cache.getIfPresent(3));
- assertEquals(null, asMap.get(3));
-
- assertEquals(Integer.valueOf(79), cache.getIfPresent(2));
- assertEquals(Integer.valueOf(79), asMap.get(2));
-
- asMap.replace(10, 100, 50);
- asMap.replace(2, 52, 99);
-
- assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(50), asMap.get(10));
- assertEquals(Integer.valueOf(79), cache.getIfPresent(2));
- assertEquals(Integer.valueOf(79), asMap.get(2));
-
- asMap.remove(10, 100);
- asMap.remove(2, 79);
-
- assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(50), asMap.get(10));
- assertEquals(null, cache.getIfPresent(2));
- assertEquals(null, asMap.get(2));
-
- asMap.putIfAbsent(2, 20);
- asMap.putIfAbsent(10, 20);
-
- assertEquals(Integer.valueOf(20), cache.getIfPresent(2));
- assertEquals(Integer.valueOf(20), asMap.get(2));
- assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(50), asMap.get(10));
- }
-
- public void testRemovalListener() {
- final int[] stats = new int[4];
-
- RemovalListener<Integer, Integer> countingListener = new RemovalListener<Integer, Integer>() {
- @Override
- public void onRemoval(RemovalNotification<Integer, Integer> notification) {
- switch (notification.getCause()) {
- case EXPIRED:
- stats[0]++;
- break;
- case EXPLICIT:
- stats[1]++;
- break;
- case REPLACED:
- stats[2]++;
- break;
- case SIZE:
- stats[3]++;
- break;
- default:
- throw new IllegalStateException("No collected exceptions in GWT CacheBuilder.");
- }
- }
- };
-
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .removalListener(countingListener)
- .ticker(fakeTicker)
- .maximumSize(2)
- .build();
-
- // Add more than two elements to increment size removals.
- cache.put(3, 20);
- cache.put(6, 2);
- cache.put(98, 45);
- cache.put(56, 76);
- cache.put(23, 84);
-
- // Replace the two present elements.
- cache.put(23, 20);
- cache.put(56, 49);
- cache.put(23, 2);
- cache.put(56, 4);
-
- // Expire the two present elements.
- fakeTicker.advance(1001, TimeUnit.MILLISECONDS);
-
- cache.getIfPresent(23);
- cache.getIfPresent(56);
-
- // Add two elements and invalidate them.
- cache.put(1, 4);
- cache.put(2, 8);
-
- cache.invalidateAll();
-
- assertEquals(2, stats[0]);
- assertEquals(2, stats[1]);
- assertEquals(4, stats[2]);
- assertEquals(3, stats[3]);
- }
-
- public void testPutAll() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .build();
-
- cache.putAll(ImmutableMap.of(10, 20, 30, 50, 60, 90));
-
- assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(50), cache.getIfPresent(30));
- assertEquals(Integer.valueOf(90), cache.getIfPresent(60));
-
- cache.asMap().putAll(ImmutableMap.of(10, 50, 30, 20, 60, 70, 5, 5));
-
- assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
- assertEquals(Integer.valueOf(20), cache.getIfPresent(30));
- assertEquals(Integer.valueOf(70), cache.getIfPresent(60));
- assertEquals(Integer.valueOf(5), cache.getIfPresent(5));
- }
-
- public void testInvalidate() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .build();
-
- cache.put(654, 2675);
- cache.put(2456, 56);
- cache.put(2, 15);
-
- cache.invalidate(654);
-
- assertFalse(cache.asMap().containsKey(654));
- assertTrue(cache.asMap().containsKey(2456));
- assertTrue(cache.asMap().containsKey(2));
- }
-
- public void testInvalidateAll() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .build();
-
- cache.put(654, 2675);
- cache.put(2456, 56);
- cache.put(2, 15);
-
- cache.invalidateAll();
- assertFalse(cache.asMap().containsKey(654));
- assertFalse(cache.asMap().containsKey(2456));
- assertFalse(cache.asMap().containsKey(2));
-
- cache.put(654, 2675);
- cache.put(2456, 56);
- cache.put(2, 15);
- cache.put(1, 3);
-
- cache.invalidateAll(ImmutableSet.of(1, 2));
-
- assertFalse(cache.asMap().containsKey(1));
- assertFalse(cache.asMap().containsKey(2));
- assertTrue(cache.asMap().containsKey(654));
- assertTrue(cache.asMap().containsKey(2456));
- }
-
- public void testAsMap_containsValue() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(20000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(654, 2675);
- fakeTicker.advance(10000, TimeUnit.MILLISECONDS);
- cache.put(2456, 56);
- cache.put(2, 15);
-
- fakeTicker.advance(10001, TimeUnit.MILLISECONDS);
-
- assertTrue(cache.asMap().containsValue(15));
- assertTrue(cache.asMap().containsValue(56));
- assertFalse(cache.asMap().containsValue(2675));
- }
-
- public void testAsMap_containsKey() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(20000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(654, 2675);
- fakeTicker.advance(10000, TimeUnit.MILLISECONDS);
- cache.put(2456, 56);
- cache.put(2, 15);
-
- fakeTicker.advance(10001, TimeUnit.MILLISECONDS);
-
- assertTrue(cache.asMap().containsKey(2));
- assertTrue(cache.asMap().containsKey(2456));
- assertFalse(cache.asMap().containsKey(654));
- }
-
- public void testAsMapValues_contains() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 20);
- fakeTicker.advance(500, TimeUnit.MILLISECONDS);
- cache.put(20, 22);
- cache.put(5, 10);
-
- fakeTicker.advance(501, TimeUnit.MILLISECONDS);
-
- assertTrue(cache.asMap().values().contains(22));
- assertTrue(cache.asMap().values().contains(10));
- assertFalse(cache.asMap().values().contains(20));
- }
-
- public void testAsMapKeySet() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 20);
- fakeTicker.advance(500, TimeUnit.MILLISECONDS);
- cache.put(20, 22);
- cache.put(5, 10);
-
- fakeTicker.advance(501, TimeUnit.MILLISECONDS);
-
- Set<Integer> foundKeys = Sets.newHashSet();
- for (Integer current : cache.asMap().keySet()) {
- foundKeys.add(current);
- }
-
- assertEquals(ImmutableSet.of(20, 5), foundKeys);
- }
-
-
- public void testAsMapKeySet_contains() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 20);
- fakeTicker.advance(500, TimeUnit.MILLISECONDS);
- cache.put(20, 22);
- cache.put(5, 10);
-
- fakeTicker.advance(501, TimeUnit.MILLISECONDS);
-
- assertTrue(cache.asMap().keySet().contains(20));
- assertTrue(cache.asMap().keySet().contains(5));
- assertFalse(cache.asMap().keySet().contains(10));
- }
-
- public void testAsMapEntrySet() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 20);
- fakeTicker.advance(500, TimeUnit.MILLISECONDS);
- cache.put(20, 22);
- cache.put(5, 10);
-
- fakeTicker.advance(501, TimeUnit.MILLISECONDS);
-
- int sum = 0;
- for (Entry<Integer, Integer> current : cache.asMap().entrySet()) {
- sum += current.getKey() + current.getValue();
- }
- assertEquals(57, sum);
- }
-
- public void testAsMapValues_iteratorRemove() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
- .ticker(fakeTicker)
- .build();
-
- cache.put(10, 20);
- Iterator<Integer> iterator = cache.asMap().values().iterator();
- iterator.next();
- iterator.remove();
-
- assertEquals(0, cache.size());
- }
-}
diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java
deleted file mode 100644
index 4149a9f..0000000
--- a/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import static com.google.common.cache.CacheBuilderSpec.parse;
-import static com.google.common.cache.TestingWeighers.constantWeigher;
-
-import com.google.common.base.Suppliers;
-import com.google.common.cache.LocalCache.Strength;
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.TestCase;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests CacheBuilderSpec.
- * TODO(user): tests of a few invalid input conditions, boundary conditions.
- *
- * @author Adam Winer
- */
-public class CacheBuilderSpecTest extends TestCase {
- public void testParse_empty() {
- CacheBuilderSpec spec = parse("");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(CacheBuilder.newBuilder(), CacheBuilder.from(spec));
- }
-
- public void testParse_initialCapacity() {
- CacheBuilderSpec spec = parse("initialCapacity=10");
- assertEquals(10, spec.initialCapacity.intValue());
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().initialCapacity(10), CacheBuilder.from(spec));
- }
-
- public void testParse_initialCapacityRepeated() {
- try {
- parse("initialCapacity=10, initialCapacity=20");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_maximumSize() {
- CacheBuilderSpec spec = parse("maximumSize=9000");
- assertNull(spec.initialCapacity);
- assertEquals(9000, spec.maximumSize.longValue());
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().maximumSize(9000), CacheBuilder.from(spec));
- }
-
- public void testParse_maximumSizeRepeated() {
- try {
- parse("maximumSize=10, maximumSize=20");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_maximumWeight() {
- CacheBuilderSpec spec = parse("maximumWeight=9000");
- assertNull(spec.initialCapacity);
- assertEquals(9000, spec.maximumWeight.longValue());
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().maximumWeight(9000), CacheBuilder.from(spec));
- }
-
- public void testParse_maximumWeightRepeated() {
- try {
- parse("maximumWeight=10, maximumWeight=20");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_maximumSizeAndMaximumWeight() {
- try {
- parse("maximumSize=10, maximumWeight=20");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_concurrencyLevel() {
- CacheBuilderSpec spec = parse("concurrencyLevel=32");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertEquals(32, spec.concurrencyLevel.intValue());
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().concurrencyLevel(32), CacheBuilder.from(spec));
- }
-
- public void testParse_concurrencyLevelRepeated() {
- try {
- parse("concurrencyLevel=10, concurrencyLevel=20");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_weakKeys() {
- CacheBuilderSpec spec = parse("weakKeys");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertEquals(Strength.WEAK, spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().weakKeys(), CacheBuilder.from(spec));
- }
-
- public void testParse_weakKeysCannotHaveValue() {
- try {
- parse("weakKeys=true");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_repeatedKeyStrength() {
- try {
- parse("weakKeys, weakKeys");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_softValues() {
- CacheBuilderSpec spec = parse("softValues");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertEquals(Strength.SOFT, spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().softValues(), CacheBuilder.from(spec));
- }
-
- public void testParse_softValuesCannotHaveValue() {
- try {
- parse("softValues=true");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_weakValues() {
- CacheBuilderSpec spec = parse("weakValues");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertEquals(Strength.WEAK, spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().weakValues(), CacheBuilder.from(spec));
- }
-
- public void testParse_weakValuesCannotHaveValue() {
- try {
- parse("weakValues=true");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_repeatedValueStrength() {
- try {
- parse("softValues, softValues");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- try {
- parse("softValues, weakValues");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- try {
- parse("weakValues, softValues");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- try {
- parse("weakValues, weakValues");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_writeExpirationDays() {
- CacheBuilderSpec spec = parse("expireAfterWrite=10d");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertEquals(TimeUnit.DAYS, spec.writeExpirationTimeUnit);
- assertEquals(10L, spec.writeExpirationDuration);
- assertNull(spec.accessExpirationTimeUnit);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.DAYS), CacheBuilder.from(spec));
- }
-
- public void testParse_writeExpirationHours() {
- CacheBuilderSpec spec = parse("expireAfterWrite=150h");
- assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
- assertEquals(150L, spec.writeExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterWrite(150L, TimeUnit.HOURS), CacheBuilder.from(spec));
- }
-
- public void testParse_writeExpirationMinutes() {
- CacheBuilderSpec spec = parse("expireAfterWrite=10m");
- assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
- assertEquals(10L, spec.writeExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.MINUTES), CacheBuilder.from(spec));
- }
-
- public void testParse_writeExpirationSeconds() {
- CacheBuilderSpec spec = parse("expireAfterWrite=10s");
- assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
- assertEquals(10L, spec.writeExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
- }
-
- public void testParse_writeExpirationRepeated() {
- try {
- parse(
- "expireAfterWrite=10s,expireAfterWrite=10m");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_accessExpirationDays() {
- CacheBuilderSpec spec = parse("expireAfterAccess=10d");
- assertNull(spec.initialCapacity);
- assertNull(spec.maximumSize);
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertNull(spec.keyStrength);
- assertNull(spec.valueStrength);
- assertNull(spec.writeExpirationTimeUnit);
- assertEquals(TimeUnit.DAYS, spec.accessExpirationTimeUnit);
- assertEquals(10L, spec.accessExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.DAYS), CacheBuilder.from(spec));
- }
-
- public void testParse_accessExpirationHours() {
- CacheBuilderSpec spec = parse("expireAfterAccess=150h");
- assertEquals(TimeUnit.HOURS, spec.accessExpirationTimeUnit);
- assertEquals(150L, spec.accessExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterAccess(150L, TimeUnit.HOURS), CacheBuilder.from(spec));
- }
-
- public void testParse_accessExpirationMinutes() {
- CacheBuilderSpec spec = parse("expireAfterAccess=10m");
- assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
- assertEquals(10L, spec.accessExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.MINUTES),
- CacheBuilder.from(spec));
- }
-
- public void testParse_accessExpirationSeconds() {
- CacheBuilderSpec spec = parse("expireAfterAccess=10s");
- assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
- assertEquals(10L, spec.accessExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.SECONDS),
- CacheBuilder.from(spec));
- }
-
- public void testParse_accessExpirationRepeated() {
- try {
- parse(
- "expireAfterAccess=10s,expireAfterAccess=10m");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_accessExpirationAndWriteExpiration() {
- CacheBuilderSpec spec = parse("expireAfterAccess=10s,expireAfterWrite=9m");
- assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
- assertEquals(9L, spec.writeExpirationDuration);
- assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
- assertEquals(10L, spec.accessExpirationDuration);
- assertCacheBuilderEquivalence(
- CacheBuilder.newBuilder()
- .expireAfterAccess(10L, TimeUnit.SECONDS)
- .expireAfterWrite(9L, TimeUnit.MINUTES),
- CacheBuilder.from(spec));
- }
-
- public void testParse_multipleKeys() {
- CacheBuilderSpec spec = parse("initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
- + "weakKeys,weakValues,expireAfterAccess=10m,expireAfterWrite=1h");
- assertEquals(10, spec.initialCapacity.intValue());
- assertEquals(20, spec.maximumSize.intValue());
- assertNull(spec.maximumWeight);
- assertEquals(30, spec.concurrencyLevel.intValue());
- assertEquals(Strength.WEAK, spec.keyStrength);
- assertEquals(Strength.WEAK, spec.valueStrength);
- assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
- assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
- assertEquals(1L, spec.writeExpirationDuration);
- assertEquals(10L, spec.accessExpirationDuration);
- CacheBuilder expected = CacheBuilder.newBuilder()
- .initialCapacity(10)
- .maximumSize(20)
- .concurrencyLevel(30)
- .weakKeys()
- .weakValues()
- .expireAfterAccess(10L, TimeUnit.MINUTES)
- .expireAfterWrite(1L, TimeUnit.HOURS);
- assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
- }
-
- public void testParse_whitespaceAllowed() {
- CacheBuilderSpec spec = parse(" initialCapacity=10,\nmaximumSize=20,\t\r"
- + "weakKeys \t ,softValues \n , \r expireAfterWrite \t = 15s\n\n");
- assertEquals(10, spec.initialCapacity.intValue());
- assertEquals(20, spec.maximumSize.intValue());
- assertNull(spec.maximumWeight);
- assertNull(spec.concurrencyLevel);
- assertEquals(Strength.WEAK, spec.keyStrength);
- assertEquals(Strength.SOFT, spec.valueStrength);
- assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
- assertEquals(15L, spec.writeExpirationDuration);
- assertNull(spec.accessExpirationTimeUnit);
- CacheBuilder expected = CacheBuilder.newBuilder()
- .initialCapacity(10)
- .maximumSize(20)
- .weakKeys()
- .softValues()
- .expireAfterWrite(15L, TimeUnit.SECONDS);
- assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
- }
-
- public void testParse_unknownKey() {
- try {
- parse("foo=17");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testParse_extraCommaIsInvalid() {
- try {
- parse("weakKeys,");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- try {
- parse(",weakKeys");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
-
- try {
- parse("weakKeys,,softValues");
- fail("Expected exception");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- }
-
- public void testEqualsAndHashCode() {
- new EqualsTester()
- .addEqualityGroup(parse(""), parse(""))
- .addEqualityGroup(parse("concurrencyLevel=7"), parse("concurrencyLevel=7"))
- .addEqualityGroup(parse("concurrencyLevel=15"), parse("concurrencyLevel=15"))
- .addEqualityGroup(parse("initialCapacity=7"), parse("initialCapacity=7"))
- .addEqualityGroup(parse("initialCapacity=15"), parse("initialCapacity=15"))
- .addEqualityGroup(parse("maximumSize=7"), parse("maximumSize=7"))
- .addEqualityGroup(parse("maximumSize=15"), parse("maximumSize=15"))
- .addEqualityGroup(parse("maximumWeight=7"), parse("maximumWeight=7"))
- .addEqualityGroup(parse("maximumWeight=15"), parse("maximumWeight=15"))
- .addEqualityGroup(parse("expireAfterAccess=60s"), parse("expireAfterAccess=1m"))
- .addEqualityGroup(parse("expireAfterAccess=60m"), parse("expireAfterAccess=1h"))
- .addEqualityGroup(parse("expireAfterWrite=60s"), parse("expireAfterWrite=1m"))
- .addEqualityGroup(parse("expireAfterWrite=60m"), parse("expireAfterWrite=1h"))
- .addEqualityGroup(parse("weakKeys"), parse("weakKeys"))
- .addEqualityGroup(parse("softValues"), parse("softValues"))
- .addEqualityGroup(parse("weakValues"), parse("weakValues"))
- .testEquals();
- }
-
- public void testMaximumWeight_withWeigher() {
- CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
- builder
- .weigher(constantWeigher(42))
- .build(CacheLoader.from(Suppliers.ofInstance(null)));
- }
-
- public void testMaximumWeight_withoutWeigher() {
- CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
- try {
- builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- public void testMaximumSize_withWeigher() {
- CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
- builder
- .weigher(constantWeigher(42))
- .build(CacheLoader.from(Suppliers.ofInstance(null)));
- }
-
- public void testMaximumSize_withoutWeigher() {
- CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
- builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
- }
-
- public void testDisableCaching() {
- // Functional test: assert that CacheBuilderSpec.disableCaching()
- // disables caching. It's irrelevant how it does so.
- CacheBuilder<Object, Object> builder = CacheBuilder.from(CacheBuilderSpec.disableCaching());
- Object key = new Object();
- Object value = new Object();
- LoadingCache<Object, Object> cache = builder.build(
- CacheLoader.from(Suppliers.ofInstance(value)));
- assertSame(value, cache.getUnchecked(key));
- assertEquals(0, cache.size());
- assertFalse(cache.asMap().containsKey(key));
- }
-
- public void testCacheBuilderFrom_string() {
- CacheBuilder fromString = CacheBuilder.from(
- "initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
- + "weakKeys,weakValues,expireAfterAccess=10m");
- CacheBuilder expected = CacheBuilder.newBuilder()
- .initialCapacity(10)
- .maximumSize(20)
- .concurrencyLevel(30)
- .weakKeys()
- .weakValues()
- .expireAfterAccess(10L, TimeUnit.MINUTES);
- assertCacheBuilderEquivalence(expected, fromString);
- }
-
- private static void assertCacheBuilderEquivalence(CacheBuilder a, CacheBuilder b) {
- assertEquals("concurrencyLevel", a.concurrencyLevel, b.concurrencyLevel);
- assertEquals("expireAfterAccessNanos", a.expireAfterAccessNanos, b.expireAfterAccessNanos);
- assertEquals("expireAfterWriteNanos", a.expireAfterWriteNanos, b.expireAfterWriteNanos);
- assertEquals("initialCapacity", a.initialCapacity, b.initialCapacity);
- assertEquals("maximumSize", a.maximumSize, b.maximumSize);
- assertEquals("maximumWeight", a.maximumWeight, b.maximumWeight);
- assertEquals("refreshNanos", a.refreshNanos, b.refreshNanos);
- assertEquals("keyEquivalence", a.keyEquivalence, b.keyEquivalence);
- assertEquals("keyStrength", a.keyStrength, b.keyStrength);
- assertEquals("removalListener", a.removalListener, b.removalListener);
- assertEquals("weigher", a.weigher, b.weigher);
- assertEquals("valueEquivalence", a.valueEquivalence, b.valueEquivalence);
- assertEquals("valueStrength", a.valueStrength, b.valueStrength);
- assertEquals("statsCounterSupplier", a.statsCounterSupplier, b.statsCounterSupplier);
- assertEquals("ticker", a.ticker, b.ticker);
- }
-}
diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderTest.java
index 1d882e6..31b917d 100644
--- a/guava-tests/test/com/google/common/cache/CacheBuilderTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheBuilderTest.java
@@ -52,6 +52,7 @@ import java.util.concurrent.atomic.AtomicInteger;
@GwtCompatible(emulated = true)
public class CacheBuilderTest extends TestCase {
+ @GwtIncompatible("removalListener")
public void testNewBuilder() {
CacheLoader<Object, Integer> loader = constantLoader(1);
@@ -288,6 +289,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
+ @GwtIncompatible("expireAfterAccess")
public void testTimeToIdle_negative() {
CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>();
try {
@@ -296,6 +298,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
+ @GwtIncompatible("expireAfterAccess")
public void testTimeToIdle_small() {
CacheBuilder.newBuilder()
.expireAfterAccess(1, NANOSECONDS)
@@ -303,6 +306,7 @@ public class CacheBuilderTest extends TestCase {
// well, it didn't blow up.
}
+ @GwtIncompatible("expireAfterAccess")
public void testTimeToIdle_setTwice() {
CacheBuilder<Object, Object> builder =
new CacheBuilder<Object, Object>().expireAfterAccess(3600, SECONDS);
@@ -313,6 +317,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
+ @GwtIncompatible("expireAfterAccess")
public void testTimeToIdleAndToLive() {
CacheBuilder.newBuilder()
.expireAfterWrite(1, NANOSECONDS)
@@ -341,6 +346,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
+ @GwtIncompatible("ticker")
public void testTicker_setTwice() {
Ticker testTicker = Ticker.systemTicker();
CacheBuilder<Object, Object> builder =
@@ -352,6 +358,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
+ @GwtIncompatible("removalListener")
public void testRemovalListener_setTwice() {
RemovalListener<Object, Object> testListener = nullRemovalListener();
CacheBuilder<Object, Object> builder =
@@ -363,7 +370,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
- @GwtIncompatible("CacheTesting")
+ @GwtIncompatible("removalListener")
public void testNullCache() {
CountingRemovalListener<Object, Object> listener = countingRemovalListener();
LoadingCache<Object, Object> nullCache = new CacheBuilder<Object, Object>()
@@ -378,7 +385,7 @@ public class CacheBuilderTest extends TestCase {
CacheTesting.checkEmpty(nullCache.asMap());
}
- @GwtIncompatible("QueuingRemovalListener")
+ @GwtIncompatible("removalListener")
public void testRemovalNotification_clear() throws InterruptedException {
// If a clear() happens while a computation is pending, we should not get a removal
@@ -443,7 +450,7 @@ public class CacheBuilderTest extends TestCase {
* removal listener), or else is not affected by the {@code clear()} (and therefore exists in the
* cache afterward).
*/
- @GwtIncompatible("QueuingRemovalListener")
+ @GwtIncompatible("removalListener")
public void testRemovalNotification_clear_basher() throws InterruptedException {
// If a clear() happens close to the end of computation, one of two things should happen:
@@ -521,10 +528,10 @@ public class CacheBuilderTest extends TestCase {
* Calls get() repeatedly from many different threads, and tests that all of the removed entries
* (removed because of size limits or expiration) trigger appropriate removal notifications.
*/
- @GwtIncompatible("QueuingRemovalListener")
+ @GwtIncompatible("removalListener")
public void testRemovalNotification_get_basher() throws InterruptedException {
- int nTasks = 1000;
+ int nTasks = 3000;
int nThreads = 100;
final int getsPerTask = 1000;
final int nUniqueKeys = 10000;
@@ -555,7 +562,6 @@ public class CacheBuilderTest extends TestCase {
}
};
final LoadingCache<String, String> cache = CacheBuilder.newBuilder()
- .recordStats()
.concurrencyLevel(2)
.expireAfterWrite(100, TimeUnit.MILLISECONDS)
.removalListener(removalListener)
diff --git a/guava-tests/test/com/google/common/cache/CacheEvictionTest.java b/guava-tests/test/com/google/common/cache/CacheEvictionTest.java
index 4011542..64e322e 100644
--- a/guava-tests/test/com/google/common/cache/CacheEvictionTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheEvictionTest.java
@@ -19,7 +19,7 @@ import static com.google.common.cache.TestingRemovalListeners.countingRemovalLis
import static com.google.common.cache.TestingWeighers.constantWeigher;
import static com.google.common.cache.TestingWeighers.intKeyWeigher;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.cache.CacheTesting.Receiver;
import com.google.common.cache.LocalCache.ReferenceEntry;
@@ -169,27 +169,27 @@ public class CacheEvictionTest extends TestCase {
.build(loader);
CacheTesting.warmUp(cache, 0, 10);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// re-order
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
// evict 3, 4, 5
getAll(cache, asList(10, 11, 12));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(6, 7, 8, 9, 0, 1, 2, 10, 11, 12);
+ ASSERT.that(keySet).hasContentsAnyOrder(6, 7, 8, 9, 0, 1, 2, 10, 11, 12);
// re-order
getAll(cache, asList(6, 7, 8));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(9, 0, 1, 2, 10, 11, 12, 6, 7, 8);
+ ASSERT.that(keySet).hasContentsAnyOrder(9, 0, 1, 2, 10, 11, 12, 6, 7, 8);
// evict 9, 0, 1
getAll(cache, asList(13, 14, 15));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(2, 10, 11, 12, 6, 7, 8, 13, 14, 15);
+ ASSERT.that(keySet).hasContentsAnyOrder(2, 10, 11, 12, 6, 7, 8, 13, 14, 15);
}
public void testEviction_weightedLru() {
@@ -202,37 +202,37 @@ public class CacheEvictionTest extends TestCase {
.build(loader);
CacheTesting.warmUp(cache, 0, 10);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// re-order
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
// evict 3, 4, 5
getAll(cache, asList(10));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(6, 7, 8, 9, 0, 1, 2, 10);
+ ASSERT.that(keySet).hasContentsAnyOrder(6, 7, 8, 9, 0, 1, 2, 10);
// re-order
getAll(cache, asList(6, 7, 8));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(9, 0, 1, 2, 10, 6, 7, 8);
+ ASSERT.that(keySet).hasContentsAnyOrder(9, 0, 1, 2, 10, 6, 7, 8);
// evict 9, 1, 2, 10
getAll(cache, asList(15));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(0, 6, 7, 8, 15);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 6, 7, 8, 15);
// fill empty space
getAll(cache, asList(9));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(0, 6, 7, 8, 15, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 6, 7, 8, 15, 9);
// evict 6
getAll(cache, asList(1));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(0, 7, 8, 15, 9, 1);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 7, 8, 15, 9, 1);
}
public void testEviction_overweight() {
@@ -245,17 +245,17 @@ public class CacheEvictionTest extends TestCase {
.build(loader);
CacheTesting.warmUp(cache, 0, 10);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// add an at-the-maximum-weight entry
getAll(cache, asList(45));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(0, 45);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 45);
// add an over-the-maximum-weight entry
getAll(cache, asList(46));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().item(0);
+ ASSERT.that(keySet).hasContentsAnyOrder(0);
}
public void testEviction_invalidateAll() {
@@ -272,7 +272,7 @@ public class CacheEvictionTest extends TestCase {
// add 0, 1, 2, 3, 4
getAll(cache, asList(0, 1, 2, 3, 4));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4);
// invalidate all
cache.invalidateAll();
@@ -282,7 +282,7 @@ public class CacheEvictionTest extends TestCase {
// add 5, 6, 7, 8, 9, 10, 11, 12
getAll(cache, asList(5, 6, 7, 8, 9, 10, 11, 12));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(5, 6, 7, 8, 9, 10, 11, 12);
+ ASSERT.that(keySet).hasContentsAnyOrder(5, 6, 7, 8, 9, 10, 11, 12);
}
private void getAll(LoadingCache<Integer, Integer> cache, List<Integer> keys) {
diff --git a/guava-tests/test/com/google/common/cache/CacheExpirationTest.java b/guava-tests/test/com/google/common/cache/CacheExpirationTest.java
index a2dd701..97677cf 100644
--- a/guava-tests/test/com/google/common/cache/CacheExpirationTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheExpirationTest.java
@@ -18,7 +18,7 @@ import static com.google.common.cache.TestingCacheLoaders.identityLoader;
import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.cache.TestingCacheLoaders.IdentityLoader;
import com.google.common.cache.TestingRemovalListeners.CountingRemovalListener;
@@ -252,7 +252,7 @@ public class CacheExpirationTest extends TestCase {
IdentityLoader<Integer> loader = identityLoader();
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .expireAfterAccess(11, MILLISECONDS)
+ .expireAfterAccess(10, MILLISECONDS)
.ticker(ticker)
.build(loader);
for (int i = 0; i < 10; i++) {
@@ -260,42 +260,42 @@ public class CacheExpirationTest extends TestCase {
ticker.advance(1, MILLISECONDS);
}
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// 0 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(1, 2, 3, 4, 5, 6, 7, 8, 9);
// reorder
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(2, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
// 3 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).hasContentsAnyOrder(4, 5, 6, 7, 8, 9, 0, 1, 2);
// reorder
getAll(cache, asList(5, 7, 9));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).has().allOf(4, 6, 8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(4, 6, 8, 0, 1, 2, 5, 7, 9);
// 4 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(6, 8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(6, 8, 0, 1, 2, 5, 7, 9);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(6, 8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(6, 8, 0, 1, 2, 5, 7, 9);
// 6 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(8, 0, 1, 2, 5, 7, 9);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(8, 0, 1, 2, 5, 7, 9);
// 8 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 5, 7, 9);
}
public void testExpirationOrder_write() throws ExecutionException {
@@ -304,7 +304,7 @@ public class CacheExpirationTest extends TestCase {
IdentityLoader<Integer> loader = identityLoader();
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .expireAfterWrite(11, MILLISECONDS)
+ .expireAfterWrite(10, MILLISECONDS)
.ticker(ticker)
.build(loader);
for (int i = 0; i < 10; i++) {
@@ -312,37 +312,37 @@ public class CacheExpirationTest extends TestCase {
ticker.advance(1, MILLISECONDS);
}
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// 0 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(1, 2, 3, 4, 5, 6, 7, 8, 9);
// get doesn't stop 1 from expiring
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(2, 3, 4, 5, 6, 7, 8, 9, 0);
+ ASSERT.that(keySet).hasContentsAnyOrder(2, 3, 4, 5, 6, 7, 8, 9, 0);
// get(K, Callable) doesn't stop 2 from expiring
cache.get(2, Callables.returning(-2));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0);
+ ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0);
// asMap.put saves 3
cache.asMap().put(3, -3);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(4, 5, 6, 7, 8, 9, 0, 3);
+ ASSERT.that(keySet).hasContentsAnyOrder(4, 5, 6, 7, 8, 9, 0, 3);
// asMap.replace saves 4
cache.asMap().replace(4, -4);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(5, 6, 7, 8, 9, 0, 3, 4);
+ ASSERT.that(keySet).hasContentsAnyOrder(5, 6, 7, 8, 9, 0, 3, 4);
// 5 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(6, 7, 8, 9, 0, 3, 4);
+ ASSERT.that(keySet).hasContentsAnyOrder(6, 7, 8, 9, 0, 3, 4);
}
public void testExpirationOrder_writeAccess() throws ExecutionException {
@@ -351,8 +351,8 @@ public class CacheExpirationTest extends TestCase {
IdentityLoader<Integer> loader = identityLoader();
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .expireAfterWrite(5, MILLISECONDS)
- .expireAfterAccess(3, MILLISECONDS)
+ .expireAfterWrite(4, MILLISECONDS)
+ .expireAfterAccess(2, MILLISECONDS)
.ticker(ticker)
.build(loader);
for (int i = 0; i < 5; i++) {
@@ -365,33 +365,33 @@ public class CacheExpirationTest extends TestCase {
ticker.advance(1, MILLISECONDS);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// get saves 1, 3; 0, 2, 4 expire
getAll(cache, asList(1, 3));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(5, 6, 7, 8, 9, 1, 3);
+ ASSERT.that(keySet).hasContentsAnyOrder(5, 6, 7, 8, 9, 1, 3);
// get saves 6, 8; 5, 7, 9 expire
getAll(cache, asList(6, 8));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(1, 3, 6, 8);
+ ASSERT.that(keySet).hasContentsAnyOrder(1, 3, 6, 8);
// get fails to save 1, put saves 3
cache.asMap().put(3, -3);
getAll(cache, asList(1));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(6, 8, 3);
+ ASSERT.that(keySet).hasContentsAnyOrder(6, 8, 3);
// get(K, Callable) fails to save 8, replace saves 6
cache.asMap().replace(6, -6);
cache.get(8, Callables.returning(-8));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).has().allOf(3, 6);
+ ASSERT.that(keySet).hasContentsAnyOrder(3, 6);
}
private void runRemovalScheduler(LoadingCache<String, Integer> cache,
diff --git a/guava-tests/test/com/google/common/cache/CacheLoadingTest.java b/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
index 90b9ff3..f108b63 100644
--- a/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
@@ -22,7 +22,7 @@ import static com.google.common.cache.TestingCacheLoaders.identityLoader;
import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.TestingCacheLoaders.CountingLoader;
@@ -98,7 +98,6 @@ public class CacheLoadingTest extends TestCase {
public void testLoad() throws ExecutionException {
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(identityLoader());
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -171,7 +170,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -219,7 +218,6 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -279,7 +277,6 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -324,7 +321,6 @@ public class CacheLoadingTest extends TestCase {
public void testBulkLoad_default() throws ExecutionException {
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(TestingCacheLoaders.<Integer>identityLoader());
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -371,7 +367,7 @@ public class CacheLoadingTest extends TestCase {
public void testBulkLoad_loadAll() throws ExecutionException {
IdentityLoader<Integer> backingLoader = identityLoader();
CacheLoader<Integer, Integer> loader = bulkLoader(backingLoader);
- LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -437,7 +433,7 @@ public class CacheLoadingTest extends TestCase {
Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() };
Map<Object, Object> result = cache.getAll(asList(lookupKeys));
- ASSERT.that(result.keySet()).has().allFrom(asList(lookupKeys));
+ ASSERT.that(result.keySet()).hasContentsAnyOrder(lookupKeys);
for (Map.Entry<Object, Object> entry : result.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
@@ -474,7 +470,7 @@ public class CacheLoadingTest extends TestCase {
Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() };
Map<Object, Object> result = cache.getAll(asList(lookupKeys));
- ASSERT.that(result.keySet()).has().allFrom(asList(lookupKeys));
+ ASSERT.that(result.keySet()).hasContentsAnyOrder(lookupKeys);
for (Map.Entry<Object, Object> entry : result.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
@@ -590,7 +586,6 @@ public class CacheLoadingTest extends TestCase {
public void testLoadNull() throws ExecutionException {
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(constantLoader(null));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -661,7 +656,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -706,7 +701,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -753,7 +748,6 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -799,7 +793,6 @@ public class CacheLoadingTest extends TestCase {
public void testBulkLoadNull() throws ExecutionException {
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(bulkLoader(constantLoader(null)));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -819,9 +812,8 @@ public class CacheLoadingTest extends TestCase {
}
public void testBulkLoadNullMap() throws ExecutionException {
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
- .build(new CacheLoader<Object, Object>() {
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(
+ new CacheLoader<Object, Object>() {
@Override
public Object load(Object key) {
throw new AssertionError();
@@ -853,7 +845,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadError() throws ExecutionException {
Error e = new Error();
CacheLoader<Object, Object> loader = errorLoader(e);
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -938,7 +930,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -984,7 +976,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1032,7 +1024,6 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -1080,7 +1071,6 @@ public class CacheLoadingTest extends TestCase {
Error e = new Error();
CacheLoader<Object, Object> loader = errorLoader(e);
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(bulkLoader(loader));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1104,7 +1094,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadCheckedException() {
Exception e = new Exception();
CacheLoader<Object, Object> loader = exceptionLoader(e);
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -1184,7 +1174,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1230,7 +1220,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1278,7 +1268,6 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -1326,7 +1315,6 @@ public class CacheLoadingTest extends TestCase {
Exception e = new Exception();
CacheLoader<Object, Object> loader = exceptionLoader(e);
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(bulkLoader(loader));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1350,7 +1338,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadUncheckedException() throws ExecutionException {
Exception e = new RuntimeException();
CacheLoader<Object, Object> loader = exceptionLoader(e);
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -1430,7 +1418,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1476,7 +1464,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1524,7 +1512,6 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -1572,7 +1559,6 @@ public class CacheLoadingTest extends TestCase {
Exception e = new RuntimeException();
CacheLoader<Object, Object> loader = exceptionLoader(e);
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
- .recordStats()
.build(bulkLoader(loader));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1608,6 +1594,7 @@ public class CacheLoadingTest extends TestCase {
};
CountingRemovalListener<Integer, String> removalListener = countingRemovalListener();
LoadingCache<Integer, String> cache = CacheBuilder.newBuilder()
+ .weakValues()
.removalListener(removalListener)
.build(failOnceFunction);
@@ -2145,79 +2132,6 @@ public class CacheLoadingTest extends TestCase {
assertEquals(2, cache.size());
assertEquals(getKey + suffix, map.get(getKey));
assertEquals(refreshKey + suffix, map.get(refreshKey));
- assertEquals(2, cache.size());
- }
-
- public void testInvalidateAndReloadDuringLoading()
- throws InterruptedException, ExecutionException {
- // computation starts; clear() is called, computation finishes
- final CountDownLatch computationStarted = new CountDownLatch(2);
- final CountDownLatch letGetFinishSignal = new CountDownLatch(1);
- final CountDownLatch getFinishedSignal = new CountDownLatch(4);
- final String getKey = "get";
- final String refreshKey = "refresh";
- final String suffix = "Suffix";
-
- CacheLoader<String, String> computeFunction = new CacheLoader<String, String>() {
- @Override
- public String load(String key) throws InterruptedException {
- computationStarted.countDown();
- letGetFinishSignal.await();
- return key + suffix;
- }
- };
-
- final LoadingCache<String, String> cache = CacheBuilder.newBuilder()
- .build(computeFunction);
- ConcurrentMap<String,String> map = cache.asMap();
- map.put(refreshKey, refreshKey);
-
- new Thread() {
- @Override
- public void run() {
- cache.getUnchecked(getKey);
- getFinishedSignal.countDown();
- }
- }.start();
- new Thread() {
- @Override
- public void run() {
- cache.refresh(refreshKey);
- getFinishedSignal.countDown();
- }
- }.start();
-
- computationStarted.await();
- cache.invalidate(getKey);
- cache.invalidate(refreshKey);
- assertFalse(map.containsKey(getKey));
- assertFalse(map.containsKey(refreshKey));
-
- // start new computations
- new Thread() {
- @Override
- public void run() {
- cache.getUnchecked(getKey);
- getFinishedSignal.countDown();
- }
- }.start();
- new Thread() {
- @Override
- public void run() {
- cache.refresh(refreshKey);
- getFinishedSignal.countDown();
- }
- }.start();
-
- // let computation complete
- letGetFinishSignal.countDown();
- getFinishedSignal.await();
- checkNothingLogged();
-
- // results should be visible
- assertEquals(2, cache.size());
- assertEquals(getKey + suffix, map.get(getKey));
- assertEquals(refreshKey + suffix, map.get(refreshKey));
}
public void testExpandDuringLoading() throws InterruptedException {
diff --git a/guava-tests/test/com/google/common/cache/CacheManualTest.java b/guava-tests/test/com/google/common/cache/CacheManualTest.java
index 5bea1a6..d8db9b6 100644
--- a/guava-tests/test/com/google/common/cache/CacheManualTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheManualTest.java
@@ -27,7 +27,7 @@ import junit.framework.TestCase;
public class CacheManualTest extends TestCase {
public void testGetIfPresent() {
- Cache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build();
+ Cache<Object, Object> cache = CacheBuilder.newBuilder().build();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -103,7 +103,7 @@ public class CacheManualTest extends TestCase {
}
public void testGetAllPresent() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder().recordStats().build();
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder().build();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
diff --git a/guava-tests/test/com/google/common/cache/CacheReferencesTest.java b/guava-tests/test/com/google/common/cache/CacheReferencesTest.java
index 295cf59..ce74b67 100644
--- a/guava-tests/test/com/google/common/cache/CacheReferencesTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheReferencesTest.java
@@ -17,7 +17,7 @@ package com.google.common.cache;
import static com.google.common.cache.LocalCache.Strength.STRONG;
import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener;
import static com.google.common.collect.Maps.immutableEntry;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.base.Function;
import com.google.common.cache.LocalCache.Strength;
@@ -95,7 +95,7 @@ public class CacheReferencesTest extends TestCase {
assertSame(value1, cache.getUnchecked(key1));
assertSame(value2, cache.getUnchecked(key2));
assertEquals(ImmutableSet.of(key1, key2), cache.asMap().keySet());
- ASSERT.that(cache.asMap().values()).has().allOf(value1, value2);
+ ASSERT.that(cache.asMap().values()).hasContentsAnyOrder(value1, value2);
assertEquals(ImmutableSet.of(immutableEntry(key1, value1), immutableEntry(key2, value2)),
cache.asMap().entrySet());
}
@@ -114,7 +114,7 @@ public class CacheReferencesTest extends TestCase {
assertTrue(cache.asMap().containsKey(key2));
assertEquals(1, cache.size());
assertEquals(ImmutableSet.of(key2), cache.asMap().keySet());
- ASSERT.that(cache.asMap().values()).has().item(value2);
+ ASSERT.that(cache.asMap().values()).hasContentsAnyOrder(value2);
assertEquals(ImmutableSet.of(immutableEntry(key2, value2)), cache.asMap().entrySet());
}
}
diff --git a/guava-tests/test/com/google/common/cache/CacheTesting.java b/guava-tests/test/com/google/common/cache/CacheTesting.java
index 62a7270..febd766 100644
--- a/guava-tests/test/com/google/common/cache/CacheTesting.java
+++ b/guava-tests/test/com/google/common/cache/CacheTesting.java
@@ -14,7 +14,6 @@
package com.google.common.cache;
-import static com.google.common.base.Preconditions.checkNotNull;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -92,8 +91,6 @@ class CacheTesting {
}
static <K, V> ReferenceEntry<K, V> getReferenceEntry(Cache<K, V> cache, K key) {
- checkNotNull(cache);
- checkNotNull(key);
LocalCache<K, V> map = toLocalCache(cache);
return map.getEntry(key);
}
@@ -103,8 +100,6 @@ class CacheTesting {
* {@link Segment#expand()}.
*/
static <K, V> void forceExpandSegment(Cache<K, V> cache, K key) {
- checkNotNull(cache);
- checkNotNull(key);
LocalCache<K, V> map = toLocalCache(cache);
int hash = map.hash(key);
Segment<K, V> segment = map.segmentFor(hash);
@@ -128,7 +123,7 @@ class CacheTesting {
* {@link #toLocalCache} without throwing an exception.
*/
static boolean hasLocalCache(Cache<?, ?> cache) {
- return (checkNotNull(cache) instanceof LocalLoadingCache);
+ return (cache instanceof LocalLoadingCache);
}
static void drainRecencyQueues(Cache<?, ?> cache) {
@@ -380,7 +375,7 @@ class CacheTesting {
*/
static void checkRecency(LoadingCache<Integer, Integer> cache, int maxSize,
Receiver<ReferenceEntry<Integer, Integer>> operation) {
- checkNotNull(operation);
+
if (hasLocalCache(cache)) {
warmUp(cache, 0, 2 * maxSize);
@@ -405,14 +400,12 @@ class CacheTesting {
* Warms the given cache by getting all values in {@code [start, end)}, in order.
*/
static void warmUp(LoadingCache<Integer, Integer> map, int start, int end) {
- checkNotNull(map);
for (int i = start; i < end; i++) {
map.getUnchecked(i);
}
}
static void expireEntries(Cache<?, ?> cache, long expiringTime, FakeTicker ticker) {
- checkNotNull(ticker);
expireEntries(toLocalCache(cache), expiringTime, ticker);
}
diff --git a/guava-tests/test/com/google/common/cache/EmptyCachesTest.java b/guava-tests/test/com/google/common/cache/EmptyCachesTest.java
index 994f236..c31cf68 100644
--- a/guava-tests/test/com/google/common/cache/EmptyCachesTest.java
+++ b/guava-tests/test/com/google/common/cache/EmptyCachesTest.java
@@ -40,9 +40,7 @@ import java.util.concurrent.ExecutionException;
*
* @author mike nonemacher
*/
-
public class EmptyCachesTest extends TestCase {
-
public void testEmpty() {
for (LoadingCache<Object, Object> cache : caches()) {
checkEmpty(cache);
@@ -316,7 +314,7 @@ public class EmptyCachesTest extends TestCase {
assertFalse(entrySet.remove(entryOf(6, 6)));
assertFalse(entrySet.remove(entryOf(-6, -6)));
assertFalse(entrySet.removeAll(asList(null, entryOf(0, 0), entryOf(15, 15))));
- assertFalse(entrySet.retainAll(asList(null, entryOf(0, 0), entryOf(15, 15))));
+ assertFalse(entrySet.retainAll( asList(null, entryOf(0, 0), entryOf(15, 15))));
checkEmpty(entrySet);
checkEmpty(cache);
}
diff --git a/guava-tests/test/com/google/common/cache/LocalCacheTest.java b/guava-tests/test/com/google/common/cache/LocalCacheTest.java
index 731de62..7f926e3 100644
--- a/guava-tests/test/com/google/common/cache/LocalCacheTest.java
+++ b/guava-tests/test/com/google/common/cache/LocalCacheTest.java
@@ -30,6 +30,7 @@ import static com.google.common.collect.Maps.immutableEntry;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.easymock.EasyMock.createMock;
import com.google.common.base.Equivalence;
import com.google.common.base.Ticker;
@@ -252,7 +253,7 @@ public class LocalCacheTest extends TestCase {
public void testSetMaximumSize() {
// vary maximumSize wrt concurrencyLevel
- for (int maxSize = 1; maxSize < 100; maxSize++) {
+ for (int maxSize = 1; maxSize < 8; maxSize++) {
checkMaximumSize(1, 8, maxSize);
checkMaximumSize(2, 8, maxSize);
checkMaximumSize(4, 8, maxSize);
@@ -280,8 +281,6 @@ public class LocalCacheTest extends TestCase {
.initialCapacity(initialCapacity)
.maximumSize(maxSize));
long totalCapacity = 0;
- assertTrue("segments=" + map.segments.length + ", maxSize=" + maxSize,
- map.segments.length <= Math.max(1, maxSize / 10));
for (int i = 0; i < map.segments.length; i++) {
totalCapacity += map.segments[i].maxSegmentWeight;
}
@@ -292,8 +291,6 @@ public class LocalCacheTest extends TestCase {
.initialCapacity(initialCapacity)
.maximumWeight(maxSize)
.weigher(constantWeigher(1)));
- assertTrue("segments=" + map.segments.length + ", maxSize=" + maxSize,
- map.segments.length <= Math.max(1, maxSize / 10));
totalCapacity = 0;
for (int i = 0; i < map.segments.length; i++) {
totalCapacity += map.segments[i].maxSegmentWeight;
@@ -485,7 +482,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
entry.setValueReference(valueRef);
table.set(index, entry);
segment.count++;
@@ -514,7 +511,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
entry.setValueReference(valueRef);
table.set(index, entry);
segment.count++;
@@ -713,11 +710,11 @@ public class LocalCacheTest extends TestCase {
// already loading
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(null);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(null, entry);
valueRef.setLoading(true);
entry.setValueReference(valueRef);
table.set(index, entry);
- assertNull(segment.refresh(key, hash, identityLoader(), false));
+ assertNull(segment.refresh(key, hash, identityLoader()));
}
// Removal listener tests
@@ -822,7 +819,7 @@ public class LocalCacheTest extends TestCase {
QueuingRemovalListener<Object, Object> listener = queuingRemovalListener();
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
.concurrencyLevel(1)
- .expireAfterWrite(3, TimeUnit.NANOSECONDS)
+ .expireAfterWrite(2, TimeUnit.NANOSECONDS)
.ticker(ticker)
.removalListener(listener));
assertTrue(listener.isEmpty());
@@ -1051,7 +1048,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
entry.setValueReference(oldValueRef);
// no entry
@@ -1095,7 +1092,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
entry.setValueReference(oldValueRef);
// no entry
@@ -1143,7 +1140,7 @@ public class LocalCacheTest extends TestCase {
// cleared
ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
entry.setValueReference(oldValueRef);
assertSame(oldValue, segment.get(key, hash));
oldValueRef.clear();
@@ -1175,7 +1172,7 @@ public class LocalCacheTest extends TestCase {
// cleared
ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
entry.setValueReference(oldValueRef);
assertSame(oldValue, segment.get(key, hash));
oldValueRef.clear();
@@ -1271,7 +1268,7 @@ public class LocalCacheTest extends TestCase {
// replaced
Object value4 = new Object();
- DummyValueReference<Object, Object> value3Ref = DummyValueReference.create(value3);
+ DummyValueReference<Object, Object> value3Ref = DummyValueReference.create(value3, entry);
valueRef = new LoadingValueReference<Object, Object>(value3Ref);
entry.setValueReference(valueRef);
table.set(index, entry);
@@ -1311,7 +1308,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
entry.setValueReference(oldValueRef);
// no entry
@@ -1351,7 +1348,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
entry.setValueReference(oldValueRef);
// no entry
@@ -1420,49 +1417,6 @@ public class LocalCacheTest extends TestCase {
}
}
- public void testGetCausesExpansion() throws ExecutionException {
- for (int count = 1; count <= 100; count++) {
- LocalCache<Object, Object> map =
- makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1));
- Segment<Object, Object> segment = map.segments[0];
- assertEquals(1, segment.table.length());
-
- for (int i = 0; i < count; i++) {
- Object key = new Object();
- final Object value = new Object();
- segment.get(key, key.hashCode(), new CacheLoader<Object, Object>() {
- @Override
- public Object load(Object key) {
- return value;
- }
- });
- }
- assertEquals(count, segment.count);
- assertTrue(count <= segment.threshold);
- assertTrue(count <= (segment.table.length() * 3 / 4));
- assertTrue(count > (segment.table.length() * 3 / 8));
- }
- }
-
- public void testPutCausesExpansion() {
- for (int count = 1; count <= 100; count++) {
- LocalCache<Object, Object> map =
- makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1));
- Segment<Object, Object> segment = map.segments[0];
- assertEquals(1, segment.table.length());
-
- for (int i = 0; i < count; i++) {
- Object key = new Object();
- Object value = new Object();
- segment.put(key, key.hashCode(), value, true);
- }
- assertEquals(count, segment.count);
- assertTrue(count <= segment.threshold);
- assertTrue(count <= (segment.table.length() * 3 / 4));
- assertTrue(count > (segment.table.length() * 3 / 8));
- }
- }
-
public void testReclaimKey() {
CountingRemovalListener<Object, Object> listener = countingRemovalListener();
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
@@ -1578,7 +1532,7 @@ public class LocalCacheTest extends TestCase {
}
// chain all entries together as we only have a single bucket
entry = DummyEntry.create(key, hash, entry);
- ValueReference<Object, Object> valueRef = DummyValueReference.create(value);
+ ValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
entry.setValueReference(valueRef);
}
segment.table.set(0, entry);
@@ -1736,7 +1690,7 @@ public class LocalCacheTest extends TestCase {
Object value = new Object();
int hash = map.hash(key);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
entry.setValueReference(valueRef);
// reclaim absent
@@ -1758,7 +1712,7 @@ public class LocalCacheTest extends TestCase {
// reclaim wrong value reference
table.set(0, entry);
- DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value);
+ DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value, entry);
entry.setValueReference(otherValueRef);
assertFalse(segment.reclaimValue(key, hash, valueRef));
assertEquals(1, listener.getCount());
@@ -1799,7 +1753,7 @@ public class LocalCacheTest extends TestCase {
// active
Object value = new Object();
- DummyValueReference<Object, Object> previousRef = DummyValueReference.create(value);
+ DummyValueReference<Object, Object> previousRef = DummyValueReference.create(value, entry);
valueRef = new LoadingValueReference<Object, Object>(previousRef);
entry.setValueReference(valueRef);
table.set(0, entry);
@@ -1810,7 +1764,7 @@ public class LocalCacheTest extends TestCase {
// wrong value reference
table.set(0, entry);
- DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value);
+ DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value, entry);
entry.setValueReference(otherValueRef);
assertFalse(segment.removeLoadingValue(key, hash, valueRef));
entry.setValueReference(valueRef);
@@ -2085,7 +2039,7 @@ public class LocalCacheTest extends TestCase {
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
.concurrencyLevel(1)
.ticker(ticker)
- .expireAfterWrite(2, TimeUnit.NANOSECONDS));
+ .expireAfterWrite(1, TimeUnit.NANOSECONDS));
Segment<Object, Object> segment = map.segments[0];
Object key = new Object();
@@ -2124,7 +2078,7 @@ public class LocalCacheTest extends TestCase {
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
.concurrencyLevel(1)
.ticker(ticker)
- .expireAfterAccess(2, TimeUnit.NANOSECONDS));
+ .expireAfterAccess(1, TimeUnit.NANOSECONDS));
Segment<Object, Object> segment = map.segments[0];
Object key = new Object();
@@ -2517,7 +2471,7 @@ public class LocalCacheTest extends TestCase {
private static <K, V> DummyEntry<K, V> createDummyEntry(
K key, int hash, V value, ReferenceEntry<K, V> next) {
DummyEntry<K, V> entry = DummyEntry.create(key, hash, next);
- DummyValueReference<K, V> valueRef = DummyValueReference.create(value);
+ DummyValueReference<K, V> valueRef = DummyValueReference.create(value, entry);
entry.setValueReference(valueRef);
return entry;
}
@@ -2642,23 +2596,26 @@ public class LocalCacheTest extends TestCase {
}
static class DummyValueReference<K, V> implements ValueReference<K, V> {
+ final ReferenceEntry<K, V> entry;
private V value;
boolean loading = false;
- public DummyValueReference() {
+ public DummyValueReference(ReferenceEntry<K, V> entry) {
+ this(null, entry);
this.loading = true;
}
- public DummyValueReference(V value) {
+ public DummyValueReference(V value, ReferenceEntry<K, V> entry) {
this.value = value;
+ this.entry = entry;
}
- public static <K, V> DummyValueReference<K, V> create(V value) {
- return new DummyValueReference<K, V>(value);
+ public static <K, V> DummyValueReference<K, V> create(V value, ReferenceEntry<K, V> entry) {
+ return new DummyValueReference<K, V>(value, entry);
}
- public static <K, V> DummyValueReference<K, V> createLoading() {
- return new DummyValueReference<K, V>();
+ public static <K, V> DummyValueReference<K, V> createLoading(ReferenceEntry<K, V> entry) {
+ return new DummyValueReference<K, V>(entry);
}
@Override
@@ -2673,13 +2630,12 @@ public class LocalCacheTest extends TestCase {
@Override
public ReferenceEntry<K, V> getEntry() {
- return null;
+ return entry;
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return this;
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new DummyValueReference<K, V>(value, entry);
}
public void setLoading(boolean loading) {
diff --git a/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java b/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java
index 90f6efb..c590cd7 100644
--- a/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java
+++ b/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java
@@ -19,19 +19,23 @@ package com.google.common.cache;
import static com.google.common.cache.CacheBuilder.EMPTY_STATS;
import static com.google.common.cache.LocalCacheTest.SMALL_MAX_SIZE;
import static com.google.common.cache.TestingCacheLoaders.identityLoader;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.cache.LocalCache.LocalLoadingCache;
import com.google.common.cache.LocalCache.Segment;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import com.google.common.testing.NullPointerTester;
+import com.google.common.util.concurrent.Callables;
import junit.framework.TestCase;
import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.Collection;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -48,7 +52,7 @@ public class LocalLoadingCacheTest extends TestCase {
}
private CacheBuilder<Object, Object> createCacheBuilder() {
- return CacheBuilder.newBuilder().recordStats();
+ return new CacheBuilder<Object, Object>();
}
// constructor tests
@@ -68,6 +72,7 @@ public class LocalLoadingCacheTest extends TestCase {
public void testNullParameters() throws Exception {
NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Callable.class, Callables.returning(null));
CacheLoader<Object, Object> loader = identityLoader();
tester.testAllPublicInstanceMethods(makeCache(createCacheBuilder(), loader));
}
@@ -160,27 +165,24 @@ public class LocalLoadingCacheTest extends TestCase {
assertNull(map.put(three, one));
assertNull(map.put(one, two));
- ASSERT.that(map).hasKey(three).withValue(one);
- ASSERT.that(map).hasKey(one).withValue(two);
-
- //TODO(user): Confirm with fry@ that this is a reasonable substitute.
- //Set<Map.Entry<Object, Object>> entries = map.entrySet();
- //ASSERT.that(entries).has().allOf(
- // Maps.immutableEntry(three, one), Maps.immutableEntry(one, two));
- //Set<Object> keys = map.keySet();
- //ASSERT.that(keys).has().allOf(one, three);
- //Collection<Object> values = map.values();
- //ASSERT.that(values).has().allOf(one, two);
+ Set<Map.Entry<Object, Object>> entries = map.entrySet();
+ ASSERT.that(entries).hasContentsAnyOrder(
+ Maps.immutableEntry(three, one), Maps.immutableEntry(one, two));
+ Set<Object> keys = map.keySet();
+ ASSERT.that(keys).hasContentsAnyOrder(one, three);
+ Collection<Object> values = map.values();
+ ASSERT.that(values).hasContentsAnyOrder(one, two);
map.clear();
assertEquals(EMPTY_STATS, cache.stats());
}
- public void testNoStats() {
- CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder()
+ public void testDisableStats() {
+ CacheBuilder<Object, Object> builder = createCacheBuilder()
.concurrencyLevel(1)
- .maximumSize(2);
+ .maximumSize(2)
+ .disableStats();
LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader());
assertEquals(EMPTY_STATS, cache.stats());
@@ -200,35 +202,6 @@ public class LocalLoadingCacheTest extends TestCase {
assertEquals(EMPTY_STATS, cache.stats());
}
- public void testRecordStats() {
- CacheBuilder<Object, Object> builder = createCacheBuilder()
- .recordStats()
- .concurrencyLevel(1)
- .maximumSize(2);
- LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader());
- assertEquals(0, cache.stats().hitCount());
- assertEquals(0, cache.stats().missCount());
-
- Object one = new Object();
- cache.getUnchecked(one);
- assertEquals(0, cache.stats().hitCount());
- assertEquals(1, cache.stats().missCount());
-
- cache.getUnchecked(one);
- assertEquals(1, cache.stats().hitCount());
- assertEquals(1, cache.stats().missCount());
-
- Object two = new Object();
- cache.getUnchecked(two);
- assertEquals(1, cache.stats().hitCount());
- assertEquals(2, cache.stats().missCount());
-
- Object three = new Object();
- cache.getUnchecked(three);
- assertEquals(1, cache.stats().hitCount());
- assertEquals(3, cache.stats().missCount());
- }
-
// asMap tests
public void testAsMap() {
diff --git a/guava-tests/test/com/google/common/cache/PackageSanityTests.java b/guava-tests/test/com/google/common/cache/PackageSanityTests.java
deleted file mode 100644
index 17f8ad0..0000000
--- a/guava-tests/test/com/google/common/cache/PackageSanityTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- setDefault(CacheLoader.class, new CacheLoader<Object, Object>() {
- @Override public Object load(Object key) {
- return key;
- }});
- setDefault(LocalCache.class, new LocalCache<Object, Object>(CacheBuilder.newBuilder(), null));
- setDefault(CacheBuilder.class, CacheBuilder.newBuilder());
- }
-}
diff --git a/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java b/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
index 7d8e662..28aa5f8 100644
--- a/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
+++ b/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
@@ -17,9 +17,11 @@ package com.google.common.cache;
import static com.google.common.cache.CacheTesting.checkEmpty;
import static com.google.common.cache.CacheTesting.checkValidState;
import static com.google.common.cache.TestingCacheLoaders.identityLoader;
+import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.base.Function;
import com.google.common.cache.CacheBuilderFactory.DurationSpec;
@@ -45,7 +47,6 @@ import java.util.Set;
*
* @author mike nonemacher
*/
-
public class PopulatedCachesTest extends TestCase {
// we use integers as keys; make sure the range covers some values that ARE cached by
// Integer.valueOf(int), and some that are not cached. (127 is the highest cached value.)
@@ -194,10 +195,11 @@ public class PopulatedCachesTest extends TestCase {
Set<Object> keys = cache.asMap().keySet();
List<Entry<Object, Object>> warmed = warmUp(cache);
- Set<Object> expected = Maps.newHashMap(cache.asMap()).keySet();
- ASSERT.that(keys).has().allFrom(expected);
- ASSERT.that(keys.toArray()).has().allFrom(expected);
- ASSERT.that(keys.toArray(new Object[0])).has().allFrom(expected);
+ Object[] expectedArray = Maps.newHashMap(cache.asMap()).keySet().toArray(new Object[0]);
+ ASSERT.that(keys).hasContentsAnyOrder(expectedArray);
+ ASSERT.that(asList(keys.toArray())).hasContentsAnyOrder(expectedArray);
+ ASSERT.that(asList(keys.toArray(new Object[(int) cache.size()])))
+ .hasContentsAnyOrder(expectedArray);
new EqualsTester()
.addEqualityGroup(cache.asMap().keySet(), keys)
@@ -221,10 +223,11 @@ public class PopulatedCachesTest extends TestCase {
Collection<Object> values = cache.asMap().values();
List<Entry<Object, Object>> warmed = warmUp(cache);
- Collection<Object> expected = Maps.newHashMap(cache.asMap()).values();
- ASSERT.that(values).has().allFrom(expected);
- ASSERT.that(values.toArray()).has().allFrom(expected);
- ASSERT.that(values.toArray(new Object[0])).has().allFrom(expected);
+ Object[] expectedArray = Maps.newHashMap(cache.asMap()).values().toArray(new Object[0]);
+ ASSERT.that(values).hasContentsAnyOrder(expectedArray);
+ ASSERT.that(asList(values.toArray())).hasContentsAnyOrder(expectedArray);
+ ASSERT.that(asList(values.toArray(new Object[(int) cache.size()])))
+ .hasContentsAnyOrder(expectedArray);
assertEquals(WARMUP_SIZE, values.size());
for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
@@ -240,16 +243,16 @@ public class PopulatedCachesTest extends TestCase {
}
@SuppressWarnings("unchecked") // generic array creation
-
public void testEntrySet_populated() {
for (LoadingCache<Object, Object> cache : caches()) {
Set<Entry<Object, Object>> entries = cache.asMap().entrySet();
List<Entry<Object, Object>> warmed = warmUp(cache, WARMUP_MIN, WARMUP_MAX);
- Set<?> expected = Maps.newHashMap(cache.asMap()).entrySet();
- ASSERT.that(entries).has().allFrom((Collection<Entry<Object, Object>>)expected);
- ASSERT.that(entries.toArray()).has().allFrom((Collection<Object>)expected);
- ASSERT.that(entries.toArray(new Entry[0])).has().allFrom((Collection<Entry>)expected);
+ Set<Entry<Object, Object>> entrySet = Maps.newHashMap(cache.asMap()).entrySet();
+ ASSERT.that(entries).is(entrySet);
+ ASSERT.that(entries.toArray()).hasContentsAnyOrder(entrySet.toArray());
+ ASSERT.that(entries.toArray(new Entry[0]))
+ .hasContentsAnyOrder(entrySet.toArray(new Entry[0]));
new EqualsTester()
.addEqualityGroup(cache.asMap().entrySet(), entries)
@@ -298,7 +301,7 @@ public class PopulatedCachesTest extends TestCase {
new Function<CacheBuilder<Object, Object>, LoadingCache<Object, Object>>() {
@Override public LoadingCache<Object, Object> apply(
CacheBuilder<Object, Object> builder) {
- return builder.recordStats().build(identityLoader());
+ return builder.build(identityLoader());
}
});
}
diff --git a/guava-tests/test/com/google/common/cache/RemovalNotificationTest.java b/guava-tests/test/com/google/common/cache/RemovalNotificationTest.java
deleted file mode 100644
index 0932829..0000000
--- a/guava-tests/test/com/google/common/cache/RemovalNotificationTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests of {@link RemovalNotification}.
- *
- * @author Ben Yu
- */
-public class RemovalNotificationTest extends TestCase {
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(
- new RemovalNotification<String, Integer>("one", 1, RemovalCause.EXPLICIT),
- new RemovalNotification<String, Integer>("one", 1, RemovalCause.REPLACED))
- .addEqualityGroup(
- new RemovalNotification<String, Integer>("1", 1, RemovalCause.EXPLICIT))
- .addEqualityGroup(
- new RemovalNotification<String, Integer>("one", 2, RemovalCause.EXPLICIT))
- .testEquals();
- }
-}
diff --git a/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java b/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java
index 3b09ed5..960fed7 100644
--- a/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java
+++ b/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java
@@ -14,8 +14,6 @@
package com.google.common.cache;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Maps;
@@ -25,8 +23,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.annotation.Nullable;
-
/**
* Utility {@link CacheLoader} implementations intended for use in testing.
*
@@ -40,7 +36,6 @@ class TestingCacheLoaders {
* {@link CacheLoader#load} calls to {@code loader}.
*/
static <K, V> CacheLoader<K, V> bulkLoader(final CacheLoader<K, V> loader) {
- checkNotNull(loader);
return new CacheLoader<K, V>() {
@Override
public V load(K key) throws Exception {
@@ -61,7 +56,7 @@ class TestingCacheLoaders {
/**
* Returns a {@link CacheLoader} that returns the given {@code constant} for every request.
*/
- static <K, V> ConstantLoader<K, V> constantLoader(@Nullable V constant) {
+ static <K, V> ConstantLoader<K, V> constantLoader(V constant) {
return new ConstantLoader<K, V>(constant);
}
@@ -76,7 +71,6 @@ class TestingCacheLoaders {
* Returns a {@link CacheLoader} that throws the given error for every request.
*/
static <K, V> CacheLoader<K, V> errorLoader(final Error e) {
- checkNotNull(e);
return new CacheLoader<K, V>() {
@Override
public V load(K key) {
@@ -89,7 +83,6 @@ class TestingCacheLoaders {
* Returns a {@link CacheLoader} that throws the given exception for every request.
*/
static <K, V> CacheLoader<K, V> exceptionLoader(final Exception e) {
- checkNotNull(e);
return new CacheLoader<K, V>() {
@Override
public V load(K key) throws Exception {
diff --git a/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java b/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java
index 5c7912a..67c71da 100644
--- a/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java
+++ b/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java
@@ -14,9 +14,6 @@
package com.google.common.cache;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
@@ -25,7 +22,6 @@ import java.util.concurrent.atomic.AtomicInteger;
*
* @author mike nonemacher
*/
-@GwtCompatible(emulated = true)
class TestingRemovalListeners {
/**
@@ -38,7 +34,6 @@ class TestingRemovalListeners {
/**
* Type-inferring factory method for creating a {@link QueuingRemovalListener}.
*/
- @GwtIncompatible("ConcurrentLinkedQueue")
static <K, V> QueuingRemovalListener<K, V> queuingRemovalListener() {
return new QueuingRemovalListener<K,V>();
}
@@ -53,7 +48,6 @@ class TestingRemovalListeners {
/**
* {@link RemovalListener} that adds all {@link RemovalNotification} objects to a queue.
*/
- @GwtIncompatible("ConcurrentLinkedQueue")
static class QueuingRemovalListener<K, V>
extends ConcurrentLinkedQueue<RemovalNotification<K, V>> implements RemovalListener<K, V> {
diff --git a/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java b/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
index 5616ecc..20f171d 100644
--- a/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
@@ -1,65 +1,551 @@
/*
- * Copyright (C) 2012 The Guava Authors
+ * Copyright (C) 2007 The Guava Authors
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.google.common.collect;
+import static java.util.Arrays.asList;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.testing.SerializableTester;
+
import junit.framework.TestCase;
-import java.util.IdentityHashMap;
+import java.io.Serializable;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
/**
- * Tests for {@code AbstractBiMap}.
+ * Common tests for any {@code BiMap}.
*
- * @author Mike Bostock
+ * @author Kevin Bourrillion
*/
-public class AbstractBiMapTest extends TestCase {
+@GwtCompatible(emulated = true)
+public abstract class AbstractBiMapTest extends TestCase {
+
+ protected abstract BiMap<Integer, String> create();
+
+ protected BiMap<Integer, String> bimap;
+ protected Set<Entry<Integer, String>> entrySet;
+
+ // public for GWT
+ @Override public void setUp() throws Exception {
+ super.setUp();
+ bimap = create();
+ entrySet = bimap.entrySet();
+ }
+
+ public void testClear() {
+ bimap.clear();
+ assertTrue(bimap.isEmpty());
+ putOneTwoThree();
+ bimap.clear();
+ assertTrue(bimap.isEmpty());
+ }
+
+ public void testContainsKey() {
+ assertFalse(bimap.containsKey(null));
+ assertFalse(bimap.containsKey(1));
+ assertFalse(bimap.containsKey("one"));
+
+ bimap.put(1, "one");
+ assertTrue(bimap.containsKey(1));
+
+ bimap.put(null, null);
+ assertTrue(bimap.containsKey(null));
+ }
+
+ public void testContainsValue() {
+ assertFalse(bimap.containsValue(null));
+ assertFalse(bimap.containsValue(1));
+ assertFalse(bimap.containsValue("one"));
+
+ bimap.put(1, "one");
+ assertTrue(bimap.containsValue("one"));
+
+ bimap.put(null, null);
+ assertTrue(bimap.containsValue(null));
+ }
+
+ public void testEquals() {
+ BiMap<Integer, String> biMap = create();
+ assertEquals(biMap, biMap);
+ assertEquals(create(), biMap);
+ biMap.put(1, null);
+ assertFalse(create().equals(biMap));
+ }
+
+ public void testGet() {
+ assertNull(bimap.get(1));
+ assertNull(bimap.get(null));
+ assertNull(bimap.get("bad"));
- // The next two tests verify that map entries are not accessed after they're
- // removed, since IdentityHashMap throws an exception when that occurs.
- public void testIdentityKeySetIteratorRemove() {
- BiMap<Integer, String> bimap = new AbstractBiMap<Integer, String>(
- new IdentityHashMap<Integer, String>(),
- new IdentityHashMap<String, Integer>()) {};
+ bimap.put(1, "one");
+ bimap.put(0, null);
+ bimap.put(null, "nothing");
+ assertEquals("one", bimap.get(1));
+ assertNull(bimap.get(0));
+ assertEquals("nothing", bimap.get(null));
+ assertNull(bimap.get("bad"));
+
+ bimap.forcePut(null, null);
+ assertNull(bimap.get(null));
+ bimap.remove(null);
+ assertNull(bimap.get(null));
+ }
+
+ public void testInverseSimple() {
+ BiMap<String, Integer> inverse = bimap.inverse();
bimap.put(1, "one");
bimap.put(2, "two");
- bimap.put(3, "three");
+ assertEquals(ImmutableMap.of("one", 1, "two", 2), inverse);
+ // see InverseBiMapTest
+
+ assertSame(bimap, inverse.inverse());
+ }
+
+ public void testInversePut() {
+ BiMap<String, Integer> inverse = bimap.inverse();
+ bimap.put(1, "one");
+ bimap.inverse().put("two", 2);
+ assertEquals(ImmutableMap.of("one", 1, "two", 2), inverse);
+ assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
+ }
+
+ public void testIsEmpty() {
+ assertTrue(bimap.isEmpty());
+ bimap.put(1, "one");
+ assertFalse(bimap.isEmpty());
+ bimap.remove(1);
+ assertTrue(bimap.isEmpty());
+ }
+
+ public void testPut() {
+ bimap.put(1, "one");
+ assertEquals(ImmutableMap.of(1, "one"), bimap);
+
+ bimap.put(2, "two");
+ assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
+
+ bimap.put(2, "two");
+ assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
+
+ bimap.put(1, "ONE");
+ assertEquals(ImmutableMap.of(1, "ONE", 2, "two"), bimap);
+
+ try {
+ bimap.put(3, "two");
+ fail();
+ } catch (IllegalArgumentException e) {
+ }
+ assertEquals(ImmutableMap.of(1, "ONE", 2, "two"), bimap);
+
+ bimap.put(-1, null);
+ bimap.put(null, "null");
+ Map<Integer, String> expected = Maps.newHashMap();
+ expected.put(1, "ONE");
+ expected.put(2, "two");
+ expected.put(-1, null);
+ expected.put(null, "null");
+
+ assertEquals(expected, bimap);
+
+ bimap.remove(-1);
+ bimap.put(null, null);
+
+ expected.remove(-1);
+ expected.put(null, null);
+
+ assertEquals(expected, bimap);
+ }
+
+ public void testPutNull() {
+ bimap.put(-1, null);
+ assertTrue(bimap.containsValue(null));
+ bimap.put(1, "one");
+ assertTrue(bimap.containsValue(null));
+ }
+
+ public void testPutAll() {
+ bimap.put(1, "one");
+ Map<Integer, String> newEntries = ImmutableMap.of(2, "two", 3, "three");
+ bimap.putAll(newEntries);
+ assertEquals(ImmutableMap.of(1, "one", 2, "two", 3, "three"), bimap);
+ }
+
+ public void testForcePut() {
+ assertNull(bimap.forcePut(1, "one"));
+ assertEquals(ImmutableMap.of(1, "one"), bimap);
+ assertEquals("one", bimap.forcePut(1, "one"));
+ assertEquals(ImmutableMap.of(1, "one"), bimap);
+ assertEquals("one", bimap.forcePut(1, "ONE"));
+ assertEquals(ImmutableMap.of(1, "ONE"), bimap);
+ assertNull(bimap.forcePut(-1, "ONE")); // key 1 disappears without a trace
+ assertEquals(ImmutableMap.of(-1, "ONE"), bimap);
+ assertNull(bimap.forcePut(2, "two"));
+ assertEquals(ImmutableMap.of(-1, "ONE", 2, "two"), bimap);
+ assertEquals("two", bimap.forcePut(2, "ONE"));
+ assertEquals(ImmutableMap.of(2, "ONE"), bimap);
+ }
+
+ public void testRemove() {
+ Map<Integer, String> map = Maps.newHashMap();
+ map.put(0, null);
+ map.put(1, "one");
+ map.put(null, "null");
+
+ bimap.putAll(map);
+ assertNull(bimap.remove(0));
+
+ map.remove(0);
+ assertEquals(map, bimap);
+
+ assertEquals("null", bimap.remove(null));
+ assertEquals(Collections.singletonMap(1, "one"), bimap);
+
+ assertNull(bimap.remove(15));
+
+ assertEquals("one", bimap.remove(1));
+ assertTrue(bimap.isEmpty());
+ }
+
+ public void testSize() {
+ assertEquals(0, bimap.size());
+ bimap.put(1, "one");
+ assertEquals(1, bimap.size());
+ bimap.put(1, "ONE");
+ assertEquals(1, bimap.size());
+ bimap.put(2, "two");
+ assertEquals(2, bimap.size());
+ bimap.forcePut(1, "two");
+ assertEquals(1, bimap.size());
+ }
+
+ public void testToString() {
+ bimap.put(1, "one");
+ bimap.put(2, "two");
+
+ String string = bimap.toString();
+ String expected = string.startsWith("{1")
+ ? "{1=one, 2=two}"
+ : "{2=two, 1=one}";
+ assertEquals(expected, bimap.toString());
+ }
+
+ // Entry Set
+
+ public void testEntrySetAdd() {
+ try {
+ entrySet.add(Maps.immutableEntry(1, "one"));
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ public void testEntrySetAddAll() {
+ try {
+ entrySet.addAll(Collections.singleton(Maps.immutableEntry(1, "one")));
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ public void testEntrySetClear() {
+ entrySet.clear();
+ assertTrue(entrySet.isEmpty());
+ assertTrue(bimap.isEmpty());
+ putOneTwoThree();
+ entrySet.clear();
+ assertTrue(entrySet.isEmpty());
+ assertTrue(bimap.isEmpty());
+ }
+
+ public void testEntrySetContains() {
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, "one")));
+ bimap.put(1, "one");
+ assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
+ assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(null, null)));
+
+ bimap.put(null, null);
+ assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
+ assertTrue(entrySet.contains(Maps.immutableEntry(null, null)));
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
+ assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
+
+ bimap.put(null, "null");
+ bimap.put(0, null);
+ assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
+ assertTrue(entrySet.contains(Maps.immutableEntry(null, "null")));
+ assertTrue(entrySet.contains(Maps.immutableEntry(0, null)));
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
+ assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
+ assertFalse(entrySet.contains(Maps.immutableEntry(null, null)));
+ }
+
+ public void testEntrySetIsEmpty() {
+ assertTrue(entrySet.isEmpty());
+ bimap.put(1, "one");
+ assertFalse(entrySet.isEmpty());
+ bimap.remove(1);
+ assertTrue(entrySet.isEmpty());
+ }
+
+ public void testEntrySetRemove() {
+ putOneTwoThree();
+ assertTrue(bimap.containsKey(1));
+ assertTrue(bimap.containsValue("one"));
+ assertTrue(entrySet.remove(Maps.immutableEntry(1, "one")));
+ assertFalse(bimap.containsKey(1));
+ assertFalse(bimap.containsValue("one"));
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ assertFalse(entrySet.remove(Maps.immutableEntry(2, "three")));
+ assertFalse(entrySet.remove(3));
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ }
+
+ public void testEntrySetRemoveAll() {
+ putOneTwoThree();
+ assertTrue(bimap.containsKey(1));
+ assertTrue(bimap.containsValue("one"));
+ assertTrue(entrySet.removeAll(
+ Collections.singleton(Maps.immutableEntry(1, "one"))));
+ assertFalse(bimap.containsKey(1));
+ assertFalse(bimap.containsValue("one"));
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ }
+
+ public void testEntrySetValue() {
+ bimap.put(1, "one");
+ Entry<Integer, String> entry = bimap.entrySet().iterator().next();
+ bimap.put(2, "two");
+ assertEquals("one", entry.getValue());
+ bimap.put(1, "one");
+ assertEquals("one", entry.getValue());
+ assertEquals("one", bimap.get(1));
+ assertEquals(Integer.valueOf(1), bimap.inverse().get("one"));
+ bimap.put(1, "uno");
+ assertEquals("uno", entry.getValue());
+ assertEquals("uno", bimap.get(1));
+ assertEquals(Integer.valueOf(1), bimap.inverse().get("uno"));
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ try {
+ entry.setValue("two");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals("uno", entry.getValue());
+ assertEquals("uno", bimap.get(1));
+ assertEquals(Integer.valueOf(1), bimap.inverse().get("uno"));
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ }
+
+ public void testEntrySetValueRemovedEntry() {
+ bimap.put(1, "a");
+ Entry<Integer, String> entry = bimap.entrySet().iterator().next();
+ bimap.clear();
+ try {
+ entry.setValue("b");
+ fail();
+ } catch (IllegalStateException expected) {}
+ assertEquals(0, bimap.size());
+ assertEquals(0, bimap.inverse().size());
+ }
+
+ public void testEntrySetValueRemovedEntryNullOldValue() {
+ bimap.put(1, null);
+ Entry<Integer, String> entry = bimap.entrySet().iterator().next();
+ bimap.clear();
+ try {
+ entry.setValue("b");
+ fail();
+ } catch (IllegalStateException expected) {}
+ assertEquals(0, bimap.size());
+ assertEquals(0, bimap.inverse().size());
+ }
+
+ public void testEntrySetValueRemovedEntryAddedEqualEntry() {
+ bimap.put(1, "a");
+ Entry<Integer, String> entry = bimap.entrySet().iterator().next();
+ bimap.clear();
+ bimap.put(1, "a");
+ try {
+ entry.setValue("b");
+ fail();
+ } catch (IllegalStateException expected) {}
+ assertEquals(1, bimap.size());
+ assertEquals("a", bimap.get(1));
+ assertEquals(1, bimap.inverse().size());
+ assertEquals((Integer) 1, bimap.inverse().get("a"));
+ }
+
+ public void testKeySetIteratorRemove() {
+ putOneTwoThree();
Iterator<Integer> iterator = bimap.keySet().iterator();
iterator.next();
- iterator.next();
- iterator.remove();
- iterator.next();
iterator.remove();
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ }
+
+ public void testKeySetRemoveAll() {
+ putOneTwoThree();
+ Set<Integer> keySet = bimap.keySet();
+ assertTrue(keySet.removeAll(asList(1, 3)));
assertEquals(1, bimap.size());
- assertEquals(1, bimap.inverse().size());
+ assertTrue(keySet.contains(2));
}
- public void testIdentityEntrySetIteratorRemove() {
- BiMap<Integer, String> bimap = new AbstractBiMap<Integer, String>(
- new IdentityHashMap<Integer, String>(),
- new IdentityHashMap<String, Integer>()) {};
- bimap.put(1, "one");
- bimap.put(2, "two");
- bimap.put(3, "three");
+ public void testKeySetRetainAll() {
+ putOneTwoThree();
+ Set<Integer> keySet = bimap.keySet();
+ assertTrue(keySet.retainAll(Collections.singleton(2)));
+ assertEquals(1, bimap.size());
+ assertTrue(keySet.contains(2));
+ }
+
+ public void testEntriesIteratorRemove() {
+ putOneTwoThree();
Iterator<Entry<Integer, String>> iterator = bimap.entrySet().iterator();
iterator.next();
- iterator.next();
iterator.remove();
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ }
+
+ public void testEntriesRetainAll() {
+ putOneTwoThree();
+ Set<Map.Entry<Integer, String>> entries = bimap.entrySet();
+ Map.Entry<Integer, String> entry = Maps.immutableEntry(2, "two");
+ assertTrue(entries.retainAll(Collections.singleton(entry)));
+ assertEquals(1, bimap.size());
+ assertTrue(bimap.containsKey(2));
+ }
+
+ public void testValuesIteratorRemove() {
+ putOneTwoThree();
+ Iterator<String> iterator = bimap.values().iterator();
iterator.next();
iterator.remove();
- assertEquals(1, bimap.size());
- assertEquals(1, bimap.inverse().size());
+ assertEquals(2, bimap.size());
+ assertEquals(2, bimap.inverse().size());
+ }
+
+ public void testValuesToArray() {
+ bimap.put(1, "one");
+ String[] array = new String[3];
+ array[1] = "garbage";
+ assertSame(array, bimap.values().toArray(array));
+ assertEquals("one", array[0]);
+ assertNull(array[1]);
+ }
+
+ public void testValuesToString() {
+ bimap.put(1, "one");
+ assertEquals("[one]", bimap.values().toString());
+ }
+
+ @GwtIncompatible("SerializableTester")
+ public void testSerialization() {
+ bimap.put(1, "one");
+ bimap.put(2, "two");
+ bimap.put(3, "three");
+ bimap.put(null, null);
+
+ BiMap<Integer, String> copy =
+ SerializableTester.reserializeAndAssert(bimap);
+ assertEquals(bimap.inverse(), copy.inverse());
+ }
+
+ void putOneTwoThree() {
+ bimap.put(1, "one");
+ bimap.put(2, "two");
+ bimap.put(3, "three");
+ }
+
+ @GwtIncompatible("used only by @GwtIncompatible code")
+ private static class BiMapPair implements Serializable {
+ final BiMap<Integer, String> forward;
+ final BiMap<String, Integer> backward;
+
+ BiMapPair(BiMap<Integer, String> original) {
+ this.forward = original;
+ this.backward = original.inverse();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ @GwtIncompatible("SerializableTester")
+ public void testSerializationWithInverseEqual() {
+ bimap.put(1, "one");
+ bimap.put(2, "two");
+ bimap.put(3, "three");
+ bimap.put(null, null);
+
+ BiMapPair pair = new BiMapPair(bimap);
+ BiMapPair copy = SerializableTester.reserialize(pair);
+ assertEquals(pair.forward, copy.forward);
+ assertEquals(pair.backward, copy.backward);
+
+ copy.forward.put(4, "four");
+ copy.backward.put("five", 5);
+ assertEquals(copy.backward, copy.forward.inverse());
+ assertEquals(copy.forward, copy.backward.inverse());
+
+ assertTrue(copy.forward.containsKey(4));
+ assertTrue(copy.forward.containsKey(5));
+ assertTrue(copy.backward.containsValue(4));
+ assertTrue(copy.backward.containsValue(5));
+ assertTrue(copy.forward.containsValue("four"));
+ assertTrue(copy.forward.containsValue("five"));
+ assertTrue(copy.backward.containsKey("four"));
+ assertTrue(copy.backward.containsKey("five"));
+ }
+
+ /**
+ * The sameness checks ensure that a bimap and its inverse remain consistent,
+ * even after the deserialized instances are updated. Also, the relationship
+ * {@code a == b.inverse()} should continue to hold after both bimaps are
+ * serialized and deserialized together.
+ */
+ @GwtIncompatible("SerializableTester")
+ public void testSerializationWithInverseSame() {
+ bimap.put(1, "one");
+ bimap.put(2, "two");
+ bimap.put(3, "three");
+ bimap.put(null, null);
+
+ BiMapPair pair = new BiMapPair(bimap);
+ BiMapPair copy = SerializableTester.reserialize(pair);
+ assertSame(copy.backward, copy.forward.inverse());
+ assertSame(copy.forward, copy.backward.inverse());
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java b/guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java
new file mode 100644
index 0000000..0f53f54
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BstTesting.assertInOrderTraversalIs;
+import static com.google.common.collect.BstTesting.nodeFactory;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.TestCase;
+
+import javax.annotation.Nullable;
+
+/**
+ * Tests for an arbitrary {@code BSTRebalancePolicy}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+public abstract class AbstractBstBalancePolicyTest extends TestCase {
+ protected abstract BstBalancePolicy<SimpleNode> getBalancePolicy();
+
+ public void testBalanceLeaf() {
+ SimpleNode a = new SimpleNode('a', null, null);
+ assertInOrderTraversalIs(getBalancePolicy().balance(nodeFactory, a, null, null), "a");
+ }
+
+ private SimpleNode balanceNew(char c, @Nullable SimpleNode left, @Nullable SimpleNode right) {
+ return getBalancePolicy().balance(nodeFactory, new SimpleNode(c, null, null), left, right);
+ }
+
+ public void testBalanceTree1() {
+ // b
+ // \
+ // c
+ SimpleNode c = balanceNew('c', null, null);
+ SimpleNode b = balanceNew('b', null, c);
+ assertInOrderTraversalIs(b, "bc");
+ }
+
+ public void testBalanceTree2() {
+ // b
+ // /
+ // a
+ SimpleNode a = balanceNew('a', null, null);
+ SimpleNode b = balanceNew('b', a, null);
+ assertInOrderTraversalIs(b, "ab");
+ }
+
+ public void testBalanceTree3() {
+ // b
+ // / \
+ // a c
+ SimpleNode a = balanceNew('a', null, null);
+ SimpleNode c = balanceNew('c', null, null);
+ SimpleNode b = balanceNew('b', a, c);
+ assertInOrderTraversalIs(b, "abc");
+ }
+
+ public void testBalanceTree4() {
+ // a
+ // \
+ // b
+ // \
+ // c
+ // \
+ // d
+ // \
+ // e
+ // \
+ // f
+
+ SimpleNode f = balanceNew('f', null, null);
+ SimpleNode e = balanceNew('e', null, f);
+ SimpleNode d = balanceNew('d', null, e);
+ SimpleNode c = balanceNew('c', null, d);
+ SimpleNode b = balanceNew('b', null, c);
+ SimpleNode a = balanceNew('a', null, b);
+ assertInOrderTraversalIs(a, "abcdef");
+ }
+
+ public void testBalanceTree5() {
+ // f
+ // /
+ // e
+ // /
+ // d
+ // /
+ // c
+ // /
+ // b
+ // /
+ // a
+ SimpleNode a = balanceNew('a', null, null);
+ SimpleNode b = balanceNew('b', a, null);
+ SimpleNode c = balanceNew('c', b, null);
+ SimpleNode d = balanceNew('d', c, null);
+ SimpleNode e = balanceNew('e', d, null);
+ SimpleNode f = balanceNew('f', e, null);
+ assertInOrderTraversalIs(f, "abcdef");
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java b/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java
index f3bc17c..13c3df2 100644
--- a/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -203,7 +203,7 @@ public abstract class AbstractCollectionTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicInstanceMethods(c);
}
@@ -221,6 +221,6 @@ public abstract class AbstractCollectionTest extends TestCase {
}
protected void assertContents(String... expected) {
- ASSERT.that(c).has().allFrom(asList(expected));
+ ASSERT.that(c).hasContentsAnyOrder(expected);
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java b/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java
index cef2c0e..ca475da 100644
--- a/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java
@@ -18,7 +18,7 @@ package com.google.common.collect;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -295,17 +295,8 @@ public abstract class AbstractImmutableSetTest extends TestCase {
.add("d", "e", "f")
.add("g", "h", "i", "j")
.build();
- ASSERT.that(set).has().allOf(
- "a", "b", "c", "d", "e", "f", "g", "h", "i", "j").inOrder();
- }
-
- public void testReuseBuilderWithNonDuplicateElements() {
- ImmutableSet.Builder<String> builder = this.<String>builder()
- .add("a")
- .add("b");
- ASSERT.that(builder.build()).has().allOf("a", "b").inOrder();
- builder.add("c", "d");
- ASSERT.that(builder.build()).has().allOf("a", "b", "c", "d").inOrder();
+ ASSERT.that(set).hasContentsInOrder(
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j");
}
public void testBuilderWithDuplicateElements() {
@@ -320,16 +311,6 @@ public abstract class AbstractImmutableSetTest extends TestCase {
assertEquals(1, set.size());
}
- public void testReuseBuilderWithDuplicateElements() {
- ImmutableSet.Builder<String> builder = this.<String>builder()
- .add("a")
- .add("a", "a")
- .add("b");
- ASSERT.that(builder.build()).has().allOf("a", "b").inOrder();
- builder.add("a", "b", "c", "c");
- ASSERT.that(builder.build()).has().allOf("a", "b", "c").inOrder();
- }
-
public void testBuilderAddAll() {
List<String> a = asList("a", "b", "c");
List<String> b = asList("c", "d", "e");
@@ -337,7 +318,7 @@ public abstract class AbstractImmutableSetTest extends TestCase {
.addAll(a)
.addAll(b)
.build();
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e");
}
static final int LAST_COLOR_ADDED = 0x00BFFF;
diff --git a/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java b/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java
index b65e88d..a456c6a 100644
--- a/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,24 +16,21 @@
package com.google.common.collect;
-import com.google.common.annotations.GwtCompatible;
-
import junit.framework.TestCase;
/**
* Tests {@link ImmutableTable}
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
-@GwtCompatible
public abstract class AbstractImmutableTableTest extends TestCase {
abstract Iterable<ImmutableTable<Character, Integer, String>>
getTestInstances();
- @SuppressWarnings("deprecation")
public final void testClear() {
- for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
+ for(ImmutableTable<Character, Integer, String> testInstance :
+ getTestInstances()) {
try {
testInstance.clear();
fail();
@@ -43,9 +40,9 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
}
- @SuppressWarnings("deprecation")
public final void testPut() {
- for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
+ for(ImmutableTable<Character, Integer, String> testInstance :
+ getTestInstances()) {
try {
testInstance.put('a', 1, "blah");
fail();
@@ -55,9 +52,9 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
}
- @SuppressWarnings("deprecation")
public final void testPutAll() {
- for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
+ for(ImmutableTable<Character, Integer, String> testInstance :
+ getTestInstances()) {
try {
testInstance.putAll(ImmutableTable.of('a', 1, "blah"));
fail();
@@ -67,9 +64,9 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
}
- @SuppressWarnings("deprecation")
public final void testRemove() {
- for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
+ for(ImmutableTable<Character, Integer, String> testInstance :
+ getTestInstances()) {
try {
testInstance.remove('a', 1);
fail();
@@ -80,13 +77,15 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
public final void testConsistentToString() {
- for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
+ for(ImmutableTable<Character, Integer, String> testInstance :
+ getTestInstances()) {
assertEquals(testInstance.rowMap().toString(), testInstance.toString());
}
}
public final void testConsistentHashCode() {
- for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
+ for(ImmutableTable<Character, Integer, String> testInstance :
+ getTestInstances()) {
assertEquals(testInstance.cellSet().hashCode(), testInstance.hashCode());
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java b/guava-tests/test/com/google/common/collect/AbstractLinkedIteratorTest.java
index 803ea5a..b51f29f 100644
--- a/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractLinkedIteratorTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -29,9 +29,9 @@ import junit.framework.TestCase;
import java.util.Iterator;
import java.util.NoSuchElementException;
-/** Tests for {@link AbstractSequentialIterator}. */
+/** Tests for {@link AbstractLinkedIterator}. */
@GwtCompatible(emulated = true)
-public class AbstractSequentialIteratorTest extends TestCase {
+public class AbstractLinkedIteratorTest extends TestCase {
@GwtIncompatible("Too slow")
public void testDoublerExhaustive() {
new IteratorTester<Integer>(3, UNMODIFIABLE, ImmutableList.of(1, 2),
@@ -50,14 +50,14 @@ public class AbstractSequentialIteratorTest extends TestCase {
return newDoubler(2, 32);
}
};
- ASSERT.that(doubled).iteratesOverSequence(2, 4, 8, 16, 32);
+ ASSERT.that(doubled).hasContentsInOrder(2, 4, 8, 16, 32);
}
public void testSampleCode() {
Iterable<Integer> actual = new Iterable<Integer>() {
@Override
public Iterator<Integer> iterator() {
- Iterator<Integer> powersOfTwo = new AbstractSequentialIterator<Integer>(1) {
+ Iterator<Integer> powersOfTwo = new AbstractLinkedIterator<Integer>(1) {
protected Integer computeNext(Integer previous) {
return (previous == 1 << 30) ? null : previous * 2;
}
@@ -65,9 +65,9 @@ public class AbstractSequentialIteratorTest extends TestCase {
return powersOfTwo;
}
};
- ASSERT.that(actual).iteratesOverSequence(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
- 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
- 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824);
+ ASSERT.that(actual).hasContentsInOrder(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096,
+ 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
+ 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824);
}
public void testEmpty() {
@@ -102,7 +102,7 @@ public class AbstractSequentialIteratorTest extends TestCase {
}
private static Iterator<Integer> newDoubler(int first, final int last) {
- return new AbstractSequentialIterator<Integer>(first) {
+ return new AbstractLinkedIterator<Integer>(first) {
@Override
protected Integer computeNext(Integer previous) {
return (previous == last) ? null : previous * 2;
@@ -111,7 +111,7 @@ public class AbstractSequentialIteratorTest extends TestCase {
}
private static <T> Iterator<T> newEmpty() {
- return new AbstractSequentialIterator<T>(null) {
+ return new AbstractLinkedIterator<T>(null) {
@Override
protected T computeNext(T previous) {
throw new AssertionFailedError();
@@ -120,7 +120,7 @@ public class AbstractSequentialIteratorTest extends TestCase {
}
private static Iterator<Object> newBroken() {
- return new AbstractSequentialIterator<Object>("UNUSED") {
+ return new AbstractLinkedIterator<Object>("UNUSED") {
@Override
protected Object computeNext(Object previous) {
throw new MyException();
diff --git a/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java
index b830c0a..1741af6 100644
--- a/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java
@@ -18,7 +18,7 @@ package com.google.common.collect;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -182,11 +182,11 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
list.add(1, 2);
assertEquals(4, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 5);
list.addAll(3, asList(4, 8));
assertEquals(6, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 8, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 8, 5);
assertEquals(8, list.get(4).intValue());
assertEquals(4, list.indexOf(8));
@@ -194,11 +194,11 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
list.remove(4);
assertEquals(5, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
list.set(4, 10);
assertEquals(5, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 10).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 10);
}
public void testListMethodsIncludingSublist() {
@@ -211,9 +211,9 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
List<Integer> list = multimap.get("foo");
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
list.set(3, 6);
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 6, 10).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 6, 10);
}
/**
@@ -229,10 +229,10 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
List<Integer> list = multimap.get("foo");
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
list.set(3, 6);
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 6, 5).inOrder();
- ASSERT.that(sublist).has().allOf(2, 3, 6).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 6, 5);
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 6);
}
/**
@@ -272,11 +272,11 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
assertEquals(1, iterator.next().intValue());
iterator.set(2);
- ASSERT.that(multimap.get("foo")).has().allOf(2, 3, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(2, 3, 5);
assertEquals(3, iterator.next().intValue());
iterator.remove();
- ASSERT.that(multimap.get("foo")).has().allOf(2, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(2, 5);
}
/**
@@ -296,12 +296,12 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
sublist.set(1, 6);
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 6, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 6, 4, 5);
}
/**
@@ -311,21 +311,21 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
sublist.remove(1);
assertEquals(4, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 4, 5);
sublist.removeAll(Collections.singleton(4));
assertEquals(3, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 5);
sublist.remove(0);
assertEquals(2, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 5);
}
/**
@@ -335,17 +335,17 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
sublist.add(6);
assertEquals(6, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 6, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 6, 5);
sublist.add(0, 7);
assertEquals(7, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 7, 2, 3, 4, 6, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 7, 2, 3, 4, 6, 5);
}
/**
@@ -355,13 +355,13 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
sublist.clear();
assertEquals(2, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 5);
}
/**
@@ -371,9 +371,9 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
List<Integer> sublist = list.subList(0, 5);
- ASSERT.that(sublist).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(1, 2, 3, 4, 5);
sublist.retainAll(Collections.EMPTY_LIST);
assertTrue(multimap.isEmpty());
@@ -394,12 +394,12 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
assertEquals(2, iterator.next().intValue());
iterator.set(6);
- ASSERT.that(multimap.get("foo")).has().allOf(1, 6, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 6, 3, 4, 5);
assertTrue(iterator.hasNext());
assertEquals(3, iterator.next().intValue());
iterator.remove();
- ASSERT.that(multimap.get("foo")).has().allOf(1, 6, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 6, 4, 5);
assertEquals(4, multimap.size());
}
@@ -485,7 +485,7 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
multimap.put("bar", 11);
multimap.put("bar", 12);
multimap.get("bar").add(0, 13);
- ASSERT.that(multimap.get("bar")).has().allOf(13, 11, 12).inOrder();
+ ASSERT.that(multimap.get("bar")).hasContentsInOrder(13, 11, 12);
}
/**
@@ -501,7 +501,7 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
multimap.putAll("foo", asList(1, 2, 2, 3, 3, 3));
multimap.get("foo").retainAll(asList(1, 2, 4));
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 2).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 2);
}
/**
@@ -517,6 +517,6 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
multimap.putAll("foo", asList(1, 2, 2, 3, 3, 3));
multimap.get("foo").removeAll(asList(2, 3, 3, 4));
- ASSERT.that(multimap.get("foo")).has().item(1);
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1);
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java
index d5f1da1..da55ee0 100644
--- a/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -508,15 +508,6 @@ public abstract class AbstractMultimapTest extends TestCase {
assertFalse(values.contains(5));
}
- public void testValuesToArray() {
- multimap.put("foo", 1);
- multimap.put("foo", nullValue());
- multimap.put(nullKey(), 3);
- Collection<Integer> values = multimap.values();
- ASSERT.that(values.toArray()).has().allOf(1, 3, nullValue());
- ASSERT.that(values.toArray(new Integer[3])).has().allOf(1, 3, nullValue());
- }
-
public void testValuesClear() {
multimap.put("foo", 1);
multimap.put("foo", nullValue());
@@ -549,7 +540,7 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.put("foo", nullValue());
multimap.put(nullKey(), 3);
Collection<Entry<String, Integer>> entries = multimap.entries();
- ASSERT.that(entries).has().allOf(
+ ASSERT.that(entries).hasContentsAnyOrder(
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("foo", nullValue()),
Maps.immutableEntry(nullKey(), 3));
@@ -571,14 +562,14 @@ public abstract class AbstractMultimapTest extends TestCase {
Map<String, Collection<Integer>> map = multimap.asMap();
assertEquals(2, map.size());
- ASSERT.that(map.get("foo")).has().allOf(1, nullValue());
- ASSERT.that(map.get(nullKey())).has().item(3);
+ ASSERT.that(map.get("foo")).hasContentsAnyOrder(1, nullValue());
+ ASSERT.that(map.get(nullKey())).hasContentsAnyOrder(3);
assertNull(map.get("bar"));
assertTrue(map.containsKey("foo"));
assertTrue(map.containsKey(nullKey()));
assertFalse(multimap.containsKey("bar"));
- ASSERT.that(map.remove("foo")).has().allOf(1, nullValue());
+ ASSERT.that(map.remove("foo")).hasContentsAnyOrder(1, nullValue());
assertFalse(multimap.containsKey("foo"));
assertEquals(1, multimap.size());
assertNull(map.remove("bar"));
@@ -638,44 +629,6 @@ public abstract class AbstractMultimapTest extends TestCase {
assertFalse(iterator.hasNext());
}
- public void testAsMapEntriesToArray() {
- multimap.put("foo", 1);
- multimap.put("foo", nullValue());
- multimap.put(nullKey(), 3);
- Collection<Entry<String, Collection<Integer>>> entries =
- multimap.asMap().entrySet();
-
- ASSERT.that(entries.toArray()).has().allOf(
- Maps.immutableEntry("foo", multimap.get("foo")),
- Maps.immutableEntry(nullKey(), multimap.get(nullKey())));
- ASSERT.that(entries.toArray(new Entry[2])).has().allOf(
- Maps.immutableEntry("foo", multimap.get("foo")),
- Maps.immutableEntry(nullKey(), multimap.get(nullKey())));
- }
-
- public void testAsMapValuesToArray() {
- multimap.put("foo", 1);
- multimap.put("foo", nullValue());
- multimap.put(nullKey(), 3);
- Collection<Collection<Integer>> values =
- multimap.asMap().values();
-
- ASSERT.that(values.toArray()).has().allOf(
- multimap.get("foo"), multimap.get(nullKey()));
- ASSERT.that(values.toArray(new Collection[2])).has().allOf(
- multimap.get("foo"), multimap.get(nullKey()));
- }
-
- public void testAsMapKeySetToArray() {
- multimap.put("foo", 1);
- multimap.put("foo", nullValue());
- multimap.put(nullKey(), 3);
- Set<String> keySet = multimap.asMap().keySet();
-
- ASSERT.that(keySet.toArray()).has().allOf("foo", nullKey());
- ASSERT.that(keySet.toArray(new String[2])).has().allOf("foo", nullKey());
- }
-
public void testAsMapToString() {
multimap.put("foo", 1);
assertEquals("{foo=[1]}", multimap.asMap().toString());
@@ -689,7 +642,7 @@ public abstract class AbstractMultimapTest extends TestCase {
Multiset<String> multiset = multimap.keys();
assertEquals(3, multiset.count("foo"));
assertEquals(1, multiset.count(nullKey()));
- ASSERT.that(multiset.elementSet()).has().allOf("foo", nullKey());
+ ASSERT.that(multiset.elementSet()).hasContentsAnyOrder("foo", nullKey());
assertEquals(2, multiset.entrySet().size());
assertEquals(4, multiset.size());
@@ -723,17 +676,6 @@ public abstract class AbstractMultimapTest extends TestCase {
assertEquals(0, multiset.setCount("bar", 0));
}
- public void testKeysToArray() {
- multimap.put("foo", 1);
- multimap.put("foo", 5);
- multimap.put("foo", nullValue());
- multimap.put(nullKey(), 3);
- ASSERT.that(multimap.keys().toArray()).has().allOf(
- "foo", "foo", "foo", nullKey());
- ASSERT.that(multimap.keys().toArray(new String[3])).has().allOf(
- "foo", "foo", "foo", nullKey());
- }
-
public void testKeysAdd() {
multimap.put("foo", 1);
Multiset<String> multiset = multimap.keys();
@@ -877,7 +819,7 @@ public abstract class AbstractMultimapTest extends TestCase {
assertTrue(values.contains(1));
assertTrue(values.contains(5));
assertFalse(values.contains(6));
- ASSERT.that(values).has().allOf(1, 3, 5);
+ ASSERT.that(values).hasContentsAnyOrder(1, 3, 5);
assertTrue(values.containsAll(asList(3, 5)));
assertFalse(values.isEmpty());
assertEquals(multimap.get("foo"), values);
@@ -892,8 +834,8 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.get("bar").addAll(asList(6, 8));
multimap.get("cow").addAll(Arrays.<Integer>asList());
assertSize(6);
- ASSERT.that(multimap.get("foo")).has().allOf(1, 3, 5, 7);
- ASSERT.that(multimap.get("bar")).has().allOf(6, 8);
+ ASSERT.that(multimap.get("foo")).hasContentsAnyOrder(1, 3, 5, 7);
+ ASSERT.that(multimap.get("bar")).hasContentsAnyOrder(6, 8);
ASSERT.that(multimap.get("cow")).isEmpty();
}
@@ -971,13 +913,13 @@ public abstract class AbstractMultimapTest extends TestCase {
assertTrue(values.removeAll(asList(11, 15)));
assertSize(4);
- ASSERT.that(multimap.get("foo")).has().allOf(9, 13, 17);
+ ASSERT.that(multimap.get("foo")).hasContentsAnyOrder(9, 13, 17);
assertFalse(values.removeAll(asList(21, 25)));
assertSize(4);
assertTrue(values.retainAll(asList(13, 17, 19)));
assertSize(3);
- ASSERT.that(multimap.get("foo")).has().allOf(13, 17);
+ ASSERT.that(multimap.get("foo")).hasContentsAnyOrder(13, 17);
assertFalse(values.retainAll(asList(13, 17, 19)));
assertSize(3);
@@ -1005,7 +947,7 @@ public abstract class AbstractMultimapTest extends TestCase {
Integer v3 = iterator.next();
assertFalse(iterator.hasNext());
- ASSERT.that(asList(v1, v2, v3)).has().allOf(1, 3, 5);
+ ASSERT.that(asList(v1, v2, v3)).hasContentsAnyOrder(1, 3, 5);
assertSize(3);
assertTrue(multimap.containsEntry("foo", v1));
assertFalse(multimap.containsEntry("foo", v2));
@@ -1020,7 +962,7 @@ public abstract class AbstractMultimapTest extends TestCase {
iterator.remove();
assertFalse(iterator.hasNext());
- ASSERT.that(asList(n1, n3)).has().allOf(v1, v3);
+ ASSERT.that(asList(n1, n3)).hasContentsAnyOrder(v1, v3);
assertSize(1);
assertFalse(multimap.containsKey("foo"));
}
@@ -1037,7 +979,7 @@ public abstract class AbstractMultimapTest extends TestCase {
Collection<Integer> values = multimap.get("foo");
Collection<Integer> collection = Lists.newArrayList(1, 3);
multimap.putAll("foo", collection);
- ASSERT.that(values).has().allOf(1, 3);
+ ASSERT.that(values).hasContentsAnyOrder(1, 3);
}
public void testGetPutAllMultimap() {
@@ -1054,10 +996,10 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap2.put(nullKey(), nullValue());
multimap.putAll(multimap2);
- ASSERT.that(valuesFoo).has().allOf(1, 2);
- ASSERT.that(valuesBar).has().item(3);
- ASSERT.that(valuesCow).has().item(5);
- ASSERT.that(valuesNull).has().allOf(nullValue(), 2);
+ ASSERT.that(valuesFoo).hasContentsAnyOrder(1, 2);
+ ASSERT.that(valuesBar).hasContentsAnyOrder(3);
+ ASSERT.that(valuesCow).hasContentsAnyOrder(5);
+ ASSERT.that(valuesNull).hasContentsAnyOrder(nullValue(), 2);
}
public void testGetRemove() {
@@ -1065,7 +1007,7 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.put("foo", 3);
Collection<Integer> values = multimap.get("foo");
multimap.remove("foo", 1);
- ASSERT.that(values).has().item(3);
+ ASSERT.that(values).hasContentsAnyOrder(3);
}
public void testGetRemoveAll() {
@@ -1081,7 +1023,7 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.put("foo", 3);
Collection<Integer> values = multimap.get("foo");
multimap.replaceValues("foo", asList(1, 5));
- ASSERT.that(values).has().allOf(1, 5);
+ ASSERT.that(values).hasContentsAnyOrder(1, 5);
multimap.replaceValues("foo", new ArrayList<Integer>());
assertTrue(multimap.isEmpty());
diff --git a/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java b/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java
index 3ca8175..af50029 100644
--- a/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java
@@ -69,6 +69,15 @@ public abstract class AbstractMultisetTest extends AbstractCollectionTest {
assertSize();
}
+ /**
+ * Don't run {@code NullPointerTester} on multisets, since they fail with
+ * Java 6 due to a bug in the JDK, as illustrated in the commented out
+ * method {@code HashMultisetTest#testAnnotations()}.
+ */
+ // TODO: Figure out if this is still true...
+ @GwtIncompatible("NullPointerTester")
+ @Override public void testNullPointerExceptions() throws Exception {}
+
public void testCountZero() {
assertEquals(0, ms.count("a"));
assertSize();
diff --git a/guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java b/guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java
deleted file mode 100644
index 1a44e87..0000000
--- a/guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtIncompatible;
-
-import junit.framework.TestCase;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * Base class for {@link RangeSet} tests.
- *
- * @author Louis Wasserman
- */
-@GwtIncompatible("TreeRangeSet")
-public abstract class AbstractRangeSetTest extends TestCase {
- public static void testInvariants(RangeSet<?> rangeSet) {
- testInvariantsInternal(rangeSet);
- testInvariantsInternal(rangeSet.complement());
- }
-
- private static <C extends Comparable> void testInvariantsInternal(RangeSet<C> rangeSet) {
- assertEquals(rangeSet.asRanges().isEmpty(), rangeSet.isEmpty());
- assertEquals(!rangeSet.asRanges().iterator().hasNext(), rangeSet.isEmpty());
-
- List<Range<C>> asRanges = ImmutableList.copyOf(rangeSet.asRanges());
-
- // test that connected ranges are coalesced
- for (int i = 0; i + 1 < asRanges.size(); i++) {
- Range<C> range1 = asRanges.get(i);
- Range<C> range2 = asRanges.get(i + 1);
- assertFalse(range1.isConnected(range2));
- }
-
- // test that there are no empty ranges
- for (Range<C> range : asRanges) {
- assertFalse(range.isEmpty());
- }
-
- Iterator<Range<C>> itr = rangeSet.asRanges().iterator();
- Range<C> expectedSpan = null;
- if (itr.hasNext()) {
- expectedSpan = itr.next();
- while (itr.hasNext()) {
- expectedSpan = expectedSpan.span(itr.next());
- }
- }
-
- try {
- Range<C> span = rangeSet.span();
- assertEquals(expectedSpan, span);
- } catch (NoSuchElementException e) {
- assertNull(expectedSpan);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java b/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java
index 5c0bc76..b808951 100644
--- a/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -183,11 +183,11 @@ public abstract class AbstractTableReadTest extends TestCase {
public void testColumnSetPartialOverlap() {
table = create(
"foo", 1, 'a', "bar", 1, 'b', "foo", 2, 'c', "bar", 3, 'd');
- ASSERT.that(table.columnKeySet()).has().allOf(1, 2, 3);
+ ASSERT.that(table.columnKeySet()).hasContentsAnyOrder(1, 2, 3);
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerInstance() {
+ public void testNullPointerInstance() throws Exception {
table = create(
"foo", 1, 'a', "bar", 1, 'b', "foo", 2, 'c', "bar", 3, 'd');
new NullPointerTester().testAllPublicInstanceMethods(table);
diff --git a/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java b/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java
index 51012b0..ca53f2c 100644
--- a/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java
@@ -17,22 +17,12 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
import java.util.ConcurrentModificationException;
import java.util.List;
-import java.util.Map.Entry;
import java.util.RandomAccess;
/**
@@ -40,35 +30,9 @@ import java.util.RandomAccess;
*
* @author Jared Levy
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class ArrayListMultimapTest extends AbstractListMultimapTest {
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() {
- @Override
- protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
- ListMultimap<String, String> multimap = ArrayListMultimap.create();
- for (Entry<String, String> entry : entries) {
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap;
- }
- })
- .named("ArrayListMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTestSuite(ArrayListMultimapTest.class);
- return suite;
- }
-
@Override protected ListMultimap<String, Integer> create() {
return ArrayListMultimap.create();
}
@@ -116,9 +80,9 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
List<Integer> sublist = list.subList(0, 5);
- ASSERT.that(sublist).has().allOf(1, 2, 3, 4, 5).inOrder();
+ ASSERT.that(sublist).hasContentsInOrder(1, 2, 3, 4, 5);
sublist.clear();
assertTrue(sublist.isEmpty());
@@ -140,7 +104,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
public void testCreate() {
ArrayListMultimap<String, Integer> multimap
= ArrayListMultimap.create();
- assertEquals(3, multimap.expectedValuesPerKey);
+ assertEquals(10, multimap.expectedValuesPerKey);
}
public void testCreateFromSizes() {
@@ -165,7 +129,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
Multimap<String, Integer> original = HashMultimap.create();
ArrayListMultimap<String, Integer> multimap
= ArrayListMultimap.create(original);
- assertEquals(3, multimap.expectedValuesPerKey);
+ assertEquals(10, multimap.expectedValuesPerKey);
}
public void testCreateFromArrayListMultimap() {
@@ -184,7 +148,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
multimap.put("bar", 3);
multimap.trimToSize();
assertEquals(3, multimap.size());
- ASSERT.that(multimap.get("foo")).has().allOf(1, 2).inOrder();
- ASSERT.that(multimap.get("bar")).has().item(3);
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2);
+ ASSERT.that(multimap.get("bar")).hasContentsInOrder(3);
}
}
diff --git a/guava-tests/test/com/google/common/collect/ArrayTableTest.java b/guava-tests/test/com/google/common/collect/ArrayTableTest.java
index 38bc927..8c2bf0c 100644
--- a/guava-tests/test/com/google/common/collect/ArrayTableTest.java
+++ b/guava-tests/test/com/google/common/collect/ArrayTableTest.java
@@ -17,10 +17,8 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.collect.Table.Cell;
import com.google.common.testing.EqualsTester;
@@ -35,7 +33,6 @@ import java.util.Map;
*
* @author Jared Levy
*/
-@GwtCompatible(emulated = true)
public class ArrayTableTest extends AbstractTableTest {
@Override protected ArrayTable<String, Integer, Character> create(
@@ -242,8 +239,7 @@ public class ArrayTableTest extends AbstractTableTest {
SerializableTester.reserializeAndAssert(table);
}
- @GwtIncompatible("reflection")
- public void testNullPointerStatic() {
+ public void testNullPointerStatic() throws Exception {
new NullPointerTester().testAllPublicStaticMethods(ArrayTable.class);
}
@@ -286,13 +282,13 @@ public class ArrayTableTest extends AbstractTableTest {
public void testRowKeyList() {
ArrayTable<String, Integer, Character> table
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- ASSERT.that(table.rowKeyList()).has().allOf("foo", "bar", "cat").inOrder();
+ ASSERT.that(table.rowKeyList()).hasContentsInOrder("foo", "bar", "cat");
}
public void testColumnKeyList() {
ArrayTable<String, Integer, Character> table
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- ASSERT.that(table.columnKeyList()).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(table.columnKeyList()).hasContentsInOrder(1, 2, 3);
}
public void testGetMissingKeys() {
@@ -394,15 +390,14 @@ public class ArrayTableTest extends AbstractTableTest {
assertNull(table.erase("bar", null));
}
- @GwtIncompatible("ArrayTable.toArray(Class)")
public void testToArray() {
ArrayTable<String, Integer, Character> table
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Character[][] array = table.toArray(Character.class);
assertEquals(3, array.length);
- ASSERT.that(array[0]).has().allOf('a', null, 'c').inOrder();
- ASSERT.that(array[1]).has().allOf('b', null, null).inOrder();
- ASSERT.that(array[2]).has().allOf(null, null, null).inOrder();
+ ASSERT.that(array[0]).hasContentsInOrder('a', null, 'c');
+ ASSERT.that(array[1]).hasContentsInOrder('b', null, null);
+ ASSERT.that(array[2]).hasContentsInOrder(null, null, null);
table.set(0, 2, 'd');
assertEquals((Character) 'c', array[0][2]);
array[0][2] = 'e';
@@ -458,14 +453,4 @@ public class ArrayTableTest extends AbstractTableTest {
assertEquals("Row dog not in [foo, bar, cat]", expected.getMessage());
}
}
-
- @GwtIncompatible("reflection")
- public void testNulls() {
- new NullPointerTester().testAllPublicInstanceMethods(create());
- }
-
- @GwtIncompatible("serialize")
- public void testSerializable() {
- SerializableTester.reserializeAndAssert(create());
- }
}
diff --git a/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java b/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
deleted file mode 100644
index 794a3a5..0000000
--- a/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-
-/**
- * Helper classes for various benchmarks.
- *
- * @author Christopher Swenson
- */
-final class BenchmarkHelpers {
- /**
- * So far, this is the best way to test various implementations of {@link Set} subclasses.
- */
- public enum SetImpl {
- Hash {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return new HashSet<E>(contents);
- }
- },
- LinkedHash {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return new LinkedHashSet<E>(contents);
- }
- },
- Tree {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return new TreeSet<E>(contents);
- }
- },
- Unmodifiable {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return Collections.unmodifiableSet(new HashSet<E>(contents));
- }
- },
- Synchronized {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return Collections.synchronizedSet(new HashSet<E>(contents));
- }
- },
- Immutable {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return ImmutableSet.copyOf(contents);
- }
- },
- ImmutableSorted {
- @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
- return ImmutableSortedSet.copyOf(contents);
- }
- },
- ;
-
- abstract <E extends Comparable<E>> Set<E> create(Collection<E> contents);
- }
-
- public enum ListMultimapImpl {
- ArrayList {
- @Override
- <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) {
- return ArrayListMultimap.create(contents);
- }
- },
- LinkedList {
- @Override
- <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) {
- return LinkedListMultimap.create(contents);
- }
- },
- ImmutableList {
- @Override
- <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) {
- return ImmutableListMultimap.copyOf(contents);
- }
- };
-
- abstract <K, V> ListMultimap<K, V> create(Multimap<K, V> contents);
- }
-
- public enum SetMultimapImpl {
- Hash {
- @Override
- <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
- Multimap<K, V> contents) {
- return HashMultimap.create(contents);
- }
- },
- LinkedHash {
- @Override
- <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
- Multimap<K, V> contents) {
- return LinkedHashMultimap.create(contents);
- }
- },
- Tree {
- @Override
- <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
- Multimap<K, V> contents) {
- return TreeMultimap.create(contents);
- }
- },
- ImmutableSet {
- @Override
- <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
- Multimap<K, V> contents) {
- return ImmutableSetMultimap.copyOf(contents);
- }
- };
-
- abstract <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
- Multimap<K, V> contents);
- }
-
- public enum MapImpl {
- Hash {
- @Override
- <K, V> Map<K, V> create(Map<K, V> map) {
- return Maps.newHashMap(map);
- }
- },
- LinkedHash {
- @Override
- <K, V> Map<K, V> create(Map<K, V> map) {
- return Maps.newLinkedHashMap(map);
- }
- },
- ConcurrentHash {
- @Override
- <K, V> Map<K, V> create(Map<K, V> map) {
- return new ConcurrentHashMap<K, V>(map);
- }
- },
- Immutable {
- @Override
- <K, V> Map<K, V> create(Map<K, V> map) {
- return ImmutableMap.copyOf(map);
- }
- };
-
- abstract <K, V> Map<K, V> create(Map<K, V> map);
- }
-
- enum SortedMapImpl {
- Tree {
- @Override
- <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) {
- SortedMap<K, V> result = Maps.newTreeMap();
- result.putAll(map);
- return result;
- }
- },
- ConcurrentSkipList {
- @Override
- <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) {
- return new ConcurrentSkipListMap<K, V>(map);
- }
- },
- ImmutableSorted {
- @Override
- <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) {
- return ImmutableSortedMap.copyOf(map);
- }
- };
-
- abstract <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map);
- }
-
- enum BiMapImpl {
- Hash{
- @Override
- <K, V> BiMap<K, V> create(BiMap<K, V> map) {
- return HashBiMap.create(map);
- }
- },
- Immutable {
- @Override
- <K, V> BiMap<K, V> create(BiMap<K, V> map) {
- return ImmutableBiMap.copyOf(map);
- }
- };
-
- abstract <K, V> BiMap<K, V> create(BiMap<K, V> map);
- }
-
- enum MultisetImpl {
- Hash {
- @Override
- <E> Multiset<E> create(Multiset<E> contents) {
- return HashMultiset.create(contents);
- }
- },
- LinkedHash {
- @Override
- <E> Multiset<E> create(Multiset<E> contents) {
- return LinkedHashMultiset.create(contents);
- }
- },
- ConcurrentHash {
- @Override
- <E> Multiset<E> create(Multiset<E> contents) {
- return ConcurrentHashMultiset.create(contents);
- }
- },
- Immutable {
- @Override
- <E> Multiset<E> create(Multiset<E> contents) {
- return ImmutableMultiset.copyOf(contents);
- }
- };
-
- abstract <E> Multiset<E> create(Multiset<E> contents);
- }
-
- enum SortedMultisetImpl {
- Tree {
- @Override
- <E extends Comparable<E>> SortedMultiset<E> create(Multiset<E> contents) {
- return TreeMultiset.create(contents);
- }
- },
- ImmutableSorted {
- @Override
- <E extends Comparable<E>> SortedMultiset<E> create(Multiset<E> contents) {
- return ImmutableSortedMultiset.copyOf(contents);
- }
- };
-
- abstract <E extends Comparable<E>> SortedMultiset<E> create(Multiset<E> contents);
- }
-
- enum TableImpl {
- HashBased {
- @Override
- <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
- Table<R, C, V> contents) {
- return HashBasedTable.create(contents);
- }
- },
- TreeBased {
- @Override
- <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
- Table<R, C, V> contents) {
- Table<R, C, V> table = TreeBasedTable.create();
- table.putAll(contents);
- return table;
- }
- },
- Array {
- @Override
- <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
- Table<R, C, V> contents) {
- if (contents.isEmpty()) {
- return ImmutableTable.of();
- } else {
- return ArrayTable.create(contents);
- }
- }
- },
- Immutable {
- @Override
- <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
- Table<R, C, V> contents) {
- return ImmutableTable.copyOf(contents);
- }
- };
-
- abstract <R extends Comparable<R>, C extends Comparable<C>, V>
- Table<R, C, V> create(Table<R, C, V> contents);
- }
-
- public enum Value {
- INSTANCE;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BiMapCollectionTest.java b/guava-tests/test/com/google/common/collect/BiMapCollectionTest.java
new file mode 100644
index 0000000..9bee5f1
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BiMapCollectionTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Set;
+
+/**
+ * Collection tests for bimaps.
+ *
+ * @author Jared Levy
+ */
+@GwtCompatible
+public class BiMapCollectionTest extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ BiMap<String, Integer> bimap = HashBiMap.create();
+ for (int i = 0; i < elements.length; i++) {
+ bimap.put(elements[i], i);
+ }
+ return bimap.keySet();
+ }
+ })
+ .named("HashBiMap.keySet")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ BiMap<Integer, String> bimap = HashBiMap.create();
+ for (int i = 0; i < elements.length; i++) {
+ bimap.put(i, elements[i]);
+ }
+ return bimap.values();
+ }
+ })
+ .named("HashBiMap.values")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION)
+ .createTestSuite());
+
+ return suite;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java b/guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java
new file mode 100644
index 0000000..6f3ae3e
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.testing.MapInterfaceTest;
+
+import junit.framework.TestCase;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Map interface tests for bimaps.
+ *
+ * @author Jared Levy
+ */
+@GwtCompatible
+public class BiMapMapInterfaceTest extends TestCase {
+
+ private abstract static class AbstractMapInterfaceTest
+ extends MapInterfaceTest<String, Integer> {
+
+ protected AbstractMapInterfaceTest(boolean modifiable) {
+ super(true, true, modifiable, modifiable, modifiable);
+ }
+
+ @Override protected String getKeyNotInPopulatedMap() {
+ return "cat";
+ }
+
+ @Override protected Integer getValueNotInPopulatedMap() {
+ return 3;
+ }
+
+ @Override protected Map<String, Integer> makeEmptyMap() {
+ return HashBiMap.create();
+ }
+
+ @Override protected Map<String, Integer> makePopulatedMap() {
+ Map<String, Integer> map = makeEmptyMap();
+ map.put("foo", 1);
+ map.put("bar", 2);
+ return map;
+ }
+
+ @Override protected void assertMoreInvariants(Map<String, Integer> map) {
+ BiMap<String, Integer> bimap = (BiMap<String, Integer>) map;
+ BiMap<Integer, String> inverse = bimap.inverse();
+ assertEquals(bimap.size(), inverse.size());
+ for (Entry<String, Integer> entry : bimap.entrySet()) {
+ assertEquals(entry.getKey(), inverse.get(entry.getValue()));
+ }
+ for (Entry<Integer, String> entry : inverse.entrySet()) {
+ assertEquals(entry.getKey(), bimap.get(entry.getValue()));
+ }
+ }
+ }
+
+ public static class HashBiMapInterfaceTest extends AbstractMapInterfaceTest {
+ public HashBiMapInterfaceTest() {
+ super(true);
+ }
+ @Override protected Map<String, Integer> makeEmptyMap() {
+ return HashBiMap.create();
+ }
+ }
+
+ public static class InverseBiMapInterfaceTest
+ extends AbstractMapInterfaceTest {
+ public InverseBiMapInterfaceTest() {
+ super(true);
+ }
+ @Override protected Map<String, Integer> makeEmptyMap() {
+ return HashBiMap.<Integer, String>create().inverse();
+ }
+ }
+
+ public static class UnmodifiableBiMapInterfaceTest
+ extends AbstractMapInterfaceTest {
+ public UnmodifiableBiMapInterfaceTest() {
+ super(false);
+ }
+ @Override protected Map<String, Integer> makeEmptyMap() {
+ return Maps.unmodifiableBiMap(HashBiMap.<String, Integer>create());
+ }
+ @Override protected Map<String, Integer> makePopulatedMap() {
+ BiMap<String, Integer> bimap = HashBiMap.create();
+ bimap.put("foo", 1);
+ bimap.put("bar", 2);
+ return Maps.unmodifiableBiMap(bimap);
+ }
+ }
+
+ public static class SynchronizedBiMapInterfaceTest
+ extends AbstractMapInterfaceTest {
+ public SynchronizedBiMapInterfaceTest() {
+ super(true);
+ }
+ @Override protected Map<String, Integer> makeEmptyMap() {
+ return Maps.synchronizedBiMap(HashBiMap.<String, Integer>create());
+ }
+ }
+
+ public void testNothing() {
+ /*
+ * It's a warning if a TestCase subclass contains no tests, so we add one.
+ * Alternatively, we could stop extending TestCase, but I worry that someone
+ * will add a test in the future and not realize that it's being ignored.
+ */
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java b/guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java
new file mode 100644
index 0000000..f084ae7
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BstTesting.countAggregate;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests for the policies exported by {@link BstCountBasedBalancePolicies}
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+public class BstCountBasedBalancePoliciesTest extends TestCase {
+ public static class NoRebalanceTest extends AbstractBstBalancePolicyTest {
+ @Override
+ protected BstBalancePolicy<SimpleNode> getBalancePolicy() {
+ return BstCountBasedBalancePolicies.noRebalancePolicy(countAggregate);
+ }
+ }
+
+ public static class SingleRebalanceTest extends AbstractBstBalancePolicyTest {
+ @Override
+ protected BstBalancePolicy<SimpleNode> getBalancePolicy() {
+ return BstCountBasedBalancePolicies.<Character, SimpleNode>singleRebalancePolicy(
+ countAggregate);
+ }
+ }
+
+ public static class FullRebalanceTest extends AbstractBstBalancePolicyTest {
+ @Override
+ protected BstBalancePolicy<SimpleNode> getBalancePolicy() {
+ return BstCountBasedBalancePolicies.<Character, SimpleNode>fullRebalancePolicy(
+ countAggregate);
+ }
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(NoRebalanceTest.class);
+ suite.addTestSuite(SingleRebalanceTest.class);
+ suite.addTestSuite(FullRebalanceTest.class);
+ return suite;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstInOrderPathTest.java b/guava-tests/test/com/google/common/collect/BstInOrderPathTest.java
new file mode 100644
index 0000000..0498401
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstInOrderPathTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+import static com.google.common.collect.BstTesting.defaultNullPointerTester;
+import static com.google.common.collect.BstTesting.extension;
+import static com.google.common.collect.BstTesting.pathToList;
+import static org.junit.contrib.truth.Truth.ASSERT;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@code BstInOrderPath}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+public class BstInOrderPathTest extends TestCase {
+ public void testFullTreeRight() {
+ // d
+ // / \
+ // b f
+ // / \ / \
+ // a c e g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', a, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+ BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
+ BstInOrderPath.inOrderFactory();
+ BstInOrderPath<SimpleNode> path = extension(factory, d, LEFT, LEFT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(a, b, d);
+ path = testNextPathIs(path, b, d);
+ path = testNextPathIs(path, c, b, d);
+ path = testNextPathIs(path, d);
+ path = testNextPathIs(path, e, f, d);
+ path = testNextPathIs(path, f, d);
+ path = testNextPathIs(path, g, f, d);
+ assertFalse(path.hasNext(RIGHT));
+ }
+
+ public void testFullTreeLeft() {
+ // d
+ // / \
+ // b f
+ // / \ / \
+ // a c e g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', a, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+ BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
+ BstInOrderPath.inOrderFactory();
+ BstInOrderPath<SimpleNode> path = extension(factory, d, RIGHT, RIGHT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(g, f, d);
+ path = testPrevPathIs(path, f, d);
+ path = testPrevPathIs(path, e, f, d);
+ path = testPrevPathIs(path, d);
+ path = testPrevPathIs(path, c, b, d);
+ path = testPrevPathIs(path, b, d);
+ path = testPrevPathIs(path, a, b, d);
+ assertFalse(path.hasNext(LEFT));
+ }
+
+ public void testPartialTree1Right() {
+
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+ BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
+ BstInOrderPath.inOrderFactory();
+ BstInOrderPath<SimpleNode> path = extension(factory, d, LEFT, LEFT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(a, b, d);
+ path = testNextPathIs(path, b, d);
+ path = testNextPathIs(path, d);
+ path = testNextPathIs(path, f, d);
+ path = testNextPathIs(path, g, f, d);
+ assertFalse(path.hasNext(RIGHT));
+ }
+
+ public void testPartialTree1Left() {
+
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+ BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
+ BstInOrderPath.inOrderFactory();
+ BstInOrderPath<SimpleNode> path = extension(factory, d, RIGHT, RIGHT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(g, f, d);
+ path = testPrevPathIs(path, f, d);
+ path = testPrevPathIs(path, d);
+ path = testPrevPathIs(path, b, d);
+ path = testPrevPathIs(path, a, b, d);
+ assertFalse(path.hasNext(LEFT));
+ }
+
+ public void testPartialTree2Right() {
+ // d
+ // / \
+ // b f
+ // \ /
+ // c e
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode f = new SimpleNode('f', e, null);
+ SimpleNode d = new SimpleNode('d', b, f);
+ BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
+ BstInOrderPath.inOrderFactory();
+ BstInOrderPath<SimpleNode> path = extension(factory, d, LEFT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(b, d);
+ path = testNextPathIs(path, c, b, d);
+ path = testNextPathIs(path, d);
+ path = testNextPathIs(path, e, f, d);
+ path = testNextPathIs(path, f, d);
+ assertFalse(path.hasNext(RIGHT));
+ }
+
+ public void testPartialTree2Left() {
+ // d
+ // / \
+ // b f
+ // \ /
+ // c e
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode f = new SimpleNode('f', e, null);
+ SimpleNode d = new SimpleNode('d', b, f);
+ BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
+ BstInOrderPath.inOrderFactory();
+ BstInOrderPath<SimpleNode> path = extension(factory, d, RIGHT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(f, d);
+ path = testPrevPathIs(path, e,f,d);
+ path = testPrevPathIs(path, d);
+ path = testPrevPathIs(path, c,b, d);
+ path = testPrevPathIs(path, b, d);
+ assertFalse(path.hasNext(LEFT));
+ }
+
+ private static BstInOrderPath<SimpleNode> testNextPathIs(
+ BstInOrderPath<SimpleNode> path, SimpleNode... nodes) {
+ assertTrue(path.hasNext(RIGHT));
+ path = path.next(RIGHT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(nodes);
+ return path;
+ }
+
+ private static BstInOrderPath<SimpleNode> testPrevPathIs(
+ BstInOrderPath<SimpleNode> path, SimpleNode... nodes) {
+ assertTrue(path.hasNext(LEFT));
+ path = path.next(LEFT);
+ ASSERT.that(pathToList(path)).hasContentsInOrder(nodes);
+ return path;
+ }
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() throws Exception {
+ defaultNullPointerTester().testAllPublicStaticMethods(BstInOrderPath.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstMutationResultTest.java b/guava-tests/test/com/google/common/collect/BstMutationResultTest.java
new file mode 100644
index 0000000..bb942c2
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstMutationResultTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BstTesting.defaultNullPointerTester;
+
+import com.google.common.annotations.GwtIncompatible;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@code BstMutationResult}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtIncompatible("NullPointerTester")
+public class BstMutationResultTest extends TestCase {
+ public void testNullPointers() throws Exception {
+ defaultNullPointerTester().testAllPublicStaticMethods(BstMutationResult.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstNodeTest.java b/guava-tests/test/com/google/common/collect/BstNodeTest.java
new file mode 100644
index 0000000..37f2bbc
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstNodeTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 'b'.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-'b'.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+import static com.google.common.collect.BstTesting.defaultNullPointerTester;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Tests for {@code BstNode}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+public class BstNodeTest extends TestCase {
+ private void testLacksChild(SimpleNode node, BstSide side) {
+ assertNull(node.childOrNull(side));
+ assertFalse(node.hasChild(side));
+ try {
+ node.getChild(side);
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {}
+ }
+
+ private void testChildIs(SimpleNode node, BstSide side, SimpleNode expectedChild) {
+ assertEquals(expectedChild, node.childOrNull(side));
+ assertTrue(node.hasChild(side));
+ assertEquals(expectedChild, node.getChild(side));
+ }
+
+ public void testHasChildLeaf() {
+ SimpleNode leaf = new SimpleNode('a', null, null);
+ testLacksChild(leaf, LEFT);
+ testLacksChild(leaf, RIGHT);
+ }
+
+ public void testHasChildLeftOnly() {
+ SimpleNode leaf = new SimpleNode('a', null, null);
+ SimpleNode node = new SimpleNode('b', leaf, null);
+ testChildIs(node, LEFT, leaf);
+ testLacksChild(node, RIGHT);
+ }
+
+ public void testHasChildRightOnly() {
+ SimpleNode leaf = new SimpleNode('c', null, null);
+ SimpleNode node = new SimpleNode('b', null, leaf);
+ testLacksChild(node, LEFT);
+ testChildIs(node, RIGHT, leaf);
+ }
+
+ public void testHasChildBoth() {
+ SimpleNode left = new SimpleNode('a', null, null);
+ SimpleNode right = new SimpleNode('c', null, null);
+ SimpleNode node = new SimpleNode('b', left, right);
+ testChildIs(node, LEFT, left);
+ testChildIs(node, RIGHT, right);
+ }
+
+ private static final char MIDDLE_KEY = 'b';
+
+ private static final List<SimpleNode> GOOD_LEFTS =
+ Arrays.asList(null, new SimpleNode('a', null, null));
+ private static final List<SimpleNode> BAD_LEFTS =
+ Arrays.asList(new SimpleNode('b', null, null), new SimpleNode('c', null, null));
+ private static final Iterable<SimpleNode> ALL_LEFTS = Iterables.concat(GOOD_LEFTS, BAD_LEFTS);
+
+ private static final List<SimpleNode> GOOD_RIGHTS =
+ Arrays.asList(null, new SimpleNode('c', null, null));
+ private static final List<SimpleNode> BAD_RIGHTS =
+ Arrays.asList(new SimpleNode('b', null, null), new SimpleNode('a', null, null));
+ private static final Iterable<SimpleNode> ALL_RIGHTS = Iterables.concat(GOOD_RIGHTS, BAD_RIGHTS);
+
+ public void testOrderingInvariantHoldsForGood() {
+ for (SimpleNode left : GOOD_LEFTS) {
+ for (SimpleNode right : GOOD_RIGHTS) {
+ assertTrue(
+ new SimpleNode(MIDDLE_KEY, left, right).orderingInvariantHolds(Ordering.natural()));
+ }
+ }
+ }
+
+ public void testOrderingInvariantBadLeft() {
+ for (SimpleNode left : BAD_LEFTS) {
+ for (SimpleNode right : ALL_RIGHTS) {
+ assertFalse(
+ new SimpleNode(MIDDLE_KEY, left, right).orderingInvariantHolds(Ordering.natural()));
+ }
+ }
+ }
+
+ public void testOrderingInvariantBadRight() {
+ for (SimpleNode left : ALL_LEFTS) {
+ for (SimpleNode right : BAD_RIGHTS) {
+ assertFalse(
+ new SimpleNode(MIDDLE_KEY, left, right).orderingInvariantHolds(Ordering.natural()));
+ }
+ }
+ }
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() throws Exception {
+ defaultNullPointerTester().testAllPublicStaticMethods(BstNode.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstOperationsTest.java b/guava-tests/test/com/google/common/collect/BstOperationsTest.java
new file mode 100644
index 0000000..7ced712
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstOperationsTest.java
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstTesting.assertInOrderTraversalIs;
+import static com.google.common.collect.BstTesting.balancePolicy;
+import static com.google.common.collect.BstTesting.defaultNullPointerTester;
+import static com.google.common.collect.BstTesting.extension;
+import static com.google.common.collect.BstTesting.nodeFactory;
+import static com.google.common.collect.BstTesting.pathFactory;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isNull;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reportMatcher;
+import static org.easymock.EasyMock.same;
+import static org.easymock.EasyMock.verify;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.BstModificationResult.ModificationType;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+
+/**
+ * Tests for {@code BstOperations}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+public class BstOperationsTest extends TestCase {
+ public void testSeek1() {
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+ assertEquals(a, BstOperations.seek(Ordering.natural(), d, 'a'));
+ assertEquals(b, BstOperations.seek(Ordering.natural(), d, 'b'));
+ assertNull(BstOperations.seek(Ordering.natural(), d, 'c'));
+ assertEquals(d, BstOperations.seek(Ordering.natural(), d, 'd'));
+ assertNull(BstOperations.seek(Ordering.natural(), d, 'e'));
+ assertEquals(f, BstOperations.seek(Ordering.natural(), d, 'f'));
+ assertEquals(g, BstOperations.seek(Ordering.natural(), d, 'g'));
+ }
+
+ public void testSeek2() {
+ // d
+ // / \
+ // b f
+ // \ /
+ // c e
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode f = new SimpleNode('f', e, null);
+ SimpleNode d = new SimpleNode('d', b, f);
+ assertNull(BstOperations.seek(Ordering.natural(), d, 'a'));
+ assertEquals(b, BstOperations.seek(Ordering.natural(), d, 'b'));
+ assertEquals(c, BstOperations.seek(Ordering.natural(), d, 'c'));
+ assertEquals(d, BstOperations.seek(Ordering.natural(), d, 'd'));
+ assertEquals(e, BstOperations.seek(Ordering.natural(), d, 'e'));
+ assertEquals(f, BstOperations.seek(Ordering.natural(), d, 'f'));
+ assertNull(BstOperations.seek(Ordering.natural(), d, 'g'));
+ }
+
+ @GwtIncompatible("EasyMock")
+ @SuppressWarnings("unchecked")
+ public void testModifyInsertAbsentNode() {
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
+ BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
+ BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
+
+ SimpleNode c = new SimpleNode('c', null, null);
+ expect(modifier.modify(eq('c'), (SimpleNode) isNull())).andReturn(
+ BstModificationResult.rebalancingChange(null, c));
+
+ expect(balancePolicy.balance(
+ same(nodeFactory), same(c), (SimpleNode) isNull(), (SimpleNode) isNull()))
+ .andReturn(c)
+ .times(0, 1);
+
+ SimpleNode bWithC = new SimpleNode('b', a, c);
+ expectPossibleEntryfication(nodeFactory, b);
+ expect(balancePolicy.balance(
+ same(nodeFactory), withKey('b'), same(a), withKey('c')))
+ .andReturn(bWithC);
+
+ SimpleNode dWithBWithC = new SimpleNode('d', bWithC, f);
+ expectPossibleEntryfication(nodeFactory, d);
+ expect(
+ balancePolicy.balance(same(nodeFactory), withKey('d'), same(bWithC), same(f)))
+ .andReturn(dWithBWithC);
+ replay(nodeFactory, balancePolicy, modifier);
+ BstMutationRule<Character, SimpleNode> mutationRule =
+ BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
+ BstMutationResult<Character, SimpleNode> mutationResult =
+ BstOperations.mutate(Ordering.natural(), mutationRule, d, 'c');
+ assertEquals('c', mutationResult.getTargetKey().charValue());
+ assertNull(mutationResult.getOriginalTarget());
+ assertEquals('c', mutationResult
+ .getChangedTarget()
+ .getKey()
+ .charValue());
+ assertSame(d, mutationResult.getOriginalRoot());
+ assertSame(dWithBWithC, mutationResult.getChangedRoot());
+ assertEquals(ModificationType.REBALANCING_CHANGE, mutationResult.modificationType());
+ verify(nodeFactory, balancePolicy, modifier);
+ }
+
+ @GwtIncompatible("EasyMock")
+ @SuppressWarnings("unchecked")
+ public void testModifyInsertPresentNode() {
+ // We wish to test that BstOperations & co. treat IDENTITY modifications as the same.
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
+ BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
+ BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
+
+ expectPossibleEntryfication(nodeFactory, a);
+ expect(modifier.modify(eq('a'), withKey('a'))).andReturn(
+ BstModificationResult.identity(a));
+ replay(nodeFactory, balancePolicy, modifier);
+ BstMutationRule<Character, SimpleNode> mutationRule =
+ BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
+ BstMutationResult<Character, SimpleNode> mutationResult =
+ BstOperations.mutate(Ordering.natural(), mutationRule, d, 'a');
+ assertEquals('a', mutationResult.getTargetKey().charValue());
+ assertSame(a, mutationResult.getOriginalTarget());
+ assertSame(a, mutationResult.getChangedTarget());
+ assertSame(d, mutationResult.getOriginalRoot());
+ assertSame(d, mutationResult.getChangedRoot());
+ assertEquals(ModificationType.IDENTITY, mutationResult.modificationType());
+ verify(nodeFactory, balancePolicy, modifier);
+ }
+
+ @GwtIncompatible("EasyMock")
+ @SuppressWarnings("unchecked")
+ public void testModifyInsertInequivalentNode() {
+ // We wish to test that BstOperations & co. treat non-equivalent() nodes as different.
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
+ BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
+ BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
+
+ expectPossibleEntryfication(nodeFactory, a);
+ SimpleNode a2 = new SimpleNode('a', null, null);
+ expect(modifier.modify(eq('a'), withKey('a'))).andReturn(
+ BstModificationResult.rebuildingChange(a, a2));
+
+ expectPossibleEntryfication(nodeFactory, a2);
+
+ SimpleNode bWithA2 = new SimpleNode('b', a2, null);
+ expect(nodeFactory.createNode(same(b), withKey('a'), (SimpleNode) isNull())).andReturn(
+ bWithA2);
+
+ SimpleNode dWithA2 = new SimpleNode('d', bWithA2, f);
+ expect(nodeFactory.createNode(same(d), same(bWithA2), same(f))).andReturn(
+ dWithA2);
+
+ replay(nodeFactory, balancePolicy, modifier);
+ BstMutationRule<Character, SimpleNode> mutationRule =
+ BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
+ BstMutationResult<Character, SimpleNode> mutationResult =
+ BstOperations.mutate(Ordering.natural(), mutationRule, d, 'a');
+ assertEquals('a', mutationResult.getTargetKey().charValue());
+ assertSame(a, mutationResult.getOriginalTarget());
+ assertEquals('a', mutationResult.getChangedTarget().getKey().charValue());
+ assertSame(d, mutationResult.getOriginalRoot());
+ assertSame(dWithA2, mutationResult.getChangedRoot());
+ assertEquals(ModificationType.REBUILDING_CHANGE, mutationResult.modificationType());
+ verify(nodeFactory, balancePolicy, modifier);
+ }
+
+ @GwtIncompatible("EasyMock")
+ @SuppressWarnings("unchecked")
+ public void testModifyDeletePresentNode() {
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
+ BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
+ BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
+
+ expectPossibleEntryfication(nodeFactory, a);
+ expect(modifier.modify(eq('a'), withKey('a'))).andReturn(
+ BstModificationResult.rebalancingChange(a, null));
+
+ expect(balancePolicy.combine(same(nodeFactory), (SimpleNode) isNull(), (SimpleNode) isNull()))
+ .andReturn(null);
+
+ expectPossibleEntryfication(nodeFactory, b);
+ SimpleNode leafB = new SimpleNode('b', null, null);
+ expect(
+ balancePolicy.balance(same(nodeFactory), withKey('b'), (SimpleNode) isNull(),
+ (SimpleNode) isNull())).andReturn(leafB);
+
+ SimpleNode dWithLeafB = new SimpleNode('d', leafB, f);
+ expectPossibleEntryfication(nodeFactory, d);
+ expect(
+ balancePolicy.balance(same(nodeFactory), withKey('d'), same(leafB), same(f)))
+ .andReturn(dWithLeafB);
+ replay(nodeFactory, balancePolicy, modifier);
+ BstMutationRule<Character, SimpleNode> mutationRule =
+ BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
+ BstMutationResult<Character, SimpleNode> mutationResult =
+ BstOperations.mutate(Ordering.natural(), mutationRule, d, 'a');
+ assertEquals('a', mutationResult.getTargetKey().charValue());
+ assertEquals('a', mutationResult
+ .getOriginalTarget()
+ .getKey()
+ .charValue());
+ assertNull(mutationResult.getChangedTarget());
+ assertSame(d, mutationResult.getOriginalRoot());
+ assertSame(dWithLeafB, mutationResult.getChangedRoot());
+ assertEquals(ModificationType.REBALANCING_CHANGE, mutationResult.modificationType());
+ verify(nodeFactory, balancePolicy, modifier);
+ }
+
+ @GwtIncompatible("EasyMock")
+ @SuppressWarnings("unchecked")
+ public void testModifyDeleteAbsentNode() {
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
+ BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
+ BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
+
+ expectPossibleEntryfication(nodeFactory, a);
+ expect(modifier.modify(eq('c'), (SimpleNode) isNull())).andReturn(
+ BstModificationResult.<SimpleNode> identity(null));
+ replay(nodeFactory, balancePolicy, modifier);
+ BstMutationRule<Character, SimpleNode> mutationRule =
+ BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
+ BstMutationResult<Character, SimpleNode> mutationResult =
+ BstOperations.mutate(Ordering.natural(), mutationRule, d, 'c');
+ assertEquals('c', mutationResult.getTargetKey().charValue());
+ assertEquals(d, mutationResult.getOriginalRoot());
+ assertEquals(d, mutationResult.getChangedRoot());
+ assertNull(mutationResult.getOriginalTarget());
+ assertNull(mutationResult.getChangedTarget());
+ assertEquals(ModificationType.IDENTITY, mutationResult.modificationType());
+ verify(nodeFactory, balancePolicy, modifier);
+ }
+
+ @GwtIncompatible("EasyMock")
+ @SuppressWarnings("unchecked")
+ public void testModifyPathInsertPresentNode() {
+ // We wish to test that BstOperations & co. treat identity-different nodes as changed,
+ // instead of using SimpleNode.equals().
+ // d
+ // / \
+ // b f
+ // / \
+ // a g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
+ BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
+ BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
+
+ expectPossibleEntryfication(nodeFactory, a);
+ expect(modifier.modify(eq('a'), withKey('a'))).andReturn(BstModificationResult.identity(a));
+ replay(nodeFactory, balancePolicy, modifier);
+ BstInOrderPath<SimpleNode> path = extension(pathFactory, d, LEFT, LEFT);
+ BstMutationRule<Character, SimpleNode> mutationRule =
+ BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
+ BstMutationResult<Character, SimpleNode> mutationResult =
+ BstOperations.mutate(path, mutationRule);
+ assertEquals('a', mutationResult.getTargetKey().charValue());
+ assertSame(a, mutationResult.getOriginalTarget());
+ assertSame(a, mutationResult.getChangedTarget());
+ assertSame(d, mutationResult.getOriginalRoot());
+ assertSame(d, mutationResult.getChangedRoot());
+ assertEquals(ModificationType.IDENTITY, mutationResult.modificationType());
+ verify(nodeFactory, balancePolicy, modifier);
+ }
+
+ @GwtIncompatible("EasyMock")
+ private SimpleNode withKey(final char c) {
+ reportMatcher(new IArgumentMatcher() {
+ @Override
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("Expected BstNode with key ").append(c);
+ }
+
+ @Override
+ public boolean matches(Object argument) {
+ return argument instanceof SimpleNode
+ && ((SimpleNode) argument).getKey().charValue() == c;
+ }
+ });
+ return null;
+ }
+
+ /**
+ * The implementation may remove the children of a node it treats as an entry for safety. Expect
+ * this and handle it.
+ */
+ @GwtIncompatible("EasyMock")
+ private void expectPossibleEntryfication(BstNodeFactory<SimpleNode> factory, SimpleNode entry) {
+ expect(factory.createNode(same(entry), (SimpleNode) isNull(), (SimpleNode) isNull()))
+ .andReturn(new SimpleNode(entry.getKey(), null, null))
+ .times(0, 1);
+ }
+ public void testInsertMin1() {
+ // d
+ // / \
+ // b f
+ // \ \
+ // c g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode newRoot = BstOperations.insertMin(d, a, nodeFactory, balancePolicy);
+ assertInOrderTraversalIs(newRoot, "abcdfg");
+ }
+
+ public void testInsertMin2() {
+ // d
+ // / \
+ // b f
+ // \
+ // g
+ SimpleNode b = new SimpleNode('b', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode newRoot = BstOperations.insertMin(d, a, nodeFactory, balancePolicy);
+ assertInOrderTraversalIs(newRoot, "abdfg");
+ }
+
+ public void testInsertMinEmpty() {
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode newRoot = BstOperations.insertMin(null, a, nodeFactory, balancePolicy);
+ assertInOrderTraversalIs(newRoot, "a");
+ }
+
+ public void testInsertMax1() {
+ // d
+ // / \
+ // b f
+ // \ \
+ // c g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ SimpleNode h = new SimpleNode('h', null, null);
+ SimpleNode newRoot = BstOperations.insertMax(d, h, nodeFactory, balancePolicy);
+ assertInOrderTraversalIs(newRoot, "bcdfgh");
+ }
+
+ public void testInsertMax2() {
+ // d
+ // / \
+ // b f
+ // /
+ // e
+ SimpleNode b = new SimpleNode('b', null, null);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode f = new SimpleNode('f', e, null);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ SimpleNode h = new SimpleNode('h', null, null);
+ SimpleNode newRoot = BstOperations.insertMax(d, h, nodeFactory, balancePolicy);
+ assertInOrderTraversalIs(newRoot, "bdefh");
+ }
+
+ public void testInsertMaxEmpty() {
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode newRoot = BstOperations.insertMax(null, a, nodeFactory, balancePolicy);
+ assertInOrderTraversalIs(newRoot, "a");
+ }
+
+ public void testExtractMin1() {
+ // d
+ // / \
+ // b f
+ // \ \
+ // c g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstMutationResult<Character, SimpleNode> extractMin =
+ BstOperations.extractMin(d, nodeFactory, balancePolicy);
+ assertEquals('b', extractMin.getTargetKey().charValue());
+ assertEquals(d, extractMin.getOriginalRoot());
+ assertEquals(b, extractMin.getOriginalTarget());
+ assertNull(extractMin.getChangedTarget());
+ assertInOrderTraversalIs(extractMin.getChangedRoot(), "cdfg");
+ }
+
+ public void testExtractMin2() {
+ // d
+ // / \
+ // b f
+ // \
+ // g
+ SimpleNode b = new SimpleNode('b', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstMutationResult<Character, SimpleNode> extractMin =
+ BstOperations.extractMin(d, nodeFactory, balancePolicy);
+ assertEquals('b', extractMin.getTargetKey().charValue());
+ assertEquals(d, extractMin.getOriginalRoot());
+ assertEquals(b, extractMin.getOriginalTarget());
+ assertNull(extractMin.getChangedTarget());
+ assertInOrderTraversalIs(extractMin.getChangedRoot(), "dfg");
+ }
+
+ public void testExtractMax1() {
+ // d
+ // / \
+ // b f
+ // \ \
+ // c g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', null, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstMutationResult<Character, SimpleNode> extractMax =
+ BstOperations.extractMax(d, nodeFactory, balancePolicy);
+ assertEquals('g', extractMax.getTargetKey().charValue());
+ assertEquals(d, extractMax.getOriginalRoot());
+ assertEquals(g, extractMax.getOriginalTarget());
+ assertNull(extractMax.getChangedTarget());
+ assertInOrderTraversalIs(extractMax.getChangedRoot(), "bcdf");
+ }
+
+ public void testExtractMax2() {
+ // d
+ // / \
+ // b f
+ // /
+ // e
+ SimpleNode b = new SimpleNode('b', null, null);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode f = new SimpleNode('f', e, null);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ BstMutationResult<Character, SimpleNode> extractMax =
+ BstOperations.extractMax(d, nodeFactory, balancePolicy);
+ assertEquals('f', extractMax.getTargetKey().charValue());
+ assertEquals(d, extractMax.getOriginalRoot());
+ assertEquals(f, extractMax.getOriginalTarget());
+ assertNull(extractMax.getChangedTarget());
+ assertInOrderTraversalIs(extractMax.getChangedRoot(), "bde");
+ }
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() throws Exception {
+ defaultNullPointerTester().testAllPublicStaticMethods(BstOperations.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstPathTest.java b/guava-tests/test/com/google/common/collect/BstPathTest.java
new file mode 100644
index 0000000..08c582d
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstPathTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.TestCase;
+
+/**
+ * Simple tests for {@code BstPath}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+public class BstPathTest extends TestCase {
+ static class SimplePath extends BstPath<SimpleNode, SimplePath> {
+ private SimplePath(SimpleNode tip, SimplePath tail) {
+ super(tip, tail);
+ }
+ }
+
+ public void testTailAtRoot() {
+ SimpleNode root = new SimpleNode('a', null, null);
+ SimplePath rootPath = new SimplePath(root, null);
+ assertFalse(rootPath.hasPrefix());
+ assertNull(rootPath.prefixOrNull());
+ try {
+ rootPath.getPrefix();
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testTailDown() {
+ SimpleNode node = new SimpleNode('a', null, null);
+ SimpleNode root = new SimpleNode('b', node, null);
+ SimplePath rootPath = new SimplePath(root, null);
+ SimplePath nodePath = new SimplePath(node, rootPath);
+ assertTrue(nodePath.hasPrefix());
+ assertEquals(rootPath, nodePath.prefixOrNull());
+ assertEquals(rootPath, nodePath.getPrefix());
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstRangeOpsTest.java b/guava-tests/test/com/google/common/collect/BstRangeOpsTest.java
new file mode 100644
index 0000000..d98041a
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstRangeOpsTest.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BoundType.CLOSED;
+import static com.google.common.collect.BoundType.OPEN;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+import static com.google.common.collect.BstTesting.assertInOrderTraversalIs;
+import static com.google.common.collect.BstTesting.balancePolicy;
+import static com.google.common.collect.BstTesting.countAggregate;
+import static com.google.common.collect.BstTesting.defaultNullPointerTester;
+import static com.google.common.collect.BstTesting.nodeFactory;
+import static com.google.common.collect.BstTesting.pathFactory;
+import static com.google.common.collect.BstTesting.pathToList;
+import static org.junit.contrib.truth.Truth.ASSERT;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.BstTesting.SimpleNode;
+
+import junit.framework.TestCase;
+
+import java.util.SortedSet;
+
+/**
+ * Tests for {@code BSTRangeOps}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+public class BstRangeOpsTest extends TestCase {
+ private static final SortedSet<Character> MODEL =
+ ImmutableSortedSet.of('a', 'b', 'c', 'd', 'e', 'f', 'g');
+ private static final SimpleNode ROOT;
+
+ static {
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', a, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+ ROOT = d;
+ }
+
+ public void testCountInRangeLowerBound() {
+ for (char c : "abcdefg".toCharArray()) {
+ for (BoundType type : BoundType.values()) {
+ long count = BstRangeOps.totalInRange(
+ countAggregate, GeneralRange.downTo(Ordering.natural(), c, type), ROOT);
+ char d = c;
+ if (type == BoundType.OPEN) {
+ d++;
+ }
+ assertEquals(MODEL.tailSet(d).size(), count);
+ }
+ }
+ }
+
+ public void testCountInRangeUpperBound() {
+ for (char c : "abcdefg".toCharArray()) {
+ for (BoundType type : BoundType.values()) {
+ long count = BstRangeOps.totalInRange(
+ countAggregate, GeneralRange.upTo(Ordering.natural(), c, type), ROOT);
+ char d = c;
+ if (type == BoundType.CLOSED) {
+ d++;
+ }
+ assertEquals(MODEL.headSet(d).size(), count);
+ }
+ }
+ }
+
+ public void testCountInRangeBothBounds() {
+ String chars = "abcdefg";
+ for (int i = 0; i < chars.length(); i++) {
+ for (BoundType lb : BoundType.values()) {
+ for (int j = i; j < chars.length(); j++) {
+ for (BoundType ub : BoundType.values()) {
+ if (i == j && lb == BoundType.OPEN && ub == BoundType.OPEN) {
+ continue;
+ }
+ long count = BstRangeOps.totalInRange(countAggregate, GeneralRange.range(
+ Ordering.natural(), chars.charAt(i), lb, chars.charAt(j), ub), ROOT);
+ char lo = chars.charAt(i);
+ if (lb == BoundType.OPEN) {
+ lo++;
+ }
+ char hi = chars.charAt(j);
+ if (ub == BoundType.CLOSED) {
+ hi++;
+ }
+ if (lo > hi) {
+ lo = hi;
+ }
+ assertEquals(MODEL.subSet(lo, hi).size(), count);
+ }
+ }
+ }
+ }
+ }
+
+ public void testCountInRangeAll() {
+ assertEquals(MODEL.size(), BstRangeOps.totalInRange(
+ countAggregate, GeneralRange.<Character>all(Ordering.natural()), ROOT));
+ }
+
+ public void testCountInRangeEmpty() {
+ SimpleNode empty = null;
+ GeneralRange<Character> range = GeneralRange.all(Ordering.natural());
+ assertEquals(0, BstRangeOps.totalInRange(countAggregate, range, empty));
+ }
+
+ public void testClearRangeLowerBound() {
+ // d
+ // / \
+ // b f
+ // / / \
+ // a e g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ assertInOrderTraversalIs(d, "abdefg");
+ GeneralRange<Character> range1 = GeneralRange.downTo(Ordering.natural(), 'f', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range1, "abde");
+
+ GeneralRange<Character> range2 = GeneralRange.downTo(Ordering.natural(), 'f', OPEN);
+ testTraversalAfterClearingRangeIs(d, range2, "abdef");
+
+ GeneralRange<Character> range3 = GeneralRange.downTo(Ordering.natural(), 'a', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range3, "");
+
+ GeneralRange<Character> range4 = GeneralRange.downTo(Ordering.natural(), 'a', OPEN);
+ testTraversalAfterClearingRangeIs(d, range4, "a");
+
+ GeneralRange<Character> range5 = GeneralRange.downTo(Ordering.natural(), 'c', OPEN);
+ testTraversalAfterClearingRangeIs(d, range5, "ab");
+
+ GeneralRange<Character> range6 = GeneralRange.downTo(Ordering.natural(), 'c', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range6, "ab");
+ }
+
+ public void testClearRangeUpperBound() {
+ // d
+ // / \
+ // b f
+ // / / \
+ // a e g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode b = new SimpleNode('b', a, null);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ assertInOrderTraversalIs(d, "abdefg");
+ GeneralRange<Character> range1 = GeneralRange.upTo(Ordering.natural(), 'f', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range1, "g");
+
+ GeneralRange<Character> range2 = GeneralRange.upTo(Ordering.natural(), 'f', OPEN);
+ testTraversalAfterClearingRangeIs(d, range2, "fg");
+
+ GeneralRange<Character> range3 = GeneralRange.upTo(Ordering.natural(), 'a', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range3, "bdefg");
+
+ GeneralRange<Character> range4 = GeneralRange.upTo(Ordering.natural(), 'a', OPEN);
+ testTraversalAfterClearingRangeIs(d, range4, "abdefg");
+
+ GeneralRange<Character> range5 = GeneralRange.upTo(Ordering.natural(), 'c', OPEN);
+ testTraversalAfterClearingRangeIs(d, range5, "defg");
+
+ GeneralRange<Character> range6 = GeneralRange.upTo(Ordering.natural(), 'c', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range6, "defg");
+ }
+
+ public void testClearRangeDoublyBounded() {
+ // d
+ // / \
+ // b f
+ // / \ / \
+ // a c e g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', a, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 =
+ GeneralRange.range(Ordering.natural(), 'c', OPEN, 'f', CLOSED);
+ testTraversalAfterClearingRangeIs(d, range1, "abcg");
+
+ GeneralRange<Character> range2 =
+ GeneralRange.range(Ordering.natural(), 'a', CLOSED, 'h', OPEN);
+ testTraversalAfterClearingRangeIs(d, range2, "");
+
+ }
+
+ public void testClearRangeAll() {
+ // d
+ // / \
+ // b f
+ // / \ / \
+ // a c e g
+ SimpleNode a = new SimpleNode('a', null, null);
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', a, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ testTraversalAfterClearingRangeIs(d, GeneralRange.<Character>all(Ordering.natural()), "");
+ }
+
+ private void testTraversalAfterClearingRangeIs(
+ SimpleNode d, GeneralRange<Character> range, String expected) {
+ assertInOrderTraversalIs(
+ BstRangeOps.minusRange(range, balancePolicy, nodeFactory, d), expected);
+ }
+
+ public void testLeftmostPathAll() {
+ // d
+ // / \
+ // b f
+ // \ / \
+ // c e g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 = GeneralRange.all(Ordering.natural());
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, LEFT, pathFactory, d)))
+ .hasContentsInOrder(b, d);
+
+ assertNull(BstRangeOps.furthestPath(range1, LEFT, pathFactory, null));
+ }
+
+ public void testLeftmostPathDownTo() {
+ // d
+ // / \
+ // b f
+ // \ / \
+ // c e g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 = GeneralRange.downTo(Ordering.natural(), 'd', OPEN);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, LEFT, pathFactory, d)))
+ .hasContentsInOrder(e, f, d);
+
+ GeneralRange<Character> range2 = GeneralRange.downTo(Ordering.natural(), 'd', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, LEFT, pathFactory, d)))
+ .hasContentsInOrder(d);
+
+ GeneralRange<Character> range3 = GeneralRange.downTo(Ordering.natural(), 'a', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range3, LEFT, pathFactory, d)))
+ .hasContentsInOrder(b, d);
+
+ GeneralRange<Character> range4 = GeneralRange.downTo(Ordering.natural(), 'h', CLOSED);
+ assertNull(BstRangeOps.furthestPath(range4, LEFT, pathFactory, d));
+ }
+
+ public void testLeftmostPathUpTo() {
+ // d
+ // / \
+ // b f
+ // \ / \
+ // c e g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 = GeneralRange.upTo(Ordering.natural(), 'd', OPEN);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, LEFT, pathFactory, d)))
+ .hasContentsInOrder(b, d);
+
+ GeneralRange<Character> range2 = GeneralRange.upTo(Ordering.natural(), 'd', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, LEFT, pathFactory, d)))
+ .hasContentsInOrder(b, d);
+
+ GeneralRange<Character> range3 = GeneralRange.upTo(Ordering.natural(), 'a', CLOSED);
+ assertNull(BstRangeOps.furthestPath(range3, LEFT, pathFactory, d));
+ }
+
+ public void testRightmostPathAll() {
+ // d
+ // / \
+ // b f
+ // \ / \
+ // c e g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 = GeneralRange.all(Ordering.natural());
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(g, f, d);
+
+ assertNull(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, null));
+ }
+
+ public void testRightmostPathDownTo() {
+ // d
+ // / \
+ // b f
+ // \ / \
+ // c e g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 = GeneralRange.downTo(Ordering.natural(), 'd', OPEN);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(g, f, d);
+
+ GeneralRange<Character> range2 = GeneralRange.downTo(Ordering.natural(), 'd', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(g, f, d);
+
+ GeneralRange<Character> range3 = GeneralRange.downTo(Ordering.natural(), 'a', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range3, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(g, f, d);
+
+ GeneralRange<Character> range4 = GeneralRange.downTo(Ordering.natural(), 'h', CLOSED);
+ assertNull(BstRangeOps.furthestPath(range4, RIGHT, pathFactory, d));
+ }
+
+ public void testRightmostPathUpTo() {
+ // d
+ // / \
+ // b f
+ // \ / \
+ // c e g
+ SimpleNode c = new SimpleNode('c', null, null);
+ SimpleNode b = new SimpleNode('b', null, c);
+ SimpleNode e = new SimpleNode('e', null, null);
+ SimpleNode g = new SimpleNode('g', null, null);
+ SimpleNode f = new SimpleNode('f', e, g);
+ SimpleNode d = new SimpleNode('d', b, f);
+
+ GeneralRange<Character> range1 = GeneralRange.upTo(Ordering.natural(), 'd', OPEN);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(c, b, d);
+
+ GeneralRange<Character> range2 = GeneralRange.upTo(Ordering.natural(), 'd', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(d);
+
+ GeneralRange<Character> range3 = GeneralRange.upTo(Ordering.natural(), 'a', CLOSED);
+ assertNull(BstRangeOps.furthestPath(range3, RIGHT, pathFactory, d));
+
+ GeneralRange<Character> range4 = GeneralRange.upTo(Ordering.natural(), 'h', CLOSED);
+ ASSERT.that(pathToList(BstRangeOps.furthestPath(range4, RIGHT, pathFactory, d)))
+ .hasContentsInOrder(g, f, d);
+ }
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() throws Exception {
+ defaultNullPointerTester().testAllPublicStaticMethods(BstRangeOps.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BstTesting.java b/guava-tests/test/com/google/common/collect/BstTesting.java
new file mode 100644
index 0000000..af929b2
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BstTesting.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+import static junit.framework.Assert.assertEquals;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Objects;
+import com.google.common.testing.NullPointerTester;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * Testing classes and utilities to be used in tests of the binary search tree framework.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+public class BstTesting {
+ static final class SimpleNode extends BstNode<Character, SimpleNode> {
+ SimpleNode(Character key, @Nullable SimpleNode left, @Nullable SimpleNode right) {
+ super(key, left, right);
+ }
+
+ @Override
+ public String toString() {
+ return getKey().toString();
+ }
+
+ @Override
+ public boolean equals(@Nullable Object obj) {
+ if (obj instanceof SimpleNode) {
+ SimpleNode node = (SimpleNode) obj;
+ return getKey().equals(node.getKey())
+ && Objects.equal(childOrNull(LEFT), node.childOrNull(LEFT))
+ && Objects.equal(childOrNull(RIGHT), node.childOrNull(RIGHT));
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(getKey(), childOrNull(LEFT), childOrNull(RIGHT));
+ }
+ }
+
+ static final BstNodeFactory<SimpleNode> nodeFactory = new BstNodeFactory<SimpleNode>() {
+ @Override
+ public SimpleNode createNode(
+ SimpleNode source, @Nullable SimpleNode left, @Nullable SimpleNode right) {
+ return new SimpleNode(source.getKey(), left, right);
+ }
+ };
+
+ static final BstBalancePolicy<SimpleNode> balancePolicy = new BstBalancePolicy<SimpleNode>() {
+ @Override
+ public SimpleNode balance(BstNodeFactory<SimpleNode> nodeFactory, SimpleNode source,
+ @Nullable SimpleNode left, @Nullable SimpleNode right) {
+ return checkNotNull(nodeFactory).createNode(source, left, right);
+ }
+
+ @Nullable
+ @Override
+ public SimpleNode combine(BstNodeFactory<SimpleNode> nodeFactory, @Nullable SimpleNode left,
+ @Nullable SimpleNode right) {
+ // Shove right into the rightmost position in the left tree.
+ if (left == null) {
+ return right;
+ } else if (right == null) {
+ return left;
+ } else if (left.hasChild(RIGHT)) {
+ return nodeFactory.createNode(
+ left, left.childOrNull(LEFT), combine(nodeFactory, left.childOrNull(RIGHT), right));
+ } else {
+ return nodeFactory.createNode(left, left.childOrNull(LEFT), right);
+ }
+ }
+ };
+
+ static final BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> pathFactory =
+ BstInOrderPath.inOrderFactory();
+
+ // A direct, if dumb, way to count total nodes in a tree.
+ static final BstAggregate<SimpleNode> countAggregate = new BstAggregate<SimpleNode>() {
+ @Override
+ public int entryValue(SimpleNode entry) {
+ return 1;
+ }
+
+ @Override
+ public long treeValue(@Nullable SimpleNode tree) {
+ if (tree == null) {
+ return 0;
+ } else {
+ return 1 + treeValue(tree.childOrNull(LEFT)) + treeValue(tree.childOrNull(RIGHT));
+ }
+ }
+ };
+
+ static <P extends BstPath<SimpleNode, P>> List<SimpleNode> pathToList(P path) {
+ List<SimpleNode> list = Lists.newArrayList();
+ for (; path != null; path = path.prefixOrNull()) {
+ list.add(path.getTip());
+ }
+ return list;
+ }
+
+ static <N extends BstNode<?, N>, P extends BstPath<N, P>> P extension(
+ BstPathFactory<N, P> factory, N root, BstSide... sides) {
+ P path = factory.initialPath(root);
+ for (BstSide side : sides) {
+ path = factory.extension(path, side);
+ }
+ return path;
+ }
+
+ static void assertInOrderTraversalIs(@Nullable SimpleNode root, String order) {
+ if (root == null) {
+ assertEquals("", order);
+ } else {
+ BstInOrderPath<SimpleNode> path = pathFactory.initialPath(root);
+ while (path.getTip().hasChild(LEFT)) {
+ path = pathFactory.extension(path, LEFT);
+ }
+ assertEquals(order.charAt(0), path
+ .getTip()
+ .getKey()
+ .charValue());
+ int i;
+ for (i = 1; path.hasNext(RIGHT); i++) {
+ path = path.next(RIGHT);
+ assertEquals(order.charAt(i), path
+ .getTip()
+ .getKey()
+ .charValue());
+ }
+ assertEquals(i, order.length());
+ }
+ }
+
+ @GwtIncompatible("NullPointerTester")
+ static NullPointerTester defaultNullPointerTester() {
+ NullPointerTester tester = new NullPointerTester();
+ SimpleNode node = new SimpleNode('a', null, null);
+ tester.setDefault(BstNode.class, node);
+ tester.setDefault(BstSide.class, LEFT);
+ tester.setDefault(BstNodeFactory.class, nodeFactory);
+ tester.setDefault(BstBalancePolicy.class, balancePolicy);
+ tester.setDefault(BstPathFactory.class, pathFactory);
+ tester.setDefault(BstPath.class, pathFactory.initialPath(node));
+ tester.setDefault(BstInOrderPath.class, pathFactory.initialPath(node));
+ tester.setDefault(Object.class, 'a');
+ tester.setDefault(GeneralRange.class, GeneralRange.all(Ordering.natural()));
+ tester.setDefault(BstAggregate.class, countAggregate);
+ BstModifier<Character, SimpleNode> modifier = new BstModifier<Character, SimpleNode>() {
+ @Nullable
+ @Override
+ public BstModificationResult<SimpleNode> modify(
+ Character key, @Nullable SimpleNode originalEntry) {
+ return BstModificationResult.identity(originalEntry);
+ }
+ };
+ tester.setDefault(
+ BstModificationResult.class, BstModificationResult.<SimpleNode>identity(null));
+ tester.setDefault(BstModifier.class, modifier);
+ tester.setDefault(
+ BstMutationRule.class, BstMutationRule.createRule(modifier, balancePolicy, nodeFactory));
+ return tester;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java b/guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java
deleted file mode 100644
index 5e6473b..0000000
--- a/guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.primitives.Ints;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Package up sample data for common collections benchmarking.
- *
- * @author Nicholaus Shupe
- */
-class CollectionBenchmarkSampleData {
- private final boolean isUserTypeFast;
- private final SpecialRandom random;
- private final double hitRate;
- private final int size;
-
- private final Set<Element> valuesInSet;
- private final Element[] queries;
-
- CollectionBenchmarkSampleData(int size) {
- this(true, new SpecialRandom(), 1.0, size);
- }
-
- CollectionBenchmarkSampleData(
- boolean isUserTypeFast,
- SpecialRandom random,
- double hitRate,
- int size) {
- this.isUserTypeFast = isUserTypeFast;
- this.random = checkNotNull(random);
- this.hitRate = hitRate;
- this.size = size;
-
- this.valuesInSet = createData();
- this.queries = createQueries(valuesInSet, 1024);
- }
-
- Set<Element> getValuesInSet() {
- return valuesInSet;
- }
-
- Element[] getQueries() {
- return queries;
- }
-
- private Element[] createQueries(Set<Element> elementsInSet, int numQueries) {
- List<Element> queryList = Lists.newArrayListWithCapacity(numQueries);
-
- int numGoodQueries = (int) (numQueries * hitRate + 0.5);
-
- // add good queries
- int size = elementsInSet.size();
- if (size > 0) {
- int minCopiesOfEachGoodQuery = numGoodQueries / size;
- int extras = numGoodQueries % size;
-
- for (int i = 0; i < minCopiesOfEachGoodQuery; i++) {
- queryList.addAll(elementsInSet);
- }
- List<Element> tmp = Lists.newArrayList(elementsInSet);
- Collections.shuffle(tmp, random);
- queryList.addAll(tmp.subList(0, extras));
- }
-
- // now add bad queries
- while (queryList.size() < numQueries) {
- Element candidate = newElement();
- if (!elementsInSet.contains(candidate)) {
- queryList.add(candidate);
- }
- }
- Collections.shuffle(queryList, random);
- return queryList.toArray(new Element[0]);
- }
-
- private Set<Element> createData() {
- Set<Element> set = Sets.newHashSetWithExpectedSize(size);
- while (set.size() < size) {
- set.add(newElement());
- }
- return set;
- }
-
- private Element newElement() {
- int value = random.nextInt();
- return isUserTypeFast
- ? new Element(value)
- : new SlowElement(value);
- }
-
- static class Element implements Comparable<Element> {
- final int hash;
- Element(int hash) {
- this.hash = hash;
- }
- @Override public boolean equals(Object obj) {
- return this == obj
- || (obj instanceof Element && ((Element) obj).hash == hash);
- }
- @Override public int hashCode() {
- return hash;
- }
- @Override
- public int compareTo(Element that) {
- return Ints.compare(hash, that.hash);
- }
- @Override public String toString() {
- return String.valueOf(hash);
- }
- }
-
- static class SlowElement extends Element {
- SlowElement(int hash) {
- super(hash);
- }
- @Override public boolean equals(Object obj) {
- return slowItDown() != 1 && super.equals(obj);
- }
- @Override public int hashCode() {
- return slowItDown() + hash;
- }
- @Override public int compareTo(Element e) {
- int x = slowItDown();
- return x + super.compareTo(e) - x; // silly attempt to prevent opt
- }
- static int slowItDown() {
- int result = 0;
- for (int i = 1; i <= 1000; i++) {
- result += i;
- }
- return result;
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/Collections2Test.java b/guava-tests/test/com/google/common/collect/Collections2Test.java
index d9763da..e17cd05 100644
--- a/guava-tests/test/com/google/common/collect/Collections2Test.java
+++ b/guava-tests/test/com/google/common/collect/Collections2Test.java
@@ -16,13 +16,11 @@
package com.google.common.collect;
-import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newLinkedList;
import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod;
import static java.util.Arrays.asList;
-import static java.util.Collections.nCopies;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -40,9 +38,7 @@ import junit.framework.TestSuite;
import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
-import java.util.NoSuchElementException;
/**
* Tests for {@link Collections2}.
@@ -196,6 +192,140 @@ public class Collections2Test extends TestCase {
.createTestSuite();
}
+ public abstract static class FilterChangeTest extends TestCase {
+ protected abstract <E> List<E> newList();
+
+ public void testFilterIllegalAdd() {
+ List<String> unfiltered = newList();
+ Collection<String> filtered
+ = Collections2.filter(unfiltered, NOT_YYY_ZZZ);
+ filtered.add("a");
+ filtered.add("b");
+ ASSERT.that(filtered).hasContentsInOrder("a", "b");
+
+ try {
+ filtered.add("yyy");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ filtered.addAll(asList("c", "zzz", "d"));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+
+ ASSERT.that(filtered).hasContentsInOrder("a", "b");
+ }
+
+ public void testFilterChangeUnfiltered() {
+ List<String> unfiltered = newList();
+ Collection<String> filtered
+ = Collections2.filter(unfiltered, NOT_YYY_ZZZ);
+
+ unfiltered.add("a");
+ unfiltered.add("yyy");
+ unfiltered.add("b");
+ ASSERT.that(unfiltered).hasContentsInOrder("a", "yyy", "b");
+ ASSERT.that(filtered).hasContentsInOrder("a", "b");
+
+ unfiltered.remove("a");
+ ASSERT.that(unfiltered).hasContentsInOrder("yyy", "b");
+ ASSERT.that(filtered).hasContentsInOrder("b");
+
+ unfiltered.clear();
+ ASSERT.that(unfiltered).isEmpty();
+ ASSERT.that(filtered).isEmpty();
+
+ unfiltered.add("yyy");
+ ASSERT.that(unfiltered).hasContentsInOrder("yyy");
+ ASSERT.that(filtered).isEmpty();
+ filtered.clear();
+ ASSERT.that(unfiltered).hasContentsInOrder("yyy");
+ ASSERT.that(filtered).isEmpty();
+
+ unfiltered.clear();
+ filtered.clear();
+ ASSERT.that(unfiltered).isEmpty();
+ ASSERT.that(filtered).isEmpty();
+
+ unfiltered.add("a");
+ ASSERT.that(unfiltered).hasContentsInOrder("a");
+ ASSERT.that(filtered).hasContentsInOrder("a");
+ filtered.clear();
+ ASSERT.that(unfiltered).isEmpty();
+ ASSERT.that(filtered).isEmpty();
+
+ unfiltered.clear();
+ Collections.addAll(unfiltered,
+ "a", "b", "yyy", "zzz", "c", "d", "yyy", "zzz");
+ ASSERT.that(unfiltered).hasContentsInOrder(
+ "a", "b", "yyy", "zzz", "c", "d", "yyy", "zzz");
+ ASSERT.that(filtered).hasContentsInOrder("a", "b", "c", "d");
+ filtered.clear();
+ ASSERT.that(unfiltered).hasContentsInOrder("yyy", "zzz", "yyy", "zzz");
+ ASSERT.that(filtered).isEmpty();
+ }
+
+ public void testFilterChangeFiltered() {
+ List<String> unfiltered = newList();
+ Collection<String> filtered
+ = Collections2.filter(unfiltered, NOT_YYY_ZZZ);
+
+ unfiltered.add("a");
+ unfiltered.add("yyy");
+ filtered.add("b");
+ ASSERT.that(unfiltered).hasContentsInOrder("a", "yyy", "b");
+ ASSERT.that(filtered).hasContentsInOrder("a", "b");
+
+ filtered.remove("a");
+ ASSERT.that(unfiltered).hasContentsInOrder("yyy", "b");
+ ASSERT.that(filtered).hasContentsInOrder("b");
+
+ filtered.clear();
+ ASSERT.that(unfiltered).hasContentsInOrder("yyy");
+ ASSERT.that(filtered);
+ }
+
+ public void testFilterFiltered() {
+ List<String> unfiltered = newList();
+ Collection<String> filtered = Collections2.filter(
+ Collections2.filter(unfiltered, LENGTH_1), STARTS_WITH_VOWEL);
+ unfiltered.add("a");
+ unfiltered.add("b");
+ unfiltered.add("apple");
+ unfiltered.add("banana");
+ unfiltered.add("e");
+ ASSERT.that(filtered).hasContentsInOrder("a", "e");
+ ASSERT.that(unfiltered).hasContentsInOrder("a", "b", "apple", "banana", "e");
+
+ try {
+ filtered.add("d");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ filtered.add("egg");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ ASSERT.that(filtered).hasContentsInOrder("a", "e");
+ ASSERT.that(unfiltered).hasContentsInOrder("a", "b", "apple", "banana", "e");
+
+ filtered.clear();
+ ASSERT.that(filtered).isEmpty();
+ ASSERT.that(unfiltered).hasContentsInOrder("b", "apple", "banana");
+ }
+ }
+
+ public static class ArrayListFilterChangeTest extends FilterChangeTest {
+ @Override protected <E> List<E> newList() {
+ return Lists.newArrayList();
+ }
+ }
+
+ public static class LinkedListFilterChangeTest extends FilterChangeTest {
+ @Override protected <E> List<E> newList() {
+ return Lists.newLinkedList();
+ }
+ }
+
private static final Function<String, String> REMOVE_FIRST_CHAR
= new Function<String, String>() {
@Override
@@ -219,7 +349,7 @@ public class Collections2Test extends TestCase {
})
.named("Collections2.transform")
.withFeatures(
- CollectionFeature.SUPPORTS_REMOVE,
+ CollectionFeature.REMOVE_OPERATIONS,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER,
CollectionSize.ANY)
@@ -227,277 +357,8 @@ public class Collections2Test extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Collections2.class);
}
-
- public void testOrderedPermutationSetEmpty() {
- List<Integer> list = newArrayList();
- Collection<List<Integer>> permutationSet =
- Collections2.orderedPermutations(list);
-
- assertEquals(1, permutationSet.size());
- ASSERT.that(permutationSet).has().item(list);
-
- Iterator<List<Integer>> permutations = permutationSet.iterator();
-
- assertNextPermutation(Lists.<Integer>newArrayList(), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testOrderedPermutationSetOneElement() {
- List<Integer> list = newArrayList(1);
- Iterator<List<Integer>> permutations =
- Collections2.orderedPermutations(list).iterator();
-
- assertNextPermutation(newArrayList(1), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testOrderedPermutationSetThreeElements() {
- List<String> list = newArrayList("b", "a", "c");
- Iterator<List<String>> permutations =
- Collections2.orderedPermutations(list).iterator();
-
- assertNextPermutation(newArrayList("a", "b", "c"), permutations);
- assertNextPermutation(newArrayList("a", "c", "b"), permutations);
- assertNextPermutation(newArrayList("b", "a", "c"), permutations);
- assertNextPermutation(newArrayList("b", "c", "a"), permutations);
- assertNextPermutation(newArrayList("c", "a", "b"), permutations);
- assertNextPermutation(newArrayList("c", "b", "a"), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testOrderedPermutationSetRepeatedElements() {
- List<Integer> list = newArrayList(1, 1, 2, 2);
- Iterator<List<Integer>> permutations =
- Collections2.orderedPermutations(list, Ordering.natural()).iterator();
-
- assertNextPermutation(newArrayList(1, 1, 2, 2), permutations);
- assertNextPermutation(newArrayList(1, 2, 1, 2), permutations);
- assertNextPermutation(newArrayList(1, 2, 2, 1), permutations);
- assertNextPermutation(newArrayList(2, 1, 1, 2), permutations);
- assertNextPermutation(newArrayList(2, 1, 2, 1), permutations);
- assertNextPermutation(newArrayList(2, 2, 1, 1), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testOrderedPermutationSetRepeatedElementsSize() {
- List<Integer> list = newArrayList(1, 1, 1, 1, 2, 2, 3);
- Collection<List<Integer>> permutations =
- Collections2.orderedPermutations(list, Ordering.natural());
-
- assertPermutationsCount(105, permutations);
- }
-
- public void testOrderedPermutationSetSizeOverflow() {
- // 12 elements won't overflow
- assertEquals(479001600 /*12!*/, Collections2.orderedPermutations(
- newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)).size());
- // 13 elements overflow an int
- assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
- newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size());
- // 21 elements overflow a long
- assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
- newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21)).size());
-
- // Almost force an overflow in the binomial coefficient calculation
- assertEquals(1391975640 /*C(34,14)*/, Collections2.orderedPermutations(
- concat(nCopies(20, 1), nCopies(14, 2))).size());
- // Do force an overflow in the binomial coefficient calculation
- assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
- concat(nCopies(21, 1), nCopies(14, 2))).size());
- }
-
- public void testOrderedPermutationSetContains() {
- List<Integer> list = newArrayList(3, 2, 1);
- Collection<List<Integer>> permutationSet =
- Collections2.orderedPermutations(list);
-
- assertTrue(permutationSet.contains(newArrayList(1, 2, 3)));
- assertTrue(permutationSet.contains(newArrayList(2, 3, 1)));
- assertFalse(permutationSet.contains(newArrayList(1, 2)));
- assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3)));
- assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4)));
- assertFalse(permutationSet.contains(null));
- }
-
- public void testPermutationSetEmpty() {
- Collection<List<Integer>> permutationSet =
- Collections2.permutations(Collections.<Integer>emptyList());
-
- assertEquals(1, permutationSet.size());
- assertTrue(permutationSet.contains(Collections.<Integer> emptyList()));
-
- Iterator<List<Integer>> permutations = permutationSet.iterator();
- assertNextPermutation(Collections.<Integer> emptyList(), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetOneElement() {
- Iterator<List<Integer>> permutations =
- Collections2.permutations(Collections.<Integer> singletonList(1))
- .iterator();
- assertNextPermutation(newArrayList(1), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetTwoElements() {
- Iterator<List<Integer>> permutations = Collections2.permutations(
- newArrayList(1, 2)).iterator();
- assertNextPermutation(newArrayList(1, 2), permutations);
- assertNextPermutation(newArrayList(2, 1), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetThreeElements() {
- Iterator<List<Integer>> permutations = Collections2.permutations(
- newArrayList(1, 2, 3)).iterator();
- assertNextPermutation(newArrayList(1, 2, 3), permutations);
- assertNextPermutation(newArrayList(1, 3, 2), permutations);
- assertNextPermutation(newArrayList(3, 1, 2), permutations);
-
- assertNextPermutation(newArrayList(3, 2, 1), permutations);
- assertNextPermutation(newArrayList(2, 3, 1), permutations);
- assertNextPermutation(newArrayList(2, 1, 3), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetThreeElementsOutOfOrder() {
- Iterator<List<Integer>> permutations = Collections2.permutations(
- newArrayList(3, 2, 1)).iterator();
- assertNextPermutation(newArrayList(3, 2, 1), permutations);
- assertNextPermutation(newArrayList(3, 1, 2), permutations);
- assertNextPermutation(newArrayList(1, 3, 2), permutations);
-
- assertNextPermutation(newArrayList(1, 2, 3), permutations);
- assertNextPermutation(newArrayList(2, 1, 3), permutations);
- assertNextPermutation(newArrayList(2, 3, 1), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetThreeRepeatedElements() {
- Iterator<List<Integer>> permutations = Collections2.permutations(
- newArrayList(1, 1, 2)).iterator();
- assertNextPermutation(newArrayList(1, 1, 2), permutations);
- assertNextPermutation(newArrayList(1, 2, 1), permutations);
- assertNextPermutation(newArrayList(2, 1, 1), permutations);
- assertNextPermutation(newArrayList(2, 1, 1), permutations);
- assertNextPermutation(newArrayList(1, 2, 1), permutations);
- assertNextPermutation(newArrayList(1, 1, 2), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetFourElements() {
- Iterator<List<Integer>> permutations = Collections2.permutations(
- newArrayList(1, 2, 3, 4)).iterator();
- assertNextPermutation(newArrayList(1, 2, 3, 4), permutations);
- assertNextPermutation(newArrayList(1, 2, 4, 3), permutations);
- assertNextPermutation(newArrayList(1, 4, 2, 3), permutations);
- assertNextPermutation(newArrayList(4, 1, 2, 3), permutations);
-
- assertNextPermutation(newArrayList(4, 1, 3, 2), permutations);
- assertNextPermutation(newArrayList(1, 4, 3, 2), permutations);
- assertNextPermutation(newArrayList(1, 3, 4, 2), permutations);
- assertNextPermutation(newArrayList(1, 3, 2, 4), permutations);
-
- assertNextPermutation(newArrayList(3, 1, 2, 4), permutations);
- assertNextPermutation(newArrayList(3, 1, 4, 2), permutations);
- assertNextPermutation(newArrayList(3, 4, 1, 2), permutations);
- assertNextPermutation(newArrayList(4, 3, 1, 2), permutations);
-
- assertNextPermutation(newArrayList(4, 3, 2, 1), permutations);
- assertNextPermutation(newArrayList(3, 4, 2, 1), permutations);
- assertNextPermutation(newArrayList(3, 2, 4, 1), permutations);
- assertNextPermutation(newArrayList(3, 2, 1, 4), permutations);
-
- assertNextPermutation(newArrayList(2, 3, 1, 4), permutations);
- assertNextPermutation(newArrayList(2, 3, 4, 1), permutations);
- assertNextPermutation(newArrayList(2, 4, 3, 1), permutations);
- assertNextPermutation(newArrayList(4, 2, 3, 1), permutations);
-
- assertNextPermutation(newArrayList(4, 2, 1, 3), permutations);
- assertNextPermutation(newArrayList(2, 4, 1, 3), permutations);
- assertNextPermutation(newArrayList(2, 1, 4, 3), permutations);
- assertNextPermutation(newArrayList(2, 1, 3, 4), permutations);
- assertNoMorePermutations(permutations);
- }
-
- public void testPermutationSetSize() {
- assertPermutationsCount(1,
- Collections2.permutations(Collections.<Integer>emptyList()));
- assertPermutationsCount(1, Collections2.permutations(newArrayList(1)));
- assertPermutationsCount(2, Collections2.permutations(newArrayList(1, 2)));
- assertPermutationsCount(6,
- Collections2.permutations(newArrayList(1, 2, 3)));
- assertPermutationsCount(5040,
- Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7)));
- assertPermutationsCount(40320,
- Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8)));
- }
-
- public void testPermutationSetSizeOverflow() {
- // 13 elements overflow an int
- assertEquals(Integer.MAX_VALUE, Collections2.permutations(newArrayList(
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size());
- // 21 elements overflow a long
- assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
- newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20)).size());
- assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
- newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21)).size());
- }
-
- public void testPermutationSetContains() {
- List<Integer> list = newArrayList(3, 2, 1);
- Collection<List<Integer>> permutationSet =
- Collections2.permutations(list);
-
- assertTrue(permutationSet.contains(newArrayList(1, 2, 3)));
- assertTrue(permutationSet.contains(newArrayList(2, 3, 1)));
- assertFalse(permutationSet.contains(newArrayList(1, 2)));
- assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3)));
- assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4)));
- assertFalse(permutationSet.contains(null));
- }
-
- private <T> void assertNextPermutation(List<T> expectedPermutation,
- Iterator<List<T>> permutations) {
- assertTrue("Expected another permutation, but there was none.",
- permutations.hasNext());
- assertEquals(expectedPermutation, permutations.next());
- }
-
- private <T> void assertNoMorePermutations(
- Iterator<List<T>> permutations) {
- assertFalse("Expected no more permutations, but there was one.",
- permutations.hasNext());
- try {
- permutations.next();
- fail("Expected NoSuchElementException.");
- } catch (NoSuchElementException expected) {}
- }
-
- private <T> void assertPermutationsCount(int expected,
- Collection<List<T>> permutationSet) {
- assertEquals(expected, permutationSet.size());
- Iterator<List<T>> permutations = permutationSet.iterator();
- for (int i = 0; i < expected; i++) {
- assertTrue(permutations.hasNext());
- permutations.next();
- }
- assertNoMorePermutations(permutations);
- }
-
- public void testToStringImplWithNullEntries() throws Exception {
- List<String> list = Lists.newArrayList();
- list.add("foo");
- list.add(null);
-
- assertEquals(list.toString(), Collections2.toStringImpl(list));
- }
-
}
diff --git a/guava-tests/test/com/google/common/collect/ComparisonChainTest.java b/guava-tests/test/com/google/common/collect/ComparisonChainTest.java
index 0a75056..c0ddcd5 100644
--- a/guava-tests/test/com/google/common/collect/ComparisonChainTest.java
+++ b/guava-tests/test/com/google/common/collect/ComparisonChainTest.java
@@ -58,7 +58,7 @@ public class ComparisonChainTest extends TestCase {
assertEquals(0, ComparisonChain.start()
.compare(1, 1)
.compare(1L, 1L)
- .compareFalseFirst(true, true)
+ .compare(true, true)
.compare(1.0, 1.0)
.compare(1.0f, 1.0f)
.compare("a", "a", Ordering.usingToString())
@@ -86,26 +86,4 @@ public class ComparisonChainTest extends TestCase {
.compare(DONT_COMPARE_ME, DONT_COMPARE_ME)
.result() < 0);
}
-
- public void testCompareFalseFirst() {
- assertTrue(ComparisonChain.start().compareFalseFirst(true, true).result() == 0);
- assertTrue(ComparisonChain.start().compareFalseFirst(true, false).result() > 0);
- assertTrue(ComparisonChain.start().compareFalseFirst(false, true).result() < 0);
- assertTrue(ComparisonChain.start().compareFalseFirst(false, false).result() == 0);
- }
-
- public void testCompareTrueFirst() {
- assertTrue(ComparisonChain.start().compareTrueFirst(true, true).result() == 0);
- assertTrue(ComparisonChain.start().compareTrueFirst(true, false).result() < 0);
- assertTrue(ComparisonChain.start().compareTrueFirst(false, true).result() > 0);
- assertTrue(ComparisonChain.start().compareTrueFirst(false, false).result() == 0);
- }
-
- @SuppressWarnings("deprecation") // test of a deprecated method
- public void testCompareBooleans() {
- assertTrue(ComparisonChain.start().compare(true, true).result() == 0);
- assertTrue(ComparisonChain.start().compare(true, false).result() > 0);
- assertTrue(ComparisonChain.start().compare(false, true).result() < 0);
- assertTrue(ComparisonChain.start().compare(false, false).result() == 0);
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java b/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
index dba499c..8a96b62 100644
--- a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import static com.google.common.collect.MapMakerInternalMap.Strength.SOFT;
import static com.google.common.collect.MapMakerInternalMap.Strength.STRONG;
import static com.google.common.collect.MapMakerInternalMap.Strength.WEAK;
import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_REMOVE;
@@ -25,19 +26,13 @@ import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
-import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.collect.MapMaker.RemovalListener;
import com.google.common.collect.MapMaker.RemovalNotification;
import com.google.common.collect.Multiset.Entry;
import com.google.common.collect.testing.IteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringMultisetGenerator;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import org.easymock.EasyMock;
@@ -54,28 +49,6 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author mike nonemacher
*/
public class ConcurrentHashMultisetTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(MultisetTestSuiteBuilder.using(concurrentMultisetGenerator())
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ConcurrentHashMultiset")
- .createTestSuite());
- suite.addTestSuite(ConcurrentHashMultisetTest.class);
- return suite;
- }
-
- private static TestStringMultisetGenerator concurrentMultisetGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return ConcurrentHashMultiset.create(asList(elements));
- }
- };
- }
-
private static final String KEY = "puppies";
ConcurrentMap<String, AtomicInteger> backingMap;
@@ -370,6 +343,10 @@ public class ConcurrentHashMultisetTest extends TestCase {
public void testIdentityKeyEquality_strongKeys() {
testIdentityKeyEquality(STRONG);
}
+
+ public void testIdentityKeyEquality_softKeys() {
+ testIdentityKeyEquality(SOFT);
+ }
public void testIdentityKeyEquality_weakKeys() {
testIdentityKeyEquality(WEAK);
@@ -380,7 +357,7 @@ public class ConcurrentHashMultisetTest extends TestCase {
MapMaker mapMaker = new MapMaker()
.setKeyStrength(keyStrength)
- .keyEquivalence(Equivalence.identity());
+ .keyEquivalence(Equivalences.identity());
ConcurrentHashMultiset<String> multiset =
ConcurrentHashMultiset.create(mapMaker);
@@ -410,6 +387,10 @@ public class ConcurrentHashMultisetTest extends TestCase {
testLogicalKeyEquality(STRONG);
}
+ public void testLogicalKeyEquality_softKeys() {
+ testLogicalKeyEquality(SOFT);
+ }
+
public void testLogicalKeyEquality_weakKeys() {
testLogicalKeyEquality(WEAK);
}
@@ -419,7 +400,7 @@ public class ConcurrentHashMultisetTest extends TestCase {
MapMaker mapMaker = new MapMaker()
.setKeyStrength(keyStrength)
- .keyEquivalence(Equivalence.equals());
+ .keyEquivalence(Equivalences.equals());
ConcurrentHashMultiset<String> multiset =
ConcurrentHashMultiset.create(mapMaker);
@@ -465,7 +446,7 @@ public class ConcurrentHashMultisetTest extends TestCase {
public void testSerializationWithMapMaker_preservesIdentityKeyEquivalence() {
MapMaker mapMaker = new MapMaker()
- .keyEquivalence(Equivalence.identity());
+ .keyEquivalence(Equivalences.identity());
ConcurrentHashMultiset<String> multiset =
ConcurrentHashMultiset.create(mapMaker);
diff --git a/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java b/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java
index cb22217..4f02c13 100644
--- a/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java
@@ -16,106 +16,28 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.MapConstraintsTest.TestKeyException;
import com.google.common.collect.MapConstraintsTest.TestValueException;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringBiMapGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Map.Entry;
/**
* Tests for {@link MapConstraints#constrainedBiMap}.
*
* @author Jared Levy
- * @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
-public class ConstrainedBiMapTest extends TestCase {
+public class ConstrainedBiMapTest extends AbstractBiMapTest {
- private static final String TEST_KEY = "42";
+ private static final Integer TEST_KEY = 42;
private static final String TEST_VALUE = "test";
- private static final MapConstraint<String, String> TEST_CONSTRAINT = new TestConstraint();
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(BiMapTestSuiteBuilder
- .using(new ConstrainedBiMapGenerator())
- .named("Maps.constrainedBiMap[HashBiMap]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION)
- .createTestSuite());
- suite.addTestSuite(ConstrainedBiMapTest.class);
- return suite;
- }
-
- public void testPutWithForbiddenKeyForbiddenValue() {
- BiMap<String, String> map = MapConstraints.constrainedBiMap(
- HashBiMap.<String, String> create(),
- TEST_CONSTRAINT);
- try {
- map.put(TEST_KEY, TEST_VALUE);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- }
-
- public void testPutWithForbiddenKeyAllowedValue() {
- BiMap<String, String> map = MapConstraints.constrainedBiMap(
- HashBiMap.<String, String> create(),
- TEST_CONSTRAINT);
- try {
- map.put(TEST_KEY, "allowed");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- }
+ private static final MapConstraint<Integer, String> TEST_CONSTRAINT
+ = new TestConstraint();
- public void testPutWithAllowedKeyForbiddenValue() {
- BiMap<String, String> map = MapConstraints.constrainedBiMap(
- HashBiMap.<String, String> create(),
- TEST_CONSTRAINT);
- try {
- map.put("allowed", TEST_VALUE);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- }
-
- public static final class ConstrainedBiMapGenerator extends TestStringBiMapGenerator {
+ private static final class TestConstraint
+ implements MapConstraint<Integer, String> {
@Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> bimap = MapConstraints.constrainedBiMap(
- HashBiMap.<String, String> create(),
- TEST_CONSTRAINT);
- for (Entry<String, String> entry : entries) {
- checkArgument(!bimap.containsKey(entry.getKey()));
- bimap.put(entry.getKey(), entry.getValue());
- }
- return bimap;
- }
- }
-
- private static final class TestConstraint implements MapConstraint<String, String> {
- @Override
- public void checkKeyValue(String key, String value) {
+ public void checkKeyValue(Integer key, String value) {
if (TEST_KEY.equals(key)) {
throw new TestKeyException();
}
@@ -123,7 +45,24 @@ public class ConstrainedBiMapTest extends TestCase {
throw new TestValueException();
}
}
-
private static final long serialVersionUID = 0;
}
+
+ @Override protected BiMap<Integer, String> create() {
+ return MapConstraints.constrainedBiMap(
+ HashBiMap.<Integer, String>create(), TEST_CONSTRAINT);
+ }
+
+ // not serializable
+ @GwtIncompatible("SerializableTester")
+ @Override
+ public void testSerialization() {}
+
+ @GwtIncompatible("SerializableTester")
+ @Override
+ public void testSerializationWithInverseEqual() {}
+
+ @GwtIncompatible("SerializableTester")
+ @Override
+ public void testSerializationWithInverseSame() {}
}
diff --git a/guava-tests/test/com/google/common/collect/ConstraintsTest.java b/guava-tests/test/com/google/common/collect/ConstraintsTest.java
index b7b6dbb..64dbc8a 100644
--- a/guava-tests/test/com/google/common/collect/ConstraintsTest.java
+++ b/guava-tests/test/com/google/common/collect/ConstraintsTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -80,9 +80,8 @@ public class ConstraintsTest extends TestCase {
constrained.add("qux");
constrained.addAll(asList("cat", "dog"));
/* equals and hashCode aren't defined for Collection */
- ASSERT.that(collection).has().allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
- ASSERT.that(constrained).has()
- .allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
+ ASSERT.that(collection).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(constrained).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
}
public void testConstrainedCollectionIllegal() {
@@ -97,8 +96,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).has().allOf("foo", "bar").inOrder();
- ASSERT.that(collection).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(constrained).hasContentsInOrder("foo", "bar");
+ ASSERT.that(collection).hasContentsInOrder("foo", "bar");
}
public void testConstrainedSetLegal() {
@@ -111,9 +110,8 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(set));
assertEquals(set.toString(), constrained.toString());
assertEquals(set.hashCode(), constrained.hashCode());
- ASSERT.that(set).has().allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
- ASSERT.that(constrained).has()
- .allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
+ ASSERT.that(set).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(constrained).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
}
public void testConstrainedSetIllegal() {
@@ -127,8 +125,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).has().allOf("foo", "bar").inOrder();
- ASSERT.that(set).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(constrained).hasContentsInOrder("foo", "bar");
+ ASSERT.that(set).hasContentsInOrder("foo", "bar");
}
public void testConstrainedSortedSetLegal() {
@@ -142,9 +140,8 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(sortedSet));
assertEquals(sortedSet.toString(), constrained.toString());
assertEquals(sortedSet.hashCode(), constrained.hashCode());
- ASSERT.that(sortedSet).has().allOf("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder();
- ASSERT.that(constrained).has()
- .allOf("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder();
+ ASSERT.that(sortedSet).hasContentsInOrder("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT);
+ ASSERT.that(constrained).hasContentsInOrder("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT);
assertNull(constrained.comparator());
assertEquals("bar", constrained.first());
assertEquals(TEST_ELEMENT, constrained.last());
@@ -174,8 +171,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).has().allOf("bar", "foo").inOrder();
- ASSERT.that(sortedSet).has().allOf("bar", "foo").inOrder();
+ ASSERT.that(constrained).hasContentsInOrder("bar", "foo");
+ ASSERT.that(sortedSet).hasContentsInOrder("bar", "foo");
}
public void testConstrainedListLegal() {
@@ -192,18 +189,18 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(list));
assertEquals(list.toString(), constrained.toString());
assertEquals(list.hashCode(), constrained.hashCode());
- ASSERT.that(list).has().allOf(
- "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
- ASSERT.that(constrained).has().allOf(
- "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
+ ASSERT.that(list).hasContentsInOrder(
+ "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
+ ASSERT.that(constrained).hasContentsInOrder(
+ "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
ListIterator<String> iterator = constrained.listIterator();
iterator.next();
iterator.set("sun");
constrained.listIterator(2).add("sky");
- ASSERT.that(list).has().allOf(
- "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
- ASSERT.that(constrained).has().allOf(
- "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
+ ASSERT.that(list).hasContentsInOrder(
+ "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
+ ASSERT.that(constrained).hasContentsInOrder(
+ "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
assertTrue(constrained instanceof RandomAccess);
}
@@ -260,8 +257,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(1, asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).has().allOf("foo", "bar").inOrder();
- ASSERT.that(list).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(constrained).hasContentsInOrder("foo", "bar");
+ ASSERT.that(list).hasContentsInOrder("foo", "bar");
}
public void testConstrainedMultisetLegal() {
@@ -276,15 +273,15 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(multiset));
assertEquals(multiset.toString(), constrained.toString());
assertEquals(multiset.hashCode(), constrained.hashCode());
- ASSERT.that(multiset).has().allOf(
+ ASSERT.that(multiset).hasContentsAnyOrder(
"foo", "bar", TEST_ELEMENT, "qux", "cat", "dog", "cow", "cow");
- ASSERT.that(constrained).has().allOf(
+ ASSERT.that(constrained).hasContentsAnyOrder(
"foo", "bar", TEST_ELEMENT, "qux", "cat", "dog", "cow", "cow");
assertEquals(1, constrained.count("foo"));
assertEquals(1, constrained.remove("foo", 3));
assertEquals(2, constrained.setCount("cow", 0));
- ASSERT.that(multiset).has().allOf("bar", TEST_ELEMENT, "qux", "cat", "dog");
- ASSERT.that(constrained).has().allOf("bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(multiset).hasContentsAnyOrder("bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(constrained).hasContentsAnyOrder("bar", TEST_ELEMENT, "qux", "cat", "dog");
}
public void testConstrainedMultisetIllegal() {
@@ -303,8 +300,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).has().allOf("foo", "bar");
- ASSERT.that(multiset).has().allOf("foo", "bar");
+ ASSERT.that(constrained).hasContentsAnyOrder("foo", "bar");
+ ASSERT.that(multiset).hasContentsAnyOrder("foo", "bar");
}
public void testNefariousAddAll() {
@@ -313,8 +310,8 @@ public class ConstraintsTest extends TestCase {
list, TEST_CONSTRAINT);
Collection<String> onceIterable = onceIterableCollection("baz");
constrained.addAll(onceIterable);
- ASSERT.that(constrained).has().allOf("foo", "bar", "baz").inOrder();
- ASSERT.that(list).has().allOf("foo", "bar", "baz").inOrder();
+ ASSERT.that(constrained).hasContentsInOrder("foo", "bar", "baz");
+ ASSERT.that(list).hasContentsInOrder("foo", "bar", "baz");
}
/**
diff --git a/guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java b/guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java
new file mode 100644
index 0000000..d36e471
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.DiscreteDomains.integers;
+
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.testers.SetHashCodeTester;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @author Gregory Kick
+ */
+public class ContiguousSetNonGwtTest extends TestCase {
+ public static class BuiltTests extends TestCase {
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(
+ SetTestSuiteBuilder
+ .using(
+ new TestIntegerSetGenerator() {
+ @Override
+ protected Set<Integer> create(Integer[] elements) {
+ // reject duplicates at creation, just so that I can use
+ // that SetFeature below, which stops a test from running
+ // that doesn't work. hack!
+ SortedSet<Integer> set = new TreeSet<Integer>();
+ Collections.addAll(set, elements);
+ checkArgument(set.size() == elements.length);
+ return Ranges.closed(set.first(), set.last()).asSet(integers());
+ }
+ })
+ .withFeatures(
+ CollectionSize.ONE,
+ CollectionSize.SEVERAL,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.NON_STANDARD_TOSTRING,
+ CollectionFeature.RESTRICTS_ELEMENTS,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION)
+ .suppressing(SetHashCodeTester.getHashCodeMethods())
+ .named("DiscreteRange.asSet, closed")
+ .createTestSuite());
+
+ return suite;
+ }
+ }
+
+ abstract static class TestIntegerSetGenerator implements TestSetGenerator<Integer> {
+ @Override public SampleElements<Integer> samples() {
+ return new SampleElements<Integer>(1, 2, 3, 4, 5);
+ }
+
+ @Override public Set<Integer> create(Object... elements) {
+ Integer[] array = new Integer[elements.length];
+ int i = 0;
+ for (Object e : elements) {
+ array[i++] = (Integer) e;
+ }
+ return create(array);
+ }
+
+ protected abstract Set<Integer> create(Integer[] elements);
+
+ @Override public Integer[] createArray(int length) {
+ return new Integer[length];
+ }
+
+ @Override public List<Integer> order(List<Integer> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ }
+
+ public void testNothing() {
+ /*
+ * It's a warning if a TestCase subclass contains no tests, so we add one.
+ * Alternatively, we could stop extending TestCase, but I worry that someone
+ * will add a test in the future and not realize that it's being ignored.
+ */
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ContiguousSetTest.java b/guava-tests/test/com/google/common/collect/ContiguousSetTest.java
index 373cf64..6909f7a 100644
--- a/guava-tests/test/com/google/common/collect/ContiguousSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ContiguousSetTest.java
@@ -18,30 +18,16 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.DiscreteDomain.integers;
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
-import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
-import static com.google.common.collect.testing.features.CollectionFeature.NON_STANDARD_TOSTRING;
-import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
-import static com.google.common.collect.testing.testers.NavigableSetNavigationTester.getHoleMethods;
+import static com.google.common.collect.DiscreteDomains.integers;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.testing.SerializableTester.reserializeAndAssert;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.SetGenerators.ContiguousSetDescendingGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ContiguousSetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ContiguousSetHeadsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ContiguousSetSubsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ContiguousSetTailsetGenerator;
import com.google.common.testing.EqualsTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.util.Set;
@@ -75,35 +61,32 @@ public class ContiguousSetTest extends TestCase {
public void testEquals() {
new EqualsTester()
.addEqualityGroup(
- ContiguousSet.create(Range.closed(1, 3), integers()),
- ContiguousSet.create(Range.closedOpen(1, 4), integers()),
- ContiguousSet.create(Range.openClosed(0, 3), integers()),
- ContiguousSet.create(Range.open(0, 4), integers()),
- ContiguousSet.create(Range.closed(1, 3), NOT_EQUAL_TO_INTEGERS),
- ContiguousSet.create(Range.closedOpen(1, 4), NOT_EQUAL_TO_INTEGERS),
- ContiguousSet.create(Range.openClosed(0, 3), NOT_EQUAL_TO_INTEGERS),
- ContiguousSet.create(Range.open(0, 4), NOT_EQUAL_TO_INTEGERS),
+ Ranges.closed(1, 3).asSet(integers()),
+ Ranges.closedOpen(1, 4).asSet(integers()),
+ Ranges.openClosed(0, 3).asSet(integers()),
+ Ranges.open(0, 4).asSet(integers()),
+ Ranges.closed(1, 3).asSet(NOT_EQUAL_TO_INTEGERS),
+ Ranges.closedOpen(1, 4).asSet(NOT_EQUAL_TO_INTEGERS),
+ Ranges.openClosed(0, 3).asSet(NOT_EQUAL_TO_INTEGERS),
+ Ranges.open(0, 4).asSet(NOT_EQUAL_TO_INTEGERS),
ImmutableSortedSet.of(1, 2, 3))
.testEquals();
// not testing hashCode for these because it takes forever to compute
- assertEquals(
- ContiguousSet.create(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), integers()),
- ContiguousSet.create(Range.<Integer>all(), integers()));
- assertEquals(
- ContiguousSet.create(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), integers()),
- ContiguousSet.create(Range.atLeast(Integer.MIN_VALUE), integers()));
- assertEquals(
- ContiguousSet.create(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), integers()),
- ContiguousSet.create(Range.atMost(Integer.MAX_VALUE), integers()));
+ assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE).asSet(integers()),
+ Ranges.<Integer>all().asSet(integers()));
+ assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE).asSet(integers()),
+ Ranges.atLeast(Integer.MIN_VALUE).asSet(integers()));
+ assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE).asSet(integers()),
+ Ranges.atMost(Integer.MAX_VALUE).asSet(integers()));
}
@GwtIncompatible("SerializableTester")
public void testSerialization() {
- ContiguousSet<Integer> empty = ContiguousSet.create(Range.closedOpen(1, 1), integers());
+ ContiguousSet<Integer> empty = Ranges.closedOpen(1, 1).asSet(integers());
assertTrue(empty instanceof EmptyContiguousSet);
reserializeAndAssert(empty);
- ContiguousSet<Integer> regular = ContiguousSet.create(Range.closed(1, 3), integers());
+ ContiguousSet<Integer> regular = Ranges.closed(1, 3).asSet(integers());
assertTrue(regular instanceof RegularContiguousSet);
reserializeAndAssert(regular);
@@ -111,7 +94,7 @@ public class ContiguousSetTest extends TestCase {
* Make sure that we're using RegularContiguousSet.SerializedForm and not
* ImmutableSet.SerializedForm, which would be enormous.
*/
- ContiguousSet<Integer> enormous = ContiguousSet.create(Range.<Integer>all(), integers());
+ ContiguousSet<Integer> enormous = Ranges.<Integer>all().asSet(integers());
assertTrue(enormous instanceof RegularContiguousSet);
// We can't use reserializeAndAssert because it calls hashCode, which is enormously slow.
ContiguousSet<Integer> enormousReserialized = reserialize(enormous);
@@ -119,58 +102,66 @@ public class ContiguousSetTest extends TestCase {
}
public void testHeadSet() {
- ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
ASSERT.that(set.headSet(1)).isEmpty();
- ASSERT.that(set.headSet(2)).has().item(1);
- ASSERT.that(set.headSet(3)).has().allOf(1, 2).inOrder();
- ASSERT.that(set.headSet(4)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.headSet(Integer.MAX_VALUE)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.headSet(1, true)).has().item(1);
- ASSERT.that(set.headSet(2, true)).has().allOf(1, 2).inOrder();
- ASSERT.that(set.headSet(3, true)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.headSet(4, true)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.headSet(Integer.MAX_VALUE, true)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.headSet(2)).hasContentsInOrder(1);
+ ASSERT.that(set.headSet(3)).hasContentsInOrder(1, 2);
+ ASSERT.that(set.headSet(4)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.headSet(Integer.MAX_VALUE)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.headSet(1, true)).hasContentsInOrder(1);
+ ASSERT.that(set.headSet(2, true)).hasContentsInOrder(1, 2);
+ ASSERT.that(set.headSet(3, true)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.headSet(4, true)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.headSet(Integer.MAX_VALUE, true)).hasContentsInOrder(1, 2, 3);
}
public void testHeadSet_tooSmall() {
- ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).headSet(0)).isEmpty();
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ try {
+ set.headSet(0);
+ fail();
+ } catch (IllegalArgumentException e) {}
}
public void testTailSet() {
- ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
- ASSERT.that(set.tailSet(Integer.MIN_VALUE)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.tailSet(1)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.tailSet(2)).has().allOf(2, 3).inOrder();
- ASSERT.that(set.tailSet(3)).has().item(3);
- ASSERT.that(set.tailSet(Integer.MIN_VALUE, false)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.tailSet(1, false)).has().allOf(2, 3).inOrder();
- ASSERT.that(set.tailSet(2, false)).has().item(3);
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ASSERT.that(set.tailSet(Integer.MIN_VALUE)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.tailSet(1)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.tailSet(2)).hasContentsInOrder(2, 3);
+ ASSERT.that(set.tailSet(3)).hasContentsInOrder(3);
+ ASSERT.that(set.tailSet(Integer.MIN_VALUE, false)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.tailSet(1, false)).hasContentsInOrder(2, 3);
+ ASSERT.that(set.tailSet(2, false)).hasContentsInOrder(3);
ASSERT.that(set.tailSet(3, false)).isEmpty();
}
public void testTailSet_tooLarge() {
- ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).tailSet(4)).isEmpty();
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ try {
+ set.tailSet(4);
+ fail();
+ } catch (IllegalArgumentException e) {}
}
public void testSubSet() {
- ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
- ASSERT.that(set.subSet(1, 4)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.subSet(2, 4)).has().allOf(2, 3).inOrder();
- ASSERT.that(set.subSet(3, 4)).has().item(3);
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ASSERT.that(set.subSet(1, 4)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.subSet(2, 4)).hasContentsInOrder(2, 3);
+ ASSERT.that(set.subSet(3, 4)).hasContentsInOrder(3);
ASSERT.that(set.subSet(3, 3)).isEmpty();
- ASSERT.that(set.subSet(2, 3)).has().item(2);
- ASSERT.that(set.subSet(1, 3)).has().allOf(1, 2).inOrder();
- ASSERT.that(set.subSet(1, 2)).has().item(1);
+ ASSERT.that(set.subSet(2, 3)).hasContentsInOrder(2);
+ ASSERT.that(set.subSet(1, 3)).hasContentsInOrder(1, 2);
+ ASSERT.that(set.subSet(1, 2)).hasContentsInOrder(1);
ASSERT.that(set.subSet(2, 2)).isEmpty();
- ASSERT.that(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.subSet(1, true, 3, true)).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(set.subSet(1, false, 3, true)).has().allOf(2, 3).inOrder();
- ASSERT.that(set.subSet(1, true, 3, false)).has().allOf(1, 2).inOrder();
- ASSERT.that(set.subSet(1, false, 3, false)).has().item(2);
+ ASSERT.that(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.subSet(1, true, 3, true)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.subSet(1, false, 3, true)).hasContentsInOrder(2, 3);
+ ASSERT.that(set.subSet(1, true, 3, false)).hasContentsInOrder(1, 2);
+ ASSERT.that(set.subSet(1, false, 3, false)).hasContentsInOrder(2);
}
public void testSubSet_outOfOrder() {
- ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
try {
set.subSet(3, 2);
fail();
@@ -178,35 +169,41 @@ public class ContiguousSetTest extends TestCase {
}
public void testSubSet_tooLarge() {
- ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(4, 6)).isEmpty();
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ try {
+ set.subSet(4, 6);
+ fail();
+ } catch (IllegalArgumentException expected) {}
}
public void testSubSet_tooSmall() {
- ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(-1, 0)).isEmpty();
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ try {
+ set.subSet(-1, 0);
+ fail();
+ } catch (IllegalArgumentException expected) {}
}
public void testFirst() {
- assertEquals(1, ContiguousSet.create(Range.closed(1, 3), integers()).first().intValue());
- assertEquals(1, ContiguousSet.create(Range.open(0, 4), integers()).first().intValue());
- assertEquals(Integer.MIN_VALUE,
- ContiguousSet.create(Range.<Integer>all(), integers()).first().intValue());
+ assertEquals(1, Ranges.closed(1, 3).asSet(integers()).first().intValue());
+ assertEquals(1, Ranges.open(0, 4).asSet(integers()).first().intValue());
+ assertEquals(Integer.MIN_VALUE, Ranges.<Integer>all().asSet(integers()).first().intValue());
}
public void testLast() {
- assertEquals(3, ContiguousSet.create(Range.closed(1, 3), integers()).last().intValue());
- assertEquals(3, ContiguousSet.create(Range.open(0, 4), integers()).last().intValue());
- assertEquals(Integer.MAX_VALUE,
- ContiguousSet.create(Range.<Integer>all(), integers()).last().intValue());
+ assertEquals(3, Ranges.closed(1, 3).asSet(integers()).last().intValue());
+ assertEquals(3, Ranges.open(0, 4).asSet(integers()).last().intValue());
+ assertEquals(Integer.MAX_VALUE, Ranges.<Integer>all().asSet(integers()).last().intValue());
}
public void testContains() {
- ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
assertFalse(set.contains(0));
assertTrue(set.contains(1));
assertTrue(set.contains(2));
assertTrue(set.contains(3));
assertFalse(set.contains(4));
- set = ContiguousSet.create(Range.open(0, 4), integers());
+ set = Ranges.open(0, 4).asSet(integers());
assertFalse(set.contains(0));
assertTrue(set.contains(1));
assertTrue(set.contains(2));
@@ -216,7 +213,7 @@ public class ContiguousSetTest extends TestCase {
}
public void testContainsAll() {
- ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
for (Set<Integer> subset : Sets.powerSet(ImmutableSet.of(1, 2, 3))) {
assertTrue(set.containsAll(subset));
}
@@ -227,117 +224,55 @@ public class ContiguousSetTest extends TestCase {
}
public void testRange() {
- assertEquals(Range.closed(1, 3),
- ContiguousSet.create(Range.closed(1, 3), integers()).range());
- assertEquals(Range.closed(1, 3),
- ContiguousSet.create(Range.closedOpen(1, 4), integers()).range());
- assertEquals(Range.closed(1, 3), ContiguousSet.create(Range.open(0, 4), integers()).range());
- assertEquals(Range.closed(1, 3),
- ContiguousSet.create(Range.openClosed(0, 3), integers()).range());
-
- assertEquals(Range.openClosed(0, 3),
- ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, CLOSED));
- assertEquals(Range.openClosed(0, 3),
- ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, CLOSED));
- assertEquals(Range.openClosed(0, 3),
- ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, CLOSED));
- assertEquals(Range.openClosed(0, 3),
- ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, CLOSED));
-
- assertEquals(Range.open(0, 4),
- ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, OPEN));
- assertEquals(Range.open(0, 4),
- ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, OPEN));
- assertEquals(Range.open(0, 4),
- ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, OPEN));
- assertEquals(Range.open(0, 4),
- ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, OPEN));
-
- assertEquals(Range.closedOpen(1, 4),
- ContiguousSet.create(Range.closed(1, 3), integers()).range(CLOSED, OPEN));
- assertEquals(Range.closedOpen(1, 4),
- ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(CLOSED, OPEN));
- assertEquals(Range.closedOpen(1, 4),
- ContiguousSet.create(Range.open(0, 4), integers()).range(CLOSED, OPEN));
- assertEquals(Range.closedOpen(1, 4),
- ContiguousSet.create(Range.openClosed(0, 3), integers()).range(CLOSED, OPEN));
+ assertEquals(Ranges.closed(1, 3), Ranges.closed(1, 3).asSet(integers()).range());
+ assertEquals(Ranges.closed(1, 3), Ranges.closedOpen(1, 4).asSet(integers()).range());
+ assertEquals(Ranges.closed(1, 3), Ranges.open(0, 4).asSet(integers()).range());
+ assertEquals(Ranges.closed(1, 3), Ranges.openClosed(0, 3).asSet(integers()).range());
+
+ assertEquals(Ranges.openClosed(0, 3),
+ Ranges.closed(1, 3).asSet(integers()).range(OPEN, CLOSED));
+ assertEquals(Ranges.openClosed(0, 3),
+ Ranges.closedOpen(1, 4).asSet(integers()).range(OPEN, CLOSED));
+ assertEquals(Ranges.openClosed(0, 3), Ranges.open(0, 4).asSet(integers()).range(OPEN, CLOSED));
+ assertEquals(Ranges.openClosed(0, 3),
+ Ranges.openClosed(0, 3).asSet(integers()).range(OPEN, CLOSED));
+
+ assertEquals(Ranges.open(0, 4), Ranges.closed(1, 3).asSet(integers()).range(OPEN, OPEN));
+ assertEquals(Ranges.open(0, 4), Ranges.closedOpen(1, 4).asSet(integers()).range(OPEN, OPEN));
+ assertEquals(Ranges.open(0, 4), Ranges.open(0, 4).asSet(integers()).range(OPEN, OPEN));
+ assertEquals(Ranges.open(0, 4), Ranges.openClosed(0, 3).asSet(integers()).range(OPEN, OPEN));
+
+ assertEquals(Ranges.closedOpen(1, 4),
+ Ranges.closed(1, 3).asSet(integers()).range(CLOSED, OPEN));
+ assertEquals(Ranges.closedOpen(1, 4),
+ Ranges.closedOpen(1, 4).asSet(integers()).range(CLOSED, OPEN));
+ assertEquals(Ranges.closedOpen(1, 4), Ranges.open(0, 4).asSet(integers()).range(CLOSED, OPEN));
+ assertEquals(Ranges.closedOpen(1, 4),
+ Ranges.openClosed(0, 3).asSet(integers()).range(CLOSED, OPEN));
}
- public void testRange_unboundedRange() {
- assertEquals(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
- ContiguousSet.create(Range.<Integer>all(), integers()).range());
- assertEquals(Range.atLeast(Integer.MIN_VALUE),
- ContiguousSet.create(Range.<Integer>all(), integers()).range(CLOSED, OPEN));
- assertEquals(Range.all(),
- ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, OPEN));
- assertEquals(Range.atMost(Integer.MAX_VALUE),
- ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, CLOSED));
+ public void testRange_unboundedRanges() {
+ assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
+ Ranges.<Integer>all().asSet(integers()).range());
+ assertEquals(Ranges.atLeast(Integer.MIN_VALUE),
+ Ranges.<Integer>all().asSet(integers()).range(CLOSED, OPEN));
+ assertEquals(Ranges.all(), Ranges.<Integer>all().asSet(integers()).range(OPEN, OPEN));
+ assertEquals(Ranges.atMost(Integer.MAX_VALUE),
+ Ranges.<Integer>all().asSet(integers()).range(OPEN, CLOSED));
}
public void testIntersection_empty() {
- ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
- ContiguousSet<Integer> emptySet = ContiguousSet.create(Range.closedOpen(2, 2), integers());
+ ContiguousSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ContiguousSet<Integer> emptySet = Ranges.closedOpen(2,2).asSet(integers());
assertEquals(ImmutableSet.of(), set.intersection(emptySet));
assertEquals(ImmutableSet.of(), emptySet.intersection(set));
- assertEquals(ImmutableSet.of(),
- ContiguousSet.create(Range.closed(-5, -1), integers()).intersection(
- ContiguousSet.create(Range.open(3, 64), integers())));
+ assertEquals(ImmutableSet.of(), Ranges.closed(-5, -1).asSet(integers()).intersection(
+ Ranges.open(3, 64).asSet(integers())));
}
public void testIntersection() {
- ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
- assertEquals(ImmutableSet.of(1, 2, 3),
- ContiguousSet.create(Range.open(-1, 4), integers()).intersection(set));
- assertEquals(ImmutableSet.of(1, 2, 3),
- set.intersection(ContiguousSet.create(Range.open(-1, 4), integers())));
- }
-
- @GwtIncompatible("suite")
- public static class BuiltTests extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ContiguousSetGenerator())
- .named("Range.asSet")
- .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
- NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
- .suppressing(getHoleMethods())
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ContiguousSetHeadsetGenerator())
- .named("Range.asSet, headset")
- .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
- NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
- .suppressing(getHoleMethods())
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ContiguousSetTailsetGenerator())
- .named("Range.asSet, tailset")
- .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
- NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
- .suppressing(getHoleMethods())
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ContiguousSetSubsetGenerator())
- .named("Range.asSet, subset")
- .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
- NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
- .suppressing(getHoleMethods())
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ContiguousSetDescendingGenerator())
- .named("Range.asSet.descendingSet")
- .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
- NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
- .suppressing(getHoleMethods())
- .createTestSuite());
-
- return suite;
- }
+ ContiguousSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ assertEquals(ImmutableSet.of(1, 2, 3), Ranges.open(-1, 4).asSet(integers()).intersection(set));
+ assertEquals(ImmutableSet.of(1, 2, 3), set.intersection(Ranges.open(-1, 4).asSet(integers())));
}
}
diff --git a/guava-tests/test/com/google/common/collect/CountTest.java b/guava-tests/test/com/google/common/collect/CountTest.java
index 85839bc..be40ff8 100644
--- a/guava-tests/test/com/google/common/collect/CountTest.java
+++ b/guava-tests/test/com/google/common/collect/CountTest.java
@@ -46,7 +46,7 @@ public class CountTest extends TestCase {
assertEquals(20, holder.get());
}
- public void testSet() {
+ public void testSet(){
Count holder = new Count(10);
holder.set(20);
assertEquals(20, holder.get());
diff --git a/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java b/guava-tests/test/com/google/common/collect/DiscreteDomainsTest.java
index fdf2acd..2aec2db 100644
--- a/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java
+++ b/guava-tests/test/com/google/common/collect/DiscreteDomainsTest.java
@@ -23,14 +23,15 @@ import com.google.common.annotations.GwtIncompatible;
import junit.framework.TestCase;
/**
- * Tests for {@link DiscreteDomain}.
+ * Tests for {@link DiscreteDomains}.
*
* @author Chris Povirk
*/
@GwtIncompatible("SerializableTester")
-public class DiscreteDomainTest extends TestCase {
+public class DiscreteDomainsTest extends TestCase {
public void testSerialization() {
- reserializeAndAssert(DiscreteDomain.integers());
- reserializeAndAssert(DiscreteDomain.longs());
+ reserializeAndAssert(DiscreteDomains.integers());
+ reserializeAndAssert(DiscreteDomains.longs());
+ reserializeAndAssert(DiscreteDomains.bigIntegers());
}
}
diff --git a/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java b/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java
index d1bd97a..38f4f32 100644
--- a/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,20 +16,19 @@
package com.google.common.collect;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.testing.EqualsTester;
/**
* Tests {@link EmptyImmutableTable}
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
-@GwtCompatible(emulated = true)
public class EmptyImmutableTableTest extends AbstractImmutableTableTest {
- private static final ImmutableTable<Character, Integer, String> INSTANCE = ImmutableTable.of();
+ private static final ImmutableTable<Character, Integer, String> INSTANCE =
+ ImmutableTable.of();
- @Override Iterable<ImmutableTable<Character, Integer, String>> getTestInstances() {
+ @Override Iterable<ImmutableTable<Character, Integer, String>>
+ getTestInstances() {
return ImmutableSet.of(INSTANCE);
}
@@ -38,20 +37,11 @@ public class EmptyImmutableTableTest extends AbstractImmutableTableTest {
}
public void testEqualsObject() {
- Table<Character, Integer, String> nonEmptyTable = HashBasedTable.create();
- nonEmptyTable.put('A', 1, "blah");
-
- new EqualsTester()
- .addEqualityGroup(INSTANCE, HashBasedTable.create(), TreeBasedTable.create())
- .addEqualityGroup(nonEmptyTable)
- .testEquals();
- }
-
- @GwtIncompatible("ArrayTable")
- public void testEqualsObjectNullValues() {
new EqualsTester()
- .addEqualityGroup(INSTANCE)
- .addEqualityGroup(ArrayTable.create(ImmutableSet.of('A'), ImmutableSet.of(1)))
+ .addEqualityGroup(INSTANCE, HashBasedTable.create(),
+ TreeBasedTable.create())
+ .addEqualityGroup(ArrayTable.create(ImmutableSet.of("A"),
+ ImmutableSet.of(1)))
.testEquals();
}
@@ -120,7 +110,8 @@ public class EmptyImmutableTableTest extends AbstractImmutableTableTest {
}
public void testReadResolve() {
- assertSame(EmptyImmutableTable.INSTANCE, EmptyImmutableTable.INSTANCE.readResolve());
+ assertSame(EmptyImmutableTable.INSTANCE,
+ EmptyImmutableTable.INSTANCE.readResolve());
}
}
diff --git a/guava-tests/test/com/google/common/collect/EnumBiMapTest.java b/guava-tests/test/com/google/common/collect/EnumBiMapTest.java
index c972606..c592f79 100644
--- a/guava-tests/test/com/google/common/collect/EnumBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/EnumBiMapTest.java
@@ -16,31 +16,16 @@
package com.google.common.collect;
-import static com.google.common.collect.testing.Helpers.orderEntriesByKey;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestBiMapGenerator;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
/**
@@ -51,66 +36,8 @@ import java.util.Set;
*/
@GwtCompatible(emulated = true)
public class EnumBiMapTest extends TestCase {
- private enum Currency { DOLLAR, FRANC, PESO, POUND, YEN }
- private enum Country { CANADA, CHILE, JAPAN, SWITZERLAND, UK }
-
- public static final class EnumBiMapGenerator implements TestBiMapGenerator<Country, Currency> {
- @SuppressWarnings("unchecked")
- @Override
- public BiMap<Country, Currency> create(Object... entries) {
- BiMap<Country, Currency> result = EnumBiMap.create(Country.class, Currency.class);
- for (Object object : entries) {
- Entry<Country, Currency> entry = (Entry<Country, Currency>) object;
- result.put(entry.getKey(), entry.getValue());
- }
- return result;
- }
-
- @Override
- public SampleElements<Entry<Country, Currency>> samples() {
- return new SampleElements<Entry<Country, Currency>>(
- Helpers.mapEntry(Country.CANADA, Currency.DOLLAR),
- Helpers.mapEntry(Country.CHILE, Currency.PESO),
- Helpers.mapEntry(Country.UK, Currency.POUND),
- Helpers.mapEntry(Country.JAPAN, Currency.YEN),
- Helpers.mapEntry(Country.SWITZERLAND, Currency.FRANC));
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<Country, Currency>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<Country, Currency>> order(List<Entry<Country, Currency>> insertionOrder) {
- return orderEntriesByKey(insertionOrder);
- }
-
- @Override
- public Country[] createKeyArray(int length) {
- return new Country[length];
- }
-
- @Override
- public Currency[] createValueArray(int length) {
- return new Currency[length];
- }
- }
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(BiMapTestSuiteBuilder.using(new EnumBiMapGenerator())
- .named("EnumBiMap")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
- MapFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
- suite.addTestSuite(EnumBiMapTest.class);
- return suite;
- }
+ private enum Currency { DOLLAR, FRANC, PESO }
+ private enum Country { CANADA, CHILE, SWITZERLAND }
public void testCreate() {
EnumBiMap<Currency, Country> bimap =
@@ -185,57 +112,20 @@ public class EnumBiMapTest extends TestCase {
assertEquals(Country.class, bimap.valueType());
}
- public void testIterationOrder() {
- // The enum orderings are alphabetical, leading to the bimap and its inverse
- // having inconsistent iteration orderings.
+ @GwtIncompatible("SerializationTester")
+ public void testSerialization() {
Map<Currency, Country> map = ImmutableMap.of(
Currency.DOLLAR, Country.CANADA,
Currency.PESO, Country.CHILE,
Currency.FRANC, Country.SWITZERLAND);
EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map);
- // forward map ordered by currency
- ASSERT.that(bimap.keySet())
- .has().allOf(Currency.DOLLAR, Currency.FRANC, Currency.PESO).inOrder();
- // forward map ordered by currency (even for country values)
- ASSERT.that(bimap.values())
- .has().allOf(Country.CANADA, Country.SWITZERLAND, Country.CHILE).inOrder();
- // backward map ordered by country
- ASSERT.that(bimap.inverse().keySet())
- .has().allOf(Country.CANADA, Country.CHILE, Country.SWITZERLAND).inOrder();
- // backward map ordered by country (even for currency values)
- ASSERT.that(bimap.inverse().values())
- .has().allOf(Currency.DOLLAR, Currency.PESO, Currency.FRANC).inOrder();
+ BiMap<Currency, Country> copy =
+ SerializableTester.reserializeAndAssert(bimap);
+ assertEquals(bimap.inverse(), copy.inverse());
}
- public void testKeySetIteratorRemove() {
- // The enum orderings are alphabetical, leading to the bimap and its inverse
- // having inconsistent iteration orderings.
- Map<Currency, Country> map = ImmutableMap.of(
- Currency.DOLLAR, Country.CANADA,
- Currency.PESO, Country.CHILE,
- Currency.FRANC, Country.SWITZERLAND);
- EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map);
-
- Iterator<Currency> iter = bimap.keySet().iterator();
- assertEquals(Currency.DOLLAR, iter.next());
- iter.remove();
-
- // forward map ordered by currency
- ASSERT.that(bimap.keySet())
- .has().allOf(Currency.FRANC, Currency.PESO).inOrder();
- // forward map ordered by currency (even for country values)
- ASSERT.that(bimap.values())
- .has().allOf(Country.SWITZERLAND, Country.CHILE).inOrder();
- // backward map ordered by country
- ASSERT.that(bimap.inverse().keySet())
- .has().allOf(Country.CHILE, Country.SWITZERLAND).inOrder();
- // backward map ordered by country (even for currency values)
- ASSERT.that(bimap.inverse().values())
- .has().allOf(Currency.PESO, Currency.FRANC).inOrder();
- }
-
- public void testValuesIteratorRemove() {
+ public void testIterationOrder() {
// The enum orderings are alphabetical, leading to the bimap and its inverse
// having inconsistent iteration orderings.
Map<Currency, Country> map = ImmutableMap.of(
@@ -244,27 +134,21 @@ public class EnumBiMapTest extends TestCase {
Currency.FRANC, Country.SWITZERLAND);
EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map);
- Iterator<Currency> iter = bimap.keySet().iterator();
- assertEquals(Currency.DOLLAR, iter.next());
- assertEquals(Currency.FRANC, iter.next());
- iter.remove();
-
// forward map ordered by currency
ASSERT.that(bimap.keySet())
- .has().allOf(Currency.DOLLAR, Currency.PESO).inOrder();
+ .hasContentsInOrder(Currency.DOLLAR, Currency.FRANC, Currency.PESO);
// forward map ordered by currency (even for country values)
ASSERT.that(bimap.values())
- .has().allOf(Country.CANADA, Country.CHILE).inOrder();
+ .hasContentsInOrder(Country.CANADA, Country.SWITZERLAND, Country.CHILE);
// backward map ordered by country
ASSERT.that(bimap.inverse().keySet())
- .has().allOf(Country.CANADA, Country.CHILE).inOrder();
+ .hasContentsInOrder(Country.CANADA, Country.CHILE, Country.SWITZERLAND);
// backward map ordered by country (even for currency values)
ASSERT.that(bimap.inverse().values())
- .has().allOf(Currency.DOLLAR, Currency.PESO).inOrder();
+ .hasContentsInOrder(Currency.DOLLAR, Currency.PESO, Currency.FRANC);
}
public void testEntrySet() {
- // Bug 3168290
Map<Currency, Country> map = ImmutableMap.of(
Currency.DOLLAR, Country.CANADA,
Currency.PESO, Country.CHILE,
@@ -275,29 +159,5 @@ public class EnumBiMapTest extends TestCase {
assertEquals(3, uniqueEntries.size());
}
- @GwtIncompatible("serialization")
- public void testSerializable() {
- SerializableTester.reserializeAndAssert(
- EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)));
- }
-
- @GwtIncompatible("reflection")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(EnumBiMap.class);
- new NullPointerTester()
- .testAllPublicInstanceMethods(
- EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CHILE)));
- }
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(
- EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)),
- EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)))
- .addEqualityGroup(EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CHILE)))
- .addEqualityGroup(EnumBiMap.create(ImmutableMap.of(Currency.FRANC, Country.CANADA)))
- .testEquals();
- }
-
/* Remaining behavior tested by AbstractBiMapTest. */
}
diff --git a/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java b/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java
index 01a4afe..e85811e 100644
--- a/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java
@@ -18,23 +18,12 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestBiMapGenerator;
-import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
/**
@@ -44,67 +33,8 @@ import java.util.Set;
*/
@GwtCompatible(emulated = true)
public class EnumHashBiMapTest extends TestCase {
- private enum Currency { DOLLAR, FRANC, PESO, POUND, YEN }
- private enum Country { CANADA, CHILE, JAPAN, SWITZERLAND, UK }
-
- public static final class EnumHashBiMapGenerator implements TestBiMapGenerator<Country, String> {
- @SuppressWarnings("unchecked")
- @Override
- public BiMap<Country, String> create(Object... entries) {
- BiMap<Country, String> result = EnumHashBiMap.create(Country.class);
- for (Object o : entries) {
- Entry<Country, String> entry = (Entry<Country, String>) o;
- result.put(entry.getKey(), entry.getValue());
- }
- return result;
- }
-
- @Override
- public SampleElements<Entry<Country, String>> samples() {
- return new SampleElements<Entry<Country, String>>(
- Maps.immutableEntry(Country.CANADA, "DOLLAR"),
- Maps.immutableEntry(Country.CHILE, "PESO"),
- Maps.immutableEntry(Country.UK, "POUND"),
- Maps.immutableEntry(Country.JAPAN, "YEN"),
- Maps.immutableEntry(Country.SWITZERLAND, "FRANC"));
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<Country, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<Country, String>> order(List<Entry<Country, String>> insertionOrder) {
- return insertionOrder;
- }
-
- @Override
- public Country[] createKeyArray(int length) {
- return new Country[length];
- }
-
- @Override
- public String[] createValueArray(int length) {
- return new String[length];
- }
- }
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(BiMapTestSuiteBuilder.using(new EnumHashBiMapGenerator())
- .named("EnumHashBiMap")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
- suite.addTestSuite(EnumHashBiMapTest.class);
- return suite;
- }
+ private enum Currency { DOLLAR, PESO, FRANC }
+ private enum Country { CANADA, CHILE, SWITZERLAND }
public void testCreate() {
EnumHashBiMap<Currency, String> bimap =
@@ -198,8 +128,8 @@ public class EnumHashBiMapTest extends TestCase {
assertEquals(Currency.class, bimap.keyType());
}
- public void testEntrySet() {
- // Bug 3168290
+ @GwtIncompatible("SerializationTester")
+ public void testSerialization() {
Map<Currency, String> map = ImmutableMap.of(
Currency.DOLLAR, "dollar",
Currency.PESO, "peso",
@@ -207,19 +137,36 @@ public class EnumHashBiMapTest extends TestCase {
EnumHashBiMap<Currency, String> bimap
= EnumHashBiMap.create(map);
- Set<Object> uniqueEntries = Sets.newIdentityHashSet();
- uniqueEntries.addAll(bimap.entrySet());
- assertEquals(3, uniqueEntries.size());
+ BiMap<Currency, String> copy =
+ SerializableTester.reserializeAndAssert(bimap);
+ assertEquals(bimap.inverse(), copy.inverse());
}
- @GwtIncompatible("serialize")
- public void testSerializable() {
- SerializableTester.reserializeAndAssert(EnumHashBiMap.create(Currency.class));
+ public void testForcePut() {
+ EnumHashBiMap<Currency, String> bimap =
+ EnumHashBiMap.create(Currency.class);
+ bimap.put(Currency.DOLLAR, "dollar");
+ try {
+ bimap.put(Currency.PESO, "dollar");
+ } catch (IllegalArgumentException expected) {}
+ bimap.forcePut(Currency.PESO, "dollar");
+ assertEquals("dollar", bimap.get(Currency.PESO));
+ assertEquals(Currency.PESO, bimap.inverse().get("dollar"));
+ assertEquals(1, bimap.size());
+ assertEquals(1, bimap.inverse().size());
}
- @GwtIncompatible("reflection")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(EnumHashBiMap.class);
- new NullPointerTester().testAllPublicInstanceMethods(EnumHashBiMap.create(Currency.class));
+ public void testEntrySet() {
+ Map<Currency, String> map = ImmutableMap.of(
+ Currency.DOLLAR, "dollar",
+ Currency.PESO, "peso",
+ Currency.FRANC, "franc");
+ EnumHashBiMap<Currency, String> bimap
+ = EnumHashBiMap.create(map);
+
+ Set<Object> uniqueEntries = Sets.newIdentityHashSet();
+ uniqueEntries.addAll(bimap.entrySet());
+ assertEquals(3, uniqueEntries.size());
}
+ /* Remaining behavior tested by AbstractBiMapTest. */
}
diff --git a/guava-tests/test/com/google/common/collect/EnumMultisetTest.java b/guava-tests/test/com/google/common/collect/EnumMultisetTest.java
index b8cceb6..e22fe5e 100644
--- a/guava-tests/test/com/google/common/collect/EnumMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/EnumMultisetTest.java
@@ -20,18 +20,9 @@ import static java.util.Arrays.asList;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.AnEnum;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestEnumMultisetGenerator;
-import com.google.common.testing.ClassSanityTester;
-import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.util.Collection;
import java.util.EnumSet;
@@ -44,31 +35,6 @@ import java.util.Set;
*/
@GwtCompatible(emulated = true)
public class EnumMultisetTest extends TestCase {
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(MultisetTestSuiteBuilder.using(enumMultisetGenerator())
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("EnumMultiset")
- .createTestSuite());
- suite.addTestSuite(EnumMultisetTest.class);
- return suite;
- }
-
- private static TestEnumMultisetGenerator enumMultisetGenerator() {
- return new TestEnumMultisetGenerator() {
- @Override protected Multiset<AnEnum> create(AnEnum[] elements) {
- return (elements.length == 0)
- ? EnumMultiset.create(AnEnum.class)
- : EnumMultiset.create(asList(elements));
- }
- };
- }
-
private static enum Color {
BLUE, RED, YELLOW, GREEN, WHITE
}
@@ -98,19 +64,6 @@ public class EnumMultisetTest extends TestCase {
fail();
} catch (IllegalArgumentException expected) {}
}
-
- public void testCreateEmptyWithClass() {
- Multiset<Color> ms = EnumMultiset.create(ImmutableList.<Color>of(), Color.class);
- ms.add(Color.RED);
- }
-
- public void testCreateEmptyWithoutClassFails() {
- try {
- Multiset<Color> ms = EnumMultiset.create(ImmutableList.<Color> of());
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
public void testToString() {
Multiset<Color> ms = EnumMultiset.create(Color.class);
@@ -126,34 +79,15 @@ public class EnumMultisetTest extends TestCase {
asList(Color.RED, Color.YELLOW, Color.RED));
assertEquals(ms, SerializableTester.reserialize(ms));
}
-
+
public void testEntrySet() {
Multiset<Color> ms = EnumMultiset.create(Color.class);
ms.add(Color.BLUE, 3);
ms.add(Color.YELLOW, 1);
ms.add(Color.RED, 2);
-
+
Set<Object> uniqueEntries = Sets.newIdentityHashSet();
uniqueEntries.addAll(ms.entrySet());
assertEquals(3, uniqueEntries.size());
}
-
- @GwtIncompatible("reflection")
- public void testEquals() throws Exception {
- new ClassSanityTester()
- .setSampleInstances(Class.class, ImmutableList.of(Color.class))
- .setSampleInstances(Enum.class, ImmutableList.copyOf(Color.values()))
- .setSampleInstances(Iterable.class,
- ImmutableList.of(ImmutableList.of(Color.RED), ImmutableList.of(Color.GREEN)))
- .forAllPublicStaticMethods(EnumMultiset.class)
- .testEquals();
- }
-
- @GwtIncompatible("reflection")
- public void testNulls() throws Exception {
- new NullPointerTester()
- .setDefault(Class.class, Color.class)
- .setDefault(Iterable.class, ImmutableList.copyOf(Color.values()))
- .testAllPublicStaticMethods(EnumMultiset.class);
- }
}
diff --git a/guava-tests/test/com/google/common/collect/FauxveridesTest.java b/guava-tests/test/com/google/common/collect/FauxveridesTest.java
index c1d861c..0bf6df4 100644
--- a/guava-tests/test/com/google/common/collect/FauxveridesTest.java
+++ b/guava-tests/test/com/google/common/collect/FauxveridesTest.java
@@ -42,7 +42,7 @@ import java.util.Set;
* are "overridden" in each immutable-collection class. This ensures, for
* example, that a call written "{@code ImmutableSortedSet.copyOf()}" cannot
* secretly be a call to {@code ImmutableSet.copyOf()}.
- *
+ *
* @author Chris Povirk
*/
public class FauxveridesTest extends TestCase {
@@ -68,10 +68,6 @@ public class FauxveridesTest extends TestCase {
doHasAllFauxveridesTest(ImmutableSortedSet.class, ImmutableSet.class);
}
- public void testImmutableSortedMultiset() {
- doHasAllFauxveridesTest(ImmutableSortedMultiset.class, ImmutableMultiset.class);
- }
-
/*
* Demonstrate that ClassCastException is possible when calling
* ImmutableSorted{Set,Map}.copyOf(), whose type parameters we are unable to
@@ -110,7 +106,8 @@ public class FauxveridesTest extends TestCase {
}
private void doHasAllFauxveridesTest(Class<?> descendant, Class<?> ancestor) {
- Set<MethodSignature> required = getAllRequiredToFauxveride(ancestor);
+ Set<MethodSignature> required =
+ getAllRequiredToFauxveride(descendant, ancestor);
Set<MethodSignature> found = getAllFauxveridden(descendant, ancestor);
required.removeAll(found);
@@ -118,7 +115,8 @@ public class FauxveridesTest extends TestCase {
Collections.emptySet(), newTreeSet(required));
}
- private static Set<MethodSignature> getAllRequiredToFauxveride(Class<?> ancestor) {
+ private static Set<MethodSignature> getAllRequiredToFauxveride(
+ Class<?> descendant, Class<?> ancestor) {
return getPublicStaticMethodsBetween(ancestor, Object.class);
}
diff --git a/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java b/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java
deleted file mode 100644
index 6e165b7..0000000
--- a/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.TestCase;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NavigableSet;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Tests for filtered collection views.
- *
- * @author Louis Wasserman
- */
-public class FilteredCollectionsTest extends TestCase {
- private static final Predicate<Integer> EVEN = new Predicate<Integer>() {
- @Override
- public boolean apply(Integer input) {
- return input % 2 == 0;
- }
- };
-
- private static final Predicate<Integer> PRIME_DIGIT =
- Predicates.in(ImmutableSet.of(2, 3, 5, 7));
-
- private static final ImmutableList<? extends List<Integer>> SAMPLE_INPUTS =
- ImmutableList.of(ImmutableList.<Integer>of(),
- ImmutableList.of(1),
- ImmutableList.of(2),
- ImmutableList.of(2, 3),
- ImmutableList.of(1, 2),
- ImmutableList.of(3, 5),
- ImmutableList.of(2, 4),
- ImmutableList.of(1, 2, 3, 5, 6, 8, 9));
-
- /*
- * We have a whole series of abstract test classes that "stack", so e.g. the tests for filtered
- * NavigableSets inherit the tests for filtered Iterables, Collections, Sets, and SortedSets. The
- * actual implementation tests are further down.
- */
-
- public static abstract class AbstractFilteredIterableTest<C extends Iterable<Integer>>
- extends TestCase {
- abstract C createUnfiltered(Iterable<Integer> contents);
-
- abstract C filter(C elements, Predicate<? super Integer> predicate);
-
- public void testIterationOrderPreserved() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C unfiltered = createUnfiltered(contents);
- C filtered = filter(unfiltered, EVEN);
-
- Iterator<Integer> filteredItr = filtered.iterator();
- for (Integer i : unfiltered) {
- if (EVEN.apply(i)) {
- assertTrue(filteredItr.hasNext());
- assertEquals(i, filteredItr.next());
- }
- }
- assertFalse(filteredItr.hasNext());
- }
- }
- }
-
- public static abstract class AbstractFilteredCollectionTest<C extends Collection<Integer>>
- extends AbstractFilteredIterableTest<C> {
-
- public void testReadsThroughAdd() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C unfiltered = createUnfiltered(contents);
- C filterThenAdd = filter(unfiltered, EVEN);
- unfiltered.add(4);
-
- List<Integer> target = Lists.newArrayList(contents);
- target.add(4);
- C addThenFilter = filter(createUnfiltered(target), EVEN);
-
- ASSERT.that(filterThenAdd).has().allFrom(addThenFilter);
- }
- }
-
- public void testAdd() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int toAdd = 0; toAdd < 10; toAdd++) {
- boolean expectedResult = createUnfiltered(contents).add(toAdd);
-
- C filtered = filter(createUnfiltered(contents), EVEN);
- try {
- assertEquals(expectedResult, filtered.add(toAdd));
- assertTrue(EVEN.apply(toAdd));
- } catch (IllegalArgumentException e) {
- assertFalse(EVEN.apply(toAdd));
- }
- }
- }
- }
-
- public void testRemove() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int toRemove = 0; toRemove < 10; toRemove++) {
- assertEquals(contents.contains(toRemove) && EVEN.apply(toRemove),
- filter(createUnfiltered(contents), EVEN).remove(toRemove));
- }
- }
- }
-
- public void testContains() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- assertEquals(EVEN.apply(i) && contents.contains(i),
- filter(createUnfiltered(contents), EVEN).contains(i));
- }
- }
- }
-
- public void testContainsOnDifferentType() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- assertFalse(filter(createUnfiltered(contents), EVEN).contains(new Object()));
- }
- }
-
- public void testAddAllFailsAtomically() {
- ImmutableList<Integer> toAdd = ImmutableList.of(2, 4, 3);
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C filtered = filter(createUnfiltered(contents), EVEN);
- C filteredToModify = filter(createUnfiltered(contents), EVEN);
-
- try {
- filteredToModify.addAll(toAdd);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
-
- ASSERT.that(filteredToModify).has().allFrom(filtered);
- }
- }
-
- public void testAddToFilterFiltered() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C unfiltered = createUnfiltered(contents);
- C filtered1 = filter(unfiltered, EVEN);
- C filtered2 = filter(filtered1, PRIME_DIGIT);
-
- try {
- filtered2.add(4);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
-
- try {
- filtered2.add(3);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
-
- filtered2.add(2);
- }
- }
-
- public void testClearFilterFiltered() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C unfiltered = createUnfiltered(contents);
- C filtered1 = filter(unfiltered, EVEN);
- C filtered2 = filter(filtered1, PRIME_DIGIT);
-
- C inverseFiltered = filter(createUnfiltered(contents),
- Predicates.not(Predicates.and(EVEN, PRIME_DIGIT)));
-
- filtered2.clear();
- ASSERT.that(unfiltered).has().allFrom(inverseFiltered);
- }
- }
- }
-
- public static abstract class AbstractFilteredSetTest<C extends Set<Integer>>
- extends AbstractFilteredCollectionTest<C> {
- public void testEqualsAndHashCode() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- Set<Integer> expected = Sets.newHashSet();
- for (Integer i : contents) {
- if (EVEN.apply(i)) {
- expected.add(i);
- }
- }
- new EqualsTester().addEqualityGroup(expected, filter(createUnfiltered(contents), EVEN))
- .testEquals();
- }
- }
- }
-
- public static abstract class AbstractFilteredSortedSetTest<C extends SortedSet<Integer>>
- extends AbstractFilteredSetTest<C> {
- public void testFirst() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C filtered = filter(createUnfiltered(contents), EVEN);
-
- try {
- Integer first = filtered.first();
- assertFalse(filtered.isEmpty());
- assertEquals(Ordering.natural().min(filtered), first);
- } catch (NoSuchElementException e) {
- assertTrue(filtered.isEmpty());
- }
- }
- }
-
- public void testLast() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- C filtered = filter(createUnfiltered(contents), EVEN);
-
- try {
- Integer first = filtered.last();
- assertFalse(filtered.isEmpty());
- assertEquals(Ordering.natural().max(filtered), first);
- } catch (NoSuchElementException e) {
- assertTrue(filtered.isEmpty());
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- public void testHeadSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- assertEquals(
- filter((C) createUnfiltered(contents).headSet(i), EVEN),
- filter(createUnfiltered(contents), EVEN).headSet(i));
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- public void testTailSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- assertEquals(
- filter((C) createUnfiltered(contents).tailSet(i), EVEN),
- filter(createUnfiltered(contents), EVEN).tailSet(i));
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- public void testSubSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- for (int j = i; j < 10; j++) {
- assertEquals(
- filter((C) createUnfiltered(contents).subSet(i, j), EVEN),
- filter(createUnfiltered(contents), EVEN).subSet(i, j));
- }
- }
- }
- }
- }
-
- public static abstract class AbstractFilteredNavigableSetTest
- extends AbstractFilteredSortedSetTest<NavigableSet<Integer>> {
-
- public void testNavigableHeadSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- for (boolean inclusive : ImmutableList.of(true, false)) {
- assertEquals(
- filter(createUnfiltered(contents).headSet(i, inclusive), EVEN),
- filter(createUnfiltered(contents), EVEN).headSet(i, inclusive));
- }
- }
- }
- }
-
- public void testNavigableTailSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- for (boolean inclusive : ImmutableList.of(true, false)) {
- assertEquals(
- filter(createUnfiltered(contents).tailSet(i, inclusive), EVEN),
- filter(createUnfiltered(contents), EVEN).tailSet(i, inclusive));
- }
- }
- }
- }
-
- public void testNavigableSubSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- for (int i = 0; i < 10; i++) {
- for (int j = i + 1; j < 10; j++) {
- for (boolean fromInclusive : ImmutableList.of(true, false)) {
- for (boolean toInclusive : ImmutableList.of(true, false)) {
- NavigableSet<Integer> filterSubset = filter(
- createUnfiltered(contents).subSet(i, fromInclusive, j, toInclusive), EVEN);
- NavigableSet<Integer> subsetFilter = filter(createUnfiltered(contents), EVEN)
- .subSet(i, fromInclusive, j, toInclusive);
- assertEquals(filterSubset, subsetFilter);
- }
- }
- }
- }
- }
- }
-
- public void testDescendingSet() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
- NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
-
- ASSERT.that(filtered.descendingSet()).has().allFrom(unfiltered.descendingSet()).inOrder();
- }
- }
-
- public void testPollFirst() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
- NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
-
- assertEquals(unfiltered.pollFirst(), filtered.pollFirst());
- assertEquals(unfiltered, filtered);
- }
- }
-
- public void testPollLast() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
- NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
-
- assertEquals(unfiltered.pollLast(), filtered.pollLast());
- assertEquals(unfiltered, filtered);
- }
- }
-
- public void testNavigation() {
- for (List<Integer> contents : SAMPLE_INPUTS) {
- NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
- NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
- for (int i = 0; i < 10; i++) {
- assertEquals(unfiltered.lower(i), filtered.lower(i));
- assertEquals(unfiltered.floor(i), filtered.floor(i));
- assertEquals(unfiltered.ceiling(i), filtered.ceiling(i));
- assertEquals(unfiltered.higher(i), filtered.higher(i));
- }
- }
- }
- }
-
- // implementation tests
-
- public static final class IterablesFilterArrayListTest
- extends AbstractFilteredIterableTest<Iterable<Integer>> {
- @Override
- Iterable<Integer> createUnfiltered(Iterable<Integer> contents) {
- return Lists.newArrayList(contents);
- }
-
- @Override
- Iterable<Integer> filter(Iterable<Integer> elements, Predicate<? super Integer> predicate) {
- return Iterables.filter(elements, predicate);
- }
- }
-
- public static final class Collections2FilterArrayListTest
- extends AbstractFilteredCollectionTest<Collection<Integer>> {
- @Override
- Collection<Integer> createUnfiltered(Iterable<Integer> contents) {
- return Lists.newArrayList(contents);
- }
-
- @Override
- Collection<Integer> filter(Collection<Integer> elements, Predicate<? super Integer> predicate) {
- return Collections2.filter(elements, predicate);
- }
- }
-
- public static final class SetsFilterHashSetTest
- extends AbstractFilteredSetTest<Set<Integer>> {
- @Override
- Set<Integer> createUnfiltered(Iterable<Integer> contents) {
- return Sets.newHashSet(contents);
- }
-
- @Override
- Set<Integer> filter(Set<Integer> elements, Predicate<? super Integer> predicate) {
- return Sets.filter(elements, predicate);
- }
- }
-
- public static final class SetsFilterSortedSetTest
- extends AbstractFilteredSortedSetTest<SortedSet<Integer>> {
- @Override
- SortedSet<Integer> createUnfiltered(Iterable<Integer> contents) {
- final TreeSet<Integer> result = Sets.newTreeSet(contents);
- // we have to make the result not Navigable
- return new ForwardingSortedSet<Integer>() {
- @Override
- protected SortedSet<Integer> delegate() {
- return result;
- }
- };
- }
-
- @Override
- SortedSet<Integer> filter(SortedSet<Integer> elements, Predicate<? super Integer> predicate) {
- return Sets.filter(elements, predicate);
- }
- }
-
- public static final class SetsFilterNavigableSetTest extends AbstractFilteredNavigableSetTest {
- @Override
- NavigableSet<Integer> createUnfiltered(Iterable<Integer> contents) {
- return Sets.newTreeSet(contents);
- }
-
- @Override
- NavigableSet<Integer> filter(
- NavigableSet<Integer> elements, Predicate<? super Integer> predicate) {
- return Sets.filter(elements, predicate);
- }
- }
-
- /** No-op test so that the class has at least one method, making Maven's test runner happy. */
- public void testNoop() {
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/FluentIterableTest.java b/guava-tests/test/com/google/common/collect/FluentIterableTest.java
deleted file mode 100644
index 52dc9ba..0000000
--- a/guava-tests/test/com/google/common/collect/FluentIterableTest.java
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.testing.IteratorFeature;
-import com.google.common.collect.testing.IteratorTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * Unit test for {@link FluentIterable}.
- *
- * @author Marcin Mikosik
- */
-@GwtCompatible(emulated = true)
-public class FluentIterableTest extends TestCase {
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicStaticMethods(FluentIterable.class);
- }
-
- public void testFrom() {
- assertEquals(ImmutableList.of(1, 2, 3, 4),
- Lists.newArrayList(FluentIterable.from(ImmutableList.of(1, 2, 3, 4))));
- }
-
- @SuppressWarnings("deprecation") // test of deprecated method
- public void testFrom_alreadyFluentIterable() {
- FluentIterable<Integer> iterable = FluentIterable.from(asList(1));
- assertSame(iterable, FluentIterable.from(iterable));
- }
-
- public void testSize1Collection() {
- assertEquals(1, FluentIterable.from(asList("a")).size());
- }
-
- public void testSize2NonCollection() {
- Iterable<Integer> iterable = new Iterable<Integer>() {
- @Override
- public Iterator<Integer> iterator() {
- return asList(0, 1).iterator();
- }
- };
- assertEquals(2, FluentIterable.from(iterable).size());
- }
-
- public void testSize_collectionDoesntIterate() {
- List<Integer> nums = asList(1, 2, 3, 4, 5);
- List<Integer> collection = new ArrayList<Integer>(nums) {
- @Override public Iterator<Integer> iterator() {
- fail("Don't iterate me!");
- return null;
- }
- };
- assertEquals(5, FluentIterable.from(collection).size());
- }
-
- public void testContains_nullSetYes() {
- Iterable<String> set = Sets.newHashSet("a", null, "b");
- assertTrue(FluentIterable.from(set).contains(null));
- }
-
- public void testContains_nullSetNo() {
- Iterable<String> set = ImmutableSortedSet.of("a", "b");
- assertFalse(FluentIterable.from(set).contains(null));
- }
-
- public void testContains_nullIterableYes() {
- Iterable<String> iterable = iterable("a", null, "b");
- assertTrue(FluentIterable.from(iterable).contains(null));
- }
-
- public void testContains_nullIterableNo() {
- Iterable<String> iterable = iterable("a", "b");
- assertFalse(FluentIterable.from(iterable).contains(null));
- }
-
- public void testContains_nonNullSetYes() {
- Iterable<String> set = Sets.newHashSet("a", null, "b");
- assertTrue(FluentIterable.from(set).contains("b"));
- }
-
- public void testContains_nonNullSetNo() {
- Iterable<String> set = Sets.newHashSet("a", "b");
- assertFalse(FluentIterable.from(set).contains("c"));
- }
-
- public void testContains_nonNullIterableYes() {
- Iterable<String> set = iterable("a", null, "b");
- assertTrue(FluentIterable.from(set).contains("b"));
- }
-
- public void testContains_nonNullIterableNo() {
- Iterable<String> iterable = iterable("a", "b");
- assertFalse(FluentIterable.from(iterable).contains("c"));
- }
-
- public void testCycle() {
- FluentIterable<String> cycle = FluentIterable.from(asList("a", "b")).cycle();
-
- int howManyChecked = 0;
- for (String string : cycle) {
- String expected = (howManyChecked % 2 == 0) ? "a" : "b";
- assertEquals(expected, string);
- if (howManyChecked++ == 5) {
- break;
- }
- }
-
- // We left the last iterator pointing to "b". But a new iterator should
- // always point to "a".
- assertEquals("a", cycle.iterator().next());
- }
-
- public void testCycle_removingAllElementsStopsCycle() {
- FluentIterable<Integer> cycle = fluent(1, 2).cycle();
- Iterator<Integer> iterator = cycle.iterator();
- iterator.next();
- iterator.remove();
- iterator.next();
- iterator.remove();
- assertFalse(iterator.hasNext());
- assertFalse(cycle.iterator().hasNext());
- }
-
- /*
- * Tests for partition(int size) method.
- */
-
- /*
- * Tests for partitionWithPadding(int size) method.
- */
-
- public void testFilter() {
- FluentIterable<String> filtered =
- FluentIterable.from(asList("foo", "bar")).filter(Predicates.equalTo("foo"));
-
- List<String> expected = Collections.singletonList("foo");
- List<String> actual = Lists.newArrayList(filtered);
- assertEquals(expected, actual);
- assertCanIterateAgain(filtered);
- assertEquals("[foo]", filtered.toString());
- }
-
- private static class TypeA {}
- private interface TypeB {}
- private static class HasBoth extends TypeA implements TypeB {}
-
- @GwtIncompatible("Iterables.filter(Iterable, Class)")
- public void testFilterByType() throws Exception {
- HasBoth hasBoth = new HasBoth();
- FluentIterable<TypeA> alist =
- FluentIterable.from(asList(new TypeA(), new TypeA(), hasBoth, new TypeA()));
- Iterable<TypeB> blist = alist.filter(TypeB.class);
- ASSERT.that(blist).iteratesOverSequence(hasBoth);
- }
-
- public void testAnyMatch() {
- ArrayList<String> list = Lists.newArrayList();
- FluentIterable<String> iterable = FluentIterable.<String>from(list);
- Predicate<String> predicate = Predicates.equalTo("pants");
-
- assertFalse(iterable.anyMatch(predicate));
- list.add("cool");
- assertFalse(iterable.anyMatch(predicate));
- list.add("pants");
- assertTrue(iterable.anyMatch(predicate));
- }
-
- public void testAllMatch() {
- List<String> list = Lists.newArrayList();
- FluentIterable<String> iterable = FluentIterable.<String>from(list);
- Predicate<String> predicate = Predicates.equalTo("cool");
-
- assertTrue(iterable.allMatch(predicate));
- list.add("cool");
- assertTrue(iterable.allMatch(predicate));
- list.add("pants");
- assertFalse(iterable.allMatch(predicate));
- }
-
- public void testFirstMatch() {
- FluentIterable<String> iterable = FluentIterable.from(Lists.newArrayList("cool", "pants"));
- assertEquals(Optional.of("cool"), iterable.firstMatch(Predicates.equalTo("cool")));
- assertEquals(Optional.of("pants"), iterable.firstMatch(Predicates.equalTo("pants")));
- assertEquals(Optional.absent(), iterable.firstMatch(Predicates.alwaysFalse()));
- assertEquals(Optional.of("cool"), iterable.firstMatch(Predicates.alwaysTrue()));
- }
-
- private static final class IntegerValueOfFunction implements Function<String, Integer> {
- @Override
- public Integer apply(String from) {
- return Integer.valueOf(from);
- }
- }
-
- public void testTransformWith() {
- List<String> input = asList("1", "2", "3");
- Iterable<Integer> iterable =
- FluentIterable.from(input).transform(new IntegerValueOfFunction());
-
- assertEquals(asList(1, 2, 3), Lists.newArrayList(iterable));
- assertCanIterateAgain(iterable);
- assertEquals("[1, 2, 3]", iterable.toString());
- }
-
- public void testTransformWith_poorlyBehavedTransform() {
- List<String> input = asList("1", null, "3");
- Iterable<Integer> iterable =
- FluentIterable.from(input).transform(new IntegerValueOfFunction());
-
- Iterator<Integer> resultIterator = iterable.iterator();
- resultIterator.next();
-
- try {
- resultIterator.next();
- fail("Transforming null to int should throw NumberFormatException");
- } catch (NumberFormatException expected) {
- }
- }
-
- private static final class StringValueOfFunction implements Function<Integer, String> {
- @Override
- public String apply(Integer from) {
- return String.valueOf(from);
- }
- }
-
- public void testTransformWith_nullFriendlyTransform() {
- List<Integer> input = asList(1, 2, null, 3);
- Iterable<String> result = FluentIterable.from(input).transform(new StringValueOfFunction());
-
- assertEquals(asList("1", "2", "null", "3"), Lists.newArrayList(result));
- }
-
- private static final class RepeatedStringValueOfFunction
- implements Function<Integer, List<String>> {
- @Override
- public List<String> apply(Integer from) {
- String value = String.valueOf(from);
- return ImmutableList.of(value, value);
- }
- }
-
- public void testTransformAndConcat() {
- List<Integer> input = asList(1, 2, 3);
- Iterable<String> result =
- FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfFunction());
- assertEquals(asList("1", "1", "2", "2", "3", "3"), Lists.newArrayList(result));
- }
-
- private static final class RepeatedStringValueOfWildcardFunction
- implements Function<Integer, List<? extends String>> {
- @Override
- public List<String> apply(Integer from) {
- String value = String.valueOf(from);
- return ImmutableList.of(value, value);
- }
- }
-
- public void testTransformAndConcat_wildcardFunctionGenerics() {
- List<Integer> input = asList(1, 2, 3);
- FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfWildcardFunction());
- }
-
- public void testFirst_list() {
- List<String> list = Lists.newArrayList("a", "b", "c");
- assertEquals("a", FluentIterable.from(list).first().get());
- }
-
- public void testFirst_null() {
- List<String> list = Lists.newArrayList(null, "a", "b");
- try {
- FluentIterable.from(list).first();
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testFirst_emptyList() {
- List<String> list = Collections.emptyList();
- assertEquals(Optional.absent(), FluentIterable.from(list).first());
- }
-
- public void testFirst_sortedSet() {
- SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a");
- assertEquals("a", FluentIterable.from(sortedSet).first().get());
- }
-
- public void testFirst_emptySortedSet() {
- SortedSet<String> sortedSet = ImmutableSortedSet.of();
- assertEquals(Optional.absent(), FluentIterable.from(sortedSet).first());
- }
-
- public void testFirst_iterable() {
- Set<String> set = ImmutableSet.of("a", "b", "c");
- assertEquals("a", FluentIterable.from(set).first().get());
- }
-
- public void testFirst_emptyIterable() {
- Set<String> set = Sets.newHashSet();
- assertEquals(Optional.absent(), FluentIterable.from(set).first());
- }
-
- public void testLast_list() {
- List<String> list = Lists.newArrayList("a", "b", "c");
- assertEquals("c", FluentIterable.from(list).last().get());
- }
-
- public void testLast_null() {
- List<String> list = Lists.newArrayList("a", "b", null);
- try {
- FluentIterable.from(list).last();
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testLast_emptyList() {
- List<String> list = Collections.emptyList();
- assertEquals(Optional.absent(), FluentIterable.from(list).last());
- }
-
- public void testLast_sortedSet() {
- SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a");
- assertEquals("c", FluentIterable.from(sortedSet).last().get());
- }
-
- public void testLast_emptySortedSet() {
- SortedSet<String> sortedSet = ImmutableSortedSet.of();
- assertEquals(Optional.absent(), FluentIterable.from(sortedSet).last());
- }
-
- public void testLast_iterable() {
- Set<String> set = ImmutableSet.of("a", "b", "c");
- assertEquals("c", FluentIterable.from(set).last().get());
- }
-
- public void testLast_emptyIterable() {
- Set<String> set = Sets.newHashSet();
- assertEquals(Optional.absent(), FluentIterable.from(set).last());
- }
-
- public void testSkip_simple() {
- Collection<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
- assertEquals(Lists.newArrayList("c", "d", "e"),
- Lists.newArrayList(FluentIterable.from(set).skip(2)));
- assertEquals("[c, d, e]", FluentIterable.from(set).skip(2).toString());
- }
-
- public void testSkip_simpleList() {
- Collection<String> list = Lists.newArrayList("a", "b", "c", "d", "e");
- assertEquals(Lists.newArrayList("c", "d", "e"),
- Lists.newArrayList(FluentIterable.from(list).skip(2)));
- assertEquals("[c, d, e]", FluentIterable.from(list).skip(2).toString());
- }
-
- public void testSkip_pastEnd() {
- Collection<String> set = ImmutableSet.of("a", "b");
- assertEquals(Collections.emptyList(), Lists.newArrayList(FluentIterable.from(set).skip(20)));
- }
-
- public void testSkip_pastEndList() {
- Collection<String> list = Lists.newArrayList("a", "b");
- assertEquals(Collections.emptyList(), Lists.newArrayList(FluentIterable.from(list).skip(20)));
- }
-
- public void testSkip_skipNone() {
- Collection<String> set = ImmutableSet.of("a", "b");
- assertEquals(Lists.newArrayList("a", "b"),
- Lists.newArrayList(FluentIterable.from(set).skip(0)));
- }
-
- public void testSkip_skipNoneList() {
- Collection<String> list = Lists.newArrayList("a", "b");
- assertEquals(Lists.newArrayList("a", "b"),
- Lists.newArrayList(FluentIterable.from(list).skip(0)));
- }
-
- public void testSkip_iterator() throws Exception {
- new IteratorTester<Integer>(5, IteratorFeature.MODIFIABLE, Lists.newArrayList(2, 3),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- Collection<Integer> collection = Sets.newLinkedHashSet();
- Collections.addAll(collection, 1, 2, 3);
- return FluentIterable.from(collection).skip(1).iterator();
- }
- }.test();
- }
-
- public void testSkip_iteratorList() throws Exception {
- new IteratorTester<Integer>(5, IteratorFeature.MODIFIABLE, Lists.newArrayList(2, 3),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return FluentIterable.from(Lists.newArrayList(1, 2, 3)).skip(1).iterator();
- }
- }.test();
- }
-
- public void testSkip_nonStructurallyModifiedList() throws Exception {
- List<String> list = Lists.newArrayList("a", "b", "c");
- FluentIterable<String> tail = FluentIterable.from(list).skip(1);
- Iterator<String> tailIterator = tail.iterator();
- list.set(2, "c2");
- assertEquals("b", tailIterator.next());
- assertEquals("c2", tailIterator.next());
- assertFalse(tailIterator.hasNext());
- }
-
- public void testSkip_structurallyModifiedSkipSome() throws Exception {
- Collection<String> set = Sets.newLinkedHashSet();
- Collections.addAll(set, "a", "b", "c");
- FluentIterable<String> tail = FluentIterable.from(set).skip(1);
- set.remove("b");
- set.addAll(Lists.newArrayList("X", "Y", "Z"));
- ASSERT.that(tail).iteratesOverSequence("c", "X", "Y", "Z");
- }
-
- public void testSkip_structurallyModifiedSkipSomeList() throws Exception {
- List<String> list = Lists.newArrayList("a", "b", "c");
- FluentIterable<String> tail = FluentIterable.from(list).skip(1);
- list.subList(1, 3).clear();
- list.addAll(0, Lists.newArrayList("X", "Y", "Z"));
- ASSERT.that(tail).iteratesOverSequence("Y", "Z", "a");
- }
-
- public void testSkip_structurallyModifiedSkipAll() throws Exception {
- Collection<String> set = Sets.newLinkedHashSet();
- Collections.addAll(set, "a", "b", "c");
- FluentIterable<String> tail = FluentIterable.from(set).skip(2);
- set.remove("a");
- set.remove("b");
- assertFalse(tail.iterator().hasNext());
- }
-
- public void testSkip_structurallyModifiedSkipAllList() throws Exception {
- List<String> list = Lists.newArrayList("a", "b", "c");
- FluentIterable<String> tail = FluentIterable.from(list).skip(2);
- list.subList(0, 2).clear();
- ASSERT.that(tail).isEmpty();
- }
-
- public void testSkip_illegalArgument() {
- try {
- FluentIterable.from(asList("a", "b", "c")).skip(-1);
- fail("Skipping negative number of elements should throw IllegalArgumentException.");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testLimit() {
- Iterable<String> iterable = Lists.newArrayList("foo", "bar", "baz");
- FluentIterable<String> limited = FluentIterable.from(iterable).limit(2);
-
- assertEquals(ImmutableList.of("foo", "bar"), Lists.newArrayList(limited));
- assertCanIterateAgain(limited);
- assertEquals("[foo, bar]", limited.toString());
- }
-
- public void testLimit_illegalArgument() {
- try {
- FluentIterable.from(Lists.newArrayList("a", "b", "c")).limit(-1);
- fail("Passing negative number to limit(...) method should throw IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testIsEmpty() {
- assertTrue(FluentIterable.<String>from(Collections.<String>emptyList()).isEmpty());
- assertFalse(FluentIterable.<String>from(Lists.newArrayList("foo")).isEmpty());
- }
-
- public void testToList() {
- assertEquals(Lists.newArrayList(1, 2, 3, 4), fluent(1, 2, 3, 4).toList());
- }
-
- public void testToList_empty() {
- assertTrue(fluent().toList().isEmpty());
- }
-
- public void testToSortedList_withComparator() {
- assertEquals(Lists.newArrayList(4, 3, 2, 1),
- fluent(4, 1, 3, 2).toSortedList(Ordering.<Integer>natural().reverse()));
- }
-
- public void testToSortedList_withDuplicates() {
- assertEquals(Lists.newArrayList(4, 3, 1, 1),
- fluent(1, 4, 1, 3).toSortedList(Ordering.<Integer>natural().reverse()));
- }
-
- public void testToSet() {
- ASSERT.that(fluent(1, 2, 3, 4).toSet()).has().allOf(1, 2, 3, 4).inOrder();
- }
-
- public void testToSet_removeDuplicates() {
- ASSERT.that(fluent(1, 2, 1, 2).toSet()).has().allOf(1, 2).inOrder();
- }
-
- public void testToSet_empty() {
- assertTrue(fluent().toSet().isEmpty());
- }
-
- public void testToSortedSet() {
- ASSERT.that(fluent(1, 4, 2, 3).toSortedSet(Ordering.<Integer>natural().reverse()))
- .has().allOf(4, 3, 2, 1).inOrder();
- }
-
- public void testToSortedSet_removeDuplicates() {
- ASSERT.that(fluent(1, 4, 1, 3).toSortedSet(Ordering.<Integer>natural().reverse()))
- .has().allOf(4, 3, 1).inOrder();
- }
-
- public void testToMap() {
- ASSERT.that(fluent(1, 2, 3).toMap(Functions.toStringFunction()).entrySet())
- .has().allOf(
- Maps.immutableEntry(1, "1"),
- Maps.immutableEntry(2, "2"),
- Maps.immutableEntry(3, "3")).inOrder();
- }
-
- public void testToMap_nullKey() {
- try {
- fluent(1, null, 2).toMap(Functions.constant("foo"));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testToMap_nullValue() {
- try {
- fluent(1, 2, 3).toMap(Functions.constant(null));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testIndex() {
- ImmutableListMultimap<Integer, String> expected =
- ImmutableListMultimap.<Integer, String>builder()
- .putAll(3, "one", "two")
- .put(5, "three")
- .put(4, "four")
- .build();
- ImmutableListMultimap<Integer, String> index =
- FluentIterable.from(asList("one", "two", "three", "four")).index(
- new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- });
- assertEquals(expected, index);
- }
-
- public void testIndex_nullKey() {
- try {
- fluent(1, 2, 3).index(Functions.constant(null));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testIndex_nullValue() {
- try {
- fluent(1, null, 2).index(Functions.constant("foo"));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testUniqueIndex() {
- ImmutableMap<Integer, String> expected =
- ImmutableMap.of(3, "two", 5, "three", 4, "four");
- ImmutableMap<Integer, String> index =
- FluentIterable.from(asList("two", "three", "four")).uniqueIndex(
- new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- });
- assertEquals(expected, index);
- }
-
- public void testUniqueIndex_duplicateKey() {
- try {
- FluentIterable.from(asList("one", "two", "three", "four")).uniqueIndex(
- new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- });
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testUniqueIndex_nullKey() {
- try {
- fluent(1, 2, 3).uniqueIndex(Functions.constant(null));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testUniqueIndex_nullValue() {
- try {
- fluent(1, null, 2).uniqueIndex(new Function<Integer, Object>() {
- @Override
- public Object apply(@Nullable Integer input) {
- return String.valueOf(input);
- }
- });
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testCopyInto_List() {
- ASSERT.that(fluent(1, 3, 5).copyInto(Lists.newArrayList(1, 2)))
- .has().allOf(1, 2, 1, 3, 5).inOrder();
- }
-
- public void testCopyInto_Set() {
- ASSERT.that(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2)))
- .has().allOf(1, 2, 3, 5);
- }
-
- public void testCopyInto_SetAllDuplicates() {
- ASSERT.that(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2, 3, 5)))
- .has().allOf(1, 2, 3, 5);
- }
-
- public void testCopyInto_NonCollection() {
- final ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
-
- final ArrayList<Integer> iterList = Lists.newArrayList(9, 8, 7);
- Iterable<Integer> iterable = new Iterable<Integer>() {
- @Override
- public Iterator<Integer> iterator() {
- return iterList.iterator();
- }
- };
-
- ASSERT.that(FluentIterable.from(iterable).copyInto(list))
- .has().allOf(1, 2, 3, 9, 8, 7).inOrder();
- }
-
- public void testGet() {
- assertEquals("a", FluentIterable
- .from(Lists.newArrayList("a", "b", "c")).get(0));
- assertEquals("b", FluentIterable
- .from(Lists.newArrayList("a", "b", "c")).get(1));
- assertEquals("c", FluentIterable
- .from(Lists.newArrayList("a", "b", "c")).get(2));
- }
-
- public void testGet_outOfBounds() {
- try {
- FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(-1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
-
- try {
- FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(3);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- private static void assertCanIterateAgain(Iterable<?> iterable) {
- for (@SuppressWarnings("unused") Object obj : iterable) {
- }
- }
-
- private static FluentIterable<Integer> fluent(Integer... elements) {
- return FluentIterable.from(Lists.newArrayList(elements));
- }
-
- private static Iterable<String> iterable(String... elements) {
- final List<String> list = asList(elements);
- return new Iterable<String>() {
- @Override
- public Iterator<String> iterator() {
- return list.iterator();
- }
- };
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java b/guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java
deleted file mode 100644
index ecb67bb..0000000
--- a/guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test for {@link ForwardingBlockingDeque}
- *
- * @author Emily Soldal
- */
-public class ForwardingBlockingDequeTest extends ForwardingTestCase {
- private BlockingDeque<String> forward;
-
- /*
- * Class parameters must be raw, so we can't create a proxy with generic
- * type arguments. The created proxy only records calls and returns null, so
- * the type is irrelevant at runtime.
- */
- @SuppressWarnings("unchecked")
- @Override protected void setUp() throws Exception {
- super.setUp();
- final BlockingDeque<String> deque = createProxyInstance(BlockingDeque.class);
- forward = new ForwardingBlockingDeque<String>() {
- @Override protected BlockingDeque<String> delegate() {
- return deque;
- }
- };
- }
-
- public void testRemainingCapacity() {
- forward.remainingCapacity();
- assertEquals("[remainingCapacity]", getCalls());
- }
-
- public void testPutFirst_T() throws InterruptedException {
- forward.putFirst("asf");
- assertEquals("[putFirst(Object)]", getCalls());
- }
-
- public void testPutLast_T() throws InterruptedException {
- forward.putFirst("asf");
- assertEquals("[putFirst(Object)]", getCalls());
- }
-
- public void testOfferFirst_T() throws InterruptedException {
- forward.offerFirst("asf", 2L, TimeUnit.SECONDS);
- assertEquals("[offerFirst(Object,long,TimeUnit)]", getCalls());
- }
-
- public void testOfferLast_T() throws InterruptedException {
- forward.offerLast("asf", 2L, TimeUnit.SECONDS);
- assertEquals("[offerLast(Object,long,TimeUnit)]", getCalls());
- }
-
- public void testTakeFirst() throws InterruptedException {
- forward.takeFirst();
- assertEquals("[takeFirst]", getCalls());
- }
-
- public void testTakeLast() throws InterruptedException {
- forward.takeLast();
- assertEquals("[takeLast]", getCalls());
- }
-
- public void testPollFirst() throws InterruptedException {
- forward.pollFirst(2L, TimeUnit.SECONDS);
- assertEquals("[pollFirst(long,TimeUnit)]", getCalls());
- }
-
- public void testPollLast() throws InterruptedException {
- forward.pollLast(2L, TimeUnit.SECONDS);
- assertEquals("[pollLast(long,TimeUnit)]", getCalls());
- }
-
- public void testPut_T() throws InterruptedException {
- forward.put("asf");
- assertEquals("[put(Object)]", getCalls());
- }
-
- public void testOffer_T() throws InterruptedException {
- forward.offer("asf", 2L, TimeUnit.SECONDS);
- assertEquals("[offer(Object,long,TimeUnit)]", getCalls());
- }
-
- public void testTake() throws InterruptedException {
- forward.take();
- assertEquals("[take]", getCalls());
- }
-
- public void testPoll() throws InterruptedException {
- forward.poll(2L, TimeUnit.SECONDS);
- assertEquals("[poll(long,TimeUnit)]", getCalls());
- }
-
- public void testDrainTo_T() {
- forward.drainTo(Lists.newArrayList());
- assertEquals("[drainTo(Collection)]", getCalls());
- }
-
- public void testDrainTo_T_maxElements() {
- forward.drainTo(Lists.newArrayList(), 3);
- assertEquals("[drainTo(Collection,int)]", getCalls());
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java b/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java
index bf45998..47942c5 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java
@@ -96,7 +96,7 @@ public class ForwardingCollectionTest extends ForwardingTestCase {
private Collection<String> forward;
- public static Test suite() {
+ public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingCollectionTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingDequeTest.java b/guava-tests/test/com/google/common/collect/ForwardingDequeTest.java
deleted file mode 100644
index 0ff18fb..0000000
--- a/guava-tests/test/com/google/common/collect/ForwardingDequeTest.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Collections;
-import java.util.Deque;
-
-/**
- * Tests for {@code ForwardingDeque}.
- *
- * @author Kurt Alfred Kluever
- */
-public class ForwardingDequeTest extends ForwardingTestCase {
- private Deque<String> forward;
-
- /*
- * Class parameters must be raw, so we can't create a proxy with generic
- * type arguments. The created proxy only records calls and returns null, so
- * the type is irrelevant at runtime.
- */
- @SuppressWarnings("unchecked")
- @Override protected void setUp() throws Exception {
- super.setUp();
- final Deque<String> deque = createProxyInstance(Deque.class);
- forward = new ForwardingDeque<String>() {
- @Override protected Deque<String> delegate() {
- return deque;
- }
- };
- }
-
- public void testAdd_T() {
- forward.add("asdf");
- assertEquals("[add(Object)]", getCalls());
- }
-
- public void testAddFirst_T() {
- forward.addFirst("asdf");
- assertEquals("[addFirst(Object)]", getCalls());
- }
-
- public void testAddLast_T() {
- forward.addLast("asdf");
- assertEquals("[addLast(Object)]", getCalls());
- }
-
- public void testAddAll_Collection() {
- forward.addAll(Collections.singleton("asdf"));
- assertEquals("[addAll(Collection)]", getCalls());
- }
-
- public void testClear() {
- forward.clear();
- assertEquals("[clear]", getCalls());
- }
-
- public void testContains_T() {
- forward.contains("asdf");
- assertEquals("[contains(Object)]", getCalls());
- }
-
- public void testContainsAll_Collection() {
- forward.containsAll(Collections.singleton("asdf"));
- assertEquals("[containsAll(Collection)]", getCalls());
- }
-
- public void testDescendingIterator() {
- forward.descendingIterator();
- assertEquals("[descendingIterator]", getCalls());
- }
-
- public void testElement() {
- forward.element();
- assertEquals("[element]", getCalls());
- }
-
- public void testGetFirst() {
- forward.getFirst();
- assertEquals("[getFirst]", getCalls());
- }
-
- public void testGetLast() {
- forward.getLast();
- assertEquals("[getLast]", getCalls());
- }
-
- public void testIterator() {
- forward.iterator();
- assertEquals("[iterator]", getCalls());
- }
-
- public void testIsEmpty() {
- forward.isEmpty();
- assertEquals("[isEmpty]", getCalls());
- }
-
- public void testOffer_T() {
- forward.offer("asdf");
- assertEquals("[offer(Object)]", getCalls());
- }
-
- public void testOfferFirst_T() {
- forward.offerFirst("asdf");
- assertEquals("[offerFirst(Object)]", getCalls());
- }
-
- public void testOfferLast_T() {
- forward.offerLast("asdf");
- assertEquals("[offerLast(Object)]", getCalls());
- }
-
- public void testPeek() {
- forward.peek();
- assertEquals("[peek]", getCalls());
- }
-
- public void testPeekFirst() {
- forward.peekFirst();
- assertEquals("[peekFirst]", getCalls());
- }
-
- public void testPeekLast() {
- forward.peekLast();
- assertEquals("[peekLast]", getCalls());
- }
-
- public void testPoll() {
- forward.poll();
- assertEquals("[poll]", getCalls());
- }
-
- public void testPollFirst() {
- forward.pollFirst();
- assertEquals("[pollFirst]", getCalls());
- }
-
- public void testPollLast() {
- forward.pollLast();
- assertEquals("[pollLast]", getCalls());
- }
-
- public void testPop() {
- forward.pop();
- assertEquals("[pop]", getCalls());
- }
-
- public void testPush_Object() {
- forward.push("asdf");
- assertEquals("[push(Object)]", getCalls());
- }
-
- public void testRemove() {
- forward.remove();
- assertEquals("[remove]", getCalls());
- }
-
- public void testRemoveFirst() {
- forward.removeFirst();
- assertEquals("[removeFirst]", getCalls());
- }
-
- public void testRemoveLast() {
- forward.removeLast();
- assertEquals("[removeLast]", getCalls());
- }
-
- public void testRemove_Object() {
- forward.remove(Object.class);
- assertEquals("[remove(Object)]", getCalls());
- }
-
- public void testRemoveFirstOccurrence_Object() {
- forward.removeFirstOccurrence(Object.class);
- assertEquals("[removeFirstOccurrence(Object)]", getCalls());
- }
-
- public void testRemoveLastOccurrence_Object() {
- forward.removeLastOccurrence(Object.class);
- assertEquals("[removeLastOccurrence(Object)]", getCalls());
- }
-
- public void testRemoveAll_Collection() {
- forward.removeAll(Collections.singleton("asdf"));
- assertEquals("[removeAll(Collection)]", getCalls());
- }
-
- public void testRetainAll_Collection() {
- forward.retainAll(Collections.singleton("asdf"));
- assertEquals("[retainAll(Collection)]", getCalls());
- }
-
- public void testSize() {
- forward.size();
- assertEquals("[size]", getCalls());
- }
-
- public void testToArray() {
- forward.toArray();
- assertEquals("[toArray]", getCalls());
- }
-
- public void testToArray_TArray() {
- forward.toArray(new String[0]);
- assertEquals("[toArray(Object[])]", getCalls());
- }
-
- public void testToString() {
- forward.toString();
- assertEquals("[toString]", getCalls());
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingListTest.java b/guava-tests/test/com/google/common/collect/ForwardingListTest.java
index a6a71b4..aaa106e 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingListTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingListTest.java
@@ -137,7 +137,7 @@ public class ForwardingListTest extends ForwardingTestCase {
private List<String> forward;
- public static Test suite() {
+ public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingListTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
index 6874627..1f92e90 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
@@ -24,7 +24,6 @@ import static org.easymock.EasyMock.verify;
import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.TestStringMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
@@ -132,8 +131,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
}).named("ForwardingMap[LinkedHashMap] with standard implementations")
.withFeatures(CollectionSize.ANY, MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER)
+ MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE)
.createTestSuite());
suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
@@ -149,7 +147,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
}).named("ForwardingMap[ImmutableMap] with standard implementations")
.withFeatures(
CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- MapFeature.ALLOWS_NULL_QUERIES, CollectionFeature.KNOWN_ORDER)
+ MapFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
return suite;
@@ -245,7 +243,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
forward().hashCode();
assertEquals("[hashCode]", getCalls());
}
-
+
public void testStandardEntrySet() throws InvocationTargetException {
@SuppressWarnings("unchecked")
final Map<String, Boolean> map = createMock(Map.class);
@@ -282,7 +280,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
verify(map, entrySet);
}
-
+
public void testStandardKeySet() throws InvocationTargetException {
@SuppressWarnings("unchecked")
Set<Entry<String, Boolean>> entrySet = createMock(Set.class);
@@ -314,7 +312,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
verify(entrySet, map);
}
-
+
public void testStandardValues() throws InvocationTargetException {
@SuppressWarnings("unchecked")
Set<Entry<String, Boolean>> entrySet = createMock(Set.class);
@@ -346,34 +344,6 @@ public class ForwardingMapTest extends ForwardingTestCase {
verify(entrySet, map);
}
- public void testToStringWithNullKeys() throws Exception {
- Map<String, String> hashmap = Maps.newHashMap();
- hashmap.put("foo", "bar");
- hashmap.put(null, "baz");
-
- StandardImplForwardingMap<String, String> forwardingMap =
- new StandardImplForwardingMap<String, String>(
- Maps.<String, String>newHashMap());
- forwardingMap.put("foo", "bar");
- forwardingMap.put(null, "baz");
-
- assertEquals(hashmap.toString(), forwardingMap.toString());
- }
-
- public void testToStringWithNullValues() throws Exception {
- Map<String, String> hashmap = Maps.newHashMap();
- hashmap.put("foo", "bar");
- hashmap.put("baz", null);
-
- StandardImplForwardingMap<String, String> forwardingMap =
- new StandardImplForwardingMap<String, String>(
- Maps.<String, String>newHashMap());
- forwardingMap.put("foo", "bar");
- forwardingMap.put("baz", null);
-
- assertEquals(hashmap.toString(), forwardingMap.toString());
- }
-
Map<String, Boolean> forward() {
return forward;
}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java b/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java
index f6c903c..a7d4d8c 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java
@@ -183,7 +183,7 @@ public class ForwardingMultisetTest extends ForwardingTestCase {
@Override public Set<String> elementSet() {
return new StandardElementSet();
}
-
+
@Override public int add(String element, int occurrences) {
throw new UnsupportedOperationException();
}
@@ -259,7 +259,7 @@ public class ForwardingMultisetTest extends ForwardingTestCase {
}
}).named("standardElementSet tripwire").withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.SUPPORTS_REMOVE).createTestSuite());
+ CollectionFeature.REMOVE_OPERATIONS).createTestSuite());
return suite;
}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java
deleted file mode 100644
index 16e2400..0000000
--- a/guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.Maps.immutableEntry;
-
-import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
-import com.google.common.collect.testing.SafeTreeMap;
-import com.google.common.collect.testing.TestStringSortedMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedMap;
-
-/**
- * Tests for {@code ForwardingNavigableMap}.
- *
- * @author Robert Konigsberg
- * @author Louis Wasserman
- */
-public class ForwardingNavigableMapTest extends ForwardingSortedMapTest {
- static class StandardImplForwardingNavigableMap<K, V>
- extends ForwardingNavigableMap<K, V> {
- private final NavigableMap<K, V> backingMap;
-
- StandardImplForwardingNavigableMap(NavigableMap<K, V> backingMap) {
- this.backingMap = backingMap;
- }
-
- @Override protected NavigableMap<K, V> delegate() {
- return backingMap;
- }
-
- @Override public boolean containsKey(Object key) {
- return standardContainsKey(key);
- }
-
- @Override public boolean containsValue(Object value) {
- return standardContainsValue(value);
- }
-
- @Override public void putAll(Map<? extends K, ? extends V> map) {
- standardPutAll(map);
- }
-
- @Override public V remove(Object object) {
- return standardRemove(object);
- }
-
- @Override public boolean equals(Object object) {
- return standardEquals(object);
- }
-
- @Override public int hashCode() {
- return standardHashCode();
- }
-
- @Override public Set<K> keySet() {
- /*
- * We can't use StandardKeySet, as NavigableMapTestSuiteBuilder assumes that our keySet is a
- * NavigableSet. We test StandardKeySet in the superclass, so it's still covered.
- */
- return navigableKeySet();
- }
-
- @Override public Collection<V> values() {
- return new StandardValues();
- }
-
- @Override public String toString() {
- return standardToString();
- }
-
- @Override public Set<Entry<K, V>> entrySet() {
- return new StandardEntrySet() {
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return backingMap.entrySet().iterator();
- }
- };
- }
-
- @Override public void clear() {
- standardClear();
- }
-
- @Override public boolean isEmpty() {
- return standardIsEmpty();
- }
-
- @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return standardSubMap(fromKey, toKey);
- }
-
- @Override
- public Entry<K, V> lowerEntry(K key) {
- return standardLowerEntry(key);
- }
-
- @Override
- public K lowerKey(K key) {
- return standardLowerKey(key);
- }
-
- @Override
- public Entry<K, V> floorEntry(K key) {
- return standardFloorEntry(key);
- }
-
- @Override
- public K floorKey(K key) {
- return standardFloorKey(key);
- }
-
- @Override
- public Entry<K, V> ceilingEntry(K key) {
- return standardCeilingEntry(key);
- }
-
- @Override
- public K ceilingKey(K key) {
- return standardCeilingKey(key);
- }
-
- @Override
- public Entry<K, V> higherEntry(K key) {
- return standardHigherEntry(key);
- }
-
- @Override
- public K higherKey(K key) {
- return standardHigherKey(key);
- }
-
- @Override
- public Entry<K, V> firstEntry() {
- return standardFirstEntry();
- }
-
- /*
- * We can't override lastEntry to delegate to standardLastEntry, as it would create an infinite
- * loop. Instead, we test standardLastEntry manually below.
- */
-
- @Override
- public Entry<K, V> pollFirstEntry() {
- return standardPollFirstEntry();
- }
-
- @Override
- public Entry<K, V> pollLastEntry() {
- return standardPollLastEntry();
- }
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- return new StandardDescendingMap();
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return new StandardNavigableKeySet();
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return standardDescendingKeySet();
- }
-
- @Override
- public K firstKey() {
- return standardFirstKey();
- }
-
- @Override
- public SortedMap<K, V> headMap(K toKey) {
- return standardHeadMap(toKey);
- }
-
- @Override
- public K lastKey() {
- return standardLastKey();
- }
-
- @Override
- public SortedMap<K, V> tailMap(K fromKey) {
- return standardTailMap(fromKey);
- }
- }
-
- static class StandardLastEntryForwardingNavigableMap<K, V>
- extends ForwardingNavigableMap<K, V> {
- private final NavigableMap<K, V> backingMap;
-
- StandardLastEntryForwardingNavigableMap(NavigableMap<K, V> backingMap) {
- this.backingMap = backingMap;
- }
-
- @Override protected NavigableMap<K, V> delegate() {
- return backingMap;
- }
-
- @Override
- public Entry<K, V> lastEntry() {
- return standardLastEntry();
- }
- }
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTestSuite(ForwardingNavigableMapTest.class);
- suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- NavigableMap<String, String> map = new SafeTreeMap<String, String>();
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- return new StandardImplForwardingNavigableMap<String, String>(map);
- }
- }).named("ForwardingNavigableMap[SafeTreeMap] with no comparator and standard "
- + "implementations").withFeatures(CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE).createTestSuite());
- // TODO(user): add forwarding-to-ImmutableSortedMap test
- return suite;
- }
-
- @Override public void setUp() throws Exception {
- super.setUp();
- /*
- * Class parameters must be raw, so we can't create a proxy with generic
- * type arguments. The created proxy only records calls and returns null, so
- * the type is irrelevant at runtime.
- */
- @SuppressWarnings("unchecked")
- final NavigableMap<String, Boolean> sortedMap =
- createProxyInstance(NavigableMap.class);
- forward = new ForwardingNavigableMap<String, Boolean>() {
- @Override protected NavigableMap<String, Boolean> delegate() {
- return sortedMap;
- }
- };
- }
-
- public void testStandardLastEntry() {
- NavigableMap<String, Integer> forwarding =
- new StandardLastEntryForwardingNavigableMap<String, Integer>(
- new SafeTreeMap<String, Integer>());
- assertNull(forwarding.lastEntry());
- forwarding.put("b", 2);
- assertEquals(immutableEntry("b", 2), forwarding.lastEntry());
- forwarding.put("c", 3);
- assertEquals(immutableEntry("c", 3), forwarding.lastEntry());
- forwarding.put("a", 1);
- assertEquals(immutableEntry("c", 3), forwarding.lastEntry());
- forwarding.remove("c");
- assertEquals(immutableEntry("b", 2), forwarding.lastEntry());
- }
-
- public void testLowerEntry() {
- forward().lowerEntry("key");
- assertEquals("[lowerEntry(Object)]", getCalls());
- }
-
- public void testLowerKey() {
- forward().lowerKey("key");
- assertEquals("[lowerKey(Object)]", getCalls());
- }
-
- public void testFloorEntry() {
- forward().floorEntry("key");
- assertEquals("[floorEntry(Object)]", getCalls());
- }
-
- public void testFloorKey() {
- forward().floorKey("key");
- assertEquals("[floorKey(Object)]", getCalls());
- }
-
- public void testCeilingEntry() {
- forward().ceilingEntry("key");
- assertEquals("[ceilingEntry(Object)]", getCalls());
- }
-
- public void testCeilingKey() {
- forward().ceilingKey("key");
- assertEquals("[ceilingKey(Object)]", getCalls());
- }
-
- public void testHigherEntry() {
- forward().higherEntry("key");
- assertEquals("[higherEntry(Object)]", getCalls());
- }
-
- public void testHigherKey() {
- forward().higherKey("key");
- assertEquals("[higherKey(Object)]", getCalls());
- }
-
- public void testPollFirstEntry() {
- forward().pollFirstEntry();
- assertEquals("[pollFirstEntry]", getCalls());
- }
-
- public void testPollLastEntry() {
- forward().pollLastEntry();
- assertEquals("[pollLastEntry]", getCalls());
- }
-
- public void testFirstEntry() {
- forward().firstEntry();
- assertEquals("[firstEntry]", getCalls());
- }
-
- public void testLastEntry() {
- forward().lastEntry();
- assertEquals("[lastEntry]", getCalls());
- }
-
- public void testDescendingMap() {
- forward().descendingMap();
- assertEquals("[descendingMap]", getCalls());
- }
-
- public void testNavigableKeySet() {
- forward().navigableKeySet();
- assertEquals("[navigableKeySet]", getCalls());
- }
-
- public void testDescendingKeySet() {
- forward().descendingKeySet();
- assertEquals("[descendingKeySet]", getCalls());
- }
-
- public void testSubMap_K_Bool_K_Bool() {
- forward().subMap("a", false, "b", true);
- assertEquals("[subMap(Object,boolean,Object,boolean)]", getCalls());
- }
-
- public void testHeadMap_K_Bool() {
- forward().headMap("a", false);
- assertEquals("[headMap(Object,boolean)]", getCalls());
- }
-
- public void testTailMap_K_Bool() {
- forward().tailMap("a", false);
- assertEquals("[tailMap(Object,boolean)]", getCalls());
- }
-
- @Override NavigableMap<String, Boolean> forward() {
- return (NavigableMap<String, Boolean>) super.forward();
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java
deleted file mode 100644
index 37b65f0..0000000
--- a/guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.collect.testing.SafeTreeSet;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * Tests for {@code ForwardingNavigableSet}.
- *
- * @author Louis Wasserman
- */
-public class ForwardingNavigableSetTest extends ForwardingSortedSetTest {
- static class StandardImplForwardingNavigableSet<T>
- extends ForwardingNavigableSet<T> {
- private final NavigableSet<T> backingSet;
-
- StandardImplForwardingNavigableSet(NavigableSet<T> backingSet) {
- this.backingSet = backingSet;
- }
-
- @Override protected NavigableSet<T> delegate() {
- return backingSet;
- }
-
- @Override public boolean equals(Object object) {
- return standardEquals(object);
- }
-
- @Override public int hashCode() {
- return standardHashCode();
- }
-
- @Override public boolean addAll(Collection<? extends T> collection) {
- return standardAddAll(collection);
- }
-
- @Override public void clear() {
- standardClear();
- }
-
- @Override public boolean contains(Object object) {
- return standardContains(object);
- }
-
- @Override public boolean containsAll(Collection<?> collection) {
- return standardContainsAll(collection);
- }
-
- @Override public boolean remove(Object object) {
- return standardRemove(object);
- }
-
- @Override public boolean removeAll(Collection<?> collection) {
- return standardRemoveAll(collection);
- }
-
- @Override public boolean retainAll(Collection<?> collection) {
- return standardRetainAll(collection);
- }
-
- @Override public Object[] toArray() {
- return standardToArray();
- }
-
- @Override public <T> T[] toArray(T[] array) {
- return standardToArray(array);
- }
-
- @Override public String toString() {
- return standardToString();
- }
-
- @Override public SortedSet<T> subSet(T fromElement, T toElement) {
- return standardSubSet(fromElement, toElement);
- }
-
- @Override
- public T lower(T e) {
- return standardLower(e);
- }
-
- @Override
- public T floor(T e) {
- return standardFloor(e);
- }
-
- @Override
- public T ceiling(T e) {
- return standardCeiling(e);
- }
-
- @Override
- public T higher(T e) {
- return standardHigher(e);
- }
-
- @Override
- public T pollFirst() {
- return standardPollFirst();
- }
-
- @Override
- public T pollLast() {
- return standardPollLast();
- }
-
- @Override
- public SortedSet<T> headSet(T toElement) {
- return standardHeadSet(toElement);
- }
-
- @Override
- public SortedSet<T> tailSet(T fromElement) {
- return standardTailSet(fromElement);
- }
- }
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTestSuite(ForwardingNavigableSetTest.class);
- suite.addTest(
- SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- return new StandardImplForwardingNavigableSet<String>(
- new SafeTreeSet<String>(Arrays.asList(elements)));
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
- }
- }).named(
- "ForwardingNavigableSet[SafeTreeSet] with standard implementations")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE).createTestSuite());
- suite.addTest(
- SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SafeTreeSet<String> set = new SafeTreeSet<String>(Ordering.natural().nullsFirst());
- set.addAll(Arrays.asList(elements));
- return new StandardImplForwardingNavigableSet<String>(set);
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
- }
- }).named(
- "ForwardingNavigableSet[SafeTreeSet[Ordering.natural.nullsFirst]]"
- + " with standard implementations")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES)
- .createTestSuite());
-
- return suite;
- }
-
- @Override public void setUp() throws Exception {
- super.setUp();
- /*
- * Class parameters must be raw, so we can't create a proxy with generic
- * type arguments. The created proxy only records calls and returns null, so
- * the type is irrelevant at runtime.
- */
- @SuppressWarnings("unchecked")
- final NavigableSet<String> navigableSet
- = createProxyInstance(NavigableSet.class);
- forward = new ForwardingNavigableSet<String>() {
- @Override protected NavigableSet<String> delegate() {
- return navigableSet;
- }
- };
- }
-
- public void testLower() {
- forward().lower("a");
- assertEquals("[lower(Object)]", getCalls());
- }
-
- public void testFloor() {
- forward().floor("a");
- assertEquals("[floor(Object)]", getCalls());
- }
-
- public void testCeiling() {
- forward().ceiling("a");
- assertEquals("[ceiling(Object)]", getCalls());
- }
-
- public void testHigher() {
- forward().higher("a");
- assertEquals("[higher(Object)]", getCalls());
- }
-
- public void testPollFirst() {
- forward().pollFirst();
- assertEquals("[pollFirst]", getCalls());
- }
-
- public void testPollLast() {
- forward().pollLast();
- assertEquals("[pollLast]", getCalls());
- }
-
- public void testDescendingIterator() {
- forward().descendingIterator();
- assertEquals("[descendingIterator]", getCalls());
- }
-
- public void testHeadSet_K_Boolean() {
- forward().headSet("key", false);
- assertEquals("[headSet(Object,boolean)]", getCalls());
- }
-
- public void testSubSet_K_Boolean_K_Boolean() {
- forward().subSet("a", true, "b", false);
- assertEquals("[subSet(Object,boolean,Object,boolean)]", getCalls());
- }
-
- public void testTailSet_K_Boolean() {
- forward().tailSet("key", false);
- assertEquals("[tailSet(Object,boolean)]", getCalls());
- }
-
- @Override NavigableSet<String> forward() {
- return (NavigableSet<String>) super.forward();
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java b/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java
index 6c3a2b6..c8f0bfe 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java
@@ -106,7 +106,7 @@ public class ForwardingQueueTest extends ForwardingTestCase {
private Queue<String> forward;
private Queue<String> queue;
- public static Test suite() {
+ public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingQueueTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSetTest.java
index c4b7b3c..19484fc 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingSetTest.java
@@ -104,7 +104,7 @@ public class ForwardingSetTest extends ForwardingTestCase {
Set<String> forward;
- public static Test suite() {
+ public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingSetTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java
index 2f0e46d..54947ba 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java
@@ -16,10 +16,9 @@
package com.google.common.collect;
-import com.google.common.collect.testing.Helpers.NullsBeforeTwo;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.SafeTreeMap;
-import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSortedMapGenerator;
+import com.google.common.collect.testing.TestStringMapGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
@@ -30,6 +29,7 @@ import junit.framework.TestSuite;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -115,8 +115,8 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingSortedMapTest.class);
- suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
Entry<String, String>[] entries) {
SortedMap<String, String> map = new SafeTreeMap<String, String>();
for (Entry<String, String> entry : entries) {
@@ -124,14 +124,20 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
}
return new StandardImplForwardingSortedMap<String, String>(map);
}
+
+ @Override public Iterable<Entry<String, String>> order(
+ List<Entry<String, String>> insertionOrder) {
+ return sort(insertionOrder);
+ }
}).named("ForwardingSortedMap[SafeTreeMap] with no comparator and standard "
+ "implementations").withFeatures(CollectionSize.ANY,
CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
MapFeature.GENERAL_PURPOSE).createTestSuite());
- suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- private final Comparator<String> comparator = NullsBeforeTwo.INSTANCE;
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ private final Comparator<String> comparator =
+ Ordering.natural().nullsFirst();
- @Override protected SortedMap<String, String> create(
+ @Override protected Map<String, String> create(
Entry<String, String>[] entries) {
SortedMap<String, String> map =
new SafeTreeMap<String, String>(comparator);
@@ -140,13 +146,18 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
}
return new StandardImplForwardingSortedMap<String, String>(map);
}
+
+ @Override public Iterable<Entry<String, String>> order(
+ List<Entry<String, String>> insertionOrder) {
+ return sort(insertionOrder);
+ }
}).named("ForwardingSortedMap[SafeTreeMap] with natural comparator and "
+ "standard implementations").withFeatures(CollectionSize.ANY,
CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE)
.createTestSuite());
- suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
Entry<String, String>[] entries) {
ImmutableSortedMap.Builder<String, String> builder =
ImmutableSortedMap.naturalOrder();
@@ -156,6 +167,11 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
return new StandardImplForwardingSortedMap<String, String>(
builder.build());
}
+
+ @Override public Iterable<Entry<String, String>> order(
+ List<Entry<String, String>> insertionOrder) {
+ return sort(insertionOrder);
+ }
}).named("ForwardingSortedMap[ImmutableSortedMap] with standard "
+ "implementations").withFeatures(
CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
@@ -164,6 +180,16 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
return suite;
}
+
+ private static Iterable<Entry<String, String>> sort(
+ List<Entry<String, String>> entries) {
+ SortedMap<String, String> map =
+ new SafeTreeMap<String, String>(Ordering.natural().nullsFirst());
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ return map.entrySet();
+ }
@Override public void setUp() throws Exception {
super.setUp();
diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java
index 3f51db3..4bf9dd7 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java
@@ -102,7 +102,7 @@ public class ForwardingSortedSetTest extends ForwardingSetTest {
}
}
- public static Test suite() {
+ public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingSortedSetTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingTestCase.java b/guava-tests/test/com/google/common/collect/ForwardingTestCase.java
index 9696176..d43d7b7 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingTestCase.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingTestCase.java
@@ -42,7 +42,7 @@ import java.util.Set;
*/
public abstract class ForwardingTestCase extends TestCase {
- private final List<String> calls = new ArrayList<String>();
+ private List<String> calls = new ArrayList<String>();
private void called(String id) {
calls.add(id);
diff --git a/guava-tests/test/com/google/common/collect/GeneralRangeTest.java b/guava-tests/test/com/google/common/collect/GeneralRangeTest.java
index 46f2e75..a90e5d1 100644
--- a/guava-tests/test/com/google/common/collect/GeneralRangeTest.java
+++ b/guava-tests/test/com/google/common/collect/GeneralRangeTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -17,19 +17,20 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.testing.NullPointerTester;
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.List;
-
/**
* Tests for {@code GeneralRange}.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
@@ -42,7 +43,7 @@ public class GeneralRangeTest extends TestCase {
for (BoundType lboundType : BoundType.values()) {
for (BoundType uboundType : BoundType.values()) {
try {
- GeneralRange.range(ORDERING, 4, lboundType, 2, uboundType);
+ GeneralRange<Integer> range = GeneralRange.range(ORDERING, 4, lboundType, 2, uboundType);
fail("Expected IAE");
} catch (IllegalArgumentException expected) {}
}
@@ -121,7 +122,7 @@ public class GeneralRangeTest extends TestCase {
public void testDoublyBoundedAgainstRange() {
for (BoundType lboundType : BoundType.values()) {
for (BoundType uboundType : BoundType.values()) {
- Range<Integer> range = Range.range(2, lboundType, 4, uboundType);
+ Range<Integer> range = Ranges.range(2, lboundType, 4, uboundType);
GeneralRange<Integer> gRange = GeneralRange.range(ORDERING, 2, lboundType, 4, uboundType);
for (Integer i : IN_ORDER_VALUES) {
assertEquals(i != null && range.contains(i), gRange.contains(i));
@@ -170,16 +171,16 @@ public class GeneralRangeTest extends TestCase {
}
public void testFromRangeAll() {
- assertEquals(GeneralRange.all(Ordering.natural()), GeneralRange.from(Range.all()));
+ assertEquals(GeneralRange.all(Ordering.natural()), GeneralRange.from(Ranges.all()));
}
public void testFromRangeOneEnd() {
for (BoundType endpointType : BoundType.values()) {
assertEquals(GeneralRange.upTo(Ordering.natural(), 3, endpointType),
- GeneralRange.from(Range.upTo(3, endpointType)));
+ GeneralRange.from(Ranges.upTo(3, endpointType)));
assertEquals(GeneralRange.downTo(Ordering.natural(), 3, endpointType),
- GeneralRange.from(Range.downTo(3, endpointType)));
+ GeneralRange.from(Ranges.downTo(3, endpointType)));
}
}
@@ -187,7 +188,7 @@ public class GeneralRangeTest extends TestCase {
for (BoundType lowerType : BoundType.values()) {
for (BoundType upperType : BoundType.values()) {
assertEquals(GeneralRange.range(Ordering.natural(), 3, lowerType, 4, upperType),
- GeneralRange.from(Range.range(3, lowerType, 4, upperType)));
+ GeneralRange.from(Ranges.range(3, lowerType, 4, upperType)));
}
}
}
@@ -203,7 +204,10 @@ public class GeneralRangeTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(GeneralRange.class);
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Comparator.class, Ordering.arbitrary());
+ tester.setDefault(BoundType.class, BoundType.CLOSED);
+ tester.testAllPublicStaticMethods(GeneralRange.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/HashBasedTableTest.java b/guava-tests/test/com/google/common/collect/HashBasedTableTest.java
index 11a1c2c..66f033b 100644
--- a/guava-tests/test/com/google/common/collect/HashBasedTableTest.java
+++ b/guava-tests/test/com/google/common/collect/HashBasedTableTest.java
@@ -23,7 +23,7 @@ import com.google.common.testing.SerializableTester;
/**
* Test cases for {@link HashBasedTable}.
- *
+ *
* @author Jared Levy
*/
@GwtCompatible(emulated = true)
@@ -38,20 +38,20 @@ public class HashBasedTableTest extends AbstractTableTest {
populate(table, data);
return table;
}
-
+
public void testCreateWithValidSizes() {
Table<String, Integer, Character> table1 = HashBasedTable.create(100, 20);
table1.put("foo", 1, 'a');
assertEquals((Character) 'a', table1.get("foo", 1));
-
+
Table<String, Integer, Character> table2 = HashBasedTable.create(100, 0);
table2.put("foo", 1, 'a');
assertEquals((Character) 'a', table2.get("foo", 1));
-
+
Table<String, Integer, Character> table3 = HashBasedTable.create(0, 20);
table3.put("foo", 1, 'a');
assertEquals((Character) 'a', table3.get("foo", 1));
-
+
Table<String, Integer, Character> table4 = HashBasedTable.create(0, 0);
table4.put("foo", 1, 'a');
assertEquals((Character) 'a', table4.get("foo", 1));
@@ -62,29 +62,29 @@ public class HashBasedTableTest extends AbstractTableTest {
HashBasedTable.create(100, -5);
fail();
} catch (IllegalArgumentException expected) {}
-
+
try {
HashBasedTable.create(-5, 20);
fail();
} catch (IllegalArgumentException expected) {}
}
-
+
public void testCreateCopy() {
Table<String, Integer, Character> original
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Table<String, Integer, Character> copy = HashBasedTable.create(original);
assertEquals(original, copy);
- assertEquals((Character) 'a', copy.get("foo", 1));
+ assertEquals((Character) 'a', copy.get("foo", 1));
}
-
+
@GwtIncompatible("SerializableTester")
public void testSerialization() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
SerializableTester.reserializeAndAssert(table);
}
-
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointerStatic() {
+ public void testNullPointerStatic() throws Exception {
new NullPointerTester().testAllPublicStaticMethods(HashBasedTable.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/HashBiMapTest.java b/guava-tests/test/com/google/common/collect/HashBiMapTest.java
index 935e228..f8661ad 100644
--- a/guava-tests/test/com/google/common/collect/HashBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/HashBiMapTest.java
@@ -17,17 +17,8 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringBiMapGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
@@ -38,33 +29,19 @@ import java.util.Set;
*
* @author Mike Bostock
*/
-@GwtCompatible(emulated = true)
-public class HashBiMapTest extends TestCase {
+@GwtCompatible
+public class HashBiMapTest extends AbstractBiMapTest {
- public static final class HashBiMapGenerator extends TestStringBiMapGenerator {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> result = HashBiMap.create();
- for (Entry<String, String> entry : entries) {
- result.put(entry.getKey(), entry.getValue());
- }
- return result;
- }
+ @Override protected BiMap<Integer, String> create() {
+ return HashBiMap.create();
}
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(BiMapTestSuiteBuilder.using(new HashBiMapGenerator())
- .named("HashBiMap")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE)
- .createTestSuite());
- suite.addTestSuite(HashBiMapTest.class);
- return suite;
+ public void testCreate() {
+ BiMap<String, String> bimap = HashBiMap.create();
+ assertEquals(0, bimap.size());
+ bimap.put("canada", "dollar");
+ assertEquals("dollar", bimap.get("canada"));
+ assertEquals("canada", bimap.inverse().get("dollar"));
}
public void testMapConstructor() {
@@ -112,16 +89,35 @@ public class HashBiMapTest extends TestCase {
}
}
- public void testBiMapEntrySetIteratorRemove() {
- BiMap<Integer, String> map = HashBiMap.create();
- map.put(1, "one");
- Set<Map.Entry<Integer, String>> entries = map.entrySet();
- Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
- Map.Entry<Integer, String> entry = iterator.next();
- entry.setValue("two"); // changes the iterator's current entry value
- assertEquals("two", map.get(1));
- assertEquals(Integer.valueOf(1), map.inverse().get("two"));
- iterator.remove(); // removes the updated entry
- assertTrue(map.isEmpty());
+ // The next two tests verify that map entries are not accessed after they're
+ // removed, since IdentityHashMap throws an exception when that occurs.
+ public void testIdentityKeySetIteratorRemove() {
+ bimap = new AbstractBiMap<Integer, String>(
+ new IdentityHashMap<Integer, String>(),
+ new IdentityHashMap<String, Integer>()) {};
+ putOneTwoThree();
+ Iterator<Integer> iterator = bimap.keySet().iterator();
+ iterator.next();
+ iterator.next();
+ iterator.remove();
+ iterator.next();
+ iterator.remove();
+ assertEquals(1, bimap.size());
+ assertEquals(1, bimap.inverse().size());
+ }
+
+ public void testIdentityEntrySetIteratorRemove() {
+ bimap = new AbstractBiMap<Integer, String>(
+ new IdentityHashMap<Integer, String>(),
+ new IdentityHashMap<String, Integer>()) {};
+ putOneTwoThree();
+ Iterator<Entry<Integer, String>> iterator = bimap.entrySet().iterator();
+ iterator.next();
+ iterator.next();
+ iterator.remove();
+ iterator.next();
+ iterator.remove();
+ assertEquals(1, bimap.size());
+ assertEquals(1, bimap.inverse().size());
}
}
diff --git a/guava-tests/test/com/google/common/collect/HashMultimapTest.java b/guava-tests/test/com/google/common/collect/HashMultimapTest.java
index 490cd84..4264a94 100644
--- a/guava-tests/test/com/google/common/collect/HashMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/HashMultimapTest.java
@@ -17,52 +17,14 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.util.Map.Entry;
/**
* Unit tests for {@link HashMultimap}.
*
* @author Jared Levy
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class HashMultimapTest extends AbstractSetMultimapTest {
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
- @Override
- protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
- SetMultimap<String, String> multimap = HashMultimap.create();
- for (Entry<String, String> entry : entries) {
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap;
- }
- })
- .named("HashMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTestSuite(HashMultimapTest.class);
- return suite;
- }
-
@Override protected Multimap<String, Integer> create() {
return HashMultimap.create();
}
@@ -77,14 +39,14 @@ public class HashMultimapTest extends AbstractSetMultimapTest {
multimap.put("bar", 2);
multimap.put("foo", 3);
assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
- assertEquals(2, multimap.expectedValuesPerKey);
+ assertEquals(8, multimap.expectedValuesPerKey);
}
public void testCreateFromMultimap() {
Multimap<String, Integer> multimap = createSample();
HashMultimap<String, Integer> copy = HashMultimap.create(multimap);
assertEquals(multimap, copy);
- assertEquals(2, copy.expectedValuesPerKey);
+ assertEquals(8, copy.expectedValuesPerKey);
}
public void testCreateFromSizes() {
diff --git a/guava-tests/test/com/google/common/collect/HashMultisetTest.java b/guava-tests/test/com/google/common/collect/HashMultisetTest.java
index 9e68156..6e20b07 100644
--- a/guava-tests/test/com/google/common/collect/HashMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/HashMultisetTest.java
@@ -16,19 +16,10 @@
package com.google.common.collect;
-import static java.util.Arrays.asList;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringMultisetGenerator;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
import java.io.Serializable;
import java.util.Arrays;
@@ -40,29 +31,6 @@ import java.util.Arrays;
*/
@GwtCompatible(emulated = true)
public class HashMultisetTest extends AbstractMultisetTest {
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(MultisetTestSuiteBuilder.using(hashMultisetGenerator())
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.GENERAL_PURPOSE)
- .named("HashMultiset")
- .createTestSuite());
- suite.addTestSuite(HashMultisetTest.class);
- return suite;
- }
-
- private static TestStringMultisetGenerator hashMultisetGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return HashMultiset.create(asList(elements));
- }
- };
- }
-
@Override protected <E> Multiset<E> create() {
return HashMultiset.create();
}
@@ -124,20 +92,30 @@ public class HashMultisetTest extends AbstractMultisetTest {
* iteration order.
*/
+ /**
+ * This test fails with Java 6, preventing us from running
+ * NullPointerTester on multisets.
+ public void testAnnotations() throws Exception {
+ Method method = HashMultiset.class.getDeclaredMethod(
+ "add", Object.class, int.class);
+ assertTrue(method.getParameterAnnotations()[0].length > 0);
+ }
+ */
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
public void testEntryAfterRemove() {
super.testEntryAfterRemove();
}
-
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
public void testEntryAfterClear() {
super.testEntryAfterClear();
}
-
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
@@ -151,7 +129,7 @@ public class HashMultisetTest extends AbstractMultisetTest {
public void testEntryAfterEntrySetIteratorRemove() {
super.testEntryAfterEntrySetIteratorRemove();
}
-
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
diff --git a/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
index c74a43d..223b0aa 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
@@ -16,19 +16,23 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableBiMap.Builder;
import com.google.common.collect.testing.MapInterfaceTest;
+import com.google.common.collect.testing.ReserializingTestSetGenerator;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapGenerator;
-import com.google.common.collect.testing.google.BiMapInverseTester;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapEntrySetGenerator;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapInverseEntrySetGenerator;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapInverseKeySetGenerator;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapInverseValuesGenerator;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapKeySetGenerator;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapValuesGenerator;
import com.google.common.testing.SerializableTester;
import junit.framework.Test;
@@ -60,14 +64,77 @@ public class ImmutableBiMapTest extends TestCase {
suite.addTestSuite(CreationTests.class);
suite.addTestSuite(BiMapSpecificTests.class);
- suite.addTest(BiMapTestSuiteBuilder.using(new ImmutableBiMapGenerator())
- .named("ImmutableBiMap")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ suite.addTest(SetTestSuiteBuilder.using(new ImmutableBiMapKeySetGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.keySet")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableBiMapEntrySetGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.entrySet")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new ImmutableBiMapValuesGenerator())
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.values")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableBiMapInverseKeySetGenerator())
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.inverse.keys")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableBiMapInverseEntrySetGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.inverse.entrySet")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableBiMapInverseValuesGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.inverse.values")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableBiMapKeySetGenerator()))
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.keySet, reserialized")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableBiMapEntrySetGenerator()))
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.entrySet, reserialized")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableBiMapValuesGenerator()))
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.KNOWN_ORDER,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- MapFeature.ALLOWS_NULL_QUERIES)
- .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods())
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableBiMap.values, reserialized")
.createTestSuite());
return suite;
@@ -267,7 +334,7 @@ public class ImmutableBiMapTest extends TestCase {
builder.build();
fail();
} catch (IllegalArgumentException expected) {
- assertTrue(expected.getMessage().contains("one"));
+ assertEquals("duplicate key: one", expected.getMessage());
}
}
@@ -340,7 +407,7 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableBiMap.of("one", 1, "one", 1);
fail();
} catch (IllegalArgumentException expected) {
- assertTrue(expected.getMessage().contains("one"));
+ assertEquals("duplicate key: one", expected.getMessage());
}
}
@@ -414,14 +481,13 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableBiMap.copyOf(map);
fail();
} catch (IllegalArgumentException expected) {
- assertTrue(expected.getMessage().contains("1"));
+ assertEquals("duplicate key: 1", expected.getMessage());
}
}
}
public static class BiMapSpecificTests extends TestCase {
- @SuppressWarnings("deprecation")
public void testForcePut() {
ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
ImmutableMap.of("one", 1, "two", 2));
@@ -436,7 +502,7 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4));
Set<String> keys = bimap.keySet();
assertEquals(Sets.newHashSet("one", "two", "three", "four"), keys);
- ASSERT.that(keys).has().allOf("one", "two", "three", "four").inOrder();
+ ASSERT.that(keys).hasContentsInOrder("one", "two", "three", "four");
}
public void testValues() {
@@ -444,7 +510,7 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4));
Set<Integer> values = bimap.values();
assertEquals(Sets.newHashSet(1, 2, 3, 4), values);
- ASSERT.that(values).has().allOf(1, 2, 3, 4).inOrder();
+ ASSERT.that(values).hasContentsInOrder(1, 2, 3, 4);
}
public void testDoubleInverse() {
diff --git a/guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java b/guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java
deleted file mode 100644
index 535c85a..0000000
--- a/guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@code ImmutableCollection}.
- *
- * @author Louis Wasserman
- */
-public class ImmutableCollectionTest extends TestCase {
- public void testCapacityExpansion() {
- assertEquals(1, ImmutableCollection.Builder.expandedCapacity(0, 1));
- assertEquals(2, ImmutableCollection.Builder.expandedCapacity(0, 2));
- assertEquals(2, ImmutableCollection.Builder.expandedCapacity(1, 2));
- assertEquals(Integer.MAX_VALUE,
- ImmutableCollection.Builder.expandedCapacity(0, Integer.MAX_VALUE));
- assertEquals(Integer.MAX_VALUE,
- ImmutableCollection.Builder.expandedCapacity(1, Integer.MAX_VALUE));
- assertEquals(Integer.MAX_VALUE,
- ImmutableCollection.Builder.expandedCapacity(Integer.MAX_VALUE - 1, Integer.MAX_VALUE));
-
- assertEquals(13, ImmutableCollection.Builder.expandedCapacity(8, 9));
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java
deleted file mode 100644
index 48c0a0b..0000000
--- a/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.AnEnum;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.TestEnumMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Tests for {@code ImmutableEnumMap}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class ImmutableEnumMapTest extends TestCase {
- public static class ImmutableEnumMapGenerator extends TestEnumMapGenerator {
- @Override
- protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) {
- Map<AnEnum, String> map = Maps.newHashMap();
- for (Entry<AnEnum, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- return Maps.immutableEnumMap(map);
- }
- }
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(MapTestSuiteBuilder.using(new ImmutableEnumMapGenerator())
- .named("Maps.immutableEnumMap")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
- suite.addTestSuite(ImmutableEnumMapTest.class);
- return suite;
- }
-
- public void testEmptyImmutableEnumMap() {
- ImmutableMap<AnEnum, String> map = Maps.immutableEnumMap(ImmutableMap.<AnEnum, String>of());
- assertEquals(ImmutableMap.of(), map);
- }
-
- public void testImmutableEnumMapOrdering() {
- ImmutableMap<AnEnum, String> map = Maps.immutableEnumMap(
- ImmutableMap.of(AnEnum.C, "c", AnEnum.A, "a", AnEnum.E, "e"));
-
- ASSERT.that(map.entrySet()).has().allOf(
- Helpers.mapEntry(AnEnum.A, "a"),
- Helpers.mapEntry(AnEnum.C, "c"),
- Helpers.mapEntry(AnEnum.E, "e")).inOrder();
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java
index d2a8d98..fb8f6b4 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java
@@ -16,23 +16,16 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableListMultimap.Builder;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.Collection;
@@ -46,31 +39,6 @@ import java.util.Map.Entry;
*/
@GwtCompatible(emulated = true)
public class ImmutableListMultimapTest extends TestCase {
- public static class ImmutableListMultimapGenerator extends TestStringListMultimapGenerator {
- @Override
- protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
- ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
- for (Entry<String, String> entry : entries) {
- builder.put(entry.getKey(), entry.getValue());
- }
- return builder.build();
- }
- }
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(ListMultimapTestSuiteBuilder.using(new ImmutableListMultimapGenerator())
- .named("ImmutableListMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTestSuite(ImmutableListMultimapTest.class);
- return suite;
- }
public void testBuilder_withImmutableEntry() {
ImmutableListMultimap<String, Integer> multimap = new Builder<String, Integer>()
@@ -263,32 +231,10 @@ public class ImmutableListMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
- ASSERT.that(multimap.values()).has().allOf(2, 4, 3, 6, 5, 2).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("b")).has().allOf(3, 6).inOrder();
- }
-
- public void testBuilderOrderKeysByDuplicates() {
- ImmutableListMultimap.Builder<String, Integer> builder
- = ImmutableListMultimap.builder();
- builder.put("bb", 3);
- builder.put("d", 2);
- builder.put("a", 5);
- builder.orderKeysBy(new Ordering<String>() {
- @Override
- public int compare(String left, String right) {
- return left.length() - right.length();
- }
- });
- builder.put("cc", 4);
- builder.put("a", 2);
- builder.put("bb", 6);
- ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("d", "a", "bb", "cc").inOrder();
- ASSERT.that(multimap.values()).has().allOf(2, 5, 2, 3, 6, 4).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("bb")).has().allOf(3, 6).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
+ ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 3, 6, 5, 2);
+ ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
+ ASSERT.that(multimap.get("b")).hasContentsInOrder(3, 6);
}
public void testBuilderOrderValuesBy() {
@@ -302,10 +248,10 @@ public class ImmutableListMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("b", "d", "a", "c").inOrder();
- ASSERT.that(multimap.values()).has().allOf(6, 3, 2, 5, 2, 4).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("b", "d", "a", "c");
+ ASSERT.that(multimap.values()).hasContentsInOrder(6, 3, 2, 5, 2, 4);
+ ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
+ ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
}
public void testBuilderOrderKeysAndValuesBy() {
@@ -320,10 +266,10 @@ public class ImmutableListMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
- ASSERT.that(multimap.values()).has().allOf(2, 4, 6, 3, 5, 2).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
+ ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 6, 3, 5, 2);
+ ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
+ ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
}
public void testCopyOf() {
@@ -515,7 +461,7 @@ public class ImmutableListMultimapTest extends TestCase {
SerializableTester.reserialize(multimap).size());
SerializableTester.reserializeAndAssert(multimap.get("foo"));
LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
- LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
+ SerializableTester.reserializeAndAssert(multimap.keys());
SerializableTester.reserializeAndAssert(multimap.asMap());
Collection<Integer> valuesCopy
= SerializableTester.reserialize(multimap.values());
diff --git a/guava-tests/test/com/google/common/collect/ImmutableListTest.java b/guava-tests/test/com/google/common/collect/ImmutableListTest.java
index e53fabf..ced0635 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableListTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableListTest.java
@@ -28,6 +28,7 @@ import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.MinimalIterable;
+import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.google.ListGenerators.BuilderAddAllListGenerator;
@@ -48,7 +49,6 @@ import junit.framework.TestSuite;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -65,53 +65,56 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
@GwtCompatible(emulated = true)
public class ImmutableListTest extends TestCase {
-
+
@GwtIncompatible("suite")
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(ListTestSuiteBuilder.using(new ImmutableListOfGenerator())
.named("ImmutableList")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new BuilderAddAllListGenerator())
.named("ImmutableList, built with Builder.add")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new BuilderAddAllListGenerator())
.named("ImmutableList, built with Builder.addAll")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new BuilderReversedListGenerator())
.named("ImmutableList, reversed")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ return SerializableTester.reserialize(
+ ImmutableList.copyOf(elements));
+ }
+ })
+ .named("ImmutableList, reserialized")
+ .withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableListHeadSubListGenerator())
.named("ImmutableList, head subList")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableListTailSubListGenerator())
.named("ImmutableList, tail subList")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableListMiddleSubListGenerator())
.named("ImmutableList, middle subList")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
@@ -194,7 +197,7 @@ public class ImmutableListTest extends TestCase {
}
// Varargs versions
-
+
public void testCreation_twelveElements() {
List<String> list = ImmutableList.of(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l");
@@ -244,7 +247,7 @@ public class ImmutableListTest extends TestCase {
String[] array = new String[] { "a" };
List<String[]> list = ImmutableList.<String[]>of(array);
assertEquals(Collections.singletonList(array), list);
- }
+ }
public void testCopyOf_emptyArray() {
String[] array = new String[0];
@@ -262,7 +265,7 @@ public class ImmutableListTest extends TestCase {
try {
ImmutableList.copyOf((String[]) null);
fail();
- } catch(NullPointerException expected) {
+ } catch(NullPointerException expected) {
}
}
@@ -333,7 +336,7 @@ public class ImmutableListTest extends TestCase {
} catch (NullPointerException expected) {
}
}
-
+
public void testCopyOf_iteratorNull() {
try {
ImmutableList.copyOf((Iterator<String>) null);
@@ -341,7 +344,7 @@ public class ImmutableListTest extends TestCase {
} catch(NullPointerException expected) {
}
}
-
+
public void testCopyOf_concurrentlyMutating() {
List<String> sample = Lists.newArrayList("a", "b", "c");
for (int delta : new int[] {-1, 0, 1}) {
@@ -392,44 +395,10 @@ public class ImmutableListTest extends TestCase {
Collection<String> c = ImmutableList.of("a", "b", "c");
assertSame(c, ImmutableList.copyOf(c));
}
-
- public void testBuilderAddArrayHandlesNulls() {
- String[] elements = {"a", null, "b"};
- ImmutableList.Builder<String> builder = ImmutableList.builder();
- try {
- builder.add(elements);
- fail ("Expected NullPointerException");
- } catch (NullPointerException expected) {
- }
- ImmutableList<String> result = builder.build();
-
- /*
- * Maybe it rejects all elements, or maybe it adds "a" before failing.
- * Either way is fine with us.
- */
- if (result.isEmpty()) {
- return;
- }
- assertTrue(ImmutableList.of("a").equals(result));
- assertEquals(1, result.size());
- }
-
- public void testBuilderAddCollectionHandlesNulls() {
- List<String> elements = Arrays.asList("a", null, "b");
- ImmutableList.Builder<String> builder = ImmutableList.builder();
- try {
- builder.addAll(elements);
- fail ("Expected NullPointerException");
- } catch (NullPointerException expected) {
- }
- ImmutableList<String> result = builder.build();
- assertEquals(ImmutableList.of("a"), result);
- assertEquals(1, result.size());
- }
}
-
+
@GwtIncompatible("reflection")
- public static class ConcurrentTests extends TestCase {
+ public static class ConcurrentTests extends TestCase {
enum WrapWithIterable { WRAP, NO_WRAP }
private static void runConcurrentlyMutatedTest(
@@ -635,11 +604,11 @@ public class ImmutableListTest extends TestCase {
return list;
}
}
-
+
public static class BasicTests extends TestCase {
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableList.class);
tester.testAllPublicInstanceMethods(ImmutableList.of(1, 2, 3));
@@ -654,7 +623,8 @@ public class ImmutableListTest extends TestCase {
@GwtIncompatible("SerializableTester")
public void testSerialization_singleton() {
Collection<String> c = ImmutableList.of("a");
- SerializableTester.reserializeAndAssert(c);
+ ImmutableList<String> copy = (SingletonImmutableList<String>)
+ SerializableTester.reserializeAndAssert(c);
}
@GwtIncompatible("SerializableTester")
diff --git a/guava-tests/test/com/google/common/collect/ImmutableMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
index 2708f39..4c04803 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
@@ -22,25 +22,23 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.testing.AnEnum;
import com.google.common.collect.testing.CollectionTestSuiteBuilder;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MapInterfaceTest;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.MinimalSet;
+import com.google.common.collect.testing.ReserializingTestCollectionGenerator;
+import com.google.common.collect.testing.ReserializingTestSetGenerator;
import com.google.common.collect.testing.SampleElements.Colliders;
import com.google.common.collect.testing.SampleElements.Unhashables;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.UnhashableObject;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEnumMapGenerator;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntryListGenerator;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapGenerator;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeyListGenerator;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntrySetGenerator;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeySetGenerator;
import com.google.common.collect.testing.google.MapGenerators.ImmutableMapUnhashableValuesGenerator;
import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValueListGenerator;
-import com.google.common.testing.EqualsTester;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValuesGenerator;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -51,7 +49,6 @@ import junit.framework.TestSuite;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
-import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -70,55 +67,72 @@ public class ImmutableMapTest extends TestCase {
TestSuite suite = new TestSuite();
suite.addTestSuite(ImmutableMapTest.class);
- suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapGenerator())
+ suite.addTest(SetTestSuiteBuilder.using(new ImmutableMapKeySetGenerator())
.withFeatures(
CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.KNOWN_ORDER,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap")
+ .named("ImmutableMap.keySet")
.createTestSuite());
- suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapCopyOfEnumMapGenerator())
+ suite.addTest(SetTestSuiteBuilder.using(new ImmutableMapEntrySetGenerator())
.withFeatures(
CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.copyOf[EnumMap]")
+ .named("ImmutableMap.entrySet")
.createTestSuite());
suite.addTest(CollectionTestSuiteBuilder.using(
- new ImmutableMapUnhashableValuesGenerator())
+ new ImmutableMapValuesGenerator())
.withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.values, unhashable")
+ .named("ImmutableMap.values")
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableMapKeyListGenerator())
- .named("ImmutableMap.keySet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableMapKeySetGenerator()))
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableMap.keySet, reserialized")
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableMapEntryListGenerator())
- .named("ImmutableMap.entrySet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableMapKeySetGenerator()))
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableMap.entrySet, reserialized")
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ ReserializingTestCollectionGenerator.newInstance(
+ new ImmutableMapValuesGenerator()))
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableMap.values, reserialized")
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new ImmutableMapUnhashableValuesGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableMap.values, unhashable")
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableMapValueListGenerator())
.named("ImmutableMap.values.asList")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -508,29 +522,8 @@ public class ImmutableMapTest extends TestCase {
assertNull(map.get(null));
}
- public void testAsMultimap() {
- ImmutableMap<String, Integer> map = ImmutableMap.of(
- "one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
- ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of(
- "one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
- assertEquals(expected, map.asMultimap());
- }
-
- public void testAsMultimapWhenEmpty() {
- ImmutableMap<String, Integer> map = ImmutableMap.of();
- ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of();
- assertEquals(expected, map.asMultimap());
- }
-
- public void testAsMultimapCaches() {
- ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
- ImmutableSetMultimap<String, Integer> multimap1 = map.asMultimap();
- ImmutableSetMultimap<String, Integer> multimap2 = map.asMultimap();
- assertSame(multimap1, multimap2);
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableMap.class);
tester.testAllPublicInstanceMethods(
@@ -581,13 +574,6 @@ public class ImmutableMapTest extends TestCase {
assertEquals(intMap.hashCode(), map.hashCode());
}
- public void testCopyOfEnumMap() {
- EnumMap<AnEnum, String> map = new EnumMap<AnEnum, String>(AnEnum.class);
- map.put(AnEnum.B, "foo");
- map.put(AnEnum.C, "bar");
- assertTrue(ImmutableMap.copyOf(map) instanceof ImmutableEnumMap);
- }
-
@GwtIncompatible("SerializableTester")
public void testViewSerialization() {
Map<String, Integer> map = ImmutableMap.of("one", 1, "two", 2, "three", 3);
@@ -599,35 +585,4 @@ public class ImmutableMapTest extends TestCase {
Lists.newArrayList(reserializedValues));
assertTrue(reserializedValues instanceof ImmutableCollection);
}
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(ImmutableList.of(), ImmutableList.of())
- .addEqualityGroup(ImmutableList.of(1), ImmutableList.of(1))
- .addEqualityGroup(ImmutableList.of(1, 2), ImmutableList.of(1, 2))
- .addEqualityGroup(ImmutableList.of(1, 2, 3))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 200, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 300, 4, 5, 6, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 400, 5, 6, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 500, 6, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 600, 7, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 700, 8, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 800, 9, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 900, 10, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 1000, 11, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1100, 12))
- .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1200))
- .testEquals();
-
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java
index d02359c..0b917e9 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java
@@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.testing.SampleElements;
import com.google.common.collect.testing.SampleElements.Unhashables;
import com.google.common.collect.testing.UnhashableObject;
-import com.google.common.testing.EqualsTester;
import junit.framework.TestCase;
@@ -33,7 +32,7 @@ import java.util.Map.Entry;
*
* @author Jared Levy
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class ImmutableMultimapTest extends TestCase {
public void testBuilder_withImmutableEntry() {
@@ -115,14 +114,4 @@ public class ImmutableMultimapTest extends TestCase {
assertTrue(multimap.get(0).contains(unhashables.e1));
assertTrue(multimap.get(2).contains("hey you"));
}
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(ImmutableMultimap.of(), ImmutableMultimap.of())
- .addEqualityGroup(ImmutableMultimap.of(1, "a"), ImmutableMultimap.of(1, "a"))
- .addEqualityGroup(
- ImmutableMultimap.of(1, "a", 2, "b"),
- ImmutableMultimap.of(2, "b", 1, "a"))
- .testEquals();
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java b/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java
index 5af65a8..657cf5c 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java
@@ -16,23 +16,19 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.TestStringSetGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
import com.google.common.collect.testing.google.TestStringMultisetGenerator;
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
-import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -40,9 +36,7 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -67,63 +61,30 @@ public class ImmutableMultisetTest extends TestCase {
}
})
.named("ImmutableMultiset")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- return ImmutableMultiset.copyOf(elements).elementSet();
- }
- })
- .named("ImmutableMultiset, element set")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ .withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- return ImmutableMultiset.copyOf(elements).asList();
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- List<String> order = new ArrayList<String>();
- for (String s : insertionOrder) {
- int index = order.indexOf(s);
- if (index == -1) {
- order.add(s);
- } else {
- order.add(index, s);
- }
- }
- return order;
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ return SerializableTester.reserialize(
+ ImmutableMultiset.copyOf(elements));
}
})
- .named("ImmutableMultiset.asList")
+ .named("ImmutableMultiset, reserialized")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- Set<String> set = new HashSet<String>();
- ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
- for (String s : elements) {
- checkArgument(set.add(s));
- builder.addCopies(s, 2);
- }
- ImmutableSet<String> elementSet = (ImmutableSet<String>) builder.build().elementSet();
- return elementSet.asList();
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ return SerializableTester.reserialize(
+ ImmutableMultiset.copyOf(elements).elementSet());
}
})
- .named("ImmutableMultiset.elementSet.asList")
+ .named("ImmutableMultiset, element set")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -437,7 +398,7 @@ public class ImmutableMultisetTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableMultiset.class);
}
@@ -452,7 +413,7 @@ public class ImmutableMultisetTest extends TestCase {
public void testSerialization_multiple() {
Collection<String> c = ImmutableMultiset.of("a", "b", "a");
Collection<String> copy = SerializableTester.reserializeAndAssert(c);
- ASSERT.that(copy).has().allOf("a", "a", "b").inOrder();
+ ASSERT.that(copy).hasContentsInOrder("a", "a", "b");
}
@GwtIncompatible("SerializableTester")
@@ -460,7 +421,7 @@ public class ImmutableMultisetTest extends TestCase {
Multiset<String> c = ImmutableMultiset.of("a", "b", "a");
Collection<String> copy =
LenientSerializableTester.reserializeAndAssertLenient(c.elementSet());
- ASSERT.that(copy).has().allOf("a", "b").inOrder();
+ ASSERT.that(copy).hasContentsInOrder("a", "b");
}
@GwtIncompatible("SerializableTester")
@@ -479,7 +440,7 @@ public class ImmutableMultisetTest extends TestCase {
public void testIterationOrder() {
Collection<String> c = ImmutableMultiset.of("a", "b", "a");
- ASSERT.that(c).has().allOf("a", "a", "b").inOrder();
+ ASSERT.that(c).hasContentsInOrder("a", "a", "b");
}
public void testMultisetWrites() {
@@ -502,13 +463,4 @@ public class ImmutableMultisetTest extends TestCase {
= ImmutableMultiset.of("a", "a", "b", "b", "b");
SerializableTester.reserializeAndAssert(multiset.asList());
}
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(ImmutableMultiset.of(), ImmutableMultiset.of())
- .addEqualityGroup(ImmutableMultiset.of(1), ImmutableMultiset.of(1))
- .addEqualityGroup(ImmutableMultiset.of(1, 1), ImmutableMultiset.of(1, 1))
- .addEqualityGroup(ImmutableMultiset.of(1, 2, 1), ImmutableMultiset.of(2, 1, 1))
- .testEquals();
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java
deleted file mode 100644
index 3d1d7b4..0000000
--- a/guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BoundType.OPEN;
-
-import com.google.common.annotations.GwtIncompatible;
-
-import junit.framework.TestCase;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-
-/**
- * Tests for {@code ImmutableRangeMap}.
- *
- * @author Louis Wasserman
- */
-@GwtIncompatible("NavigableMap")
-public class ImmutableRangeMapTest extends TestCase {
- private static final ImmutableList<Range<Integer>> RANGES;
- private static final int MIN_BOUND = 0;
- private static final int MAX_BOUND = 10;
- static {
- ImmutableList.Builder<Range<Integer>> builder = ImmutableList.builder();
-
- builder.add(Range.<Integer>all());
-
- // Add one-ended ranges
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- for (BoundType type : BoundType.values()) {
- builder.add(Range.upTo(i, type));
- builder.add(Range.downTo(i, type));
- }
- }
-
- // Add two-ended ranges
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- for (int j = i + 1; j <= MAX_BOUND; j++) {
- for (BoundType lowerType : BoundType.values()) {
- for (BoundType upperType : BoundType.values()) {
- if (i == j & lowerType == OPEN & upperType == OPEN) {
- continue;
- }
- builder.add(Range.range(i, lowerType, j, upperType));
- }
- }
- }
- }
- RANGES = builder.build();
- }
-
- public void testBuilderRejectsEmptyRanges() {
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder();
- try {
- builder.put(Range.closedOpen(i, i), 1);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- try {
- builder.put(Range.openClosed(i, i), 1);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
- }
-
- public void testOverlapRejection() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- boolean expectRejection =
- range1.isConnected(range2) && !range1.intersection(range2).isEmpty();
- ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder();
- builder.put(range1, 1);
- try {
- builder.put(range2, 2);
- assertFalse(expectRejection);
- } catch (IllegalArgumentException e) {
- assertTrue(expectRejection);
- }
- }
- }
- }
-
- public void testGet() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
- ImmutableRangeMap<Integer, Integer> rangeMap =
- ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
-
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- Integer expectedValue = null;
- if (range1.contains(i)) {
- expectedValue = 1;
- } else if (range2.contains(i)) {
- expectedValue = 2;
- }
-
- assertEquals(expectedValue, rangeMap.get(i));
- }
- }
- }
- }
- }
-
- public void testSpanEmpty() {
- try {
- ImmutableRangeMap.of().span();
- fail("Expected NoSuchElementException");
- } catch (NoSuchElementException expected) {
- }
- }
-
- public void testSpanSingleRange() {
- for (Range<Integer> range : RANGES) {
- RangeMap<Integer, Integer> rangemap =
- ImmutableRangeMap.<Integer, Integer>builder().put(range, 1).build();
- assertEquals(range, rangemap.span());
- }
- }
-
- public void testSpanTwoRanges() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
- RangeMap<Integer, Integer> rangemap =
- ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
- assertEquals(range1.span(range2), rangemap.span());
- }
- }
- }
- }
-
- public void testGetEntry() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
- ImmutableRangeMap<Integer, Integer> rangeMap =
- ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
-
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- Entry<Range<Integer>, Integer> expectedEntry = null;
- if (range1.contains(i)) {
- expectedEntry = Maps.immutableEntry(range1, 1);
- } else if (range2.contains(i)) {
- expectedEntry = Maps.immutableEntry(range2, 2);
- }
-
- assertEquals(expectedEntry, rangeMap.getEntry(i));
- }
- }
- }
- }
- }
-
- public void testGetLargeRangeMap() {
- ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder();
- for (int i = 0; i < 100; i++) {
- builder.put(Range.closedOpen(i, i + 1), i);
- }
- ImmutableRangeMap<Integer, Integer> map = builder.build();
- for (int i = 0; i < 100; i++) {
- assertEquals(Integer.valueOf(i), map.get(i));
- }
- }
-
- public void testAsMapOfRanges() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
- ImmutableRangeMap<Integer, Integer> rangeMap =
- ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
-
- ImmutableMap<Range<Integer>, Integer> expectedAsMap =
- ImmutableMap.of(range1, 1, range2, 2);
- ImmutableMap<Range<Integer>, Integer> asMap = rangeMap.asMapOfRanges();
- assertEquals(expectedAsMap, asMap);
-
- for (Range<Integer> query : RANGES) {
- assertEquals(expectedAsMap.get(query), asMap.get(query));
- }
- }
- }
- }
- }
-
- public void testSubRangeMap() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
- for (Range<Integer> subRange : RANGES) {
- ImmutableRangeMap<Integer, Integer> rangeMap =
- ImmutableRangeMap.<Integer, Integer>builder()
- .put(range1, 1).put(range2, 2).build();
-
- ImmutableRangeMap.Builder<Integer, Integer> expectedBuilder =
- ImmutableRangeMap.builder();
- for (Map.Entry<Range<Integer>, Integer> entry : rangeMap.asMapOfRanges().entrySet()) {
- if (entry.getKey().isConnected(subRange)
- && !entry.getKey().intersection(subRange).isEmpty()) {
- expectedBuilder.put(entry.getKey().intersection(subRange), entry.getValue());
- }
- }
-
- ImmutableRangeMap<Integer, Integer> expected = expectedBuilder.build();
- assertEquals(expected, rangeMap.subRangeMap(subRange));
- }
- }
- }
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java
deleted file mode 100644
index 352ac78..0000000
--- a/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.math.BigInteger;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for {@link ImmutableRangeSet}.
- *
- * @author Louis Wasserman
- */
-@GwtIncompatible("ImmutableRangeSet")
-public class ImmutableRangeSetTest extends AbstractRangeSetTest {
- @SuppressWarnings("unchecked") // varargs
- private static final ImmutableSet<Range<Integer>> RANGES = ImmutableSet.of(
- Range.<Integer>all(),
- Range.closedOpen(3, 5),
- Range.singleton(1),
- Range.lessThan(2),
- Range.greaterThan(10),
- Range.atMost(4),
- Range.atLeast(3),
- Range.closed(4, 6),
- Range.closedOpen(1, 3),
- Range.openClosed(5, 7),
- Range.open(3, 4));
-
- static final class ImmutableRangeSetIntegerAsSetGenerator implements TestSetGenerator<Integer> {
- @Override
- public SampleElements<Integer> samples() {
- return new SampleElements<Integer>(1, 4, 3, 2, 5);
- }
-
- @Override
- public Integer[] createArray(int length) {
- return new Integer[length];
- }
-
- @Override
- public Iterable<Integer> order(List<Integer> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
-
- @Override
- public Set<Integer> create(Object... elements) {
- ImmutableRangeSet.Builder<Integer> builder = ImmutableRangeSet.builder();
- for (Object o : elements) {
- Integer i = (Integer) o;
- builder.add(Range.singleton(i));
- }
- return builder.build().asSet(DiscreteDomains.integers());
- }
- }
-
- static final class ImmutableRangeSetBigIntegerAsSetGenerator
- implements TestSetGenerator<BigInteger> {
- @Override
- public SampleElements<BigInteger> samples() {
- return new SampleElements<BigInteger>(
- BigInteger.valueOf(1),
- BigInteger.valueOf(4),
- BigInteger.valueOf(3),
- BigInteger.valueOf(2),
- BigInteger.valueOf(5));
- }
-
- @Override
- public BigInteger[] createArray(int length) {
- return new BigInteger[length];
- }
-
- @Override
- public Iterable<BigInteger> order(List<BigInteger> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
-
- @Override
- public Set<BigInteger> create(Object... elements) {
- ImmutableRangeSet.Builder<BigInteger> builder = ImmutableRangeSet.builder();
- for (Object o : elements) {
- BigInteger i = (BigInteger) o;
- builder.add(Range.closedOpen(i, i.add(BigInteger.ONE)));
- }
- return builder.build().asSet(DiscreteDomain.bigIntegers());
- }
- }
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(ImmutableRangeSetTest.class);
- suite.addTest(NavigableSetTestSuiteBuilder.using(new ImmutableRangeSetIntegerAsSetGenerator())
- .named("ImmutableRangeSet.asSet[DiscreteDomains.integers[]]")
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.NON_STANDARD_TOSTRING,
- CollectionFeature.SERIALIZABLE)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableRangeSetBigIntegerAsSetGenerator())
- .named("ImmutableRangeSet.asSet[DiscreteDomains.bigIntegers[]]")
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.NON_STANDARD_TOSTRING,
- CollectionFeature.SERIALIZABLE)
- .createTestSuite());
- return suite;
- }
-
- public void testEmpty() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of();
-
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- assertEquals(ImmutableRangeSet.<Integer>all(), rangeSet.complement());
- assertFalse(rangeSet.contains(0));
- assertFalse(rangeSet.encloses(Range.singleton(0)));
- assertTrue(rangeSet.enclosesAll(rangeSet));
- assertTrue(rangeSet.isEmpty());
- }
-
- public void testAll() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.all();
-
- ASSERT.that(rangeSet.asRanges()).has().item(Range.<Integer>all());
- assertTrue(rangeSet.contains(0));
- assertTrue(rangeSet.encloses(Range.<Integer>all()));
- assertTrue(rangeSet.enclosesAll(rangeSet));
- assertEquals(ImmutableRangeSet.<Integer>of(), rangeSet.complement());
- }
-
- public void testSingleBoundedRange() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of(Range.closedOpen(1, 5));
-
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 5));
-
- assertTrue(rangeSet.encloses(Range.closed(3, 4)));
- assertTrue(rangeSet.encloses(Range.closedOpen(1, 4)));
- assertTrue(rangeSet.encloses(Range.closedOpen(1, 5)));
- assertFalse(rangeSet.encloses(Range.greaterThan(2)));
-
- assertTrue(rangeSet.contains(3));
- assertFalse(rangeSet.contains(5));
- assertFalse(rangeSet.contains(0));
-
- RangeSet<Integer> expectedComplement = TreeRangeSet.create();
- expectedComplement.add(Range.lessThan(1));
- expectedComplement.add(Range.atLeast(5));
-
- assertEquals(expectedComplement, rangeSet.complement());
- }
-
- public void testSingleBoundedBelowRange() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of(Range.greaterThan(2));
-
- ASSERT.that(rangeSet.asRanges()).has().item(Range.greaterThan(2));
-
- assertTrue(rangeSet.encloses(Range.closed(3, 4)));
- assertTrue(rangeSet.encloses(Range.greaterThan(3)));
- assertFalse(rangeSet.encloses(Range.closedOpen(1, 5)));
-
- assertTrue(rangeSet.contains(3));
- assertTrue(rangeSet.contains(5));
- assertFalse(rangeSet.contains(0));
- assertFalse(rangeSet.contains(2));
-
- assertEquals(ImmutableRangeSet.of(Range.atMost(2)), rangeSet.complement());
- }
-
- public void testSingleBoundedAboveRange() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of(Range.atMost(3));
-
- ASSERT.that(rangeSet.asRanges()).has().item(Range.atMost(3));
-
- assertTrue(rangeSet.encloses(Range.closed(2, 3)));
- assertTrue(rangeSet.encloses(Range.lessThan(1)));
- assertFalse(rangeSet.encloses(Range.closedOpen(1, 5)));
-
- assertTrue(rangeSet.contains(3));
- assertTrue(rangeSet.contains(0));
- assertFalse(rangeSet.contains(4));
- assertFalse(rangeSet.contains(5));
-
- assertEquals(ImmutableRangeSet.of(Range.greaterThan(3)), rangeSet.complement());
- }
-
- public void testMultipleBoundedRanges() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
-
- ASSERT.that(rangeSet.asRanges())
- .has().allOf(Range.closedOpen(1, 3), Range.closed(5, 8)).inOrder();
-
- assertTrue(rangeSet.encloses(Range.closed(1, 2)));
- assertTrue(rangeSet.encloses(Range.open(5, 8)));
- assertFalse(rangeSet.encloses(Range.closed(1, 8)));
- assertFalse(rangeSet.encloses(Range.greaterThan(5)));
-
- RangeSet<Integer> expectedComplement = ImmutableRangeSet.<Integer>builder()
- .add(Range.lessThan(1))
- .add(Range.closedOpen(3, 5))
- .add(Range.greaterThan(8))
- .build();
-
- assertEquals(expectedComplement, rangeSet.complement());
- }
-
- public void testMultipleBoundedBelowRanges() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.greaterThan(6)).add(Range.closedOpen(1, 3)).build();
-
- ASSERT.that(rangeSet.asRanges())
- .has().allOf(Range.closedOpen(1, 3), Range.greaterThan(6)).inOrder();
-
- assertTrue(rangeSet.encloses(Range.closed(1, 2)));
- assertTrue(rangeSet.encloses(Range.open(6, 8)));
- assertFalse(rangeSet.encloses(Range.closed(1, 8)));
- assertFalse(rangeSet.encloses(Range.greaterThan(5)));
-
- RangeSet<Integer> expectedComplement = ImmutableRangeSet.<Integer>builder()
- .add(Range.lessThan(1))
- .add(Range.closed(3, 6))
- .build();
-
- assertEquals(expectedComplement, rangeSet.complement());
- }
-
- public void testMultipleBoundedAboveRanges() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.atMost(0)).add(Range.closedOpen(2, 5)).build();
-
- ASSERT.that(rangeSet.asRanges())
- .has().allOf(Range.atMost(0), Range.closedOpen(2, 5)).inOrder();
-
- assertTrue(rangeSet.encloses(Range.closed(2, 4)));
- assertTrue(rangeSet.encloses(Range.open(-5, -2)));
- assertFalse(rangeSet.encloses(Range.closed(1, 8)));
- assertFalse(rangeSet.encloses(Range.greaterThan(5)));
-
- RangeSet<Integer> expectedComplement = ImmutableRangeSet.<Integer>builder()
- .add(Range.open(0, 2))
- .add(Range.atLeast(5))
- .build();
-
- assertEquals(expectedComplement, rangeSet.complement());
- }
-
- public void testAddUnsupported() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
-
- try {
- rangeSet.add(Range.open(3, 4));
- fail();
- } catch (UnsupportedOperationException expected) {
- // success
- }
- }
-
- public void testAddAllUnsupported() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
-
- try {
- rangeSet.addAll(ImmutableRangeSet.<Integer>of());
- fail();
- } catch (UnsupportedOperationException expected) {
- // success
- }
- }
-
- public void testRemoveUnsupported() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
-
- try {
- rangeSet.remove(Range.closed(6, 7));
- fail();
- } catch (UnsupportedOperationException expected) {
- // success
- }
- }
-
- public void testRemoveAllUnsupported() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
-
- try {
- rangeSet.removeAll(ImmutableRangeSet.<Integer>of());
- fail();
- } catch (UnsupportedOperationException expected) {
- // success
- }
-
- try {
- rangeSet.removeAll(ImmutableRangeSet.of(Range.closed(6, 8)));
- fail();
- } catch (UnsupportedOperationException expected) {
- // success
- }
- }
-
- public void testExhaustive() {
- @SuppressWarnings("unchecked")
- ImmutableSet<Range<Integer>> ranges = ImmutableSet.of(
- Range.<Integer>all(),
- Range.<Integer>closedOpen(3, 5),
- Range.singleton(1),
- Range.lessThan(2),
- Range.greaterThan(10),
- Range.atMost(4),
- Range.atLeast(3),
- Range.closed(4, 6),
- Range.closedOpen(1, 3),
- Range.openClosed(5, 7),
- Range.open(3, 4));
- for (Set<Range<Integer>> subset : Sets.powerSet(ranges)) {
- RangeSet<Integer> mutable = TreeRangeSet.create();
- ImmutableRangeSet.Builder<Integer> builder = ImmutableRangeSet.builder();
-
- int expectedRanges = 0;
- for (Range<Integer> range : subset) {
- boolean overlaps = false;
- for (Range<Integer> other : mutable.asRanges()) {
- if (other.isConnected(range) && !other.intersection(range).isEmpty()) {
- overlaps = true;
- }
- }
-
- try {
- builder.add(range);
- assertFalse(overlaps);
- mutable.add(range);
- } catch (IllegalArgumentException e) {
- assertTrue(overlaps);
- }
- }
-
- ImmutableRangeSet<Integer> built = builder.build();
- assertEquals(mutable, built);
- assertEquals(ImmutableRangeSet.copyOf(mutable), built);
- assertEquals(mutable.complement(), built.complement());
-
- for (int i = 0; i <= 11; i++) {
- assertEquals(mutable.contains(i), built.contains(i));
- }
-
- SerializableTester.reserializeAndAssert(built);
- }
- }
-
- public void testAsSet() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(2, 4))
- .add(Range.open(6, 7))
- .add(Range.closedOpen(8, 10))
- .add(Range.openClosed(15, 17))
- .build();
- ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
- ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
- assertEquals(expectedSet, asSet);
- ASSERT.that(asSet).has().allFrom(expectedSet).inOrder();
- assertTrue(asSet.containsAll(expectedSet));
- SerializableTester.reserializeAndAssert(asSet);
- }
-
- public void testAsSetHeadSet() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(2, 4))
- .add(Range.open(6, 7))
- .add(Range.closedOpen(8, 10))
- .add(Range.openClosed(15, 17))
- .build();
-
- ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
- ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
-
- for (int i = 0; i <= 20; i++) {
- assertEquals(asSet.headSet(i, false), expectedSet.headSet(i, false));
- assertEquals(asSet.headSet(i, true), expectedSet.headSet(i, true));
- }
- }
-
- public void testAsSetTailSet() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(2, 4))
- .add(Range.open(6, 7))
- .add(Range.closedOpen(8, 10))
- .add(Range.openClosed(15, 17))
- .build();
-
- ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
- ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
-
- for (int i = 0; i <= 20; i++) {
- assertEquals(asSet.tailSet(i, false), expectedSet.tailSet(i, false));
- assertEquals(asSet.tailSet(i, true), expectedSet.tailSet(i, true));
- }
- }
-
- public void testAsSetSubSet() {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(Range.closed(2, 4))
- .add(Range.open(6, 7))
- .add(Range.closedOpen(8, 10))
- .add(Range.openClosed(15, 17))
- .build();
-
- ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
- ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
-
- for (int i = 0; i <= 20; i++) {
- for (int j = i + 1; j <= 20; j++) {
- assertEquals(expectedSet.subSet(i, false, j, false),
- asSet.subSet(i, false, j, false));
- assertEquals(expectedSet.subSet(i, true, j, false),
- asSet.subSet(i, true, j, false));
- assertEquals(expectedSet.subSet(i, false, j, true),
- asSet.subSet(i, false, j, true));
- assertEquals(expectedSet.subSet(i, true, j, true),
- asSet.subSet(i, true, j, true));
- }
- }
- }
-
- public void testSubRangeSet() {
- ImmutableList.Builder<Range<Integer>> rangesBuilder = ImmutableList.builder();
- rangesBuilder.add(Range.<Integer>all());
- for (int i = -2; i <= 2; i++) {
- for (BoundType boundType : BoundType.values()) {
- rangesBuilder.add(Range.upTo(i, boundType));
- rangesBuilder.add(Range.downTo(i, boundType));
- }
- for (int j = i + 1; j <= 2; j++) {
- for (BoundType lbType : BoundType.values()) {
- for (BoundType ubType : BoundType.values()) {
- rangesBuilder.add(Range.range(i, lbType, j, ubType));
- }
- }
- }
- }
- ImmutableList<Range<Integer>> ranges = rangesBuilder.build();
- for (int i = -2; i <= 2; i++) {
- rangesBuilder.add(Range.closedOpen(i, i));
- rangesBuilder.add(Range.openClosed(i, i));
- }
- ImmutableList<Range<Integer>> subRanges = rangesBuilder.build();
- for (Range<Integer> range1 : ranges) {
- for (Range<Integer> range2 : ranges) {
- if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
- ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
- .add(range1)
- .add(range2)
- .build();
- for (Range<Integer> subRange : subRanges) {
- RangeSet<Integer> expected = TreeRangeSet.create();
- for (Range<Integer> range : rangeSet.asRanges()) {
- if (range.isConnected(subRange)) {
- expected.add(range.intersection(subRange));
- }
- }
- ImmutableRangeSet<Integer> subRangeSet = rangeSet.subRangeSet(subRange);
- assertEquals(expected, subRangeSet);
- assertEquals(expected.asRanges(), subRangeSet.asRanges());
- if (!expected.isEmpty()) {
- assertEquals(expected.span(), subRangeSet.span());
- }
- for (int i = -3; i <= 3; i++) {
- assertEquals(expected.contains(i), subRangeSet.contains(i));
- }
- }
- }
- }
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java
new file mode 100644
index 0000000..9ebceec
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.TestStringSortedSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.SetGenerators.DegeneratedImmutableSetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSetAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSetCopyOfGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSetWithBadHashesGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListSubListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetCopyOfGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetHeadsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetTailsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedsetSubsetAsListSubListGenerator;
+import com.google.common.collect.testing.testers.SetHashCodeTester;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * Collection tests for {@link ImmutableSet} and {@link ImmutableSortedSet}.
+ *
+ * @author Kevin Bourrillion
+ * @author Jared Levy
+ */
+@GwtIncompatible("suite") // handled by collect/gwt/suites
+public class ImmutableSetCollectionTest extends TestCase {
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(SetTestSuiteBuilder.using(new ImmutableSetCopyOfGenerator())
+ .named(ImmutableSetTest.class.getName())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ Set<String> set = ImmutableSet.copyOf(elements);
+ return SerializableTester.reserialize(set);
+ }
+ })
+ .named(ImmutableSetTest.class.getName() + ", reserialized")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSetWithBadHashesGenerator())
+ .named(ImmutableSetTest.class.getName() + ", with bad hashes")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new DegeneratedImmutableSetGenerator())
+ .named(ImmutableSetTest.class.getName() + ", degenerate")
+ .withFeatures(CollectionSize.ONE, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetCopyOfGenerator())
+ .named(ImmutableSortedSetTest.class.getName())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSortedSetGenerator() {
+ @Override protected SortedSet<String> create(String[] elements) {
+ SortedSet<String> set = ImmutableSortedSet.copyOf(elements);
+ return SerializableTester.reserialize(set);
+ }
+ })
+ .named(ImmutableSortedSetTest.class.getName() + ", reserialized")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetHeadsetGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", headset")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetTailsetGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", tailset")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetSubsetGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", subset")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSortedSetGenerator() {
+ @Override protected SortedSet<String> create(String[] elements) {
+ List<String> list = Lists.newArrayList(elements);
+ list.add("zzz");
+ return SerializableTester.reserialize(
+ ImmutableSortedSet.copyOf(list).headSet("zzy"));
+ }
+ })
+ .named(
+ ImmutableSortedSetTest.class.getName() + ", headset, reserialized")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSortedSetGenerator() {
+ @Override protected SortedSet<String> create(String[] elements) {
+ List<String> list = Lists.newArrayList(elements);
+ list.add("\0");
+ return SerializableTester.reserialize(
+ ImmutableSortedSet.copyOf(list).tailSet("\0\0"));
+ }
+ })
+ .named(
+ ImmutableSortedSetTest.class.getName() + ", tailset, reserialized")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSortedSetGenerator() {
+ @Override protected SortedSet<String> create(String[] elements) {
+ List<String> list = Lists.newArrayList(elements);
+ list.add("\0");
+ list.add("zzz");
+ return SerializableTester.reserialize(
+ ImmutableSortedSet.copyOf(list).subSet("\0\0", "zzy"));
+ }
+ })
+ .named(
+ ImmutableSortedSetTest.class.getName() + ", subset, reserialized")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetExplicitComparator())
+ .named(ImmutableSortedSetTest.class.getName()
+ + ", explicit comparator, vararg")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetExplicitSuperclassComparatorGenerator())
+ .named(ImmutableSortedSetTest.class.getName()
+ + ", explicit superclass comparator, iterable")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetReversedOrderGenerator())
+ .named(ImmutableSortedSetTest.class.getName()
+ + ", reverseOrder, iterator")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedSetUnhashableGenerator())
+ .suppressing(SetHashCodeTester.getHashCodeMethods())
+ .named(ImmutableSortedSetTest.class.getName() + ", unhashable")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new ImmutableSetAsListGenerator())
+ .named("ImmutableSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedSetAsListGenerator())
+ .named("ImmutableSortedSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedSetSubsetAsListGenerator())
+ .named("ImmutableSortedSet.subSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedSetAsListSubListGenerator())
+ .named("ImmutableSortedSet.asList.subList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedsetSubsetAsListSubListGenerator())
+ .named("ImmutableSortedSet.subSet.asList.subList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ return suite;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java
index 654d80e..8c182cf 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java
@@ -16,23 +16,16 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSetMultimap.Builder;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.Collection;
@@ -46,29 +39,6 @@ import java.util.Map.Entry;
*/
@GwtCompatible(emulated = true)
public class ImmutableSetMultimapTest extends TestCase {
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(ImmutableSetMultimapTest.class);
- suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
- @Override
- protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
- ImmutableSetMultimap.Builder<String, String> builder = ImmutableSetMultimap.builder();
- for (Entry<String, String> entry : entries) {
- builder.put(entry.getKey(), entry.getValue());
- }
- return builder.build();
- }
- })
- .named("ImmutableSetMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .createTestSuite());
- return suite;
- }
public void testBuilder_withImmutableEntry() {
ImmutableSetMultimap<String, Integer> multimap = new Builder<String, Integer>()
@@ -249,35 +219,10 @@ public class ImmutableSetMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
- ASSERT.that(multimap.values()).has().allOf(2, 4, 3, 6, 5, 2).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("b")).has().allOf(3, 6).inOrder();
- assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
- assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
- assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
- }
-
- public void testBuilderOrderKeysByDuplicates() {
- ImmutableSetMultimap.Builder<String, Integer> builder
- = ImmutableSetMultimap.builder();
- builder.put("bb", 3);
- builder.put("d", 2);
- builder.put("a", 5);
- builder.orderKeysBy(new Ordering<String>() {
- @Override
- public int compare(String left, String right) {
- return left.length() - right.length();
- }
- });
- builder.put("cc", 4);
- builder.put("a", 2);
- builder.put("bb", 6);
- ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("d", "a", "bb", "cc").inOrder();
- ASSERT.that(multimap.values()).has().allOf(2, 5, 2, 3, 6, 4).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("bb")).has().allOf(3, 6).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
+ ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 3, 6, 5, 2);
+ ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
+ ASSERT.that(multimap.get("b")).hasContentsInOrder(3, 6);
assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
@@ -294,18 +239,18 @@ public class ImmutableSetMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("b", "d", "a", "c").inOrder();
- ASSERT.that(multimap.values()).has().allOf(6, 3, 2, 5, 2, 4).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("b", "d", "a", "c");
+ ASSERT.that(multimap.values()).hasContentsInOrder(6, 3, 2, 5, 2, 4);
+ ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
+ ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
}
@@ -321,21 +266,21 @@ public class ImmutableSetMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
- ASSERT.that(multimap.values()).has().allOf(2, 4, 6, 3, 5, 2).inOrder();
- ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
- ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
+ ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 6, 3, 5, 2);
+ ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
+ ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
}
-
+
public void testCopyOf() {
HashMultimap<String, Integer> input = HashMultimap.create();
input.put("foo", 1);
@@ -502,7 +447,7 @@ public class ImmutableSetMultimapTest extends TestCase {
assertEquals(alternatingKeysAndValues[i++], entry.getKey());
assertEquals(alternatingKeysAndValues[i++], entry.getValue());
}
- }
+ }
@GwtIncompatible("SerializableTester")
public void testSerialization() {
@@ -512,7 +457,7 @@ public class ImmutableSetMultimapTest extends TestCase {
SerializableTester.reserialize(multimap).size());
SerializableTester.reserializeAndAssert(multimap.get("foo"));
LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
- LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
+ SerializableTester.reserializeAndAssert(multimap.keys());
SerializableTester.reserializeAndAssert(multimap.asMap());
Collection<Integer> valuesCopy
= SerializableTester.reserialize(multimap.values());
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
index dba83a5..6ed82ec 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
@@ -16,23 +16,13 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet.Builder;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.SetGenerators.DegeneratedImmutableSetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSetAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSetCopyOfGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSetWithBadHashesGenerator;
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.SerializableTester;
import java.util.Collection;
import java.util.Collections;
@@ -49,44 +39,6 @@ import java.util.Set;
@GwtCompatible(emulated = true)
public class ImmutableSetTest extends AbstractImmutableSetTest {
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(SetTestSuiteBuilder.using(new ImmutableSetCopyOfGenerator())
- .named(ImmutableSetTest.class.getName())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSetWithBadHashesGenerator())
- .named(ImmutableSetTest.class.getName() + ", with bad hashes")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new DegeneratedImmutableSetGenerator())
- .named(ImmutableSetTest.class.getName() + ", degenerate")
- .withFeatures(CollectionSize.ONE, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new ImmutableSetAsListGenerator())
- .named("ImmutableSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTestSuite(ImmutableSetTest.class);
-
- return suite;
- }
-
@Override protected Set<String> of() {
return ImmutableSet.of();
}
@@ -153,7 +105,7 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
// now we'll get the varargs overload
ImmutableSet<String> set = ImmutableSet.of(
"a", "b", "c", "c", "c", "c", "b", "b", "a", "a", "c", "c", "c", "a");
- ASSERT.that(set).has().allOf("a", "b", "c").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c");
}
public void testCreation_arrayOfArray() {
@@ -162,13 +114,19 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
assertEquals(Collections.singleton(array), set);
}
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicStaticMethods(ImmutableSet.class);
+ }
+
@GwtIncompatible("ImmutableSet.chooseTableSize")
public void testChooseTableSize() {
assertEquals(8, ImmutableSet.chooseTableSize(3));
- assertEquals(8, ImmutableSet.chooseTableSize(4));
+ assertEquals(16, ImmutableSet.chooseTableSize(4));
- assertEquals(1 << 29, ImmutableSet.chooseTableSize(1 << 28));
- assertEquals(1 << 29, ImmutableSet.chooseTableSize(1 << 29 - 1));
+ assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 28));
+ assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 29 - 1));
// Now we hit the cap
assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 29));
@@ -184,12 +142,12 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
@GwtIncompatible("RegularImmutableSet.table not in emulation")
public void testResizeTable() {
- verifyTableSize(100, 2, 4);
- verifyTableSize(100, 5, 8);
- verifyTableSize(100, 33, 64);
- verifyTableSize(17, 17, 32);
- verifyTableSize(17, 16, 32);
- verifyTableSize(17, 15, 32);
+ verifyTableSize(100, 2, 8);
+ verifyTableSize(100, 5, 16);
+ verifyTableSize(100, 33, 256);
+ verifyTableSize(17, 17, 64);
+ verifyTableSize(17, 16, 64);
+ verifyTableSize(17, 15, 64);
}
@GwtIncompatible("RegularImmutableSet.table not in emulation")
@@ -215,6 +173,21 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
verifyThreadSafe();
}
+ public void testAsList() {
+ ImmutableSet<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
+ ImmutableList<String> list = set.asList();
+ assertEquals(ImmutableList.of("a", "b", "c", "d", "e"), list);
+ }
+
+ @GwtIncompatible("SerializableTester, ImmutableAsList")
+ public void testAsListReturnTypeAndSerialization() {
+ ImmutableSet<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
+ ImmutableList<String> list = set.asList();
+ assertTrue(list instanceof ImmutableAsList);
+ ImmutableList<String> copy = SerializableTester.reserializeAndAssert(list);
+ assertTrue(copy instanceof ImmutableAsList);
+ }
+
@Override <E extends Comparable<E>> Builder<E> builder() {
return ImmutableSet.builder();
}
@@ -222,12 +195,4 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
@Override int getComplexBuilderSetLastElement() {
return LAST_COLOR_ADDED;
}
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(ImmutableSet.of(), ImmutableSet.of())
- .addEqualityGroup(ImmutableSet.of(1), ImmutableSet.of(1), ImmutableSet.of(1, 1))
- .addEqualityGroup(ImmutableSet.of(1, 2, 1), ImmutableSet.of(2, 1, 1))
- .testEquals();
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java
index b4a2632..988aa4e 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java
@@ -16,22 +16,25 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSortedMap.Builder;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
+import com.google.common.collect.testing.CollectionTestSuiteBuilder;
+import com.google.common.collect.testing.ReserializingTestCollectionGenerator;
+import com.google.common.collect.testing.ReserializingTestSetGenerator;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.SortedMapInterfaceTest;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapEntryListGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapKeyListGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapValueListGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapEntrySetGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapHeadMapKeySetGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapKeySetGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapSubMapEntryGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapTailMapValuesGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapValuesGenerator;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -63,42 +66,88 @@ public class ImmutableSortedMapTest extends TestCase {
TestSuite suite = new TestSuite();
suite.addTestSuite(ImmutableSortedMapTest.class);
- suite.addTest(NavigableMapTestSuiteBuilder.using(
- new ImmutableSortedMapGenerator())
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedMapKeySetGenerator())
.withFeatures(
CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.KNOWN_ORDER,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- MapFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap")
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.keySet")
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedMapEntryListGenerator())
- .named("ImmutableSortedMap.entrySet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedMapEntrySetGenerator())
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.entrySet")
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new ImmutableSortedMapValuesGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.values")
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedMapKeyListGenerator())
- .named("ImmutableSortedMap.keySet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableSortedMapKeySetGenerator()))
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.keySet, reserialized")
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedMapValueListGenerator())
- .named("ImmutableSortedMap.values.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
+ suite.addTest(SetTestSuiteBuilder.using(
+ ReserializingTestSetGenerator.newInstance(
+ new ImmutableSortedMapEntrySetGenerator()))
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.entrySet, reserialized")
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ ReserializingTestCollectionGenerator.newInstance(
+ new ImmutableSortedMapValuesGenerator()))
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.values, reserialized")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedMapHeadMapKeySetGenerator())
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.headMap.keySet")
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSortedMapSubMapEntryGenerator())
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.subMap.entrySet")
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new ImmutableSortedMapTailMapValuesGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap.tailMap.values")
.createTestSuite());
return suite;
@@ -216,7 +265,7 @@ public class ImmutableSortedMapTest extends TestCase {
return 4;
}
}
-
+
public static class TailMapTests extends AbstractMapTests<String, Integer> {
@Override protected SortedMap<String, Integer> makePopulatedMap() {
return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5)
@@ -650,7 +699,7 @@ public class ImmutableSortedMapTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableSortedMap.class);
tester.testAllPublicInstanceMethods(
@@ -695,7 +744,8 @@ public class ImmutableSortedMapTest extends TestCase {
Map<String, IntHolder> map
= ImmutableSortedMap.of("a", holderA, "b", holderB);
holderA.value = 3;
- assertTrue(map.entrySet().contains(Maps.immutableEntry("a", new IntHolder(3))));
+ assertTrue(map.entrySet().contains(
+ Maps.immutableEntry("a", new IntHolder(3))));
Map<String, Integer> intMap
= ImmutableSortedMap.of("a", 3, "b", 2);
assertEquals(intMap.hashCode(), map.entrySet().hashCode());
@@ -716,86 +766,60 @@ public class ImmutableSortedMapTest extends TestCase {
public void testHeadMapInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", true);
- ASSERT.that(map.entrySet()).has().allOf(
- Maps.immutableEntry("one", 1),
- Maps.immutableEntry("three", 3)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1),
+ Maps.immutableEntry("three", 3));
}
@SuppressWarnings("unchecked") // varargs
public void testHeadMapExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", false);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1));
}
@SuppressWarnings("unchecked") // varargs
public void testTailMapInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", true);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3),
- Maps.immutableEntry("two", 2)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3),
+ Maps.immutableEntry("two", 2));
}
@SuppressWarnings("unchecked") // varargs
public void testTailMapExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", false);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("two", 2)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("two", 2));
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapExclusiveExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", false);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3));
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapInclusiveExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", false);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1),
- Maps.immutableEntry("three", 3)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1),
+ Maps.immutableEntry("three", 3));
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapExclusiveInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", true);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3),
- Maps.immutableEntry("two", 2)).inOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3),
+ Maps.immutableEntry("two", 2));
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapInclusiveInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", true);
- ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1),
- Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2)).inOrder();
- }
-
- private static class SelfComparableExample implements Comparable<SelfComparableExample> {
- @Override
- public int compareTo(SelfComparableExample o) {
- return 0;
- }
- }
-
- public void testBuilderGenerics_SelfComparable() {
- ImmutableSortedMap.Builder<SelfComparableExample, Object> natural =
- ImmutableSortedMap.naturalOrder();
-
- ImmutableSortedMap.Builder<SelfComparableExample, Object> reverse =
- ImmutableSortedMap.reverseOrder();
- }
-
- private static class SuperComparableExample extends SelfComparableExample {}
-
- public void testBuilderGenerics_SuperComparable() {
- ImmutableSortedMap.Builder<SuperComparableExample, Object> natural =
- ImmutableSortedMap.naturalOrder();
-
- ImmutableSortedMap.Builder<SuperComparableExample, Object> reverse =
- ImmutableSortedMap.reverseOrder();
+ ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1),
+ Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2));
}
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java
index fe661d4..5ecb339 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -14,15 +14,13 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.base.Function;
-import com.google.common.collect.Multiset.Entry;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MinimalCollection;
-import com.google.common.collect.testing.TestStringListGenerator;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSetGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
@@ -35,10 +33,9 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.easymock.EasyMock;
-
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -46,7 +43,7 @@ import java.util.Set;
/**
* Tests for {@link ImmutableSortedMultiset}.
- *
+ *
* @author Louis Wasserman
*/
public class ImmutableSortedMultisetTest extends TestCase {
@@ -55,61 +52,47 @@ public class ImmutableSortedMultisetTest extends TestCase {
suite.addTestSuite(ImmutableSortedMultisetTest.class);
suite.addTest(SortedMultisetTestSuiteBuilder.using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- return ImmutableSortedMultiset.copyOf(elements);
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .named("ImmutableSortedMultiset")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ return ImmutableSortedMultiset.copyOf(elements);
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ }).named("ImmutableSortedMultiset").withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override
- protected List<String> create(String[] elements) {
- return ImmutableSortedMultiset.copyOf(elements).asList();
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .named("ImmutableSortedMultiset.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ suite.addTest(SortedMultisetTestSuiteBuilder.using(new TestStringMultisetGenerator() {
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ return SerializableTester.reserialize(ImmutableSortedMultiset.copyOf(elements));
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ }).named("ImmutableSortedMultiset, reserialized").withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override
- protected List<String> create(String[] elements) {
- Set<String> set = Sets.newHashSet();
- ImmutableSortedMultiset.Builder<String> builder = ImmutableSortedMultiset.naturalOrder();
- for (String s : elements) {
- checkArgument(set.add(s));
- builder.addCopies(s, 2);
+ suite.addTest(SetTestSuiteBuilder
+ .using(new TestStringSetGenerator() {
+ @Override
+ protected Set<String> create(String[] elements) {
+ return SerializableTester.reserialize(ImmutableSortedMultiset.copyOf(elements)
+ .elementSet());
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().immutableSortedCopy(insertionOrder);
}
- return builder.build().elementSet().asList();
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .named("ImmutableSortedMultiset.elementSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ }).named("ImmutableSortedMultiset, element set").withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
return suite;
@@ -408,8 +391,14 @@ public class ImmutableSortedMultisetTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(ImmutableSortedMultiset.class);
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Comparator.class, Ordering.natural());
+ tester.setDefault(Comparable.class, "");
+ tester.setDefault(Iterator.class, Iterators.emptyIterator());
+ tester.setDefault(Iterable.class, Collections.emptySet());
+ tester.setDefault(Comparable[].class, new Comparable[0]);
+ tester.testAllPublicStaticMethods(ImmutableSortedMultiset.class);
}
public void testSerialization_empty() {
@@ -420,13 +409,13 @@ public class ImmutableSortedMultisetTest extends TestCase {
public void testSerialization_multiple() {
Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a");
Collection<String> copy = SerializableTester.reserializeAndAssert(c);
- ASSERT.that(copy).has().allOf("a", "a", "b").inOrder();
+ ASSERT.that(copy).hasContentsInOrder("a", "a", "b");
}
public void testSerialization_elementSet() {
Multiset<String> c = ImmutableSortedMultiset.of("a", "b", "a");
Collection<String> copy = SerializableTester.reserializeAndAssert(c.elementSet());
- ASSERT.that(copy).has().allOf("a", "b").inOrder();
+ ASSERT.that(copy).hasContentsInOrder("a", "b");
}
public void testSerialization_entrySet() {
@@ -444,7 +433,7 @@ public class ImmutableSortedMultisetTest extends TestCase {
public void testIterationOrder() {
Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a");
- ASSERT.that(c).has().allOf("a", "a", "b").inOrder();
+ ASSERT.that(c).hasContentsInOrder("a", "a", "b");
}
public void testMultisetWrites() {
@@ -462,62 +451,4 @@ public class ImmutableSortedMultisetTest extends TestCase {
assertEquals(2, list.indexOf("b"));
assertEquals(4, list.lastIndexOf("b"));
}
-
- public void testCopyOfDefensiveCopy() {
- // Test that toArray() is used to make a defensive copy in copyOf(), so concurrently modified
- // synchronized collections can be safely copied.
- @SuppressWarnings("unchecked")
- Collection<String> toCopy = EasyMock.createMock(Collection.class);
- EasyMock.expect(toCopy.toArray()).andReturn(new Object[0]);
- EasyMock.replay(toCopy);
- ImmutableSortedMultiset<String> multiset =
- ImmutableSortedMultiset.copyOf(Ordering.natural(), toCopy);
- EasyMock.verify(toCopy);
- }
-
- @SuppressWarnings("unchecked")
- public void testCopyOfSortedDefensiveCopy() {
- // Test that toArray() is used to make a defensive copy in copyOf(), so concurrently modified
- // synchronized collections can be safely copied.
- SortedMultiset<String> toCopy = EasyMock.createMock(SortedMultiset.class);
- Set<Entry<String>> entrySet = EasyMock.createMock(Set.class);
- EasyMock.expect((Comparator<Comparable>) toCopy.comparator())
- .andReturn(Ordering.natural());
- EasyMock.expect(toCopy.entrySet()).andReturn(entrySet);
- EasyMock.expect(entrySet.toArray()).andReturn(new Object[0]);
- EasyMock.replay(toCopy, entrySet);
- ImmutableSortedMultiset<String> multiset =
- ImmutableSortedMultiset.copyOfSorted(toCopy);
- EasyMock.verify(toCopy, entrySet);
- }
-
- private static class IntegerDiv10 implements Comparable<IntegerDiv10> {
- final int value;
-
- IntegerDiv10(int value) {
- this.value = value;
- }
-
- @Override
- public int compareTo(IntegerDiv10 o) {
- return value / 10 - o.value / 10;
- }
-
- @Override public String toString() {
- return Integer.toString(value);
- }
- }
-
- public void testCopyOfDuplicateInconsistentWithEquals() {
- IntegerDiv10 three = new IntegerDiv10(3);
- IntegerDiv10 eleven = new IntegerDiv10(11);
- IntegerDiv10 twelve = new IntegerDiv10(12);
- IntegerDiv10 twenty = new IntegerDiv10(20);
-
- List<IntegerDiv10> original = ImmutableList.of(three, eleven, twelve, twenty);
-
- Multiset<IntegerDiv10> copy = ImmutableSortedMultiset.copyOf(original);
- assertTrue(copy.contains(eleven));
- assertTrue(copy.contains(twelve));
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
index b4820b2..59506db 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
@@ -17,33 +17,14 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetCopyOfGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetHeadsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetTailsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator;
-import com.google.common.collect.testing.testers.SetHashCodeTester;
+import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -62,117 +43,6 @@ import java.util.TreeSet;
@GwtCompatible(emulated = true)
public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetCopyOfGenerator())
- .named(ImmutableSortedSetTest.class.getName())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetHeadsetGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", headset")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetTailsetGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", tailset")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetSubsetGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", subset")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetExplicitComparator())
- .named(ImmutableSortedSetTest.class.getName()
- + ", explicit comparator, vararg")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetExplicitSuperclassComparatorGenerator())
- .named(ImmutableSortedSetTest.class.getName()
- + ", explicit superclass comparator, iterable")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetReversedOrderGenerator())
- .named(ImmutableSortedSetTest.class.getName()
- + ", reverseOrder, iterator")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetUnhashableGenerator())
- .suppressing(SetHashCodeTester.getHashCodeMethods())
- .named(ImmutableSortedSetTest.class.getName() + ", unhashable")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(
- new ImmutableSortedSetDescendingGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", descending")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedSetAsListGenerator())
- .named("ImmutableSortedSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedSetSubsetAsListGenerator())
- .named("ImmutableSortedSet.subSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedSetDescendingAsListGenerator())
- .named("ImmutableSortedSet.descendingSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTestSuite(ImmutableSortedSetTest.class);
-
- return suite;
- }
-
// enum singleton pattern
private enum StringLengthComparator implements Comparator<String> {
INSTANCE;
@@ -234,8 +104,10 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(ImmutableSortedSet.class);
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Comparable[].class, new Comparable[] { 0 });
+ tester.testAllPublicStaticMethods(ImmutableSortedSet.class);
}
public void testEmpty_comparator() {
@@ -291,7 +163,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testSingle_headSet() {
SortedSet<String> set = of("e");
assertTrue(set.headSet("g") instanceof ImmutableSortedSet);
- ASSERT.that(set.headSet("g")).has().item("e");
+ ASSERT.that(set.headSet("g")).hasContentsInOrder("e");
assertSame(of(), set.headSet("c"));
assertSame(of(), set.headSet("e"));
}
@@ -299,16 +171,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testSingle_tailSet() {
SortedSet<String> set = of("e");
assertTrue(set.tailSet("c") instanceof ImmutableSortedSet);
- ASSERT.that(set.tailSet("c")).has().item("e");
- ASSERT.that(set.tailSet("e")).has().item("e");
+ ASSERT.that(set.tailSet("c")).hasContentsInOrder("e");
+ ASSERT.that(set.tailSet("e")).hasContentsInOrder("e");
assertSame(of(), set.tailSet("g"));
}
public void testSingle_subSet() {
SortedSet<String> set = of("e");
assertTrue(set.subSet("c", "g") instanceof ImmutableSortedSet);
- ASSERT.that(set.subSet("c", "g")).has().item("e");
- ASSERT.that(set.subSet("e", "g")).has().item("e");
+ ASSERT.that(set.subSet("c", "g")).hasContentsInOrder("e");
+ ASSERT.that(set.subSet("e", "g")).hasContentsInOrder("e");
assertSame(of(), set.subSet("f", "g"));
assertSame(of(), set.subSet("c", "e"));
assertSame(of(), set.subSet("c", "d"));
@@ -333,7 +205,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_ordering() {
SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
/*
@@ -382,7 +254,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_ordering_dupes() {
SortedSet<String> set = of("e", "a", "e", "f", "b", "b", "d", "a", "c");
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
public void testOf_comparator() {
@@ -393,8 +265,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_headSet() {
SortedSet<String> set = of("e", "f", "b", "d", "c");
assertTrue(set.headSet("e") instanceof ImmutableSortedSet);
- ASSERT.that(set.headSet("e")).has().allOf("b", "c", "d").inOrder();
- ASSERT.that(set.headSet("g")).has().allOf("b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set.headSet("e")).hasContentsInOrder("b", "c", "d");
+ ASSERT.that(set.headSet("g")).hasContentsInOrder("b", "c", "d", "e", "f");
assertSame(of(), set.headSet("a"));
assertSame(of(), set.headSet("b"));
}
@@ -402,16 +274,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_tailSet() {
SortedSet<String> set = of("e", "f", "b", "d", "c");
assertTrue(set.tailSet("e") instanceof ImmutableSortedSet);
- ASSERT.that(set.tailSet("e")).has().allOf("e", "f").inOrder();
- ASSERT.that(set.tailSet("a")).has().allOf("b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set.tailSet("e")).hasContentsInOrder("e", "f");
+ ASSERT.that(set.tailSet("a")).hasContentsInOrder("b", "c", "d", "e", "f");
assertSame(of(), set.tailSet("g"));
}
public void testOf_subSet() {
SortedSet<String> set = of("e", "f", "b", "d", "c");
assertTrue(set.subSet("c", "e") instanceof ImmutableSortedSet);
- ASSERT.that(set.subSet("c", "e")).has().allOf("c", "d").inOrder();
- ASSERT.that(set.subSet("a", "g")).has().allOf("b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set.subSet("c", "e")).hasContentsInOrder("c", "d");
+ ASSERT.that(set.subSet("a", "g")).hasContentsInOrder("b", "c", "d", "e", "f");
assertSame(of(), set.subSet("a", "b"));
assertSame(of(), set.subSet("g", "h"));
assertSame(of(), set.subSet("c", "c"));
@@ -451,14 +323,14 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testExplicit_ordering() {
SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
"in", "the", "quick", "jumped", "over", "a").build();
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
}
public void testExplicit_ordering_dupes() {
SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
"in", "the", "quick", "brown", "fox", "jumped",
"over", "a", "lazy", "dog").build();
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
}
public void testExplicit_contains() {
@@ -488,9 +360,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
"in", "the", "quick", "jumped", "over", "a").build();
assertTrue(set.headSet("a") instanceof ImmutableSortedSet);
assertTrue(set.headSet("fish") instanceof ImmutableSortedSet);
- ASSERT.that(set.headSet("fish")).has().allOf("a", "in", "the").inOrder();
- ASSERT.that(set.headSet("california")).has()
- .allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set.headSet("fish")).hasContentsInOrder("a", "in", "the");
+ ASSERT.that(
+ set.headSet("california")).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
assertTrue(set.headSet("a").isEmpty());
assertTrue(set.headSet("").isEmpty());
}
@@ -500,9 +372,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
"in", "the", "quick", "jumped", "over", "a").build();
assertTrue(set.tailSet("california") instanceof ImmutableSortedSet);
assertTrue(set.tailSet("fish") instanceof ImmutableSortedSet);
- ASSERT.that(set.tailSet("fish")).has().allOf("over", "quick", "jumped").inOrder();
+ ASSERT.that(set.tailSet("fish")).hasContentsInOrder("over", "quick", "jumped");
ASSERT.that(
- set.tailSet("a")).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ set.tailSet("a")).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
assertTrue(set.tailSet("california").isEmpty());
}
@@ -511,9 +383,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
"in", "the", "quick", "jumped", "over", "a").build();
assertTrue(set.subSet("the", "quick") instanceof ImmutableSortedSet);
assertTrue(set.subSet("", "b") instanceof ImmutableSortedSet);
- ASSERT.that(set.subSet("the", "quick")).has().allOf("the", "over").inOrder();
+ ASSERT.that(set.subSet("the", "quick")).hasContentsInOrder("the", "over");
ASSERT.that(set.subSet("a", "california"))
- .has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ .hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
assertTrue(set.subSet("", "b").isEmpty());
assertTrue(set.subSet("vermont", "california").isEmpty());
assertTrue(set.subSet("aaa", "zzz").isEmpty());
@@ -557,13 +429,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testCopyOf_ordering() {
SortedSet<String> set =
copyOf(asList("e", "a", "f", "b", "d", "c"));
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
public void testCopyOf_ordering_dupes() {
SortedSet<String> set =
copyOf(asList("e", "a", "e", "f", "b", "b", "d", "a", "c"));
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
public void testCopyOf_subSet() {
@@ -594,13 +466,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testCopyOf_iterator_ordering() {
SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
public void testCopyOf_iterator_ordering_dupes() {
SortedSet<String> set =
copyOf(asIterator("e", "a", "e", "f", "b", "b", "d", "a", "c"));
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
public void testCopyOf_iterator_comparator() {
@@ -611,7 +483,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testCopyOf_sortedSet_ordering() {
SortedSet<String> set =
copyOf(Sets.newTreeSet(asList("e", "a", "f", "b", "d", "c")));
- ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
}
public void testCopyOf_sortedSet_comparator() {
@@ -623,7 +495,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> set =
ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
"in", "the", "quick", "jumped", "over", "a"));
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
}
public void testCopyOfExplicit_ordering_dupes() {
@@ -631,7 +503,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
"in", "the", "quick", "brown", "fox", "jumped", "over", "a",
"lazy", "dog"));
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
}
public void testCopyOfExplicit_comparator() {
@@ -645,7 +517,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> set =
ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
"in", "the", "quick", "jumped", "over", "a"));
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
}
public void testCopyOfExplicit_iterator_ordering_dupes() {
@@ -653,7 +525,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
"in", "the", "quick", "brown", "fox", "jumped", "over", "a",
"lazy", "dog"));
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
}
public void testCopyOfExplicit_iterator_comparator() {
@@ -667,14 +539,14 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
SortedSet<String> set = copyOf(input);
- ASSERT.that(set).has().allOf("a", "in", "jumped", "over", "quick", "the").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "jumped", "over", "quick", "the");
}
public void testCopyOfSorted_natural_ordering() {
SortedSet<String> input = Sets.newTreeSet(
asList("in", "the", "quick", "jumped", "over", "a"));
SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
- ASSERT.that(set).has().allOf("a", "in", "jumped", "over", "quick", "the").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "jumped", "over", "quick", "the");
}
public void testCopyOfSorted_natural_comparator() {
@@ -688,7 +560,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
- ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
+ ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
assertSame(STRING_LENGTH, set.comparator());
}
@@ -786,7 +658,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testReverseOrder() {
SortedSet<String> set = ImmutableSortedSet.<String>reverseOrder()
.add("a", "b", "c").build();
- ASSERT.that(set).has().allOf("c", "b", "a").inOrder();
+ ASSERT.that(set).hasContentsInOrder("c", "b", "a");
assertEquals(Ordering.natural().reverse(), set.comparator());
}
@@ -801,16 +673,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testSupertypeComparator() {
SortedSet<Integer> set = new ImmutableSortedSet.Builder<Integer>(TO_STRING)
.add(3, 12, 101, 44).build();
- ASSERT.that(set).has().allOf(101, 12, 3, 44).inOrder();
+ ASSERT.that(set).hasContentsInOrder(101, 12, 3, 44);
}
public void testSupertypeComparatorSubtypeElements() {
SortedSet<Number> set = new ImmutableSortedSet.Builder<Number>(TO_STRING)
.add(3, 12, 101, 44).build();
- ASSERT.that(set).has().allOf(101, 12, 3, 44).inOrder();
+ ASSERT.that(set).hasContentsInOrder(101, 12, 3, 44);
}
- @Override <E extends Comparable<E>> ImmutableSortedSet.Builder<E> builder() {
+ @Override <E extends Comparable<E>> Builder<E> builder() {
return ImmutableSortedSet.naturalOrder();
}
@@ -949,7 +821,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
ASSERT.that(set.headSet(strings[i], true))
- .has().allFrom(sortedNumberNames(0, i + 1)).inOrder();
+ .hasContentsInOrder(sortedNumberNames(0, i + 1));
}
}
@@ -958,7 +830,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
- ASSERT.that(set.headSet(strings[i], false)).has().allFrom(sortedNumberNames(0, i)).inOrder();
+ ASSERT.that(set.headSet(strings[i], false)).hasContentsInOrder(sortedNumberNames(0, i));
}
}
@@ -967,8 +839,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
- ASSERT.that(set.tailSet(strings[i], true)).has().allFrom(
- sortedNumberNames(i, strings.length)).inOrder();
+ ASSERT.that(set.tailSet(strings[i], true)).hasContentsInOrder(
+ sortedNumberNames(i, strings.length));
}
}
@@ -977,8 +849,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
- ASSERT.that(set.tailSet(strings[i], false)).has().allFrom(
- sortedNumberNames(i + 1, strings.length)).inOrder();
+ ASSERT.that(set.tailSet(strings[i], false)).hasContentsInOrder(
+ sortedNumberNames(i + 1, strings.length));
}
}
@@ -989,7 +861,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], false, strings[j], false))
- .has().allFrom(sortedNumberNames(Math.min(i + 1, j), j)).inOrder();
+ .hasContentsInOrder(sortedNumberNames(Math.min(i + 1, j), j));
}
}
}
@@ -1001,7 +873,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], true, strings[j], false))
- .has().allFrom(sortedNumberNames(i, j)).inOrder();
+ .hasContentsInOrder(sortedNumberNames(i, j));
}
}
}
@@ -1013,7 +885,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], false, strings[j], true))
- .has().allFrom(sortedNumberNames(i + 1, j + 1)).inOrder();
+ .hasContentsInOrder(sortedNumberNames(i + 1, j + 1));
}
}
}
@@ -1025,13 +897,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], true, strings[j], true))
- .has().allFrom(sortedNumberNames(i, j + 1)).inOrder();
+ .hasContentsInOrder(sortedNumberNames(i, j + 1));
}
}
}
- private static ImmutableList<String> sortedNumberNames(int i, int j) {
- return ImmutableList.copyOf(SORTED_NUMBER_NAMES.subList(i, j));
+ private static String[] sortedNumberNames(int i, int j) {
+ return SORTED_NUMBER_NAMES.subList(i, j).toArray(new String[0]);
}
private static final ImmutableList<String> NUMBER_NAMES =
@@ -1040,22 +912,4 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
private static final ImmutableList<String> SORTED_NUMBER_NAMES =
Ordering.natural().immutableSortedCopy(NUMBER_NAMES);
- private static class SelfComparableExample implements Comparable<SelfComparableExample> {
- @Override
- public int compareTo(SelfComparableExample o) {
- return 0;
- }
- }
-
- public void testBuilderGenerics_SelfComparable() {
- ImmutableSortedSet.Builder<SelfComparableExample> natural = ImmutableSortedSet.naturalOrder();
- ImmutableSortedSet.Builder<SelfComparableExample> reverse = ImmutableSortedSet.reverseOrder();
- }
-
- private static class SuperComparableExample extends SelfComparableExample {}
-
- public void testBuilderGenerics_SuperComparable() {
- ImmutableSortedSet.Builder<SuperComparableExample> natural = ImmutableSortedSet.naturalOrder();
- ImmutableSortedSet.Builder<SuperComparableExample> reverse = ImmutableSortedSet.reverseOrder();
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableTableTest.java b/guava-tests/test/com/google/common/collect/ImmutableTableTest.java
index 97570fa..6311b68 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,13 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
+import static org.junit.contrib.truth.Truth.ASSERT;
/**
* Tests common methods in {@link ImmutableTable}
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
-@GwtCompatible(emulated = true)
public class ImmutableTableTest extends AbstractTableReadTest {
@Override protected Table<String, Integer, Character> create(Object... data) {
ImmutableTable.Builder<String, Integer, Character> builder =
@@ -184,9 +181,9 @@ public class ImmutableTableTest extends AbstractTableReadTest {
validateTableCopies(table);
// Even though rowKeySet, columnKeySet, and cellSet have the same
// iteration ordering, row has an inconsistent ordering.
- ASSERT.that(table.row('b').keySet()).has().allOf(1, 2).inOrder();
+ ASSERT.that(table.row('b').keySet()).hasContentsInOrder(1, 2);
ASSERT.that(ImmutableTable.copyOf(table).row('b').keySet())
- .has().allOf(2, 1).inOrder();
+ .hasContentsInOrder(2, 1);
}
public void testCopyOfSparse() {
@@ -227,10 +224,10 @@ public class ImmutableTableTest extends AbstractTableReadTest {
= builder.orderRowsBy(Ordering.natural())
.orderColumnsBy(Ordering.natural())
.putAll(table).build();
- ASSERT.that(copy.rowKeySet()).has().allOf('a', 'b').inOrder();
- ASSERT.that(copy.columnKeySet()).has().allOf(1, 2).inOrder();
- ASSERT.that(copy.values()).has().allOf("baz", "bar", "foo").inOrder();
- ASSERT.that(copy.row('b').keySet()).has().allOf(1, 2).inOrder();
+ ASSERT.that(copy.rowKeySet()).hasContentsInOrder('a', 'b');
+ ASSERT.that(copy.columnKeySet()).hasContentsInOrder(1, 2);
+ ASSERT.that(copy.values()).hasContentsInOrder("baz", "bar", "foo");
+ ASSERT.that(copy.row('b').keySet()).hasContentsInOrder(1, 2);
}
public void testBuilder_orderRowsAndColumnsBy_sparse() {
@@ -248,12 +245,12 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('r', 4, "foo");
builder.put('x', 5, "bar");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).has().allOf('b', 'c', 'e', 'r', 'x').inOrder();
- ASSERT.that(table.columnKeySet()).has().allOf(0, 1, 2, 3, 4, 5, 7).inOrder();
- ASSERT.that(table.values()).has().allOf("cat", "axe", "baz", "tub",
- "dog", "bar", "foo", "foo", "bar").inOrder();
- ASSERT.that(table.row('c').keySet()).has().allOf(0, 3).inOrder();
- ASSERT.that(table.column(5).keySet()).has().allOf('e', 'x').inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder('b', 'c', 'e', 'r', 'x');
+ ASSERT.that(table.columnKeySet()).hasContentsInOrder(0, 1, 2, 3, 4, 5, 7);
+ ASSERT.that(table.values()).hasContentsInOrder("cat", "axe", "baz", "tub",
+ "dog", "bar", "foo", "foo", "bar");
+ ASSERT.that(table.row('c').keySet()).hasContentsInOrder(0, 3);
+ ASSERT.that(table.column(5).keySet()).hasContentsInOrder('e', 'x');
}
public void testBuilder_orderRowsAndColumnsBy_dense() {
@@ -270,12 +267,12 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('a', 2, "bar");
builder.put('a', 1, "baz");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).has().allOf('a', 'b', 'c').inOrder();
- ASSERT.that(table.columnKeySet()).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(table.values()).has().allOf("baz", "bar", "foo", "dog",
- "cat", "baz", "bar", "foo").inOrder();
- ASSERT.that(table.row('c').keySet()).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(table.column(1).keySet()).has().allOf('a', 'b', 'c').inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder('a', 'b', 'c');
+ ASSERT.that(table.columnKeySet()).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(table.values()).hasContentsInOrder("baz", "bar", "foo", "dog",
+ "cat", "baz", "bar", "foo");
+ ASSERT.that(table.row('c').keySet()).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(table.column(1).keySet()).hasContentsInOrder('a', 'b', 'c');
}
public void testBuilder_orderRowsBy_sparse() {
@@ -292,8 +289,8 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('r', 4, "foo");
builder.put('x', 5, "bar");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).has().allOf('b', 'c', 'e', 'r', 'x').inOrder();
- ASSERT.that(table.column(5).keySet()).has().allOf('e', 'x').inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder('b', 'c', 'e', 'r', 'x');
+ ASSERT.that(table.column(5).keySet()).hasContentsInOrder('e', 'x');
}
public void testBuilder_orderRowsBy_dense() {
@@ -309,8 +306,8 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('a', 2, "bar");
builder.put('a', 1, "baz");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).has().allOf('a', 'b', 'c').inOrder();
- ASSERT.that(table.column(1).keySet()).has().allOf('a', 'b', 'c').inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder('a', 'b', 'c');
+ ASSERT.that(table.column(1).keySet()).hasContentsInOrder('a', 'b', 'c');
}
public void testBuilder_orderColumnsBy_sparse() {
@@ -327,8 +324,8 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('r', 4, "foo");
builder.put('x', 5, "bar");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.columnKeySet()).has().allOf(0, 1, 2, 3, 4, 5, 7).inOrder();
- ASSERT.that(table.row('c').keySet()).has().allOf(0, 3).inOrder();
+ ASSERT.that(table.columnKeySet()).hasContentsInOrder(0, 1, 2, 3, 4, 5, 7);
+ ASSERT.that(table.row('c').keySet()).hasContentsInOrder(0, 3);
}
public void testBuilder_orderColumnsBy_dense() {
@@ -344,7 +341,7 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('a', 2, "bar");
builder.put('a', 1, "baz");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.columnKeySet()).has().allOf(1, 2, 3).inOrder();
- ASSERT.that(table.row('c').keySet()).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(table.columnKeySet()).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(table.row('c').keySet()).hasContentsInOrder(1, 2, 3);
}
}
diff --git a/guava-tests/test/com/google/common/collect/InternersTest.java b/guava-tests/test/com/google/common/collect/InternersTest.java
index 49ea67c..db11ad2 100644
--- a/guava-tests/test/com/google/common/collect/InternersTest.java
+++ b/guava-tests/test/com/google/common/collect/InternersTest.java
@@ -17,7 +17,6 @@
package com.google.common.collect;
import com.google.common.base.Function;
-import com.google.common.testing.GcFinalization;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -73,10 +72,17 @@ public class InternersTest extends TestCase {
assertSame(canonical, pool.intern(canonical));
WeakReference<Integer> signal = new WeakReference<Integer>(canonical);
- canonical = null; // Hint to the JIT that canonical is unreachable
-
- GcFinalization.awaitClear(signal);
- assertSame(not, pool.intern(not));
+ canonical = null;
+
+ for (int i = 0; i < 3000; i++) {
+ System.gc();
+ if (signal.get() == null) { // it was collected
+ assertSame(not, pool.intern(not));
+ return;
+ }
+ Thread.sleep(1);
+ }
+ fail("reference didn't get cleaned up");
}
public void testAsFunction_simplistic() {
@@ -90,7 +96,7 @@ public class InternersTest extends TestCase {
assertSame(canonical, internerFunction.apply(not));
}
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
new NullPointerTester().testAllPublicStaticMethods(Interners.class);
}
}
diff --git a/guava/src/com/google/common/collect/ForwardingImmutableMap.java b/guava-tests/test/com/google/common/collect/InverseBiMapTest.java
index a367157..637b629 100644
--- a/guava/src/com/google/common/collect/ForwardingImmutableMap.java
+++ b/guava-tests/test/com/google/common/collect/InverseBiMapTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Guava Authors
+ * Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,14 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
/**
- * Unused stub class, unreferenced under Java and manually emulated under GWT.
+ * Unit test covering the inverse view of a {@code BiMap}.
*
- * @author Chris Povirk
+ * @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
-abstract class ForwardingImmutableMap<K, V> {
- private ForwardingImmutableMap() {}
+@GwtCompatible
+public class InverseBiMapTest extends AbstractBiMapTest {
+ @Override protected BiMap<Integer, String> create() {
+ BiMap<String, Integer> inverse = HashBiMap.create();
+ return inverse.inverse();
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/IterablesTest.java b/guava-tests/test/com/google/common/collect/IterablesTest.java
index ba989b1..b0ea688 100644
--- a/guava-tests/test/com/google/common/collect/IterablesTest.java
+++ b/guava-tests/test/com/google/common/collect/IterablesTest.java
@@ -23,7 +23,7 @@ import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -32,7 +32,6 @@ import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.testing.IteratorTester;
-import com.google.common.testing.ClassSanityTester;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -211,6 +210,18 @@ public class IterablesTest extends TestCase {
assertTrue(Arrays.equals(sourceArray, newArray));
}
+ public void testFilter() {
+ Iterable<String> unfiltered = newArrayList("foo", "bar");
+ Iterable<String> filtered = Iterables.filter(unfiltered,
+ Predicates.equalTo("foo"));
+
+ List<String> expected = Collections.singletonList("foo");
+ List<String> actual = newArrayList(filtered);
+ assertEquals(expected, actual);
+ assertCanIterateAgain(filtered);
+ assertEquals("[foo]", filtered.toString());
+ }
+
public void testAny() {
List<String> list = newArrayList();
Predicate<String> predicate = Predicates.equalTo("pants");
@@ -283,7 +294,7 @@ public class IterablesTest extends TestCase {
Iterable<TypeA> alist = Lists
.newArrayList(new TypeA(), new TypeA(), hasBoth, new TypeA());
Iterable<TypeB> blist = Iterables.filter(alist, TypeB.class);
- ASSERT.that(blist).iteratesOverSequence(hasBoth);
+ ASSERT.that(blist).hasContentsInOrder(hasBoth);
}
public void testTransform() {
@@ -411,7 +422,7 @@ public class IterablesTest extends TestCase {
int n = 4;
Iterable<Integer> repeated
= Iterables.concat(Collections.nCopies(n, iterable));
- ASSERT.that(repeated).iteratesOverSequence(
+ ASSERT.that(repeated).hasContentsInOrder(
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
}
@@ -510,8 +521,8 @@ public class IterablesTest extends TestCase {
List<String> freshlyAdded = newArrayList("freshly", "added");
boolean changed = Iterables.addAll(alreadyThere, freshlyAdded);
- ASSERT.that(alreadyThere).has().allOf(
- "already", "there", "freshly", "added").inOrder();
+ ASSERT.that(alreadyThere).hasContentsInOrder(
+ "already", "there", "freshly", "added");
assertTrue(changed);
}
@@ -521,7 +532,7 @@ public class IterablesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Iterables.class);
}
@@ -554,6 +565,42 @@ public class IterablesTest extends TestCase {
assertFalse(Iterables.elementsEqual(b, a));
}
+ @GwtIncompatible("slow (~30s)")
+ @SuppressWarnings("deprecation") // test of a deprecated method
+ public void testReversePassesIteratorsTester() {
+ new IteratorTester<Integer>(5, MODIFIABLE, newArrayList(2, 4, 6, 8),
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ @Override protected Iterator<Integer> newTargetIterator() {
+ return Iterables.reverse(newArrayList(8, 6, 4, 2)).iterator();
+ }
+ }.test();
+ }
+
+ @SuppressWarnings("deprecation") // test of a deprecated method
+ public void testReverseWorksAsExpected() {
+ String[] testStrs = new String[] {"foo", "bar", "baz"};
+ String[] expected = new String[] {"baz", "bar", "foo"};
+
+ List<String> stuff = ImmutableList.copyOf(testStrs);
+
+ Iterable<String> reversed = Iterables.reverse(stuff);
+ ASSERT.that(reversed).hasContentsInOrder(expected);
+ assertEquals("[baz, bar, foo]", reversed.toString());
+
+ List<String> removable = newArrayList("foo", "bar", "bad", "baz");
+
+ reversed = Iterables.reverse(removable);
+ ASSERT.that(reversed).hasContentsInOrder("baz", "bad", "bar", "foo");
+
+ Iterator<String> reverseIter = reversed.iterator();
+ assertEquals("baz", reverseIter.next());
+ assertEquals("bad", reverseIter.next());
+ reverseIter.remove();
+
+ ASSERT.that(reversed).hasContentsInOrder(expected);
+ ASSERT.that(reversed).hasContentsInOrder(expected);
+ }
+
public void testToString() {
List<String> list = Collections.emptyList();
assertEquals("[]", Iterables.toString(list));
@@ -656,7 +703,7 @@ public class IterablesTest extends TestCase {
Iterable<String> tail = skip(set, 1);
set.remove("b");
set.addAll(newArrayList("A", "B", "C"));
- ASSERT.that(tail).iteratesOverSequence("c", "A", "B", "C");
+ ASSERT.that(tail).hasContentsInOrder("c", "A", "B", "C");
}
public void testSkip_structurallyModifiedSkipSomeList() throws Exception {
@@ -664,7 +711,7 @@ public class IterablesTest extends TestCase {
Iterable<String> tail = skip(list, 1);
list.subList(1, 3).clear();
list.addAll(0, newArrayList("A", "B", "C"));
- ASSERT.that(tail).iteratesOverSequence("B", "C", "a");
+ ASSERT.that(tail).hasContentsInOrder("B", "C", "a");
}
public void testSkip_structurallyModifiedSkipAll() throws Exception {
@@ -1086,7 +1133,7 @@ public class IterablesTest extends TestCase {
/** Returns a new iterable over the specified strings. */
private static Iterable<String> create(String... strings) {
final List<String> list = asList(strings);
- return new FluentIterable<String>() {
+ return new Iterables.IterableWithToString<String>() {
@Override
public Iterator<String> iterator() {
return list.iterator();
@@ -1102,12 +1149,12 @@ public class IterablesTest extends TestCase {
Iterable<String> consumingIterable = Iterables.consumingIterable(list);
Iterator<String> consumingIterator = consumingIterable.iterator();
- ASSERT.that(list).has().allOf("a", "b").inOrder();
+ ASSERT.that(list).hasContentsInOrder("a", "b");
assertTrue(consumingIterator.hasNext());
- ASSERT.that(list).has().allOf("a", "b").inOrder();
+ ASSERT.that(list).hasContentsInOrder("a", "b");
assertEquals("a", consumingIterator.next());
- ASSERT.that(list).has().item("b");
+ ASSERT.that(list).hasContentsInOrder("b");
assertTrue(consumingIterator.hasNext());
assertEquals("b", consumingIterator.next());
@@ -1314,15 +1361,7 @@ public class IterablesTest extends TestCase {
verifyMergeSorted(iterables, allIntegers);
}
- @GwtIncompatible("reflection")
- public void testIterables_nullCheck() throws Exception {
- new ClassSanityTester()
- .forAllPublicStaticMethods(Iterables.class)
- .thatReturn(Iterable.class)
- .testNulls();
- }
-
- private static void verifyMergeSorted(Iterable<Iterable<Integer>> iterables,
+ private void verifyMergeSorted(Iterable<Iterable<Integer>> iterables,
Iterable<Integer> unsortedExpected) {
Iterable<Integer> expected =
Ordering.natural().sortedCopy(unsortedExpected);
diff --git a/guava-tests/test/com/google/common/collect/IteratorsTest.java b/guava-tests/test/com/google/common/collect/IteratorsTest.java
index 4c348f6..60f3a3a 100644
--- a/guava-tests/test/com/google/common/collect/IteratorsTest.java
+++ b/guava-tests/test/com/google/common/collect/IteratorsTest.java
@@ -16,15 +16,15 @@
package com.google.common.collect;
-import static com.google.common.collect.Iterators.advance;
import static com.google.common.collect.Iterators.get;
import static com.google.common.collect.Iterators.getLast;
+import static com.google.common.collect.Iterators.skip;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -44,6 +44,7 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -51,7 +52,6 @@ import java.util.ConcurrentModificationException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
-import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.Set;
@@ -88,39 +88,6 @@ public class IteratorsTest extends TestCase {
}
}
- public void testEmptyListIterator() {
- ListIterator<String> iterator = Iterators.emptyListIterator();
- assertFalse(iterator.hasNext());
- assertFalse(iterator.hasPrevious());
- assertEquals(0, iterator.nextIndex());
- assertEquals(-1, iterator.previousIndex());
- try {
- iterator.next();
- fail("no exception thrown");
- } catch (NoSuchElementException expected) {
- }
- try {
- iterator.previous();
- fail("no exception thrown");
- } catch (NoSuchElementException expected) {
- }
- try {
- iterator.remove();
- fail("no exception thrown");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- iterator.set("a");
- fail("no exception thrown");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- iterator.add("a");
- fail("no exception thrown");
- } catch (UnsupportedOperationException expected) {
- }
- }
-
public void testSize0() {
Iterator<String> iterator = Iterators.emptyIterator();
assertEquals(0, Iterators.size(iterator));
@@ -750,7 +717,7 @@ public class IteratorsTest extends TestCase {
boolean changed = Iterators.addAll(alreadyThere,
Iterators.<String>emptyIterator());
- ASSERT.that(alreadyThere).has().allOf("already", "there").inOrder();
+ ASSERT.that(alreadyThere).hasContentsInOrder("already", "there");
assertFalse(changed);
}
@@ -760,7 +727,7 @@ public class IteratorsTest extends TestCase {
boolean changed = Iterators.addAll(alreadyThere, freshlyAdded.iterator());
- ASSERT.that(alreadyThere).has().allOf("already", "there", "freshly", "added");
+ ASSERT.that(alreadyThere).hasContentsInOrder("already", "there", "freshly", "added");
assertTrue(changed);
}
@@ -770,12 +737,12 @@ public class IteratorsTest extends TestCase {
List<String> oneMore = Lists.newArrayList("there");
boolean changed = Iterators.addAll(alreadyThere, oneMore.iterator());
- ASSERT.that(alreadyThere).has().allOf("already", "there").inOrder();
+ ASSERT.that(alreadyThere).hasContentsInOrder("already", "there");
assertFalse(changed);
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Iterators.class);
}
@@ -1032,29 +999,29 @@ public class IteratorsTest extends TestCase {
public void testForArrayOffset() {
String[] array = {"foo", "bar", "cat", "dog"};
- Iterator<String> iterator = Iterators.forArray(array, 1, 2, 0);
+ Iterator<String> iterator = Iterators.forArray(array, 1, 2);
assertTrue(iterator.hasNext());
assertEquals("bar", iterator.next());
assertTrue(iterator.hasNext());
assertEquals("cat", iterator.next());
assertFalse(iterator.hasNext());
try {
- Iterators.forArray(array, 2, 3, 0);
+ Iterators.forArray(array, 2, 3);
fail();
} catch (IndexOutOfBoundsException expected) {}
}
public void testForArrayLength0() {
String[] array = {"foo", "bar"};
- assertFalse(Iterators.forArray(array, 0, 0, 0).hasNext());
- assertFalse(Iterators.forArray(array, 1, 0, 0).hasNext());
- assertFalse(Iterators.forArray(array, 2, 0, 0).hasNext());
+ assertFalse(Iterators.forArray(array, 0, 0).hasNext());
+ assertFalse(Iterators.forArray(array, 1, 0).hasNext());
+ assertFalse(Iterators.forArray(array, 2, 0).hasNext());
try {
- Iterators.forArray(array, -1, 0, 0);
+ Iterators.forArray(array, -1, 0);
fail();
} catch (IndexOutOfBoundsException expected) {}
try {
- Iterators.forArray(array, 3, 0, 0);
+ Iterators.forArray(array, 3, 0);
fail();
} catch (IndexOutOfBoundsException expected) {}
}
@@ -1074,7 +1041,7 @@ public class IteratorsTest extends TestCase {
new IteratorTester<Integer>(6, UNMODIFIABLE, asList(1, 2, 3),
IteratorTester.KnownOrder.KNOWN_ORDER) {
@Override protected Iterator<Integer> newTargetIterator() {
- return Iterators.forArray(new Integer[] { 0, 1, 2, 3, 4 }, 1, 3, 0);
+ return Iterators.forArray(new Integer[] { 0, 1, 2, 3, 4 }, 1, 3);
}
}.test();
}
@@ -1171,18 +1138,11 @@ public class IteratorsTest extends TestCase {
}
public void testToString() {
- Iterator<String> iterator = Lists.newArrayList("yam", "bam", "jam", "ham").iterator();
- assertEquals("[yam, bam, jam, ham]", Iterators.toString(iterator));
- }
+ List<String> list = Collections.emptyList();
+ assertEquals("[]", Iterators.toString(list.iterator()));
- public void testToStringWithNull() {
- Iterator<String> iterator = Lists.newArrayList("hello", null, "world").iterator();
- assertEquals("[hello, null, world]", Iterators.toString(iterator));
- }
-
- public void testToStringEmptyIterator() {
- Iterator<String> iterator = Collections.<String>emptyList().iterator();
- assertEquals("[]", Iterators.toString(iterator));
+ list = Lists.newArrayList("yam", "bam", "jam", "ham");
+ assertEquals("[yam, bam, jam, ham]", Iterators.toString(list.iterator()));
}
public void testLimit() {
@@ -1382,29 +1342,29 @@ public class IteratorsTest extends TestCase {
assertTrue(iterator.hasNext());
}
- public void testAdvance_basic() {
+ public void testSkip_basic() {
List<String> list = newArrayList();
list.add("a");
list.add("b");
Iterator<String> iterator = list.iterator();
- advance(iterator, 1);
+ skip(iterator, 1);
assertEquals("b", iterator.next());
}
- public void testAdvance_pastEnd() {
+ public void testSkip_pastEnd() {
List<String> list = newArrayList();
list.add("a");
list.add("b");
Iterator<String> iterator = list.iterator();
- advance(iterator, 5);
+ skip(iterator, 5);
assertFalse(iterator.hasNext());
}
- public void testAdvance_illegalArgument() {
+ public void testSkip_illegalArgument() {
List<String> list = newArrayList("a", "b", "c");
Iterator<String> iterator = list.iterator();
try {
- advance(iterator, -1);
+ skip(iterator, -1);
fail();
} catch (IllegalArgumentException expected) {}
}
@@ -1506,12 +1466,12 @@ public class IteratorsTest extends TestCase {
Iterator<String> consumingIterator =
Iterators.consumingIterator(list.iterator());
- ASSERT.that(list).has().allOf("a", "b").inOrder();
+ ASSERT.that(list).hasContentsInOrder("a", "b");
assertTrue(consumingIterator.hasNext());
- ASSERT.that(list).has().allOf("a", "b").inOrder();
+ ASSERT.that(list).hasContentsInOrder("a", "b");
assertEquals("a", consumingIterator.next());
- ASSERT.that(list).has().item("b");
+ ASSERT.that(list).hasContentsInOrder("b");
assertTrue(consumingIterator.hasNext());
assertEquals("b", consumingIterator.next());
diff --git a/guava-tests/test/com/google/common/collect/LenientSerializableTester.java b/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
index ec286d5..5f4f771 100644
--- a/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
+++ b/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
@@ -42,7 +42,6 @@ final class LenientSerializableTester {
* TODO(cpovirk): move this to c.g.c.testing if we allow for c.g.c.annotations dependencies so
* that it can be GWTified?
*/
-
@GwtIncompatible("SerializableTester")
static <E> Set<E> reserializeAndAssertLenient(Set<E> original) {
Set<E> copy = reserialize(original);
@@ -51,13 +50,5 @@ final class LenientSerializableTester {
return copy;
}
- @GwtIncompatible("SerializableTester")
- static <E> Multiset<E> reserializeAndAssertLenient(Multiset<E> original) {
- Multiset<E> copy = reserialize(original);
- assertEquals(original, copy);
- assertTrue(copy instanceof ImmutableMultiset);
- return copy;
- }
-
private LenientSerializableTester() {}
}
diff --git a/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java b/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java
index ea0490f..fb728b3 100644
--- a/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java
@@ -19,24 +19,15 @@ package com.google.common.collect;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.newLinkedHashSet;
-import static com.google.common.collect.testing.Helpers.mapEntry;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.IteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -52,51 +43,10 @@ import java.util.Set;
@GwtCompatible(emulated = true)
public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
- @Override
- protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
- SetMultimap<String, String> multimap = LinkedHashMultimap.create();
- for (Entry<String, String> entry : entries) {
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap;
- }
- })
- .named("LinkedHashMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTestSuite(LinkedHashMultimapTest.class);
- return suite;
- }
-
@Override protected Multimap<String, Integer> create() {
return LinkedHashMultimap.create();
}
- public void testValueSetHashTableExpansion() {
- LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create();
- for (int z = 1; z <= 100; z++) {
- multimap.put("a", z);
- // The Eclipse compiler (and hence GWT) rejects a parameterized cast.
- @SuppressWarnings("unchecked")
- LinkedHashMultimap<String, Integer>.ValueSet valueSet =
- (LinkedHashMultimap.ValueSet) multimap.backingMap().get("a");
- assertEquals(z, valueSet.size());
- assertFalse(Hashing.needsResizing(valueSet.size(), valueSet.hashTable.length,
- LinkedHashMultimap.VALUE_SET_LOAD_FACTOR));
- }
- }
-
private Multimap<String, Integer> initializeMultimap5() {
Multimap<String, Integer> multimap = getMultimap();
multimap.put("foo", 5);
@@ -135,30 +85,13 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
assertOrderingReadOnly(copy);
}
- @GwtIncompatible("SeriazableTester")
- public void testSerializationOrderingKeysAndEntries() {
- Multimap<String, Integer> multimap = LinkedHashMultimap.create();
- multimap.put("a", 1);
- multimap.put("b", 2);
- multimap.put("a", 3);
- multimap.put("c", 4);
- multimap.remove("a", 1);
- multimap = SerializableTester.reserializeAndAssert(multimap);
- ASSERT.that(multimap.keySet()).has().allOf("a", "b", "c").inOrder();
- ASSERT.that(multimap.entries()).has().allOf(
- mapEntry("b", 2),
- mapEntry("a", 3),
- mapEntry("c", 4)).inOrder();
- // note that the keys and entries are in different orders
- }
-
private void assertOrderingReadOnly(Multimap<String, Integer> multimap) {
- ASSERT.that(multimap.get("foo")).has().allOf(5, 3).inOrder();
- ASSERT.that(multimap.get("bar")).has().allOf(4, 1).inOrder();
- ASSERT.that(multimap.get("cow")).has().item(2);
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(5, 3);
+ ASSERT.that(multimap.get("bar")).hasContentsInOrder(4, 1);
+ ASSERT.that(multimap.get("cow")).hasContentsInOrder(2);
- ASSERT.that(multimap.keySet()).has().allOf("foo", "bar", "cow").inOrder();
- ASSERT.that(multimap.values()).has().allOf(5, 4, 3, 2, 1).inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow");
+ ASSERT.that(multimap.values()).hasContentsInOrder(5, 4, 3, 2, 1);
Iterator<Map.Entry<String, Integer>> entryIterator =
multimap.entries().iterator();
@@ -172,28 +105,28 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
multimap.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = collectionIterator.next();
assertEquals("foo", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(5, 3).inOrder();
+ ASSERT.that(entry.getValue()).hasContentsInOrder(5, 3);
entry = collectionIterator.next();
assertEquals("bar", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(4, 1).inOrder();
+ ASSERT.that(entry.getValue()).hasContentsInOrder(4, 1);
entry = collectionIterator.next();
assertEquals("cow", entry.getKey());
- ASSERT.that(entry.getValue()).has().item(2);
+ ASSERT.that(entry.getValue()).hasContentsInOrder(2);
}
public void testOrderingUpdates() {
Multimap<String, Integer> multimap = initializeMultimap5();
- ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).has().allOf(5, 3).inOrder();
- ASSERT.that(multimap.keySet()).has().allOf("foo", "bar", "cow").inOrder();
- ASSERT.that(multimap.removeAll("foo")).has().allOf(6, 7).inOrder();
- ASSERT.that(multimap.keySet()).has().allOf("bar", "cow").inOrder();
+ ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).hasContentsInOrder(5, 3);
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow");
+ ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(6, 7);
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow");
assertTrue(multimap.remove("bar", 4));
- ASSERT.that(multimap.keySet()).has().allOf("bar", "cow").inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow");
assertTrue(multimap.remove("bar", 1));
- ASSERT.that(multimap.keySet()).has().item("cow");
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("cow");
multimap.put("bar", 9);
- ASSERT.that(multimap.keySet()).has().allOf("cow", "bar").inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("cow", "bar");
}
public void testToStringNullExact() {
@@ -236,6 +169,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
multimap.put("bar", 2);
multimap.put("foo", 3);
assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
+ assertEquals(8, multimap.expectedValuesPerKey);
}
public void testCreateFromMultimap() {
@@ -243,6 +177,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
LinkedHashMultimap<String, Integer> copy =
LinkedHashMultimap.create(multimap);
assertEquals(multimap, copy);
+ assertEquals(8, copy.expectedValuesPerKey);
}
public void testCreateFromSizes() {
@@ -252,6 +187,7 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
multimap.put("bar", 2);
multimap.put("foo", 3);
assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
+ assertEquals(15, multimap.expectedValuesPerKey);
}
public void testCreateFromIllegalSizes() {
@@ -357,8 +293,8 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
@GwtIncompatible("unreasonable slow")
public void testKeySetIteration() {
- new IteratorTester<String>(6, MODIFIABLE,
- newLinkedHashSet(asList("foo", "bar", "baz", "dog", "cat")),
+ new IteratorTester<String>(6, MODIFIABLE, newLinkedHashSet(asList(
+ "foo", "bar", "baz", "dog", "cat")),
IteratorTester.KnownOrder.KNOWN_ORDER) {
private Multimap<String, Integer> multimap;
@@ -418,4 +354,5 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
}
}.test();
}
+
}
diff --git a/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java b/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java
index c6148c8..dee3760 100644
--- a/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java
@@ -18,24 +18,15 @@ package com.google.common.collect;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.IteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringMultisetGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
-import java.util.List;
/**
* Unit test for {@link LinkedHashMultiset}.
@@ -44,44 +35,6 @@ import java.util.List;
*/
@GwtCompatible(emulated = true)
public class LinkedHashMultisetTest extends AbstractMultisetTest {
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(MultisetTestSuiteBuilder.using(linkedHashMultisetGenerator())
- .named("LinkedHashMultiset")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.GENERAL_PURPOSE)
- .createTestSuite());
- suite.addTestSuite(LinkedHashMultisetTest.class);
- return suite;
- }
-
- private static TestStringMultisetGenerator linkedHashMultisetGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return LinkedHashMultiset.create(asList(elements));
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- List<String> order = Lists.newArrayList();
- for (String s : insertionOrder) {
- int index = order.indexOf(s);
- if (index == -1) {
- order.add(s);
- } else {
- order.add(index, s);
- }
- }
- return order;
- }
- };
- }
-
@Override protected <E> Multiset<E> create() {
return LinkedHashMultiset.create();
}
@@ -153,14 +106,14 @@ public class LinkedHashMultisetTest extends AbstractMultisetTest {
ms.add("a");
ms.add("b", 2);
ms.add("c");
- ASSERT.that(ms.elementSet()).has().allOf("a", "b", "c").inOrder();
+ ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "b", "c");
ms.remove("b");
- ASSERT.that(ms.elementSet()).has().allOf("a", "b", "c").inOrder();
+ ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "b", "c");
ms.add("b");
- ASSERT.that(ms.elementSet()).has().allOf("a", "b", "c").inOrder();
+ ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "b", "c");
ms.remove("b", 2);
ms.add("b");
- ASSERT.that(ms.elementSet()).has().allOf("a", "c", "b").inOrder();
+ ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "c", "b");
}
public void testIteratorRemoveConcurrentModification() {
diff --git a/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java b/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java
index ffa2435..fd19386 100644
--- a/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java
@@ -23,21 +23,12 @@ import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_REMOVE;
import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_SET;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.ListIteratorTester;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.Collection;
@@ -58,32 +49,6 @@ import java.util.Set;
@GwtCompatible(emulated = true)
public class LinkedListMultimapTest extends AbstractListMultimapTest {
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() {
- @Override
- protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
- ListMultimap<String, String> multimap = LinkedListMultimap.create();
- for (Entry<String, String> entry : entries) {
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap;
- }
- })
- .named("LinkedListMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTestSuite(LinkedListMultimapTest.class);
- return suite;
- }
-
@Override protected LinkedListMultimap<String, Integer> create() {
return LinkedListMultimap.create();
}
@@ -230,10 +195,10 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
List<Integer> foos = map.get("foo");
Collection<Integer> values = map.values();
assertEquals(asList(1, 2), foos);
- ASSERT.that(values).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(values).hasContentsInOrder(1, 2, 3);
map.clear();
assertEquals(Collections.emptyList(), foos);
- ASSERT.that(values).isEmpty();
+ ASSERT.that(values).hasContentsInOrder();
assertEquals("[]", map.entries().toString());
assertEquals("{}", map.toString());
}
@@ -257,7 +222,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
map.put("bar", 4);
assertEquals("[bar=1, foo=2, bar=3, bar=4]",
map.entries().toString());
- ASSERT.that(map.keys()).has().allOf("bar", "foo", "bar", "bar").inOrder();
+ ASSERT.that(map.keys()).hasContentsInOrder("bar", "foo", "bar", "bar");
map.keys().remove("bar"); // bar is no longer the first key!
assertEquals("{foo=[2], bar=[3, 4]}", map.toString());
}
@@ -303,7 +268,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
= map.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = entries.next();
assertEquals("bar", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(1, 3).inOrder();
+ ASSERT.that(entry.getValue()).hasContentsInOrder(1, 3);
try {
entry.setValue(Arrays.<Integer>asList());
fail("UnsupportedOperationException expected");
@@ -311,7 +276,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
entries.remove(); // clear
entry = entries.next();
assertEquals("foo", entry.getKey());
- ASSERT.that(entry.getValue()).has().item(2);
+ ASSERT.that(entry.getValue()).hasContentsInOrder(2);
assertFalse(entries.hasNext());
assertEquals("{foo=[2]}", map.toString());
}
@@ -505,13 +470,4 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
}
}.test();
}
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(
- LinkedListMultimap.create(),
- LinkedListMultimap.create(),
- LinkedListMultimap.create(1))
- .testEquals();
- }
}
diff --git a/guava-tests/test/com/google/common/collect/ListsTest.java b/guava-tests/test/com/google/common/collect/ListsTest.java
index 8dd557c..cd7f710 100644
--- a/guava-tests/test/com/google/common/collect/ListsTest.java
+++ b/guava-tests/test/com/google/common/collect/ListsTest.java
@@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -28,12 +28,12 @@ import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.TestListGenerator;
import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
-import com.google.common.collect.testing.google.ListGenerators.CharactersOfCharSequenceGenerator;
-import com.google.common.collect.testing.google.ListGenerators.CharactersOfStringGenerator;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -53,7 +53,6 @@ import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
-import java.util.concurrent.CopyOnWriteArrayList;
/**
* Unit test for {@code Lists}.
@@ -70,14 +69,6 @@ public class ListsTest extends TestCase {
private static final Iterable<Integer> SOME_ITERABLE = new SomeIterable();
- private static final class RemoveFirstFunction
- implements Function<String, String>, Serializable {
- @Override
- public String apply(String from) {
- return (from.length() == 0) ? from : from.substring(1);
- }
- }
-
private static class SomeIterable implements Iterable<Integer>, Serializable {
@Override
public Iterator<Integer> iterator() {
@@ -115,31 +106,34 @@ public class ListsTest extends TestCase {
suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
@Override protected List<String> create(String[] elements) {
String[] rest = new String[elements.length - 1];
- System.arraycopy(elements, 1, rest, 0, elements.length - 1);
+ Platform.unsafeArrayCopy(elements, 1, rest, 0, elements.length - 1);
return Lists.asList(elements[0], rest);
}
})
.named("Lists.asList, 2 parameter")
.withFeatures(CollectionSize.SEVERAL, CollectionSize.ONE,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
@Override protected List<String> create(String[] elements) {
String[] rest = new String[elements.length - 2];
- System.arraycopy(elements, 2, rest, 0, elements.length - 2);
+ Platform.unsafeArrayCopy(elements, 2, rest, 0, elements.length - 2);
return Lists.asList(elements[0], elements[1], rest);
}
})
.named("Lists.asList, 3 parameter")
.withFeatures(CollectionSize.SEVERAL,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
final Function<String, String> removeFirst
- = new RemoveFirstFunction();
+ = new Function<String, String>() {
+ @Override
+ public String apply(String from) {
+ return (from.length() == 0) ? from : from.substring(1);
+ }
+ };
suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
@Override protected List<String> create(String[] elements) {
@@ -153,7 +147,6 @@ public class ListsTest extends TestCase {
.named("Lists.transform, random access, no nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -169,7 +162,6 @@ public class ListsTest extends TestCase {
.named("Lists.transform, sequential access, no nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -182,7 +174,6 @@ public class ListsTest extends TestCase {
.named("Lists.transform, random access, nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
@@ -196,7 +187,6 @@ public class ListsTest extends TestCase {
.named("Lists.transform, sequential access, nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
@@ -244,15 +234,55 @@ public class ListsTest extends TestCase {
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new CharactersOfStringGenerator())
- .named("Lists.charactersOf[String]").withFeatures(
- CollectionSize.ANY,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ suite.addTest(
+ ListTestSuiteBuilder.using(new TestListGenerator<Character>() {
+ @Override public List<Character> create(Object... elements) {
+ char[] chars = new char[elements.length];
+ for (int i = 0; i < elements.length; i++)
+ chars[i] = (Character) elements[i];
+ return Lists.charactersOf(String.copyValueOf(chars));
+ }
+
+ @Override public Character[] createArray(int length) {
+ return new Character[length];
+ }
+
+ @Override public Iterable<Character> order(
+ List<Character> insertionOrder) {
+ return ImmutableList.copyOf(insertionOrder);
+ }
+
+ @Override public SampleElements<Character> samples() {
+ return new SampleElements<Character>('a', 'b', 'c', 'd', 'e');
+ }
+ }).named("Lists.charactersOf[String]").withFeatures(
+ CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new CharactersOfCharSequenceGenerator())
- .named("Lists.charactersOf[CharSequence]").withFeatures(
+ suite.addTest(
+ ListTestSuiteBuilder.using(new TestListGenerator<Character>() {
+ @Override public List<Character> create(Object... elements) {
+ char[] chars = new char[elements.length];
+ for (int i = 0; i < elements.length; i++)
+ chars[i] = (Character) elements[i];
+ StringBuilder str = new StringBuilder();
+ str.append(chars);
+ return Lists.charactersOf(str);
+ }
+
+ @Override public Character[] createArray(int length) {
+ return new Character[length];
+ }
+
+ @Override public Iterable<Character> order(
+ List<Character> insertionOrder) {
+ return ImmutableList.copyOf(insertionOrder);
+ }
+
+ @Override public SampleElements<Character> samples() {
+ return new SampleElements<Character>('a', 'b', 'c', 'd', 'e');
+ }
+ }).named("Lists.charactersOf[CharSequence]").withFeatures(
CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -352,21 +382,8 @@ public class ListsTest extends TestCase {
assertEquals(SOME_COLLECTION, list);
}
- @GwtIncompatible("CopyOnWriteArrayList")
- public void testNewCOWALEmpty() {
- CopyOnWriteArrayList<Integer> list = Lists.newCopyOnWriteArrayList();
- assertEquals(Collections.emptyList(), list);
- }
-
- @GwtIncompatible("CopyOnWriteArrayList")
- public void testNewCOWALFromIterable() {
- CopyOnWriteArrayList<Integer> list = Lists.newCopyOnWriteArrayList(
- SOME_ITERABLE);
- assertEquals(SOME_COLLECTION, list);
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Lists.class);
}
@@ -418,7 +435,7 @@ public class ListsTest extends TestCase {
}
private void checkFooBarBazList(List<String> list) {
- ASSERT.that(list).has().allOf("foo", "bar", "baz").inOrder();
+ ASSERT.that(list).hasContentsInOrder("foo", "bar", "baz");
assertEquals(3, list.size());
assertIndexIsOutOfBounds(list, -1);
assertEquals("foo", list.get(0));
@@ -429,7 +446,7 @@ public class ListsTest extends TestCase {
public void testAsList1Small() {
List<String> list = Lists.asList("foo", new String[0]);
- ASSERT.that(list).has().item("foo");
+ ASSERT.that(list).hasContentsInOrder("foo");
assertEquals(1, list.size());
assertIndexIsOutOfBounds(list, -1);
assertEquals("foo", list.get(0));
@@ -460,7 +477,7 @@ public class ListsTest extends TestCase {
@GwtIncompatible("SerializableTester")
public void testAsList2Small() {
List<String> list = Lists.asList("foo", "bar", new String[0]);
- ASSERT.that(list).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(list).hasContentsInOrder("foo", "bar");
assertEquals(2, list.size());
assertIndexIsOutOfBounds(list, -1);
assertEquals("foo", list.get(0));
@@ -526,64 +543,18 @@ public class ListsTest extends TestCase {
assertEquals(Collections.emptyList(), fromList);
}
- private static <E> List<E> list(E... elements) {
- return ImmutableList.copyOf(elements);
- }
-
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProduct_binary1x1() {
- ASSERT.that(Lists.cartesianProduct(list(1), list(2))).has().item(list(1, 2));
- }
-
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProduct_binary1x2() {
- ASSERT.that(Lists.cartesianProduct(list(1), list(2, 3)))
- .has().allOf(list(1, 2), list(1, 3)).inOrder();
- }
-
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProduct_binary2x2() {
- ASSERT.that(Lists.cartesianProduct(list(1, 2), list(3, 4)))
- .has().allOf(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder();
- }
-
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProduct_2x2x2() {
- ASSERT.that(Lists.cartesianProduct(list(0, 1), list(0, 1), list(0, 1))).has().allOf(
- list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1),
- list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder();
- }
-
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProduct_contains() {
- List<List<Integer>> actual = Lists.cartesianProduct(list(1, 2), list(3, 4));
- assertTrue(actual.contains(list(1, 3)));
- assertTrue(actual.contains(list(1, 4)));
- assertTrue(actual.contains(list(2, 3)));
- assertTrue(actual.contains(list(2, 4)));
- assertFalse(actual.contains(list(3, 1)));
- }
-
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProduct_unrelatedTypes() {
- List<Integer> x = list(1, 2);
- List<String> y = list("3", "4");
-
- List<Object> exp1 = list((Object) 1, "3");
- List<Object> exp2 = list((Object) 1, "4");
- List<Object> exp3 = list((Object) 2, "3");
- List<Object> exp4 = list((Object) 2, "4");
-
- ASSERT.that(Lists.<Object>cartesianProduct(x, y)).has().allOf(exp1, exp2, exp3, exp4).inOrder();
+ @GwtIncompatible("SerializableTester")
+ public void testTransformEqualityRandomAccess() {
+ List<String> list = Lists.transform(SOME_LIST, SOME_FUNCTION);
+ assertEquals(SOME_STRING_LIST, list);
+ SerializableTester.reserializeAndAssert(list);
}
- @SuppressWarnings("unchecked") // varargs!
- public void testCartesianProductTooBig() {
- List<String> list = Collections.nCopies(10000, "foo");
- try {
- Lists.cartesianProduct(list, list, list, list, list);
- fail("Expected IAE");
- } catch (IllegalArgumentException expected) {}
+ @GwtIncompatible("SerializableTester")
+ public void testTransformEqualitySequential() {
+ List<String> list = Lists.transform(SOME_SEQUENTIAL_LIST, SOME_FUNCTION);
+ assertEquals(SOME_STRING_LIST, list);
+ SerializableTester.reserializeAndAssert(list);
}
public void testTransformHashCodeRandomAccess() {
@@ -750,7 +721,6 @@ public class ListsTest extends TestCase {
ListIterator<Integer> sampleListIterator =
SOME_SEQUENTIAL_LIST.listIterator();
List<Integer> listMock = EasyMock.createMock(IntegerList.class);
- EasyMock.expect(listMock.size()).andReturn(SOME_SEQUENTIAL_LIST.size());
EasyMock.expect(listMock.listIterator(0)).andReturn(sampleListIterator);
EasyMock.replay(listMock);
List<String> transform = Lists.transform(listMock, SOME_FUNCTION);
diff --git a/guava-tests/test/com/google/common/collect/MapConstraintsTest.java b/guava-tests/test/com/google/common/collect/MapConstraintsTest.java
index d743032..6cf647b 100644
--- a/guava-tests/test/com/google/common/collect/MapConstraintsTest.java
+++ b/guava-tests/test/com/google/common/collect/MapConstraintsTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static com.google.common.collect.testing.Helpers.nefariousMapEntry;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -115,11 +115,11 @@ public class MapConstraintsTest extends TestCase {
assertFalse(map.values() instanceof Serializable);
assertEquals(map.toString(), constrained.toString());
assertEquals(map.hashCode(), constrained.hashCode());
- ASSERT.that(map.entrySet()).has().allOf(
+ ASSERT.that(map.entrySet()).hasContentsInOrder(
Maps.immutableEntry(TEST_KEY, TEST_VALUE),
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("bar", 2),
- Maps.immutableEntry("baz", 3)).inOrder();
+ Maps.immutableEntry("baz", 3));
}
public void testConstrainedMapIllegal() {
@@ -163,11 +163,11 @@ public class MapConstraintsTest extends TestCase {
assertEquals(map.values(), constrained.values());
assertEquals(map.toString(), constrained.toString());
assertEquals(map.hashCode(), constrained.hashCode());
- ASSERT.that(map.entrySet()).has().allOf(
+ ASSERT.that(map.entrySet()).hasContentsInOrder(
Maps.immutableEntry(TEST_KEY, TEST_VALUE),
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("bar", 2),
- Maps.immutableEntry("baz", 3)).inOrder();
+ Maps.immutableEntry("baz", 3));
}
public void testConstrainedBiMapIllegal() {
@@ -232,7 +232,7 @@ public class MapConstraintsTest extends TestCase {
assertTrue(constrained.equals(multimap));
ASSERT.that(ImmutableList.copyOf(multimap.entries()))
.is(ImmutableList.copyOf(constrained.entries()));
- ASSERT.that(constrained.asMap().get("foo")).has().item(1);
+ ASSERT.that(constrained.asMap().get("foo")).hasContentsInOrder(1);
assertNull(constrained.asMap().get("missing"));
assertEquals(multimap.asMap(), constrained.asMap());
assertEquals(multimap.values(), constrained.values());
@@ -240,7 +240,7 @@ public class MapConstraintsTest extends TestCase {
assertEquals(multimap.keySet(), constrained.keySet());
assertEquals(multimap.toString(), constrained.toString());
assertEquals(multimap.hashCode(), constrained.hashCode());
- ASSERT.that(multimap.entries()).has().allOf(
+ ASSERT.that(multimap.entries()).hasContentsInOrder(
Maps.immutableEntry(TEST_KEY, TEST_VALUE),
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("bar", 2),
@@ -252,7 +252,7 @@ public class MapConstraintsTest extends TestCase {
Maps.immutableEntry("bim", 8),
Maps.immutableEntry("bop", 9),
Maps.immutableEntry("dig", 10),
- Maps.immutableEntry("dag", 11)).inOrder();
+ Maps.immutableEntry("dag", 11));
assertFalse(constrained.asMap().values() instanceof Serializable);
Iterator<Collection<Integer>> iterator =
constrained.asMap().values().iterator();
diff --git a/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java b/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
index c8c4d47..443a8a8 100644
--- a/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
+++ b/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
@@ -122,6 +122,25 @@ public class MapMakerInternalMapTest extends TestCase {
assertSame(map.valueStrength.defaultEquivalence(), map.valueEquivalence);
}
+ public void testSetValueEquivalence() {
+ Equivalence<Object> testEquivalence = new Equivalence<Object>() {
+ @Override
+ protected boolean doEquivalent(Object a, Object b) {
+ return false;
+ }
+
+ @Override
+ protected int doHash(Object t) {
+ return 0;
+ }
+ };
+
+ MapMakerInternalMap<Object, Object> map =
+ makeMap(createMapMaker().valueEquivalence(testEquivalence));
+ assertSame(testEquivalence, map.valueEquivalence);
+ assertSame(map.keyStrength.defaultEquivalence(), map.keyEquivalence);
+ }
+
public void testSetConcurrencyLevel() {
// round up to nearest power of two
@@ -227,6 +246,13 @@ public class MapMakerInternalMapTest extends TestCase {
assertSame(EntryFactory.WEAK, map.entryFactory);
}
+ @SuppressWarnings("deprecation")
+ public void testSetSoftKeys() {
+ MapMakerInternalMap<Object, Object> map = makeMap(createMapMaker().softKeys());
+ checkStrength(map, Strength.SOFT, Strength.STRONG);
+ assertSame(EntryFactory.SOFT, map.entryFactory);
+ }
+
public void testSetWeakValues() {
MapMakerInternalMap<Object, Object> map = makeMap(createMapMaker().weakValues());
checkStrength(map, Strength.STRONG, Strength.WEAK);
@@ -1078,7 +1104,7 @@ public class MapMakerInternalMapTest extends TestCase {
table.set(0, entry);
segment.count = 1;
assertTrue(segment.removeEntry(entry, hash, RemovalCause.COLLECTED));
- assertNotificationEnqueued(map, key, value);
+ assertNotificationEnqueued(map, key, value, hash);
assertTrue(map.removalNotificationQueue.isEmpty());
assertFalse(segment.evictionQueue.contains(entry));
assertFalse(segment.expirationQueue.contains(entry));
@@ -1178,7 +1204,7 @@ public class MapMakerInternalMapTest extends TestCase {
}
private static <K, V> void assertNotificationEnqueued(
- MapMakerInternalMap<K, V> map, K key, V value) {
+ MapMakerInternalMap<K, V> map, K key, V value, int hash) {
RemovalNotification<K, V> notification = map.removalNotificationQueue.poll();
assertSame(key, notification.getKey());
assertSame(value, notification.getValue());
@@ -1601,7 +1627,7 @@ public class MapMakerInternalMapTest extends TestCase {
/**
* Returns an iterable containing all combinations of maximumSize, expireAfterAccess/Write,
- * weakKeys and weak/softValues.
+ * weak/softKeys and weak/softValues.
*/
private static Iterable<MapMaker> allEntryTypeMakers() {
List<MapMaker> result = newArrayList(allKeyValueStrengthMakers());
@@ -1639,15 +1665,19 @@ public class MapMakerInternalMapTest extends TestCase {
}
/**
- * Returns an iterable containing all combinations weakKeys and weak/softValues.
+ * Returns an iterable containing all combinations weak/softKeys and weak/softValues.
*/
+ @SuppressWarnings("deprecation")
private static Iterable<MapMaker> allKeyValueStrengthMakers() {
return ImmutableList.of(createMapMaker(),
createMapMaker().weakValues(),
createMapMaker().softValues(),
createMapMaker().weakKeys(),
createMapMaker().weakKeys().weakValues(),
- createMapMaker().weakKeys().softValues());
+ createMapMaker().weakKeys().softValues(),
+ createMapMaker().softKeys(),
+ createMapMaker().softKeys().weakValues(),
+ createMapMaker().softKeys().softValues());
}
// listeners
@@ -1826,8 +1856,7 @@ public class MapMakerInternalMapTest extends TestCase {
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return new DummyValueReference<K, V>(value, entry);
}
diff --git a/guava-tests/test/com/google/common/collect/MapsCollectionTest.java b/guava-tests/test/com/google/common/collect/MapsCollectionTest.java
deleted file mode 100644
index f921859..0000000
--- a/guava-tests/test/com/google/common/collect/MapsCollectionTest.java
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
-import com.google.common.collect.testing.SafeTreeMap;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
-import com.google.common.collect.testing.TestMapGenerator;
-import com.google.common.collect.testing.TestStringMapGenerator;
-import com.google.common.collect.testing.TestStringSortedMapGenerator;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapRemoveTester;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringBiMapGenerator;
-import com.google.common.collect.testing.testers.CollectionIteratorTester;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * Test suites for wrappers in {@code Maps}.
- *
- * @author Louis Wasserman
- */
-public class MapsCollectionTest extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(NavigableMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
- @Override
- protected SortedMap<String, String> create(Entry<String, String>[] entries) {
- SafeTreeMap<String, String> map = new SafeTreeMap<String, String>();
- putEntries(map, entries);
- return Maps.unmodifiableNavigableMap(map);
- }
- })
- .named("unmodifiableNavigableMap[SafeTreeMap]")
- .withFeatures(CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_VALUES)
- .createTestSuite());
- suite.addTest(NavigableMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
-
- @Override
- protected SortedMap<String, String> create(Entry<String, String>[] entries) {
- SafeTreeMap<String, String> map = new SafeTreeMap<String, String>();
- putEntries(map, entries);
- return SerializableTester.reserialize(Maps.unmodifiableNavigableMap(map));
- }
- })
- .named("unmodifiableNavigableMap[SafeTreeMap], reserialized")
- .withFeatures(CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_VALUES)
- .createTestSuite());
- suite.addTest(BiMapTestSuiteBuilder
- .using(new TestStringBiMapGenerator() {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> bimap = HashBiMap.create(entries.length);
- for (Entry<String, String> entry : entries) {
- checkArgument(!bimap.containsKey(entry.getKey()));
- bimap.put(entry.getKey(), entry.getValue());
- }
- return Maps.unmodifiableBiMap(bimap);
- }
- })
- .named("unmodifiableBiMap[HashBiMap]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION)
- .createTestSuite());
- suite.addTest(BiMapTestSuiteBuilder
- .using(new TestStringBiMapGenerator() {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> bimap = HashBiMap.create(entries.length);
- for (Entry<String, String> entry : entries) {
- checkArgument(!bimap.containsKey(entry.getKey()));
- bimap.put(entry.getKey(), entry.getValue());
- }
- return SerializableTester.reserialize(Maps.unmodifiableBiMap(bimap));
- }
- })
- .named("unmodifiableBiMap[HashBiMap], reserialized")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION)
- .createTestSuite());
- suite.addTest(MapTestSuiteBuilder
- .using(new TestMapGenerator<String, Integer>() {
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- mapEntry("x", 1),
- mapEntry("xxx", 3),
- mapEntry("xx", 2),
- mapEntry("xxxx", 4),
- mapEntry("aaaaa", 5));
- }
-
- @Override
- public Map<String, Integer> create(Object... elements) {
- Set<String> set = Sets.newLinkedHashSet();
- for (Object e : elements) {
- Entry<?, ?> entry = (Entry<?, ?>) e;
- checkNotNull(entry.getValue());
- set.add((String) checkNotNull(entry.getKey()));
- }
- return Maps.asMap(set, new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- });
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, Integer>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<String, Integer>> order(
- List<Entry<String, Integer>> insertionOrder) {
- return insertionOrder;
- }
-
- @Override
- public String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public Integer[] createValueArray(int length) {
- return new Integer[length];
- }
- })
- .named("Maps.asMap[Set, Function]")
- .withFeatures(CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE)
- .createTestSuite());
- suite.addTest(SortedMapTestSuiteBuilder
- .using(new TestMapGenerator<String, Integer>() {
- @Override
- public String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public Integer[] createValueArray(int length) {
- return new Integer[length];
- }
-
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- mapEntry("a", 1),
- mapEntry("aa", 2),
- mapEntry("aba", 3),
- mapEntry("bbbb", 4),
- mapEntry("ccccc", 5));
- }
-
- @Override
- public SortedMap<String, Integer> create(Object... elements) {
- SortedSet<String> set = new NonNavigableSortedSet();
- for (Object e : elements) {
- Entry<?, ?> entry = (Entry<?, ?>) e;
- checkNotNull(entry.getValue());
- set.add((String) checkNotNull(entry.getKey()));
- }
- return Maps.asMap(set, new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- });
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, Integer>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<String, Integer>> order(
- List<Entry<String, Integer>> insertionOrder) {
- Collections.sort(insertionOrder, new Comparator<Entry<String, Integer>>() {
- @Override
- public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
- return o1.getKey().compareTo(o2.getKey());
- }
- });
- return insertionOrder;
- }
- })
- .named("Maps.asMap[SortedSet, Function]")
- .withFeatures(CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE)
- .createTestSuite());
- suite.addTest(NavigableMapTestSuiteBuilder
- .using(new TestMapGenerator<String, Integer>() {
- @Override
- public String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public Integer[] createValueArray(int length) {
- return new Integer[length];
- }
-
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- mapEntry("a", 1),
- mapEntry("aa", 2),
- mapEntry("aba", 3),
- mapEntry("bbbb", 4),
- mapEntry("ccccc", 5));
- }
-
- @Override
- public NavigableMap<String, Integer> create(Object... elements) {
- NavigableSet<String> set = Sets.newTreeSet(Ordering.natural());
- for (Object e : elements) {
- Map.Entry<?, ?> entry = (Entry<?, ?>) e;
- checkNotNull(entry.getValue());
- set.add((String) checkNotNull(entry.getKey()));
- }
- return Maps.asMap(set, new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- });
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, Integer>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<String, Integer>> order(
- List<Entry<String, Integer>> insertionOrder) {
- Collections.sort(insertionOrder, new Comparator<Entry<String, Integer>>() {
- @Override
- public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
- return o1.getKey().compareTo(o2.getKey());
- }
- });
- return insertionOrder;
- }
- })
- .named("Maps.asMap[NavigableSet, Function]")
- .withFeatures(CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE)
- .createTestSuite());
- suite.addTest(filterSuite());
- return suite;
- }
-
- static TestSuite filterSuite() {
- TestSuite suite = new TestSuite("Filter");
- suite.addTest(filterMapSuite());
- suite.addTest(filterBiMapSuite());
- suite.addTest(filterSortedMapSuite());
- suite.addTest(filterNavigableMapSuite());
- return suite;
- }
-
- static TestSuite filterMapSuite() {
- TestSuite suite = new TestSuite("FilterMap");
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- @Override
- protected Map<String, String> create(Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterKeys(map, FILTER_KEYS);
- }
- })
- .named("Maps.filterKeys[Map, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- @Override
- protected Map<String, String> create(Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterValues(map, FILTER_VALUES);
- }
- })
- .named("Maps.filterValues[Map, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- @Override
- protected Map<String, String> create(Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterEntries(map, FILTER_ENTRIES);
- }
- })
- .named("Maps.filterEntries[Map, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- @Override
- protected Map<String, String> create(Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- map = Maps.filterEntries(map, FILTER_ENTRIES_1);
- return Maps.filterEntries(map, FILTER_ENTRIES_2);
- }
- })
- .named("Maps.filterEntries[Maps.filterEntries[Map, Predicate], Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
- return suite;
- }
-
- static TestSuite filterBiMapSuite() {
- TestSuite suite = new TestSuite("FilterBiMap");
- suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> map = HashBiMap.create();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterKeys(map, FILTER_KEYS);
- }
- })
- .named("Maps.filterKeys[BiMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- BiMapRemoveTester.getKeySetIteratorRemoveMethod())
- .createTestSuite());
- suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> map = HashBiMap.create();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterValues(map, FILTER_VALUES);
- }
- })
- .named("Maps.filterValues[BiMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- BiMapRemoveTester.getKeySetIteratorRemoveMethod())
- .createTestSuite());
- suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- BiMap<String, String> map = HashBiMap.create();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterEntries(map, FILTER_ENTRIES);
- }
- })
- .named("Maps.filterEntries[BiMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- BiMapRemoveTester.getKeySetIteratorRemoveMethod())
- .createTestSuite());
- return suite;
- }
-
- static TestSuite filterSortedMapSuite() {
- TestSuite suite = new TestSuite("FilterSortedMap");
- suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override
- protected SortedMap<String, String> create(Entry<String, String>[] entries) {
- SortedMap<String, String> map = new NonNavigableSortedMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterKeys(map, FILTER_KEYS);
- }
- })
- .named("Maps.filterKeys[SortedMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override
- protected SortedMap<String, String> create(Entry<String, String>[] entries) {
- SortedMap<String, String> map = new NonNavigableSortedMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterValues(map, FILTER_VALUES);
- }
- })
- .named("Maps.filterValues[SortedMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override
- protected SortedMap<String, String> create(Entry<String, String>[] entries) {
- SortedMap<String, String> map = new NonNavigableSortedMap();
- putEntries(map, entries);
- map.putAll(ENTRIES_TO_FILTER);
- return Maps.filterEntries(map, FILTER_ENTRIES);
- }
- })
- .named("Maps.filterEntries[SortedMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- return suite;
- }
-
- static TestSuite filterNavigableMapSuite() {
- TestSuite suite = new TestSuite("FilterNavigableMap");
- suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override
- protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
- NavigableMap<String, String> map = new SafeTreeMap<String, String>();
- putEntries(map, entries);
- map.put("banana", "toast");
- map.put("eggplant", "spam");
- return Maps.filterKeys(map, FILTER_KEYS);
- }
- })
- .named("Maps.filterKeys[NavigableMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override
- protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
- NavigableMap<String, String> map = new SafeTreeMap<String, String>();
- putEntries(map, entries);
- map.put("banana", "toast");
- map.put("eggplant", "spam");
- return Maps.filterValues(map, FILTER_VALUES);
- }
- })
- .named("Maps.filterValues[NavigableMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- @Override
- protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
- NavigableMap<String, String> map = new SafeTreeMap<String, String>();
- putEntries(map, entries);
- map.put("banana", "toast");
- map.put("eggplant", "spam");
- return Maps.filterEntries(map, FILTER_ENTRIES);
- }
- })
- .named("Maps.filterEntries[NavigableMap, Predicate]")
- .withFeatures(
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- CollectionSize.ANY)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- return suite;
- }
-
- static void putEntries(Map<String, String> map, Entry<String, String>[] entries) {
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- }
-
- static final Predicate<String> FILTER_KEYS = new Predicate<String>() {
- @Override
- public boolean apply(@Nullable String string) {
- return !"banana".equals(string) && !"eggplant".equals(string);
- }
- };
-
- static final Predicate<String> FILTER_VALUES = new Predicate<String>() {
- @Override
- public boolean apply(@Nullable String string) {
- return !"toast".equals(string) && !"spam".equals(string);
- }
- };
-
- static final Predicate<Entry<String, String>> FILTER_ENTRIES =
- new Predicate<Entry<String, String>>() {
- @Override
- public boolean apply(Entry<String, String> entry) {
- return !Helpers.mapEntry("banana", "toast").equals(entry)
- && !Helpers.mapEntry("eggplant", "spam").equals(entry);
- }
- };
-
- static final Predicate<Entry<String, String>> FILTER_ENTRIES_1 =
- new Predicate<Entry<String, String>>() {
- @Override
- public boolean apply(Entry<String, String> entry) {
- return !Helpers.mapEntry("banana", "toast").equals(entry);
- }
- };
-
- static final Predicate<Entry<String, String>> FILTER_ENTRIES_2 =
- new Predicate<Entry<String, String>>() {
- @Override
- public boolean apply(Entry<String, String> entry) {
- return !Helpers.mapEntry("eggplant", "spam").equals(entry);
- }
- };
-
- static final Map<String, String> ENTRIES_TO_FILTER =
- ImmutableMap.of("banana", "toast", "eggplant", "spam");
-
- static final Predicate<Entry<String, String>> NOT_NULL_ENTRY =
- new Predicate<Entry<String, String>>() {
- @Override
- public boolean apply(Entry<String, String> entry) {
- return entry.getKey() != null && entry.getValue() != null;
- }
- };
-
- private static class NonNavigableSortedSet
- extends ForwardingSortedSet<String> {
-
- private final SortedSet<String> delegate = Sets.newTreeSet(Ordering.natural());
-
- @Override
- protected SortedSet<String> delegate() {
- return delegate;
- }
- }
-
- private static class NonNavigableSortedMap
- extends ForwardingSortedMap<String, String> {
-
- private final SortedMap<String, String> delegate =
- new SafeTreeMap<String, String>(Ordering.natural());
-
- @Override
- protected SortedMap<String, String> delegate() {
- return delegate;
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java b/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java
index 01a3f13..34768ea 100644
--- a/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java
+++ b/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java
@@ -16,13 +16,13 @@
package com.google.common.collect;
+import java.util.Map;
+import java.util.SortedMap;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
import com.google.common.base.Functions;
-import java.util.Map;
-import java.util.SortedMap;
-
/**
* Tests for {@link Maps#transformValues(SortedMap, Function)}.
*
diff --git a/guava-tests/test/com/google/common/collect/MapsTest.java b/guava-tests/test/com/google/common/collect/MapsTest.java
index c893953..823afa7 100644
--- a/guava-tests/test/com/google/common/collect/MapsTest.java
+++ b/guava-tests/test/com/google/common/collect/MapsTest.java
@@ -17,15 +17,13 @@
package com.google.common.collect;
import static com.google.common.collect.Maps.transformEntries;
-import static com.google.common.collect.Maps.transformValues;
-import static com.google.common.collect.Maps.unmodifiableNavigableMap;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
@@ -33,16 +31,21 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Maps.ValueDifferenceImpl;
import com.google.common.collect.SetsTest.Derived;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.SortedMapInterfaceTest;
+import com.google.common.collect.testing.TestStringMapGenerator;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.io.IOException;
-import java.io.StringReader;
import java.lang.reflect.Field;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
@@ -54,12 +57,9 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
-import java.util.SortedSet;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentMap;
@@ -231,9 +231,9 @@ public class MapsTest extends TestCase {
assertEquals(Collections.emptyMap(), map);
map.put(new Derived("foo"), 1);
map.put(new Derived("bar"), 2);
- ASSERT.that(map.keySet()).has().allOf(
- new Derived("bar"), new Derived("foo")).inOrder();
- ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
+ ASSERT.that(map.keySet()).hasContentsInOrder(
+ new Derived("bar"), new Derived("foo"));
+ ASSERT.that(map.values()).hasContentsInOrder(2, 1);
assertNull(map.comparator());
}
@@ -242,9 +242,9 @@ public class MapsTest extends TestCase {
assertEquals(Collections.emptyMap(), map);
map.put(new LegacyComparable("foo"), 1);
map.put(new LegacyComparable("bar"), 2);
- ASSERT.that(map.keySet()).has().allOf(
- new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
- ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
+ ASSERT.that(map.keySet()).hasContentsInOrder(
+ new LegacyComparable("bar"), new LegacyComparable("foo"));
+ ASSERT.that(map.values()).hasContentsInOrder(2, 1);
assertNull(map.comparator());
}
@@ -310,26 +310,24 @@ public class MapsTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
- public void testToStringImplWithNullKeys() throws Exception {
- Map<String, String> hashmap = Maps.newHashMap();
- hashmap.put("foo", "bar");
- hashmap.put(null, "baz");
-
- assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
- }
-
- public void testToStringImplWithNullValues() throws Exception {
- Map<String, String> hashmap = Maps.newHashMap();
- hashmap.put("foo", "bar");
- hashmap.put("baz", null);
-
- assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
- new NullPointerTester().testAllPublicStaticMethods(Maps.class);
- }
+ public void testNullPointerExceptions() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(BiMap.class, ImmutableBiMap.of());
+ tester.setDefault(EntryTransformer.class, ALWAYS_NULL);
+ tester.setDefault(Equivalence.class, Equivalences.equals());
+ tester.setDefault(SortedMap.class, Maps.newTreeMap());
+ tester.ignore(Maps.class.getDeclaredMethod("uniqueIndex", Object.class, Function.class));
+ tester.testAllPublicStaticMethods(Maps.class);
+ }
+
+ private static final EntryTransformer<Object, Object, Object> ALWAYS_NULL =
+ new EntryTransformer<Object, Object, Object>() {
+ @Override
+ public Object transformEntry(Object k, Object v1) {
+ return null;
+ }
+ };
private static final Map<Integer, Integer> EMPTY
= Collections.emptyMap();
@@ -424,7 +422,7 @@ public class MapsTest extends TestCase {
// TODO(kevinb): replace with Ascii.caseInsensitiveEquivalence() when it
// exists
- Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf(
+ Equivalence<String> caseInsensitiveEquivalence = Equivalences.equals().onResultOf(
new Function<String, String>() {
@Override public String apply(String input) {
return input.toLowerCase();
@@ -513,26 +511,26 @@ public class MapsTest extends TestCase {
SortedMapDifference<Integer, String> diff1 =
Maps.difference(left, right);
assertFalse(diff1.areEqual());
- ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().allOf(
- Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder();
- ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(
+ ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).hasContentsInOrder(
+ Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b"));
+ ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).hasContentsInOrder(
Maps.immutableEntry(6, "z"));
- ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
+ ASSERT.that(diff1.entriesInCommon().entrySet()).hasContentsInOrder(
Maps.immutableEntry(1, "a"));
- ASSERT.that(diff1.entriesDiffering().entrySet()).has().allOf(
+ ASSERT.that(diff1.entriesDiffering().entrySet()).hasContentsInOrder(
Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")),
- Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder();
+ Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")));
assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: "
+ "value differences={5=(e, g), 3=(c, f)}", diff1.toString());
SortedMapDifference<Integer, String> diff2 =
Maps.difference(right, left);
assertFalse(diff2.areEqual());
- ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).has().item(
+ ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).hasContentsInOrder(
Maps.immutableEntry(6, "z"));
- ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).has().allOf(
- Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
- ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
+ ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).hasContentsInOrder(
+ Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d"));
+ ASSERT.that(diff1.entriesInCommon().entrySet()).hasContentsInOrder(
Maps.immutableEntry(1, "a"));
assertEquals(ImmutableMap.of(
3, ValueDifferenceImpl.create("f", "c"),
@@ -552,15 +550,15 @@ public class MapsTest extends TestCase {
Maps.difference(left, right);
left.put(6, "z");
assertFalse(diff1.areEqual());
- ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().allOf(
- Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
- ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(
+ ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).hasContentsInOrder(
+ Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d"));
+ ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).hasContentsInOrder(
Maps.immutableEntry(6, "z"));
- ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
+ ASSERT.that(diff1.entriesInCommon().entrySet()).hasContentsInOrder(
Maps.immutableEntry(1, "a"));
- ASSERT.that(diff1.entriesDiffering().entrySet()).has().allOf(
+ ASSERT.that(diff1.entriesDiffering().entrySet()).hasContentsInOrder(
Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")),
- Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder();
+ Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")));
try {
diff1.entriesInCommon().put(7, "x");
fail();
@@ -601,364 +599,6 @@ public class MapsTest extends TestCase {
.testEquals();
}
- private static final Function<String, Integer> LENGTH_FUNCTION =
- new Function<String, Integer>() {
- @Override
- public Integer apply(String input) {
- return input.length();
- }
- };
-
- public void testAsMap() {
- Set<String> strings = ImmutableSet.of("one", "two", "three");
- Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertEquals(Integer.valueOf(5), map.get("three"));
- assertNull(map.get("five"));
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("two", 3),
- mapEntry("three", 5)).inOrder();
- }
-
- public void testAsMapReadsThrough() {
- Set<String> strings = Sets.newLinkedHashSet();
- Collections.addAll(strings, "one", "two", "three");
- Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertNull(map.get("four"));
- strings.add("four");
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
- assertEquals(Integer.valueOf(4), map.get("four"));
- }
-
- public void testAsMapWritesThrough() {
- Set<String> strings = Sets.newLinkedHashSet();
- Collections.addAll(strings, "one", "two", "three");
- Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertEquals(Integer.valueOf(3), map.remove("two"));
- ASSERT.that(strings).has().allOf("one", "three").inOrder();
- }
-
- public void testAsMapEmpty() {
- Set<String> strings = ImmutableSet.of();
- Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- ASSERT.that(map.entrySet()).isEmpty();
- assertTrue(map.isEmpty());
- assertNull(map.get("five"));
- }
-
- private static class NonNavigableSortedSet
- extends ForwardingSortedSet<String> {
- private final SortedSet<String> delegate = Sets.newTreeSet();
-
- @Override
- protected SortedSet<String> delegate() {
- return delegate;
- }
- }
-
- public void testAsMapReturnsSortedMapForSortedSetInput() {
- Set<String> set = new NonNavigableSortedSet();
- assertTrue(Maps.asMap(set, Functions.identity()) instanceof SortedMap);
- }
-
- public void testAsMapSorted() {
- SortedSet<String> strings = new NonNavigableSortedSet();
- Collections.addAll(strings, "one", "two", "three");
- SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertEquals(Integer.valueOf(5), map.get("three"));
- assertNull(map.get("five"));
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("three", 5),
- mapEntry("two", 3)).inOrder();
- ASSERT.that(map.tailMap("onea").entrySet()).has().allOf(
- mapEntry("three", 5),
- mapEntry("two", 3)).inOrder();
- ASSERT.that(map.subMap("one", "two").entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("three", 5)).inOrder();
- }
-
- public void testAsMapSortedReadsThrough() {
- SortedSet<String> strings = new NonNavigableSortedSet();
- Collections.addAll(strings, "one", "two", "three");
- SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertNull(map.comparator());
- assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
- assertNull(map.get("four"));
- strings.add("four");
- assertEquals(
- ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
- map);
- assertEquals(Integer.valueOf(4), map.get("four"));
- SortedMap<String, Integer> headMap = map.headMap("two");
- assertEquals(
- ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
- headMap);
- strings.add("five");
- strings.remove("one");
- assertEquals(
- ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
- headMap);
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("five", 4),
- mapEntry("four", 4),
- mapEntry("three", 5),
- mapEntry("two", 3)).inOrder();
- }
-
- public void testAsMapSortedWritesThrough() {
- SortedSet<String> strings = new NonNavigableSortedSet();
- Collections.addAll(strings, "one", "two", "three");
- SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertEquals(Integer.valueOf(3), map.remove("two"));
- ASSERT.that(strings).has().allOf("one", "three").inOrder();
- }
-
- public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() {
- SortedMap<String, Integer> map = Maps.asMap(
- new NonNavigableSortedSet(), LENGTH_FUNCTION);
- try {
- map.subMap("a", "z").keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.tailMap("a").keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.headMap("r").keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.headMap("r").tailMap("m").keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- public void testAsMapSortedEmpty() {
- SortedSet<String> strings = new NonNavigableSortedSet();
- SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- ASSERT.that(map.entrySet()).isEmpty();
- assertTrue(map.isEmpty());
- assertNull(map.get("five"));
- }
-
- @GwtIncompatible("NavigableMap")
- public void testAsMapReturnsNavigableMapForNavigableSetInput() {
- Set<String> set = Sets.newTreeSet();
- assertTrue(Maps.asMap(set, Functions.identity()) instanceof NavigableMap);
- }
-
- @GwtIncompatible("NavigableMap")
- public void testAsMapNavigable() {
- NavigableSet<String> strings =
- Sets.newTreeSet(asList("one", "two", "three"));
- NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertEquals(Integer.valueOf(5), map.get("three"));
- assertNull(map.get("five"));
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("three", 5),
- mapEntry("two", 3)).inOrder();
- ASSERT.that(map.tailMap("onea").entrySet()).has().allOf(
- mapEntry("three", 5),
- mapEntry("two", 3)).inOrder();
- ASSERT.that(map.subMap("one", "two").entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("three", 5)).inOrder();
-
- assertEquals(ImmutableSortedMap.of("two", 3, "three", 5),
- map.tailMap("three", true));
- assertEquals(ImmutableSortedMap.of("one", 3, "three", 5),
- map.headMap("two", false));
- assertEquals(ImmutableSortedMap.of("three", 5),
- map.subMap("one", false, "tr", true));
-
- assertEquals("three", map.higherKey("one"));
- assertEquals("three", map.higherKey("r"));
- assertEquals("three", map.ceilingKey("r"));
- assertEquals("one", map.ceilingKey("one"));
- assertEquals(mapEntry("three", 5), map.higherEntry("one"));
- assertEquals(mapEntry("one", 3), map.ceilingEntry("one"));
- assertEquals("one", map.lowerKey("three"));
- assertEquals("one", map.lowerKey("r"));
- assertEquals("one", map.floorKey("r"));
- assertEquals("three", map.floorKey("three"));
-
- ASSERT.that(map.descendingMap().entrySet()).has().allOf(
- mapEntry("two", 3),
- mapEntry("three", 5),
- mapEntry("one", 3)).inOrder();
- assertEquals(map.headMap("three", true),
- map.descendingMap().tailMap("three", true));
- ASSERT.that(map.tailMap("three", false).entrySet()).has().item(
- mapEntry("two", 3));
- assertNull(map.tailMap("three", true).lowerEntry("three"));
- ASSERT.that(map.headMap("two", false).values()).has().allOf(3, 5).inOrder();
- ASSERT.that(map.headMap("two", false).descendingMap().values())
- .has().allOf(5, 3).inOrder();
- ASSERT.that(map.descendingKeySet()).has().allOf(
- "two", "three", "one").inOrder();
-
- assertEquals(mapEntry("one", 3), map.pollFirstEntry());
- assertEquals(mapEntry("two", 3), map.pollLastEntry());
- assertEquals(1, map.size());
- }
-
- @GwtIncompatible("NavigableMap")
- public void testAsMapNavigableReadsThrough() {
- NavigableSet<String> strings = Sets.newTreeSet();
- Collections.addAll(strings, "one", "two", "three");
- NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertNull(map.comparator());
- assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
- assertNull(map.get("four"));
- strings.add("four");
- assertEquals(
- ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
- map);
- assertEquals(Integer.valueOf(4), map.get("four"));
- SortedMap<String, Integer> headMap = map.headMap("two");
- assertEquals(
- ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
- headMap);
- strings.add("five");
- strings.remove("one");
- assertEquals(
- ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
- headMap);
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("five", 4),
- mapEntry("four", 4),
- mapEntry("three", 5),
- mapEntry("two", 3)).inOrder();
-
- NavigableMap<String, Integer> tailMap = map.tailMap("s", true);
- NavigableMap<String, Integer> subMap = map.subMap("a", true, "t", false);
-
- strings.add("six");
- strings.remove("two");
- ASSERT.that(tailMap.entrySet()).has().allOf(
- mapEntry("six", 3),
- mapEntry("three", 5)).inOrder();
- ASSERT.that(subMap.entrySet()).has().allOf(
- mapEntry("five", 4),
- mapEntry("four", 4),
- mapEntry("six", 3)).inOrder();
- }
-
- @GwtIncompatible("NavigableMap")
- public void testAsMapNavigableWritesThrough() {
- NavigableSet<String> strings = Sets.newTreeSet();
- Collections.addAll(strings, "one", "two", "three");
- NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- assertEquals(Integer.valueOf(3), map.remove("two"));
- ASSERT.that(strings).has().allOf("one", "three").inOrder();
- assertEquals(mapEntry("three", 5),
- map.subMap("one", false, "zzz", true).pollLastEntry());
- ASSERT.that(strings).has().item("one");
- }
-
- @GwtIncompatible("NavigableMap")
- public void testAsMapNavigableSubViewKeySetsDoNotSupportAdd() {
- NavigableMap<String, Integer> map = Maps.asMap(
- Sets.<String>newTreeSet(), LENGTH_FUNCTION);
- try {
- map.descendingKeySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.subMap("a", true, "z", false).keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.tailMap("a", true).keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.headMap("r", true).keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- try {
- map.headMap("r", false).tailMap("m", true).keySet().add("a");
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- @GwtIncompatible("NavigableMap")
- public void testAsMapNavigableEmpty() {
- NavigableSet<String> strings = ImmutableSortedSet.of();
- NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
- ASSERT.that(map.entrySet()).isEmpty();
- assertTrue(map.isEmpty());
- assertNull(map.get("five"));
- }
-
- public void testToMap() {
- Iterable<String> strings = ImmutableList.of("one", "two", "three");
- ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("two", 3),
- mapEntry("three", 5)).inOrder();
- }
-
- public void testToMapIterator() {
- Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator();
- ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("two", 3),
- mapEntry("three", 5)).inOrder();
- }
-
- public void testToMapWithDuplicateKeys() {
- Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one");
- ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
- assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
- ASSERT.that(map.entrySet()).has().allOf(
- mapEntry("one", 3),
- mapEntry("two", 3),
- mapEntry("three", 5)).inOrder();
- }
-
- public void testToMapWithNullKeys() {
- Iterable<String> strings = Arrays.asList("one", null, "three");
- try {
- Maps.toMap(strings, Functions.constant("foo"));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void testToMapWithNullValues() {
- Iterable<String> strings = ImmutableList.of("one", "two", "three");
- try {
- Maps.toMap(strings, Functions.constant(null));
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
private static final BiMap<Integer, String> INT_TO_STRING_MAP =
new ImmutableBiMap.Builder<Integer, String>()
.put(1, "one")
@@ -985,6 +625,29 @@ public class MapsTest extends TestCase {
assertEquals(INT_TO_STRING_MAP, outputMap);
}
+ // NOTE: evil, never do this
+ private abstract static class IterableIterator<T>
+ extends ForwardingIterator<T> implements Iterable<T> {
+ @Override
+ public Iterator<T> iterator() {
+ return this;
+ }
+ }
+
+ @SuppressWarnings("deprecation") // that is the purpose of this test
+ public void testUniqueIndexIterableIterator() {
+ ImmutableMap<Integer, String> outputMap =
+ Maps.uniqueIndex(new IterableIterator<String>() {
+ private final Iterator<String> iterator = INT_TO_STRING_MAP.values().iterator();
+
+ public Iterator<String> delegate() {
+ return iterator;
+ }
+ },
+ Functions.forMap(INT_TO_STRING_MAP.inverse()));
+ assertEquals(INT_TO_STRING_MAP, outputMap);
+ }
+
public void testUniqueIndexIterator() {
ImmutableMap<Integer, String> outputMap =
Maps.uniqueIndex(INT_TO_STRING_MAP.values().iterator(),
@@ -1043,7 +706,8 @@ public class MapsTest extends TestCase {
// Now test values loaded from a stream.
String props = "test\n second = 2\n Third item : a short phrase ";
- testProp.load(new StringReader(props));
+ // TODO: change to StringReader in Java 1.6
+ testProp.load(new java.io.StringBufferInputStream(props));
result = Maps.fromProperties(testProp);
assertEquals(4, result.size());
@@ -1061,7 +725,8 @@ public class MapsTest extends TestCase {
testProp = new Properties(System.getProperties());
String override = "test\njava.version : hidden";
- testProp.load(new StringReader(override));
+ // TODO: change to StringReader in Java 1.6
+ testProp.load(new java.io.StringBufferInputStream(override));
result = Maps.fromProperties(testProp);
assertTrue(result.size() > 2);
@@ -1127,7 +792,7 @@ public class MapsTest extends TestCase {
}
@SuppressWarnings("unchecked")
@Override public boolean equals(Object o) {
- if (o instanceof Map.Entry) {
+ if (o instanceof Map.Entry<?, ?>) {
Map.Entry<K, V> e = (Map.Entry<K, V>) o;
e.setValue(value); // muhahaha!
}
@@ -1201,6 +866,18 @@ public class MapsTest extends TestCase {
} catch (UnsupportedOperationException expected) {}
}
+ public void testBiMapEntrySetIteratorRemove() {
+ BiMap<Integer, String> map = HashBiMap.create();
+ map.put(1, "one");
+ Set<Map.Entry<Integer, String>> entries = map.entrySet();
+ Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
+ Map.Entry<Integer, String> entry = iterator.next();
+ entry.setValue("two"); // changes the iterator's current entry value
+ assertEquals("two", map.get(1));
+ iterator.remove(); // removes the updated entry
+ assertTrue(map.isEmpty());
+ }
+
public void testImmutableEntry() {
Map.Entry<String, Integer> e = Maps.immutableEntry("foo", 1);
assertEquals("foo", e.getKey());
@@ -1261,303 +938,193 @@ public class MapsTest extends TestCase {
}
};
- private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() {
- @Override
- public Double apply(Integer in) {
- return Math.sqrt(in);
- }
- };
-
- public static class FilteredMapTest extends TestCase {
- Map<String, Integer> createUnfiltered() {
- return Maps.newHashMap();
- }
-
- public void testFilteredKeysIllegalPut() {
- Map<String, Integer> unfiltered = createUnfiltered();
- Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
- filtered.put("a", 1);
- filtered.put("b", 2);
- assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
-
- try {
- filtered.put("yyy", 3);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testFilteredKeysIllegalPutAll() {
- Map<String, Integer> unfiltered = createUnfiltered();
- Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
- filtered.put("a", 1);
- filtered.put("b", 2);
- assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
-
- try {
- filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
- fail();
- } catch (IllegalArgumentException expected) {}
-
- assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
- }
-
- public void testFilteredKeysFilteredReflectsBackingChanges() {
- Map<String, Integer> unfiltered = createUnfiltered();
- Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
- unfiltered.put("two", 2);
- unfiltered.put("three", 3);
- unfiltered.put("four", 4);
- assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
- assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
-
- unfiltered.remove("three");
- assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
- assertEquals(ImmutableMap.of("four", 4), filtered);
-
- unfiltered.clear();
- assertEquals(ImmutableMap.of(), unfiltered);
- assertEquals(ImmutableMap.of(), filtered);
- }
-
- public void testFilteredValuesIllegalPut() {
- Map<String, Integer> unfiltered = createUnfiltered();
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- filtered.put("a", 2);
- unfiltered.put("b", 4);
- unfiltered.put("c", 5);
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
-
- try {
- filtered.put("yyy", 3);
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- }
-
- public void testFilteredValuesIllegalPutAll() {
- Map<String, Integer> unfiltered = createUnfiltered();
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- filtered.put("a", 2);
- unfiltered.put("b", 4);
- unfiltered.put("c", 5);
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
-
- try {
- filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- }
+ public void testFilteredKeysIllegalPut() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
+ filtered.put("a", 1);
+ filtered.put("b", 2);
+ assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
- public void testFilteredValuesIllegalSetValue() {
- Map<String, Integer> unfiltered = createUnfiltered();
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- filtered.put("a", 2);
- filtered.put("b", 4);
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
-
- Entry<String, Integer> entry = filtered.entrySet().iterator().next();
- try {
- entry.setValue(5);
- fail();
- } catch (IllegalArgumentException expected) {}
-
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- }
-
- public void testFilteredValuesClear() {
- Map<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("one", 1);
- unfiltered.put("two", 2);
- unfiltered.put("three", 3);
- unfiltered.put("four", 4);
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
- unfiltered);
- assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
-
- filtered.clear();
- assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
- assertTrue(filtered.isEmpty());
- }
+ try {
+ filtered.put("yyy", 3);
+ fail();
+ } catch (IllegalArgumentException expected) {}
- public void testFilteredEntriesIllegalPut() {
- Map<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
+ try {
+ filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
+ fail();
+ } catch (IllegalArgumentException expected) {}
- filtered.put("chicken", 7);
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
+ }
- try {
- filtered.put("cow", 7);
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
- }
+ public void testFilteredKeysChangeFiltered() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
+ unfiltered.put("two", 2);
+ unfiltered.put("three", 3);
+ unfiltered.put("four", 4);
+ assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
+ assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
- public void testFilteredEntriesIllegalPutAll() {
- Map<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
+ unfiltered.remove("three");
+ assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
+ assertEquals(ImmutableMap.of("four", 4), filtered);
- filtered.put("chicken", 7);
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ unfiltered.clear();
+ assertEquals(ImmutableMap.of(), unfiltered);
+ assertEquals(ImmutableMap.of(), filtered);
+ }
- try {
- filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
- }
+ public void testFilteredKeysChangeUnfiltered() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
+ unfiltered.put("two", 2);
+ unfiltered.put("three", 3);
+ unfiltered.put("four", 4);
+ assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
+ assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
- public void testFilteredEntriesObjectPredicate() {
- Map<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Predicate<Object> predicate = Predicates.alwaysFalse();
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, predicate);
- assertTrue(filtered.isEmpty());
- }
+ filtered.remove("three");
+ assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
+ assertEquals(ImmutableMap.of("four", 4), filtered);
- public void testFilteredEntriesWildCardEntryPredicate() {
- Map<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
- @Override
- public boolean apply(Entry<?, ?> input) {
- return "cat".equals(input.getKey())
- || Integer.valueOf(2) == input.getValue();
- }
- };
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, predicate);
- assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
- }
+ filtered.clear();
+ assertEquals(ImmutableMap.of("two", 2), unfiltered);
+ assertEquals(ImmutableMap.of(), filtered);
}
- public static class FilteredSortedMapTest extends FilteredMapTest {
- @Override
- SortedMap<String, Integer> createUnfiltered() {
- return Maps.newTreeMap();
- }
-
- public void testFilterKeysIdentifiesSortedMap() {
- SortedMap<String, Integer> map = createUnfiltered();
- assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
- instanceof SortedMap);
- }
+ public void testFilteredValuesIllegalPut() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ filtered.put("a", 2);
+ unfiltered.put("b", 4);
+ unfiltered.put("c", 5);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- public void testFilterValuesIdentifiesSortedMap() {
- SortedMap<String, Integer> map = createUnfiltered();
- assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
- instanceof SortedMap);
- }
+ try {
+ filtered.put("yyy", 3);
+ fail();
+ } catch (IllegalArgumentException expected) {}
- public void testFilterEntriesIdentifiesSortedMap() {
- SortedMap<String, Integer> map = createUnfiltered();
- assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
- instanceof SortedMap);
- }
+ try {
+ filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
+ fail();
+ } catch (IllegalArgumentException expected) {}
- public void testFirstAndLastKeyFilteredMap() {
- SortedMap<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("apple", 2);
- unfiltered.put("banana", 6);
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 5);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ }
- SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
- assertEquals("banana", filtered.firstKey());
- assertEquals("cat", filtered.lastKey());
- }
+ public void testFilteredValuesIllegalSetValue() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ filtered.put("a", 2);
+ filtered.put("b", 4);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- public void testHeadSubTailMap_FilteredMap() {
- SortedMap<String, Integer> unfiltered = createUnfiltered();
- unfiltered.put("apple", 2);
- unfiltered.put("banana", 6);
- unfiltered.put("cat", 4);
- unfiltered.put("dog", 3);
- SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
+ Entry<String, Integer> entry = filtered.entrySet().iterator().next();
+ try {
+ entry.setValue(5);
+ fail();
+ } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("banana", 6), filtered.headMap("dog"));
- assertEquals(ImmutableMap.of(), filtered.headMap("banana"));
- assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.headMap("emu"));
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ }
- assertEquals(ImmutableMap.of("banana", 6), filtered.subMap("banana", "dog"));
- assertEquals(ImmutableMap.of("dog", 3), filtered.subMap("cat", "emu"));
+ public void testFilteredValuesClear() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ unfiltered.put("one", 1);
+ unfiltered.put("two", 2);
+ unfiltered.put("three", 3);
+ unfiltered.put("four", 4);
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
+ unfiltered);
+ assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
- assertEquals(ImmutableMap.of("dog", 3), filtered.tailMap("cat"));
- assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.tailMap("banana"));
- }
+ filtered.clear();
+ assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
+ assertTrue(filtered.isEmpty());
}
- public static class FilteredBiMapTest extends FilteredMapTest {
- @Override
- BiMap<String, Integer> createUnfiltered() {
- return HashBiMap.create();
- }
+ public void testFilteredEntriesIllegalPut() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
- public void testFilterKeysIdentifiesBiMap() {
- BiMap<String, Integer> map = createUnfiltered();
- assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
- instanceof BiMap);
- }
+ filtered.put("chicken", 7);
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
- public void testFilterValuesIdentifiesBiMap() {
- BiMap<String, Integer> map = createUnfiltered();
- assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
- instanceof BiMap);
- }
+ try {
+ filtered.put("cow", 7);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
- public void testFilterEntriesIdentifiesBiMap() {
- BiMap<String, Integer> map = createUnfiltered();
- assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
- instanceof BiMap);
- }
+ try {
+ filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ }
+
+ public void testFilteredEntriesObjectPredicate() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Predicate<Object> predicate = Predicates.alwaysFalse();
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, predicate);
+ assertTrue(filtered.isEmpty());
+ }
+
+ public void testFilteredEntriesWildCardEntryPredicate() {
+ Map<String, Integer> unfiltered = Maps.newHashMap();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
+ @Override
+ public boolean apply(Entry<?, ?> input) {
+ return "cat".equals(input.getKey())
+ || Integer.valueOf(2) == input.getValue();
+ }
+ };
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, predicate);
+ assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
}
public void testTransformValues() {
Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
- Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
+ Function<Integer, Double> sqrt = new Function<Integer, Double>() {
+ @Override
+ public Double apply(Integer in) {
+ return Math.sqrt(in);
+ }
+ };
+ Map<String, Double> transformed = Maps.transformValues(map, sqrt);
assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
}
public void testTransformValuesSecretlySorted() {
- Map<String, Integer> map =
- sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
- Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
-
- assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
- assertTrue(transformed instanceof SortedMap);
- }
-
- @GwtIncompatible("NavigableMap")
- public void testTransformValuesSecretlyNavigable() {
Map<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
- Map<String, Double> transformed;
-
- transformed = transformValues(map, SQRT_FUNCTION);
- assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
- assertTrue(transformed instanceof NavigableMap);
+ Function<Integer, Double> sqrt = new Function<Integer, Double>() {
+ @Override
+ public Double apply(Integer in) {
+ return Math.sqrt(in);
+ }
+ };
+ Map<String, Double> transformed = Maps.transformValues(map, sqrt);
- transformed =
- transformValues((SortedMap<String, Integer>) map, SQRT_FUNCTION);
assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
- assertTrue(transformed instanceof NavigableMap);
+ assertTrue(transformed instanceof SortedMap);
}
public void testTransformEntries() {
@@ -1569,7 +1136,7 @@ public class MapsTest extends TestCase {
return key + value;
}
};
- Map<String, String> transformed = transformEntries(map, concat);
+ Map<String, String> transformed = Maps.transformEntries(map, concat);
assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
}
@@ -1583,33 +1150,12 @@ public class MapsTest extends TestCase {
return key + value;
}
};
- Map<String, String> transformed = transformEntries(map, concat);
+ Map<String, String> transformed = Maps.transformEntries(map, concat);
assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
assertTrue(transformed instanceof SortedMap);
}
- @GwtIncompatible("NavigableMap")
- public void testTransformEntriesSecretlyNavigable() {
- Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
- EntryTransformer<String, String, String> concat =
- new EntryTransformer<String, String, String>() {
- @Override
- public String transformEntry(String key, String value) {
- return key + value;
- }
- };
- Map<String, String> transformed;
-
- transformed = transformEntries(map, concat);
- assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
- assertTrue(transformed instanceof NavigableMap);
-
- transformed = transformEntries((SortedMap<String, String>) map, concat);
- assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
- assertTrue(transformed instanceof NavigableMap);
- }
-
public void testTransformEntriesGenerics() {
Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2);
Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2);
@@ -1676,65 +1222,169 @@ public class MapsTest extends TestCase {
return value ? key : "no" + key;
}
};
- Map<String, String> transformed = transformEntries(options, flagPrefixer);
+ Map<String, String> transformed =
+ Maps.transformEntries(options, flagPrefixer);
assertEquals("{verbose=verbose, sort=nosort}", transformed.toString());
}
- // Logically this would accept a NavigableMap, but that won't work under GWT.
- private static <K, V> SortedMap<K, V> sortedNotNavigable(
- final SortedMap<K, V> map) {
- return new ForwardingSortedMap<K, V>() {
- @Override protected SortedMap<K, V> delegate() {
- return map;
- }
- };
- }
+ // TestStringMapGenerator uses entries of the form "one=January" and so forth.
+ // To test the filtered collections, we'll create a map containing the entries
+ // they ask for, plus some bogus numeric entries. Then our predicates will
+ // simply filter numeric entries back out.
- public void testSortedMapTransformValues() {
- SortedMap<String, Integer> map =
- sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
- SortedMap<String, Double> transformed =
- transformValues(map, SQRT_FUNCTION);
+ private static ImmutableMap<String, String> ENTRIES_TO_FILTER_OUT =
+ new ImmutableMap.Builder<String, String>()
+ .put("0", "0")
+ .put("1", "1")
+ .put("2", "2")
+ .build();
- /*
- * We'd like to sanity check that we didn't get a NavigableMap out, but we
- * can't easily do so while maintaining GWT compatibility.
- */
- assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
+ @GwtIncompatible("suite")
+ public static class FilteredMapTests extends TestCase {
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(MapTestSuiteBuilder.using(
+ new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
+ Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ map.putAll(ENTRIES_TO_FILTER_OUT);
+ return Maps.filterKeys(map, new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input == null
+ || (input.charAt(0) >= 'a' && input.charAt(0) <= 'z');
+ }
+ });
+ }
+ })
+ .named("Maps.filterKeys")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE)
+ .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ suite.addTest(MapTestSuiteBuilder.using(
+ new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
+ Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ map.putAll(ENTRIES_TO_FILTER_OUT);
+ return Maps.filterValues(map, new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input == null
+ || (input.charAt(0) >= 'A' && input.charAt(0) <= 'Z');
+ }
+ });
+ }
+ })
+ .named("Maps.filterValues")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE)
+ .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ suite.addTest(MapTestSuiteBuilder.using(
+ new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
+ Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ map.putAll(ENTRIES_TO_FILTER_OUT);
+ return Maps.filterEntries(map,
+ new Predicate<Entry<String, String>>() {
+ @Override
+ public boolean apply(Entry<String, String> entry) {
+ String input = entry.getKey();
+ return input == null
+ || (input.charAt(0) >= 'a' && input.charAt(0) <= 'z');
+ }
+ });
+ }
+ })
+ .named("Maps.filterEntries")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE)
+ .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ suite.addTest(MapTestSuiteBuilder.using(
+ new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
+ Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ map.putAll(ENTRIES_TO_FILTER_OUT);
+ map.put("", "weird");
+ Map<String, String> withoutEmptyKey = Maps.filterKeys(map,
+ new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input == null || input.length() != 0;
+ }
+ });
+ return Maps.filterKeys(withoutEmptyKey, new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input == null
+ || (input.charAt(0) >= 'a' && input.charAt(0) <= 'z');
+ }
+ });
+ // note: these filters were deliberately chosen so that an
+ // element somehow getting around the first filter would cause
+ // an exception in the second
+ }
+ })
+ .named("Maps.filterKeys, chained")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE)
+ .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ return suite;
+ }
}
- @GwtIncompatible("NavigableMap")
- public void testNavigableMapTransformValues() {
- NavigableMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
- NavigableMap<String, Double> transformed =
- transformValues(map, SQRT_FUNCTION);
+ public void testSortedMapTransformValues() {
+ SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
+ Function<Integer, Double> sqrt = new Function<Integer, Double>() {
+ @Override
+ public Double apply(Integer in) {
+ return Math.sqrt(in);
+ }
+ };
+ SortedMap<String, Double> transformed =
+ Maps.transformValues(map, sqrt);
assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
}
public void testSortedMapTransformEntries() {
- SortedMap<String, String> map =
- sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9"));
- EntryTransformer<String, String, String> concat =
- new EntryTransformer<String, String, String>() {
- @Override
- public String transformEntry(String key, String value) {
- return key + value;
- }
- };
- SortedMap<String, String> transformed = transformEntries(map, concat);
-
- /*
- * We'd like to sanity check that we didn't get a NavigableMap out, but we
- * can't easily do so while maintaining GWT compatibility.
- */
- assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
- }
-
- @GwtIncompatible("NavigableMap")
- public void testNavigableMapTransformEntries() {
- NavigableMap<String, String> map =
- ImmutableSortedMap.of("a", "4", "b", "9");
+ SortedMap<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
EntryTransformer<String, String, String> concat =
new EntryTransformer<String, String, String>() {
@Override
@@ -1742,148 +1392,128 @@ public class MapsTest extends TestCase {
return key + value;
}
};
- NavigableMap<String, String> transformed = transformEntries(map, concat);
+ SortedMap<String, String> transformed =
+ Maps.transformEntries(map, concat);
assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
}
- @GwtIncompatible("NavigableMap")
- public void testUnmodifiableNavigableMap() {
- TreeMap<Integer, String> mod = Maps.newTreeMap();
- mod.put(1, "one");
- mod.put(2, "two");
- mod.put(3, "three");
-
- NavigableMap<Integer, String> unmod = unmodifiableNavigableMap(mod);
-
- /* unmod is a view. */
- mod.put(4, "four");
- assertEquals("four", unmod.get(4));
- assertEquals("four", unmod.descendingMap().get(4));
-
- ensureNotDirectlyModifiable(unmod);
- ensureNotDirectlyModifiable(unmod.descendingMap());
- ensureNotDirectlyModifiable(unmod.headMap(2, true));
- ensureNotDirectlyModifiable(unmod.subMap(1, true, 3, true));
- ensureNotDirectlyModifiable(unmod.tailMap(2, true));
-
- Collection<String> values = unmod.values();
- try {
- values.add("4");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- values.remove("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- values.removeAll(Collections.singleton("four"));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+ /*
+ * Not testing Map methods of Maps.filter*(SortedMap), since the
+ * implementation doesn't override Maps.FilteredEntryMap, which is already
+ * tested.
+ */
+
+ public void testSortedMapFilterKeys() {
+ Comparator<Integer> comparator = Ordering.natural();
+ SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
+ unfiltered.put(1, "one");
+ unfiltered.put(2, "two");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ unfiltered.put(6, "six");
+ unfiltered.put(7, "seven");
+ SortedMap<Integer, String> filtered
+ = Maps.filterKeys(unfiltered, EVEN);
+ ASSERT.that(filtered.keySet()).hasContentsInOrder(2, 4, 6);
+ assertSame(comparator, filtered.comparator());
+ assertEquals((Integer) 2, filtered.firstKey());
+ assertEquals((Integer) 6, filtered.lastKey());
+ ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(2, 4);
+ ASSERT.that(filtered.tailMap(3).keySet()).hasContentsInOrder(4, 6);
+ ASSERT.that(filtered.subMap(3, 5).keySet()).hasContentsInOrder(4);
+ }
+
+ public void testSortedMapFilterValues() {
+ Comparator<Integer> comparator = Ordering.natural();
+ SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
+ unfiltered.put(1, "one");
+ unfiltered.put(2, "two");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ unfiltered.put(6, "six");
+ unfiltered.put(7, "seven");
+ SortedMap<Integer, String> filtered
+ = Maps.filterValues(unfiltered, NOT_LENGTH_3);
+ ASSERT.that(filtered.keySet()).hasContentsInOrder(3, 4, 5, 7);
+ assertSame(comparator, filtered.comparator());
+ assertEquals((Integer) 3, filtered.firstKey());
+ assertEquals((Integer) 7, filtered.lastKey());
+ ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(3, 4);
+ ASSERT.that(filtered.tailMap(4).keySet()).hasContentsInOrder(4, 5, 7);
+ ASSERT.that(filtered.subMap(4, 6).keySet()).hasContentsInOrder(4, 5);
+ }
+
+ private static final Predicate<Map.Entry<Integer, String>>
+ EVEN_AND_LENGTH_3 = new Predicate<Map.Entry<Integer, String>>() {
+ @Override public boolean apply(Entry<Integer, String> entry) {
+ return (entry.getKey() == null || entry.getKey() % 2 == 0)
+ && (entry.getValue() == null || entry.getValue().length() == 3);
+ }
+ };
+
+ private static class ContainsKeySafeSortedMap
+ extends ForwardingSortedMap<Integer, String> {
+ SortedMap<Integer, String> delegate
+ = Maps.newTreeMap(Ordering.natural().nullsFirst());
+
+ @Override protected SortedMap<Integer, String> delegate() {
+ return delegate;
}
- try {
- values.retainAll(Collections.singleton("four"));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+
+ // Needed by MapInterfaceTest.testContainsKey()
+ @Override public boolean containsKey(Object key) {
+ try {
+ return super.containsKey(key);
+ } catch (ClassCastException e) {
+ return false;
+ }
}
- try {
- Iterator<String> iterator = values.iterator();
- iterator.next();
- iterator.remove();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+ }
+
+ public static class FilteredEntriesSortedMapInterfaceTest
+ extends SortedMapInterfaceTest<Integer, String> {
+ public FilteredEntriesSortedMapInterfaceTest() {
+ super(true, true, true, true, true);
}
- Set<Map.Entry<Integer, String>> entries = unmod.entrySet();
- try {
- Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
- iterator.next();
- iterator.remove();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+ @Override protected SortedMap<Integer, String> makeEmptyMap() {
+ SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
+ unfiltered.put(1, "one");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ return Maps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
}
- Map.Entry<Integer, String> entry = entries.iterator().next();
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- entry = unmod.lowerEntry(1);
- assertNull(entry);
- entry = unmod.floorEntry(2);
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- entry = unmod.ceilingEntry(2);
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- entry = unmod.lowerEntry(2);
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- entry = unmod.higherEntry(2);
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- entry = unmod.firstEntry();
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- entry = unmod.lastEntry();
- try {
- entry.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- @SuppressWarnings("unchecked")
- Map.Entry<Integer, String> entry2 =
- (Map.Entry<Integer, String>) entries.toArray()[0];
- try {
- entry2.setValue("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- }
- @GwtIncompatible("NavigableMap")
- void ensureNotDirectlyModifiable(NavigableMap<Integer, String> unmod) {
- try {
- unmod.put(4, "four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+ @Override protected SortedMap<Integer, String> makePopulatedMap() {
+ SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
+ unfiltered.put(1, "one");
+ unfiltered.put(2, "two");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ unfiltered.put(6, "six");
+ return Maps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
}
- try {
- unmod.putAll(Collections.singletonMap(4, "four"));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- unmod.remove("four");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- unmod.pollFirstEntry();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+
+ @Override protected Integer getKeyNotInPopulatedMap() {
+ return 10;
}
- try {
- unmod.pollLastEntry();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+
+ @Override protected String getValueNotInPopulatedMap() {
+ return "ten";
}
+
+ // Iterators don't support remove.
+ @Override public void testEntrySetIteratorRemove() {}
+ @Override public void testValuesIteratorRemove() {}
+
+ // These tests fail on GWT.
+ // TODO: Investigate why.
+ @Override public void testEntrySetRemoveAll() {}
+ @Override public void testEntrySetRetainAll() {}
}
}
diff --git a/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java b/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java
index 00679cc..549cb52 100644
--- a/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java
+++ b/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java
@@ -16,11 +16,6 @@
package com.google.common.collect;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.testing.MapInterfaceTest;
-
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
@@ -28,6 +23,11 @@ import java.util.Set;
import javax.annotation.Nullable;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.testing.MapInterfaceTest;
+
/**
* Tests for {@link Maps#transformValues}.
*
diff --git a/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java b/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java
index 48ebea3..8cc8559 100644
--- a/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java
+++ b/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.collect.testing.IteratorFeature;
import com.google.common.collect.testing.IteratorTester;
@@ -26,7 +26,6 @@ import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
@@ -355,7 +354,7 @@ public class MinMaxPriorityQueueTest extends TestCase {
}
}
assertTrue(q.isIntact());
- ASSERT.that(result).has().allOf(1, 15, 13, 8, 14);
+ ASSERT.that(result).hasContentsAnyOrder(1, 15, 13, 8, 14);
}
/**
@@ -562,18 +561,6 @@ public class MinMaxPriorityQueueTest extends TestCase {
}
}
- public void testRemoveAt_exhaustive() {
- int size = 8;
- List<Integer> expected = createOrderedList(size);
- for (Collection<Integer> perm : Collections2.permutations(expected)) {
- for (int i = 0; i < perm.size(); i++) {
- MinMaxPriorityQueue<Integer> q = MinMaxPriorityQueue.create(perm);
- q.removeAt(i);
- assertTrue("Remove at " + i + " perm " + perm, q.isIntact());
- }
- }
- }
-
/**
* Regression test for bug found.
*/
@@ -690,26 +677,6 @@ public class MinMaxPriorityQueueTest extends TestCase {
assertTrue(q.isEmpty());
}
- public void testExhaustive_pollAndPush() {
- int size = 8;
- List<Integer> expected = createOrderedList(size);
- for (Collection<Integer> perm : Collections2.permutations(expected)) {
- MinMaxPriorityQueue<Integer> q = MinMaxPriorityQueue.create(perm);
- List<Integer> elements = Lists.newArrayListWithCapacity(size);
- while (!q.isEmpty()) {
- Integer next = q.pollFirst();
- for (int i = 0; i <= size; i++) {
- assertTrue(q.add(i));
- assertTrue(q.add(next));
- assertTrue(q.remove(i));
- assertEquals(next, q.poll());
- }
- elements.add(next);
- }
- assertEquals("Started with " + perm, expected, elements);
- }
- }
-
/**
* Regression test for b/4124577
*/
@@ -720,23 +687,23 @@ public class MinMaxPriorityQueueTest extends TestCase {
List<Integer> contents = Lists.newArrayList(expected);
List<Integer> elements = Lists.newArrayListWithCapacity(size);
while (!q.isEmpty()) {
- ASSERT.that(q).has().allFrom(contents);
+ ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
Integer next = q.pollFirst();
contents.remove(next);
- ASSERT.that(q).has().allFrom(contents);
+ ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
for (int i = 0; i <= size; i++) {
q.add(i);
contents.add(i);
- ASSERT.that(q).has().allFrom(contents);
+ ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
q.add(next);
contents.add(next);
- ASSERT.that(q).has().allFrom(contents);
+ ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
q.remove(i);
assertTrue(contents.remove(Integer.valueOf(i)));
- ASSERT.that(q).has().allFrom(contents);
+ ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
assertEquals(next, q.poll());
contents.remove(next);
- ASSERT.that(q).has().allFrom(contents);
+ ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
}
elements.add(next);
}
@@ -819,7 +786,7 @@ public class MinMaxPriorityQueueTest extends TestCase {
}
}
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicConstructors(MinMaxPriorityQueue.class);
tester.testAllPublicStaticMethods(MinMaxPriorityQueue.class);
diff --git a/guava-tests/test/com/google/common/collect/MultimapCollectionTest.java b/guava-tests/test/com/google/common/collect/MultimapCollectionTest.java
new file mode 100644
index 0000000..886dfd1
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/MultimapCollectionTest.java
@@ -0,0 +1,978 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
+import static com.google.common.collect.testing.features.CollectionFeature.REMOVE_OPERATIONS;
+import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
+import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
+import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
+import static java.lang.reflect.Proxy.newProxyInstance;
+
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.testing.CollectionTestSuiteBuilder;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestCollectionGenerator;
+import com.google.common.collect.testing.TestListGenerator;
+import com.google.common.collect.testing.TestStringCollectionGenerator;
+import com.google.common.collect.testing.TestStringListGenerator;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.TestStringSortedSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.Feature;
+import com.google.common.collect.testing.features.ListFeature;
+import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.MultisetWritesTester;
+import com.google.common.collect.testing.google.TestStringMultisetGenerator;
+import com.google.common.collect.testing.testers.CollectionIteratorTester;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Run collection tests on {@link Multimap} implementations.
+ *
+ * @author Jared Levy
+ */
+@GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
+public class MultimapCollectionTest extends TestCase {
+
+ private static final Feature<?>[] COLLECTION_FEATURES = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.GENERAL_PURPOSE
+ };
+
+ static final Feature<?>[] COLLECTION_FEATURES_ORDER = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE
+ };
+ static final Feature<?>[] COLLECTION_FEATURES_REMOVE = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS
+ };
+
+ static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.REMOVE_OPERATIONS
+ };
+
+ private static final Feature<?>[] LIST_FEATURES = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ ListFeature.GENERAL_PURPOSE
+ };
+
+ private static final Feature<?>[] LIST_FEATURES_REMOVE_SET = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ ListFeature.REMOVE_OPERATIONS,
+ ListFeature.SUPPORTS_SET
+ };
+
+ private static final Feature<?>[] FOR_MAP_FEATURES_ONE = {
+ CollectionSize.ONE,
+ ALLOWS_NULL_VALUES,
+ REMOVE_OPERATIONS,
+ };
+
+ private static final Feature<?>[] FOR_MAP_FEATURES_ANY = {
+ CollectionSize.ANY,
+ ALLOWS_NULL_VALUES,
+ REMOVE_OPERATIONS,
+ };
+
+ static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY
+ = new Supplier<TreeSet<String>>() {
+ @Override
+ public TreeSet<String> get() {
+ return new TreeSet<String>(Ordering.natural().nullsLast());
+ }
+ };
+
+ static void populateMultimapForGet(
+ Multimap<Integer, String> multimap, String[] elements) {
+ multimap.put(2, "foo");
+ for (String element : elements) {
+ multimap.put(3, element);
+ }
+ }
+
+ static void populateMultimapForKeySet(
+ Multimap<String, Integer> multimap, String[] elements) {
+ for (String element : elements) {
+ multimap.put(element, 2);
+ multimap.put(element, 3);
+ }
+ }
+
+ static void populateMultimapForValues(
+ Multimap<Integer, String> multimap, String[] elements) {
+ for (int i = 0; i < elements.length; i++) {
+ multimap.put(i % 2, elements[i]);
+ }
+ }
+
+ static void populateMultimapForKeys(
+ Multimap<String, Integer> multimap, String[] elements) {
+ for (int i = 0; i < elements.length; i++) {
+ multimap.put(elements[i], i);
+ }
+ }
+
+ /**
+ * Implements {@code Multimap.put()} -- and no other methods -- for a {@code
+ * Map} by ignoring all but the latest value for each key. This class exists
+ * only so that we can use
+ * {@link MultimapCollectionTest#populateMultimapForGet(Multimap, String[])}
+ * and similar methods to populate a map to be passed to
+ * {@link Multimaps#forMap(Map)}. All tests should run against the result of
+ * {@link #build()}.
+ */
+ private static final class PopulatableMapAsMultimap<K, V>
+ extends ForwardingMultimap<K, V> {
+ final Map<K, V> map;
+ final SetMultimap<K, V> unusableDelegate;
+
+ static <K, V> PopulatableMapAsMultimap<K, V> create() {
+ return new PopulatableMapAsMultimap<K, V>();
+ }
+
+ @SuppressWarnings("unchecked") // all methods throw immediately
+ PopulatableMapAsMultimap() {
+ this.map = newHashMap();
+ this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance(
+ SetMultimap.class.getClassLoader(),
+ new Class<?>[] {SetMultimap.class},
+ new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ throw new UnsupportedOperationException();
+ }
+ });
+ }
+
+ @Override protected Multimap<K, V> delegate() {
+ return unusableDelegate;
+ }
+
+ @Override public boolean put(K key, V value) {
+ map.put(key, value);
+ return true;
+ }
+
+ SetMultimap<K, V> build() {
+ return Multimaps.forMap(map);
+ }
+ }
+
+ static abstract class TestEntriesGenerator
+ implements TestCollectionGenerator<Entry<String, Integer>> {
+ @Override
+ public SampleElements<Entry<String, Integer>> samples() {
+ return new SampleElements<Entry<String, Integer>>(
+ Maps.immutableEntry("bar", 1),
+ Maps.immutableEntry("bar", 2),
+ Maps.immutableEntry("foo", 3),
+ Maps.immutableEntry("bar", 3),
+ Maps.immutableEntry("cat", 2));
+ }
+
+ @Override
+ public Collection<Entry<String, Integer>> create(Object... elements) {
+ Multimap<String, Integer> multimap = createMultimap();
+ for (Object element : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Integer> entry = (Entry<String, Integer>) element;
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap.entries();
+ }
+
+ abstract Multimap<String, Integer> createMultimap();
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Entry<String, Integer>[] createArray(int length) {
+ return (Entry<String, Integer>[]) new Entry<?, ?>[length];
+ }
+
+ @Override
+ public List<Entry<String, Integer>> order(
+ List<Entry<String, Integer>> insertionOrder) {
+ return insertionOrder;
+ }
+ }
+
+ public static abstract class TestEntriesListGenerator
+ extends TestEntriesGenerator
+ implements TestListGenerator<Entry<String, Integer>> {
+ @Override public List<Entry<String, Integer>> create(Object... elements) {
+ return (List<Entry<String, Integer>>) super.create(elements);
+ }
+ }
+
+ private static abstract class TestEntrySetGenerator
+ extends TestEntriesGenerator {
+ @Override abstract SetMultimap<String, Integer> createMultimap();
+
+ @Override public Set<Entry<String, Integer>> create(Object... elements) {
+ return (Set<Entry<String, Integer>>) super.create(elements);
+ }
+ }
+
+ private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE
+ = new Predicate<Map.Entry<Integer, String>>() {
+ @Override public boolean apply(Entry<Integer, String> entry) {
+ return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey();
+ }
+ };
+
+ private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE
+ = new Predicate<Map.Entry<String, Integer>>() {
+ @Override public boolean apply(Entry<String, Integer> entry) {
+ return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue();
+ }
+ };
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SetMultimap<Integer, String> multimap = HashMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return multimap.get(3);
+ }
+ })
+ .named("HashMultimap.get")
+ .withFeatures(COLLECTION_FEATURES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SetMultimap<Integer, String> multimap
+ = LinkedHashMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return multimap.get(3);
+ }
+ })
+ .named("LinkedHashMultimap.get")
+ .withFeatures(COLLECTION_FEATURES_ORDER)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSortedSetGenerator() {
+ @Override protected SortedSet<String> create(String[] elements) {
+ SortedSetMultimap<Integer, String> multimap =
+ TreeMultimap.create(Ordering.natural().nullsFirst(),
+ Ordering.natural().nullsLast());
+ populateMultimapForGet(multimap, elements);
+ return multimap.get(3);
+ }
+ })
+ .named("TreeMultimap.get")
+ .withFeatures(COLLECTION_FEATURES_ORDER)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ ListMultimap<Integer, String> multimap
+ = ArrayListMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return multimap.get(3);
+ }
+ })
+ .named("ArrayListMultimap.get")
+ .withFeatures(LIST_FEATURES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ ListMultimap<Integer, String> multimap
+ = Multimaps.synchronizedListMultimap(
+ ArrayListMultimap.<Integer, String>create());
+ populateMultimapForGet(multimap, elements);
+ return multimap.get(3);
+ }
+ })
+ .named("synchronized ArrayListMultimap.get")
+ .withFeatures(LIST_FEATURES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ ListMultimap<Integer, String> multimap
+ = LinkedListMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return multimap.get(3);
+ }
+ })
+ .named("LinkedListMultimap.get")
+ .withFeatures(LIST_FEATURES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ ImmutableListMultimap.Builder<Integer, String> builder
+ = ImmutableListMultimap.builder();
+ ListMultimap<Integer, String> multimap
+ = builder.put(2, "foo")
+ .putAll(3, elements)
+ .build();
+ return multimap.get(3);
+ }
+ })
+ .named("ImmutableListMultimap.get")
+ .withFeatures(CollectionSize.ANY)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ PopulatableMapAsMultimap<Integer, String> multimap
+ = PopulatableMapAsMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return multimap.build().get(3);
+ }
+ })
+ .named("Multimaps.forMap.get")
+ .withFeatures(FOR_MAP_FEATURES_ONE)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SetMultimap<Integer, String> multimap
+ = LinkedHashMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ multimap.put(3, "badvalue");
+ multimap.put(55556, "foo");
+ return (Set<String>) Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).get(3);
+ }
+ })
+ .named("Multimaps.filterEntries.get")
+ .withFeatures(COLLECTION_FEATURES_ORDER)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ Multimap<String, Integer> multimap = HashMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.keySet();
+ }
+ })
+ .named("HashMultimap.keySet")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = LinkedHashMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.keySet();
+ }
+ })
+ .named("LinkedHashMultimap.keySet")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSortedSetGenerator() {
+ @Override protected SortedSet<String> create(String[] elements) {
+ TreeMultimap<String, Integer> multimap =
+ TreeMultimap.create(Ordering.natural().nullsFirst(),
+ Ordering.natural().nullsLast());
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.keySet();
+ }
+ })
+ .named("TreeMultimap.keySet")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = ArrayListMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.keySet();
+ }
+ })
+ .named("ArrayListMultimap.keySet")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = LinkedListMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.keySet();
+ }
+ })
+ .named("LinkedListMultimap.keySet")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ ImmutableListMultimap.Builder<String, Integer> builder
+ = ImmutableListMultimap.builder();
+ for (String element : elements) {
+ builder.put(element, 2);
+ builder.put(element, 3);
+ }
+ Multimap<String, Integer> multimap = builder.build();
+ return multimap.keySet();
+ }
+ })
+ .named("ImmutableListMultimap.keySet")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ PopulatableMapAsMultimap<String, Integer> multimap
+ = PopulatableMapAsMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.build().keySet();
+ }
+ })
+ .named("Multimaps.forMap.keySet")
+ .withFeatures(FOR_MAP_FEATURES_ANY)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SetMultimap<String, Integer> multimap = LinkedHashMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ multimap.put("badkey", 3);
+ multimap.put("a", 55556);
+ return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keySet();
+ }
+ })
+ .named("Multimaps.filterEntries.keySet")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap = HashMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ return multimap.values();
+ }
+ })
+ .named("HashMultimap.values")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap
+ = LinkedHashMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ return multimap.values();
+ }
+ })
+ .named("LinkedHashMultimap.values")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap
+ = TreeMultimap.create(Ordering.natural().nullsFirst(),
+ Ordering.natural().nullsLast());
+ populateMultimapForValues(multimap, elements);
+ return multimap.values();
+ }
+ })
+ .named("TreeMultimap.values")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap
+ = ArrayListMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ return multimap.values();
+ }
+ })
+ .named("ArrayListMultimap.values")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new TestStringListGenerator() {
+ @Override public List<String> create(String[] elements) {
+ LinkedListMultimap<Integer, String> multimap
+ = LinkedListMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ return multimap.values();
+ }
+ })
+ .named("LinkedListMultimap.values")
+ .withFeatures(LIST_FEATURES_REMOVE_SET)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ ImmutableListMultimap.Builder<Integer, String> builder
+ = ImmutableListMultimap.builder();
+ for (int i = 0; i < elements.length; i++) {
+ builder.put(i % 2, elements[i]);
+ }
+ return builder.build().values();
+ }
+ })
+ .named("ImmutableListMultimap.values")
+ .withFeatures(CollectionSize.ANY)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap
+ = LinkedHashMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ multimap.put(3, "badvalue");
+ multimap.put(55556, "foo");
+ return Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).values();
+ }
+ })
+ .named("Multimaps.filterEntries.values")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ // TODO: use collection testers on Multimaps.forMap.values
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap = HashMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return multimap.keys();
+ }
+ })
+ .named("HashMultimap.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = LinkedHashMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return multimap.keys();
+ }
+ })
+ .named("LinkedHashMultimap.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = TreeMultimap.create(Ordering.natural().nullsFirst(),
+ Ordering.natural().nullsLast());
+ populateMultimapForKeys(multimap, elements);
+ return multimap.keys();
+ }
+
+ @Override public List<String> order(List<String> insertionOrder) {
+ Collections.sort(insertionOrder, Ordering.natural().nullsFirst());
+ return insertionOrder;
+ }
+ })
+ .named("TreeMultimap.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = ArrayListMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return multimap.keys();
+ }
+ })
+ .named("ArrayListMultimap.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = Multimaps.synchronizedListMultimap(
+ ArrayListMultimap.<String, Integer>create());
+ populateMultimapForKeys(multimap, elements);
+ return multimap.keys();
+ }
+ })
+ .named("synchronized ArrayListMultimap.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = LinkedListMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return multimap.keys();
+ }
+ })
+ .named("LinkedListMultimap.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ ImmutableListMultimap.Builder<String, Integer> builder
+ = ImmutableListMultimap.builder();
+ for (int i = 0; i < elements.length; i++) {
+ builder.put(elements[i], i);
+ }
+ Multimap<String, Integer> multimap = builder.build();
+ return multimap.keys();
+ }
+ })
+ .named("ImmutableListMultimap.keys")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ PopulatableMapAsMultimap<String, Integer> multimap
+ = PopulatableMapAsMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return multimap.build().keys();
+ }
+ })
+ .named("Multimaps.forMap.keys")
+ .withFeatures(FOR_MAP_FEATURES_ANY)
+ .suppressing(getReadsDuplicateInitializingMethods())
+ .suppressing(getSetCountDuplicateInitializingMethods())
+ .suppressing(getIteratorDuplicateInitializingMethods())
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ SetMultimap<String, Integer> multimap = LinkedHashMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ multimap.put("badkey", 3);
+ multimap.put("a", 55556);
+ return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keys();
+ }
+ })
+ .named("Multimaps.filterEntries.keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .suppressing(MultisetWritesTester.getEntrySetIteratorMethod())
+ .suppressing(getIteratorDuplicateInitializingMethods())
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntrySetGenerator() {
+ @Override SetMultimap<String, Integer> createMultimap() {
+ return HashMultimap.create();
+ }
+ })
+ .named("HashMultimap.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntrySetGenerator() {
+ @Override SetMultimap<String, Integer> createMultimap() {
+ return LinkedHashMultimap.create();
+ }
+ })
+ .named("LinkedHashMultimap.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntrySetGenerator() {
+ @Override SetMultimap<String, Integer> createMultimap() {
+ return TreeMultimap.create(Ordering.natural().nullsFirst(),
+ Ordering.natural().nullsLast());
+ }
+ })
+ .named("TreeMultimap.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntriesGenerator() {
+ @Override Multimap<String, Integer> createMultimap() {
+ return ArrayListMultimap.create();
+ }
+ })
+ .named("ArrayListMultimap.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntriesGenerator() {
+ @Override Multimap<String, Integer> createMultimap() {
+ return Multimaps.synchronizedListMultimap(
+ ArrayListMultimap.<String, Integer>create());
+ }
+ })
+ .named("synchronized ArrayListMultimap.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new TestEntriesListGenerator() {
+ @Override Multimap<String, Integer> createMultimap() {
+ return LinkedListMultimap.create();
+ }
+ })
+ .named("LinkedListMultimap.entries")
+ .withFeatures(CollectionSize.ANY, ListFeature.REMOVE_OPERATIONS,
+ CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntriesGenerator() {
+ @Override Multimap<String, Integer> createMultimap() {
+ return ImmutableListMultimap.of();
+ }
+
+ @Override public Collection<Entry<String, Integer>> create(
+ Object... elements) {
+ ImmutableListMultimap.Builder<String, Integer> builder
+ = ImmutableListMultimap.builder();
+ for (Object element : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Integer> entry = (Entry<String, Integer>) element;
+ builder.put(entry.getKey(), entry.getValue());
+ }
+ return builder.build().entries();
+ }
+ })
+ .named("ImmutableListMultimap.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(
+ new TestEntriesGenerator() {
+ @Override Multimap<String, Integer> createMultimap() {
+ Multimap<String, Integer> multimap = LinkedHashMultimap.create();
+ multimap.put("badkey", 3);
+ multimap.put("a", 55556);
+ return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE);
+ }
+ })
+ .named("Multimap.filterEntries.entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.KNOWN_ORDER)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ ListMultimap<Integer, String> multimap = ArrayListMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<String> identity()).get(3);
+ }
+ }).named("Multimaps.transformValues[ListMultimap].get").withFeatures(
+ CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS,
+ ListFeature.SUPPORTS_REMOVE_WITH_INDEX).createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ ListMultimap<String, Integer> multimap = ArrayListMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<Integer> identity()).keySet();
+ }
+ }).named("Multimaps.transformValues[ListMultimap].keySet").withFeatures(
+ CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS).createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ ListMultimap<String, Integer> multimap
+ = ArrayListMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<Integer> identity()).keys();
+ }
+ })
+ .named("Multimaps.transform[ListMultimap].keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(
+ CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ ListMultimap<Integer, String> multimap = ArrayListMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<String> identity()).values();
+ }
+ }).named("Multimaps.transformValues[ListMultimap].values").withFeatures(
+ COLLECTION_FEATURES_REMOVE).createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() {
+ @Override public Collection<Entry<String, Integer>> create(
+ Object... elements) {
+ ListMultimap<String, Integer> multimap = ArrayListMultimap.create();
+ for (Object element : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Integer> entry = (Entry<String, Integer>) element;
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return Multimaps.transformValues(
+ multimap, Functions.<Integer> identity()).entries();
+ }
+
+ @Override Multimap<String, Integer> createMultimap() {
+ return Multimaps.transformValues(
+ ArrayListMultimap.<String, Integer> create(),
+ Functions.<Integer> identity());
+ }
+ }).named("Multimaps.transformValues[ListMultimap].entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
+ .createTestSuite());
+
+ suite.addTest(
+ CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() {
+ @Override protected Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap = ArrayListMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<String> identity()).get(3);
+ }
+ }).named("Multimaps.transformValues[Multimap].get").withFeatures(
+ CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS).createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ Multimap<String, Integer> multimap = ArrayListMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<Integer> identity()).keySet();
+ }
+ }).named("Multimaps.transformValues[Multimap].keySet").withFeatures(
+ COLLECTION_FEATURES_REMOVE).createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multimap<String, Integer> multimap
+ = ArrayListMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<Integer> identity()).keys();
+ }
+ })
+ .named("Multimaps.transformValues[Multimap].keys")
+ .withFeatures(COLLECTION_FEATURES_REMOVE)
+ .createTestSuite());
+
+ suite.addTest(
+ CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() {
+ @Override public Collection<String> create(String[] elements) {
+ Multimap<Integer, String> multimap = ArrayListMultimap.create();
+ populateMultimapForValues(multimap, elements);
+ return Multimaps.transformValues(
+ multimap, Functions.<String> identity()).values();
+ }
+ }).named("Multimaps.transformValues[Multimap].values").withFeatures(
+ COLLECTION_FEATURES_REMOVE).createTestSuite());
+
+ suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() {
+ @Override public Collection<Entry<String, Integer>> create(
+ Object... elements) {
+ Multimap<String, Integer> multimap = ArrayListMultimap.create();
+ for (Object element : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Integer> entry = (Entry<String, Integer>) element;
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return Multimaps.transformValues(
+ multimap, Functions.<Integer> identity()).entries();
+ }
+ @Override Multimap<String, Integer> createMultimap() {
+ return Multimaps.transformValues(
+ (Multimap<String, Integer>)
+ ArrayListMultimap.<String, Integer> create(),
+ Functions.<Integer> identity());
+ }
+ }).named("Multimaps.transformValues[Multimap].entries")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
+ .createTestSuite());
+
+ // TODO: use collection testers on Multimaps.forMap.entries
+
+ return suite;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java b/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java
deleted file mode 100644
index 48be857..0000000
--- a/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.Maps.newHashMap;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
-import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
-import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
-import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
-import static java.lang.reflect.Proxy.newProxyInstance;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Ascii;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Maps.EntryTransformer;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestCollectionGenerator;
-import com.google.common.collect.testing.TestListGenerator;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.MultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.MultisetIteratorTester;
-import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.MultisetWritesTester;
-import com.google.common.collect.testing.google.TestListMultimapGenerator;
-import com.google.common.collect.testing.google.TestMultimapGenerator;
-import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
-import com.google.common.collect.testing.google.TestStringMultisetGenerator;
-import com.google.common.collect.testing.testers.CollectionIteratorTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * Run collection tests on wrappers from {@link Multimaps}.
- *
- * @author Jared Levy
- */
-@GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
-public class MultimapsCollectionTest extends TestCase {
-
- static final Feature<?>[] COLLECTION_FEATURES_ORDER = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE
- };
- static final Feature<?>[] COLLECTION_FEATURES_REMOVE = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.SUPPORTS_REMOVE
- };
-
- static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SUPPORTS_REMOVE
- };
-
- private static final Feature<?>[] FOR_MAP_FEATURES_ONE = {
- CollectionSize.ONE,
- ALLOWS_NULL_VALUES,
- SUPPORTS_REMOVE,
- };
-
- private static final Feature<?>[] FOR_MAP_FEATURES_ANY = {
- CollectionSize.ANY,
- ALLOWS_NULL_VALUES,
- SUPPORTS_REMOVE,
- MultisetTestSuiteBuilder.NoRecurse.NO_ENTRY_SET, // Cannot create entries with count > 1
- };
-
- static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY = new Supplier<TreeSet<String>>() {
- @Override
- public TreeSet<String> get() {
- return new TreeSet<String>(Ordering.natural().nullsLast());
- }
- };
-
- static void populateMultimapForGet(
- Multimap<Integer, String> multimap, String[] elements) {
- multimap.put(2, "foo");
- for (String element : elements) {
- multimap.put(3, element);
- }
- }
-
- static void populateMultimapForKeySet(
- Multimap<String, Integer> multimap, String[] elements) {
- for (String element : elements) {
- multimap.put(element, 2);
- multimap.put(element, 3);
- }
- }
-
- static void populateMultimapForValues(
- Multimap<Integer, String> multimap, String[] elements) {
- for (int i = 0; i < elements.length; i++) {
- multimap.put(i % 2, elements[i]);
- }
- }
-
- static void populateMultimapForKeys(
- Multimap<String, Integer> multimap, String[] elements) {
- for (int i = 0; i < elements.length; i++) {
- multimap.put(elements[i], i);
- }
- }
-
- /**
- * Implements {@code Multimap.put()} -- and no other methods -- for a {@code
- * Map} by ignoring all but the latest value for each key. This class exists
- * only so that we can use
- * {@link MultimapsCollectionTest#populateMultimapForGet(Multimap, String[])}
- * and similar methods to populate a map to be passed to
- * {@link Multimaps#forMap(Map)}. All tests should run against the result of
- * {@link #build()}.
- */
- private static final class PopulatableMapAsMultimap<K, V>
- extends ForwardingMultimap<K, V> {
- final Map<K, V> map;
- final SetMultimap<K, V> unusableDelegate;
-
- static <K, V> PopulatableMapAsMultimap<K, V> create() {
- return new PopulatableMapAsMultimap<K, V>();
- }
-
- @SuppressWarnings("unchecked") // all methods throw immediately
- PopulatableMapAsMultimap() {
- this.map = newHashMap();
- this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance(
- SetMultimap.class.getClassLoader(),
- new Class<?>[] {SetMultimap.class},
- new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- throw new UnsupportedOperationException();
- }
- });
- }
-
- @Override protected Multimap<K, V> delegate() {
- return unusableDelegate;
- }
-
- @Override public boolean put(K key, V value) {
- map.put(key, value);
- return true;
- }
-
- SetMultimap<K, V> build() {
- return Multimaps.forMap(map);
- }
- }
-
- abstract static class TestEntriesGenerator
- implements TestCollectionGenerator<Entry<String, Integer>> {
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- Maps.immutableEntry("bar", 1),
- Maps.immutableEntry("bar", 2),
- Maps.immutableEntry("foo", 3),
- Maps.immutableEntry("bar", 3),
- Maps.immutableEntry("cat", 2));
- }
-
- @Override
- public Collection<Entry<String, Integer>> create(Object... elements) {
- Multimap<String, Integer> multimap = createMultimap();
- for (Object element : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) element;
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap.entries();
- }
-
- abstract Multimap<String, Integer> createMultimap();
-
- @Override
- @SuppressWarnings("unchecked")
- public Entry<String, Integer>[] createArray(int length) {
- return (Entry<String, Integer>[]) new Entry<?, ?>[length];
- }
-
- @Override
- public List<Entry<String, Integer>> order(
- List<Entry<String, Integer>> insertionOrder) {
- return insertionOrder;
- }
- }
-
- public abstract static class TestEntriesListGenerator
- extends TestEntriesGenerator
- implements TestListGenerator<Entry<String, Integer>> {
- @Override public List<Entry<String, Integer>> create(Object... elements) {
- return (List<Entry<String, Integer>>) super.create(elements);
- }
- }
-
- private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE
- = new Predicate<Map.Entry<Integer, String>>() {
- @Override public boolean apply(Entry<Integer, String> entry) {
- return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey();
- }
- };
-
- private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE
- = new Predicate<Map.Entry<String, Integer>>() {
- @Override public boolean apply(Entry<String, Integer> entry) {
- return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue();
- }
- };
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() {
- @Override
- protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
- ListMultimap<String, String> multimap = Multimaps.synchronizedListMultimap(
- ArrayListMultimap.<String, String> create());
- for (Entry<String, String> entry : entries) {
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap;
- }
- })
- .named("synchronized ArrayListMultimap")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTest(transformSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- PopulatableMapAsMultimap<Integer, String> multimap
- = PopulatableMapAsMultimap.create();
- populateMultimapForGet(multimap, elements);
- return multimap.build().get(3);
- }
- })
- .named("Multimaps.forMap.get")
- .withFeatures(FOR_MAP_FEATURES_ONE)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- PopulatableMapAsMultimap<String, Integer> multimap
- = PopulatableMapAsMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return multimap.build().keySet();
- }
- })
- .named("Multimaps.forMap.keySet")
- .withFeatures(FOR_MAP_FEATURES_ANY)
- .createTestSuite());
-
- // TODO: use collection testers on Multimaps.forMap.values
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- PopulatableMapAsMultimap<String, Integer> multimap
- = PopulatableMapAsMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return multimap.build().keys();
- }
- })
- .named("Multimaps.forMap.keys")
- .withFeatures(FOR_MAP_FEATURES_ANY)
- .suppressing(getReadsDuplicateInitializingMethods())
- .suppressing(getSetCountDuplicateInitializingMethods())
- .suppressing(getIteratorDuplicateInitializingMethods())
- .createTestSuite());
-
- // TODO: use collection testers on Multimaps.forMap.entries
-
- return suite;
- }
-
- static abstract class TransformedMultimapGenerator<M extends Multimap<String, String>>
- implements TestMultimapGenerator<String, String, M> {
-
- @Override
- public String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public String[] createValueArray(int length) {
- return new String[length];
- }
-
- @Override
- public SampleElements<String> sampleKeys() {
- return new SampleElements<String>("one", "two", "three", "four", "five");
- }
-
- @Override
- public SampleElements<String> sampleValues() {
- return new SampleElements<String>("january", "february", "march", "april", "may");
- }
-
- @Override
- public Collection<String> createCollection(Iterable<? extends String> values) {
- return Lists.newArrayList(values);
- }
-
- @Override
- public SampleElements<Entry<String, String>> samples() {
- return new SampleElements<Entry<String, String>>(
- mapEntry("one", "january"),
- mapEntry("two", "february"),
- mapEntry("three", "march"),
- mapEntry("four", "april"),
- mapEntry("five", "may"));
- }
-
- @Override
- public M create(Object... elements) {
- Multimap<String, String> multimap = ArrayListMultimap.create();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, String> entry = (Entry<String, String>) o;
- multimap.put(entry.getKey(), Ascii.toUpperCase(entry.getValue()));
- }
- return transform(multimap);
- }
-
- abstract M transform(Multimap<String, String> multimap);
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) {
- return insertionOrder;
- }
-
- static final Function<String, String> FUNCTION = new Function<String, String>() {
- @Override
- public String apply(String value) {
- return Ascii.toLowerCase(value);
- }
- };
-
- static final EntryTransformer<String, String, String> ENTRY_TRANSFORMER =
- new EntryTransformer<String, String, String>() {
- @Override
- public String transformEntry(String key, String value) {
- return Ascii.toLowerCase(value);
- }
- };
- }
-
- static abstract class TransformedListMultimapGenerator
- extends TransformedMultimapGenerator<ListMultimap<String, String>>
- implements TestListMultimapGenerator<String, String> {
- }
-
- private static Test transformSuite() {
- TestSuite suite = new TestSuite("Multimaps.transform*");
- suite.addTest(MultimapTestSuiteBuilder.using(
- new TransformedMultimapGenerator<Multimap<String,String>>() {
- @Override
- Multimap<String, String> transform(Multimap<String, String> multimap) {
- return Multimaps.transformValues(multimap, FUNCTION);
- }
- })
- .named("Multimaps.transformValues[Multimap]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.ALLOWS_NULL_KEYS)
- .createTestSuite());
- suite.addTest(MultimapTestSuiteBuilder.using(
- new TransformedMultimapGenerator<Multimap<String,String>>() {
- @Override
- Multimap<String, String> transform(Multimap<String, String> multimap) {
- return Multimaps.transformEntries(multimap, ENTRY_TRANSFORMER);
- }
- })
- .named("Multimaps.transformEntries[Multimap]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.ALLOWS_NULL_KEYS)
- .createTestSuite());
- suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() {
- @Override
- ListMultimap<String, String> transform(Multimap<String, String> multimap) {
- return Multimaps.transformValues((ListMultimap<String, String>) multimap, FUNCTION);
- }
- })
- .named("Multimaps.transformValues[ListMultimap]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.ALLOWS_NULL_KEYS)
- .createTestSuite());
- suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() {
- @Override
- ListMultimap<String, String> transform(Multimap<String, String> multimap) {
- return Multimaps.transformEntries(
- (ListMultimap<String, String>) multimap, ENTRY_TRANSFORMER);
- }
- })
- .named("Multimaps.transformEntries[ListMultimap]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.ALLOWS_NULL_KEYS)
- .createTestSuite());
-
- // TODO: use collection testers on Multimaps.forMap.entries
-
- suite.addTest(filterSuite());
-
- return suite;
- }
-
- static abstract class TestFilteredMultimapGenerator
- implements TestMultimapGenerator<String, Integer, Multimap<String, Integer>> {
-
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- mapEntry("one", 114),
- mapEntry("two", 37),
- mapEntry("three", 42),
- mapEntry("four", 19),
- mapEntry("five", 82));
- }
-
- abstract Multimap<String, Integer> filter(Multimap<String, Integer> multimap);
-
- @Override
- public Multimap<String, Integer> create(Object... elements) {
- Multimap<String, Integer> multimap = LinkedHashMultimap.create();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) o;
- multimap.put(entry.getKey(), entry.getValue());
- }
- return filter(multimap);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, Integer>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) {
- return insertionOrder;
- }
-
- @Override
- public String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @Override
- public Integer[] createValueArray(int length) {
- return new Integer[length];
- }
-
- @Override
- public SampleElements<String> sampleKeys() {
- return new SampleElements<String>("one", "two", "three", "four", "five");
- }
-
- @Override
- public SampleElements<Integer> sampleValues() {
- return new SampleElements<Integer>(114, 37, 42, 19, 82);
- }
-
- @Override
- public Collection<Integer> createCollection(Iterable<? extends Integer> values) {
- return Sets.newLinkedHashSet(values);
- }
- }
-
- private static Test filterSuite() {
- TestSuite suite = new TestSuite("Multimaps.filter*");
- suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
- @Override
- Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
- multimap.put("foo", 17);
- multimap.put("bar", 32);
- multimap.put("foo", 16);
- return Multimaps.filterKeys(multimap,
- Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar"))));
- }
- })
- .named("Multimaps.filterKeys[Multimap, Predicate]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
- .createTestSuite());
- suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
- @Override
- Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
- multimap.put("one", 314);
- multimap.put("two", 159);
- multimap.put("one", 265);
- return Multimaps.filterValues(multimap,
- Predicates.not(Predicates.in(ImmutableSet.of(314, 159, 265))));
- }
- })
- .named("Multimaps.filterValues[Multimap, Predicate]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
- .createTestSuite());
- suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
- @Override
- Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
- ImmutableSetMultimap<String, Integer> badEntries =
- ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358);
- multimap.putAll(badEntries);
- return Multimaps.filterEntries(multimap,
- Predicates.not(Predicates.in(badEntries.entries())));
- }
- })
- .named("Multimaps.filterEntries[Multimap, Predicate]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
- .createTestSuite());
- suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
- @Override
- Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
- ImmutableSetMultimap<String, Integer> badEntries =
- ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358);
- multimap.putAll(badEntries);
- multimap = Multimaps.filterKeys(multimap,
- Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar"))));
- return Multimaps.filterEntries(multimap,
- Predicates.not(Predicates.in(badEntries.entries())));
- }
- })
- .named("Multimaps.filterEntries[Maps.filterKeys[Multimap]]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
- .createTestSuite());
- suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
- @Override
- Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
- ImmutableSetMultimap<String, Integer> badEntries =
- ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358);
- multimap.putAll(badEntries);
- multimap = Multimaps.filterEntries(multimap,
- Predicates.not(Predicates.in(ImmutableMap.of("one", 159, "two", 265).entrySet())));
- return Multimaps.filterKeys(multimap,
- Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar"))));
- }
- })
- .named("Multimaps.filterKeys[Maps.filterEntries[Multimap]]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
- .createTestSuite());
- suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
- @Override
- Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
- ImmutableSetMultimap<String, Integer> badEntries =
- ImmutableSetMultimap.of("foo", 314, "bar", 358);
- multimap.putAll(badEntries);
- multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("foo")));
- multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("bar")));
- return multimap;
- }
- })
- .named("Multimaps.filterKeys[Maps.filterKeys[Multimap]]")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES)
- .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
- .createTestSuite());
- return suite;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/MultimapsTest.java b/guava-tests/test/com/google/common/collect/MultimapsTest.java
index 5047842..5ba5180 100644
--- a/guava-tests/test/com/google/common/collect/MultimapsTest.java
+++ b/guava-tests/test/com/google/common/collect/MultimapsTest.java
@@ -16,13 +16,12 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Maps.immutableEntry;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.testing.Helpers.nefariousMapEntry;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -62,7 +61,6 @@ import javax.annotation.Nullable;
*/
@GwtCompatible(emulated = true)
public class MultimapsTest extends AbstractMultimapTest {
-
private static final Comparator<Integer> INT_COMPARATOR =
Ordering.<Integer>natural().reverse().nullsFirst();
@@ -80,7 +78,7 @@ public class MultimapsTest extends AbstractMultimapTest {
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableListMultimapShortCircuit() {
+ public void testUnmodifiableListMultimapShortCircuit(){
ListMultimap<String, Integer> mod = ArrayListMultimap.create();
ListMultimap<String, Integer> unmod = Multimaps.unmodifiableListMultimap(mod);
assertNotSame(mod, unmod);
@@ -93,7 +91,7 @@ public class MultimapsTest extends AbstractMultimapTest {
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableSetMultimapShortCircuit() {
+ public void testUnmodifiableSetMultimapShortCircuit(){
SetMultimap<String, Integer> mod = HashMultimap.create();
SetMultimap<String, Integer> unmod = Multimaps.unmodifiableSetMultimap(mod);
assertNotSame(mod, unmod);
@@ -106,7 +104,7 @@ public class MultimapsTest extends AbstractMultimapTest {
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableMultimapShortCircuit() {
+ public void testUnmodifiableMultimapShortCircuit(){
Multimap<String, Integer> mod = HashMultimap.create();
Multimap<String, Integer> unmod = Multimaps.unmodifiableMultimap(mod);
assertNotSame(mod, unmod);
@@ -232,7 +230,7 @@ public class MultimapsTest extends AbstractMultimapTest {
assertTrue(unmod.containsEntry("foo", 1));
assertEquals(mod, unmod);
}
-
+
@SuppressWarnings("unchecked")
public void testUnmodifiableMultimapEntries() {
Multimap<String, Integer> mod = HashMultimap.create();
@@ -298,7 +296,7 @@ public class MultimapsTest extends AbstractMultimapTest {
assertEquals(multimap.hashCode(), unmodifiable.hashCode());
assertEquals(multimap, unmodifiable);
- ASSERT.that(unmodifiable.asMap().get("bar")).has().allOf(5, -1);
+ ASSERT.that(unmodifiable.asMap().get("bar")).hasContentsAnyOrder(5, -1);
assertNull(unmodifiable.asMap().get("missing"));
assertFalse(unmodifiable.entries() instanceof Serializable);
@@ -430,11 +428,11 @@ public class MultimapsTest extends AbstractMultimapTest {
assertFalse(map.containsKey("bar"));
assertEquals(map.keySet(), multimapView.keySet());
assertEquals(map.keySet(), multimapView.keys().elementSet());
- ASSERT.that(multimapView.keys()).has().item("foo");
- ASSERT.that(multimapView.values()).has().item(1);
- ASSERT.that(multimapView.entries()).has().item(
+ ASSERT.that(multimapView.keys()).hasContentsAnyOrder("foo");
+ ASSERT.that(multimapView.values()).hasContentsAnyOrder(1);
+ ASSERT.that(multimapView.entries()).hasContentsAnyOrder(
Maps.immutableEntry("foo", 1));
- ASSERT.that(multimapView.asMap().entrySet()).has().item(
+ ASSERT.that(multimapView.asMap().entrySet()).hasContentsAnyOrder(
Maps.immutableEntry(
"foo", (Collection<Integer>) Collections.singleton(1)));
multimapView.clear();
@@ -551,52 +549,6 @@ public class MultimapsTest extends AbstractMultimapTest {
private static final long serialVersionUID = 0;
}
- public void testNewMultimapWithCollectionRejectingNegativeElements() {
- CountingSupplier<Set<Integer>> factory = new SetSupplier() {
- @Override
- public Set<Integer> getImpl() {
- final Set<Integer> backing = super.getImpl();
- return new ForwardingSet<Integer>() {
- @Override
- protected Set<Integer> delegate() {
- return backing;
- }
-
- @Override
- public boolean add(Integer element) {
- checkArgument(element >= 0);
- return super.add(element);
- }
-
- @Override
- public boolean addAll(Collection<? extends Integer> collection) {
- return standardAddAll(collection);
- }
- };
- }
- };
-
- Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
- Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
- try {
- multimap.put(Color.BLUE, -1);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- multimap.put(Color.RED, 1);
- multimap.put(Color.BLUE, 2);
- try {
- multimap.put(Color.GREEN, -1);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // expected
- }
- ASSERT.that(multimap.entries()).has().allOf(
- Maps.immutableEntry(Color.RED, 1),
- Maps.immutableEntry(Color.BLUE, 2));
- }
-
public void testNewMultimap() {
// The ubiquitous EnumArrayBlockingQueueMultimap
CountingSupplier<Queue<Integer>> factory = new QueueSupplier();
@@ -666,15 +618,15 @@ public class MultimapsTest extends AbstractMultimapTest {
SerializableTester.reserializeAndAssert(multimap);
}
- private static class SetSupplier extends CountingSupplier<Set<Integer>> {
- @Override public Set<Integer> getImpl() {
+ private static class SetSupplier extends CountingSupplier<HashSet<Integer>> {
+ @Override public HashSet<Integer> getImpl() {
return new HashSet<Integer>(4);
}
private static final long serialVersionUID = 0;
}
public void testNewSetMultimap() {
- CountingSupplier<Set<Integer>> factory = new SetSupplier();
+ CountingSupplier<HashSet<Integer>> factory = new SetSupplier();
Map<Color, Collection<Integer>> map = Maps.newHashMap();
SetMultimap<Color, Integer> multimap =
Multimaps.newSetMultimap(map, factory);
@@ -688,7 +640,7 @@ public class MultimapsTest extends AbstractMultimapTest {
@GwtIncompatible("SerializableTester")
public void testNewSetMultimapSerialization() {
- CountingSupplier<Set<Integer>> factory = new SetSupplier();
+ CountingSupplier<HashSet<Integer>> factory = new SetSupplier();
Map<Color, Collection<Integer>> map = Maps.newHashMap();
SetMultimap<Color, Integer> multimap = Multimaps.newSetMultimap(map, factory);
multimap.putAll(Color.BLUE, asList(3, 1, 4));
@@ -762,6 +714,39 @@ public class MultimapsTest extends AbstractMultimapTest {
assertEquals(stringToObject, outputMap);
}
+ // NOTE: evil, never do this
+ private abstract static class IterableIterator<T>
+ extends ForwardingIterator<T> implements Iterable<T> {
+ @Override
+ public Iterator<T> iterator() {
+ return this;
+ }
+ }
+
+ @SuppressWarnings("deprecation") // that is the purpose of this test
+ public void testIndexIterableIterator() {
+ final Multimap<String, Object> stringToObject =
+ new ImmutableMultimap.Builder<String, Object>()
+ .put("1", 1)
+ .put("1", 1L)
+ .put("1", "1")
+ .put("2", 2)
+ .put("2", 2L)
+ .build();
+
+ IterableIterator<Object> iterIter = new IterableIterator<Object>() {
+ private final Iterator<Object> iterator = stringToObject.values().iterator();
+
+ public Iterator<Object> delegate() {
+ return iterator;
+ }
+ };
+
+ ImmutableMultimap<String, Object> outputMap =
+ Multimaps.index(iterIter, Functions.toStringFunction());
+ assertEquals(stringToObject, outputMap);
+ }
+
public void testIndex_ordering() {
final Multimap<Integer, String> expectedIndex =
new ImmutableListMultimap.Builder<Integer, String>()
@@ -814,10 +799,11 @@ public class MultimapsTest extends AbstractMultimapTest {
return in * in;
}
};
- Multimap<String, Integer> transformed = Multimaps.transformValues(multimap, square);
- ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", 4),
+ Multimap<String, Integer> transformed =
+ Multimaps.transformValues(multimap, square);
+ ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", 4),
immutableEntry("a", 16), immutableEntry("b", 9), immutableEntry("b", 9),
- immutableEntry("c", 36)).inOrder();
+ immutableEntry("c", 36));
}
@GwtIncompatible(value = "untested")
@@ -833,7 +819,7 @@ public class MultimapsTest extends AbstractMultimapTest {
});
Entry<String, String> entry = multimap.entries().iterator().next();
entry.setValue("bbb");
- ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", 3)).inOrder();
+ ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", 3));
}
@GwtIncompatible(value = "untested")
@@ -848,9 +834,9 @@ public class MultimapsTest extends AbstractMultimapTest {
};
ListMultimap<String, Integer> transformed =
Multimaps.transformValues(multimap, square);
- ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", 4),
+ ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", 4),
immutableEntry("a", 16), immutableEntry("b", 9), immutableEntry("b", 9),
- immutableEntry("c", 36)).inOrder();
+ immutableEntry("c", 36));
}
@GwtIncompatible(value = "untested")
@@ -866,8 +852,8 @@ public class MultimapsTest extends AbstractMultimapTest {
};
Multimap<String, String> transformed =
Multimaps.transformEntries(multimap, transformer);
- ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", "a"),
- immutableEntry("a", "a"), immutableEntry("b", "nob")).inOrder();
+ ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", "a"),
+ immutableEntry("a", "a"), immutableEntry("b", "nob"));
}
@GwtIncompatible(value = "untested")
@@ -889,24 +875,13 @@ public class MultimapsTest extends AbstractMultimapTest {
assertEquals("{a=[a1, a4, a4], b=[b6]}", transformed.toString());
}
- public <K, V> void testSynchronizedMultimapSampleCodeCompilation() {
- K key = null;
-
- Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
- HashMultimap.<K, V>create());
- Collection<V> values = multimap.get(key); // Needn't be in synchronized block
- synchronized (multimap) { // Synchronizing on multimap, not values!
- Iterator<V> i = values.iterator(); // Must be in synchronized block
- while (i.hasNext()) {
- foo(i.next());
- }
- }
- }
-
- private static void foo(Object o) {}
-
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(Multimaps.class);
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Multimap.class, ImmutableMultimap.of());
+ tester.setDefault(ListMultimap.class, ImmutableListMultimap.of());
+ tester.setDefault(EntryTransformer.class, ALWAYS_NULL);
+ tester.ignore(Multimaps.class.getDeclaredMethod("index", Object.class, Function.class));
+ tester.testAllPublicStaticMethods(Multimaps.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java b/guava-tests/test/com/google/common/collect/MultisetCollectionTest.java
index a32fdc8..47a94d3 100644
--- a/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/MultisetCollectionTest.java
@@ -16,111 +16,150 @@
package com.google.common.collect;
+import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
+import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
+import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
import static java.util.Arrays.asList;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
+import com.google.common.collect.testing.AnEnum;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.MultisetIteratorTester;
import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.MultisetWritesTester;
import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestEnumMultisetGenerator;
import com.google.common.collect.testing.google.TestStringMultisetGenerator;
-import com.google.common.collect.testing.testers.CollectionIteratorTester;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
- * Collection tests on wrappers from {@link Multisets}.
+ * Collection tests for {@link Multiset} implementations.
*
* @author Jared Levy
*/
@GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
-public class MultisetsCollectionTest extends TestCase {
+public class MultisetCollectionTest extends TestCase {
+
public static Test suite() {
TestSuite suite = new TestSuite();
+ suite.addTest(MultisetTestSuiteBuilder.using(hashMultisetGenerator())
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.GENERAL_PURPOSE)
+ .named("HashMultiset")
+ .createTestSuite());
+
suite.addTest(MultisetTestSuiteBuilder.using(
unmodifiableMultisetGenerator())
.withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("Multisets.unmodifiableMultiset[LinkedHashMultiset]")
+ .named("UnmodifiableTreeMultiset")
.createTestSuite());
- suite.addTest(SortedMultisetTestSuiteBuilder.using(unmodifiableSortedMultisetGenerator())
+ suite.addTest(SortedMultisetTestSuiteBuilder
+ .using(new TestStringMultisetGenerator() {
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ return TreeMultiset.create(Arrays.asList(elements));
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
.withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("Multisets.unmodifiableMultiset[TreeMultiset]")
+ .named("TreeMultiset, Ordering.natural")
.createTestSuite());
+
- suite.addTest(MultisetTestSuiteBuilder.using(unionGenerator())
- .withFeatures(CollectionSize.ANY,
+ suite.addTest(SortedMultisetTestSuiteBuilder
+ .using(new TestStringMultisetGenerator() {
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ Multiset<String> result = TreeMultiset.create(Ordering.natural().nullsFirst());
+ result.addAll(Arrays.asList(elements));
+ return result;
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
+ }
+ })
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE,
CollectionFeature.ALLOWS_NULL_VALUES)
- .named("Multisets.union")
+ .named("TreeMultiset, Ordering.natural.nullsFirst")
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(intersectionGenerator())
+ suite.addTest(MultisetTestSuiteBuilder.using(forSetGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.REMOVE_OPERATIONS)
+ .suppressing(getReadsDuplicateInitializingMethods())
+ .suppressing(getSetCountDuplicateInitializingMethods())
+ .suppressing(getIteratorDuplicateInitializingMethods())
+ .named("ForSetMultiset")
+ .createTestSuite());
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ concurrentMultisetGenerator())
.withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER)
- .named("Multisets.intersection")
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ConcurrentHashMultiset")
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(sumGenerator())
+ suite.addTest(MultisetTestSuiteBuilder.using(enumMultisetGenerator())
.withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES)
- .named("Multisets.sum")
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("EnumMultiset")
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(differenceGenerator())
+ suite.addTest(MultisetTestSuiteBuilder.using(intersectionGenerator())
.withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER)
- .named("Multisets.difference")
+ .named("IntersectionMultiset")
.createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(filteredGenerator())
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE)
- .named("Multiset.filter[Multiset, Predicate]")
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod(),
- MultisetIteratorTester.getIteratorKnownOrderRemoveSupportedMethod(),
- MultisetWritesTester.getEntrySetIteratorMethod())
+
+ suite.addTest(SortedMultisetTestSuiteBuilder.using(unmodifiableSortedMultisetGenerator())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("UnmodifiableSortedTreeMultiset")
.createTestSuite());
return suite;
}
+ private static TestStringMultisetGenerator hashMultisetGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ return HashMultiset.create(asList(elements));
+ }
+ };
+ }
+
private static TestStringMultisetGenerator unmodifiableMultisetGenerator() {
return new TestStringMultisetGenerator() {
@Override protected Multiset<String> create(String[] elements) {
return Multisets.unmodifiableMultiset(
- LinkedHashMultiset.create(asList(elements)));
+ TreeMultiset.create(asList(elements)));
}
@Override public List<String> order(List<String> insertionOrder) {
- List<String> order = new ArrayList<String>();
- for (String s : insertionOrder) {
- int index = order.indexOf(s);
- if (index == -1) {
- order.add(s);
- } else {
- order.add(index, s);
- }
- }
- return order;
+ Collections.sort(insertionOrder);
+ return insertionOrder;
}
};
}
@@ -138,26 +177,28 @@ public class MultisetsCollectionTest extends TestCase {
};
}
- private static TestStringMultisetGenerator unionGenerator() {
+ private static TestStringMultisetGenerator forSetGenerator() {
return new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- Multiset<String> multiset1 = LinkedHashMultiset.create();
- Multiset<String> multiset2 = LinkedHashMultiset.create();
- for (int i = 0; i < elements.length; i++) {
- String element = elements[i];
- if (multiset1.contains(element) ||
- multiset2.contains(element)) {
- // add to both; the one already containing it will have more
- multiset1.add(element);
- multiset2.add(element);
- } else if (i % 2 == 0) {
- multiset1.add(elements[i]);
- } else {
- multiset2.add(elements[i]);
- }
- }
- return Multisets.union(multiset1, multiset2);
+ @Override protected Multiset<String> create(String[] elements) {
+ return Multisets.forSet(Sets.newHashSet(elements));
+ }
+ };
+ }
+
+ private static TestStringMultisetGenerator concurrentMultisetGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ return ConcurrentHashMultiset.create(asList(elements));
+ }
+ };
+ }
+
+ private static TestEnumMultisetGenerator enumMultisetGenerator() {
+ return new TestEnumMultisetGenerator() {
+ @Override protected Multiset<AnEnum> create(AnEnum[] elements) {
+ return (elements.length == 0)
+ ? EnumMultiset.create(AnEnum.class)
+ : EnumMultiset.create(asList(elements));
}
};
}
@@ -182,7 +223,7 @@ public class MultisetsCollectionTest extends TestCase {
* "add an extra item 0 to A and an extra item 1 to B" really means
* "add an extra item 0 to A and B," which isn't what we want.
*/
- if (!Objects.equal(elements[0], elements[1])) {
+ if (!elements[0].equals(elements[1])) {
multiset2.add(elements[1], 2);
}
}
@@ -190,65 +231,4 @@ public class MultisetsCollectionTest extends TestCase {
}
};
}
-
- private static TestStringMultisetGenerator sumGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multiset<String> multiset1 = LinkedHashMultiset.create();
- Multiset<String> multiset2 = LinkedHashMultiset.create();
- for (int i = 0; i < elements.length; i++) {
- // add to either; sum should contain all
- if (i % 2 == 0) {
- multiset1.add(elements[i]);
- } else {
- multiset2.add(elements[i]);
- }
- }
- return Multisets.sum(multiset1, multiset2);
- }
- };
- }
-
- private static TestStringMultisetGenerator differenceGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multiset<String> multiset1 = LinkedHashMultiset.create();
- Multiset<String> multiset2 = LinkedHashMultiset.create();
- multiset1.add("equalIn1");
- multiset1.add("fewerIn1");
- multiset2.add("equalIn1");
- multiset2.add("fewerIn1", 3);
- multiset2.add("onlyIn2", 2);
- for (int i = 0; i < elements.length; i++) {
- // add 1 more copy of each element to multiset1 than multiset2
- multiset1.add(elements[i], i + 2);
- multiset2.add(elements[i], i + 1);
- }
- return Multisets.difference(multiset1, multiset2);
- }
- };
- }
-
- private static final Multiset<String> ELEMENTS_TO_FILTER_OUT = ImmutableMultiset.of(
- "foobar", "bazfoo", "foobar", "foobar");
-
- private static final Predicate<String> PREDICATE =
- Predicates.not(Predicates.in(ELEMENTS_TO_FILTER_OUT));
-
- private static TestStringMultisetGenerator filteredGenerator() {
- return new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- Multiset<String> multiset = LinkedHashMultiset.create();
- multiset.addAll(Arrays.asList(elements));
- multiset.addAll(ELEMENTS_TO_FILTER_OUT);
- return Multisets.filter(multiset, PREDICATE);
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Lists.newArrayList(LinkedHashMultiset.create(insertionOrder));
- }
- };
- }
}
diff --git a/guava-tests/test/com/google/common/collect/MultisetsTest.java b/guava-tests/test/com/google/common/collect/MultisetsTest.java
index 91b3c14..214d736 100644
--- a/guava-tests/test/com/google/common/collect/MultisetsTest.java
+++ b/guava-tests/test/com/google/common/collect/MultisetsTest.java
@@ -16,18 +16,21 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
+import static com.google.common.testing.SerializableTester.reserializeAndAssert;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.DerivedComparable;
import com.google.common.testing.NullPointerTester;
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.Collections;
-
/**
* Tests for {@link Multisets}.
*
@@ -40,14 +43,79 @@ public class MultisetsTest extends TestCase {
/* See MultisetsImmutableEntryTest for immutableEntry() tests. */
+ public void testForSet() {
+ Set<String> set = new HashSet<String>();
+ set.add("foo");
+ set.add("bar");
+ set.add(null);
+ Multiset<String> multiset = HashMultiset.create();
+ multiset.addAll(set);
+ Multiset<String> multisetView = Multisets.forSet(set);
+ assertTrue(multiset.equals(multisetView));
+ assertTrue(multisetView.equals(multiset));
+ assertEquals(multiset.toString(), multisetView.toString());
+ assertEquals(multiset.hashCode(), multisetView.hashCode());
+ assertEquals(multiset.size(), multisetView.size());
+ assertTrue(multisetView.contains("foo"));
+ assertEquals(set, multisetView.elementSet());
+ assertEquals(multisetView.elementSet(), set);
+ assertEquals(multiset.elementSet(), multisetView.elementSet());
+ assertEquals(multisetView.elementSet(), multiset.elementSet());
+ try {
+ multisetView.add("baz");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {}
+ try {
+ multisetView.addAll(Collections.singleton("baz"));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {}
+ try {
+ multisetView.elementSet().add("baz");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {}
+ try {
+ multisetView.elementSet().addAll(Collections.singleton("baz"));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {}
+ multisetView.remove("bar");
+ assertFalse(multisetView.contains("bar"));
+ assertFalse(set.contains("bar"));
+ assertEquals(set, multisetView.elementSet());
+ ASSERT.that(multisetView.elementSet()).hasContentsAnyOrder("foo", null);
+ ASSERT.that(multisetView.entrySet()).hasContentsAnyOrder(
+ Multisets.immutableEntry("foo", 1), Multisets.immutableEntry((String) null, 1));
+ multisetView.clear();
+ assertFalse(multisetView.contains("foo"));
+ assertFalse(set.contains("foo"));
+ assertTrue(set.isEmpty());
+ assertTrue(multisetView.isEmpty());
+ multiset.clear();
+ assertEquals(multiset.toString(), multisetView.toString());
+ assertEquals(multiset.hashCode(), multisetView.hashCode());
+ assertEquals(multiset.size(), multisetView.size());
+ }
+
+ @GwtIncompatible("SerializableTester")
+ public void testForSetSerialization() {
+ Set<String> set = new HashSet<String>();
+ set.add("foo");
+ set.add("bar");
+ set.add(null);
+ Multiset<String> multiset = HashMultiset.create();
+ multiset.addAll(set);
+ Multiset<String> multisetView = Multisets.forSet(set);
+ assertTrue(multiset.equals(multisetView));
+ reserializeAndAssert(multisetView);
+ }
+
public void testNewTreeMultisetDerived() {
TreeMultiset<DerivedComparable> set = TreeMultiset.create();
assertTrue(set.isEmpty());
set.add(new DerivedComparable("foo"), 2);
set.add(new DerivedComparable("bar"), 3);
- ASSERT.that(set).has().allOf(
+ ASSERT.that(set).hasContentsInOrder(
new DerivedComparable("bar"), new DerivedComparable("bar"), new DerivedComparable("bar"),
- new DerivedComparable("foo"), new DerivedComparable("foo")).inOrder();
+ new DerivedComparable("foo"), new DerivedComparable("foo"));
}
public void testNewTreeMultisetNonGeneric() {
@@ -55,9 +123,9 @@ public class MultisetsTest extends TestCase {
assertTrue(set.isEmpty());
set.add(new LegacyComparable("foo"), 2);
set.add(new LegacyComparable("bar"), 3);
- ASSERT.that(set).has().allOf(new LegacyComparable("bar"),
+ ASSERT.that(set).hasContentsInOrder(new LegacyComparable("bar"),
new LegacyComparable("bar"), new LegacyComparable("bar"),
- new LegacyComparable("foo"), new LegacyComparable("foo")).inOrder();
+ new LegacyComparable("foo"), new LegacyComparable("foo"));
}
public void testNewTreeMultisetComparator() {
@@ -65,7 +133,7 @@ public class MultisetsTest extends TestCase {
= TreeMultiset.create(Collections.reverseOrder());
multiset.add("bar", 3);
multiset.add("foo", 2);
- ASSERT.that(multiset).has().allOf("foo", "foo", "bar", "bar", "bar").inOrder();
+ ASSERT.that(multiset).hasContentsInOrder("foo", "foo", "bar", "bar", "bar");
}
public void testRetainOccurrencesEmpty() {
@@ -73,7 +141,7 @@ public class MultisetsTest extends TestCase {
Multiset<String> toRetain =
HashMultiset.create(Arrays.asList("a", "b", "a"));
assertFalse(Multisets.retainOccurrences(multiset, toRetain));
- ASSERT.that(multiset).isEmpty();
+ ASSERT.that(multiset).hasContentsInOrder();
}
public void testRemoveOccurrencesEmpty() {
@@ -84,96 +152,18 @@ public class MultisetsTest extends TestCase {
assertTrue(multiset.isEmpty());
}
- public void testUnion() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create(
- Arrays.asList("a", "b", "b", "c"));
- ASSERT.that(Multisets.union(ms1, ms2)).has().allOf("a", "a", "b", "b", "c");
- }
-
- public void testUnionEqualMultisets() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- assertEquals(ms1, Multisets.union(ms1, ms2));
- }
-
- public void testUnionEmptyNonempty() {
- Multiset<String> ms1 = HashMultiset.create();
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- assertEquals(ms2, Multisets.union(ms1, ms2));
- }
-
- public void testUnionNonemptyEmpty() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create();
- assertEquals(ms1, Multisets.union(ms1, ms2));
- }
-
public void testIntersectEmptyNonempty() {
Multiset<String> ms1 = HashMultiset.create();
Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty();
+ ASSERT.that(Multisets.intersection(ms1, ms2)).hasContentsInOrder();
}
public void testIntersectNonemptyEmpty() {
Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
Multiset<String> ms2 = HashMultiset.create();
- ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty();
- }
-
- public void testSum() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b", "c"));
- ASSERT.that(Multisets.sum(ms1, ms2)).has().allOf("a", "a", "b", "b", "c");
- }
-
- public void testSumEmptyNonempty() {
- Multiset<String> ms1 = HashMultiset.create();
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- ASSERT.that(Multisets.sum(ms1, ms2)).has().allOf("a", "b", "a");
- }
-
- public void testSumNonemptyEmpty() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create();
- ASSERT.that(Multisets.sum(ms1, ms2)).has().allOf("a", "b", "a");
- }
-
- public void testDifferenceWithNoRemovedElements() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a"));
- ASSERT.that(Multisets.difference(ms1, ms2)).has().allOf("a", "b");
- }
-
- public void testDifferenceWithRemovedElement() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b"));
- ASSERT.that(Multisets.difference(ms1, ms2)).has().allOf("a", "a");
- }
-
- public void testDifferenceWithMoreElementsInSecondMultiset() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "b", "b"));
- Multiset<String> diff = Multisets.difference(ms1, ms2);
- ASSERT.that(diff).has().item("a");
- assertEquals(0, diff.count("b"));
- assertEquals(1, diff.count("a"));
- assertFalse(diff.contains("b"));
- assertTrue(diff.contains("a"));
- }
-
- public void testDifferenceEmptyNonempty() {
- Multiset<String> ms1 = HashMultiset.create();
- Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- assertEquals(ms1, Multisets.difference(ms1, ms2));
- }
-
- public void testDifferenceNonemptyEmpty() {
- Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- Multiset<String> ms2 = HashMultiset.create();
- assertEquals(ms1, Multisets.difference(ms1, ms2));
+ ASSERT.that(Multisets.intersection(ms1, ms2)).hasContentsInOrder();
}
-
+
public void testContainsOccurrencesEmpty() {
Multiset<String> superMultiset = HashMultiset.create(Arrays.asList("a", "b", "a"));
Multiset<String> subMultiset = HashMultiset.create();
@@ -190,7 +180,7 @@ public class MultisetsTest extends TestCase {
assertFalse(Multisets.containsOccurrences(superMultiset, diffMultiset));
assertTrue(Multisets.containsOccurrences(diffMultiset, subMultiset));
}
-
+
public void testRetainEmptyOccurrences() {
Multiset<String> multiset =
HashMultiset.create(Arrays.asList("a", "b", "a"));
@@ -205,7 +195,7 @@ public class MultisetsTest extends TestCase {
Multiset<String> toRetain =
HashMultiset.create(Arrays.asList("a", "b", "b"));
assertTrue(Multisets.retainOccurrences(multiset, toRetain));
- ASSERT.that(multiset).has().allOf("a", "b").inOrder();
+ ASSERT.that(multiset).hasContentsInOrder("a", "b");
}
public void testRemoveEmptyOccurrences() {
@@ -213,7 +203,7 @@ public class MultisetsTest extends TestCase {
TreeMultiset.create(Arrays.asList("a", "b", "a"));
Multiset<String> toRemove = HashMultiset.create();
assertFalse(Multisets.removeOccurrences(multiset, toRemove));
- ASSERT.that(multiset).has().allOf("a", "a", "b").inOrder();
+ ASSERT.that(multiset).hasContentsInOrder("a", "a", "b");
}
public void testRemoveOccurrences() {
@@ -222,11 +212,11 @@ public class MultisetsTest extends TestCase {
Multiset<String> toRemove =
HashMultiset.create(Arrays.asList("a", "b", "b"));
assertTrue(Multisets.removeOccurrences(multiset, toRemove));
- ASSERT.that(multiset).has().allOf("a", "c").inOrder();
+ ASSERT.that(multiset).hasContentsInOrder("a", "c");
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableMultisetShortCircuit() {
+ public void testUnmodifiableMultisetShortCircuit(){
Multiset<String> mod = HashMultiset.create();
Multiset<String> unmod = Multisets.unmodifiableMultiset(mod);
assertNotSame(mod, unmod);
@@ -235,30 +225,32 @@ public class MultisetsTest extends TestCase {
assertSame(immutable, Multisets.unmodifiableMultiset(immutable));
assertSame(immutable, Multisets.unmodifiableMultiset((Multiset<String>) immutable));
}
-
+
public void testHighestCountFirst() {
Multiset<String> multiset = HashMultiset.create(
Arrays.asList("a", "a", "a", "b", "c", "c"));
- ImmutableMultiset<String> sortedMultiset =
+ ImmutableMultiset<String> sortedMultiset =
Multisets.copyHighestCountFirst(multiset);
- ASSERT.that(sortedMultiset.entrySet()).has().allOf(
+ ASSERT.that(sortedMultiset.entrySet()).hasContentsInOrder(
Multisets.immutableEntry("a", 3), Multisets.immutableEntry("c", 2),
- Multisets.immutableEntry("b", 1)).inOrder();
+ Multisets.immutableEntry("b", 1));
- ASSERT.that(sortedMultiset).has().allOf(
+ ASSERT.that(sortedMultiset).hasContentsInOrder(
"a",
"a",
"a",
"c",
"c",
- "b").inOrder();
-
+ "b");
+
ASSERT.that(Multisets.copyHighestCountFirst(ImmutableMultiset.of())).isEmpty();
}
-
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(Multisets.class);
+ public void testNullPointers() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Multiset.class, ImmutableMultiset.of());
+ tester.testAllPublicStaticMethods(Multisets.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/NewCustomTableTest.java b/guava-tests/test/com/google/common/collect/NewCustomTableTest.java
index 21ef378..a491b71 100644
--- a/guava-tests/test/com/google/common/collect/NewCustomTableTest.java
+++ b/guava-tests/test/com/google/common/collect/NewCustomTableTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Supplier;
@@ -51,11 +51,11 @@ public class NewCustomTableTest extends AbstractTableTest {
public void testRowKeySetOrdering() {
table = create("foo", 3, 'a', "bar", 1, 'b', "foo", 2, 'c');
- ASSERT.that(table.rowKeySet()).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder("foo", "bar");
}
public void testRowOrdering() {
table = create("foo", 3, 'a', "bar", 1, 'b', "foo", 2, 'c');
- ASSERT.that(table.row("foo").keySet()).has().allOf(2, 3).inOrder();
+ ASSERT.that(table.row("foo").keySet()).hasContentsInOrder(2, 3);
}
}
diff --git a/guava-tests/test/com/google/common/collect/ObjectArraysTest.java b/guava-tests/test/com/google/common/collect/ObjectArraysTest.java
index 030895c..8fa1009 100644
--- a/guava-tests/test/com/google/common/collect/ObjectArraysTest.java
+++ b/guava-tests/test/com/google/common/collect/ObjectArraysTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -37,7 +37,7 @@ import java.util.List;
public class ObjectArraysTest extends TestCase {
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ObjectArrays.class);
}
@@ -98,7 +98,7 @@ public class ObjectArraysTest extends TestCase {
String[] result = ObjectArrays.concat(
new String[0], new String[] { "a", "b" }, String.class);
assertEquals(String[].class, result.getClass());
- ASSERT.that(result).has().allOf("a", "b").inOrder();
+ ASSERT.that(result).hasContentsInOrder("a", "b");
}
@GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)")
@@ -106,7 +106,7 @@ public class ObjectArraysTest extends TestCase {
String[] result = ObjectArrays.concat(
new String[] { "a", "b" }, new String[0], String.class);
assertEquals(String[].class, result.getClass());
- ASSERT.that(result).has().allOf("a", "b").inOrder();
+ ASSERT.that(result).hasContentsInOrder("a", "b");
}
@GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)")
@@ -114,7 +114,7 @@ public class ObjectArraysTest extends TestCase {
String[] result = ObjectArrays.concat(
new String[] { "a", "b" }, new String[] { "c", "d" }, String.class);
assertEquals(String[].class, result.getClass());
- ASSERT.that(result).has().allOf("a", "b", "c", "d").inOrder();
+ ASSERT.that(result).hasContentsInOrder("a", "b", "c", "d");
}
@GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)")
@@ -170,81 +170,31 @@ public class ObjectArraysTest extends TestCase {
public void testPrependZeroElements() {
String[] result = ObjectArrays.concat("foo", new String[] {});
- ASSERT.that(result).has().item("foo");
+ ASSERT.that(result).hasContentsInOrder("foo");
}
public void testPrependOneElement() {
- String[] result = ObjectArrays.concat("foo", new String[] { "bar" });
- ASSERT.that(result).has().allOf("foo", "bar").inOrder();
+ String[] result = ObjectArrays.concat("foo", new String[]{ "bar" });
+ ASSERT.that(result).hasContentsInOrder("foo", "bar");
}
public void testPrependTwoElements() {
- String[] result = ObjectArrays.concat("foo", new String[] { "bar", "baz" });
- ASSERT.that(result).has().allOf("foo", "bar", "baz").inOrder();
+ String[] result = ObjectArrays.concat("foo", new String[]{ "bar", "baz" });
+ ASSERT.that(result).hasContentsInOrder("foo", "bar", "baz");
}
public void testAppendZeroElements() {
String[] result = ObjectArrays.concat(new String[] {}, "foo");
- ASSERT.that(result).has().item("foo");
+ ASSERT.that(result).hasContentsInOrder("foo");
}
public void testAppendOneElement() {
- String[] result = ObjectArrays.concat(new String[] { "foo" }, "bar");
- ASSERT.that(result).has().allOf("foo", "bar").inOrder();
+ String[] result = ObjectArrays.concat(new String[]{ "foo" }, "bar");
+ ASSERT.that(result).hasContentsInOrder("foo", "bar");
}
public void testAppendTwoElements() {
- String[] result = ObjectArrays.concat(new String[] { "foo", "bar" }, "baz");
- ASSERT.that(result).has().allOf("foo", "bar", "baz").inOrder();
- }
-
- public void testEmptyArrayToEmpty() {
- doTestNewArrayEquals(new Object[0], 0);
- }
-
- public void testEmptyArrayToNonEmpty() {
- checkArrayEquals(new Long[5], ObjectArrays.newArray(new Long[0], 5));
- }
-
- public void testNonEmptyToShorter() {
- checkArrayEquals(new String[9], ObjectArrays.newArray(new String[10], 9));
- }
-
- public void testNonEmptyToSameLength() {
- doTestNewArrayEquals(new String[10], 10);
- }
-
- public void testNonEmptyToLonger() {
- checkArrayEquals(new String[10],
- ObjectArrays.newArray(new String[] { "a", "b", "c", "d", "e" }, 10));
- }
-
- public void testCloneEmptyArray() {
- checkArrayEquals(new String[0], Platform.clone(new String[0]));
- }
-
- public void testCloneSingletonArray() {
- checkArrayEquals(
- new String[] { "a" }, Platform.clone(new String[] { "a" }));
- }
-
- public void testCloneMultipleElementArray() {
- checkArrayEquals(
- new String[] { "a", "b", "c" }, Platform.clone(new String[] { "a", "b", "c" }));
- }
-
- private static void checkArrayEquals(Object[] expected, Object[] actual) {
- assertTrue("expected(" + expected.getClass() + "): " + Arrays.toString(expected)
- + " actual(" + actual.getClass() + "): " + Arrays.toString(actual),
- arrayEquals(expected, actual));
- }
-
- private static boolean arrayEquals(Object[] array1, Object[] array2) {
- assertSame(array1.getClass(), array2.getClass());
- return Arrays.equals(array1, array2);
- }
-
- private static void doTestNewArrayEquals(Object[] expected, int length) {
- checkArrayEquals(expected, ObjectArrays.newArray(expected, length));
+ String[] result = ObjectArrays.concat(new String[]{ "foo", "bar" }, "baz");
+ ASSERT.that(result).hasContentsInOrder("foo", "bar", "baz");
}
}
diff --git a/guava-tests/test/com/google/common/collect/OrderingTest.java b/guava-tests/test/com/google/common/collect/OrderingTest.java
index e3450a0..142c8b9 100644
--- a/guava-tests/test/com/google/common/collect/OrderingTest.java
+++ b/guava-tests/test/com/google/common/collect/OrderingTest.java
@@ -16,12 +16,11 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.testing.SerializableTester.reserializeAndAssert;
import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -56,21 +55,6 @@ public class OrderingTest extends TestCase {
private final Ordering<Number> numberOrdering = new NumberOrdering();
- public void testAllEqual() {
- Ordering<Object> comparator = Ordering.allEqual();
- assertSame(comparator, comparator.reverse());
-
- assertEquals(comparator.compare(null, null), 0);
- assertEquals(comparator.compare(new Object(), new Object()), 0);
- assertEquals(comparator.compare("apples", "oranges"), 0);
- assertSame(comparator, reserialize(comparator));
- assertEquals("Ordering.allEqual()", comparator.toString());
-
- List<String> strings = ImmutableList.of("b", "a", "d", "c");
- assertEquals(strings, comparator.sortedCopy(strings));
- assertEquals(strings, comparator.immutableSortedCopy(strings));
- }
-
public void testNatural() {
Ordering<Integer> comparator = Ordering.natural();
Helpers.testComparator(comparator,
@@ -156,7 +140,7 @@ public class OrderingTest extends TestCase {
= Ordering.explicit(2, 8, 6, 1, 7, 5, 3, 4, 0, 9);
List<Integer> list = Arrays.asList(0, 3, 5, 6, 7, 8, 9);
Collections.sort(list, c);
- ASSERT.that(list).has().allOf(8, 6, 7, 5, 3, 0, 9).inOrder();
+ ASSERT.that(list).hasContentsInOrder(8, 6, 7, 5, 3, 0, 9);
reserializeAndAssert(c);
}
@@ -240,7 +224,7 @@ public class OrderingTest extends TestCase {
}
public void testCompound_static() {
- Comparator<String> comparator = Ordering.compound(ImmutableList.of(
+ Comparator<String> comparator = Ordering.compound(asList(
byCharAt(0), byCharAt(1), byCharAt(2),
byCharAt(3), byCharAt(4), byCharAt(5)));
Helpers.testComparator(comparator, ImmutableList.of(
@@ -386,34 +370,16 @@ public class OrderingTest extends TestCase {
ImmutableList<String> b = ImmutableList.of("b");
Helpers.testComparator(lexy, empty, a, aa, ab, b);
-
- new EqualsTester()
- .addEqualityGroup(lexy, ordering.lexicographical())
- .addEqualityGroup(numberOrdering.lexicographical())
- .addEqualityGroup(Ordering.natural())
- .testEquals();
}
public void testNullsFirst() {
Ordering<Integer> ordering = Ordering.natural().nullsFirst();
Helpers.testComparator(ordering, null, Integer.MIN_VALUE, 0, 1);
-
- new EqualsTester()
- .addEqualityGroup(ordering, Ordering.natural().nullsFirst())
- .addEqualityGroup(numberOrdering.nullsFirst())
- .addEqualityGroup(Ordering.natural())
- .testEquals();
}
public void testNullsLast() {
Ordering<Integer> ordering = Ordering.natural().nullsLast();
Helpers.testComparator(ordering, 0, 1, Integer.MAX_VALUE, null);
-
- new EqualsTester()
- .addEqualityGroup(ordering, Ordering.natural().nullsLast())
- .addEqualityGroup(numberOrdering.nullsLast())
- .addEqualityGroup(Ordering.natural())
- .testEquals();
}
public void testBinarySearch() {
@@ -470,37 +436,21 @@ public class OrderingTest extends TestCase {
Collections.<Integer>emptyList()));
}
- public void testLeastOfIterable_empty_0() {
+ public void testLeastOf_emptyList_0() {
List<Integer> result = numberOrdering.leastOf(Arrays.<Integer>asList(), 0);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOfIterator_empty_0() {
- List<Integer> result = numberOrdering.leastOf(
- Iterators.<Integer>emptyIterator(), 0);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.<Integer>of(), result);
- }
-
- public void testLeastOfIterable_empty_1() {
+ public void testLeastOf_emptyList_1() {
List<Integer> result = numberOrdering.leastOf(Arrays.<Integer>asList(), 1);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOfIterator_empty_1() {
- List<Integer> result = numberOrdering.leastOf(
- Iterators.<Integer>emptyIterator(), 1);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.<Integer>of(), result);
- }
-
- public void testLeastOfIterable_simple_negativeOne() {
+ public void testLeastOf_simple_negativeOne() {
try {
numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), -1);
fail();
@@ -508,76 +458,28 @@ public class OrderingTest extends TestCase {
}
}
- public void testLeastOfIterator_simple_negativeOne() {
- try {
- numberOrdering.leastOf(Iterators.forArray(3, 4, 5, -1), -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testLeastOfIterable_singleton_0() {
+ public void testLeastOf_singletonList_0() {
List<Integer> result = numberOrdering.leastOf(Arrays.asList(3), 0);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOfIterator_singleton_0() {
- List<Integer> result = numberOrdering.leastOf(
- Iterators.singletonIterator(3), 0);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.<Integer>of(), result);
- }
-
- public void testLeastOfIterable_simple_0() {
+ public void testLeastOf_simple_0() {
List<Integer> result = numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), 0);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOfIterator_simple_0() {
- List<Integer> result = numberOrdering.leastOf(
- Iterators.forArray(3, 4, 5, -1), 0);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.<Integer>of(), result);
- }
-
- public void testLeastOfIterable_simple_1() {
+ public void testLeastOf_simple_1() {
List<Integer> result = numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), 1);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.of(-1), result);
}
- public void testLeastOfIterator_simple_1() {
- List<Integer> result = numberOrdering.leastOf(
- Iterators.forArray(3, 4, 5, -1), 1);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.of(-1), result);
- }
-
- public void testLeastOfIterable_simple_nMinusOne_withNullElement() {
- List<Integer> list = Arrays.asList(3, null, 5, -1);
- List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size() - 1);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.of(-1, 3, 5), result);
- }
-
- public void testLeastOfIterator_simple_nMinusOne_withNullElement() {
- Iterator<Integer> itr = Iterators.forArray(3, null, 5, -1);
- List<Integer> result = Ordering.natural().nullsLast().leastOf(itr, 3);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.of(-1, 3, 5), result);
- }
-
- public void testLeastOfIterable_simple_nMinusOne() {
+ public void testLeastOf_simple_nMinusOne() {
List<Integer> list = Arrays.asList(3, 4, 5, -1);
List<Integer> result = numberOrdering.leastOf(list, list.size() - 1);
assertTrue(result instanceof RandomAccess);
@@ -585,15 +487,7 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, 4), result);
}
- public void testLeastOfIterator_simple_nMinusOne() {
- List<Integer> list = Arrays.asList(3, 4, 5, -1);
- List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size() - 1);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.of(-1, 3, 4), result);
- }
-
- public void testLeastOfIterable_simple_n() {
+ public void testLeastOf_simple_n() {
List<Integer> list = Arrays.asList(3, 4, 5, -1);
List<Integer> result = numberOrdering.leastOf(list, list.size());
assertTrue(result instanceof RandomAccess);
@@ -601,32 +495,7 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
}
- public void testLeastOfIterator_simple_n() {
- List<Integer> list = Arrays.asList(3, 4, 5, -1);
- List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size());
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
- }
-
- public void testLeastOfIterable_simple_n_withNullElement() {
- List<Integer> list = Arrays.asList(3, 4, 5, null, -1);
- List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size());
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(Arrays.asList(-1, 3, 4, 5, null), result);
- }
-
- public void testLeastOfIterator_simple_n_withNullElement() {
- List<Integer> list = Arrays.asList(3, 4, 5, null, -1);
- List<Integer> result = Ordering.natural().nullsLast().leastOf(
- list.iterator(), list.size());
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(Arrays.asList(-1, 3, 4, 5, null), result);
- }
-
- public void testLeastOfIterable_simple_nPlusOne() {
+ public void testLeastOf_simple_nPlusOne() {
List<Integer> list = Arrays.asList(3, 4, 5, -1);
List<Integer> result = numberOrdering.leastOf(list, list.size() + 1);
assertTrue(result instanceof RandomAccess);
@@ -634,15 +503,7 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
}
- public void testLeastOfIterator_simple_nPlusOne() {
- List<Integer> list = Arrays.asList(3, 4, 5, -1);
- List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size() + 1);
- assertTrue(result instanceof RandomAccess);
- assertListImmutable(result);
- assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
- }
-
- public void testLeastOfIterable_ties() {
+ public void testLeastOf_ties() {
Integer foo = new Integer(Integer.MAX_VALUE - 10);
Integer bar = new Integer(Integer.MAX_VALUE - 10);
@@ -654,18 +515,6 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, foo, bar), result);
}
- public void testLeastOfIterator_ties() {
- Integer foo = new Integer(Integer.MAX_VALUE - 10);
- Integer bar = new Integer(Integer.MAX_VALUE - 10);
-
- assertNotSame(foo, bar);
- assertEquals(foo, bar);
-
- List<Integer> list = Arrays.asList(3, foo, bar, -1);
- List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size());
- assertEquals(ImmutableList.of(-1, 3, foo, bar), result);
- }
-
@GwtIncompatible("slow")
public void testLeastOf_reconcileAgainstSortAndSublist() {
runLeastOfComparison(1000, 300, 20);
@@ -694,19 +543,7 @@ public class OrderingTest extends TestCase {
}
}
- public void testLeastOfIterableLargeK() {
- List<Integer> list = Arrays.asList(4, 2, 3, 5, 1);
- assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ordering.natural()
- .leastOf(list, Integer.MAX_VALUE));
- }
-
- public void testLeastOfIteratorLargeK() {
- List<Integer> list = Arrays.asList(4, 2, 3, 5, 1);
- assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ordering.natural()
- .leastOf(list.iterator(), Integer.MAX_VALUE));
- }
-
- public void testGreatestOfIterable_simple() {
+ public void testGreatestOf_simple() {
/*
* If greatestOf() promised to be implemented as reverse().leastOf(), this
* test would be enough. It doesn't... but we'll cheat and act like it does
@@ -716,17 +553,6 @@ public class OrderingTest extends TestCase {
assertEquals(Arrays.asList(4, 4, 3, 3), numberOrdering.greatestOf(list, 4));
}
- public void testGreatestOfIterator_simple() {
- /*
- * If greatestOf() promised to be implemented as reverse().leastOf(), this
- * test would be enough. It doesn't... but we'll cheat and act like it does
- * anyway. There's a comment there to remind us to fix this if we change it.
- */
- List<Integer> list = Arrays.asList(3, 1, 3, 2, 4, 2, 4, 3);
- assertEquals(Arrays.asList(4, 4, 3, 3),
- numberOrdering.greatestOf(list.iterator(), 4));
- }
-
private static void assertListImmutable(List<Integer> result) {
try {
result.set(0, 1);
@@ -833,48 +659,32 @@ public class OrderingTest extends TestCase {
private static final int RECURSE_DEPTH = 2;
public void testCombinationsExhaustively_startingFromNatural() {
- testExhaustively(Ordering.<String>natural(), "a", "b", "d");
+ testExhaustively(Ordering.<String>natural(), Arrays.asList("a", "b"));
}
public void testCombinationsExhaustively_startingFromExplicit() {
testExhaustively(Ordering.explicit("a", "b", "c", "d"),
- "a", "b", "d");
+ Arrays.asList("b", "d"));
}
public void testCombinationsExhaustively_startingFromUsingToString() {
- testExhaustively(Ordering.usingToString(), 1, 12, 2);
- }
-
- public void testCombinationsExhaustively_startingFromFromComparator() {
- testExhaustively(Ordering.from(String.CASE_INSENSITIVE_ORDER),
- "A", "b", "C", "d");
+ testExhaustively(Ordering.usingToString(), Arrays.asList(1, 12, 2));
}
public void testCombinationsExhaustively_startingFromArbitrary() {
Ordering<Object> arbitrary = Ordering.arbitrary();
- Object[] array = {1, "foo", new Object()};
+ List<Object> list = Arrays.asList(1, "foo", new Object());
// There's no way to tell what the order should be except empirically
- Arrays.sort(array, arbitrary);
- testExhaustively(arbitrary, array);
+ Collections.sort(list, arbitrary);
+ testExhaustively(arbitrary, list);
}
- /**
- * Requires at least 3 elements in {@code strictlyOrderedElements} in order to
- * test the varargs version of min/max.
- */
private static <T> void testExhaustively(
- Ordering<? super T> ordering, T... strictlyOrderedElements) {
- checkArgument(strictlyOrderedElements.length >= 3, "strictlyOrderedElements "
- + "requires at least 3 elements");
- List<T> list = Arrays.asList(strictlyOrderedElements);
-
- // for use calling Collection.toArray later
- T[] emptyArray = Platform.newArray(strictlyOrderedElements, 0);
-
+ Ordering<? super T> ordering, List<T> list) {
// shoot me, but I didn't want to deal with wildcards through the whole test
@SuppressWarnings("unchecked")
- Scenario<T> starter = new Scenario<T>((Ordering) ordering, list, emptyArray);
+ Scenario<T> starter = new Scenario<T>((Ordering) ordering, list);
verifyScenario(starter, 0);
}
@@ -883,7 +693,6 @@ public class OrderingTest extends TestCase {
scenario.testIsOrdered();
scenario.testMinAndMax();
scenario.testBinarySearch();
- scenario.testSortedCopy();
if (level < RECURSE_DEPTH) {
for (OrderingMutation alteration : OrderingMutation.values()) {
@@ -899,12 +708,10 @@ public class OrderingTest extends TestCase {
private static class Scenario<T> {
final Ordering<T> ordering;
final List<T> strictlyOrderedList;
- final T[] emptyArray;
- Scenario(Ordering<T> ordering, List<T> strictlyOrderedList, T[] emptyArray) {
+ Scenario(Ordering<T> ordering, List<T> strictlyOrderedList) {
this.ordering = ordering;
this.strictlyOrderedList = strictlyOrderedList;
- this.emptyArray = emptyArray;
}
void testCompareTo() {
@@ -916,30 +723,13 @@ public class OrderingTest extends TestCase {
assertTrue(ordering.isStrictlyOrdered(strictlyOrderedList));
}
- @SuppressWarnings("unchecked") // generic arrays and unchecked cast
void testMinAndMax() {
List<T> shuffledList = Lists.newArrayList(strictlyOrderedList);
shuffledList = shuffledCopy(shuffledList, new Random(5));
- T min = strictlyOrderedList.get(0);
- T max = strictlyOrderedList.get(strictlyOrderedList.size() - 1);
-
- T first = shuffledList.get(0);
- T second = shuffledList.get(1);
- T third = shuffledList.get(2);
- T[] rest = shuffledList.subList(3, shuffledList.size()).toArray(emptyArray);
-
- assertEquals(min, ordering.min(shuffledList));
- assertEquals(min, ordering.min(shuffledList.iterator()));
- assertEquals(min, ordering.min(first, second, third, rest));
- assertEquals(min, ordering.min(min, max));
- assertEquals(min, ordering.min(max, min));
-
- assertEquals(max, ordering.max(shuffledList));
- assertEquals(max, ordering.max(shuffledList.iterator()));
- assertEquals(max, ordering.max(first, second, third, rest));
- assertEquals(max, ordering.max(min, max));
- assertEquals(max, ordering.max(max, min));
+ assertEquals(strictlyOrderedList.get(0), ordering.min(shuffledList));
+ assertEquals(strictlyOrderedList.get(strictlyOrderedList.size() - 1),
+ ordering.max(shuffledList));
}
void testBinarySearch() {
@@ -951,17 +741,6 @@ public class OrderingTest extends TestCase {
T valueNotInList = newList.remove(1);
assertEquals(-2, ordering.binarySearch(newList, valueNotInList));
}
-
- void testSortedCopy() {
- List<T> shuffledList = Lists.newArrayList(strictlyOrderedList);
- shuffledList = shuffledCopy(shuffledList, new Random(5));
-
- assertEquals(strictlyOrderedList, ordering.sortedCopy(shuffledList));
-
- if (!strictlyOrderedList.contains(null)) {
- assertEquals(strictlyOrderedList, ordering.immutableSortedCopy(shuffledList));
- }
- }
}
/**
@@ -975,7 +754,7 @@ public class OrderingTest extends TestCase {
@Override <T> Scenario<?> mutate(Scenario<T> scenario) {
List<T> newList = Lists.newArrayList(scenario.strictlyOrderedList);
Collections.reverse(newList);
- return new Scenario<T>(scenario.ordering.reverse(), newList, scenario.emptyArray);
+ return new Scenario<T>(scenario.ordering.reverse(), newList);
}
},
NULLS_FIRST {
@@ -987,7 +766,7 @@ public class OrderingTest extends TestCase {
newList.add(t);
}
}
- return new Scenario<T>(scenario.ordering.nullsFirst(), newList, scenario.emptyArray);
+ return new Scenario<T>(scenario.ordering.nullsFirst(), newList);
}
},
NULLS_LAST {
@@ -999,7 +778,7 @@ public class OrderingTest extends TestCase {
}
}
newList.add(null);
- return new Scenario<T>(scenario.ordering.nullsLast(), newList, scenario.emptyArray);
+ return new Scenario<T>(scenario.ordering.nullsLast(), newList);
}
},
ON_RESULT_OF {
@@ -1015,11 +794,10 @@ public class OrderingTest extends TestCase {
for (int i = 0; i < scenario.strictlyOrderedList.size(); i++) {
list.add(i);
}
- return new Scenario<Integer>(ordering, list, new Integer[0]);
+ return new Scenario<Integer>(ordering, list);
}
},
COMPOUND_THIS_WITH_NATURAL {
- @SuppressWarnings("unchecked") // raw array
@Override <T> Scenario<?> mutate(Scenario<T> scenario) {
List<Composite<T>> composites = Lists.newArrayList();
for (T t : scenario.strictlyOrderedList) {
@@ -1029,11 +807,10 @@ public class OrderingTest extends TestCase {
Ordering<Composite<T>> ordering =
scenario.ordering.onResultOf(Composite.<T>getValueFunction())
.compound(Ordering.natural());
- return new Scenario<Composite<T>>(ordering, composites, new Composite[0]);
+ return new Scenario<Composite<T>>(ordering, composites);
}
},
COMPOUND_NATURAL_WITH_THIS {
- @SuppressWarnings("unchecked") // raw array
@Override <T> Scenario<?> mutate(Scenario<T> scenario) {
List<Composite<T>> composites = Lists.newArrayList();
for (T t : scenario.strictlyOrderedList) {
@@ -1044,7 +821,7 @@ public class OrderingTest extends TestCase {
}
Ordering<Composite<T>> ordering = Ordering.natural().compound(
scenario.ordering.onResultOf(Composite.<T>getValueFunction()));
- return new Scenario<Composite<T>>(ordering, composites, new Composite[0]);
+ return new Scenario<Composite<T>>(ordering, composites);
}
},
LEXICOGRAPHICAL {
@@ -1059,7 +836,7 @@ public class OrderingTest extends TestCase {
}
}
return new Scenario<Iterable<T>>(
- scenario.ordering.lexicographical(), words, new Iterable[0]);
+ scenario.ordering.lexicographical(), words);
}
},
;
@@ -1098,7 +875,7 @@ public class OrderingTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Ordering.class);
diff --git a/guava-tests/test/com/google/common/collect/PackageSanityTests.java b/guava-tests/test/com/google/common/collect/PackageSanityTests.java
deleted file mode 100644
index c847140..0000000
--- a/guava-tests/test/com/google/common/collect/PackageSanityTests.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Covers basic sanity checks for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- publicApiOnly(); // Many package-private classes are tested through the public API.
- setDefault(DiscreteDomain.class, DiscreteDomain.integers());
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/QueuesTest.java b/guava-tests/test/com/google/common/collect/QueuesTest.java
index d64caae..bffcb39 100644
--- a/guava-tests/test/com/google/common/collect/QueuesTest.java
+++ b/guava-tests/test/com/google/common/collect/QueuesTest.java
@@ -208,17 +208,6 @@ public class QueuesTest extends TestCase {
assertEquals(100, buf.size());
}
- public void testNewLinkedBlockingDequeCapacity() {
- try {
- Queues.newLinkedBlockingDeque(0);
- fail("Should have thrown IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // any capacity less than 1 should throw IllegalArgumentException
- }
- assertEquals(1, Queues.newLinkedBlockingDeque(1).remainingCapacity());
- assertEquals(11, Queues.newLinkedBlockingDeque(11).remainingCapacity());
- }
-
public void testNewLinkedBlockingQueueCapacity() {
try {
Queues.newLinkedBlockingQueue(0);
diff --git a/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java b/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java
index 7828f64..7b1d297 100644
--- a/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java
+++ b/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java
@@ -28,14 +28,16 @@ import junit.framework.TestCase;
*/
public class RangeNonGwtTest extends TestCase {
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(BoundType.class, BoundType.OPEN);
+ tester.setDefault(Comparable.class, 0);
tester.testAllPublicStaticMethods(Range.class);
- tester.testAllPublicStaticMethods(Range.class);
+ tester.testAllPublicStaticMethods(Ranges.class);
- tester.testAllPublicInstanceMethods(Range.all());
- tester.testAllPublicInstanceMethods(Range.open(1, 3));
+ tester.testAllPublicInstanceMethods(Ranges.all());
+ tester.testAllPublicInstanceMethods(Ranges.open(1, 3));
}
}
diff --git a/guava-tests/test/com/google/common/collect/RangeTest.java b/guava-tests/test/com/google/common/collect/RangeTest.java
index 8c30ae2..9b74b0e 100644
--- a/guava-tests/test/com/google/common/collect/RangeTest.java
+++ b/guava-tests/test/com/google/common/collect/RangeTest.java
@@ -18,7 +18,7 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.DiscreteDomain.integers;
+import static com.google.common.collect.DiscreteDomains.integers;
import static com.google.common.testing.SerializableTester.reserializeAndAssert;
import static java.util.Arrays.asList;
@@ -29,10 +29,7 @@ import com.google.common.testing.EqualsTester;
import junit.framework.TestCase;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.List;
-import java.util.NoSuchElementException;
/**
* Unit test for {@link Range}.
@@ -42,7 +39,7 @@ import java.util.NoSuchElementException;
@GwtCompatible
public class RangeTest extends TestCase {
public void testOpen() {
- Range<Integer> range = Range.open(4, 8);
+ Range<Integer> range = Ranges.open(4, 8);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(4, (int) range.lowerEndpoint());
@@ -57,19 +54,19 @@ public class RangeTest extends TestCase {
public void testOpen_invalid() {
try {
- Range.open(4, 3);
+ Ranges.open(4, 3);
fail();
} catch (IllegalArgumentException expected) {
}
try {
- Range.open(3, 3);
+ Ranges.open(3, 3);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testClosed() {
- Range<Integer> range = Range.closed(5, 7);
+ Range<Integer> range = Ranges.closed(5, 7);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(5, (int) range.lowerEndpoint());
@@ -84,14 +81,14 @@ public class RangeTest extends TestCase {
public void testClosed_invalid() {
try {
- Range.closed(4, 3);
+ Ranges.closed(4, 3);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testOpenClosed() {
- Range<Integer> range = Range.openClosed(4, 7);
+ Range<Integer> range = Ranges.openClosed(4, 7);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(4, (int) range.lowerEndpoint());
@@ -105,7 +102,7 @@ public class RangeTest extends TestCase {
}
public void testClosedOpen() {
- Range<Integer> range = Range.closedOpen(5, 8);
+ Range<Integer> range = Ranges.closedOpen(5, 8);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(5, (int) range.lowerEndpoint());
@@ -119,13 +116,13 @@ public class RangeTest extends TestCase {
}
public void testIsConnected() {
- assertTrue(Range.closed(3, 5).isConnected(Range.open(5, 6)));
- assertTrue(Range.closed(3, 5).isConnected(Range.openClosed(5, 5)));
- assertTrue(Range.open(3, 5).isConnected(Range.closed(5, 6)));
- assertTrue(Range.closed(3, 7).isConnected(Range.open(6, 8)));
- assertTrue(Range.open(3, 7).isConnected(Range.closed(5, 6)));
- assertFalse(Range.closed(3, 5).isConnected(Range.closed(7, 8)));
- assertFalse(Range.closed(3, 5).isConnected(Range.closedOpen(7, 7)));
+ assertTrue(Ranges.closed(3, 5).isConnected(Ranges.open(5, 6)));
+ assertTrue(Ranges.closed(3, 5).isConnected(Ranges.openClosed(5, 5)));
+ assertTrue(Ranges.open(3, 5).isConnected(Ranges.closed(5, 6)));
+ assertTrue(Ranges.closed(3, 7).isConnected(Ranges.open(6, 8)));
+ assertTrue(Ranges.open(3, 7).isConnected(Ranges.closed(5, 6)));
+ assertFalse(Ranges.closed(3, 5).isConnected(Ranges.closed(7, 8)));
+ assertFalse(Ranges.closed(3, 5).isConnected(Ranges.closedOpen(7, 7)));
}
private static void checkContains(Range<Integer> range) {
@@ -136,7 +133,7 @@ public class RangeTest extends TestCase {
}
public void testSingleton() {
- Range<Integer> range = Range.closed(4, 4);
+ Range<Integer> range = Ranges.closed(4, 4);
assertFalse(range.contains(3));
assertTrue(range.contains(4));
assertFalse(range.contains(5));
@@ -152,7 +149,7 @@ public class RangeTest extends TestCase {
}
public void testEmpty1() {
- Range<Integer> range = Range.closedOpen(4, 4);
+ Range<Integer> range = Ranges.closedOpen(4, 4);
assertFalse(range.contains(3));
assertFalse(range.contains(4));
assertFalse(range.contains(5));
@@ -168,7 +165,7 @@ public class RangeTest extends TestCase {
}
public void testEmpty2() {
- Range<Integer> range = Range.openClosed(4, 4);
+ Range<Integer> range = Ranges.openClosed(4, 4);
assertFalse(range.contains(3));
assertFalse(range.contains(4));
assertFalse(range.contains(5));
@@ -184,7 +181,7 @@ public class RangeTest extends TestCase {
}
public void testLessThan() {
- Range<Integer> range = Range.lessThan(5);
+ Range<Integer> range = Ranges.lessThan(5);
assertTrue(range.contains(Integer.MIN_VALUE));
assertTrue(range.contains(4));
assertFalse(range.contains(5));
@@ -198,7 +195,7 @@ public class RangeTest extends TestCase {
}
public void testGreaterThan() {
- Range<Integer> range = Range.greaterThan(5);
+ Range<Integer> range = Ranges.greaterThan(5);
assertFalse(range.contains(5));
assertTrue(range.contains(6));
assertTrue(range.contains(Integer.MAX_VALUE));
@@ -212,7 +209,7 @@ public class RangeTest extends TestCase {
}
public void testAtLeast() {
- Range<Integer> range = Range.atLeast(6);
+ Range<Integer> range = Ranges.atLeast(6);
assertFalse(range.contains(5));
assertTrue(range.contains(6));
assertTrue(range.contains(Integer.MAX_VALUE));
@@ -226,7 +223,7 @@ public class RangeTest extends TestCase {
}
public void testAtMost() {
- Range<Integer> range = Range.atMost(4);
+ Range<Integer> range = Ranges.atMost(4);
assertTrue(range.contains(Integer.MIN_VALUE));
assertTrue(range.contains(4));
assertFalse(range.contains(5));
@@ -240,15 +237,14 @@ public class RangeTest extends TestCase {
}
public void testAll() {
- Range<Integer> range = Range.all();
+ Range<Integer> range = Ranges.all();
assertTrue(range.contains(Integer.MIN_VALUE));
assertTrue(range.contains(Integer.MAX_VALUE));
assertUnboundedBelow(range);
assertUnboundedAbove(range);
assertFalse(range.isEmpty());
assertEquals("(-\u221e\u2025+\u221e)", range.toString());
- assertSame(range, reserializeAndAssert(range));
- assertSame(range, Range.all());
+ reserializeAndAssert(range);
}
private static void assertUnboundedBelow(Range<Integer> range) {
@@ -280,18 +276,18 @@ public class RangeTest extends TestCase {
}
public void testOrderingCuts() {
- Cut<Integer> a = Range.lessThan(0).lowerBound;
- Cut<Integer> b = Range.atLeast(0).lowerBound;
- Cut<Integer> c = Range.greaterThan(0).lowerBound;
- Cut<Integer> d = Range.atLeast(1).lowerBound;
- Cut<Integer> e = Range.greaterThan(1).lowerBound;
- Cut<Integer> f = Range.greaterThan(1).upperBound;
+ Cut<Integer> a = Ranges.lessThan(0).lowerBound;
+ Cut<Integer> b = Ranges.atLeast(0).lowerBound;
+ Cut<Integer> c = Ranges.greaterThan(0).lowerBound;
+ Cut<Integer> d = Ranges.atLeast(1).lowerBound;
+ Cut<Integer> e = Ranges.greaterThan(1).lowerBound;
+ Cut<Integer> f = Ranges.greaterThan(1).upperBound;
Helpers.testCompareToAndEquals(ImmutableList.of(a, b, c, d, e, f));
}
public void testContainsAll() {
- Range<Integer> range = Range.closed(3, 5);
+ Range<Integer> range = Ranges.closed(3, 5);
assertTrue(range.containsAll(asList(3, 3, 4, 5)));
assertFalse(range.containsAll(asList(3, 3, 4, 5, 6)));
@@ -302,219 +298,219 @@ public class RangeTest extends TestCase {
assertTrue(range.containsAll(ImmutableSortedSet.<Integer>of()));
assertFalse(range.containsAll(ImmutableSortedSet.of(3, 3, 4, 5, 6)));
- assertTrue(Range.openClosed(3, 3).containsAll(
+ assertTrue(Ranges.openClosed(3, 3).containsAll(
Collections.<Integer>emptySet()));
}
public void testEncloses_open() {
- Range<Integer> range = Range.open(2, 5);
+ Range<Integer> range = Ranges.open(2, 5);
assertTrue(range.encloses(range));
- assertTrue(range.encloses(Range.open(2, 4)));
- assertTrue(range.encloses(Range.open(3, 5)));
- assertTrue(range.encloses(Range.closed(3, 4)));
+ assertTrue(range.encloses(Ranges.open(2, 4)));
+ assertTrue(range.encloses(Ranges.open(3, 5)));
+ assertTrue(range.encloses(Ranges.closed(3, 4)));
- assertFalse(range.encloses(Range.openClosed(2, 5)));
- assertFalse(range.encloses(Range.closedOpen(2, 5)));
- assertFalse(range.encloses(Range.closed(1, 4)));
- assertFalse(range.encloses(Range.closed(3, 6)));
- assertFalse(range.encloses(Range.greaterThan(3)));
- assertFalse(range.encloses(Range.lessThan(3)));
- assertFalse(range.encloses(Range.atLeast(3)));
- assertFalse(range.encloses(Range.atMost(3)));
- assertFalse(range.encloses(Range.<Integer>all()));
+ assertFalse(range.encloses(Ranges.openClosed(2, 5)));
+ assertFalse(range.encloses(Ranges.closedOpen(2, 5)));
+ assertFalse(range.encloses(Ranges.closed(1, 4)));
+ assertFalse(range.encloses(Ranges.closed(3, 6)));
+ assertFalse(range.encloses(Ranges.greaterThan(3)));
+ assertFalse(range.encloses(Ranges.lessThan(3)));
+ assertFalse(range.encloses(Ranges.atLeast(3)));
+ assertFalse(range.encloses(Ranges.atMost(3)));
+ assertFalse(range.encloses(Ranges.<Integer>all()));
}
public void testEncloses_closed() {
- Range<Integer> range = Range.closed(2, 5);
+ Range<Integer> range = Ranges.closed(2, 5);
assertTrue(range.encloses(range));
- assertTrue(range.encloses(Range.open(2, 5)));
- assertTrue(range.encloses(Range.openClosed(2, 5)));
- assertTrue(range.encloses(Range.closedOpen(2, 5)));
- assertTrue(range.encloses(Range.closed(3, 5)));
- assertTrue(range.encloses(Range.closed(2, 4)));
+ assertTrue(range.encloses(Ranges.open(2, 5)));
+ assertTrue(range.encloses(Ranges.openClosed(2, 5)));
+ assertTrue(range.encloses(Ranges.closedOpen(2, 5)));
+ assertTrue(range.encloses(Ranges.closed(3, 5)));
+ assertTrue(range.encloses(Ranges.closed(2, 4)));
- assertFalse(range.encloses(Range.open(1, 6)));
- assertFalse(range.encloses(Range.greaterThan(3)));
- assertFalse(range.encloses(Range.lessThan(3)));
- assertFalse(range.encloses(Range.atLeast(3)));
- assertFalse(range.encloses(Range.atMost(3)));
- assertFalse(range.encloses(Range.<Integer>all()));
+ assertFalse(range.encloses(Ranges.open(1, 6)));
+ assertFalse(range.encloses(Ranges.greaterThan(3)));
+ assertFalse(range.encloses(Ranges.lessThan(3)));
+ assertFalse(range.encloses(Ranges.atLeast(3)));
+ assertFalse(range.encloses(Ranges.atMost(3)));
+ assertFalse(range.encloses(Ranges.<Integer>all()));
}
public void testIntersection_empty() {
- Range<Integer> range = Range.closedOpen(3, 3);
+ Range<Integer> range = Ranges.closedOpen(3, 3);
assertEquals(range, range.intersection(range));
try {
- range.intersection(Range.open(3, 5));
+ range.intersection(Ranges.open(3, 5));
fail();
} catch (IllegalArgumentException expected) {
}
try {
- range.intersection(Range.closed(0, 2));
+ range.intersection(Ranges.closed(0, 2));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIntersection_deFactoEmpty() {
- Range<Integer> range = Range.open(3, 4);
+ Range<Integer> range = Ranges.open(3, 4);
assertEquals(range, range.intersection(range));
- assertEquals(Range.openClosed(3, 3),
- range.intersection(Range.atMost(3)));
- assertEquals(Range.closedOpen(4, 4),
- range.intersection(Range.atLeast(4)));
-
+ assertEquals(Ranges.openClosed(3, 3),
+ range.intersection(Ranges.atMost(3)));
+ assertEquals(Ranges.closedOpen(4, 4),
+ range.intersection(Ranges.atLeast(4)));
+
try {
- range.intersection(Range.lessThan(3));
+ range.intersection(Ranges.lessThan(3));
fail();
} catch (IllegalArgumentException expected) {
}
try {
- range.intersection(Range.greaterThan(4));
+ range.intersection(Ranges.greaterThan(4));
fail();
} catch (IllegalArgumentException expected) {
}
- range = Range.closed(3, 4);
- assertEquals(Range.openClosed(4, 4),
- range.intersection(Range.greaterThan(4)));
+ range = Ranges.closed(3, 4);
+ assertEquals(Ranges.openClosed(4, 4),
+ range.intersection(Ranges.greaterThan(4)));
}
public void testIntersection_singleton() {
- Range<Integer> range = Range.closed(3, 3);
+ Range<Integer> range = Ranges.closed(3, 3);
assertEquals(range, range.intersection(range));
- assertEquals(range, range.intersection(Range.atMost(4)));
- assertEquals(range, range.intersection(Range.atMost(3)));
- assertEquals(range, range.intersection(Range.atLeast(3)));
- assertEquals(range, range.intersection(Range.atLeast(2)));
+ assertEquals(range, range.intersection(Ranges.atMost(4)));
+ assertEquals(range, range.intersection(Ranges.atMost(3)));
+ assertEquals(range, range.intersection(Ranges.atLeast(3)));
+ assertEquals(range, range.intersection(Ranges.atLeast(2)));
- assertEquals(Range.closedOpen(3, 3),
- range.intersection(Range.lessThan(3)));
- assertEquals(Range.openClosed(3, 3),
- range.intersection(Range.greaterThan(3)));
+ assertEquals(Ranges.closedOpen(3, 3),
+ range.intersection(Ranges.lessThan(3)));
+ assertEquals(Ranges.openClosed(3, 3),
+ range.intersection(Ranges.greaterThan(3)));
try {
- range.intersection(Range.atLeast(4));
+ range.intersection(Ranges.atLeast(4));
fail();
} catch (IllegalArgumentException expected) {
}
try {
- range.intersection(Range.atMost(2));
+ range.intersection(Ranges.atMost(2));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIntersection_general() {
- Range<Integer> range = Range.closed(4, 8);
+ Range<Integer> range = Ranges.closed(4, 8);
// separate below
try {
- range.intersection(Range.closed(0, 2));
+ range.intersection(Ranges.closed(0, 2));
fail();
} catch (IllegalArgumentException expected) {
}
// adjacent below
- assertEquals(Range.closedOpen(4, 4),
- range.intersection(Range.closedOpen(2, 4)));
+ assertEquals(Ranges.closedOpen(4, 4),
+ range.intersection(Ranges.closedOpen(2, 4)));
// overlap below
- assertEquals(Range.closed(4, 6), range.intersection(Range.closed(2, 6)));
+ assertEquals(Ranges.closed(4, 6), range.intersection(Ranges.closed(2, 6)));
// enclosed with same start
- assertEquals(Range.closed(4, 6), range.intersection(Range.closed(4, 6)));
+ assertEquals(Ranges.closed(4, 6), range.intersection(Ranges.closed(4, 6)));
// enclosed, interior
- assertEquals(Range.closed(5, 7), range.intersection(Range.closed(5, 7)));
+ assertEquals(Ranges.closed(5, 7), range.intersection(Ranges.closed(5, 7)));
// enclosed with same end
- assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 8)));
+ assertEquals(Ranges.closed(6, 8), range.intersection(Ranges.closed(6, 8)));
// equal
assertEquals(range, range.intersection(range));
// enclosing with same start
- assertEquals(range, range.intersection(Range.closed(4, 10)));
+ assertEquals(range, range.intersection(Ranges.closed(4, 10)));
// enclosing with same end
- assertEquals(range, range.intersection(Range.closed(2, 8)));
+ assertEquals(range, range.intersection(Ranges.closed(2, 8)));
// enclosing, exterior
- assertEquals(range, range.intersection(Range.closed(2, 10)));
+ assertEquals(range, range.intersection(Ranges.closed(2, 10)));
// overlap above
- assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 10)));
+ assertEquals(Ranges.closed(6, 8), range.intersection(Ranges.closed(6, 10)));
// adjacent above
- assertEquals(Range.openClosed(8, 8),
- range.intersection(Range.openClosed(8, 10)));
+ assertEquals(Ranges.openClosed(8, 8),
+ range.intersection(Ranges.openClosed(8, 10)));
// separate above
try {
- range.intersection(Range.closed(10, 12));
+ range.intersection(Ranges.closed(10, 12));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testSpan_general() {
- Range<Integer> range = Range.closed(4, 8);
+ Range<Integer> range = Ranges.closed(4, 8);
// separate below
- assertEquals(Range.closed(0, 8), range.span(Range.closed(0, 2)));
- assertEquals(Range.atMost(8), range.span(Range.atMost(2)));
+ assertEquals(Ranges.closed(0, 8), range.span(Ranges.closed(0, 2)));
+ assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(2)));
// adjacent below
- assertEquals(Range.closed(2, 8), range.span(Range.closedOpen(2, 4)));
- assertEquals(Range.atMost(8), range.span(Range.lessThan(4)));
+ assertEquals(Ranges.closed(2, 8), range.span(Ranges.closedOpen(2, 4)));
+ assertEquals(Ranges.atMost(8), range.span(Ranges.lessThan(4)));
// overlap below
- assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 6)));
- assertEquals(Range.atMost(8), range.span(Range.atMost(6)));
+ assertEquals(Ranges.closed(2, 8), range.span(Ranges.closed(2, 6)));
+ assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(6)));
// enclosed with same start
- assertEquals(range, range.span(Range.closed(4, 6)));
+ assertEquals(range, range.span(Ranges.closed(4, 6)));
// enclosed, interior
- assertEquals(range, range.span(Range.closed(5, 7)));
+ assertEquals(range, range.span(Ranges.closed(5, 7)));
// enclosed with same end
- assertEquals(range, range.span(Range.closed(6, 8)));
+ assertEquals(range, range.span(Ranges.closed(6, 8)));
// equal
assertEquals(range, range.span(range));
// enclosing with same start
- assertEquals(Range.closed(4, 10), range.span(Range.closed(4, 10)));
- assertEquals(Range.atLeast(4), range.span(Range.atLeast(4)));
+ assertEquals(Ranges.closed(4, 10), range.span(Ranges.closed(4, 10)));
+ assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(4)));
// enclosing with same end
- assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 8)));
- assertEquals(Range.atMost(8), range.span(Range.atMost(8)));
+ assertEquals(Ranges.closed(2, 8), range.span(Ranges.closed(2, 8)));
+ assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(8)));
// enclosing, exterior
- assertEquals(Range.closed(2, 10), range.span(Range.closed(2, 10)));
- assertEquals(Range.<Integer>all(), range.span(Range.<Integer>all()));
+ assertEquals(Ranges.closed(2, 10), range.span(Ranges.closed(2, 10)));
+ assertEquals(Ranges.<Integer>all(), range.span(Ranges.<Integer>all()));
// overlap above
- assertEquals(Range.closed(4, 10), range.span(Range.closed(6, 10)));
- assertEquals(Range.atLeast(4), range.span(Range.atLeast(6)));
+ assertEquals(Ranges.closed(4, 10), range.span(Ranges.closed(6, 10)));
+ assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(6)));
// adjacent above
- assertEquals(Range.closed(4, 10), range.span(Range.openClosed(8, 10)));
- assertEquals(Range.atLeast(4), range.span(Range.greaterThan(8)));
+ assertEquals(Ranges.closed(4, 10), range.span(Ranges.openClosed(8, 10)));
+ assertEquals(Ranges.atLeast(4), range.span(Ranges.greaterThan(8)));
// separate above
- assertEquals(Range.closed(4, 12), range.span(Range.closed(10, 12)));
- assertEquals(Range.atLeast(4), range.span(Range.atLeast(10)));
+ assertEquals(Ranges.closed(4, 12), range.span(Ranges.closed(10, 12)));
+ assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(10)));
}
public void testApply() {
- Predicate<Integer> predicate = Range.closed(2, 3);
+ Predicate<Integer> predicate = Ranges.closed(2, 3);
assertFalse(predicate.apply(1));
assertTrue(predicate.apply(2));
assertTrue(predicate.apply(3));
@@ -523,36 +519,36 @@ public class RangeTest extends TestCase {
public void testEquals() {
new EqualsTester()
- .addEqualityGroup(Range.open(1, 5),
- Range.range(1, OPEN, 5, OPEN))
- .addEqualityGroup(Range.greaterThan(2), Range.greaterThan(2))
- .addEqualityGroup(Range.all(), Range.all())
+ .addEqualityGroup(Ranges.open(1, 5),
+ Ranges.range(1, OPEN, 5, OPEN))
+ .addEqualityGroup(Ranges.greaterThan(2), Ranges.greaterThan(2))
+ .addEqualityGroup(Ranges.all(), Ranges.all())
.addEqualityGroup("Phil")
.testEquals();
}
public void testLegacyComparable() {
Range<LegacyComparable> range
- = Range.closed(LegacyComparable.X, LegacyComparable.Y);
+ = Ranges.closed(LegacyComparable.X, LegacyComparable.Y);
}
private static final DiscreteDomain<Integer> UNBOUNDED_DOMAIN =
new DiscreteDomain<Integer>() {
@Override public Integer next(Integer value) {
- return integers().next(value);
+ return DiscreteDomains.integers().next(value);
}
@Override public Integer previous(Integer value) {
- return integers().previous(value);
+ return DiscreteDomains.integers().previous(value);
}
@Override public long distance(Integer start, Integer end) {
- return integers().distance(start, end);
+ return DiscreteDomains.integers().distance(start, end);
}
};
public void testAsSet_noMin() {
- Range<Integer> range = Range.lessThan(0);
+ Range<Integer> range = Ranges.lessThan(0);
try {
range.asSet(UNBOUNDED_DOMAIN);
fail();
@@ -560,7 +556,7 @@ public class RangeTest extends TestCase {
}
public void testAsSet_noMax() {
- Range<Integer> range = Range.greaterThan(0);
+ Range<Integer> range = Ranges.greaterThan(0);
try {
range.asSet(UNBOUNDED_DOMAIN);
fail();
@@ -568,97 +564,41 @@ public class RangeTest extends TestCase {
}
public void testAsSet_empty() {
- assertEquals(ImmutableSet.of(), Range.closedOpen(1, 1).asSet(integers()));
- assertEquals(ImmutableSet.of(), Range.openClosed(5, 5).asSet(integers()));
- assertEquals(ImmutableSet.of(), Range.lessThan(Integer.MIN_VALUE).asSet(integers()));
- assertEquals(ImmutableSet.of(), Range.greaterThan(Integer.MAX_VALUE).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Ranges.closedOpen(1, 1).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Ranges.openClosed(5, 5).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Ranges.lessThan(Integer.MIN_VALUE).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Ranges.greaterThan(Integer.MAX_VALUE).asSet(integers()));
}
public void testCanonical() {
- assertEquals(Range.closedOpen(1, 5),
- Range.closed(1, 4).canonical(integers()));
- assertEquals(Range.closedOpen(1, 5),
- Range.open(0, 5).canonical(integers()));
- assertEquals(Range.closedOpen(1, 5),
- Range.closedOpen(1, 5).canonical(integers()));
- assertEquals(Range.closedOpen(1, 5),
- Range.openClosed(0, 4).canonical(integers()));
+ assertEquals(Ranges.closedOpen(1, 5),
+ Ranges.closed(1, 4).canonical(integers()));
+ assertEquals(Ranges.closedOpen(1, 5),
+ Ranges.open(0, 5).canonical(integers()));
+ assertEquals(Ranges.closedOpen(1, 5),
+ Ranges.closedOpen(1, 5).canonical(integers()));
+ assertEquals(Ranges.closedOpen(1, 5),
+ Ranges.openClosed(0, 4).canonical(integers()));
- assertEquals(Range.closedOpen(Integer.MIN_VALUE, 0),
- Range.closedOpen(Integer.MIN_VALUE, 0).canonical(integers()));
+ assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 0),
+ Ranges.closedOpen(Integer.MIN_VALUE, 0).canonical(integers()));
- assertEquals(Range.closedOpen(Integer.MIN_VALUE, 0),
- Range.lessThan(0).canonical(integers()));
- assertEquals(Range.closedOpen(Integer.MIN_VALUE, 1),
- Range.atMost(0).canonical(integers()));
- assertEquals(Range.atLeast(0), Range.atLeast(0).canonical(integers()));
- assertEquals(Range.atLeast(1), Range.greaterThan(0).canonical(integers()));
+ assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 0),
+ Ranges.lessThan(0).canonical(integers()));
+ assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 1),
+ Ranges.atMost(0).canonical(integers()));
+ assertEquals(Ranges.atLeast(0), Ranges.atLeast(0).canonical(integers()));
+ assertEquals(Ranges.atLeast(1), Ranges.greaterThan(0).canonical(integers()));
- assertEquals(Range.atLeast(Integer.MIN_VALUE), Range.<Integer>all().canonical(integers()));
+ assertEquals(Ranges.atLeast(Integer.MIN_VALUE), Ranges.<Integer>all().canonical(integers()));
}
public void testCanonical_unboundedDomain() {
- assertEquals(Range.lessThan(0), Range.lessThan(0).canonical(UNBOUNDED_DOMAIN));
- assertEquals(Range.lessThan(1), Range.atMost(0).canonical(UNBOUNDED_DOMAIN));
- assertEquals(Range.atLeast(0), Range.atLeast(0).canonical(UNBOUNDED_DOMAIN));
- assertEquals(Range.atLeast(1), Range.greaterThan(0).canonical(UNBOUNDED_DOMAIN));
-
- assertEquals(Range.all(), Range.<Integer>all().canonical(UNBOUNDED_DOMAIN));
- }
-
- public void testEncloseAll() {
- assertEquals(Range.closed(0, 0), Range.encloseAll(Arrays.asList(0)));
- assertEquals(Range.closed(-3, 5), Range.encloseAll(Arrays.asList(5, -3)));
- assertEquals(Range.closed(-3, 5), Range.encloseAll(Arrays.asList(1, 2, 2, 2, 5, -3, 0, -1)));
- }
-
- public void testEncloseAll_empty() {
- try {
- Range.encloseAll(ImmutableSet.<Integer>of());
- fail();
- } catch (NoSuchElementException expected) {}
- }
+ assertEquals(Ranges.lessThan(0), Ranges.lessThan(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Ranges.lessThan(1), Ranges.atMost(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Ranges.atLeast(0), Ranges.atLeast(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Ranges.atLeast(1), Ranges.greaterThan(0).canonical(UNBOUNDED_DOMAIN));
- public void testEncloseAll_nullValue() {
- List<Integer> nullFirst = Lists.newArrayList(null, 0);
- try {
- Range.encloseAll(nullFirst);
- fail();
- } catch (NullPointerException expected) {}
- List<Integer> nullNotFirst = Lists.newArrayList(0, null);
- try {
- Range.encloseAll(nullNotFirst);
- fail();
- } catch (NullPointerException expected) {}
- }
-
- public void testEquivalentFactories() {
- new EqualsTester()
- .addEqualityGroup(Range.all())
- .addEqualityGroup(
- Range.atLeast(1),
- Range.downTo(1, CLOSED))
- .addEqualityGroup(
- Range.greaterThan(1),
- Range.downTo(1, OPEN))
- .addEqualityGroup(
- Range.atMost(7),
- Range.upTo(7, CLOSED))
- .addEqualityGroup(
- Range.lessThan(7),
- Range.upTo(7, OPEN))
- .addEqualityGroup(
- Range.open(1, 7),
- Range.range(1, OPEN, 7, OPEN))
- .addEqualityGroup(
- Range.openClosed(1, 7),
- Range.range(1, OPEN, 7, CLOSED))
- .addEqualityGroup(
- Range.closed(1, 7),
- Range.range(1, CLOSED, 7, CLOSED))
- .addEqualityGroup(
- Range.closedOpen(1, 7),
- Range.range(1, CLOSED, 7, OPEN))
- .testEquals();
+ assertEquals(Ranges.all(), Ranges.<Integer>all().canonical(UNBOUNDED_DOMAIN));
}
}
diff --git a/guava-tests/test/com/google/common/collect/RangesTest.java b/guava-tests/test/com/google/common/collect/RangesTest.java
index 54a1074..a7caf67 100644
--- a/guava-tests/test/com/google/common/collect/RangesTest.java
+++ b/guava-tests/test/com/google/common/collect/RangesTest.java
@@ -32,7 +32,6 @@ import java.util.NoSuchElementException;
* @author Gregory Kick
*/
@GwtCompatible
-@SuppressWarnings("deprecation") // since Ranges is deprecated
public class RangesTest extends TestCase {
public void testSingleton() {
assertEquals(Ranges.closed(0, 0), Ranges.singleton(0));
diff --git a/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java b/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java
index 3cfa363..13332a5 100644
--- a/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,15 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.RegularImmutableTable.DenseImmutableTable;
import com.google.common.collect.RegularImmutableTable.SparseImmutableTable;
import com.google.common.collect.Table.Cell;
/**
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
-@GwtCompatible
public class RegularImmutableTableTest extends AbstractImmutableTableTest {
private static final ImmutableSet<Cell<Character, Integer, String>> CELLS =
ImmutableSet.of(
@@ -41,11 +39,11 @@ public class RegularImmutableTableTest extends AbstractImmutableTableTest {
ImmutableSet.of(1, 2);
private static final SparseImmutableTable<Character, Integer, String> SPARSE =
- new SparseImmutableTable<Character, Integer, String>(CELLS.asList(), ROW_SPACE,
+ new SparseImmutableTable<Character, Integer, String>(CELLS, ROW_SPACE,
COLUMN_SPACE);
private static final DenseImmutableTable<Character, Integer, String> DENSE =
- new DenseImmutableTable<Character, Integer, String>(CELLS.asList(), ROW_SPACE,
+ new DenseImmutableTable<Character, Integer, String>(CELLS, ROW_SPACE,
COLUMN_SPACE);
@Override Iterable<ImmutableTable<Character, Integer, String>>
@@ -64,9 +62,8 @@ public class RegularImmutableTableTest extends AbstractImmutableTableTest {
public void testValues() {
for (ImmutableTable<Character, Integer, String> testInstance :
getTestInstances()) {
- ASSERT.that(testInstance.values())
- .has().allOf("foo", "bar", "baz")
- .inOrder();
+ ASSERT.that(testInstance.values()).hasContentsInOrder("foo", "bar",
+ "baz");
}
}
diff --git a/guava-tests/test/com/google/common/collect/SetOperationsTest.java b/guava-tests/test/com/google/common/collect/SetOperationsTest.java
index 474d9f7..4b43c0a 100644
--- a/guava-tests/test/com/google/common/collect/SetOperationsTest.java
+++ b/guava-tests/test/com/google/common/collect/SetOperationsTest.java
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.TestStringSetGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -39,9 +38,8 @@ import java.util.Set;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class SetOperationsTest extends TestCase {
- @GwtIncompatible("suite")
public static Test suite() {
TestSuite suite = new TestSuite();
diff --git a/guava-tests/test/com/google/common/collect/SetsTest.java b/guava-tests/test/com/google/common/collect/SetsTest.java
index d99129d..4dc847b 100644
--- a/guava-tests/test/com/google/common/collect/SetsTest.java
+++ b/guava-tests/test/com/google/common/collect/SetsTest.java
@@ -20,22 +20,21 @@ import static com.google.common.collect.Iterables.unmodifiableIterable;
import static com.google.common.collect.Sets.newEnumSet;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.powerSet;
-import static com.google.common.collect.Sets.unmodifiableNavigableSet;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod;
import static java.io.ObjectStreamConstants.TC_REFERENCE;
import static java.io.ObjectStreamConstants.baseWireHandle;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.testing.AnEnum;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.MinimalIterable;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.SafeTreeSet;
import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.TestEnumSetGenerator;
import com.google.common.collect.testing.TestStringSetGenerator;
@@ -70,12 +69,10 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
-import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.Nullable;
@@ -174,36 +171,6 @@ public class SetsTest extends TestCase {
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SafeTreeSet<String> set = new SafeTreeSet<String>(Arrays.asList(elements));
- return Sets.unmodifiableNavigableSet(set);
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .named("Sets.unmodifiableNavigableSet[TreeSet]")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SafeTreeSet<String> set = new SafeTreeSet<String>(Arrays.asList(elements));
- return SerializableTester.reserialize(Sets.unmodifiableNavigableSet(set));
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .named("Sets.unmodifiableNavigableSet[TreeSet], reserialized")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
suite.addTest(testsForFilter());
suite.addTest(testsForFilterNoNulls());
suite.addTest(testsForFilterFiltered());
@@ -234,8 +201,7 @@ public class SetsTest extends TestCase {
@GwtIncompatible("suite")
private static Test testsForFilterNoNulls() {
- TestSuite suite = new TestSuite();
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ return SetTestSuiteBuilder.using(new TestStringSetGenerator() {
@Override public Set<String> create(String[] elements) {
Set<String> unfiltered = Sets.newLinkedHashSet();
unfiltered.add("yyy");
@@ -251,30 +217,7 @@ public class SetsTest extends TestCase {
CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_QUERIES)
.suppressing(getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override public NavigableSet<String> create(String[] elements) {
- NavigableSet<String> unfiltered = Sets.newTreeSet();
- unfiltered.add("yyy");
- unfiltered.addAll(ImmutableList.copyOf(elements));
- unfiltered.add("zzz");
- return Sets.filter(unfiltered, Collections2Test.LENGTH_1);
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .named("Sets.filter[NavigableSet]")
- .withFeatures(
- SetFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .suppressing(getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- return suite;
+ .createTestSuite();
}
@GwtIncompatible("suite")
@@ -306,7 +249,7 @@ public class SetsTest extends TestCase {
public void testImmutableEnumSet() {
Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B);
- ASSERT.that(units).has().allOf(SomeEnum.B, SomeEnum.D).inOrder();
+ ASSERT.that(units).hasContentsInOrder(SomeEnum.B, SomeEnum.D);
try {
units.remove(SomeEnum.B);
fail("ImmutableEnumSet should throw an exception on remove()");
@@ -321,7 +264,7 @@ public class SetsTest extends TestCase {
public void testImmutableEnumSet_serialized() {
Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B);
- ASSERT.that(units).has().allOf(SomeEnum.B, SomeEnum.D).inOrder();
+ ASSERT.that(units).hasContentsInOrder(SomeEnum.B, SomeEnum.D);
Set<SomeEnum> copy = SerializableTester.reserializeAndAssert(units);
assertTrue(copy instanceof ImmutableEnumSet);
@@ -330,15 +273,15 @@ public class SetsTest extends TestCase {
public void testImmutableEnumSet_fromIterable() {
ImmutableSet<SomeEnum> none
= Sets.immutableEnumSet(MinimalIterable.<SomeEnum>of());
- ASSERT.that(none).isEmpty();
+ ASSERT.that(none).hasContentsInOrder();
ImmutableSet<SomeEnum> one
= Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.B));
- ASSERT.that(one).has().item(SomeEnum.B);
+ ASSERT.that(one).hasContentsInOrder(SomeEnum.B);
ImmutableSet<SomeEnum> two
= Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.D, SomeEnum.B));
- ASSERT.that(two).has().allOf(SomeEnum.B, SomeEnum.D).inOrder();
+ ASSERT.that(two).hasContentsInOrder(SomeEnum.B, SomeEnum.D);
}
@GwtIncompatible("java serialization not supported in GWT.")
@@ -483,7 +426,7 @@ public class SetsTest extends TestCase {
assertTrue(set.isEmpty());
set.add(new Derived("foo"));
set.add(new Derived("bar"));
- ASSERT.that(set).has().allOf(new Derived("bar"), new Derived("foo")).inOrder();
+ ASSERT.that(set).hasContentsInOrder(new Derived("bar"), new Derived("foo"));
}
public void testNewTreeSetEmptyNonGeneric() {
@@ -491,8 +434,7 @@ public class SetsTest extends TestCase {
assertTrue(set.isEmpty());
set.add(new LegacyComparable("foo"));
set.add(new LegacyComparable("bar"));
- ASSERT.that(set).has()
- .allOf(new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
+ ASSERT.that(set).hasContentsInOrder(new LegacyComparable("bar"), new LegacyComparable("foo"));
}
public void testNewTreeSetFromCollection() {
@@ -509,16 +451,16 @@ public class SetsTest extends TestCase {
Iterable<Derived> iterable =
Arrays.asList(new Derived("foo"), new Derived("bar"));
TreeSet<Derived> set = Sets.newTreeSet(iterable);
- ASSERT.that(set).has().allOf(
- new Derived("bar"), new Derived("foo")).inOrder();
+ ASSERT.that(set).hasContentsInOrder(
+ new Derived("bar"), new Derived("foo"));
}
public void testNewTreeSetFromIterableNonGeneric() {
Iterable<LegacyComparable> iterable =
Arrays.asList(new LegacyComparable("foo"), new LegacyComparable("bar"));
TreeSet<LegacyComparable> set = Sets.newTreeSet(iterable);
- ASSERT.that(set).has().allOf(
- new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
+ ASSERT.that(set).hasContentsInOrder(
+ new LegacyComparable("bar"), new LegacyComparable("foo"));
}
public void testNewTreeSetEmptyWithComparator() {
@@ -537,18 +479,6 @@ public class SetsTest extends TestCase {
assertEquals(2, set.size());
}
- @GwtIncompatible("CopyOnWriteArraySet")
- public void testNewCOWASEmpty() {
- CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet();
- verifySetContents(set, EMPTY_COLLECTION);
- }
-
- @GwtIncompatible("CopyOnWriteArraySet")
- public void testNewCOWASFromIterable() {
- CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet(SOME_ITERABLE);
- verifySetContents(set, SOME_COLLECTION);
- }
-
public void testComplementOfEnumSet() {
Set<SomeEnum> units = EnumSet.of(SomeEnum.B, SomeEnum.D);
EnumSet<SomeEnum> otherUnits = Sets.complementOf(units);
@@ -600,11 +530,15 @@ public class SetsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() {
- new NullPointerTester()
- .setDefault(Enum.class, SomeEnum.A)
- .setDefault(Class.class, SomeEnum.class) // for newEnumSet
- .testAllPublicStaticMethods(Sets.class);
+ public void testNullPointerExceptions() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Enum.class, SomeEnum.A);
+
+ // TODO: make NPT create empty arrays for defaults automatically
+ tester.setDefault(Collection[].class, new Collection[0]);
+ tester.setDefault(Enum[].class, new Enum[0]);
+ tester.setDefault(Set[].class, new Set[0]);
+ tester.testAllPublicStaticMethods(Sets.class);
}
public void testNewSetFromMap() {
@@ -619,7 +553,7 @@ public class SetsTest extends TestCase {
Sets.newSetFromMap(new LinkedHashMap<Integer, Boolean>());
set.addAll(SOME_COLLECTION);
Set<Integer> copy = SerializableTester.reserializeAndAssert(set);
- ASSERT.that(copy).has().allOf(0, 1).inOrder();
+ ASSERT.that(copy).hasContentsInOrder(0, 1);
}
public void testNewSetFromMapIllegal() {
@@ -639,7 +573,7 @@ public class SetsTest extends TestCase {
*/
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_zeroary() {
- ASSERT.that(Sets.cartesianProduct()).has().allOf(list());
+ ASSERT.that(Sets.cartesianProduct()).hasContentsAnyOrder(list());
}
/**
@@ -648,7 +582,7 @@ public class SetsTest extends TestCase {
*/
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_unary() {
- ASSERT.that(Sets.cartesianProduct(set(1, 2))).has().allOf(list(1), list(2));
+ ASSERT.that(Sets.cartesianProduct(set(1, 2))).hasContentsAnyOrder(list(1), list(2));
}
@SuppressWarnings("unchecked") // varargs!
@@ -677,26 +611,26 @@ public class SetsTest extends TestCase {
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_binary1x1() {
- ASSERT.that(Sets.cartesianProduct(set(1), set(2))).has().item(list(1, 2));
+ ASSERT.that(Sets.cartesianProduct(set(1), set(2))).hasContentsAnyOrder(list(1, 2));
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_binary1x2() {
- ASSERT.that(Sets.cartesianProduct(set(1), set(2, 3)))
- .has().allOf(list(1, 2), list(1, 3)).inOrder();
+ ASSERT.that(Sets.cartesianProduct(set(1), set(2, 3))).hasContentsAnyOrder(
+ list(1, 2), list(1, 3));
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_binary2x2() {
- ASSERT.that(Sets.cartesianProduct(set(1, 2), set(3, 4)))
- .has().allOf(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder();
+ ASSERT.that(Sets.cartesianProduct(set(1, 2), set(3, 4))).hasContentsAnyOrder(
+ list(1, 3), list(1, 4), list(2, 3), list(2, 4));
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_2x2x2() {
- ASSERT.that(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))).has().allOf(
+ ASSERT.that(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))).hasContentsAnyOrder(
list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1),
- list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder();
+ list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1));
}
@SuppressWarnings("unchecked") // varargs!
@@ -719,14 +653,14 @@ public class SetsTest extends TestCase {
List<Object> exp3 = list((Object) 2, "3");
List<Object> exp4 = list((Object) 2, "4");
- ASSERT.that(Sets.<Object>cartesianProduct(x, y)).has().allOf(exp1, exp2, exp3, exp4).inOrder();
+ ASSERT.that(Sets.<Object>cartesianProduct(x, y)).hasContentsAnyOrder(exp1, exp2, exp3, exp4);
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProductTooBig() {
- Set<Integer> set = Range.closed(0, 10000).asSet(DiscreteDomain.integers());
+ Set<Integer> set = Ranges.closed(0, 10000).asSet(DiscreteDomains.integers());
try {
- Sets.cartesianProduct(set, set, set, set, set);
+ Set<List<Integer>> productSet = Sets.cartesianProduct(set, set, set, set, set);
fail("Expected IAE");
} catch (IllegalArgumentException expected) {}
}
@@ -1063,113 +997,105 @@ public class SetsTest extends TestCase {
private static final long serialVersionUID = 0;
}
- @GwtIncompatible("NavigableSet")
- public void testUnmodifiableNavigableSet() {
- TreeSet<Integer> mod = Sets.newTreeSet();
- mod.add(1);
- mod.add(2);
- mod.add(3);
-
- NavigableSet<Integer> unmod = unmodifiableNavigableSet(mod);
-
- /* Unmodifiable is a view. */
- mod.add(4);
- assertTrue(unmod.contains(4));
- assertTrue(unmod.descendingSet().contains(4));
+ public void testFilterFiltered() {
+ Set<String> unfiltered = Sets.newHashSet();
+ Set<String> filtered = Sets.filter(
+ Sets.filter(unfiltered, Collections2Test.LENGTH_1),
+ Collections2Test.STARTS_WITH_VOWEL);
+ unfiltered.add("a");
+ unfiltered.add("b");
+ unfiltered.add("apple");
+ unfiltered.add("banana");
+ unfiltered.add("e");
+ assertEquals(ImmutableSet.of("a", "e"), filtered);
+ assertEquals(ImmutableSet.of("a", "b", "apple", "banana", "e"), unfiltered);
- ensureNotDirectlyModifiable(unmod);
- ensureNotDirectlyModifiable(unmod.descendingSet());
- ensureNotDirectlyModifiable(unmod.headSet(2));
- ensureNotDirectlyModifiable(unmod.headSet(2, true));
- ensureNotDirectlyModifiable(unmod.tailSet(2));
- ensureNotDirectlyModifiable(unmod.tailSet(2, true));
- ensureNotDirectlyModifiable(unmod.subSet(1, 3));
- ensureNotDirectlyModifiable(unmod.subSet(1, true, 3, true));
-
- /* UnsupportedOperationException on indirect modifications. */
- NavigableSet<Integer> reverse = unmod.descendingSet();
- try {
- reverse.add(4);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
try {
- reverse.addAll(Collections.singleton(4));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
+ filtered.add("d");
+ fail();
+ } catch (IllegalArgumentException expected) {}
try {
- reverse.remove(4);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
+ filtered.add("egg");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableSet.of("a", "e"), filtered);
+ assertEquals(ImmutableSet.of("a", "b", "apple", "banana", "e"), unfiltered);
+
+ filtered.clear();
+ assertTrue(filtered.isEmpty());
+ assertEquals(ImmutableSet.of("b", "apple", "banana"), unfiltered);
}
- void ensureNotDirectlyModifiable(SortedSet<Integer> unmod) {
- try {
- unmod.add(4);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- unmod.remove(4);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- unmod.addAll(Collections.singleton(4));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- Iterator<Integer> iterator = unmod.iterator();
- iterator.next();
- iterator.remove();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+ public void testFilterSorted() {
+ SortedSet<Long> sorted = Sets.newTreeSet();
+ for (long i = 1; i < 11; i++) {
+ sorted.add(i);
}
+ SortedSet<Long> filteredEven = Sets.filter(sorted, new Predicate<Long>() {
+ @Override
+ public boolean apply(Long input) {
+ return input % 2 == 0;
+ }
+ });
+
+ assertEquals("filteredSortedSet", ImmutableSet.of(2L, 4L, 6L, 8L, 10L), filteredEven);
+ assertEquals("First", 2L, filteredEven.first().longValue());
+ assertEquals("Last", 10L, filteredEven.last().longValue());
+ assertEquals("subSet", ImmutableSet.of(4L, 6L), filteredEven.subSet(4L, 8L));
+ assertEquals("headSet", ImmutableSet.of(2L, 4L), filteredEven.headSet(5L));
+ assertEquals("tailSet", ImmutableSet.of(8L, 10L), filteredEven.tailSet(7L));
+ assertEquals("comparator", sorted.comparator(), filteredEven.comparator());
+
+ sorted.add(12L);
+ sorted.add(0L);
+ assertEquals("addingElementsToSet", ImmutableSet.of(0L, 2L, 4L, 6L, 8L, 10L, 12L),
+ filteredEven);
+ assertEquals("FirstOnModifiedSortedSet", 0L, filteredEven.first().longValue());
+ assertEquals("LastOnModifiedSortedSet", 12L, filteredEven.last().longValue());
}
- @GwtIncompatible("NavigableSet")
- void ensureNotDirectlyModifiable(NavigableSet<Integer> unmod) {
- try {
- unmod.add(4);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- unmod.remove(4);
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
- try {
- unmod.addAll(Collections.singleton(4));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
+ static SortedSet<Long> filteredEmpty = Sets.filter(new TreeSet<Long>(), Predicates.alwaysTrue());
+ public void testFilteredSortedEmpty_size() {
+ assertEquals("filterEmptySize", 0, filteredEmpty.size());
+ }
+
+ public void testFilteredSortedEmpty_first() {
try {
- unmod.pollFirst();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
+ filteredEmpty.first();
+ fail("CallFirstOnEmptySetThrowsException");
+ } catch (NoSuchElementException expected) {}
+ }
+
+ public void testFilteredSortedEmpty_last() {
try {
- unmod.pollLast();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
+ filteredEmpty.last();
+ fail("CallLastOnEmptySetThrowsException");
+ } catch (NoSuchElementException expected) {}
+ }
+
+ static SortedSet<Long> sorted = Sets.newTreeSet();
+ static {
+ for (long i = 1; i < 11; i++) {
+ sorted.add(i);
}
+ }
+ static SortedSet<Long> filterAllElements = Sets.filter(sorted, Predicates.alwaysFalse());
+
+ public void testFilteredSortedAllFiltered_size() {
+ assertEquals("filterAllElementsSize", 0, filterAllElements.size());
+ }
+
+ public void testFilteredSortedAllFiltered_first() {
try {
- Iterator<Integer> iterator = unmod.iterator();
- iterator.next();
- iterator.remove();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
+ filterAllElements.first();
+ fail("CallFirstOnSetWithAllElementsFilteredThrowsException");
+ } catch (NoSuchElementException expected) {}
+ }
+
+ public void testFilteredSortedAllFiltered_last() {
try {
- Iterator<Integer> iterator = unmod.descendingIterator();
- iterator.next();
- iterator.remove();
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {
- }
+ filterAllElements.last();
+ fail("CallLastOnSetWithAllElementsFilteredThrowsException");
+ } catch (NoSuchElementException expected) {}
}
}
diff --git a/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java b/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java
index 60eaec8..608fbae 100644
--- a/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2007 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -17,14 +17,13 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.Multiset.Entry;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.annotation.Nullable;
-
/**
* Unit test for {@link AbstractMultiset}.
*
@@ -68,7 +67,7 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest {
implements Serializable {
final Map<E, Integer> backingMap = Maps.newHashMap();
- @Override public int add(@Nullable E element, int occurrences) {
+ @Override public int add(E element, int occurrences) {
checkArgument(occurrences >= 0);
Integer frequency = backingMap.get(element);
if (frequency == null) {
@@ -123,7 +122,7 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest {
private static class SimpleAbstractMultiset<E> extends NoRemoveMultiset<E> {
@SuppressWarnings("unchecked")
- @Override public int remove(@Nullable Object element, int occurrences) {
+ @Override public int remove(Object element, int occurrences) {
checkArgument(occurrences >= 0);
Integer count = backingMap.get(element);
if (count == null) {
diff --git a/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java b/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java
index 395be9c..36b8159 100644
--- a/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,19 +16,16 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.testing.EqualsTester;
/**
* Tests {@link SingletonImmutableTable}.
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
-@GwtCompatible(emulated = true)
public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
private final ImmutableTable<Character, Integer, String> testTable =
new SingletonImmutableTable<Character, Integer, String>('a', 1, "blah");
@@ -38,7 +35,8 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
}
public void testCellSet() {
- assertEquals(ImmutableSet.of(Tables.immutableCell('a', 1, "blah")), testTable.cellSet());
+ assertEquals(ImmutableSet.of(Tables.immutableCell('a', 1, "blah")),
+ testTable.cellSet());
}
public void testColumn() {
@@ -51,7 +49,8 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
}
public void testColumnMap() {
- assertEquals(ImmutableMap.of(1, ImmutableMap.of('a', "blah")), testTable.columnMap());
+ assertEquals(ImmutableMap.of(1, ImmutableMap.of('a', "blah")),
+ testTable.columnMap());
}
public void testRow() {
@@ -70,20 +69,14 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
public void testEqualsObject() {
new EqualsTester()
- .addEqualityGroup(testTable, HashBasedTable.create(testTable))
- .addEqualityGroup(EmptyImmutableTable.INSTANCE, HashBasedTable.create())
+ .addEqualityGroup(testTable, ArrayTable.create(testTable),
+ HashBasedTable.create(testTable))
+ .addEqualityGroup(EmptyImmutableTable.INSTANCE,
+ HashBasedTable.create())
.addEqualityGroup(HashBasedTable.create(ImmutableTable.of('A', 2, "")))
.testEquals();
}
- @GwtIncompatible("ArrayTable")
- public void testEqualsObjectNullValues() {
- new EqualsTester()
- .addEqualityGroup(testTable)
- .addEqualityGroup(ArrayTable.create(ImmutableSet.of('A'), ImmutableSet.of(1)))
- .testEquals();
- }
-
public void testToString() {
assertEquals("{a={1=blah}}", testTable.toString());
}
@@ -126,10 +119,11 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
}
public void testValues() {
- ASSERT.that(testTable.values()).has().item("blah");
+ ASSERT.that(testTable.values()).hasContentsInOrder("blah");
}
- @Override Iterable<ImmutableTable<Character, Integer, String>> getTestInstances() {
+ @Override Iterable<ImmutableTable<Character, Integer, String>>
+ getTestInstances() {
return ImmutableSet.of(testTable);
}
}
diff --git a/guava-tests/test/com/google/common/collect/SortedIterablesTest.java b/guava-tests/test/com/google/common/collect/SortedIterablesTest.java
index d3a50f8..e16a75a 100644
--- a/guava-tests/test/com/google/common/collect/SortedIterablesTest.java
+++ b/guava-tests/test/com/google/common/collect/SortedIterablesTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -14,19 +14,43 @@
package com.google.common.collect;
+import static org.junit.contrib.truth.Truth.ASSERT;
+
import com.google.common.annotations.GwtCompatible;
import junit.framework.TestCase;
+import java.util.Arrays;
+import java.util.List;
import java.util.SortedSet;
/**
* Unit tests for {@code SortedIterables}.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible
public class SortedIterablesTest extends TestCase {
+ @SuppressWarnings("unchecked")
+ public void testSortedCounts() {
+ List<Integer> list = Arrays.asList(3, 9, 8, 4, 5, 2, 2, 8);
+ ASSERT.that(SortedIterables.sortedCounts(Ordering.natural(), list))
+ .hasContentsInOrder(
+ Multisets.immutableEntry(2, 2), Multisets.immutableEntry(3, 1),
+ Multisets.immutableEntry(4, 1), Multisets.immutableEntry(5, 1),
+ Multisets.immutableEntry(8, 2), Multisets.immutableEntry(9, 1));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testSortedCountsIterator() {
+ List<Integer> list = Arrays.asList(3, 9, 8, 4, 5, 2, 2, 8);
+ ASSERT.that(SortedIterables.sortedCounts(Ordering.natural(), list.iterator()))
+ .hasContentsInOrder(
+ Multisets.immutableEntry(2, 2), Multisets.immutableEntry(3, 1),
+ Multisets.immutableEntry(4, 1), Multisets.immutableEntry(5, 1),
+ Multisets.immutableEntry(8, 2), Multisets.immutableEntry(9, 1));
+ }
+
public void testSameComparator() {
assertTrue(SortedIterables.hasSameComparator(Ordering.natural(), Sets.newTreeSet()));
// Before JDK6 (including under GWT), the TreeMap keySet is a plain Set.
@@ -37,8 +61,4 @@ public class SortedIterablesTest extends TestCase {
assertTrue(SortedIterables.hasSameComparator(Ordering.natural().reverse(),
Sets.newTreeSet(Ordering.natural().reverse())));
}
-
- public void testComparator() {
- assertEquals(Ordering.natural(), SortedIterables.comparator(Sets.newTreeSet()));
- }
}
diff --git a/guava-tests/test/com/google/common/collect/SortedListsTest.java b/guava-tests/test/com/google/common/collect/SortedListsTest.java
index 02b259a..884f5f9 100644
--- a/guava-tests/test/com/google/common/collect/SortedListsTest.java
+++ b/guava-tests/test/com/google/common/collect/SortedListsTest.java
@@ -16,6 +16,8 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
import com.google.common.collect.SortedLists.KeyAbsentBehavior;
import com.google.common.collect.SortedLists.KeyPresentBehavior;
import com.google.common.testing.NullPointerTester;
@@ -117,7 +119,13 @@ public class SortedListsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(SortedLists.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Function.class, Functions.identity());
+ tester.setDefault(List.class, LIST_WITH_DUPS);
+ tester.setDefault(Comparable.class, 2);
+ tester.setDefault(KeyPresentBehavior.class, KeyPresentBehavior.ANY_PRESENT);
+ tester.setDefault(KeyAbsentBehavior.class, KeyAbsentBehavior.NEXT_HIGHER);
+ tester.testAllPublicStaticMethods(SortedLists.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/SortedMapsTest.java b/guava-tests/test/com/google/common/collect/SortedMapsTest.java
new file mode 100644
index 0000000..5529521
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/SortedMapsTest.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static org.junit.contrib.truth.Truth.ASSERT;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Maps.EntryTransformer;
+import com.google.common.collect.testing.SortedMapInterfaceTest;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+
+/**
+ * Tests for SortedMaps.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+@SuppressWarnings("deprecation")
+public class SortedMapsTest extends TestCase {
+
+ private static final EntryTransformer<Object, Object, Object> ALWAYS_NULL =
+ new EntryTransformer<Object, Object, Object>() {
+ @Override
+ public Object transformEntry(Object k, Object v1) {
+ return null;
+ }
+ };
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointer() throws Exception {
+ NullPointerTester nullPointerTester = new NullPointerTester();
+ nullPointerTester.setDefault(EntryTransformer.class, ALWAYS_NULL);
+ nullPointerTester.setDefault(
+ SortedMap.class, Maps.<String, String>newTreeMap());
+ nullPointerTester.testAllPublicStaticMethods(SortedMaps.class);
+ }
+
+ public void testTransformSortedValues() {
+ SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
+ Function<Integer, Double> sqrt = new Function<Integer, Double>() {
+ @Override
+ public Double apply(Integer in) {
+ return Math.sqrt(in);
+ }
+ };
+ SortedMap<String, Double> transformed =
+ SortedMaps.transformValues(map, sqrt);
+
+ assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
+ }
+
+ public void testTransformSortedEntries() {
+ SortedMap<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
+ EntryTransformer<String, String, String> concat =
+ new EntryTransformer<String, String, String>() {
+ @Override
+ public String transformEntry(String key, String value) {
+ return key + value;
+ }
+ };
+ SortedMap<String, String> transformed =
+ SortedMaps.transformEntries(map, concat);
+
+ assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
+ }
+
+ // Not testing Map methods of SortedMaps.filter*, since the implementation
+ // doesn't override Maps.FilteredEntryMap, which is already tested.
+
+ private static final Predicate<Integer> EVEN =
+ new Predicate<Integer>() {
+ @Override
+ public boolean apply(Integer input) {
+ return input % 2 == 0;
+ }
+ };
+
+ public void testFilterKeys() {
+ Comparator<Integer> comparator = Ordering.natural();
+ SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
+ unfiltered.put(1, "one");
+ unfiltered.put(2, "two");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ unfiltered.put(6, "six");
+ unfiltered.put(7, "seven");
+ SortedMap<Integer, String> filtered
+ = SortedMaps.filterKeys(unfiltered, EVEN);
+ ASSERT.that(filtered.keySet()).hasContentsInOrder(2, 4, 6);
+ assertSame(comparator, filtered.comparator());
+ assertEquals((Integer) 2, filtered.firstKey());
+ assertEquals((Integer) 6, filtered.lastKey());
+ ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(2, 4);
+ ASSERT.that(filtered.tailMap(3).keySet()).hasContentsInOrder(4, 6);
+ ASSERT.that(filtered.subMap(3, 5).keySet()).hasContentsInOrder(4);
+ }
+
+ private static final Predicate<String> NOT_LENGTH_3 =
+ new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input == null || input.length() != 3;
+ }
+ };
+
+ public void testFilterValues() {
+ Comparator<Integer> comparator = Ordering.natural();
+ SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
+ unfiltered.put(1, "one");
+ unfiltered.put(2, "two");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ unfiltered.put(6, "six");
+ unfiltered.put(7, "seven");
+ SortedMap<Integer, String> filtered
+ = SortedMaps.filterValues(unfiltered, NOT_LENGTH_3);
+ ASSERT.that(filtered.keySet()).hasContentsInOrder(3, 4, 5, 7);
+ assertSame(comparator, filtered.comparator());
+ assertEquals((Integer) 3, filtered.firstKey());
+ assertEquals((Integer) 7, filtered.lastKey());
+ ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(3, 4);
+ ASSERT.that(filtered.tailMap(4).keySet()).hasContentsInOrder(4, 5, 7);
+ ASSERT.that(filtered.subMap(4, 6).keySet()).hasContentsInOrder(4, 5);
+ }
+
+ private static final Predicate<Map.Entry<Integer, String>>
+ EVEN_AND_LENGTH_3 = new Predicate<Map.Entry<Integer, String>>() {
+ @Override public boolean apply(Entry<Integer, String> entry) {
+ return (entry.getKey() == null || entry.getKey() % 2 == 0)
+ && (entry.getValue() == null || entry.getValue().length() == 3);
+ }
+ };
+
+ private static class ContainsKeySafeSortedMap
+ extends ForwardingSortedMap<Integer, String> {
+ SortedMap<Integer, String> delegate
+ = Maps.newTreeMap(Ordering.natural().nullsFirst());
+
+ @Override protected SortedMap<Integer, String> delegate() {
+ return delegate;
+ }
+
+ // Needed by MapInterfaceTest.testContainsKey()
+ @Override public boolean containsKey(Object key) {
+ try {
+ return super.containsKey(key);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+ }
+
+ public static class FilteredEntriesSortedMapInterfaceTest
+ extends SortedMapInterfaceTest<Integer, String> {
+ public FilteredEntriesSortedMapInterfaceTest() {
+ super(true, true, true, true, true);
+ }
+
+ @Override protected SortedMap<Integer, String> makeEmptyMap() {
+ SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
+ unfiltered.put(1, "one");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ return SortedMaps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
+ }
+
+ @Override protected SortedMap<Integer, String> makePopulatedMap() {
+ SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
+ unfiltered.put(1, "one");
+ unfiltered.put(2, "two");
+ unfiltered.put(3, "three");
+ unfiltered.put(4, "four");
+ unfiltered.put(5, "five");
+ unfiltered.put(6, "six");
+ return SortedMaps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
+ }
+
+ @Override protected Integer getKeyNotInPopulatedMap() {
+ return 10;
+ }
+
+ @Override protected String getValueNotInPopulatedMap() {
+ return "ten";
+ }
+
+ // Iterators don't support remove.
+ @Override public void testEntrySetIteratorRemove() {}
+ @Override public void testValuesIteratorRemove() {}
+
+ // These tests fail on GWT.
+ // TODO: Investigate why.
+ @Override public void testEntrySetRemoveAll() {}
+ @Override public void testEntrySetRetainAll() {}
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/SpecialRandom.java b/guava-tests/test/com/google/common/collect/SpecialRandom.java
deleted file mode 100644
index 4b6d827..0000000
--- a/guava-tests/test/com/google/common/collect/SpecialRandom.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Random;
-
-/**
- * Utility class for being able to seed a {@link Random} value with a passed
- * in seed from a benchmark parameter.
- *
- * TODO: Remove this class once Caliper has a better way.
- *
- * @author Nicholaus Shupe
- */
-public final class SpecialRandom extends Random {
- public static SpecialRandom valueOf(String s) {
- return (s.length() == 0)
- ? new SpecialRandom()
- : new SpecialRandom(Long.parseLong(s));
- }
-
- private final boolean hasSeed;
- private final long seed;
-
- public SpecialRandom() {
- this.hasSeed = false;
- this.seed = 0;
- }
-
- public SpecialRandom(long seed) {
- super(seed);
- this.hasSeed = true;
- this.seed = seed;
- }
-
- @Override public String toString() {
- return hasSeed ? "(seed:" + seed : "(default seed)";
- }
-
- private static final long serialVersionUID = 0;
-}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java
index b0efcf0..7e99f71 100644
--- a/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java
@@ -16,20 +16,11 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.collect.Synchronized.SynchronizedBiMap;
import com.google.common.collect.Synchronized.SynchronizedSet;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.BiMapInverseTester;
-import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringBiMapGenerator;
import junit.framework.TestSuite;
-import java.util.Map.Entry;
import java.util.Set;
/**
@@ -41,24 +32,7 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest {
public static TestSuite suite() {
TestSuite suite = new TestSuite(SynchronizedBiMapTest.class);
- suite.addTest(BiMapTestSuiteBuilder.using(new SynchTestingBiMapGenerator())
- .named("Synchronized.biMap[TestBiMap]")
- .withFeatures(CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION)
- .createTestSuite());
- suite.addTest(BiMapTestSuiteBuilder.using(new SynchronizedHashBiMapGenerator())
- .named("synchronizedBiMap[HashBiMap]")
- .withFeatures(CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.SERIALIZABLE)
- .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods())
- .createTestSuite());
+ suite.addTestSuite(AbstractBiMapTests.class);
return suite;
}
@@ -69,34 +43,6 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest {
return outer;
}
- public static final class SynchronizedHashBiMapGenerator extends TestStringBiMapGenerator {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- Object mutex = new Object();
- BiMap<String, String> result = HashBiMap.create();
- for (Entry<String, String> entry : entries) {
- checkArgument(!result.containsKey(entry.getKey()));
- result.put(entry.getKey(), entry.getValue());
- }
- return Maps.synchronizedBiMap(result);
- }
- }
-
- public static final class SynchTestingBiMapGenerator extends TestStringBiMapGenerator {
- @Override
- protected BiMap<String, String> create(Entry<String, String>[] entries) {
- Object mutex = new Object();
- BiMap<String, String> backing =
- new TestBiMap<String, String>(HashBiMap.<String, String>create(), mutex);
- BiMap<String, String> result = Synchronized.biMap(backing, mutex);
- for (Entry<String, String> entry : entries) {
- checkArgument(!result.containsKey(entry.getKey()));
- result.put(entry.getKey(), entry.getValue());
- }
- return result;
- }
- }
-
static class TestBiMap<K, V> extends TestMap<K, V> implements BiMap<K, V> {
private final BiMap<K, V> delegate;
@@ -143,4 +89,26 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest {
assertTrue(values instanceof SynchronizedSet);
assertSame(mutex, ((SynchronizedSet<?>) values).mutex);
}
+
+ public static class AbstractBiMapTests extends AbstractBiMapTest {
+ public final Object mutex = new Integer(1); // something Serializable
+
+ @Override protected BiMap<Integer, String> create() {
+ TestBiMap<Integer, String> inner = new TestBiMap<Integer, String>(
+ HashBiMap.<Integer, String>create(), mutex);
+ BiMap<Integer, String> outer = Synchronized.biMap(inner, mutex);
+ return outer;
+ }
+
+ /**
+ * If you serialize a synchronized bimap and its inverse together, the
+ * reserialized bimaps will have backing maps that stay in sync, as shown
+ * by the {@code testSerializationWithInverseEqual()} test. However, the
+ * inverse of one won't be the same as the other.
+ *
+ * To make them the same, the inverse synchronized bimap would need a custom
+ * serialized form, similar to what {@code AbstractBiMap.Inverse} does.
+ */
+ @Override public void testSerializationWithInverseSame() {}
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java
index 75559be..9e8ee22 100644
--- a/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import java.io.Serializable;
import java.util.Arrays;
@@ -173,11 +173,11 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest {
ArrayListMultimap.<String, Integer>create());
multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
- ASSERT.that(multimap.removeAll("foo")).has().allOf(3, -1, 2, 4, 1).inOrder();
+ ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(3, -1, 2, 4, 1);
assertFalse(multimap.containsKey("foo"));
ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5)))
- .has().allOf(1, 2, 3, 1).inOrder();
- ASSERT.that(multimap.get("bar")).has().allOf(6, 5).inOrder();
+ .hasContentsInOrder(1, 2, 3, 1);
+ ASSERT.that(multimap.get("bar")).hasContentsInOrder(6, 5);
}
public void testSynchronizedSortedSetMultimap() {
@@ -186,11 +186,11 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest {
TreeMultimap.<String, Integer>create());
multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
- ASSERT.that(multimap.removeAll("foo")).has().allOf(-1, 1, 2, 3, 4).inOrder();
+ ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(-1, 1, 2, 3, 4);
assertFalse(multimap.containsKey("foo"));
ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5)))
- .has().allOf(1, 2, 3).inOrder();
- ASSERT.that(multimap.get("bar")).has().allOf(5, 6).inOrder();
+ .hasContentsInOrder(1, 2, 3);
+ ASSERT.that(multimap.get("bar")).hasContentsInOrder(5, 6);
}
public void testSynchronizedArrayListMultimapRandomAccess() {
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java
deleted file mode 100644
index 99370dd..0000000
--- a/guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.collect.Synchronized.SynchronizedNavigableMap;
-import com.google.common.collect.Synchronized.SynchronizedNavigableSet;
-import com.google.common.collect.Synchronized.SynchronizedSortedMap;
-import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
-import com.google.common.collect.testing.SafeTreeMap;
-import com.google.common.collect.testing.TestStringSortedMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestSuite;
-
-import java.io.Serializable;
-import java.util.Comparator;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.SortedMap;
-
-/**
- * Tests for {@link Maps#synchronizedNavigableMap(NavigableMap)}.
- *
- * @author Louis Wasserman
- */
-public class SynchronizedNavigableMapTest extends SynchronizedMapTest {
- @Override protected <K, V> NavigableMap<K, V> create() {
- @SuppressWarnings("unchecked")
- NavigableMap<K, V> innermost = new SafeTreeMap<K, V>(
- (Comparator<? super K>) Ordering.natural().nullsFirst());
- TestMap<K, V> inner = new TestMap<K, V>(innermost, mutex);
- NavigableMap<K, V> outer = Synchronized.navigableMap(inner, mutex);
- return outer;
- }
-
- static class TestEntry<K, V> extends ForwardingMapEntry<K, V>
- implements Serializable {
- private final Entry<K, V> delegate;
- private final Object mutex;
-
- TestEntry(Entry<K, V> delegate, Object mutex) {
- this.delegate = delegate;
- this.mutex = mutex;
- }
-
- @Override protected Entry<K, V> delegate() {
- return delegate;
- }
-
- @Override public boolean equals(Object object) {
- assertTrue(Thread.holdsLock(mutex));
- return super.equals(object);
- }
-
- @Override public K getKey() {
- assertTrue(Thread.holdsLock(mutex));
- return super.getKey();
- }
-
- @Override public V getValue() {
- assertTrue(Thread.holdsLock(mutex));
- return super.getValue();
- }
-
- @Override public int hashCode() {
- assertTrue(Thread.holdsLock(mutex));
- return super.hashCode();
- }
-
- @Override public V setValue(V value) {
- assertTrue(Thread.holdsLock(mutex));
- return super.setValue(value);
- }
-
- private static final long serialVersionUID = 0;
- }
-
- static class TestMap<K, V> extends SynchronizedMapTest.TestMap<K, V>
- implements NavigableMap<K, V> {
-
- public TestMap(NavigableMap<K, V> delegate, Object mutex) {
- super(delegate, mutex);
- }
-
- @Override protected NavigableMap<K, V> delegate() {
- return (NavigableMap<K, V>) super.delegate();
- }
-
- @Override public Entry<K, V> ceilingEntry(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().ceilingEntry(key);
- }
-
- @Override public K ceilingKey(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().ceilingKey(key);
- }
-
- @Override public NavigableSet<K> descendingKeySet() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().descendingKeySet();
- }
-
- @Override public NavigableMap<K, V> descendingMap() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().descendingMap();
- }
-
- @Override public Entry<K, V> firstEntry() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().firstEntry();
- }
-
- @Override public Entry<K, V> floorEntry(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().floorEntry(key);
- }
-
- @Override public K floorKey(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().floorKey(key);
- }
-
- @Override public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().headMap(toKey, inclusive);
- }
-
- @Override public SortedMap<K, V> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override public Entry<K, V> higherEntry(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().higherEntry(key);
- }
-
- @Override public K higherKey(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().higherKey(key);
- }
-
- @Override public Entry<K, V> lastEntry() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().lastEntry();
- }
-
- @Override public Entry<K, V> lowerEntry(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().lowerEntry(key);
- }
-
- @Override public K lowerKey(K key) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().lowerKey(key);
- }
-
- @Override public NavigableSet<K> navigableKeySet() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().navigableKeySet();
- }
-
- @Override public Entry<K, V> pollFirstEntry() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().pollFirstEntry();
- }
-
- @Override public Entry<K, V> pollLastEntry() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().pollLastEntry();
- }
-
- @Override public NavigableMap<K, V> subMap(
- K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive);
- }
-
- @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return delegate().subMap(fromKey, true, toKey, false);
- }
-
- @Override public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().tailMap(fromKey, inclusive);
- }
-
- @Override public SortedMap<K, V> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override public Comparator<? super K> comparator() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().comparator();
- }
-
- @Override public K firstKey() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().firstKey();
- }
-
- @Override public K lastKey() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().lastKey();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(SynchronizedNavigableMapTest.class);
- suite.addTest(
- NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
- private final Object mutex = new Integer(1);
-
- @Override protected SortedMap<String, String> create(
- Entry<String, String>[] entries) {
- NavigableMap<String, String> innermost =
- new SafeTreeMap<String, String>();
- for (Entry<String, String> entry : entries) {
- innermost.put(entry.getKey(), entry.getValue());
- }
- TestMap<String, String> inner =
- new TestMap<String, String>(innermost, mutex);
- NavigableMap<String, String> outer =
- Synchronized.navigableMap(inner, mutex);
- return outer;
- }
- }).named("Maps.synchronizedNavigableMap[SafeTreeMap]")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_VALUES)
- .createTestSuite());
-
- return suite;
- }
-
- public void testComparator() {
- create().comparator();
- }
-
- public void testCeilingEntry() {
- create().ceilingEntry("a");
- }
-
- public void testCeilingKey() {
- create().ceilingKey("a");
- }
-
- public void testDescendingKeySet() {
- NavigableMap<String, Integer> map = create();
- NavigableSet<String> descendingKeySet = map.descendingKeySet();
- assertTrue(descendingKeySet instanceof SynchronizedNavigableSet);
- assertSame(
- mutex, ((SynchronizedNavigableSet<String>) descendingKeySet).mutex);
- }
-
- public void testDescendingMap() {
- NavigableMap<String, Integer> map = create();
- NavigableMap<String, Integer> descendingMap = map.descendingMap();
- assertTrue(descendingMap instanceof SynchronizedNavigableMap);
- assertSame(mutex,
- ((SynchronizedNavigableMap<String, Integer>) descendingMap).mutex);
- }
-
- public void testFirstEntry() {
- create().firstEntry();
- }
-
- public void testFirstKey() {
- NavigableMap<String, Integer> map = create();
- map.put("a", 1);
- map.firstKey();
- }
-
- public void testFloorEntry() {
- create().floorEntry("a");
- }
-
- public void testFloorKey() {
- create().floorKey("a");
- }
-
- public void testHeadMap_K() {
- NavigableMap<String, Integer> map = create();
- SortedMap<String, Integer> headMap = map.headMap("a");
- assertTrue(headMap instanceof SynchronizedSortedMap);
- assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) headMap).mutex);
- }
-
- public void testHeadMap_K_B() {
- NavigableMap<String, Integer> map = create();
- NavigableMap<String, Integer> headMap = map.headMap("a", true);
- assertTrue(headMap instanceof SynchronizedNavigableMap);
- assertSame(
- mutex, ((SynchronizedNavigableMap<String, Integer>) headMap).mutex);
- }
-
- public void testHigherEntry() {
- create().higherEntry("a");
- }
-
- public void testHigherKey() {
- create().higherKey("a");
- }
-
- public void testLastEntry() {
- create().lastEntry();
- }
-
- public void testLastKey() {
- NavigableMap<String, Integer> map = create();
- map.put("a", 1);
- map.lastKey();
- }
-
- public void testLowerEntry() {
- create().lowerEntry("a");
- }
-
- public void testLowerKey() {
- create().lowerKey("a");
- }
-
- public void testNavigableKeySet() {
- NavigableMap<String, Integer> map = create();
- NavigableSet<String> navigableKeySet = map.navigableKeySet();
- assertTrue(navigableKeySet instanceof SynchronizedNavigableSet);
- assertSame(
- mutex, ((SynchronizedNavigableSet<String>) navigableKeySet).mutex);
- }
-
- public void testPollFirstEntry() {
- create().pollFirstEntry();
- }
-
- public void testPollLastEntry() {
- create().pollLastEntry();
- }
-
- public void testSubMap_K_K() {
- NavigableMap<String, Integer> map = create();
- SortedMap<String, Integer> subMap = map.subMap("a", "b");
- assertTrue(subMap instanceof SynchronizedSortedMap);
- assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex);
- }
-
- public void testSubMap_K_B_K_B() {
- NavigableMap<String, Integer> map = create();
- NavigableMap<String, Integer> subMap = map.subMap("a", true, "b", false);
- assertTrue(subMap instanceof SynchronizedNavigableMap);
- assertSame(
- mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex);
- }
-
- public void testTailMap_K() {
- NavigableMap<String, Integer> map = create();
- SortedMap<String, Integer> subMap = map.tailMap("a");
- assertTrue(subMap instanceof SynchronizedSortedMap);
- assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex);
- }
-
- public void testTailMap_K_B() {
- NavigableMap<String, Integer> map = create();
- NavigableMap<String, Integer> subMap = map.tailMap("a", true);
- assertTrue(subMap instanceof SynchronizedNavigableMap);
- assertSame(
- mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex);
- }
-
- @Override public void testSerialization() {
- SerializableTester.reserializeAndAssert(create());
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java b/guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java
deleted file mode 100644
index 9350f62..0000000
--- a/guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.collect.Synchronized.SynchronizedNavigableSet;
-import com.google.common.collect.Synchronized.SynchronizedSortedSet;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.SafeTreeSet;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestSuite;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NavigableSet;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Tests for {@link Sets#synchronizedNavigableSet(NavigableSet)}.
- *
- * @author Louis Wasserman
- */
-public class SynchronizedNavigableSetTest extends SynchronizedSetTest {
- @SuppressWarnings("unchecked")
- @Override protected <E> NavigableSet<E> create() {
- TestSet<E> inner = new TestSet<E>(
- new TreeSet<E>((Comparator<E>) Ordering.natural().nullsFirst()), mutex);
- NavigableSet<E> outer =
- Synchronized.navigableSet(inner, mutex);
- return outer;
- }
-
- static class TestSet<E> extends SynchronizedSetTest.TestSet<E>
- implements NavigableSet<E> {
-
- TestSet(NavigableSet<E> delegate, Object mutex) {
- super(delegate, mutex);
- }
-
- @Override protected NavigableSet<E> delegate() {
- return (NavigableSet<E>) super.delegate();
- }
-
- @Override public E ceiling(E e) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().ceiling(e);
- }
-
- @Override public Iterator<E> descendingIterator() {
- return delegate().descendingIterator();
- }
-
- @Override public NavigableSet<E> descendingSet() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().descendingSet();
- }
-
- @Override public E floor(E e) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().floor(e);
- }
-
- @Override public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().headSet(toElement, inclusive);
- }
-
- @Override public SortedSet<E> headSet(E toElement) {
- return headSet(toElement, false);
- }
-
- @Override public E higher(E e) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().higher(e);
- }
-
- @Override public E lower(E e) {
- return delegate().lower(e);
- }
-
- @Override public E pollFirst() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().pollFirst();
- }
-
- @Override public E pollLast() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().pollLast();
- }
-
- @Override public NavigableSet<E> subSet(E fromElement,
- boolean fromInclusive, E toElement, boolean toInclusive) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().subSet(
- fromElement, fromInclusive, toElement, toInclusive);
- }
-
- @Override public SortedSet<E> subSet(E fromElement, E toElement) {
- return subSet(fromElement, true, toElement, false);
- }
-
- @Override public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().tailSet(fromElement, inclusive);
- }
-
- @Override public SortedSet<E> tailSet(E fromElement) {
- return tailSet(fromElement, true);
- }
-
- @Override public Comparator<? super E> comparator() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().comparator();
- }
-
- @Override public E first() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().first();
- }
-
- @Override public E last() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate().last();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(SynchronizedNavigableSetTest.class);
- suite.addTest(
- NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- private final Object mutex = new Integer(1);
-
- @Override protected Set<String> create(String[] elements) {
- NavigableSet<String> innermost = new SafeTreeSet<String>();
- innermost.addAll(Arrays.asList(elements));
- TestSet<String> inner = new TestSet<String>(innermost, mutex);
- NavigableSet<String> outer =
- Synchronized.navigableSet(inner, mutex);
- return outer;
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- }).named("Sets.synchronizedNavigableSet[SafeTreeSet]")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE).createTestSuite());
-
- return suite;
- }
-
- public void testComparator() {
- create().comparator();
- }
-
- public void testCeiling() {
- create().ceiling("a");
- }
-
- public void testFloor() {
- create().floor("a");
- }
-
- public void testHigher() {
- create().higher("a");
- }
-
- public void testLower() {
- create().lower("a");
- }
-
- public void testDescendingSet() {
- NavigableSet<String> map = create();
- NavigableSet<String> descendingSet = map.descendingSet();
- assertTrue(descendingSet instanceof SynchronizedNavigableSet);
- assertSame(mutex, ((SynchronizedNavigableSet<String>) descendingSet).mutex);
- }
-
- public void testFirst() {
- NavigableSet<String> set = create();
- set.add("a");
- set.first();
- }
-
- public void testPollFirst() {
- create().pollFirst();
- }
-
- public void testLast() {
- NavigableSet<String> set = create();
- set.add("a");
- set.last();
- }
-
- public void testPollLast() {
- create().pollLast();
- }
-
- public void testHeadSet_E() {
- NavigableSet<String> map = create();
- SortedSet<String> headSet = map.headSet("a");
- assertTrue(headSet instanceof SynchronizedSortedSet);
- assertSame(mutex, ((SynchronizedSortedSet<String>) headSet).mutex);
- }
-
- public void testHeadSet_E_B() {
- NavigableSet<String> map = create();
- NavigableSet<String> headSet = map.headSet("a", true);
- assertTrue(headSet instanceof SynchronizedNavigableSet);
- assertSame(mutex, ((SynchronizedNavigableSet<String>) headSet).mutex);
- }
-
- public void testSubSet_E_E() {
- NavigableSet<String> map = create();
- SortedSet<String> subSet = map.subSet("a", "b");
- assertTrue(subSet instanceof SynchronizedSortedSet);
- assertSame(mutex, ((SynchronizedSortedSet<String>) subSet).mutex);
- }
-
- public void testSubSet_E_B_E_B() {
- NavigableSet<String> map = create();
- NavigableSet<String> subSet = map.subSet("a", false, "b", true);
- assertTrue(subSet instanceof SynchronizedNavigableSet);
- assertSame(mutex, ((SynchronizedNavigableSet<String>) subSet).mutex);
- }
-
- public void testTailSet_E() {
- NavigableSet<String> map = create();
- SortedSet<String> tailSet = map.tailSet("a");
- assertTrue(tailSet instanceof SynchronizedSortedSet);
- assertSame(mutex, ((SynchronizedSortedSet<String>) tailSet).mutex);
- }
-
- public void testTailSet_E_B() {
- NavigableSet<String> map = create();
- NavigableSet<String> tailSet = map.tailSet("a", true);
- assertTrue(tailSet instanceof SynchronizedNavigableSet);
- assertSame(mutex, ((SynchronizedNavigableSet<String>) tailSet).mutex);
- }
-
- @Override public void testSerialization() {
- SerializableTester.reserializeAndAssert(create());
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java b/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
deleted file mode 100644
index 4cce708..0000000
--- a/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import junit.framework.TestCase;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Queue;
-
-/**
- * Tests for {@link Synchronized#queue} and {@link Queues#synchronizedQueue}.
- *
- * @author Kurt Alfred Kluever
- */
-public class SynchronizedQueueTest extends TestCase {
-
- protected Queue<String> create() {
- TestQueue<String> inner = new TestQueue<String>();
- Queue<String> outer = Synchronized.queue(inner, inner.mutex);
- outer.add("foo"); // necessary because we try to remove elements later on
- return outer;
- }
-
- private static final class TestQueue<E> implements Queue<E> {
- private final Queue<E> delegate = Lists.newLinkedList();
- public final Object mutex = new Integer(1); // something Serializable
-
- @Override
- public boolean offer(E o) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.offer(o);
- }
-
- @Override
- public E poll() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.poll();
- }
-
- @Override
- public E remove() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.remove();
- }
-
- @Override
- public E peek() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.peek();
- }
-
- @Override
- public E element() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.element();
- }
-
- @Override
- public Iterator<E> iterator() {
- // We explicitly don't lock for iterator()
- assertFalse(Thread.holdsLock(mutex));
- return delegate.iterator();
- }
-
- @Override
- public int size() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.size();
- }
-
- @Override
- public boolean removeAll(Collection<?> collection) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.removeAll(collection);
- }
-
- @Override
- public boolean isEmpty() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.isEmpty();
- }
-
- @Override
- public boolean contains(Object object) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.contains(object);
- }
-
- @Override
- public boolean add(E element) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.add(element);
- }
-
- @Override
- public boolean remove(Object object) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.remove(object);
- }
-
- @Override
- public boolean containsAll(Collection<?> collection) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.containsAll(collection);
- }
-
- @Override
- public boolean addAll(Collection<? extends E> collection) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.addAll(collection);
- }
-
- @Override
- public boolean retainAll(Collection<?> collection) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.retainAll(collection);
- }
-
- @Override
- public void clear() {
- assertTrue(Thread.holdsLock(mutex));
- delegate.clear();
- }
-
- @Override
- public Object[] toArray() {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.toArray();
- }
-
- @Override
- public <T> T[] toArray(T[] array) {
- assertTrue(Thread.holdsLock(mutex));
- return delegate.toArray(array);
- }
-
- private static final long serialVersionUID = 0;
- }
-
- public void testHoldsLockOnAllOperations() {
- create().element();
- create().offer("foo");
- create().peek();
- create().poll();
- create().remove();
- create().add("foo");
- create().addAll(ImmutableList.of("foo"));
- create().clear();
- create().contains("foo");
- create().containsAll(ImmutableList.of("foo"));
- create().equals(ImmutableList.of("foo"));
- create().hashCode();
- create().isEmpty();
- create().iterator();
- create().remove("foo");
- create().removeAll(ImmutableList.of("foo"));
- create().retainAll(ImmutableList.of("foo"));
- create().size();
- create().toArray();
- create().toArray(new String[] { "foo" });
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java b/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java
index b14da0a..a33d0b7 100644
--- a/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java
+++ b/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java
@@ -41,7 +41,7 @@ public class SynchronizedSetTest extends AbstractCollectionTest {
return outer;
}
- @Override public void testNullPointerExceptions() {
+ @Override public void testNullPointerExceptions() throws Exception {
/* Skip this test, as SynchronizedSet is not a public class. */
}
diff --git a/guava-tests/test/com/google/common/collect/TableCollectionTest.java b/guava-tests/test/com/google/common/collect/TableCollectionTest.java
index 2e85311..9eed028 100644
--- a/guava-tests/test/com/google/common/collect/TableCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/TableCollectionTest.java
@@ -70,14 +70,14 @@ public class TableCollectionTest extends TestCase {
private static final Feature<?>[] COLLECTION_FEATURES_REMOVE = {
CollectionSize.ANY,
- CollectionFeature.SUPPORTS_REMOVE,
+ CollectionFeature.REMOVE_OPERATIONS,
CollectionFeature.ALLOWS_NULL_QUERIES
};
private static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = {
CollectionSize.ANY,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SUPPORTS_REMOVE,
+ CollectionFeature.REMOVE_OPERATIONS,
CollectionFeature.ALLOWS_NULL_QUERIES
};
@@ -214,7 +214,7 @@ public class TableCollectionTest extends TestCase {
.named("TreeBasedTable.rowKeySet.subSet")
.withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
.createTestSuite());
-
+
suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
@Override protected Set<String> create(String[] elements) {
Table<String, Integer, Character> table = HashBasedTable.create();
@@ -458,7 +458,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("HashBasedTable.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE,
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -468,7 +468,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("TreeBasedTable.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE,
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -480,7 +480,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("TransposedTable.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE,
+ .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -502,8 +502,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("TransformValues.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.SUPPORTS_REMOVE)
+ .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() {
diff --git a/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java b/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java
index 1ea040c..99787a9 100644
--- a/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java
+++ b/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java
@@ -50,7 +50,7 @@ public class TablesTransformValuesTest extends AbstractTableTest {
// Null support depends on the underlying table and function.
@GwtIncompatible("NullPointerTester")
- @Override public void testNullPointerInstance() {}
+ @Override public void testNullPointerInstance() throws Exception {}
// put() and putAll() aren't supported.
@Override public void testPut() {
diff --git a/guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java b/guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java
new file mode 100644
index 0000000..03c2f6e
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringListGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+import java.util.List;
+
+@GwtCompatible
+public class TransformedImmutableListTest extends TestCase {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ return ListTestSuiteBuilder.using(new TestStringListGenerator() {
+
+ @SuppressWarnings("serial")
+ @Override protected List<String> create(String[] elements) {
+ return new TransformedImmutableList<String, String>(
+ ImmutableList.copyOf(elements)) {
+
+ @Override String transform(String str) {
+ return str;
+ }
+ };
+ }
+ }).named("TransformedImmutableList identity").withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_QUERIES).createTestSuite();
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/TransformedSetTest.java b/guava-tests/test/com/google/common/collect/TransformedSetTest.java
new file mode 100644
index 0000000..8a26ed8
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/TransformedSetTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.SetFeature;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests for {@link Sets#transform(Set, Sets.InvertibleFunction)}.
+ *
+ * @author Dimitris Andreou
+ */
+@GwtCompatible(emulated = true)
+public class TransformedSetTest extends TestCase {
+ // Negates each integer. This is a true bijection, even considering MIN_VALUE
+ private static final Sets.InvertibleFunction<Integer, Integer> integerBijection =
+ new Sets.InvertibleFunction<Integer, Integer>() {
+ @Override public Integer apply(Integer integer) {
+ return integer != null ? -integer : null;
+ }
+
+ @Override
+ public Integer invert(Integer integer) {
+ return integer != null ? -integer : null;
+ }
+ };
+
+ @GwtIncompatible("suite")
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(SetTestSuiteBuilder
+ .using(new TransformedIntegerSetGenerator())
+ .named("TransformedSet")
+ .withFeatures(
+ SetFeature.GENERAL_PURPOSE,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionSize.SEVERAL)
+ .createTestSuite());
+ return suite;
+ }
+
+ public void testSimpleCases() {
+ Set<Integer> original = Sets.newHashSet(0, 1, 2, 3);
+ Set<Integer> transformed = Sets.transform(original, integerBijection);
+
+ assertEquals(ImmutableSet.of(0, -1, -2, -3), transformed);
+
+ // adding/removing to the original, see if transformed is affected
+ assertTrue(original.remove(2));
+ assertTrue(original.add(4));
+ assertEquals(ImmutableSet.of(0, 1, 3, 4), original);
+ assertEquals(ImmutableSet.of(0, -1, -3, -4), transformed);
+
+ // adding/removing to the transformed, see if original is affected
+ assertTrue(transformed.remove(-1));
+ assertTrue(transformed.add(-5));
+ assertEquals(ImmutableSet.of(0, -3, -4, -5), transformed);
+ assertEquals(ImmutableSet.of(0, 3, 4, 5), original);
+
+ // redoing the same actions as above; no effect
+ assertFalse(transformed.remove(-1));
+ assertFalse(transformed.add(-5));
+
+ // they should always have the same size
+ assertEquals(original.size(), transformed.size());
+
+ transformed.clear();
+ assertTrue(original.isEmpty());
+ assertTrue(transformed.isEmpty());
+ }
+
+ public static class TransformedIntegerSetGenerator implements TestSetGenerator<Integer> {
+ @Override public Set<Integer> create(Object... elements) {
+ // Would use Collections#checkedCollection, but I get:
+ // [ERROR] The method checkedCollection(Collection, Class<Integer>)
+ // is undefined for the type Collections
+ @SuppressWarnings("unchecked")
+ Iterable<Integer> integers = (Iterable) Arrays.asList(elements);
+
+ // I invert these before adding, so that the transformed set will have
+ // the expected elements themselves, not their image under the bijection
+ Set<Integer> invertedIntegers = Sets.newHashSet(Iterables.transform(integers,
+ integerBijection.inverse()));
+ return Sets.transform(invertedIntegers, integerBijection);
+ }
+
+ @Override public Integer[] createArray(int length) {
+ return new Integer[length];
+ }
+
+ @Override public SampleElements<Integer> samples() {
+ return new SampleElements<Integer>(-1, 0, 1, 2, 3);
+ }
+
+ @Override public Iterable<Integer> order(List<Integer> insertionOrder) {
+ throw new AssertionError();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java b/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java
index 81550f8..f4469ca 100644
--- a/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java
@@ -16,13 +16,13 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.SortedMapInterfaceTest;
-import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSortedMapGenerator;
+import com.google.common.collect.testing.TestStringMapGenerator;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import com.google.common.testing.SerializableTester;
@@ -39,20 +39,19 @@ import java.util.SortedMap;
/**
* Test cases for {@link TreeBasedTable}.
- *
+ *
* @author Jared Levy
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
public class TreeBasedTableTest extends AbstractTableTest {
- @GwtIncompatible("suite")
- public static Test suite() {
+ public static Test suite(){
TestSuite suite = new TestSuite();
suite.addTestSuite(TreeBasedTableTest.class);
suite.addTestSuite(TreeRowTest.class);
- suite.addTest(SortedMapTestSuiteBuilder
- .using(new TestStringSortedMapGenerator() {
- @Override protected SortedMap<String, String> create(
+ suite.addTest(MapTestSuiteBuilder
+ .using(new TestStringMapGenerator() {
+ @Override protected Map<String, String> create(
Entry<String, String>[] entries) {
TreeBasedTable<String, String, String> table =
TreeBasedTable.create();
@@ -68,7 +67,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
.named("RowMapTestSuite").createTestSuite());
return suite;
}
-
+
public static class TreeRowTest extends
SortedMapInterfaceTest<String, String> {
public TreeRowTest() {
@@ -119,7 +118,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
}
private TreeBasedTable<String, Integer, Character> sortedTable;
-
+
protected TreeBasedTable<String, Integer, Character> create(
Comparator<? super String> rowComparator,
Comparator<? super Integer> columnComparator,
@@ -132,7 +131,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
populate(table, data);
return table;
}
-
+
@Override protected TreeBasedTable<String, Integer, Character> create(
Object... data) {
TreeBasedTable<String, Integer, Character> table = TreeBasedTable.create();
@@ -141,8 +140,8 @@ public class TreeBasedTableTest extends AbstractTableTest {
table.clear();
populate(table, data);
return table;
- }
-
+ }
+
public void testCreateExplicitComparators() {
table = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
@@ -150,10 +149,10 @@ public class TreeBasedTableTest extends AbstractTableTest {
table.put("foo", 12, 'b');
table.put("bar", 5, 'c');
table.put("cat", 8, 'd');
- ASSERT.that(table.rowKeySet()).has().allOf("foo", "cat", "bar").inOrder();
- ASSERT.that(table.row("foo").keySet()).has().allOf(12, 3).inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder("foo", "cat", "bar");
+ ASSERT.that(table.row("foo").keySet()).hasContentsInOrder(12, 3);
}
-
+
public void testCreateCopy() {
TreeBasedTable<String, Integer, Character> original = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
@@ -162,127 +161,127 @@ public class TreeBasedTableTest extends AbstractTableTest {
original.put("bar", 5, 'c');
original.put("cat", 8, 'd');
table = TreeBasedTable.create(original);
- ASSERT.that(table.rowKeySet()).has().allOf("foo", "cat", "bar").inOrder();
- ASSERT.that(table.row("foo").keySet()).has().allOf(12, 3).inOrder();
+ ASSERT.that(table.rowKeySet()).hasContentsInOrder("foo", "cat", "bar");
+ ASSERT.that(table.row("foo").keySet()).hasContentsInOrder(12, 3);
assertEquals(original, table);
}
-
+
@GwtIncompatible("SerializableTester")
public void testSerialization() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
SerializableTester.reserializeAndAssert(table);
}
-
+
public void testToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
assertEquals("{bar={1=b}, foo={1=a, 3=c}}", table.toString());
assertEquals("{bar={1=b}, foo={1=a, 3=c}}", table.rowMap().toString());
}
-
+
public void testCellSetToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
assertEquals("[(bar,1)=b, (foo,1)=a, (foo,3)=c]",
- table.cellSet().toString());
+ table.cellSet().toString());
}
-
+
public void testRowKeySetToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertEquals("[bar, foo]", table.rowKeySet().toString());
+ assertEquals("[bar, foo]", table.rowKeySet().toString());
}
-
+
public void testValuesToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertEquals("[b, a, c]", table.values().toString());
+ assertEquals("[b, a, c]", table.values().toString());
}
-
+
public void testRowComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(), sortedTable.rowComparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Collections.reverseOrder(), sortedTable.rowComparator());
}
-
+
public void testColumnComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(), sortedTable.columnComparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Ordering.usingToString(), sortedTable.columnComparator());
}
-
+
public void testRowKeySetComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(),
sortedTable.rowKeySet().comparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Collections.reverseOrder(),
sortedTable.rowKeySet().comparator());
}
-
+
public void testRowKeySetFirst() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("bar", sortedTable.rowKeySet().first());
- }
-
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("bar", sortedTable.rowKeySet().first());
+ }
+
public void testRowKeySetLast() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("foo", sortedTable.rowKeySet().last());
- }
-
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("foo", sortedTable.rowKeySet().last());
+ }
+
public void testRowKeySetHeadSet() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Set<String> set = sortedTable.rowKeySet().headSet("cat");
assertEquals(Collections.singleton("bar"), set);
set.clear();
assertTrue(set.isEmpty());
assertEquals(Collections.singleton("foo"), sortedTable.rowKeySet());
- }
-
+ }
+
public void testRowKeySetTailSet() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Set<String> set = sortedTable.rowKeySet().tailSet("cat");
assertEquals(Collections.singleton("foo"), set);
set.clear();
assertTrue(set.isEmpty());
assertEquals(Collections.singleton("bar"), sortedTable.rowKeySet());
}
-
+
public void testRowKeySetSubSet() {
sortedTable = create(
- "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
+ "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
Set<String> set = sortedTable.rowKeySet().subSet("cat", "egg");
assertEquals(Collections.singleton("dog"), set);
set.clear();
assertTrue(set.isEmpty());
assertEquals(ImmutableSet.of("bar", "foo"), sortedTable.rowKeySet());
}
-
+
public void testRowMapComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(), sortedTable.rowMap().comparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Collections.reverseOrder(), sortedTable.rowMap().comparator());
- }
-
+ }
+
public void testRowMapFirstKey() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("bar", sortedTable.rowMap().firstKey());
- }
-
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("bar", sortedTable.rowMap().firstKey());
+ }
+
public void testRowMapLastKey() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("foo", sortedTable.rowMap().lastKey());
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("foo", sortedTable.rowMap().lastKey());
}
-
+
public void testRowKeyMapHeadMap() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Map<String, Map<Integer, Character>> map
= sortedTable.rowMap().headMap("cat");
assertEquals(1, map.size());
@@ -290,10 +289,10 @@ public class TreeBasedTableTest extends AbstractTableTest {
map.clear();
assertTrue(map.isEmpty());
assertEquals(Collections.singleton("foo"), sortedTable.rowKeySet());
- }
-
+ }
+
public void testRowKeyMapTailMap() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Map<String, Map<Integer, Character>> map
= sortedTable.rowMap().tailMap("cat");
assertEquals(1, map.size());
@@ -302,10 +301,10 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertTrue(map.isEmpty());
assertEquals(Collections.singleton("bar"), sortedTable.rowKeySet());
}
-
+
public void testRowKeyMapSubMap() {
sortedTable = create(
- "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
+ "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
Map<String, Map<Integer, Character>> map
= sortedTable.rowMap().subMap("cat", "egg");
assertEquals(ImmutableMap.of(2, 'd'), map.get("dog"));
@@ -313,13 +312,13 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertTrue(map.isEmpty());
assertEquals(ImmutableSet.of("bar", "foo"), sortedTable.rowKeySet());
}
-
- public void testRowMapValuesAreSorted() {
+
+ public void testRowMapValuesAreSorted(){
sortedTable = create(
"foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
assertTrue(sortedTable.rowMap().get("foo") instanceof SortedMap);
}
-
+
public void testColumnKeySet_isSorted() {
table = create("a", 2, 'X',
"a", 2, 'X',
@@ -335,7 +334,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
);
assertEquals("[1, 2, 3, 5, 10, 15, 20]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_isSortedWithRealComparator() {
table = create(String.CASE_INSENSITIVE_ORDER,
Ordering.natural().reverse(),
@@ -352,33 +351,33 @@ public class TreeBasedTableTest extends AbstractTableTest {
"e", 5, 'X'
);
assertEquals("[20, 15, 10, 5, 3, 2, 1]", table.columnKeySet().toString());
- }
-
+ }
+
public void testColumnKeySet_empty() {
table = create();
assertEquals("[]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_oneRow() {
table = create("a", 2, 'X',
"a", 1, 'X'
);
assertEquals("[1, 2]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_oneColumn() {
table = create("a", 1, 'X',
"b", 1, 'X'
);
assertEquals("[1]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_oneEntry() {
table = create("a", 1, 'X');
assertEquals("[1]", table.columnKeySet().toString());
}
- public void testRowEntrySetContains() {
+ public void testRowEntrySetContains(){
table =
sortedTable =
create("a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10,
@@ -395,7 +394,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertFalse(entrySet.contains(Maps.immutableEntry(15, 'X')));
}
- public void testRowEntrySetRemove() {
+ public void testRowEntrySetRemove(){
table =
sortedTable =
create("a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10,
@@ -411,8 +410,8 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertFalse(entrySet.remove(Maps.immutableEntry(20, 'X')));
assertFalse(entrySet.remove(Maps.immutableEntry(15, 'X')));
}
-
- public void testRowSize() {
+
+ public void testRowSize(){
table =
sortedTable =
create("a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10,
diff --git a/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java b/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java
index 3269397..bc9b68f 100644
--- a/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -96,13 +96,13 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
tree.put("google", 6);
tree.put("tree", 0);
tree.put("tree", 3);
- ASSERT.that(tree.keySet()).has().allOf("tree", "google").inOrder();
- ASSERT.that(tree.get("google")).has().allOf(6, 2).inOrder();
+ ASSERT.that(tree.keySet()).hasContentsInOrder("tree", "google");
+ ASSERT.that(tree.get("google")).hasContentsInOrder(6, 2);
TreeMultimap<String, Integer> copy = TreeMultimap.create(tree);
assertEquals(tree, copy);
- ASSERT.that(copy.keySet()).has().allOf("google", "tree").inOrder();
- ASSERT.that(copy.get("google")).has().allOf(2, 6).inOrder();
+ ASSERT.that(copy.keySet()).hasContentsInOrder("google", "tree");
+ ASSERT.that(copy.get("google")).hasContentsInOrder(2, 6);
assertEquals(Ordering.natural(), copy.keyComparator());
assertEquals(Ordering.natural(), copy.valueComparator());
assertEquals(Ordering.natural(), copy.get("google").comparator());
@@ -121,14 +121,14 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
public void testOrderedGet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.get(null)).has().allOf(7, 3, 1).inOrder();
- ASSERT.that(multimap.get("google")).has().allOf(6, 2).inOrder();
- ASSERT.that(multimap.get("tree")).has().allOf(null, 0).inOrder();
+ ASSERT.that(multimap.get(null)).hasContentsInOrder(7, 3, 1);
+ ASSERT.that(multimap.get("google")).hasContentsInOrder(6, 2);
+ ASSERT.that(multimap.get("tree")).hasContentsInOrder(null, 0);
}
public void testOrderedKeySet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.keySet()).has().allOf(null, "tree", "google").inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder(null, "tree", "google");
}
public void testOrderedAsMapEntries() {
@@ -137,30 +137,29 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
multimap.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = iterator.next();
assertEquals(null, entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(7, 3, 1);
+ ASSERT.that(entry.getValue()).hasContentsAnyOrder(7, 3, 1);
entry = iterator.next();
assertEquals("tree", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(null, 0);
+ ASSERT.that(entry.getValue()).hasContentsAnyOrder(null, 0);
entry = iterator.next();
assertEquals("google", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(6, 2);
+ ASSERT.that(entry.getValue()).hasContentsAnyOrder(6, 2);
}
public void testOrderedEntries() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.entries()).has().allOf(
+ ASSERT.that(multimap.entries()).hasContentsInOrder(
Maps.immutableEntry((String) null, 7),
Maps.immutableEntry((String) null, 3),
Maps.immutableEntry((String) null, 1),
Maps.immutableEntry("tree", (Integer) null),
Maps.immutableEntry("tree", 0),
- Maps.immutableEntry("google", 6),
- Maps.immutableEntry("google", 2)).inOrder();
+ Maps.immutableEntry("google", 6), Maps.immutableEntry("google", 2));
}
public void testOrderedValues() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.values()).has().allOf(7, 3, 1, null, 0, 6, 2).inOrder();
+ ASSERT.that(multimap.values()).hasContentsInOrder(7, 3, 1, null, 0, 6, 2);
}
public void testComparator() {
@@ -197,8 +196,8 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
TreeMultimap<String, Integer> multimap = createPopulate();
TreeMultimap<String, Integer> copy
= SerializableTester.reserializeAndAssert(multimap);
- ASSERT.that(copy.values()).has().allOf(7, 3, 1, null, 0, 6, 2).inOrder();
- ASSERT.that(copy.keySet()).has().allOf(null, "tree", "google").inOrder();
+ ASSERT.that(copy.values()).hasContentsInOrder(7, 3, 1, null, 0, 6, 2);
+ ASSERT.that(copy.keySet()).hasContentsInOrder(null, "tree", "google");
assertEquals(multimap.keyComparator(), copy.keyComparator());
assertEquals(multimap.valueComparator(), copy.valueComparator());
}
diff --git a/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java b/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java
index 1ee1320..5416a1d 100644
--- a/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java
@@ -16,39 +16,26 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.truth0.Truth.ASSERT;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Sets.newHashSet;
+import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
+import static java.util.Arrays.asList;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.DerivedComparable;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestSortedMapGenerator;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.TestStringSortedSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.google.SortedSetMultimapTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
+import com.google.common.collect.testing.IteratorTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
+import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -59,196 +46,7 @@ import java.util.SortedSet;
* @author Jared Levy
*/
@GwtCompatible(emulated = true)
-public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- // TODO(user): should we force TreeMultimap to be more thorough about checking nulls?
- suite.addTest(SortedSetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
- @Override
- protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
- SetMultimap<String, String> multimap = TreeMultimap.create(
- Ordering.natural().nullsFirst(), Ordering.natural().nullsFirst());
- for (Entry<String, String> entry : entries) {
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap;
- }
-
- @Override
- public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) {
- return new Ordering<Entry<String, String>>() {
- @Override
- public int compare(Entry<String, String> left, Entry<String, String> right) {
- return ComparisonChain.start()
- .compare(left.getKey(), right.getKey(), Ordering.natural().nullsFirst())
- .compare(left.getValue(), right.getValue(), Ordering.natural().nullsFirst())
- .result();
- }
- }.sortedCopy(insertionOrder);
- }
- })
- .named("TreeMultimap nullsFirst")
- .withFeatures(
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE,
- MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.SERIALIZABLE,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSortedSetGenerator() {
- @Override
- protected NavigableSet<String> create(String[] elements) {
- TreeMultimap<String, Integer> multimap = TreeMultimap.create(
- Ordering.natural().nullsFirst(), Ordering.natural());
- for (int i = 0; i < elements.length; i++) {
- multimap.put(elements[i], i);
- }
- return multimap.keySet();
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
- }
- })
- .named("TreeMultimap.keySet")
- .withFeatures(
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.SUPPORTS_REMOVE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTest(NavigableMapTestSuiteBuilder.using(
- new TestSortedMapGenerator<String, Collection<String>>() {
-
- @Override
- public String[] createKeyArray(int length) {
- return new String[length];
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Collection<String>[] createValueArray(int length) {
- return new Collection[length];
- }
-
- @Override
- public SampleElements<Entry<String, Collection<String>>> samples() {
- return new SampleElements<Entry<String, Collection<String>>>(
- Helpers.mapEntry("a", (Collection<String>) ImmutableSortedSet.of("alex")),
- Helpers.mapEntry("b", (Collection<String>) ImmutableSortedSet.of("bob", "bagel")),
- Helpers.mapEntry("c", (Collection<String>) ImmutableSortedSet.of("carl", "carol")),
- Helpers.mapEntry("d", (Collection<String>) ImmutableSortedSet.of("david", "dead")),
- Helpers.mapEntry("e", (Collection<String>) ImmutableSortedSet.of("eric", "elaine")));
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<String, Collection<String>>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<String, Collection<String>>> order(
- List<Entry<String, Collection<String>>> insertionOrder) {
- return new Ordering<Entry<String, ?>>() {
- @Override
- public int compare(Entry<String, ?> left, Entry<String, ?> right) {
- return left.getKey().compareTo(right.getKey());
- }
- }.sortedCopy(insertionOrder);
- }
-
- @Override
- public NavigableMap<String, Collection<String>> create(Object... elements) {
- TreeMultimap<String, String> multimap = TreeMultimap.create();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Collection<String>> entry = (Entry<String, Collection<String>>) o;
- checkArgument(!multimap.containsKey(entry.getKey()));
- multimap.putAll(entry.getKey(), entry.getValue());
- }
- return multimap.asMap();
- }
-
- @Override
- public Entry<String, Collection<String>> belowSamplesLesser() {
- return Helpers.mapEntry("-- a", (Collection<String>) ImmutableSortedSet.of("--below"));
- }
-
- @Override
- public Entry<String, Collection<String>> belowSamplesGreater() {
- return Helpers.mapEntry("-- b", (Collection<String>) ImmutableSortedSet.of("--below"));
- }
-
- @Override
- public Entry<String, Collection<String>> aboveSamplesLesser() {
- return Helpers.mapEntry("~~ b", (Collection<String>) ImmutableSortedSet.of("~above"));
- }
-
- @Override
- public Entry<String, Collection<String>> aboveSamplesGreater() {
- return Helpers.mapEntry("~~ c", (Collection<String>) ImmutableSortedSet.of("~above"));
- }
- })
- .named("TreeMultimap.asMap")
- .withFeatures(
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override
- protected Set<String> create(String[] elements) {
- TreeMultimap<Integer, String> multimap = TreeMultimap.create(
- Ordering.natural(), Ordering.natural().nullsFirst());
- multimap.putAll(1, Arrays.asList(elements));
- return multimap.get(1);
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
- }
- })
- .named("TreeMultimap.get")
- .withFeatures(
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY)
- .createTestSuite());
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override
- protected Set<String> create(String[] elements) {
- TreeMultimap<Integer, String> multimap = TreeMultimap.create(
- Ordering.natural(), Ordering.natural().nullsFirst());
- multimap.putAll(1, Arrays.asList(elements));
- return (Set<String>) multimap.asMap().entrySet().iterator().next().getValue();
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
- }
- })
- .named("TreeMultimap.asMap.entrySet collection")
- .withFeatures(
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ONE,
- CollectionSize.SEVERAL)
- .createTestSuite());
- suite.addTestSuite(TreeMultimapNaturalTest.class);
- return suite;
- }
-
+public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
@Override protected Multimap<String, Integer> create() {
return TreeMultimap.create();
}
@@ -285,14 +83,14 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
public void testOrderedGet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.get("foo")).has().allOf(1, 3, 7).inOrder();
- ASSERT.that(multimap.get("google")).has().allOf(2, 6).inOrder();
- ASSERT.that(multimap.get("tree")).has().allOf(0, 4).inOrder();
+ ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 3, 7);
+ ASSERT.that(multimap.get("google")).hasContentsInOrder(2, 6);
+ ASSERT.that(multimap.get("tree")).hasContentsInOrder(0, 4);
}
public void testOrderedKeySet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.keySet()).has().allOf("foo", "google", "tree").inOrder();
+ ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "google", "tree");
}
public void testOrderedAsMapEntries() {
@@ -301,31 +99,95 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
multimap.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = iterator.next();
assertEquals("foo", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(1, 3, 7);
+ ASSERT.that(entry.getValue()).hasContentsAnyOrder(1, 3, 7);
entry = iterator.next();
assertEquals("google", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(2, 6);
+ ASSERT.that(entry.getValue()).hasContentsAnyOrder(2, 6);
entry = iterator.next();
assertEquals("tree", entry.getKey());
- ASSERT.that(entry.getValue()).has().allOf(0, 4);
+ ASSERT.that(entry.getValue()).hasContentsAnyOrder(0, 4);
}
public void testOrderedEntries() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.entries()).has().allOf(
+ ASSERT.that(multimap.entries()).hasContentsInOrder(
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("foo", 3),
Maps.immutableEntry("foo", 7),
Maps.immutableEntry("google", 2),
Maps.immutableEntry("google", 6),
Maps.immutableEntry("tree", 0),
- Maps.immutableEntry("tree", 4)).inOrder();
+ Maps.immutableEntry("tree", 4));
}
public void testOrderedValues() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.values()).has().allOf(
- 1, 3, 7, 2, 6, 0, 4).inOrder();
+ ASSERT.that(multimap.values()).hasContentsInOrder(
+ 1, 3, 7, 2, 6, 0, 4);
+ }
+
+ public void testFirst() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ assertEquals(Integer.valueOf(1), multimap.get("foo").first());
+ try {
+ multimap.get("missing").first();
+ fail("Expected NoSuchElementException");
+ } catch (NoSuchElementException expected) {}
+ }
+
+ public void testLast() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ assertEquals(Integer.valueOf(7), multimap.get("foo").last());
+ try {
+ multimap.get("missing").last();
+ fail("Expected NoSuchElementException");
+ } catch (NoSuchElementException expected) {}
+ }
+
+ public void testComparatorFromGet() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ assertSame(Ordering.natural(), multimap.get("foo").comparator());
+ assertSame(Ordering.natural(), multimap.get("missing").comparator());
+ }
+
+ public void testHeadSet() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ Set<Integer> fooSet = multimap.get("foo").headSet(4);
+ assertEquals(Sets.newHashSet(1, 3), fooSet);
+ Set<Integer> missingSet = multimap.get("missing").headSet(4);
+ assertEquals(Sets.newHashSet(), missingSet);
+
+ multimap.put("foo", 0);
+ assertEquals(Sets.newHashSet(0, 1, 3), fooSet);
+
+ missingSet.add(2);
+ assertEquals(Sets.newHashSet(2), multimap.get("missing"));
+ }
+
+ public void testTailSet() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ Set<Integer> fooSet = multimap.get("foo").tailSet(2);
+ assertEquals(Sets.newHashSet(3, 7), fooSet);
+ Set<Integer> missingSet = multimap.get("missing").tailSet(4);
+ assertEquals(Sets.newHashSet(), missingSet);
+
+ multimap.put("foo", 6);
+ assertEquals(Sets.newHashSet(3, 6, 7), fooSet);
+
+ missingSet.add(9);
+ assertEquals(Sets.newHashSet(9), multimap.get("missing"));
+ }
+
+ public void testSubSet() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ Set<Integer> fooSet = multimap.get("foo").subSet(2, 6);
+ assertEquals(Sets.newHashSet(3), fooSet);
+
+ multimap.put("foo", 5);
+ assertEquals(Sets.newHashSet(3, 5), fooSet);
+
+ fooSet.add(4);
+ assertEquals(Sets.newHashSet(1, 3, 4, 5, 7), multimap.get("foo"));
}
public void testMultimapConstructor() {
@@ -334,7 +196,7 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
assertEquals(multimap, copy);
}
- private static final Comparator<Double> KEY_COMPARATOR =
+ private static final Comparator<Double> KEY_COMPARATOR =
Ordering.natural();
private static final Comparator<Double> VALUE_COMPARATOR =
@@ -400,13 +262,209 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
assertEquals(Ordering.natural(), multimap.valueComparator());
}
+ public void testSortedKeySet() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ SortedSet<String> keySet = multimap.keySet();
+
+ assertEquals("foo", keySet.first());
+ assertEquals("tree", keySet.last());
+ assertEquals(Ordering.natural(), keySet.comparator());
+ assertEquals(ImmutableSet.of("foo", "google"), keySet.headSet("hi"));
+ assertEquals(ImmutableSet.of("tree"), keySet.tailSet("hi"));
+ assertEquals(ImmutableSet.of("google"), keySet.subSet("gap", "hi"));
+ }
+
+ public void testKeySetSubSet() {
+ TreeMultimap<String, Integer> multimap = createPopulate();
+ SortedSet<String> keySet = multimap.keySet();
+ SortedSet<String> subSet = keySet.subSet("gap", "hi");
+
+ assertEquals(1, subSet.size());
+ assertTrue(subSet.contains("google"));
+ assertFalse(subSet.contains("foo"));
+ assertTrue(subSet.containsAll(Collections.singleton("google")));
+ assertFalse(subSet.containsAll(Collections.singleton("foo")));
+
+ Iterator<String> iterator = subSet.iterator();
+ assertTrue(iterator.hasNext());
+ assertEquals("google", iterator.next());
+ assertFalse(iterator.hasNext());
+
+ assertFalse(subSet.remove("foo"));
+ assertTrue(multimap.containsKey("foo"));
+ assertEquals(7, multimap.size());
+ assertTrue(subSet.remove("google"));
+ assertFalse(multimap.containsKey("google"));
+ assertEquals(5, multimap.size());
+ }
+
+ @GwtIncompatible("unreasonable slow")
+ public void testGetIteration() {
+ new IteratorTester<Integer>(6, MODIFIABLE,
+ Sets.newTreeSet(asList(2, 3, 4, 7, 8)),
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ private Multimap<String, Integer> multimap;
+
+ @Override protected Iterator<Integer> newTargetIterator() {
+ multimap = create();
+ multimap.putAll("foo", asList(3, 8, 4));
+ multimap.putAll("bar", asList(5, 6));
+ multimap.putAll("foo", asList(7, 2));
+ return multimap.get("foo").iterator();
+ }
+
+ @Override protected void verify(List<Integer> elements) {
+ assertEquals(newHashSet(elements), multimap.get("foo"));
+ }
+ }.test();
+ }
+
+ @SuppressWarnings("unchecked")
+ @GwtIncompatible("unreasonable slow")
+ public void testEntriesIteration() {
+ Set<Entry<String, Integer>> set = Sets.newLinkedHashSet(asList(
+ Maps.immutableEntry("bar", 4),
+ Maps.immutableEntry("bar", 5),
+ Maps.immutableEntry("foo", 2),
+ Maps.immutableEntry("foo", 3),
+ Maps.immutableEntry("foo", 6)));
+ new IteratorTester<Entry<String, Integer>>(6, MODIFIABLE, set,
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ private Multimap<String, Integer> multimap;
+
+ @Override protected Iterator<Entry<String, Integer>> newTargetIterator() {
+ multimap = create();
+ multimap.putAll("foo", asList(6, 3));
+ multimap.putAll("bar", asList(4, 5));
+ multimap.putAll("foo", asList(2));
+ return multimap.entries().iterator();
+ }
+
+ @Override protected void verify(List<Entry<String, Integer>> elements) {
+ assertEquals(newHashSet(elements), multimap.entries());
+ }
+ }.test();
+ }
+
+ @GwtIncompatible("unreasonable slow")
+ public void testKeysIteration() {
+ new IteratorTester<String>(6, MODIFIABLE, Lists.newArrayList("bar", "bar",
+ "foo", "foo", "foo"), IteratorTester.KnownOrder.KNOWN_ORDER) {
+ private Multimap<String, Integer> multimap;
+
+ @Override protected Iterator<String> newTargetIterator() {
+ multimap = create();
+ multimap.putAll("foo", asList(2, 3));
+ multimap.putAll("bar", asList(4, 5));
+ multimap.putAll("foo", asList(6));
+ return multimap.keys().iterator();
+ }
+
+ @Override protected void verify(List<String> elements) {
+ assertEquals(elements, Lists.newArrayList(multimap.keys()));
+ }
+ }.test();
+ }
+
+ @GwtIncompatible("unreasonable slow")
+ public void testValuesIteration() {
+ new IteratorTester<Integer>(6, MODIFIABLE, newArrayList(4, 5, 2, 3, 6),
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ private Multimap<String, Integer> multimap;
+
+ @Override protected Iterator<Integer> newTargetIterator() {
+ multimap = create();
+ multimap.putAll("foo", asList(2, 3));
+ multimap.putAll("bar", asList(4, 5));
+ multimap.putAll("foo", asList(6));
+ return multimap.values().iterator();
+ }
+
+ @Override protected void verify(List<Integer> elements) {
+ assertEquals(elements, Lists.newArrayList(multimap.values()));
+ }
+ }.test();
+ }
+
+ @GwtIncompatible("unreasonable slow")
+ public void testKeySetIteration() {
+ new IteratorTester<String>(6, MODIFIABLE,
+ Sets.newTreeSet(asList("bar", "baz", "cat", "dog", "foo")),
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ private Multimap<String, Integer> multimap;
+
+ @Override protected Iterator<String> newTargetIterator() {
+ multimap = create();
+ multimap.putAll("foo", asList(2, 3));
+ multimap.putAll("bar", asList(4, 5));
+ multimap.putAll("foo", asList(6));
+ multimap.putAll("baz", asList(7, 8));
+ multimap.putAll("dog", asList(9));
+ multimap.putAll("bar", asList(10, 11));
+ multimap.putAll("cat", asList(12, 13, 14));
+ return multimap.keySet().iterator();
+ }
+
+ @Override protected void verify(List<String> elements) {
+ assertEquals(newHashSet(elements), multimap.keySet());
+ }
+ }.test();
+ }
+
+ @SuppressWarnings("unchecked")
+ @GwtIncompatible("unreasonable slow")
+ public void testAsSetIteration() {
+ Set<Entry<String, Collection<Integer>>> set = Sets.newTreeSet(
+ new Comparator<Entry<String, ?>>() {
+ @Override
+ public int compare(Entry<String, ?> o1, Entry<String, ?> o2) {
+ return o1.getKey().compareTo(o2.getKey());
+ }
+ });
+ Collections.addAll(set,
+ Maps.immutableEntry("bar",
+ (Collection<Integer>) Sets.newHashSet(4, 5, 10, 11)),
+ Maps.immutableEntry("baz",
+ (Collection<Integer>) Sets.newHashSet(7, 8)),
+ Maps.immutableEntry("cat",
+ (Collection<Integer>) Sets.newHashSet(12, 13, 14)),
+ Maps.immutableEntry("dog",
+ (Collection<Integer>) Sets.newHashSet(9)),
+ Maps.immutableEntry("foo",
+ (Collection<Integer>) Sets.newHashSet(2, 3, 6))
+ );
+
+ new IteratorTester<Entry<String, Collection<Integer>>>(6, MODIFIABLE, set,
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ private Multimap<String, Integer> multimap;
+
+ @Override protected Iterator<Entry<String, Collection<Integer>>>
+ newTargetIterator() {
+ multimap = create();
+ multimap.putAll("foo", asList(2, 3));
+ multimap.putAll("bar", asList(4, 5));
+ multimap.putAll("foo", asList(6));
+ multimap.putAll("baz", asList(7, 8));
+ multimap.putAll("dog", asList(9));
+ multimap.putAll("bar", asList(10, 11));
+ multimap.putAll("cat", asList(12, 13, 14));
+ return multimap.asMap().entrySet().iterator();
+ }
+
+ @Override protected void verify(
+ List<Entry<String, Collection<Integer>>> elements) {
+ assertEquals(newHashSet(elements), multimap.asMap().entrySet());
+ }
+ }.test();
+ }
+
@GwtIncompatible("SerializableTester")
public void testExplicitComparatorSerialization() {
TreeMultimap<String, Integer> multimap = createPopulate();
TreeMultimap<String, Integer> copy
= SerializableTester.reserializeAndAssert(multimap);
- ASSERT.that(copy.values()).has().allOf(1, 3, 7, 2, 6, 0, 4).inOrder();
- ASSERT.that(copy.keySet()).has().allOf("foo", "google", "tree").inOrder();
+ ASSERT.that(copy.values()).hasContentsInOrder(1, 3, 7, 2, 6, 0, 4);
+ ASSERT.that(copy.keySet()).hasContentsInOrder("foo", "google", "tree");
assertEquals(multimap.keyComparator(), copy.keyComparator());
assertEquals(multimap.valueComparator(), copy.valueComparator());
}
@@ -421,11 +479,11 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
multimap.put(new DerivedComparable("bar"), new DerivedComparable("b"));
multimap.put(new DerivedComparable("bar"), new DerivedComparable("a"));
multimap.put(new DerivedComparable("bar"), new DerivedComparable("r"));
- ASSERT.that(multimap.keySet()).has().allOf(
- new DerivedComparable("bar"), new DerivedComparable("foo")).inOrder();
- ASSERT.that(multimap.values()).has().allOf(
+ ASSERT.that(multimap.keySet()).hasContentsInOrder(
+ new DerivedComparable("bar"), new DerivedComparable("foo"));
+ ASSERT.that(multimap.values()).hasContentsInOrder(
new DerivedComparable("a"), new DerivedComparable("b"), new DerivedComparable("r"),
- new DerivedComparable("f"), new DerivedComparable("o")).inOrder();
+ new DerivedComparable("f"), new DerivedComparable("o"));
assertEquals(Ordering.natural(), multimap.keyComparator());
assertEquals(Ordering.natural(), multimap.valueComparator());
SerializableTester.reserializeAndAssert(multimap);
@@ -442,14 +500,14 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
multimap.put(new LegacyComparable("bar"), new LegacyComparable("b"));
multimap.put(new LegacyComparable("bar"), new LegacyComparable("a"));
multimap.put(new LegacyComparable("bar"), new LegacyComparable("r"));
- ASSERT.that(multimap.keySet()).has().allOf(
- new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
- ASSERT.that(multimap.values()).has().allOf(
+ ASSERT.that(multimap.keySet()).hasContentsInOrder(
+ new LegacyComparable("bar"), new LegacyComparable("foo"));
+ ASSERT.that(multimap.values()).hasContentsInOrder(
new LegacyComparable("a"),
new LegacyComparable("b"),
new LegacyComparable("r"),
new LegacyComparable("f"),
- new LegacyComparable("o")).inOrder();
+ new LegacyComparable("o"));
assertEquals(Ordering.natural(), multimap.keyComparator());
assertEquals(Ordering.natural(), multimap.valueComparator());
SerializableTester.reserializeAndAssert(multimap);
@@ -488,33 +546,4 @@ public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
assertEquals(4, multimap.values().size());
assertEquals(4, multimap.keys().size());
}
-
- @GwtIncompatible("reflection")
- public void testKeySetBridgeMethods() {
- for (Method m : TreeMultimap.class.getMethods()) {
- if (m.getName().equals("keySet") && m.getReturnType().equals(SortedSet.class)) {
- return;
- }
- }
- fail("No bridge method found");
- }
-
- @GwtIncompatible("reflection")
- public void testAsMapBridgeMethods() {
- for (Method m : TreeMultimap.class.getMethods()) {
- if (m.getName().equals("asMap") && m.getReturnType().equals(SortedMap.class)) {
- return;
- }
- }
- }
-
- @GwtIncompatible("reflection")
- public void testGetBridgeMethods() {
- for (Method m : TreeMultimap.class.getMethods()) {
- if (m.getName().equals("get") && m.getReturnType().equals(SortedSet.class)) {
- return;
- }
- }
- fail("No bridge method found");
- }
}
diff --git a/guava-tests/test/com/google/common/collect/TreeMultisetTest.java b/guava-tests/test/com/google/common/collect/TreeMultisetTest.java
index ef92e3e..2d70307 100644
--- a/guava-tests/test/com/google/common/collect/TreeMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeMultisetTest.java
@@ -19,24 +19,8 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static java.util.Collections.sort;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers.NullsBeforeB;
-import com.google.common.collect.testing.IteratorTester;
-import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestStringMultisetGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@@ -45,6 +29,10 @@ import java.util.List;
import java.util.Set;
import java.util.SortedSet;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.IteratorTester;
+
/**
* Unit test for {@link TreeMultiset}.
*
@@ -52,70 +40,6 @@ import java.util.SortedSet;
*/
@GwtCompatible(emulated = true)
public class TreeMultisetTest extends AbstractMultisetTest {
-
- @GwtIncompatible("suite")
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(SortedMultisetTestSuiteBuilder
- .using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- return TreeMultiset.create(Arrays.asList(elements));
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("TreeMultiset, Ordering.natural")
- .createTestSuite());
- suite.addTest(SortedMultisetTestSuiteBuilder
- .using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- Multiset<String> result = TreeMultiset.create(NullsBeforeB.INSTANCE);
- result.addAll(Arrays.asList(elements));
- return result;
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- sort(insertionOrder, NullsBeforeB.INSTANCE);
- return insertionOrder;
- }
- })
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.SERIALIZABLE,
- CollectionFeature.ALLOWS_NULL_VALUES)
- .named("TreeMultiset, NullsBeforeB")
- .createTestSuite());
- suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override
- protected Set<String> create(String[] elements) {
- return TreeMultiset.create(Arrays.asList(elements)).elementSet();
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
- }
- })
- .named("TreeMultiset[Ordering.natural].elementSet")
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.SUPPORTS_REMOVE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
- suite.addTestSuite(TreeMultisetTest.class);
- return suite;
- }
-
@SuppressWarnings("unchecked")
@Override protected <E> Multiset<E> create() {
return (Multiset) TreeMultiset.create();
@@ -215,9 +139,9 @@ public class TreeMultisetTest extends AbstractMultisetTest {
assertEquals("c", elementSet.last());
assertEquals(Ordering.natural(), elementSet.comparator());
- ASSERT.that(elementSet.headSet("b")).has().allOf("a").inOrder();
- ASSERT.that(elementSet.tailSet("b")).has().allOf("b", "c").inOrder();
- ASSERT.that(elementSet.subSet("a", "c")).has().allOf("a", "b").inOrder();
+ ASSERT.that(elementSet.headSet("b")).hasContentsInOrder("a");
+ ASSERT.that(elementSet.tailSet("b")).hasContentsInOrder("b", "c");
+ ASSERT.that(elementSet.subSet("a", "c")).hasContentsInOrder("a", "b");
}
public void testElementSetSubsetRemove() {
@@ -230,18 +154,18 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
+ ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
assertTrue(subset.remove("c"));
- ASSERT.that(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder();
- ASSERT.that(subset).has().allOf("b", "d", "e").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "d", "e", "f");
+ ASSERT.that(subset).hasContentsInOrder("b", "d", "e");
assertEquals(10, ms.size());
assertFalse(subset.remove("a"));
- ASSERT.that(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder();
- ASSERT.that(subset).has().allOf("b", "d", "e").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "d", "e", "f");
+ ASSERT.that(subset).hasContentsInOrder("b", "d", "e");
assertEquals(10, ms.size());
}
@@ -255,13 +179,13 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
+ ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
assertTrue(subset.removeAll(Arrays.asList("a", "c")));
- ASSERT.that(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder();
- ASSERT.that(subset).has().allOf("b", "d", "e").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "d", "e", "f");
+ ASSERT.that(subset).hasContentsInOrder("b", "d", "e");
assertEquals(10, ms.size());
}
@@ -275,13 +199,13 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
+ ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
assertTrue(subset.retainAll(Arrays.asList("a", "c")));
- ASSERT.that(elementSet).has().allOf("a", "c", "f").inOrder();
- ASSERT.that(subset).has().allOf("c").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "c", "f");
+ ASSERT.that(subset).hasContentsInOrder("c");
assertEquals(5, ms.size());
}
@@ -295,13 +219,13 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
+ ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
subset.clear();
- ASSERT.that(elementSet).has().allOf("a", "f").inOrder();
- ASSERT.that(subset).isEmpty();
+ ASSERT.that(elementSet).hasContentsInOrder("a", "f");
+ ASSERT.that(subset).hasContentsInOrder();
assertEquals(3, ms.size());
}
@@ -320,7 +244,7 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("b");
ms.add("d");
- ASSERT.that(ms).has().allOf("d", "c", "b", "b", "a").inOrder();
+ ASSERT.that(ms).hasContentsInOrder("d", "c", "b", "b", "a");
SortedSet<String> elementSet = ms.elementSet();
assertEquals("d", elementSet.first());
@@ -338,7 +262,7 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("b");
ms.add(null, 2);
- ASSERT.that(ms).has().allOf(null, null, null, "a", "b", "b").inOrder();
+ ASSERT.that(ms).hasContentsInOrder(null, null, null, "a", "b", "b");
assertEquals(3, ms.count(null));
SortedSet<String> elementSet = ms.elementSet();
@@ -408,14 +332,5 @@ public class TreeMultisetTest extends AbstractMultisetTest {
c = ms = TreeMultiset.create(Ordering.natural().nullsFirst());
super.testToStringNull();
}
-
- @GwtIncompatible("reflection")
- public void testElementSetBridgeMethods() {
- for (Method m : TreeMultiset.class.getMethods()) {
- if (m.getName().equals("elementSet") && m.getReturnType().equals(SortedSet.class)) {
- return;
- }
- }
- fail("No bridge method found");
- }
}
+
diff --git a/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java b/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
deleted file mode 100644
index c914065..0000000
--- a/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.testing.Helpers.mapEntry;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.testers.CollectionIteratorTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-
-/**
- * Tests for {@code TreeRangeMap}.
- *
- * @author Louis Wasserman
- */
-@GwtIncompatible("NavigableMap")
-public class TreeRangeMapTest extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(TreeRangeMapTest.class);
- suite.addTest(MapTestSuiteBuilder.using(new TestMapGenerator<Range<Integer>, String>() {
- @Override
- public SampleElements<Entry<Range<Integer>, String>> samples() {
- return new SampleElements<Entry<Range<Integer>, String>>(
- mapEntry(Range.singleton(0), "banana"),
- mapEntry(Range.closedOpen(3, 5), "frisbee"),
- mapEntry(Range.atMost(-1), "fruitcake"),
- mapEntry(Range.open(10, 15), "elephant"),
- mapEntry(Range.closed(20, 22), "umbrella"));
- }
-
- @Override
- public Map<Range<Integer>, String> create(Object... elements) {
- RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<Range<Integer>, String> entry = (Entry<Range<Integer>, String>) o;
- rangeMap.put(entry.getKey(), entry.getValue());
- }
- return rangeMap.asMapOfRanges();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<Range<Integer>, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<Range<Integer>, String>> order(
- List<Entry<Range<Integer>, String>> insertionOrder) {
- return Range.RANGE_LEX_ORDERING.onResultOf(Maps.<Range<Integer>>keyFunction())
- .sortedCopy(insertionOrder);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Range<Integer>[] createKeyArray(int length) {
- return new Range[length];
- }
-
- @Override
- public String[] createValueArray(int length) {
- return new String[length];
- }
- })
- .named("TreeRangeMap.asMapOfRanges")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(MapTestSuiteBuilder.using(new TestMapGenerator<Range<Integer>, String>() {
- @Override
- public SampleElements<Entry<Range<Integer>, String>> samples() {
- return new SampleElements<Entry<Range<Integer>, String>>(
- mapEntry(Range.singleton(0), "banana"),
- mapEntry(Range.closedOpen(3, 5), "frisbee"),
- mapEntry(Range.atMost(-1), "fruitcake"),
- mapEntry(Range.open(10, 15), "elephant"),
- mapEntry(Range.closed(20, 22), "umbrella"));
- }
-
- @Override
- public Map<Range<Integer>, String> create(Object... elements) {
- RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
- for (Object o : elements) {
- @SuppressWarnings("unchecked")
- Entry<Range<Integer>, String> entry = (Entry<Range<Integer>, String>) o;
- rangeMap.put(entry.getKey(), entry.getValue());
- }
- return rangeMap.subRangeMap(Range.atMost(22)).asMapOfRanges();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Entry<Range<Integer>, String>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<Range<Integer>, String>> order(
- List<Entry<Range<Integer>, String>> insertionOrder) {
- return Range.RANGE_LEX_ORDERING.onResultOf(Maps.<Range<Integer>>keyFunction())
- .sortedCopy(insertionOrder);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Range<Integer>[] createKeyArray(int length) {
- return new Range[length];
- }
-
- @Override
- public String[] createValueArray(int length) {
- return new String[length];
- }
- })
- .named("TreeRangeMap.subRangeMap.asMapOfRanges")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.KNOWN_ORDER)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
- return suite;
- }
-
- private static final ImmutableList<Range<Integer>> RANGES;
- private static final int MIN_BOUND = -2;
- private static final int MAX_BOUND = 2;
- static {
- ImmutableList.Builder<Range<Integer>> builder = ImmutableList.builder();
-
- builder.add(Range.<Integer>all());
-
- // Add one-ended ranges
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- for (BoundType type : BoundType.values()) {
- builder.add(Range.upTo(i, type));
- builder.add(Range.downTo(i, type));
- }
- }
-
- // Add two-ended ranges
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- for (int j = i; j <= MAX_BOUND; j++) {
- for (BoundType lowerType : BoundType.values()) {
- for (BoundType upperType : BoundType.values()) {
- if (i == j & lowerType == OPEN & upperType == OPEN) {
- continue;
- }
- builder.add(Range.range(i, lowerType, j, upperType));
- }
- }
- }
- }
- RANGES = builder.build();
- }
-
- public void testSpanSingleRange() {
- for (Range<Integer> range : RANGES) {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(range, 1);
-
- try {
- assertEquals(range, rangeMap.span());
- assertFalse(range.isEmpty());
- } catch (NoSuchElementException e) {
- assertTrue(range.isEmpty());
- }
- }
- }
-
- public void testSpanTwoRanges() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(range1, 1);
- rangeMap.put(range2, 2);
-
- Range<Integer> expected;
- if (range1.isEmpty()) {
- if (range2.isEmpty()) {
- expected = null;
- } else {
- expected = range2;
- }
- } else {
- if (range2.isEmpty()) {
- expected = range1;
- } else {
- expected = range1.span(range2);
- }
- }
-
- try {
- assertEquals(expected, rangeMap.span());
- assertNotNull(expected);
- } catch (NoSuchElementException e) {
- assertNull(expected);
- }
- }
- }
- }
-
- public void testAllRangesAlone() {
- for (Range<Integer> range : RANGES) {
- Map<Integer, Integer> model = Maps.newHashMap();
- putModel(model, range, 1);
- RangeMap<Integer, Integer> test = TreeRangeMap.create();
- test.put(range, 1);
- verify(model, test);
- }
- }
-
- public void testAllRangePairs() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- Map<Integer, Integer> model = Maps.newHashMap();
- putModel(model, range1, 1);
- putModel(model, range2, 2);
- RangeMap<Integer, Integer> test = TreeRangeMap.create();
- test.put(range1, 1);
- test.put(range2, 2);
- verify(model, test);
- }
- }
- }
-
- public void testAllRangeTriples() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- for (Range<Integer> range3 : RANGES) {
- Map<Integer, Integer> model = Maps.newHashMap();
- putModel(model, range1, 1);
- putModel(model, range2, 2);
- putModel(model, range3, 3);
- RangeMap<Integer, Integer> test = TreeRangeMap.create();
- test.put(range1, 1);
- test.put(range2, 2);
- test.put(range3, 3);
- verify(model, test);
- }
- }
- }
- }
-
- public void testPutAll() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- for (Range<Integer> range3 : RANGES) {
- Map<Integer, Integer> model = Maps.newHashMap();
- putModel(model, range1, 1);
- putModel(model, range2, 2);
- putModel(model, range3, 3);
- RangeMap<Integer, Integer> test = TreeRangeMap.create();
- RangeMap<Integer, Integer> test2 = TreeRangeMap.create();
- // put range2 and range3 into test2, and then put test2 into test
- test.put(range1, 1);
- test2.put(range2, 2);
- test2.put(range3, 3);
- test.putAll(test2);
- verify(model, test);
- }
- }
- }
- }
-
- public void testPutAndRemove() {
- for (Range<Integer> rangeToPut : RANGES) {
- for (Range<Integer> rangeToRemove : RANGES) {
- Map<Integer, Integer> model = Maps.newHashMap();
- putModel(model, rangeToPut, 1);
- removeModel(model, rangeToRemove);
- RangeMap<Integer, Integer> test = TreeRangeMap.create();
- test.put(rangeToPut, 1);
- test.remove(rangeToRemove);
- verify(model, test);
- }
- }
- }
-
- public void testPutTwoAndRemove() {
- for (Range<Integer> rangeToPut1 : RANGES) {
- for (Range<Integer> rangeToPut2 : RANGES) {
- for (Range<Integer> rangeToRemove : RANGES) {
- Map<Integer, Integer> model = Maps.newHashMap();
- putModel(model, rangeToPut1, 1);
- putModel(model, rangeToPut2, 2);
- removeModel(model, rangeToRemove);
- RangeMap<Integer, Integer> test = TreeRangeMap.create();
- test.put(rangeToPut1, 1);
- test.put(rangeToPut2, 2);
- test.remove(rangeToRemove);
- verify(model, test);
- }
- }
- }
- }
-
- public void testSubRangeMapExhaustive() {
- for (Range<Integer> range1 : RANGES) {
- for (Range<Integer> range2 : RANGES) {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(range1, 1);
- rangeMap.put(range2, 2);
-
- for (Range<Integer> subRange : RANGES) {
- RangeMap<Integer, Integer> expected = TreeRangeMap.create();
- for (Map.Entry<Range<Integer>, Integer> entry : rangeMap.asMapOfRanges().entrySet()) {
- if (entry.getKey().isConnected(subRange)) {
- expected.put(entry.getKey().intersection(subRange), entry.getValue());
- }
- }
- RangeMap<Integer, Integer> subRangeMap = rangeMap.subRangeMap(subRange);
- assertEquals(expected, subRangeMap);
- assertEquals(expected.asMapOfRanges(), subRangeMap.asMapOfRanges());
-
- if (!expected.asMapOfRanges().isEmpty()) {
- assertEquals(expected.span(), subRangeMap.span());
- }
-
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- assertEquals(expected.get(i), subRangeMap.get(i));
- }
-
- for (Range<Integer> query : RANGES) {
- assertEquals(
- expected.asMapOfRanges().get(query),
- subRangeMap.asMapOfRanges().get(query));
- }
- }
- }
- }
- }
-
- public void testSubSubRangeMap() {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(Range.open(3, 7), 1);
- rangeMap.put(Range.closed(9, 10), 2);
- rangeMap.put(Range.closed(12, 16), 3);
- RangeMap<Integer, Integer> sub1 = rangeMap.subRangeMap(Range.closed(5, 11));
- assertEquals(ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.closed(9, 10), 2),
- sub1.asMapOfRanges());
- RangeMap<Integer, Integer> sub2 = sub1.subRangeMap(Range.open(6, 15));
- assertEquals(ImmutableMap.of(Range.open(6, 7), 1, Range.closed(9, 10), 2),
- sub2.asMapOfRanges());
- }
-
- public void testSubRangeMapPut() {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(Range.open(3, 7), 1);
- rangeMap.put(Range.closed(9, 10), 2);
- rangeMap.put(Range.closed(12, 16), 3);
- RangeMap<Integer, Integer> sub = rangeMap.subRangeMap(Range.closed(5, 11));
- assertEquals(ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.closed(9, 10), 2),
- sub.asMapOfRanges());
- sub.put(Range.closed(7, 9), 4);
- assertEquals(
- ImmutableMap.of(
- Range.closedOpen(5, 7), 1, Range.closed(7, 9), 4, Range.openClosed(9, 10), 2),
- sub.asMapOfRanges());
- assertEquals(
- ImmutableMap.of(Range.open(3, 7), 1, Range.closed(7, 9), 4, Range.openClosed(9, 10), 2,
- Range.closed(12, 16), 3),
- rangeMap.asMapOfRanges());
-
- try {
- sub.put(Range.open(9, 12), 5);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
-
- sub = sub.subRangeMap(Range.closedOpen(5, 5));
- sub.put(Range.closedOpen(5, 5), 6); // should be a no-op
- assertEquals(
- ImmutableMap.of(Range.open(3, 7), 1, Range.closed(7, 9), 4, Range.openClosed(9, 10), 2,
- Range.closed(12, 16), 3),
- rangeMap.asMapOfRanges());
- }
-
- public void testSubRangeMapRemove() {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(Range.open(3, 7), 1);
- rangeMap.put(Range.closed(9, 10), 2);
- rangeMap.put(Range.closed(12, 16), 3);
- RangeMap<Integer, Integer> sub = rangeMap.subRangeMap(Range.closed(5, 11));
- assertEquals(ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.closed(9, 10), 2),
- sub.asMapOfRanges());
- sub.remove(Range.closed(7, 9));
- assertEquals(
- ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.openClosed(9, 10), 2),
- sub.asMapOfRanges());
- assertEquals(
- ImmutableMap.of(Range.open(3, 7), 1, Range.openClosed(9, 10), 2, Range.closed(12, 16), 3),
- rangeMap.asMapOfRanges());
-
- sub.remove(Range.closed(3, 9));
- assertEquals(
- ImmutableMap.of(Range.openClosed(9, 10), 2),
- sub.asMapOfRanges());
- assertEquals(
- ImmutableMap.of(Range.open(3, 5), 1, Range.openClosed(9, 10), 2, Range.closed(12, 16), 3),
- rangeMap.asMapOfRanges());
- }
-
- public void testSubRangeMapClear() {
- RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
- rangeMap.put(Range.open(3, 7), 1);
- rangeMap.put(Range.closed(9, 10), 2);
- rangeMap.put(Range.closed(12, 16), 3);
- RangeMap<Integer, Integer> sub = rangeMap.subRangeMap(Range.closed(5, 11));
- sub.clear();
- assertEquals(
- ImmutableMap.of(Range.open(3, 5), 1, Range.closed(12, 16), 3),
- rangeMap.asMapOfRanges());
- }
-
- private void verify(Map<Integer, Integer> model, RangeMap<Integer, Integer> test) {
- for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
- assertEquals(model.get(i), test.get(i));
-
- Map.Entry<Range<Integer>, Integer> entry = test.getEntry(i);
- assertEquals(model.containsKey(i), entry != null);
- if (entry != null) {
- assertTrue(test.asMapOfRanges().entrySet().contains(entry));
- }
- }
- for (Range<Integer> range : test.asMapOfRanges().keySet()) {
- assertFalse(range.isEmpty());
- }
- }
-
- private void putModel(Map<Integer, Integer> model, Range<Integer> range, int value) {
- for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
- if (range.contains(i)) {
- model.put(i, value);
- }
- }
- }
-
- private void removeModel(Map<Integer, Integer> model, Range<Integer> range) {
- for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
- if (range.contains(i)) {
- model.remove(i);
- }
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java b/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
deleted file mode 100644
index e67508d..0000000
--- a/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.Range.range;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.annotations.GwtIncompatible;
-
-import java.util.List;
-import java.util.NavigableMap;
-
-/**
- * Tests for {@link TreeRangeSet}.
- *
- * @author Louis Wasserman
- * @author Chris Povirk
- */
-@GwtIncompatible("TreeRangeSet")
-public class TreeRangeSetTest extends AbstractRangeSetTest {
- // TODO(cpovirk): test all of these with the ranges added in the reverse order
-
- private static final ImmutableList<Range<Integer>> QUERY_RANGES;
-
- private static final int MIN_BOUND = -1;
- private static final int MAX_BOUND = 1;
-
- static {
- ImmutableList.Builder<Range<Integer>> queryBuilder = ImmutableList.builder();
-
- queryBuilder.add(Range.<Integer>all());
-
- for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
- for (BoundType boundType : BoundType.values()) {
- queryBuilder.add(Range.upTo(i, boundType));
- queryBuilder.add(Range.downTo(i, boundType));
- }
- queryBuilder.add(Range.singleton(i));
- queryBuilder.add(Range.openClosed(i, i));
- queryBuilder.add(Range.closedOpen(i, i));
-
- for (BoundType lowerBoundType : BoundType.values()) {
- for (int j = i + 1; j <= MAX_BOUND; j++) {
- for (BoundType upperBoundType : BoundType.values()) {
- queryBuilder.add(Range.range(i, lowerBoundType, j, upperBoundType));
- }
- }
- }
- }
- QUERY_RANGES = queryBuilder.build();
- }
-
- void testViewAgainstExpected(RangeSet<Integer> expected, RangeSet<Integer> view) {
- assertEquals(expected, view);
- assertEquals(expected.asRanges(), view.asRanges());
- assertEquals(expected.isEmpty(), view.isEmpty());
-
- if (!expected.isEmpty()) {
- assertEquals(expected.span(), view.span());
- }
-
- for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
- assertEquals(expected.contains(i), view.contains(i));
- assertEquals(expected.rangeContaining(i), view.rangeContaining(i));
- }
- testEnclosing(view);
- if (view instanceof TreeRangeSet) {
- testRangesByLowerBounds((TreeRangeSet<Integer>) view, expected.asRanges());
- }
- }
-
- private static final ImmutableList<Cut<Integer>> CUTS_TO_TEST;
-
- static {
- List<Cut<Integer>> cutsToTest = Lists.newArrayList();
- for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
- cutsToTest.add(Cut.belowValue(i));
- cutsToTest.add(Cut.aboveValue(i));
- }
- cutsToTest.add(Cut.<Integer>aboveAll());
- cutsToTest.add(Cut.<Integer>belowAll());
- CUTS_TO_TEST = ImmutableList.copyOf(cutsToTest);
- }
-
- private void testRangesByLowerBounds(
- TreeRangeSet<Integer> rangeSet, Iterable<Range<Integer>> expectedRanges) {
- NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByLowerBound = Maps.newTreeMap();
- for (Range<Integer> range : expectedRanges) {
- expectedRangesByLowerBound.put(range.lowerBound, range);
- }
-
- NavigableMap<Cut<Integer>, Range<Integer>> rangesByLowerBound = rangeSet.rangesByLowerBound;
- testNavigationAgainstExpected(expectedRangesByLowerBound, rangesByLowerBound, CUTS_TO_TEST);
- }
-
- <K, V> void testNavigationAgainstExpected(
- NavigableMap<K, V> expected, NavigableMap<K, V> navigableMap, Iterable<K> keysToTest) {
- for (K key : keysToTest) {
- assertEquals(expected.lowerEntry(key), navigableMap.lowerEntry(key));
- assertEquals(expected.floorEntry(key), navigableMap.floorEntry(key));
- assertEquals(expected.ceilingEntry(key), navigableMap.ceilingEntry(key));
- assertEquals(expected.higherEntry(key), navigableMap.higherEntry(key));
- for (boolean inclusive : new boolean[] {false, true}) {
- ASSERT.that(navigableMap.headMap(key, inclusive).entrySet())
- .has().allFrom(expected.headMap(key, inclusive).entrySet()).inOrder();
- ASSERT.that(navigableMap.tailMap(key, inclusive).entrySet())
- .has().allFrom(expected.tailMap(key, inclusive).entrySet()).inOrder();
- ASSERT.that(navigableMap.headMap(key, inclusive).descendingMap().entrySet())
- .has().allFrom(expected.headMap(key, inclusive).descendingMap().entrySet()).inOrder();
- ASSERT.that(navigableMap.tailMap(key, inclusive).descendingMap().entrySet())
- .has().allFrom(expected.tailMap(key, inclusive).descendingMap().entrySet()).inOrder();
- }
- }
- }
-
- public void testEnclosing(RangeSet<Integer> rangeSet) {
- for (Range<Integer> query : QUERY_RANGES) {
- boolean expectEnclose = false;
- for (Range<Integer> expectedRange : rangeSet.asRanges()) {
- if (expectedRange.encloses(query)) {
- expectEnclose = true;
- break;
- }
- }
-
- assertEquals(rangeSet + " was incorrect on encloses(" + query + ")", expectEnclose,
- rangeSet.encloses(query));
- }
- }
-
- public void testAllSingleRangesComplementAgainstRemove() {
- for (Range<Integer> range : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range);
-
- TreeRangeSet<Integer> complement = TreeRangeSet.create();
- complement.add(Range.<Integer>all());
- complement.remove(range);
-
- assertEquals(complement, rangeSet.complement());
- ASSERT.that(rangeSet.complement().asRanges()).has().allFrom(complement.asRanges()).inOrder();
- }
- }
-
- public void testInvariantsEmpty() {
- testInvariants(TreeRangeSet.create());
- }
-
- public void testAllSingleRangesEnclosing() {
- for (Range<Integer> range : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range);
- testEnclosing(rangeSet);
- testEnclosing(rangeSet.complement());
- }
- }
-
- public void testAllTwoRangesEnclosing() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
- testEnclosing(rangeSet);
- testEnclosing(rangeSet.complement());
- }
- }
- }
-
- public void testCreateCopy() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
-
- assertEquals(rangeSet, TreeRangeSet.create(rangeSet));
- }
- }
- }
-
- private RangeSet<Integer> expectedSubRangeSet(
- RangeSet<Integer> rangeSet, Range<Integer> subRange) {
- RangeSet<Integer> expected = TreeRangeSet.create();
- for (Range<Integer> range : rangeSet.asRanges()) {
- if (range.isConnected(subRange)) {
- expected.add(range.intersection(subRange));
- }
- }
- return expected;
- }
-
- private RangeSet<Integer> expectedComplement(RangeSet<Integer> rangeSet) {
- RangeSet<Integer> expected = TreeRangeSet.create();
- expected.add(Range.<Integer>all());
- expected.removeAll(rangeSet);
- return expected;
- }
-
- public void testSubRangeSet() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
- for (Range<Integer> subRange : QUERY_RANGES) {
- testViewAgainstExpected(
- expectedSubRangeSet(rangeSet, subRange), rangeSet.subRangeSet(subRange));
- }
- }
- }
- }
-
- public void testComplement() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
- testViewAgainstExpected(expectedComplement(rangeSet), rangeSet.complement());
- }
- }
- }
-
- public void testSubRangeSetOfComplement() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
- for (Range<Integer> subRange : QUERY_RANGES) {
- testViewAgainstExpected(
- expectedSubRangeSet(expectedComplement(rangeSet), subRange),
- rangeSet.complement().subRangeSet(subRange));
- }
- }
- }
- }
-
- public void testComplementOfSubRangeSet() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
- for (Range<Integer> subRange : QUERY_RANGES) {
- testViewAgainstExpected(
- expectedComplement(expectedSubRangeSet(rangeSet, subRange)),
- rangeSet.subRangeSet(subRange).complement());
- }
- }
- }
- }
-
- public void testRangesByUpperBound() {
- for (Range<Integer> range1 : QUERY_RANGES) {
- for (Range<Integer> range2 : QUERY_RANGES) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(range1);
- rangeSet.add(range2);
-
- NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByUpperBound = Maps.newTreeMap();
- for (Range<Integer> range : rangeSet.asRanges()) {
- expectedRangesByUpperBound.put(range.upperBound, range);
- }
- testNavigationAgainstExpected(expectedRangesByUpperBound,
- new TreeRangeSet.RangesByUpperBound<Integer>(rangeSet.rangesByLowerBound),
- CUTS_TO_TEST);
- }
- }
- }
-
- public void testMergesConnectedWithOverlap() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 4));
- rangeSet.add(Range.open(2, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
- }
-
- public void testMergesConnectedDisjoint() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 4));
- rangeSet.add(Range.open(4, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
- }
-
- public void testIgnoresSmallerSharingNoBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 6));
- rangeSet.add(Range.open(2, 4));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testIgnoresSmallerSharingLowerBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 6));
- rangeSet.add(Range.closed(1, 4));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testIgnoresSmallerSharingUpperBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 6));
- rangeSet.add(Range.closed(3, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testIgnoresEqual() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 6));
- rangeSet.add(Range.closed(1, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testExtendSameLowerBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 4));
- rangeSet.add(Range.closed(1, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testExtendSameUpperBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.add(Range.closed(1, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testExtendBothDirections() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 4));
- rangeSet.add(Range.closed(1, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testAddEmpty() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closedOpen(3, 3));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- ASSERT.that(rangeSet.complement().asRanges()).has().allOf(Range.<Integer>all()).inOrder();
- }
-
- public void testFillHoleExactly() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closedOpen(1, 3));
- rangeSet.add(Range.closedOpen(4, 6));
- rangeSet.add(Range.closedOpen(3, 4));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
- }
-
- public void testFillHoleWithOverlap() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closedOpen(1, 3));
- rangeSet.add(Range.closedOpen(4, 6));
- rangeSet.add(Range.closedOpen(2, 5));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
- }
-
- public void testAddManyPairs() {
- for (int aLow = 0; aLow < 6; aLow++) {
- for (int aHigh = 0; aHigh < 6; aHigh++) {
- for (BoundType aLowType : BoundType.values()) {
- for (BoundType aHighType : BoundType.values()) {
- if ((aLow == aHigh && aLowType == OPEN && aHighType == OPEN) || aLow > aHigh) {
- continue;
- }
- for (int bLow = 0; bLow < 6; bLow++) {
- for (int bHigh = 0; bHigh < 6; bHigh++) {
- for (BoundType bLowType : BoundType.values()) {
- for (BoundType bHighType : BoundType.values()) {
- if ((bLow == bHigh && bLowType == OPEN && bHighType == OPEN) || bLow > bHigh) {
- continue;
- }
- doPairTest(range(aLow, aLowType, aHigh, aHighType),
- range(bLow, bLowType, bHigh, bHighType));
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- private static void doPairTest(Range<Integer> a, Range<Integer> b) {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(a);
- rangeSet.add(b);
- if (a.isEmpty() && b.isEmpty()) {
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- } else if (a.isEmpty()) {
- ASSERT.that(rangeSet.asRanges()).has().item(b);
- } else if (b.isEmpty()) {
- ASSERT.that(rangeSet.asRanges()).has().item(a);
- } else if (a.isConnected(b)) {
- ASSERT.that(rangeSet.asRanges()).has().allOf(a.span(b)).inOrder();
- } else {
- if (a.lowerEndpoint() < b.lowerEndpoint()) {
- ASSERT.that(rangeSet.asRanges()).has().allOf(a, b).inOrder();
- } else {
- ASSERT.that(rangeSet.asRanges()).has().allOf(b, a).inOrder();
- }
- }
- }
-
- public void testRemoveEmpty() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(1, 6));
- rangeSet.remove(Range.closedOpen(3, 3));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
- }
-
- public void testRemovePartSharingLowerBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 5));
- rangeSet.remove(Range.closedOpen(3, 5));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.singleton(5));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(5), Range.greaterThan(5)).inOrder();
- }
-
- public void testRemovePartSharingUpperBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 5));
- rangeSet.remove(Range.openClosed(3, 5));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().item(Range.singleton(3));
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.lessThan(3), Range.greaterThan(3)).inOrder();
- }
-
- public void testRemoveMiddle() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.atMost(6));
- rangeSet.remove(Range.closedOpen(3, 4));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().allOf(Range.lessThan(3), Range.closed(4, 6)).inOrder();
- ASSERT.that(rangeSet.complement().asRanges())
- .has().allOf(Range.closedOpen(3, 4), Range.greaterThan(6)).inOrder();
- }
-
- public void testRemoveNoOverlap() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closedOpen(1, 3));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().allOf(Range.closed(3, 6)).inOrder();
- }
-
- public void testRemovePartFromBelowLowerBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closed(1, 3));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().allOf(Range.openClosed(3, 6)).inOrder();
- }
-
- public void testRemovePartFromAboveUpperBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closed(6, 9));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).has().allOf(Range.closedOpen(3, 6)).inOrder();
- }
-
- public void testRemoveExact() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closed(3, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- }
-
- public void testRemoveAllFromBelowLowerBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closed(2, 6));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- }
-
- public void testRemoveAllFromAboveUpperBound() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closed(3, 7));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- }
-
- public void testRemoveAllExtendingBothDirections() {
- TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 6));
- rangeSet.remove(Range.closed(2, 7));
- testInvariants(rangeSet);
- ASSERT.that(rangeSet.asRanges()).isEmpty();
- }
-
- public void testRangeContaining1() {
- RangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 10));
- assertEquals(Range.closed(3, 10), rangeSet.rangeContaining(5));
- assertTrue(rangeSet.contains(5));
- assertNull(rangeSet.rangeContaining(1));
- assertFalse(rangeSet.contains(1));
- }
-
- public void testRangeContaining2() {
- RangeSet<Integer> rangeSet = TreeRangeSet.create();
- rangeSet.add(Range.closed(3, 10));
- rangeSet.remove(Range.open(5, 7));
- assertEquals(Range.closed(3, 5), rangeSet.rangeContaining(5));
- assertTrue(rangeSet.contains(5));
- assertEquals(Range.closed(7, 10), rangeSet.rangeContaining(8));
- assertTrue(rangeSet.contains(8));
- assertNull(rangeSet.rangeContaining(6));
- assertFalse(rangeSet.contains(6));
- }
-}
diff --git a/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java b/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java
index 1a0d555..79862c7 100644
--- a/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java
+++ b/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java
@@ -17,11 +17,9 @@
package com.google.common.eventbus;
import com.google.common.collect.Lists;
-
-import junit.framework.TestCase;
-
import java.util.List;
import java.util.concurrent.Executor;
+import junit.framework.TestCase;
/**
* Test case for {@link AsyncEventBus}.
diff --git a/guava-tests/test/com/google/common/eventbus/EventBusTest.java b/guava-tests/test/com/google/common/eventbus/EventBusTest.java
index 0180557..2a11784 100644
--- a/guava-tests/test/com/google/common/eventbus/EventBusTest.java
+++ b/guava-tests/test/com/google/common/eventbus/EventBusTest.java
@@ -16,17 +16,11 @@
package com.google.common.eventbus;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-
-import junit.framework.TestCase;
-
import java.util.Collection;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+import junit.framework.TestCase;
/**
* Test case for {@link EventBus}.
@@ -47,6 +41,11 @@ public class EventBusTest extends TestCase {
public void testBasicCatcherDistribution() {
StringCatcher catcher = new StringCatcher();
bus.register(catcher);
+
+ Set<EventHandler> wrappers = bus.getHandlersForEventType(String.class);
+ assertNotNull("Should have at least one method registered.", wrappers);
+ assertEquals("One method should be registered.", 1, wrappers.size());
+
bus.post(EVENT);
List<String> events = catcher.getEvents();
@@ -210,57 +209,12 @@ public class EventBusTest extends TestCase {
expectedEvents, catcher2.getEvents());
}
- // NOTE: This test will always pass if register() is thread-safe but may also
- // pass if it isn't, though this is unlikely.
-
- public void testRegisterThreadSafety() throws Exception {
- List<StringCatcher> catchers = Lists.newCopyOnWriteArrayList();
- List<Future<?>> futures = Lists.newArrayList();
- ExecutorService executor = Executors.newFixedThreadPool(10);
- int numberOfCatchers = 10000;
- for (int i = 0; i < numberOfCatchers; i++) {
- futures.add(executor.submit(new Registrator(bus, catchers)));
- }
- for (int i = 0; i < numberOfCatchers; i++) {
- futures.get(i).get();
- }
- assertEquals("Unexpected number of catchers in the list",
- numberOfCatchers, catchers.size());
- bus.post(EVENT);
- List<String> expectedEvents = ImmutableList.of(EVENT);
- for (StringCatcher catcher : catchers) {
- assertEquals("One of the registered catchers did not receive an event.",
- expectedEvents, catcher.getEvents());
- }
- }
-
private <T> void assertContains(T element, Collection<T> collection) {
assertTrue("Collection must contain " + element,
collection.contains(element));
}
/**
- * Runnable which registers a StringCatcher on an event bus and adds it to a
- * list.
- */
- private static class Registrator implements Runnable {
- private final EventBus bus;
- private final List<StringCatcher> catchers;
-
- Registrator(EventBus bus, List<StringCatcher> catchers) {
- this.bus = bus;
- this.catchers = catchers;
- }
-
- @Override
- public void run() {
- StringCatcher catcher = new StringCatcher();
- bus.register(catcher);
- catchers.add(catcher);
- }
- }
-
- /**
* A collector for DeadEvents.
*
* @author cbiffle
diff --git a/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java b/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java
index bdbc332..00a189a 100644
--- a/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java
+++ b/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java
@@ -16,12 +16,9 @@
package com.google.common.eventbus;
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.TestCase;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import junit.framework.TestCase;
/**
* Test case for {@link EventHandler}.
@@ -59,6 +56,31 @@ public class EventHandlerTest extends TestCase {
methodArgument == FIXTURE_ARGUMENT);
}
+ /**
+ * Checks that EventHandler's constructor disallows null methods.
+ */
+ public void testRejectionOfNullMethods() {
+ try {
+ new EventHandler(this, null);
+ fail("EventHandler must immediately reject null methods.");
+ } catch (NullPointerException e) {
+ // Hooray!
+ }
+ }
+
+ /**
+ * Checks that EventHandler's constructor disallows null targets.
+ */
+ public void testRejectionOfNullTargets() {
+ Method method = getRecordingMethod();
+ try {
+ new EventHandler(null, method);
+ fail("EventHandler must immediately reject null targets.");
+ } catch (NullPointerException e) {
+ // Huzzah!
+ }
+ }
+
public void testExceptionWrapping() {
Method method = getExceptionThrowingMethod();
EventHandler handler = new EventHandler(this, method);
@@ -84,17 +106,6 @@ public class EventHandlerTest extends TestCase {
}
}
- public void testEquals() throws Exception {
- Method charAt = String.class.getMethod("charAt", int.class);
- Method concat = String.class.getMethod("concat", String.class);
- new EqualsTester()
- .addEqualityGroup(
- new EventHandler("foo", charAt), new EventHandler("foo", charAt))
- .addEqualityGroup(new EventHandler("bar", charAt))
- .addEqualityGroup(new EventHandler("foo", concat))
- .testEquals();
- }
-
/**
* Gets a reference to {@link #recordingMethod(Object)}.
*
diff --git a/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java b/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java
deleted file mode 100644
index 5024370..0000000
--- a/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.eventbus;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-import java.lang.reflect.Method;
-
-import javax.annotation.Nullable;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
-
- public PackageSanityTests() throws Exception {
- setDefault(EventHandler.class, new DummyHandler().toEventHandler());
- setDefault(Method.class, DummyHandler.handlerMethod());
- }
-
- private static class DummyHandler {
-
- @SuppressWarnings("unused") // Used by reflection
- public void handle(@Nullable Object anything) {}
-
- EventHandler toEventHandler() throws Exception {
- return new EventHandler(this, handlerMethod());
- }
-
- private static Method handlerMethod() throws NoSuchMethodException {
- return DummyHandler.class.getMethod("handle", Object.class);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java b/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java
index f39f5f8..3f23050 100644
--- a/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java
+++ b/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java
@@ -17,10 +17,8 @@
package com.google.common.eventbus;
import com.google.common.collect.Lists;
-
-import junit.framework.TestCase;
-
import java.util.List;
+import junit.framework.TestCase;
/**
* Validate that {@link EventBus} behaves carefully when listeners publish
diff --git a/guava-tests/test/com/google/common/eventbus/StringCatcher.java b/guava-tests/test/com/google/common/eventbus/StringCatcher.java
index d4bfdbd..fa2e446 100644
--- a/guava-tests/test/com/google/common/eventbus/StringCatcher.java
+++ b/guava-tests/test/com/google/common/eventbus/StringCatcher.java
@@ -17,12 +17,8 @@
package com.google.common.eventbus;
import com.google.common.collect.Lists;
-
-import junit.framework.Assert;
-
import java.util.List;
-
-import javax.annotation.Nullable;
+import junit.framework.Assert;
/**
* A simple EventHandler mock that records Strings.
@@ -36,11 +32,11 @@ public class StringCatcher {
private List<String> events = Lists.newArrayList();
@Subscribe
- public void hereHaveAString(@Nullable String string) {
+ public void hereHaveAString(String string) {
events.add(string);
}
- public void methodWithoutAnnotation(@Nullable String string) {
+ public void methodWithoutAnnotation(String string) {
Assert.fail("Event bus must not call methods without @Subscribe!");
}
diff --git a/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java b/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java
deleted file mode 100644
index a28ba00..0000000
--- a/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.eventbus.outside;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.collect.Lists;
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.Subscribe;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-
-/**
- * Test that EventBus finds the correct handlers.
- *
- * This test must be outside the c.g.c.eventbus package to test correctly.
- * @author Louis Wasserman
- */
-public class AnnotatedHandlerFinderTests {
-
- private static final Object EVENT = new Object();
-
- abstract static class AbstractEventBusTest<H> extends TestCase {
- abstract H createHandler();
-
- private H handler;
-
- H getHandler() {
- return handler;
- }
-
- @Override
- protected void setUp() throws Exception {
- handler = createHandler();
- EventBus bus = new EventBus();
- bus.register(handler);
- bus.post(EVENT);
- }
-
- @Override
- protected void tearDown() throws Exception {
- handler = null;
- }
- }
-
- /*
- * We break the tests up based on whether they are annotated or abstract in the superclass.
- */
- public static class BaseHandlerFinderTest extends
- AbstractEventBusTest<BaseHandlerFinderTest.Handler> {
- static class Handler {
- final List<Object> nonSubscriberEvents = Lists.newArrayList();
- final List<Object> subscriberEvents = Lists.newArrayList();
-
- public void notASubscriber(Object o) {
- nonSubscriberEvents.add(o);
- }
-
- @Subscribe
- public void subscriber(Object o) {
- subscriberEvents.add(o);
- }
- }
-
- public void testNonSubscriber() {
- ASSERT.that(getHandler().nonSubscriberEvents).isEmpty();
- }
-
- public void testSubscriber() {
- ASSERT.that(getHandler().subscriberEvents).has().item(EVENT);
- }
-
- @Override
- Handler createHandler() {
- return new Handler();
- }
- }
-
- public static class AnnotatedAndAbstractInSuperclassTest extends
- AbstractEventBusTest<AnnotatedAndAbstractInSuperclassTest.SubClass> {
- abstract static class SuperClass {
- @Subscribe
- public abstract void overriddenAndAnnotatedInSubclass(Object o);
-
- @Subscribe
- public abstract void overriddenInSubclass(Object o);
- }
-
- static class SubClass extends SuperClass {
- final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
- final List<Object> overriddenInSubclassEvents = Lists.newArrayList();
-
- @Subscribe
- @Override
- public void overriddenAndAnnotatedInSubclass(Object o) {
- overriddenAndAnnotatedInSubclassEvents.add(o);
- }
-
- @Override
- public void overriddenInSubclass(Object o) {
- overriddenInSubclassEvents.add(o);
- }
- }
-
- public void testOverriddenAndAnnotatedInSubclass() {
- ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
- }
-
- public void testOverriddenNotAnnotatedInSubclass() {
- ASSERT.that(getHandler().overriddenInSubclassEvents).has().item(EVENT);
- }
-
- @Override
- SubClass createHandler() {
- return new SubClass();
- }
- }
-
- public static class AnnotatedNotAbstractInSuperclassTest extends
- AbstractEventBusTest<AnnotatedNotAbstractInSuperclassTest.SubClass> {
- static class SuperClass {
- final List<Object> notOverriddenInSubclassEvents = Lists.newArrayList();
- final List<Object> overriddenNotAnnotatedInSubclassEvents = Lists.newArrayList();
- final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
- final List<Object> differentlyOverriddenNotAnnotatedInSubclassBadEvents = Lists
- .newArrayList();
- final List<Object> differentlyOverriddenAnnotatedInSubclassBadEvents = Lists.newArrayList();
-
- @Subscribe
- public void notOverriddenInSubclass(Object o) {
- notOverriddenInSubclassEvents.add(o);
- }
-
- @Subscribe
- public void overriddenNotAnnotatedInSubclass(Object o) {
- overriddenNotAnnotatedInSubclassEvents.add(o);
- }
-
- @Subscribe
- public void overriddenAndAnnotatedInSubclass(Object o) {
- overriddenAndAnnotatedInSubclassEvents.add(o);
- }
-
- @Subscribe
- public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
- // the subclass overrides this and does *not* call super.dONAIS(o)
- differentlyOverriddenNotAnnotatedInSubclassBadEvents.add(o);
- }
-
- @Subscribe
- public void differentlyOverriddenAnnotatedInSubclass(Object o) {
- // the subclass overrides this and does *not* call super.dOAIS(o)
- differentlyOverriddenAnnotatedInSubclassBadEvents.add(o);
- }
- }
-
- static class SubClass extends SuperClass {
- final List<Object> differentlyOverriddenNotAnnotatedInSubclassGoodEvents = Lists
- .newArrayList();
- final List<Object> differentlyOverriddenAnnotatedInSubclassGoodEvents = Lists.newArrayList();
-
- @Override
- public void overriddenNotAnnotatedInSubclass(Object o) {
- super.overriddenNotAnnotatedInSubclass(o);
- }
-
- @Subscribe
- @Override
- public void overriddenAndAnnotatedInSubclass(Object o) {
- super.overriddenAndAnnotatedInSubclass(o);
- }
-
- @Override
- public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
- differentlyOverriddenNotAnnotatedInSubclassGoodEvents.add(o);
- }
-
- @Subscribe
- @Override
- public void differentlyOverriddenAnnotatedInSubclass(Object o) {
- differentlyOverriddenAnnotatedInSubclassGoodEvents.add(o);
- }
- }
-
- public void testNotOverriddenInSubclass() {
- ASSERT.that(getHandler().notOverriddenInSubclassEvents).has().item(EVENT);
- }
-
- public void testOverriddenNotAnnotatedInSubclass() {
- ASSERT.that(getHandler().overriddenNotAnnotatedInSubclassEvents).has().item(EVENT);
- }
-
- public void testDifferentlyOverriddenNotAnnotatedInSubclass() {
- ASSERT
- .that(getHandler().differentlyOverriddenNotAnnotatedInSubclassGoodEvents)
- .has().item(EVENT);
- ASSERT.that(getHandler().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty();
- }
-
- public void testOverriddenAndAnnotatedInSubclass() {
- ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
- }
-
- public void testDifferentlyOverriddenAndAnnotatedInSubclass() {
- ASSERT
- .that(getHandler().differentlyOverriddenAnnotatedInSubclassGoodEvents)
- .has().item(EVENT);
- ASSERT.that(getHandler().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty();
- }
-
- @Override
- SubClass createHandler() {
- return new SubClass();
- }
- }
-
- public static class AbstractNotAnnotatedInSuperclassTest extends
- AbstractEventBusTest<AbstractNotAnnotatedInSuperclassTest.SubClass> {
- abstract static class SuperClass {
- public abstract void overriddenInSubclassNowhereAnnotated(Object o);
-
- public abstract void overriddenAndAnnotatedInSubclass(Object o);
- }
-
- static class SubClass extends SuperClass {
- final List<Object> overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList();
- final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
-
- @Override
- public void overriddenInSubclassNowhereAnnotated(Object o) {
- overriddenInSubclassNowhereAnnotatedEvents.add(o);
- }
-
- @Subscribe
- @Override
- public void overriddenAndAnnotatedInSubclass(Object o) {
- overriddenAndAnnotatedInSubclassEvents.add(o);
- }
- }
-
- public void testOverriddenAndAnnotatedInSubclass() {
- ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
- }
-
- public void testOverriddenInSubclassNowhereAnnotated() {
- ASSERT.that(getHandler().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
- }
-
- @Override
- SubClass createHandler() {
- return new SubClass();
- }
- }
-
- public static class NeitherAbstractNorAnnotatedInSuperclassTest extends
- AbstractEventBusTest<NeitherAbstractNorAnnotatedInSuperclassTest.SubClass> {
- static class SuperClass {
- final List<Object> neitherOverriddenNorAnnotatedEvents = Lists.newArrayList();
- final List<Object> overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList();
- final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
-
- public void neitherOverriddenNorAnnotated(Object o) {
- neitherOverriddenNorAnnotatedEvents.add(o);
- }
-
- public void overriddenInSubclassNowhereAnnotated(Object o) {
- overriddenInSubclassNowhereAnnotatedEvents.add(o);
- }
-
- public void overriddenAndAnnotatedInSubclass(Object o) {
- overriddenAndAnnotatedInSubclassEvents.add(o);
- }
- }
-
- static class SubClass extends SuperClass {
- @Override
- public void overriddenInSubclassNowhereAnnotated(Object o) {
- super.overriddenInSubclassNowhereAnnotated(o);
- }
-
- @Subscribe
- @Override
- public void overriddenAndAnnotatedInSubclass(Object o) {
- super.overriddenAndAnnotatedInSubclass(o);
- }
- }
-
- public void testNeitherOverriddenNorAnnotated() {
- ASSERT.that(getHandler().neitherOverriddenNorAnnotatedEvents).isEmpty();
- }
-
- public void testOverriddenInSubclassNowhereAnnotated() {
- ASSERT.that(getHandler().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
- }
-
- public void testOverriddenAndAnnotatedInSubclass() {
- ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
- }
-
- @Override
- SubClass createHandler() {
- return new SubClass();
- }
- }
-
- public static class DeepInterfaceTest extends
- AbstractEventBusTest<DeepInterfaceTest.HandlerClass> {
- interface Interface1 {
- @Subscribe
- void annotatedIn1(Object o);
-
- @Subscribe
- void annotatedIn1And2(Object o);
-
- @Subscribe
- void annotatedIn1And2AndClass(Object o);
-
- void declaredIn1AnnotatedIn2(Object o);
-
- void declaredIn1AnnotatedInClass(Object o);
-
- void nowhereAnnotated(Object o);
- }
-
- interface Interface2 extends Interface1 {
- @Override
- @Subscribe
- void declaredIn1AnnotatedIn2(Object o);
-
- @Override
- @Subscribe
- void annotatedIn1And2(Object o);
-
- @Override
- @Subscribe
- void annotatedIn1And2AndClass(Object o);
-
- void declaredIn2AnnotatedInClass(Object o);
-
- @Subscribe
- void annotatedIn2(Object o);
- }
-
- static class HandlerClass implements Interface2 {
- final List<Object> annotatedIn1Events = Lists.newArrayList();
- final List<Object> annotatedIn1And2Events = Lists.newArrayList();
- final List<Object> annotatedIn1And2AndClassEvents = Lists.newArrayList();
- final List<Object> declaredIn1AnnotatedIn2Events = Lists.newArrayList();
- final List<Object> declaredIn1AnnotatedInClassEvents = Lists.newArrayList();
- final List<Object> declaredIn2AnnotatedInClassEvents = Lists.newArrayList();
- final List<Object> annotatedIn2Events = Lists.newArrayList();
- final List<Object> nowhereAnnotatedEvents = Lists.newArrayList();
-
- @Override
- public void annotatedIn1(Object o) {
- annotatedIn1Events.add(o);
- }
-
- @Subscribe
- @Override
- public void declaredIn1AnnotatedInClass(Object o) {
- declaredIn1AnnotatedInClassEvents.add(o);
- }
-
- @Override
- public void declaredIn1AnnotatedIn2(Object o) {
- declaredIn1AnnotatedIn2Events.add(o);
- }
-
- @Override
- public void annotatedIn1And2(Object o) {
- annotatedIn1And2Events.add(o);
- }
-
- @Subscribe
- @Override
- public void annotatedIn1And2AndClass(Object o) {
- annotatedIn1And2AndClassEvents.add(o);
- }
-
- @Subscribe
- @Override
- public void declaredIn2AnnotatedInClass(Object o) {
- declaredIn2AnnotatedInClassEvents.add(o);
- }
-
- @Override
- public void annotatedIn2(Object o) {
- annotatedIn2Events.add(o);
- }
-
- @Override
- public void nowhereAnnotated(Object o) {
- nowhereAnnotatedEvents.add(o);
- }
- }
-
- public void testAnnotatedIn1() {
- ASSERT.that(getHandler().annotatedIn1Events).has().item(EVENT);
- }
-
- public void testAnnotatedIn2() {
- ASSERT.that(getHandler().annotatedIn2Events).has().item(EVENT);
- }
-
- public void testAnnotatedIn1And2() {
- ASSERT.that(getHandler().annotatedIn1And2Events).has().item(EVENT);
- }
-
- public void testAnnotatedIn1And2AndClass() {
- ASSERT.that(getHandler().annotatedIn1And2AndClassEvents).has().item(EVENT);
- }
-
- public void testDeclaredIn1AnnotatedIn2() {
- ASSERT.that(getHandler().declaredIn1AnnotatedIn2Events).has().item(EVENT);
- }
-
- public void testDeclaredIn1AnnotatedInClass() {
- ASSERT.that(getHandler().declaredIn1AnnotatedInClassEvents).has().item(EVENT);
- }
-
- public void testDeclaredIn2AnnotatedInClass() {
- ASSERT.that(getHandler().declaredIn2AnnotatedInClassEvents).has().item(EVENT);
- }
-
- public void testNowhereAnnotated() {
- ASSERT.that(getHandler().nowhereAnnotatedEvents).isEmpty();
- }
-
- @Override
- HandlerClass createHandler() {
- return new HandlerClass();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java b/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java
deleted file mode 100644
index d23e021..0000000
--- a/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.eventbus.outside;
-
-import com.google.common.eventbus.EventBus;
-import com.google.common.eventbus.Subscribe;
-
-import junit.framework.TestCase;
-
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Test cases for {@code EventBus} that must not be in the same package.
- *
- * @author Louis Wasserman
- */
-public class OutsideEventBusTest extends TestCase {
-
- /*
- * If you do this test from common.eventbus.EventBusTest, it doesn't actually test the behavior.
- * That is, even if exactly the same method works from inside the common.eventbus package tests,
- * it can fail here.
- */
- public void testAnonymous() {
- final AtomicReference<String> holder = new AtomicReference<String>();
- final AtomicInteger deliveries = new AtomicInteger();
- EventBus bus = new EventBus();
- bus.register(new Object() {
- @Subscribe
- public void accept(String str) {
- holder.set(str);
- deliveries.incrementAndGet();
- }
- });
-
- String EVENT = "Hello!";
- bus.post(EVENT);
-
- assertEquals("Only one event should be delivered.", 1, deliveries.get());
- assertEquals("Correct string should be delivered.", EVENT, holder.get());
- }
-}
diff --git a/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java b/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java
deleted file mode 100644
index 53a55a5..0000000
--- a/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.hash;
-
-import static com.google.common.base.Charsets.UTF_16LE;
-import static org.junit.Assert.assertArrayEquals;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Random;
-
-/**
- * Tests for AbstractByteHasher.
- *
- * @author Colin Decker
- */
-public class AbstractByteHasherTest extends TestCase {
-
- public void testBytes() {
- TestHasher hasher = new TestHasher(); // byte order insignificant here
- byte[] expected = {1, 2, 3, 4, 5, 6, 7, 8};
- hasher.putByte((byte) 1);
- hasher.putBytes(new byte[]{2, 3, 4, 5, 6});
- hasher.putByte((byte) 7);
- hasher.putBytes(new byte[]{});
- hasher.putBytes(new byte[]{8});
- hasher.assertBytes(expected);
- }
-
- public void testShort() {
- TestHasher hasher = new TestHasher();
- hasher.putShort((short) 0x0201);
- hasher.assertBytes(new byte[]{1, 2});
- }
-
- public void testInt() {
- TestHasher hasher = new TestHasher();
- hasher.putInt(0x04030201);
- hasher.assertBytes(new byte[]{1, 2, 3, 4});
- }
-
- public void testLong() {
- TestHasher hasher = new TestHasher();
- hasher.putLong(0x0807060504030201L);
- hasher.assertBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
- }
-
- public void testChar() {
- TestHasher hasher = new TestHasher();
- hasher.putChar((char) 0x0201);
- hasher.assertBytes(new byte[]{1, 2});
- }
-
- public void testString() {
- Random random = new Random();
- for (int i = 0; i < 100; i++) {
- byte[] bytes = new byte[64];
- random.nextBytes(bytes);
- String s = new String(bytes, UTF_16LE); // so all random strings are valid
- assertEquals(
- new TestHasher().putString(s).hash(),
- new TestHasher().putBytes(s.getBytes(UTF_16LE)).hash());
- assertEquals(
- new TestHasher().putString(s).hash(),
- new TestHasher().putString(s, UTF_16LE).hash());
- }
- }
-
- public void testFloat() {
- TestHasher hasher = new TestHasher();
- hasher.putFloat(Float.intBitsToFloat(0x04030201));
- hasher.assertBytes(new byte[]{1, 2, 3, 4});
- }
-
- public void testDouble() {
- TestHasher hasher = new TestHasher();
- hasher.putDouble(Double.longBitsToDouble(0x0807060504030201L));
- hasher.assertBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
- }
-
- public void testCorrectExceptions() {
- TestHasher hasher = new TestHasher();
- try {
- hasher.putBytes(new byte[8], -1, 4);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- hasher.putBytes(new byte[8], 0, 16);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- try {
- hasher.putBytes(new byte[8], 0, -1);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
- }
-
- private class TestHasher extends AbstractByteHasher {
-
- private final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- @Override
- protected void update(byte b) {
- out.write(b);
- }
-
- @Override
- protected void update(byte[] b, int off, int len) {
- out.write(b, off, len);
- }
-
- byte[] bytes() {
- return out.toByteArray();
- }
-
- void assertBytes(byte[] expected) {
- assertArrayEquals(expected, bytes());
- }
-
- @Override
- public HashCode hash() {
- return HashCodes.fromBytesNoCopy(bytes());
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java b/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java
index 2cec063..b4edf42 100644
--- a/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java
+++ b/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java
@@ -1,18 +1,4 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
@@ -36,8 +22,8 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
* Constructs two trivial HashFunctions (output := input), one streaming and one non-streaming,
* and checks that their results are identical, no matter which newHasher version we used.
*/
- public void testExhaustive() {
- List<Hasher> hashers = ImmutableList.of(
+ public void test() {
+ List<Hasher> hashers = ImmutableList.of(
new StreamingVersion().newHasher(),
new StreamingVersion().newHasher(52),
new NonStreamingVersion().newHasher(),
@@ -54,43 +40,7 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
assertEquals(codes[i - 1], codes[i]);
}
}
-
- public void testPutStringWithLowSurrogate() {
- // we pad because the dummy hash function we use to test this, merely copies the input into
- // the output, so the input must be at least 32 bits, since the output has to be that long
- assertPutString(new char[] { 'p', HashTestUtils.randomLowSurrogate(new Random()) });
- }
-
- public void testPutStringWithHighSurrogate() {
- // we pad because the dummy hash function we use to test this, merely copies the input into
- // the output, so the input must be at least 32 bits, since the output has to be that long
- assertPutString(new char[] { 'p', HashTestUtils.randomHighSurrogate(new Random()) });
- }
-
- public void testPutStringWithLowHighSurrogate() {
- assertPutString(new char[] {
- HashTestUtils.randomLowSurrogate(new Random()),
- HashTestUtils.randomHighSurrogate(new Random()) });
- }
-
- public void testPutStringWithHighLowSurrogate() {
- assertPutString(new char[] {
- HashTestUtils.randomHighSurrogate(new Random()),
- HashTestUtils.randomLowSurrogate(new Random()) });
- }
-
- private static void assertPutString(char[] chars) {
- Hasher h1 = new NonStreamingVersion().newHasher();
- Hasher h2 = new NonStreamingVersion().newHasher();
- String s = new String(chars);
- // this is the correct implementation of the spec
- for (int i = 0; i < s.length(); i++) {
- h1.putChar(s.charAt(i));
- }
- h2.putString(s);
- assertEquals(h1.hash(), h2.hash());
- }
-
+
static class StreamingVersion extends AbstractStreamingHashFunction {
@Override
public int bits() {
@@ -122,7 +72,7 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
};
}
}
-
+
static class NonStreamingVersion extends AbstractNonStreamingHashFunction {
@Override
public int bits() {
@@ -138,12 +88,12 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
public HashCode hashBytes(byte[] input, int off, int len) {
return HashCodes.fromBytes(Arrays.copyOfRange(input, off, off + len));
}
-
+
@Override
public HashCode hashString(CharSequence input) {
throw new UnsupportedOperationException();
}
-
+
@Override
public HashCode hashString(CharSequence input, Charset charset) {
throw new UnsupportedOperationException();
@@ -153,10 +103,5 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
public HashCode hashLong(long input) {
throw new UnsupportedOperationException();
}
-
- @Override
- public HashCode hashInt(int input) {
- throw new UnsupportedOperationException();
- }
}
}
diff --git a/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java b/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java
index 7324e6f..8f1cbb4 100644
--- a/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java
+++ b/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java
@@ -1,23 +1,7 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
-import static com.google.common.base.Charsets.UTF_16LE;
-
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.hash.AbstractStreamingHashFunction.AbstractStreamingHasher;
@@ -35,24 +19,30 @@ import java.util.List;
import java.util.Random;
/**
- * Tests for AbstractStreamingHasher.
- *
- * @author Dimitris Andreou
+ * Tests for AbstractHashSink.
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
public class AbstractStreamingHasherTest extends TestCase {
+ /** Test we get the HashCode that is created by the sink. Later we ignore the result */
+ public void testSanity() {
+ Sink sink = new Sink(4);
+ assertEquals(0xDeadBeef, sink.makeHash().asInt());
+ }
+
public void testBytes() {
Sink sink = new Sink(4); // byte order insignificant here
byte[] expected = { 1, 2, 3, 4, 5, 6, 7, 8 };
sink.putByte((byte) 1);
sink.putBytes(new byte[] { 2, 3, 4, 5, 6 });
sink.putByte((byte) 7);
- sink.putBytes(new byte[] {});
+ sink.putBytes(new byte[] { });
sink.putBytes(new byte[] { 8 });
sink.hash();
sink.assertInvariants(8);
sink.assertBytes(expected);
}
-
+
public void testShort() {
Sink sink = new Sink(4);
sink.putShort((short) 0x0201);
@@ -60,7 +50,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(2);
sink.assertBytes(new byte[] { 1, 2, 0, 0 }); // padded with zeros
}
-
+
public void testInt() {
Sink sink = new Sink(4);
sink.putInt(0x04030201);
@@ -68,7 +58,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(4);
sink.assertBytes(new byte[] { 1, 2, 3, 4 });
}
-
+
public void testLong() {
Sink sink = new Sink(8);
sink.putLong(0x0807060504030201L);
@@ -76,7 +66,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(8);
sink.assertBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
}
-
+
public void testChar() {
Sink sink = new Sink(4);
sink.putChar((char) 0x0201);
@@ -84,22 +74,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(2);
sink.assertBytes(new byte[] { 1, 2, 0, 0 }); // padded with zeros
}
-
- public void testString() {
- Random random = new Random();
- for (int i = 0; i < 100; i++) {
- byte[] bytes = new byte[64];
- random.nextBytes(bytes);
- String s = new String(bytes, UTF_16LE); // so all random strings are valid
- assertEquals(
- new Sink(4).putString(s).hash(),
- new Sink(4).putBytes(s.getBytes(UTF_16LE)).hash());
- assertEquals(
- new Sink(4).putString(s).hash(),
- new Sink(4).putString(s, UTF_16LE).hash());
- }
- }
-
+
public void testFloat() {
Sink sink = new Sink(4);
sink.putFloat(Float.intBitsToFloat(0x04030201));
@@ -107,7 +82,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(4);
sink.assertBytes(new byte[] { 1, 2, 3, 4 });
}
-
+
public void testDouble() {
Sink sink = new Sink(8);
sink.putDouble(Double.longBitsToDouble(0x0807060504030201L));
@@ -115,7 +90,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(8);
sink.assertBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
}
-
+
public void testCorrectExceptions() {
Sink sink = new Sink(4);
try {
@@ -131,16 +106,16 @@ public class AbstractStreamingHasherTest extends TestCase {
fail();
} catch (IndexOutOfBoundsException ok) {}
}
-
+
/**
* This test creates a long random sequence of inputs, then a lot of differently configured
* sinks process it; all should produce the same answer, the only difference should be the
- * number of process()/processRemaining() invocations, due to alignment.
+ * number of process()/processRemaining() invocations, due to alignment.
*/
public void testExhaustive() throws Exception {
Random random = new Random(0); // will iteratively make more debuggable, each time it breaks
for (int totalInsertions = 0; totalInsertions < 200; totalInsertions++) {
-
+
List<Sink> sinks = Lists.newArrayList();
for (int chunkSize = 4; chunkSize <= 32; chunkSize++) {
for (int bufferSize = chunkSize; bufferSize <= chunkSize * 4; bufferSize += chunkSize) {
@@ -148,28 +123,22 @@ public class AbstractStreamingHasherTest extends TestCase {
sinks.add(new Sink(chunkSize, bufferSize));
// For convenience, testing only with big endianness, to match DataOutputStream.
// I regard highly unlikely that both the little endianness tests above and this one
- // passes, and there is still a little endianness bug lurking around.
+ // passes, and there is still a little endianness bug lurking around.
}
}
-
+
Control control = new Control();
Hasher controlSink = control.newHasher(1024);
-
- Iterable<Hasher> sinksAndControl =
- Iterables.concat(sinks, Collections.singleton(controlSink));
+
+ Iterable<Hasher> sinksAndControl = Iterables.concat(
+ sinks, Collections.singleton(controlSink));
for (int insertion = 0; insertion < totalInsertions; insertion++) {
- RandomHasherAction.pickAtRandom(random).performAction(random, sinksAndControl);
- }
- // We need to ensure that at least 4 bytes have been put into the hasher or else
- // Hasher#hash will throw an ISE.
- int intToPut = random.nextInt();
- for (Hasher hasher : sinksAndControl) {
- hasher.putInt(intToPut);
+ RandomHasherAction.pickAtRandom(random).performAction(random, sinksAndControl);
}
for (Sink sink : sinks) {
sink.hash();
}
-
+
byte[] expected = controlSink.hash().asBytes();
for (Sink sink : sinks) {
sink.assertInvariants(expected.length);
@@ -177,15 +146,15 @@ public class AbstractStreamingHasherTest extends TestCase {
}
}
}
-
+
private static class Sink extends AbstractStreamingHasher {
final int chunkSize;
final int bufferSize;
final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
+
int processCalled = 0;
boolean remainingCalled = false;
-
+
Sink(int chunkSize, int bufferSize) {
super(chunkSize, bufferSize);
this.chunkSize = chunkSize;
@@ -199,7 +168,7 @@ public class AbstractStreamingHasherTest extends TestCase {
}
@Override HashCode makeHash() {
- return HashCodes.fromBytes(out.toByteArray());
+ return HashCodes.fromInt(0xDeadBeef);
}
@Override protected void process(ByteBuffer bb) {
@@ -210,7 +179,7 @@ public class AbstractStreamingHasherTest extends TestCase {
out.write(bb.get());
}
}
-
+
@Override protected void processRemaining(ByteBuffer bb) {
assertFalse(remainingCalled);
remainingCalled = true;
@@ -223,21 +192,21 @@ public class AbstractStreamingHasherTest extends TestCase {
assertEquals(before + 1, after); // default implementation pads and calls process()
processCalled--; // don't count the tail invocation (makes tests a bit more understandable)
}
-
+
// ensures that the number of invocations looks sane
void assertInvariants(int expectedBytes) {
- // we should have seen as many bytes as the next multiple of chunk after expectedBytes - 1
+ // we should have seen as many bytes as the next multiple of chunk after expectedBytes - 1
assertEquals(out.toByteArray().length, ceilToMultiple(expectedBytes, chunkSize));
assertEquals(expectedBytes / chunkSize, processCalled);
assertEquals(expectedBytes % chunkSize != 0, remainingCalled);
}
-
+
// returns the minimum x such as x >= a && (x % b) == 0
private static int ceilToMultiple(int a, int b) {
int remainder = a % b;
return remainder == 0 ? a : a + b - remainder;
}
-
+
void assertBytes(byte[] expected) {
byte[] got = out.toByteArray();
for (int i = 0; i < expected.length; i++) {
@@ -245,14 +214,13 @@ public class AbstractStreamingHasherTest extends TestCase {
}
}
}
-
- // Assumes that AbstractNonStreamingHashFunction works properly (must be tested elsewhere!)
+
private static class Control extends AbstractNonStreamingHashFunction {
@Override
public HashCode hashBytes(byte[] input) {
return HashCodes.fromBytes(input);
}
-
+
@Override
public HashCode hashBytes(byte[] input, int off, int len) {
return hashBytes(Arrays.copyOfRange(input, off, off + len));
@@ -277,10 +245,5 @@ public class AbstractStreamingHasherTest extends TestCase {
public HashCode hashLong(long input) {
throw new UnsupportedOperationException();
}
-
- @Override
- public HashCode hashInt(int input) {
- throw new UnsupportedOperationException();
- }
}
}
diff --git a/guava-tests/test/com/google/common/hash/BloomFilterTest.java b/guava-tests/test/com/google/common/hash/BloomFilterTest.java
index d9056f6..26b7641 100644
--- a/guava-tests/test/com/google/common/hash/BloomFilterTest.java
+++ b/guava-tests/test/com/google/common/hash/BloomFilterTest.java
@@ -1,79 +1,20 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
-import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
import java.util.Random;
-import javax.annotation.Nullable;
-
/**
* Tests for SimpleGenericBloomFilter and derived BloomFilter views.
- *
- * @author Dimitris Andreou
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
public class BloomFilterTest extends TestCase {
-
- public void testCreateAndCheckBloomFilterWithKnownFalsePositives() {
- int numInsertions = 1000000;
- BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.stringFunnel(), numInsertions);
-
- // Insert "numInsertions" even numbers into the BF.
- for (int i = 0; i < numInsertions * 2; i += 2) {
- bf.put(Integer.toString(i));
- }
-
- // Assert that the BF "might" have all of the even numbers.
- for (int i = 0; i < numInsertions * 2; i += 2) {
- assertTrue(bf.mightContain(Integer.toString(i)));
- }
-
- // Now we check for known false positives using a set of known false positives.
- // (These are all of the false positives under 900.)
- ImmutableSet<Integer> falsePositives = ImmutableSet.of(
- 49, 51, 59, 163, 199, 321, 325, 363, 367, 469, 545, 561, 727, 769, 773, 781);
- for (int i = 1; i < 900; i += 2) {
- if (!falsePositives.contains(i)) {
- assertFalse("BF should not contain " + i, bf.mightContain(Integer.toString(i)));
- }
- }
-
- // Check that there are exactly 29824 false positives for this BF.
- int knownNumberOfFalsePositives = 29824;
- int numFpp = 0;
- for (int i = 1; i < numInsertions * 2; i += 2) {
- if (bf.mightContain(Integer.toString(i))) {
- numFpp++;
- }
- }
- assertEquals(knownNumberOfFalsePositives, numFpp);
- double actualFpp = (double) knownNumberOfFalsePositives / numInsertions;
- double expectedFpp = bf.expectedFpp();
- // The normal order of (expected, actual) is reversed here on purpose.
- assertEquals(actualFpp, expectedFpp, 0.00015);
- }
-
/**
* Sanity checking with many combinations of false positive rates and expected insertions
*/
@@ -84,43 +25,9 @@ public class BloomFilterTest extends TestCase {
}
}
}
-
- public void testPreconditions() {
- try {
- BloomFilter.create(Funnels.stringFunnel(), -1);
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- BloomFilter.create(Funnels.stringFunnel(), -1, 0.03);
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- BloomFilter.create(Funnels.stringFunnel(), 1, 0.0);
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- BloomFilter.create(Funnels.stringFunnel(), 1, 1.0);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testFailureWhenMoreThan255HashFunctionsAreNeeded() {
- try {
- int n = 1000;
- double p = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000001;
- BloomFilter.create(Funnels.stringFunnel(), n, p);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNullPointers() {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicInstanceMethods(BloomFilter.create(Funnels.stringFunnel(), 100));
- tester.testAllPublicStaticMethods(BloomFilter.class);
- }
-
+
/**
- * Tests that we never get an optimal hashes number of zero.
+ * Tests that we never get an optimal hashes number of zero.
*/
public void testOptimalHashes() {
for (int n = 1; n < 1000; n++) {
@@ -129,9 +36,9 @@ public class BloomFilterTest extends TestCase {
}
}
}
-
+
/**
- * Tests that we always get a non-negative optimal size.
+ * Tests that we always get a non-negative optimal size.
*/
public void testOptimalSize() {
for (int n = 1; n < 1000; n++) {
@@ -139,148 +46,36 @@ public class BloomFilterTest extends TestCase {
assertTrue(BloomFilter.optimalNumOfBits(n, fpp) >= 0);
}
}
-
+
// some random values
- Random random = new Random(0);
+ Random random = new Random(0);
for (int repeats = 0; repeats < 10000; repeats++) {
assertTrue(BloomFilter.optimalNumOfBits(random.nextInt(1 << 16), random.nextDouble()) >= 0);
}
-
- // and some crazy values (this used to be capped to Integer.MAX_VALUE, now it can go bigger
- assertEquals(3327428144502L, BloomFilter.optimalNumOfBits(
+
+ // and some crazy values
+ assertEquals(Integer.MAX_VALUE, BloomFilter.optimalNumOfBits(
Integer.MAX_VALUE, Double.MIN_VALUE));
- try {
- BloomFilter.create(HashTestUtils.BAD_FUNNEL, Integer.MAX_VALUE, Double.MIN_VALUE);
- fail("we can't represent such a large BF!");
- } catch (IllegalArgumentException expected) {
- assertEquals("Could not create BloomFilter of 3327428144502 bits", expected.getMessage());
- }
}
-
+
private void checkSanity(BloomFilter<Object> bf) {
assertFalse(bf.mightContain(new Object()));
- assertFalse(bf.apply(new Object()));
for (int i = 0; i < 100; i++) {
Object o = new Object();
bf.put(o);
assertTrue(bf.mightContain(o));
- assertTrue(bf.apply(o));
}
}
-
- public void testCopy() {
- BloomFilter<CharSequence> original = BloomFilter.create(Funnels.stringFunnel(), 100);
- BloomFilter<CharSequence> copy = original.copy();
- assertNotSame(original, copy);
- assertEquals(original, copy);
- }
-
- public void testExpectedFpp() {
- BloomFilter<Object> bf = BloomFilter.create(HashTestUtils.BAD_FUNNEL, 10, 0.03);
- double fpp = bf.expectedFpp();
- assertEquals(0.0, fpp);
- // usually completed in less than 200 iterations
- while (fpp != 1.0) {
- boolean changed = bf.put(new Object());
- double newFpp = bf.expectedFpp();
- // if changed, the new fpp is strictly higher, otherwise it is the same
- assertTrue(changed ? newFpp > fpp : newFpp == fpp);
- fpp = newFpp;
- }
- }
-
- public void testEquals_empty() {
- new EqualsTester()
- .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 100, 0.01))
- .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 100, 0.02))
- .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 200, 0.01))
- .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 200, 0.02))
- .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 100, 0.01))
- .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 100, 0.02))
- .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 200, 0.01))
- .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 200, 0.02))
- .testEquals();
- }
-
- public void testEquals() {
- BloomFilter<CharSequence> bf1 = BloomFilter.create(Funnels.stringFunnel(), 100);
- bf1.put("1");
- bf1.put("2");
-
- BloomFilter<CharSequence> bf2 = BloomFilter.create(Funnels.stringFunnel(), 100);
- bf2.put("1");
- bf2.put("2");
-
- new EqualsTester()
- .addEqualityGroup(bf1, bf2)
- .testEquals();
-
- bf2.put("3");
-
- new EqualsTester()
- .addEqualityGroup(bf1)
- .addEqualityGroup(bf2)
- .testEquals();
- }
-
- public void testEqualsWithCustomFunnel() {
- BloomFilter<Long> bf1 = BloomFilter.create(new CustomFunnel(), 100);
- BloomFilter<Long> bf2 = BloomFilter.create(new CustomFunnel(), 100);
- assertEquals(bf1, bf2);
- }
-
- public void testSerializationWithCustomFunnel() {
- SerializableTester.reserializeAndAssert(BloomFilter.create(new CustomFunnel(), 100));
- }
-
- private static final class CustomFunnel implements Funnel<Long> {
- @Override
- public void funnel(Long value, PrimitiveSink into) {
- into.putLong(value);
- }
- @Override
- public boolean equals(@Nullable Object object) {
- return (object instanceof CustomFunnel);
- }
- @Override
- public int hashCode() {
- return 42;
- }
- }
-
- public void testPutReturnValue() {
- for (int i = 0; i < 10; i++) {
- BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.stringFunnel(), 100);
- for (int j = 0; j < 10; j++) {
- String value = new Object().toString();
- boolean mightContain = bf.mightContain(value);
- boolean put = bf.put(value);
- assertTrue(mightContain != put);
- }
- }
- }
-
- public void testJavaSerialization() {
+
+ public void testSerialization() {
BloomFilter<byte[]> bf = BloomFilter.create(Funnels.byteArrayFunnel(), 100);
for (int i = 0; i < 10; i++) {
bf.put(Ints.toByteArray(i));
}
-
- BloomFilter<byte[]> copy = SerializableTester.reserialize(bf);
+
+ bf = SerializableTester.reserialize(bf);
for (int i = 0; i < 10; i++) {
- assertTrue(copy.mightContain(Ints.toByteArray(i)));
+ assertTrue(bf.mightContain(Ints.toByteArray(i)));
}
- assertEquals(bf.expectedFpp(), copy.expectedFpp());
-
- SerializableTester.reserializeAndAssert(bf);
- }
-
- /**
- * This test will fail whenever someone updates/reorders the BloomFilterStrategies constants.
- * Only appending a new constant is allowed.
- */
- public void testBloomFilterStrategies() {
- assertEquals(1, BloomFilterStrategies.values().length);
- assertEquals(BloomFilterStrategies.MURMUR128_MITZ_32, BloomFilterStrategies.values()[0]);
}
}
diff --git a/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java b/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java
deleted file mode 100644
index 5b29c46..0000000
--- a/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.hash;
-
-import static com.google.common.hash.Hashing.ChecksumType.ADLER_32;
-import static com.google.common.hash.Hashing.ChecksumType.CRC_32;
-
-import com.google.common.base.Supplier;
-
-import junit.framework.TestCase;
-
-import java.util.zip.Checksum;
-
-/**
- * Tests for ChecksumHashFunction.
- *
- * @author Colin Decker
- */
-public class ChecksumHashFunctionTest extends TestCase {
-
- public void testCrc32_equalsChecksumValue() throws Exception {
- assertChecksum(CRC_32, "");
- assertChecksum(CRC_32, "Z");
- assertChecksum(CRC_32, "foobar");
- }
-
- public void testAdler32_equalsChecksumValue() throws Exception {
- assertChecksum(ADLER_32, "");
- assertChecksum(ADLER_32, "Z");
- assertChecksum(ADLER_32, "foobar");
- }
-
- public void testCrc32_knownValues() throws Exception {
- assertHash32(0x1C8600E3, CRC_32, "hell");
- assertHash32(0x3610A686, CRC_32, "hello");
- assertHash32(0xED81F9F6, CRC_32, "hello ");
- assertHash32(0x4850DDC2, CRC_32, "hello w");
- assertHash32(0x7A2D6005, CRC_32, "hello wo");
- assertHash32(0x1C192672, CRC_32, "hello wor");
- assertHash32(0x414FA339, CRC_32, "The quick brown fox jumps over the lazy dog");
- assertHash32(0x4400B5BC, CRC_32, "The quick brown fox jumps over the lazy cog");
- }
-
- public void testAdler32_knownValues() throws Exception {
- assertHash32(0x041701A6, ADLER_32, "hell");
- assertHash32(0x062C0215, ADLER_32, "hello");
- assertHash32(0x08610235, ADLER_32, "hello ");
- assertHash32(0x0B0D02AC, ADLER_32, "hello w");
- assertHash32(0x0E28031B, ADLER_32, "hello wo");
- assertHash32(0x11B5038D, ADLER_32, "hello wor");
- assertHash32(0x5BDC0FDA, ADLER_32, "The quick brown fox jumps over the lazy dog");
- assertHash32(0x5BD90FD9, ADLER_32, "The quick brown fox jumps over the lazy cog");
- }
-
- private static void assertChecksum(Supplier<Checksum> supplier, String input) {
- byte[] bytes = HashTestUtils.ascii(input);
-
- Checksum checksum = supplier.get();
- checksum.update(bytes, 0, bytes.length);
- long value = checksum.getValue();
-
- String toString = "name";
- HashFunction func = new ChecksumHashFunction(supplier, 32, toString);
- assertEquals(toString, func.toString());
- assertEquals(value, func.hashBytes(bytes).padToLong());
- }
-
- private static void assertHash32(int expected, Supplier<Checksum> supplier, String input) {
- byte[] bytes = HashTestUtils.ascii(input);
- String toString = "name";
- HashFunction func = new ChecksumHashFunction(supplier, 32, toString);
- assertEquals(expected, func.hashBytes(bytes).asInt());
- assertEquals(toString, func.toString());
- }
-}
diff --git a/guava-tests/test/com/google/common/hash/FunnelsTest.java b/guava-tests/test/com/google/common/hash/FunnelsTest.java
index 368f7b5..698549a 100644
--- a/guava-tests/test/com/google/common/hash/FunnelsTest.java
+++ b/guava-tests/test/com/google/common/hash/FunnelsTest.java
@@ -1,41 +1,31 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
import com.google.common.hash.AbstractStreamingHashFunction.AbstractStreamingHasher;
import junit.framework.TestCase;
-import java.io.OutputStream;
+import org.easymock.EasyMock;
+
import java.nio.ByteBuffer;
/**
* Tests for HashExtractors.
- *
- * @author Dimitris Andreou
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
public class FunnelsTest extends TestCase {
public void testForBytes() {
- PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
- Funnels.byteArrayFunnel().funnel(new byte[] { 4, 3, 2, 1 }, bytePrimitiveSink);
- verify(bytePrimitiveSink).putBytes(new byte[] { 4, 3, 2, 1 });
+ Sink byteSink = EasyMock.createMock(Sink.class);
+
+ EasyMock.expect(byteSink.putBytes(EasyMock.aryEq(new byte[] { 4, 3, 2, 1})))
+ .andReturn(byteSink).once();
+ EasyMock.replay(byteSink);
+
+ Funnels.byteArrayFunnel().funnel(new byte[]{4, 3, 2, 1}, byteSink);
+
+ EasyMock.verify(byteSink);
}
public void testForBytes_null() {
@@ -43,39 +33,23 @@ public class FunnelsTest extends TestCase {
}
public void testForStrings() {
- PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
- Funnels.stringFunnel().funnel("test", bytePrimitiveSink);
- verify(bytePrimitiveSink).putString("test");
- }
+ Sink byteSink = EasyMock.createMock(Sink.class);
+
+ EasyMock.expect(byteSink.putString("test")).andReturn(byteSink).once();
+ EasyMock.replay(byteSink);
+
+ Funnels.stringFunnel().funnel("test", byteSink);
+
+ EasyMock.verify(byteSink);
+ }
+
public void testForStrings_null() {
assertNullsThrowException(Funnels.stringFunnel());
}
-
- public void testForInts() {
- Integer value = 1234;
- PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
- Funnels.integerFunnel().funnel(value, bytePrimitiveSink);
- verify(bytePrimitiveSink).putInt(1234);
- }
-
- public void testForInts_null() {
- assertNullsThrowException(Funnels.integerFunnel());
- }
-
- public void testForLongs() {
- Long value = 1234L;
- PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
- Funnels.longFunnel().funnel(value, bytePrimitiveSink);
- verify(bytePrimitiveSink).putLong(1234);
- }
-
- public void testForLongs_null() {
- assertNullsThrowException(Funnels.longFunnel());
- }
-
+
private static void assertNullsThrowException(Funnel<?> funnel) {
- PrimitiveSink bytePrimitiveSink = new AbstractStreamingHasher(4, 4) {
+ Sink byteSink = new AbstractStreamingHasher(4, 4) {
@Override HashCode makeHash() { throw new UnsupportedOperationException(); }
@Override protected void process(ByteBuffer bb) {
@@ -85,20 +59,8 @@ public class FunnelsTest extends TestCase {
}
};
try {
- funnel.funnel(null, bytePrimitiveSink);
+ funnel.funnel(null, byteSink);
fail();
} catch (NullPointerException ok) {}
}
-
- public void testAsOutputStream() throws Exception {
- PrimitiveSink sink = mock(PrimitiveSink.class);
- OutputStream out = Funnels.asOutputStream(sink);
- byte[] bytes = { 1, 2, 3, 4 };
- out.write(255);
- out.write(bytes);
- out.write(bytes, 1, 2);
- verify(sink).putByte((byte) 255);
- verify(sink).putBytes(bytes);
- verify(sink).putBytes(bytes, 1, 2);
- }
}
diff --git a/guava-tests/test/com/google/common/hash/HashCodesTest.java b/guava-tests/test/com/google/common/hash/HashCodesTest.java
index 70fb7ec..2b483ac 100644
--- a/guava-tests/test/com/google/common/hash/HashCodesTest.java
+++ b/guava-tests/test/com/google/common/hash/HashCodesTest.java
@@ -1,23 +1,8 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
import com.google.common.collect.ImmutableList;
-import com.google.common.testing.ClassSanityTester;
import junit.framework.TestCase;
@@ -25,124 +10,67 @@ import java.util.Arrays;
/**
* Tests for HashCodes, especially making sure that their endianness promises (big-endian)
- * are upheld.
- *
- * @author Dimitris Andreou
+ * are upheld.
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
public class HashCodesTest extends TestCase {
// note: asInt(), asLong() are in little endian
private static final ImmutableList<ExpectedHashCode> expectedHashCodes = ImmutableList.of(
- new ExpectedHashCode(new byte[] {
+ new ExpectedHashCode(new byte[] {
(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89,
(byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01},
0x89abcdef, 0x0123456789abcdefL, "efcdab8967452301"),
-
- new ExpectedHashCode(new byte[] {
+
+ new ExpectedHashCode(new byte[] {
(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89,
(byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01, // up to here, same bytes as above
(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
(byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08},
0x89abcdef, 0x0123456789abcdefL, // asInt/asLong as above, due to equal eight first bytes
- "efcdab89674523010102030405060708"),
-
+ "efcdab89674523010102030405060708"),
+
new ExpectedHashCode(new byte[] { (byte) 0xdf, (byte) 0x9b, (byte) 0x57, (byte) 0x13 },
0x13579bdf, null, "df9b5713"),
-
- new ExpectedHashCode(new byte[] {
+
+ new ExpectedHashCode(new byte[] {
(byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00},
0x0000abcd, null, "cdab0000"),
-
- new ExpectedHashCode(new byte[] {
+
+ new ExpectedHashCode(new byte[] {
(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00},
0x00abcdef, 0x0000000000abcdefL, "efcdab0000000000")
);
-
+
// expectedHashCodes must contain at least one hash code with 4 bytes
public void testFromInt() {
for (ExpectedHashCode expected : expectedHashCodes) {
- if (expected.bytes.length == 4) {
+ if (expected.bytes.length == 4) {
HashCode fromInt = HashCodes.fromInt(expected.asInt);
assertExpectedHashCode(expected, fromInt);
}
}
}
-
+
// expectedHashCodes must contain at least one hash code with 8 bytes
public void testFromLong() {
for (ExpectedHashCode expected : expectedHashCodes) {
- if (expected.bytes.length == 8) {
+ if (expected.bytes.length == 8) {
HashCode fromLong = HashCodes.fromLong(expected.asLong);
assertExpectedHashCode(expected, fromLong);
}
}
}
-
+
public void testFromBytes() {
for (ExpectedHashCode expected : expectedHashCodes) {
HashCode fromBytes = HashCodes.fromBytes(expected.bytes);
assertExpectedHashCode(expected, fromBytes);
}
}
-
- public void testFromBytes_copyOccurs() {
- byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 };
- HashCode hashCode = HashCodes.fromBytes(bytes);
- int expectedInt = 0x0000abcd;
- String expectedToString = "cdab0000";
-
- assertEquals(expectedInt, hashCode.asInt());
- assertEquals(expectedToString, hashCode.toString());
-
- bytes[0] = (byte) 0x00;
-
- assertEquals(expectedInt, hashCode.asInt());
- assertEquals(expectedToString, hashCode.toString());
- }
-
- public void testFromBytesNoCopy_noCopyOccurs() {
- byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 };
- HashCode hashCode = HashCodes.fromBytesNoCopy(bytes);
-
- assertEquals(0x0000abcd, hashCode.asInt());
- assertEquals("cdab0000", hashCode.toString());
-
- bytes[0] = (byte) 0x00;
-
- assertEquals(0x0000ab00, hashCode.asInt());
- assertEquals("00ab0000", hashCode.toString());
- }
-
- public void testPadToLong() {
- assertEquals(0x1111111111111111L, HashCodes.fromLong(0x1111111111111111L).padToLong());
- assertEquals(0x9999999999999999L, HashCodes.fromLong(0x9999999999999999L).padToLong());
- assertEquals(0x0000000011111111L, HashCodes.fromInt(0x11111111).padToLong());
- assertEquals(0x0000000099999999L, HashCodes.fromInt(0x99999999).padToLong());
-
- byte[] longBytes = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99,
- (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99};
- byte[] intBytes = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99};
- assertEquals(0x9999999999999999L, HashCodes.fromBytesNoCopy(longBytes).padToLong());
- assertEquals(0x0000000099999999L, HashCodes.fromBytesNoCopy(intBytes).padToLong());
- }
-
- public void testHashCodes_nulls() throws Exception {
- sanityTester().testNulls();
- }
-
- public void testHashCodes_equalsAndSerializable() throws Exception {
- sanityTester().testEqualsAndSerializable();
- }
-
- private static ClassSanityTester.FactoryMethodReturnValueTester sanityTester() {
- return new ClassSanityTester()
- .setDefault(byte[].class, new byte[] {1, 2, 3, 4})
- .setSampleInstances(byte[].class,
- ImmutableList.of(new byte[] {1, 2, 3, 4}, new byte[] {5, 6, 7, 8}))
- .forAllPublicStaticMethods(HashCodes.class);
- }
-
- private static void assertExpectedHashCode(ExpectedHashCode expected, HashCode hash) {
+
+ private void assertExpectedHashCode(ExpectedHashCode expected, HashCode hash) {
assertTrue(Arrays.equals(expected.bytes, hash.asBytes()));
byte[] bb = new byte[hash.bits() / 8];
hash.writeBytesTo(bb, 0, bb.length);
@@ -160,27 +88,27 @@ public class HashCodesTest extends TestCase {
assertSideEffectFree(hash);
assertReadableBytes(hash);
}
-
- private static void assertSideEffectFree(HashCode hash) {
+
+ private void assertSideEffectFree(HashCode hash) {
byte[] original = hash.asBytes();
byte[] mutated = hash.asBytes();
mutated[0]++;
assertTrue(Arrays.equals(original, hash.asBytes()));
}
-
- private static void assertReadableBytes(HashCode hashCode) {
+
+ private void assertReadableBytes(HashCode hashCode) {
assertTrue(hashCode.bits() >= 32); // sanity
byte[] hashBytes = hashCode.asBytes();
int totalBytes = hashCode.bits() / 8;
-
+
for (int bytes = 0; bytes < totalBytes; bytes++) {
byte[] bb = new byte[bytes];
hashCode.writeBytesTo(bb, 0, bb.length);
-
+
assertTrue(Arrays.equals(Arrays.copyOf(hashBytes, bytes), bb));
}
}
-
+
private static class ExpectedHashCode {
final byte[] bytes;
final int asInt;
diff --git a/guava-tests/test/com/google/common/hash/HashFunctionsTest.java b/guava-tests/test/com/google/common/hash/HashFunctionsTest.java
new file mode 100644
index 0000000..f9fd6c4
--- /dev/null
+++ b/guava-tests/test/com/google/common/hash/HashFunctionsTest.java
@@ -0,0 +1,74 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package com.google.common.hash;
+
+import com.google.common.collect.Sets;
+
+import junit.framework.TestCase;
+
+import java.util.Set;
+
+/**
+ * Tests for HashFunctions.
+ *
+ * @author andreou@google.com (Dimitris Andreou)
+ */
+public class HashFunctionsTest extends TestCase {
+ public void testMd5() {
+ assertInvariants(Hashing.md5());
+ }
+
+ public void testMurmur3_138() {
+ assertInvariants(Hashing.murmur3_128());
+ }
+
+ public void testMurmur3_32() {
+ assertInvariants(Hashing.murmur3_32());
+ }
+
+ public void testGoodFastHash() {
+ for (int i = 1; i < 500; i++) {
+ HashFunction hasher = Hashing.goodFastHash(i);
+ assertTrue(hasher.bits() >= i);
+ assertInvariants(hasher);
+ }
+ }
+
+ /**
+ * Checks that a Hasher returns the same HashCode when given the same input, and also
+ * that the collision rate looks sane.
+ */
+ private static void assertInvariants(HashFunction hashFunction) {
+ int objects = 100;
+ Set<HashCode> hashcodes = Sets.newHashSetWithExpectedSize(objects);
+ for (int i = 0; i < objects; i++) {
+ Object o = new Object();
+ HashCode hashcode1 = hashFunction.newHasher().putObject(o, HashTestUtils.BAD_FUNNEL).hash();
+ HashCode hashcode2 = hashFunction.newHasher().putObject(o, HashTestUtils.BAD_FUNNEL).hash();
+ assertEquals(hashcode1, hashcode2); // idempotent
+ assertEquals(hashFunction.bits(), hashcode1.bits());
+ assertEquals(hashFunction.bits(), hashcode1.asBytes().length * 8);
+ hashcodes.add(hashcode1);
+ }
+ assertTrue(hashcodes.size() > objects * 0.95); // quite relaxed test
+
+ assertHashBytesThrowsCorrectExceptions(hashFunction);
+ }
+
+ private static void assertHashBytesThrowsCorrectExceptions(HashFunction hashFunction) {
+ hashFunction.hashBytes(new byte[64], 0, 0);
+
+ try {
+ hashFunction.hashBytes(new byte[128], -1, 128);
+ fail();
+ } catch (IndexOutOfBoundsException ok) {}
+ try {
+ hashFunction.hashBytes(new byte[128], 64, 256 /* too long len */);
+ fail();
+ } catch (IndexOutOfBoundsException ok) {}
+ try {
+ hashFunction.hashBytes(new byte[64], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException ok) {}
+ }
+}
diff --git a/guava-tests/test/com/google/common/hash/HashTestUtils.java b/guava-tests/test/com/google/common/hash/HashTestUtils.java
index 8a894f7..a857a79 100644
--- a/guava-tests/test/com/google/common/hash/HashTestUtils.java
+++ b/guava-tests/test/com/google/common/hash/HashTestUtils.java
@@ -1,44 +1,20 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
-import com.google.common.testing.EqualsTester;
import org.junit.Assert;
-import java.nio.charset.Charset;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Random;
-import java.util.Set;
/**
- * Various utilities for testing {@link HashFunction}s.
- *
- * @author Dimitris Andreou
- * @author Kurt Alfred Kluever
+ * @author andreou@google.com (Dimitris Andreou)
*/
-final class HashTestUtils {
+class HashTestUtils {
private HashTestUtils() {}
/**
@@ -52,6 +28,17 @@ final class HashTestUtils {
return bytes;
}
+ /**
+ * Returns a byte array representation for a sequence of longs, in big-endian order.
+ */
+ static byte[] toBytes(ByteOrder bo, long... longs) {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[longs.length * 8]).order(bo);
+ for (long x : longs) {
+ bb.putLong(x);
+ }
+ return bb.array();
+ }
+
interface HashFn {
byte[] hash(byte[] input, int seed);
}
@@ -69,510 +56,123 @@ final class HashTestUtils {
byte[] hash = hashFunction.hash(Arrays.copyOf(key, i), seed);
System.arraycopy(hash, 0, hashes, i * hashBytes, hash.length);
}
-
+
// Then hash the result array
byte[] result = hashFunction.hash(hashes, 0);
-
+
// interpreted in little-endian order.
- int verification = Integer.reverseBytes(Ints.fromByteArray(result));
+ int verification = Integer.reverseBytes(Ints.fromByteArray(result));
if (expected != verification) {
throw new AssertionError("Expected: " + Integer.toHexString(expected)
+ " got: " + Integer.toHexString(verification));
}
}
-
+
+ static void assertEqualHashes(byte[] expectedHash, byte[] actualHash) {
+ if (!Arrays.equals(expectedHash, actualHash)) {
+ Assert.fail(String.format("Should be: %x, was %x", expectedHash, actualHash));
+ }
+ }
+
static final Funnel<Object> BAD_FUNNEL = new Funnel<Object>() {
- @Override public void funnel(Object object, PrimitiveSink bytePrimitiveSink) {
- bytePrimitiveSink.putInt(object.hashCode());
+ @Override public void funnel(Object object, Sink byteSink) {
+ byteSink.putInt(object.hashCode());
}
};
-
+
static enum RandomHasherAction {
PUT_BOOLEAN() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
boolean value = random.nextBoolean();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putBoolean(value);
}
}
},
PUT_BYTE() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
int value = random.nextInt();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putByte((byte) value);
}
}
},
PUT_SHORT() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
short value = (short) random.nextInt();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putShort(value);
}
}
},
PUT_CHAR() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
char value = (char) random.nextInt();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putChar(value);
}
}
},
PUT_INT() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
int value = random.nextInt();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putInt(value);
}
}
},
PUT_LONG() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
long value = random.nextLong();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putLong(value);
}
}
},
PUT_FLOAT() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
float value = random.nextFloat();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putFloat(value);
}
}
},
PUT_DOUBLE() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
double value = random.nextDouble();
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putDouble(value);
}
}
},
PUT_BYTES() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
byte[] value = new byte[random.nextInt(128)];
random.nextBytes(value);
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putBytes(value);
}
}
},
PUT_BYTES_INT_INT() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
byte[] value = new byte[random.nextInt(128)];
random.nextBytes(value);
int off = random.nextInt(value.length + 1);
int len = random.nextInt(value.length - off + 1);
- for (PrimitiveSink sink : sinks) {
+ for (Sink sink : sinks) {
sink.putBytes(value);
}
}
- },
- PUT_STRING() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
- char[] value = new char[random.nextInt(128)];
- for (int i = 0; i < value.length; i++) {
- value[i] = (char) random.nextInt();
- }
- String s = new String(value);
- for (PrimitiveSink sink : sinks) {
- sink.putString(s);
- }
- }
- },
- PUT_STRING_LOW_SURROGATE() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
- String s = new String(new char[] { randomLowSurrogate(random) });
- for (PrimitiveSink sink : sinks) {
- sink.putString(s);
- }
- }
- },
- PUT_STRING_HIGH_SURROGATE() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
- String s = new String(new char[] { randomHighSurrogate(random) });
- for (PrimitiveSink sink : sinks) {
- sink.putString(s);
- }
- }
- },
- PUT_STRING_LOW_HIGH_SURROGATE() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
- String s = new String(new char[] {
- randomLowSurrogate(random), randomHighSurrogate(random)});
- for (PrimitiveSink sink : sinks) {
- sink.putString(s);
- }
- }
- },
- PUT_STRING_HIGH_LOW_SURROGATE() {
- @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
- String s = new String(new char[] {
- randomHighSurrogate(random), randomLowSurrogate(random)});
- for (PrimitiveSink sink : sinks) {
- sink.putString(s);
- }
- }
};
-
- abstract void performAction(Random random, Iterable<? extends PrimitiveSink> sinks);
-
+
+ abstract void performAction(Random random, Iterable<? extends Sink> sinks);
+
private static final RandomHasherAction[] actions = values();
-
+
static RandomHasherAction pickAtRandom(Random random) {
return actions[random.nextInt(actions.length)];
}
}
-
- /**
- * Test that the hash function contains no funnels. A funnel is a situation where a set of input
- * (key) bits 'affects' a strictly smaller set of output bits. Funneling is bad because it can
- * result in more-than-ideal collisions for a non-uniformly distributed key space. In practice,
- * most key spaces are ANYTHING BUT uniformly distributed. A bit(i) in the input is said to
- * 'affect' a bit(j) in the output if two inputs, identical but for bit(i), will differ at output
- * bit(j) about half the time
- *
- * <p>Funneling is pretty simple to detect. The key idea is to find example keys which
- * unequivocably demonstrate that funneling cannot be occuring. This is done bit-by-bit. For
- * each input bit(i) and output bit(j), two pairs of keys must be found with all bits identical
- * except bit(i). One pair must differ in output bit(j), and one pair must not. This proves that
- * input bit(i) can alter output bit(j).
- */
- static void checkNoFunnels(HashFunction function) {
- Random rand = new Random(0);
- int keyBits = 32;
- int hashBits = function.bits();
-
- // output loop tests input bit
- for (int i = 0; i < keyBits; i++) {
- int same = 0x0; // bitset for output bits with same values
- int diff = 0x0; // bitset for output bits with different values
- int count = 0;
- // originally was 2 * Math.log(...), making it try more times to avoid flakiness issues
- int maxCount = (int) (4 * Math.log(2 * keyBits * hashBits) + 1);
- while (same != 0xffffffff || diff != 0xffffffff) {
- int key1 = rand.nextInt();
- // flip input bit for key2
- int key2 = key1 ^ (1 << i);
- // get hashes
- int hash1 = function.newHasher().putInt(key1).hash().asInt();
- int hash2 = function.newHasher().putInt(key2).hash().asInt();
- // test whether the hash values have same output bits
- same |= ~(hash1 ^ hash2);
- // test whether the hash values have different output bits
- diff |= (hash1 ^ hash2);
-
- count++;
- // check whether we've exceeded the probabilistically
- // likely number of trials to have proven no funneling
- if (count > maxCount) {
- Assert.fail("input bit(" + i + ") was found not to affect all " +
- hashBits + " output bits; The unaffected bits are " +
- "as follows: " + ~(same & diff) + ". This was " +
- "determined after " + count + " trials.");
- }
- }
- }
- }
-
- /**
- * Test for avalanche. Avalanche means that output bits differ with roughly 1/2 probability on
- * different input keys. This test verifies that each possible 1-bit key delta achieves avalanche.
- *
- * <p>For more information: http://burtleburtle.net/bob/hash/avalanche.html
- */
- static void checkAvalanche(HashFunction function, int trials, double epsilon) {
- Random rand = new Random(0);
- int keyBits = 32;
- int hashBits = function.bits();
- for (int i = 0; i < keyBits; i++) {
- int[] same = new int[hashBits];
- int[] diff = new int[hashBits];
- // go through trials to compute probability
- for (int j = 0; j < trials; j++) {
- int key1 = rand.nextInt();
- // flip input bit for key2
- int key2 = key1 ^ (1 << i);
- // compute hash values
- int hash1 = function.newHasher().putInt(key1).hash().asInt();
- int hash2 = function.newHasher().putInt(key2).hash().asInt();
- for (int k = 0; k < hashBits; k++) {
- if ((hash1 & (1 << k)) == (hash2 & (1 << k))) {
- same[k] += 1;
- } else {
- diff[k] += 1;
- }
- }
- }
- // measure probability and assert it's within margin of error
- for (int j = 0; j < hashBits; j++) {
- double prob = (double) diff[j] / (double) (diff[j] + same[j]);
- Assert.assertEquals(0.50d, prob, epsilon);
- }
- }
- }
-
- /**
- * Test for 2-bit characteristics. A characteristic is a delta in the input which is repeated in
- * the output. For example, if f() is a block cipher and c is a characteristic, then
- * f(x^c) = f(x)^c with greater than expected probability. The test for funneling is merely a test
- * for 1-bit characteristics.
- *
- * <p>There is more general code provided by Bob Jenkins to test arbitrarily sized characteristics
- * using the magic of gaussian elimination: http://burtleburtle.net/bob/crypto/findingc.html.
- */
- static void checkNo2BitCharacteristics(HashFunction function) {
- Random rand = new Random(0);
- int keyBits = 32;
-
- // get every one of (keyBits choose 2) deltas:
- for (int i = 0; i < keyBits; i++) {
- for (int j = 0; j < keyBits; j++) {
- if (j <= i) continue;
- int count = 0;
- int maxCount = 20; // the probability of error here is miniscule
- boolean diff = false;
-
- while (diff == false) {
- int delta = (1 << i) | (1 << j);
- int key1 = rand.nextInt();
- // apply delta
- int key2 = key1 ^ delta;
-
- // get hashes
- int hash1 = function.newHasher().putInt(key1).hash().asInt();
- int hash2 = function.newHasher().putInt(key2).hash().asInt();
-
- // this 2-bit candidate delta is not a characteristic
- // if deltas are different
- if ((hash1 ^ hash2) != delta) {
- diff = true;
- continue;
- }
-
- // check if we've exceeded the probabilistically
- // likely number of trials to have proven 2-bit candidate
- // is not a characteristic
- count++;
- if (count > maxCount) {
- Assert.fail("2-bit delta (" + i + ", " + j + ") is likely a " +
- "characteristic for this hash. This was " +
- "determined after " + count + " trials");
- }
- }
- }
- }
- }
-
- /**
- * Test for avalanche with 2-bit deltas. Most probabilities of output bit(j) differing are well
- * within 50%.
- */
- static void check2BitAvalanche(HashFunction function, int trials, double epsilon) {
- Random rand = new Random(0);
- int keyBits = 32;
- int hashBits = function.bits();
- for (int bit1 = 0; bit1 < keyBits; bit1++) {
- for (int bit2 = 0; bit2 < keyBits; bit2++) {
- if (bit2 <= bit1) continue;
- int delta = (1 << bit1) | (1 << bit2);
- int[] same = new int[hashBits];
- int[] diff = new int[hashBits];
- // go through trials to compute probability
- for (int j = 0; j < trials; j++) {
- int key1 = rand.nextInt();
- // flip input bit for key2
- int key2 = key1 ^ delta;
- // compute hash values
- int hash1 = function.newHasher().putInt(key1).hash().asInt();
- int hash2 = function.newHasher().putInt(key2).hash().asInt();
- for (int k = 0; k < hashBits; k++) {
- if ((hash1 & (1 << k)) == (hash2 & (1 << k))) {
- same[k] += 1;
- } else {
- diff[k] += 1;
- }
- }
- }
- // measure probability and assert it's within margin of error
- for (int j = 0; j < hashBits; j++) {
- double prob = (double) diff[j] / (double) (diff[j] + same[j]);
- Assert.assertEquals(0.50d, prob, epsilon);
- }
- }
- }
- }
-
- /**
- * Checks that a Hasher returns the same HashCode when given the same input, and also
- * that the collision rate looks sane.
- */
- static void assertInvariants(HashFunction hashFunction) {
- int objects = 100;
- Set<HashCode> hashcodes = Sets.newHashSetWithExpectedSize(objects);
- for (int i = 0; i < objects; i++) {
- Object o = new Object();
- HashCode hashcode1 = hashFunction.hashObject(o, HashTestUtils.BAD_FUNNEL);
- HashCode hashcode2 = hashFunction.hashObject(o, HashTestUtils.BAD_FUNNEL);
- Assert.assertEquals(hashcode1, hashcode2); // idempotent
- Assert.assertEquals(hashFunction.bits(), hashcode1.bits());
- Assert.assertEquals(hashFunction.bits(), hashcode1.asBytes().length * 8);
- hashcodes.add(hashcode1);
- }
- Assert.assertTrue(hashcodes.size() > objects * 0.95); // quite relaxed test
-
- assertHashBytesThrowsCorrectExceptions(hashFunction);
- assertIndependentHashers(hashFunction);
- assertShortcutsAreEquivalent(hashFunction, 512);
- }
-
- static void assertHashBytesThrowsCorrectExceptions(HashFunction hashFunction) {
- hashFunction.hashBytes(new byte[64], 0, 0);
-
- try {
- hashFunction.hashBytes(new byte[128], -1, 128);
- Assert.fail();
- } catch (IndexOutOfBoundsException expected) {}
- try {
- hashFunction.hashBytes(new byte[128], 64, 256 /* too long len */);
- Assert.fail();
- } catch (IndexOutOfBoundsException expected) {}
- try {
- hashFunction.hashBytes(new byte[64], 0, -1);
- Assert.fail();
- } catch (IndexOutOfBoundsException expected) {}
- }
-
- static void assertIndependentHashers(HashFunction hashFunction) {
- int numActions = 100;
- // hashcodes from non-overlapping hash computations
- HashCode expected1 = randomHash(hashFunction, new Random(1L), numActions);
- HashCode expected2 = randomHash(hashFunction, new Random(2L), numActions);
-
- // equivalent, but overlapping, computations (should produce the same results as above)
- Random random1 = new Random(1L);
- Random random2 = new Random(2L);
- Hasher hasher1 = hashFunction.newHasher();
- Hasher hasher2 = hashFunction.newHasher();
- for (int i = 0; i < numActions; i++) {
- RandomHasherAction.pickAtRandom(random1).performAction(random1, ImmutableSet.of(hasher1));
- RandomHasherAction.pickAtRandom(random2).performAction(random2, ImmutableSet.of(hasher2));
- }
-
- Assert.assertEquals(expected1, hasher1.hash());
- Assert.assertEquals(expected2, hasher2.hash());
- }
-
- static HashCode randomHash(HashFunction hashFunction, Random random, int numActions) {
- Hasher hasher = hashFunction.newHasher();
- for (int i = 0; i < numActions; i++) {
- RandomHasherAction.pickAtRandom(random).performAction(random, ImmutableSet.of(hasher));
- }
- return hasher.hash();
- }
-
- private static void assertShortcutsAreEquivalent(HashFunction hashFunction, int trials) {
- Random random = new Random(42085L);
- for (int i = 0; i < trials; i++) {
- assertHashBytesEquivalence(hashFunction, random);
- assertHashIntEquivalence(hashFunction, random);
- assertHashLongEquivalence(hashFunction, random);
- assertHashStringEquivalence(hashFunction, random);
- assertHashStringWithSurrogatesEquivalence(hashFunction, random);
- }
- }
-
- private static void assertHashBytesEquivalence(HashFunction hashFunction, Random random) {
- int size = random.nextInt(2048);
- byte[] bytes = new byte[size];
- random.nextBytes(bytes);
- assertEquals(hashFunction.hashBytes(bytes),
- hashFunction.newHasher(size).putBytes(bytes).hash());
- int off = random.nextInt(size);
- int len = random.nextInt(size - off);
- assertEquals(hashFunction.hashBytes(bytes, off, len),
- hashFunction.newHasher(size).putBytes(bytes, off, len).hash());
- }
-
- private static void assertHashIntEquivalence(HashFunction hashFunction, Random random) {
- int i = random.nextInt();
- assertEquals(hashFunction.hashInt(i),
- hashFunction.newHasher().putInt(i).hash());
- }
-
- private static void assertHashLongEquivalence(HashFunction hashFunction, Random random) {
- long l = random.nextLong();
- assertEquals(hashFunction.hashLong(l),
- hashFunction.newHasher().putLong(l).hash());
- }
-
- private static final ImmutableList<Charset> CHARSETS = ImmutableList.of(
- Charsets.ISO_8859_1,
- Charsets.US_ASCII,
- Charsets.UTF_16,
- Charsets.UTF_16BE,
- Charsets.UTF_16LE,
- Charsets.UTF_8);
-
- private static void assertHashStringEquivalence(HashFunction hashFunction, Random random) {
- // Test that only data and data-order is important, not the individual operations.
- new EqualsTester()
- .addEqualityGroup(
- hashFunction.newHasher().putString("abc").hash(),
- hashFunction.newHasher().putString("ab").putString("c").hash(),
- hashFunction.newHasher().putString("a").putString("bc").hash(),
- hashFunction.newHasher().putString("a").putString("b").putString("c").hash(),
- hashFunction.newHasher().putChar('a').putString("bc").hash(),
- hashFunction.newHasher().putString("ab").putChar('c').hash(),
- hashFunction.newHasher().putChar('a').putChar('b').putChar('c').hash())
- .testEquals();
-
- int size = random.nextInt(2048);
- byte[] bytes = new byte[size];
- random.nextBytes(bytes);
- String string = new String(bytes);
- assertEquals(hashFunction.hashString(string),
- hashFunction.newHasher().putString(string).hash());
- // These assertions causes failures when testing with mvn. See b/6657789
- // assertEquals(hashFunction.hashString(string),
- // hashFunction.hashString(string, Charsets.UTF_16LE));
- // assertEquals(hashFunction.hashString(string),
- // hashFunction.newHasher().putString(string, Charsets.UTF_16LE).hash());
- for (Charset charset : CHARSETS) {
- assertEquals(hashFunction.hashString(string, charset),
- hashFunction.newHasher().putString(string, charset).hash());
- }
- }
-
- /**
- * This verifies that putString(String) and hashString(String) are equivalent, even for
- * funny strings composed by (possibly unmatched, and mostly illegal) surrogate characters.
- * (But doesn't test that they do the right thing - just their consistency).
- */
- private static void assertHashStringWithSurrogatesEquivalence(
- HashFunction hashFunction, Random random) {
- int size = random.nextInt(8) + 1;
- char[] chars = new char[size];
- for (int i = 0; i < chars.length; i++) {
- chars[i] = random.nextBoolean() ? randomLowSurrogate(random) : randomHighSurrogate(random);
- }
- String string = new String(chars);
- assertEquals(hashFunction.hashString(string),
- hashFunction.newHasher().putString(string).hash());
- }
-
- static char randomLowSurrogate(Random random) {
- return (char) (Character.MIN_LOW_SURROGATE
- + random.nextInt(Character.MAX_LOW_SURROGATE - Character.MIN_LOW_SURROGATE + 1));
- }
-
- static char randomHighSurrogate(Random random) {
- return (char) (Character.MIN_HIGH_SURROGATE
- + random.nextInt(Character.MAX_HIGH_SURROGATE - Character.MIN_HIGH_SURROGATE + 1));
- }
}
diff --git a/guava-tests/test/com/google/common/hash/HashingTest.java b/guava-tests/test/com/google/common/hash/HashingTest.java
index f5488a1..547d5a3 100644
--- a/guava-tests/test/com/google/common/hash/HashingTest.java
+++ b/guava-tests/test/com/google/common/hash/HashingTest.java
@@ -16,125 +16,20 @@
package com.google.common.hash;
-import static com.google.common.hash.Hashing.ConcatenatedHashFunction;
-
-import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Lists;
-import com.google.common.collect.Table.Cell;
-import com.google.common.testing.NullPointerTester;
import com.google.common.util.concurrent.AtomicLongMap;
import junit.framework.TestCase;
-import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/**
- * Unit tests for {@link Hashing}.
- *
- * @author Dimitris Andreou
- * @author Kurt Alfred Kluever
+ * Unit tests for functions of {@code Hashing} that don't have their own tests.
*/
public class HashingTest extends TestCase {
- public void testMd5() {
- HashTestUtils.checkAvalanche(Hashing.md5(), 100, 0.4);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.md5());
- HashTestUtils.checkNoFunnels(Hashing.md5());
- HashTestUtils.assertInvariants(Hashing.md5());
- assertEquals("Hashing.md5()", Hashing.md5().toString());
- }
-
- public void testSha1() {
- HashTestUtils.checkAvalanche(Hashing.sha1(), 100, 0.4);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.sha1());
- HashTestUtils.checkNoFunnels(Hashing.sha1());
- HashTestUtils.assertInvariants(Hashing.sha1());
- assertEquals("Hashing.sha1()", Hashing.sha1().toString());
- }
-
- public void testSha256() {
- HashTestUtils.checkAvalanche(Hashing.sha256(), 100, 0.4);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.sha256());
- HashTestUtils.checkNoFunnels(Hashing.sha256());
- HashTestUtils.assertInvariants(Hashing.sha256());
- assertEquals("Hashing.sha256()", Hashing.sha256().toString());
- }
-
- public void testSha512() {
- HashTestUtils.checkAvalanche(Hashing.sha512(), 100, 0.4);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.sha512());
- HashTestUtils.checkNoFunnels(Hashing.sha512());
- HashTestUtils.assertInvariants(Hashing.sha512());
- assertEquals("Hashing.sha512()", Hashing.sha512().toString());
- }
-
- public void testCrc32() {
- HashTestUtils.assertInvariants(Hashing.crc32());
- assertEquals("Hashing.crc32()", Hashing.crc32().toString());
- }
-
- public void testAdler32() {
- HashTestUtils.assertInvariants(Hashing.adler32());
- assertEquals("Hashing.adler32()", Hashing.adler32().toString());
- }
-
- public void testMurmur3_128() {
- HashTestUtils.check2BitAvalanche(Hashing.murmur3_128(), 250, 0.20);
- HashTestUtils.checkAvalanche(Hashing.murmur3_128(), 250, 0.17);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.murmur3_128());
- HashTestUtils.checkNoFunnels(Hashing.murmur3_128());
- HashTestUtils.assertInvariants(Hashing.murmur3_128());
- assertEquals("Hashing.murmur3_128(0)", Hashing.murmur3_128().toString());
- }
-
- public void testMurmur3_32() {
- HashTestUtils.check2BitAvalanche(Hashing.murmur3_32(), 250, 0.20);
- HashTestUtils.checkAvalanche(Hashing.murmur3_32(), 250, 0.17);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.murmur3_32());
- HashTestUtils.checkNoFunnels(Hashing.murmur3_32());
- HashTestUtils.assertInvariants(Hashing.murmur3_32());
- assertEquals("Hashing.murmur3_32(0)", Hashing.murmur3_32().toString());
- }
-
- public void testGoodFastHash() {
- for (int i = 1; i < 200; i += 17) {
- HashFunction hasher = Hashing.goodFastHash(i);
- assertTrue(hasher.bits() >= i);
- HashTestUtils.assertInvariants(hasher);
- }
- }
-
- // goodFastHash(32) uses Murmur3_32. Use the same epsilon bounds.
- public void testGoodFastHash32() {
- HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(32), 250, 0.20);
- HashTestUtils.checkAvalanche(Hashing.goodFastHash(32), 250, 0.17);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(32));
- HashTestUtils.checkNoFunnels(Hashing.goodFastHash(32));
- HashTestUtils.assertInvariants(Hashing.goodFastHash(32));
- }
-
- // goodFastHash(128) uses Murmur3_128. Use the same epsilon bounds.
- public void testGoodFastHash128() {
- HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(128), 250, 0.20);
- HashTestUtils.checkAvalanche(Hashing.goodFastHash(128), 250, 0.17);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(128));
- HashTestUtils.checkNoFunnels(Hashing.goodFastHash(128));
- HashTestUtils.assertInvariants(Hashing.goodFastHash(128));
- }
-
- // goodFastHash(256) uses Murmur3_128. Use the same epsilon bounds.
- public void testGoodFastHash256() {
- HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(256), 250, 0.20);
- HashTestUtils.checkAvalanche(Hashing.goodFastHash(256), 250, 0.17);
- HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(256));
- HashTestUtils.checkNoFunnels(Hashing.goodFastHash(256));
- HashTestUtils.assertInvariants(Hashing.goodFastHash(256));
- }
-
public void testPadToLong() {
assertEquals(0x1111111111111111L, Hashing.padToLong(HashCodes.fromLong(0x1111111111111111L)));
assertEquals(0x9999999999999999L, Hashing.padToLong(HashCodes.fromLong(0x9999999999999999L)));
@@ -208,24 +103,14 @@ public class HashingTest extends TestCase {
assertEquals(Hashing.consistentHash(equivLong, 5555), Hashing.consistentHash(hashCode, 5555));
}
- /**
- * Tests that the linear congruential generator is actually compatible with the c++
- * implementation.
- *
- * This test was added to help refactoring, it is not a strict requirement, it can be removed if
- * functionality changes in the future.
- */
- public void testConsistentHash_linearCongruentialGeneratorCompatibility() {
- assertEquals(55, Hashing.consistentHash(1, 100));
- assertEquals(62, Hashing.consistentHash(2, 100));
- assertEquals(8, Hashing.consistentHash(3, 100));
- assertEquals(45, Hashing.consistentHash(4, 100));
- assertEquals(59, Hashing.consistentHash(5, 100));
+ public void testCombineOrdered_null() {
+ try {
+ Hashing.combineOrdered(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
}
- private static final double MAX_PERCENT_SPREAD = 0.5;
- private static final long RANDOM_SEED = 177L;
-
public void testCombineOrdered_empty() {
try {
Hashing.combineOrdered(Collections.<HashCode>emptySet());
@@ -268,6 +153,14 @@ public class HashingTest extends TestCase {
assertFalse(hashCode1.equals(hashCode2));
}
+ public void testCombineUnordered_null() {
+ try {
+ Hashing.combineUnordered(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
public void testCombineUnordered_empty() {
try {
Hashing.combineUnordered(Collections.<HashCode>emptySet());
@@ -308,82 +201,4 @@ public class HashingTest extends TestCase {
assertEquals(hashCode1, hashCode2);
}
-
- public void testConcatenatedHashFunction_bits() {
- assertEquals(Hashing.md5().bits(),
- new ConcatenatedHashFunction(Hashing.md5()).bits());
- assertEquals(Hashing.md5().bits() + Hashing.murmur3_32().bits(),
- new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32()).bits());
- assertEquals(Hashing.md5().bits() + Hashing.murmur3_32().bits() + Hashing.murmur3_128().bits(),
- new ConcatenatedHashFunction(
- Hashing.md5(), Hashing.murmur3_32(), Hashing.murmur3_128()).bits());
- }
-
- public void testConcatenatedHashFunction_makeHash() {
- byte[] md5Hash = Hashing.md5().hashLong(42L).asBytes();
- byte[] murmur3Hash = Hashing.murmur3_32().hashLong(42L).asBytes();
- byte[] combined = new byte[md5Hash.length + murmur3Hash.length];
- ByteBuffer buffer = ByteBuffer.wrap(combined);
- buffer.put(md5Hash);
- buffer.put(murmur3Hash);
-
- assertEquals(HashCodes.fromBytes(combined),
- new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32()).hashLong(42L));
- }
-
- private static final String EMPTY_STRING = "";
- private static final String TQBFJOTLD = "The quick brown fox jumps over the lazy dog";
- private static final String TQBFJOTLDP = "The quick brown fox jumps over the lazy dog.";
-
- private static final ImmutableTable<HashFunction, String, String> KNOWN_HASHES =
- ImmutableTable.<HashFunction, String, String>builder()
- .put(Hashing.adler32(), EMPTY_STRING, "01000000")
- .put(Hashing.adler32(), TQBFJOTLD, "da0fdc5b")
- .put(Hashing.adler32(), TQBFJOTLDP, "0810e46b")
- .put(Hashing.md5(), EMPTY_STRING, "d41d8cd98f00b204e9800998ecf8427e")
- .put(Hashing.md5(), TQBFJOTLD, "9e107d9d372bb6826bd81d3542a419d6")
- .put(Hashing.md5(), TQBFJOTLDP, "e4d909c290d0fb1ca068ffaddf22cbd0")
- .put(Hashing.murmur3_128(), EMPTY_STRING, "00000000000000000000000000000000")
- .put(Hashing.murmur3_128(), TQBFJOTLD, "6c1b07bc7bbc4be347939ac4a93c437a")
- .put(Hashing.murmur3_128(), TQBFJOTLDP, "c902e99e1f4899cde7b68789a3a15d69")
- .put(Hashing.murmur3_32(), EMPTY_STRING, "00000000")
- .put(Hashing.murmur3_32(), TQBFJOTLD, "23f74f2e")
- .put(Hashing.murmur3_32(), TQBFJOTLDP, "fc8bc4d5")
- .put(Hashing.sha1(), EMPTY_STRING, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
- .put(Hashing.sha1(), TQBFJOTLD, "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12")
- .put(Hashing.sha1(), TQBFJOTLDP, "408d94384216f890ff7a0c3528e8bed1e0b01621")
- .put(Hashing.sha256(), EMPTY_STRING,
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
- .put(Hashing.sha256(), TQBFJOTLD,
- "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")
- .put(Hashing.sha256(), TQBFJOTLDP,
- "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c")
- .put(Hashing.sha512(), EMPTY_STRING,
- "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" +
- "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
- .put(Hashing.sha512(), TQBFJOTLD,
- "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64" +
- "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6")
- .put(Hashing.sha512(), TQBFJOTLDP,
- "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" +
- "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed")
- .build();
-
- public void testKnownUtf8Hashing() {
- for (Cell<HashFunction, String, String> cell : KNOWN_HASHES.cellSet()) {
- HashFunction func = cell.getRowKey();
- String input = cell.getColumnKey();
- String expected = cell.getValue();
- assertEquals(
- String.format("Known hash for hash(%s, UTF_8) failed", input),
- expected,
- func.hashString(input, Charsets.UTF_8).toString());
- }
- }
-
- public void testNullPointers() {
- NullPointerTester tester = new NullPointerTester()
- .setDefault(HashCode.class, HashCodes.fromInt(0));
- tester.testAllPublicStaticMethods(Hashing.class);
- }
}
diff --git a/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java b/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java
index 2a9547b..a70466e 100644
--- a/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java
+++ b/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java
@@ -1,73 +1,34 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
-import com.google.common.collect.ImmutableSet;
-
-import junit.framework.TestCase;
-
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
+
+import junit.framework.TestCase;
/**
* Tests for the MessageDigestHashFunction.
*
- * @author Kurt Alfred Kluever
+ * @author kak@google.com (Kurt Alfred Kluever)
*/
public class MessageDigestHashFunctionTest extends TestCase {
- private static final ImmutableSet<String> INPUTS = ImmutableSet.of("", "Z", "foobar");
- private static final ImmutableSet<String> ALGORITHMS = ImmutableSet.of(
- "MD5", "SHA1", "SHA-1", "SHA-256", "SHA-512");
-
- public void testHashing() {
- for (String stringToTest : INPUTS) {
- for (String algorithmToTest : ALGORITHMS) {
- assertMessageDigestHashing(HashTestUtils.ascii(stringToTest), algorithmToTest);
- }
- }
+ public void testMd5Hashing() throws Exception {
+ assertMessageDigestHashing(HashTestUtils.ascii(""), "MD5");
+ assertMessageDigestHashing(HashTestUtils.ascii("Z"), "MD5");
+ assertMessageDigestHashing(HashTestUtils.ascii("foobar"), "MD5");
}
- public void testToString() {
- assertEquals("Hashing.md5()", Hashing.md5().toString());
- assertEquals("Hashing.sha1()", Hashing.sha1().toString());
- assertEquals("Hashing.sha256()", Hashing.sha256().toString());
- assertEquals("Hashing.sha512()", Hashing.sha512().toString());
+ public void testSha1Hashing() throws Exception {
+ assertMessageDigestHashing(HashTestUtils.ascii(""), "SHA1");
+ assertMessageDigestHashing(HashTestUtils.ascii("Z"), "SHA1");
+ assertMessageDigestHashing(HashTestUtils.ascii("foobar"), "SHA1");
}
- private static void assertMessageDigestHashing(byte[] input, String algorithmName) {
- try {
- MessageDigest digest = MessageDigest.getInstance(algorithmName);
- assertEquals(
- HashCodes.fromBytes(digest.digest(input)),
- new MessageDigestHashFunction(algorithmName, algorithmName).hashBytes(input));
- for (int bytes = 4; bytes <= digest.getDigestLength(); bytes++) {
- assertEquals(
- HashCodes.fromBytes(Arrays.copyOf(digest.digest(input), bytes)),
- new MessageDigestHashFunction(algorithmName, bytes, algorithmName).hashBytes(input));
- }
- try {
- int maxSize = digest.getDigestLength();
- new MessageDigestHashFunction(algorithmName, maxSize + 1, algorithmName);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- } catch (NoSuchAlgorithmException nsae) {
- throw new AssertionError(nsae);
- }
+ private static void assertMessageDigestHashing(byte[] input, String algorithmName)
+ throws NoSuchAlgorithmException {
+ HashTestUtils.assertEqualHashes(
+ MessageDigest.getInstance(algorithmName).digest(input),
+ new MessageDigestHashFunction(algorithmName).hashBytes(input).asBytes());
}
}
diff --git a/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java b/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java
index ab319fb..4a4eea7 100644
--- a/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java
+++ b/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java
@@ -16,55 +16,44 @@
package com.google.common.hash;
+import static com.google.common.hash.HashTestUtils.ascii;
+import static com.google.common.hash.HashTestUtils.toBytes;
import static com.google.common.hash.Hashing.murmur3_128;
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
-import com.google.common.base.Charsets;
import com.google.common.hash.Funnels;
import com.google.common.hash.HashTestUtils.HashFn;
import junit.framework.TestCase;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
+import java.util.Arrays;
/**
- * Tests for {@link Murmur3_128HashFunction}.
+ * Tests for Murmur3Hash128.
*/
public class Murmur3Hash128Test extends TestCase {
- public void testKnownValues() {
- assertHash(0, 0x629942693e10f867L, 0x92db0b82baeb5347L, "hell");
- assertHash(1, 0xa78ddff5adae8d10L, 0x128900ef20900135L, "hello");
- assertHash(2, 0x8a486b23f422e826L, 0xf962a2c58947765fL, "hello ");
- assertHash(3, 0x2ea59f466f6bed8cL, 0xc610990acc428a17L, "hello w");
- assertHash(4, 0x79f6305a386c572cL, 0x46305aed3483b94eL, "hello wo");
- assertHash(5, 0xc2219d213ec1f1b5L, 0xa1d8e2e0a52785bdL, "hello wor");
- assertHash(0, 0xe34bbc7bbc071b6cL, 0x7a433ca9c49a9347L,
- "The quick brown fox jumps over the lazy dog");
- assertHash(0, 0x658ca970ff85269aL, 0x43fee3eaa68e5c3eL,
- "The quick brown fox jumps over the lazy cog");
-
- // Known output from Python smhasher
- HashCode foxHash =
- murmur3_128(0).hashString("The quick brown fox jumps over the lazy dog", Charsets.UTF_8);
- assertEquals("6c1b07bc7bbc4be347939ac4a93c437a", foxHash.toString());
- }
-
- private static void assertHash(int seed, long expected1, long expected2, String stringInput) {
- HashCode expected = toHashCode(expected1, expected2);
- byte[] input = HashTestUtils.ascii(stringInput);
- assertEquals(expected, murmur3_128(seed).hashBytes(input));
- assertEquals(expected, murmur3_128(seed).newHasher().putBytes(input).hash());
+ public void testCompatibilityWithCPlusPlus() {
+ assertHash(0, toBytes(LITTLE_ENDIAN, 0x629942693e10f867L, 0x92db0b82baeb5347L),
+ ascii("hell"));
+ assertHash(1, toBytes(LITTLE_ENDIAN, 0xa78ddff5adae8d10L, 0x128900ef20900135L),
+ ascii("hello"));
+ assertHash(2, toBytes(LITTLE_ENDIAN, 0x8a486b23f422e826L, 0xf962a2c58947765fL),
+ ascii("hello "));
+ assertHash(3, toBytes(LITTLE_ENDIAN, 0x2ea59f466f6bed8cL, 0xc610990acc428a17L),
+ ascii("hello w"));
+ assertHash(4, toBytes(LITTLE_ENDIAN, 0x79f6305a386c572cL, 0x46305aed3483b94eL),
+ ascii("hello wo"));
+ assertHash(5, toBytes(LITTLE_ENDIAN, 0xc2219d213ec1f1b5L, 0xa1d8e2e0a52785bdL),
+ ascii("hello wor"));
+ assertHash(0, toBytes(LITTLE_ENDIAN, 0xe34bbc7bbc071b6cL, 0x7a433ca9c49a9347L),
+ ascii("The quick brown fox jumps over the lazy dog"));
+ assertHash(0, toBytes(LITTLE_ENDIAN, 0x658ca970ff85269aL, 0x43fee3eaa68e5c3eL),
+ ascii("The quick brown fox jumps over the lazy cog"));
}
-
- /**
- * Returns a {@link HashCode} for a sequence of longs, in big-endian order.
- */
- private static HashCode toHashCode(long... longs) {
- ByteBuffer bb = ByteBuffer.wrap(new byte[longs.length * 8]).order(ByteOrder.LITTLE_ENDIAN);
- for (long x : longs) {
- bb.putLong(x);
- }
- return HashCodes.fromBytes(bb.array());
+
+ private static void assertHash(int seed, byte[] expectedHash, byte[] input) {
+ byte[] hash = murmur3_128(seed).newHasher().putBytes(input).hash().asBytes();
+ assertTrue(Arrays.equals(expectedHash, hash));
}
public void testParanoid() {
@@ -75,12 +64,8 @@ public class Murmur3Hash128Test extends TestCase {
return hasher.hash().asBytes();
}
};
- // Murmur3F, MurmurHash3 for x64, 128-bit (MurmurHash3_x64_128)
- // From http://code.google.com/p/smhasher/source/browse/trunk/main.cpp
+ // the magic number comes from:
+ // http://code.google.com/p/smhasher/source/browse/trunk/main.cpp, #74
HashTestUtils.verifyHashFunction(hf, 128, 0x6384BA69);
}
-
- public void testInvariants() {
- HashTestUtils.assertInvariants(murmur3_128());
- }
}
diff --git a/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java b/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java
index dcd57ae..541b53a 100644
--- a/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java
+++ b/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java
@@ -24,38 +24,9 @@ import com.google.common.hash.HashTestUtils.HashFn;
import junit.framework.TestCase;
/**
- * Tests for {@link Murmur3_32HashFunction}.
+ * Tests for Murmur3Hash32.
*/
public class Murmur3Hash32Test extends TestCase {
- public void testKnownIntegerInputs() {
- assertHash(593689054, murmur3_32().hashInt(0));
- assertHash(-189366624, murmur3_32().hashInt(-42));
- assertHash(-1134849565, murmur3_32().hashInt(42));
- assertHash(-1718298732, murmur3_32().hashInt(Integer.MIN_VALUE));
- assertHash(-1653689534, murmur3_32().hashInt(Integer.MAX_VALUE));
- }
-
- public void testKnownLongInputs() {
- assertHash(1669671676, murmur3_32().hashLong(0L));
- assertHash(-846261623, murmur3_32().hashLong(-42L));
- assertHash(1871679806, murmur3_32().hashLong(42L));
- assertHash(1366273829, murmur3_32().hashLong(Long.MIN_VALUE));
- assertHash(-2106506049, murmur3_32().hashLong(Long.MAX_VALUE));
- }
-
- public void testKnownStringInputs() {
- assertHash(0, murmur3_32().hashString(""));
- assertHash(679745764, murmur3_32().hashString("k"));
- assertHash(1510782915, murmur3_32().hashString("hell"));
- assertHash(-675079799, murmur3_32().hashString("hello"));
- assertHash(1935035788, murmur3_32().hashString("http://www.google.com/"));
- assertHash(-528633700, murmur3_32().hashString("The quick brown fox jumps over the lazy dog"));
- }
-
- private static void assertHash(int expected, HashCode actual) {
- assertEquals(HashCodes.fromInt(expected), actual);
- }
-
public void testParanoid() {
HashFn hf = new HashFn() {
@Override public byte[] hash(byte[] input, int seed) {
@@ -64,12 +35,8 @@ public class Murmur3Hash32Test extends TestCase {
return hasher.hash().asBytes();
}
};
- // Murmur3A, MurmurHash3 for x86, 32-bit (MurmurHash3_x86_32)
- // http://code.google.com/p/smhasher/source/browse/trunk/main.cpp
+ // the magic number comes from:
+ // http://code.google.com/p/smhasher/source/browse/trunk/main.cpp, #72
HashTestUtils.verifyHashFunction(hf, 32, 0xB0F57EE3);
}
-
- public void testInvariants() {
- HashTestUtils.assertInvariants(murmur3_32());
- }
}
diff --git a/guava-tests/test/com/google/common/hash/PackageSanityTests.java b/guava-tests/test/com/google/common/hash/PackageSanityTests.java
deleted file mode 100644
index a752a33..0000000
--- a/guava-tests/test/com/google/common/hash/PackageSanityTests.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import com.google.common.hash.BloomFilterStrategies.BitArray;
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- setDefault(BitArray.class, new BitArray(1));
- setDefault(HashCode.class, HashCodes.fromInt(1));
- setDefault(String.class, "MD5");
- setDefault(int.class, 32);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/BaseEncodingTest.java b/guava-tests/test/com/google/common/io/BaseEncodingTest.java
deleted file mode 100644
index fb33841..0000000
--- a/guava-tests/test/com/google/common/io/BaseEncodingTest.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.BaseEncoding.base16;
-import static com.google.common.io.BaseEncoding.base32;
-import static com.google.common.io.BaseEncoding.base32Hex;
-import static com.google.common.io.BaseEncoding.base64;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Ascii;
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Tests for {@code BaseEncoding}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BaseEncodingTest extends TestCase {
- public void assertEquals(byte[] expected, byte[] actual) {
- assertEquals(expected.length, actual.length);
- for (int i = 0; i < expected.length; i++) {
- assertEquals(expected[i], actual[i]);
- }
- }
-
- public void testSeparatorsExplicitly() {
- testEncodes(base64().withSeparator("\n", 3), "foobar", "Zm9\nvYm\nFy");
- testEncodes(base64().withSeparator("$", 4), "foobar", "Zm9v$YmFy");
- testEncodes(base32().withSeparator("*", 4), "foobar", "MZXW*6YTB*OI==*====");
- }
-
- @SuppressWarnings("ReturnValueIgnored")
- public void testSeparatorSameAsPadChar() {
- try {
- base64().withSeparator("=", 3);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
-
- try {
- base64().withPadChar('#').withSeparator("!#!", 3);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
- }
-
- @SuppressWarnings("ReturnValueIgnored")
- public void testAtMostOneSeparator() {
- BaseEncoding separated = base64().withSeparator("\n", 3);
- try {
- separated.withSeparator("$", 4);
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException expected) {}
- }
-
- public void testBase64() {
- // The following test vectors are specified in RFC 4648 itself
- testEncodingWithSeparators(base64(), "", "");
- testEncodingWithSeparators(base64(), "f", "Zg==");
- testEncodingWithSeparators(base64(), "fo", "Zm8=");
- testEncodingWithSeparators(base64(), "foo", "Zm9v");
- testEncodingWithSeparators(base64(), "foob", "Zm9vYg==");
- testEncodingWithSeparators(base64(), "fooba", "Zm9vYmE=");
- testEncodingWithSeparators(base64(), "foobar", "Zm9vYmFy");
- }
-
- @GwtIncompatible("Reader/Writer")
- public void testBase64Streaming() throws IOException {
- // The following test vectors are specified in RFC 4648 itself
- testStreamingEncodingWithSeparators(base64(), "", "");
- testStreamingEncodingWithSeparators(base64(), "f", "Zg==");
- testStreamingEncodingWithSeparators(base64(), "fo", "Zm8=");
- testStreamingEncodingWithSeparators(base64(), "foo", "Zm9v");
- testStreamingEncodingWithSeparators(base64(), "foob", "Zm9vYg==");
- testStreamingEncodingWithSeparators(base64(), "fooba", "Zm9vYmE=");
- testStreamingEncodingWithSeparators(base64(), "foobar", "Zm9vYmFy");
- }
-
- public void testBase64LenientPadding() {
- testDecodes(base64(), "Zg", "f");
- testDecodes(base64(), "Zg=", "f");
- testDecodes(base64(), "Zg==", "f"); // proper padding length
- testDecodes(base64(), "Zg===", "f");
- testDecodes(base64(), "Zg====", "f");
- }
-
- public void testBase64InvalidDecodings() {
- // These contain bytes not in the decodabet.
- assertFailsToDecode(base64(), "\u007f");
- assertFailsToDecode(base64(), "Wf2!");
- // This sentence just isn't base64() encoded.
- assertFailsToDecode(base64(), "let's not talk of love or chains!");
- // A 4n+1 length string is never legal base64().
- assertFailsToDecode(base64(), "12345");
- }
-
- @SuppressWarnings("ReturnValueIgnored")
- public void testBase64CannotUpperCase() {
- try {
- base64().upperCase();
- fail();
- } catch (IllegalStateException expected) {
- // success
- }
- }
-
- @SuppressWarnings("ReturnValueIgnored")
- public void testBase64CannotLowerCase() {
- try {
- base64().lowerCase();
- fail();
- } catch (IllegalStateException expected) {
- // success
- }
- }
-
- public void testBase64AlternatePadding() {
- BaseEncoding enc = base64().withPadChar('~');
- testEncodingWithSeparators(enc, "", "");
- testEncodingWithSeparators(enc, "f", "Zg~~");
- testEncodingWithSeparators(enc, "fo", "Zm8~");
- testEncodingWithSeparators(enc, "foo", "Zm9v");
- testEncodingWithSeparators(enc, "foob", "Zm9vYg~~");
- testEncodingWithSeparators(enc, "fooba", "Zm9vYmE~");
- testEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
- }
-
- @GwtIncompatible("Reader/Writer")
- public void testBase64StreamingAlternatePadding() throws IOException {
- BaseEncoding enc = base64().withPadChar('~');
- testStreamingEncodingWithSeparators(enc, "", "");
- testStreamingEncodingWithSeparators(enc, "f", "Zg~~");
- testStreamingEncodingWithSeparators(enc, "fo", "Zm8~");
- testStreamingEncodingWithSeparators(enc, "foo", "Zm9v");
- testStreamingEncodingWithSeparators(enc, "foob", "Zm9vYg~~");
- testStreamingEncodingWithSeparators(enc, "fooba", "Zm9vYmE~");
- testStreamingEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
- }
-
- public void testBase64OmitPadding() {
- BaseEncoding enc = base64().omitPadding();
- testEncodingWithSeparators(enc, "", "");
- testEncodingWithSeparators(enc, "f", "Zg");
- testEncodingWithSeparators(enc, "fo", "Zm8");
- testEncodingWithSeparators(enc, "foo", "Zm9v");
- testEncodingWithSeparators(enc, "foob", "Zm9vYg");
- testEncodingWithSeparators(enc, "fooba", "Zm9vYmE");
- testEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
- }
-
- @GwtIncompatible("Reader/Writer")
- public void testBase64StreamingOmitPadding() throws IOException {
- BaseEncoding enc = base64().omitPadding();
- testStreamingEncodingWithSeparators(enc, "", "");
- testStreamingEncodingWithSeparators(enc, "f", "Zg");
- testStreamingEncodingWithSeparators(enc, "fo", "Zm8");
- testStreamingEncodingWithSeparators(enc, "foo", "Zm9v");
- testStreamingEncodingWithSeparators(enc, "foob", "Zm9vYg");
- testStreamingEncodingWithSeparators(enc, "fooba", "Zm9vYmE");
- testStreamingEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
- }
-
- public void testBase32() {
- // The following test vectors are specified in RFC 4648 itself
- testEncodingWithCasing(base32(), "", "");
- testEncodingWithCasing(base32(), "f", "MY======");
- testEncodingWithCasing(base32(), "fo", "MZXQ====");
- testEncodingWithCasing(base32(), "foo", "MZXW6===");
- testEncodingWithCasing(base32(), "foob", "MZXW6YQ=");
- testEncodingWithCasing(base32(), "fooba", "MZXW6YTB");
- testEncodingWithCasing(base32(), "foobar", "MZXW6YTBOI======");
- }
-
- @GwtIncompatible("Reader/Writer")
- public void testBase32Streaming() throws IOException {
- // The following test vectors are specified in RFC 4648 itself
- testStreamingEncodingWithCasing(base32(), "", "");
- testStreamingEncodingWithCasing(base32(), "f", "MY======");
- testStreamingEncodingWithCasing(base32(), "fo", "MZXQ====");
- testStreamingEncodingWithCasing(base32(), "foo", "MZXW6===");
- testStreamingEncodingWithCasing(base32(), "foob", "MZXW6YQ=");
- testStreamingEncodingWithCasing(base32(), "fooba", "MZXW6YTB");
- testStreamingEncodingWithCasing(base32(), "foobar", "MZXW6YTBOI======");
- }
-
- public void testBase32LenientPadding() {
- testDecodes(base32(), "MZXW6", "foo");
- testDecodes(base32(), "MZXW6=", "foo");
- testDecodes(base32(), "MZXW6==", "foo");
- testDecodes(base32(), "MZXW6===", "foo"); // proper padding length
- testDecodes(base32(), "MZXW6====", "foo");
- testDecodes(base32(), "MZXW6=====", "foo");
- }
-
- public void testBase32AlternatePadding() {
- BaseEncoding enc = base32().withPadChar('~');
- testEncodingWithCasing(enc, "", "");
- testEncodingWithCasing(enc, "f", "MY~~~~~~");
- testEncodingWithCasing(enc, "fo", "MZXQ~~~~");
- testEncodingWithCasing(enc, "foo", "MZXW6~~~");
- testEncodingWithCasing(enc, "foob", "MZXW6YQ~");
- testEncodingWithCasing(enc, "fooba", "MZXW6YTB");
- testEncodingWithCasing(enc, "foobar", "MZXW6YTBOI~~~~~~");
- }
-
- public void testBase32InvalidDecodings() {
- // These contain bytes not in the decodabet.
- assertFailsToDecode(base32(), "\u007f");
- assertFailsToDecode(base32(), "Wf2!");
- // This sentence just isn't base32() encoded.
- assertFailsToDecode(base32(), "let's not talk of love or chains!");
- // An 8n+{1,3,6} length string is never legal base32.
- assertFailsToDecode(base32(), "A");
- assertFailsToDecode(base32(), "ABC");
- assertFailsToDecode(base32(), "ABCDEF");
- }
-
- public void testBase32UpperCaseIsNoOp() {
- assertSame(base32(), base32().upperCase());
- }
-
- public void testBase32Hex() {
- // The following test vectors are specified in RFC 4648 itself
- testEncodingWithCasing(base32Hex(), "", "");
- testEncodingWithCasing(base32Hex(), "f", "CO======");
- testEncodingWithCasing(base32Hex(), "fo", "CPNG====");
- testEncodingWithCasing(base32Hex(), "foo", "CPNMU===");
- testEncodingWithCasing(base32Hex(), "foob", "CPNMUOG=");
- testEncodingWithCasing(base32Hex(), "fooba", "CPNMUOJ1");
- testEncodingWithCasing(base32Hex(), "foobar", "CPNMUOJ1E8======");
- }
-
- @GwtIncompatible("Reader/Writer")
- public void testBase32HexStreaming() throws IOException {
- // The following test vectors are specified in RFC 4648 itself
- testStreamingEncodingWithCasing(base32Hex(), "", "");
- testStreamingEncodingWithCasing(base32Hex(), "f", "CO======");
- testStreamingEncodingWithCasing(base32Hex(), "fo", "CPNG====");
- testStreamingEncodingWithCasing(base32Hex(), "foo", "CPNMU===");
- testStreamingEncodingWithCasing(base32Hex(), "foob", "CPNMUOG=");
- testStreamingEncodingWithCasing(base32Hex(), "fooba", "CPNMUOJ1");
- testStreamingEncodingWithCasing(base32Hex(), "foobar", "CPNMUOJ1E8======");
- }
-
- public void testBase32HexLenientPadding() {
- testDecodes(base32Hex(), "CPNMU", "foo");
- testDecodes(base32Hex(), "CPNMU=", "foo");
- testDecodes(base32Hex(), "CPNMU==", "foo");
- testDecodes(base32Hex(), "CPNMU===", "foo"); // proper padding length
- testDecodes(base32Hex(), "CPNMU====", "foo");
- testDecodes(base32Hex(), "CPNMU=====", "foo");
- }
-
- public void testBase32HexInvalidDecodings() {
- // These contain bytes not in the decodabet.
- assertFailsToDecode(base32Hex(), "\u007f");
- assertFailsToDecode(base32Hex(), "Wf2!");
- // This sentence just isn't base32 encoded.
- assertFailsToDecode(base32Hex(), "let's not talk of love or chains!");
- // An 8n+{1,3,6} length string is never legal base32.
- assertFailsToDecode(base32Hex(), "A");
- assertFailsToDecode(base32Hex(), "ABC");
- assertFailsToDecode(base32Hex(), "ABCDEF");
- }
-
- public void testBase32HexUpperCaseIsNoOp() {
- assertSame(base32Hex(), base32Hex().upperCase());
- }
-
- public void testBase16() {
- testEncodingWithCasing(base16(), "", "");
- testEncodingWithCasing(base16(), "f", "66");
- testEncodingWithCasing(base16(), "fo", "666F");
- testEncodingWithCasing(base16(), "foo", "666F6F");
- testEncodingWithCasing(base16(), "foob", "666F6F62");
- testEncodingWithCasing(base16(), "fooba", "666F6F6261");
- testEncodingWithCasing(base16(), "foobar", "666F6F626172");
- }
-
- public void testBase16UpperCaseIsNoOp() {
- assertSame(base16().upperCase(), base16().upperCase());
- }
-
- private void testEncodingWithCasing(BaseEncoding encoding, String decoded, String encoded) {
- testEncodingWithSeparators(encoding, decoded, encoded);
- testEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded));
- testEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded));
- }
-
- private void testEncodingWithSeparators(BaseEncoding encoding, String decoded, String encoded) {
- testEncoding(encoding, decoded, encoded);
-
- // test separators work
- for (int sepLength = 3; sepLength <= 5; sepLength++) {
- for (String separator : ImmutableList.of(",", "\n", ";;", "")) {
- testEncoding(encoding.withSeparator(separator, sepLength), decoded,
- Joiner.on(separator).join(Splitter.fixedLength(sepLength).split(encoded)));
- }
- }
- }
-
- private void testEncoding(BaseEncoding encoding, String decoded, String encoded) {
- testEncodes(encoding, decoded, encoded);
- testDecodes(encoding, encoded, decoded);
- }
-
- private void testEncodes(BaseEncoding encoding, String decoded, String encoded) {
- byte[] bytes;
- try {
- bytes = decoded.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError();
- }
- assertEquals(encoded, encoding.encode(bytes));
- }
-
- private void testDecodes(BaseEncoding encoding, String encoded, String decoded) {
- byte[] bytes;
- try {
- bytes = decoded.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError();
- }
- assertEquals(bytes, encoding.decode(encoded));
- }
-
- private void assertFailsToDecode(BaseEncoding encoding, String cannotDecode) {
- try {
- encoding.decode(cannotDecode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- }
-
- @GwtIncompatible("Reader/Writer")
- private void testStreamingEncodingWithCasing(
- BaseEncoding encoding, String decoded, String encoded) throws IOException {
- testStreamingEncodingWithSeparators(encoding, decoded, encoded);
- testStreamingEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded));
- testStreamingEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded));
- }
-
- @GwtIncompatible("Reader/Writer")
- private void testStreamingEncodingWithSeparators(
- BaseEncoding encoding, String decoded, String encoded) throws IOException {
- testStreamingEncoding(encoding, decoded, encoded);
-
- // test separators work
- for (int sepLength = 3; sepLength <= 5; sepLength++) {
- for (String separator : ImmutableList.of(",", "\n", ";;", "")) {
- testStreamingEncoding(encoding.withSeparator(separator, sepLength), decoded,
- Joiner.on(separator).join(Splitter.fixedLength(sepLength).split(encoded)));
- }
- }
- }
-
- @GwtIncompatible("Reader/Writer")
- private void testStreamingEncoding(BaseEncoding encoding, String decoded, String encoded)
- throws IOException {
- testStreamingEncodes(encoding, decoded, encoded);
- testStreamingDecodes(encoding, encoded, decoded);
- }
-
- @GwtIncompatible("Writer")
- private void testStreamingEncodes(BaseEncoding encoding, String decoded, String encoded)
- throws IOException {
- byte[] bytes;
- try {
- bytes = decoded.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError();
- }
- StringWriter writer = new StringWriter();
- OutputStream encodingStream = encoding.encodingStream(writer);
- encodingStream.write(bytes);
- encodingStream.close();
- assertEquals(encoded, writer.toString());
- }
-
- @GwtIncompatible("Reader")
- private void testStreamingDecodes(BaseEncoding encoding, String encoded, String decoded)
- throws IOException {
- byte[] bytes;
- try {
- bytes = decoded.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError();
- }
- InputStream decodingStream = encoding.decodingStream(new StringReader(encoded));
- for (int i = 0; i < bytes.length; i++) {
- assertEquals(bytes[i] & 0xFF, decodingStream.read());
- }
- assertEquals(-1, decodingStream.read());
- decodingStream.close();
- }
-
- public void testToString() {
- assertEquals("BaseEncoding.base64().withPadChar(=)", BaseEncoding.base64().toString());
- assertEquals("BaseEncoding.base32Hex().omitPadding()",
- BaseEncoding.base32Hex().omitPadding().toString());
- assertEquals("BaseEncoding.base32().lowerCase().withPadChar($)",
- BaseEncoding.base32().lowerCase().withPadChar('$').toString());
- assertEquals("BaseEncoding.base16().withSeparator(\"\n\", 10)",
- BaseEncoding.base16().withSeparator("\n", 10).toString());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/ByteSinkTest.java b/guava-tests/test/com/google/common/io/ByteSinkTest.java
deleted file mode 100644
index adb659c..0000000
--- a/guava-tests/test/com/google/common/io/ByteSinkTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.TestOption.CLOSE_THROWS;
-import static com.google.common.io.TestOption.OPEN_THROWS;
-import static com.google.common.io.TestOption.READ_THROWS;
-import static com.google.common.io.TestOption.WRITE_THROWS;
-import static org.junit.Assert.assertArrayEquals;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.EnumSet;
-
-/**
- * Tests for the default implementations of {@code ByteSink} methods.
- *
- * @author Colin Decker
- */
-public class ByteSinkTest extends IoTestCase {
-
- private final byte[] bytes = newPreFilledByteArray(10000);
-
- private TestByteSink sink;
-
- @Override
- protected void setUp() throws Exception {
- sink = new TestByteSink();
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedOutputStream out = sink.openBufferedStream();
- assertTrue(sink.wasStreamOpened());
- assertFalse(sink.wasStreamClosed());
-
- out.write(new byte[] {1, 2, 3, 4});
- out.close();
-
- assertTrue(sink.wasStreamClosed());
- assertArrayEquals(new byte[] {1, 2, 3, 4}, sink.getBytes());
- }
-
- public void testWrite_bytes() throws IOException {
- assertArrayEquals(new byte[0], sink.getBytes());
- sink.write(bytes);
-
- assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
- assertArrayEquals(bytes, sink.getBytes());
- }
-
- public void testWriteFrom_inputStream() throws IOException {
- ByteArrayInputStream in = new ByteArrayInputStream(bytes);
- sink.writeFrom(in);
-
- assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
- assertArrayEquals(bytes, sink.getBytes());
- }
-
- public void testWriteFromStream_doesNotCloseThatStream() throws IOException {
- TestInputStream in = new TestInputStream(new ByteArrayInputStream(new byte[10]));
- assertFalse(in.closed());
- sink.writeFrom(in);
- assertFalse(in.closed());
- }
-
- public void testClosesOnErrors_copyingFromByteSourceThatThrows() {
- for (TestOption option : EnumSet.of(OPEN_THROWS, READ_THROWS, CLOSE_THROWS)) {
- TestByteSource failSource = new TestByteSource(new byte[10], option);
- TestByteSink okSink = new TestByteSink();
- try {
- failSource.copyTo(okSink);
- fail();
- } catch (IOException expected) {}
- // ensure stream was closed IF it was opened (depends on implementation whether or not it's
- // opened at all if source.newInputStream() throws).
- assertTrue("stream not closed when copying from source with option: " + option,
- !okSink.wasStreamOpened() || okSink.wasStreamClosed());
- }
- }
-
- public void testClosesOnErrors_whenWriteThrows() {
- TestByteSink failSink = new TestByteSink(WRITE_THROWS);
- try {
- new TestByteSource(new byte[10]).copyTo(failSink);
- fail();
- } catch (IOException expected) {
- }
- assertTrue(failSink.wasStreamClosed());
- }
-
- public void testClosesOnErrors_writingFromInputStreamThatThrows() {
- TestByteSink okSink = new TestByteSink();
- try {
- TestInputStream in = new TestInputStream(
- new ByteArrayInputStream(new byte[10]), READ_THROWS);
- okSink.writeFrom(in);
- fail();
- } catch (IOException expected) {
- }
- assertTrue(okSink.wasStreamClosed());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/ByteSinkTester.java b/guava-tests/test/com/google/common/io/ByteSinkTester.java
deleted file mode 100644
index 69b9d94..0000000
--- a/guava-tests/test/com/google/common/io/ByteSinkTester.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.SourceSinkFactory.ByteSinkFactory;
-import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
-import static org.junit.Assert.assertArrayEquals;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableList;
-
-import junit.framework.TestSuite;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-/**
- * A generator of {@code TestSuite} instances for testing {@code ByteSink} implementations.
- * Generates tests of a all methods on a {@code ByteSink} given various inputs written to it as well
- * as sub-suites for testing the {@code CharSink} view in the same way.
- *
- * @author Colin Decker
- */
-public class ByteSinkTester extends SourceSinkTester<ByteSink, byte[], ByteSinkFactory> {
-
- private static final ImmutableList<Method> testMethods
- = getTestMethods(ByteSinkTester.class);
-
- static TestSuite tests(String name, ByteSinkFactory factory) {
- TestSuite suite = new TestSuite(name);
- for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
- String desc = entry.getKey();
- TestSuite stringSuite = suiteForString(name, factory, entry.getValue(), desc);
- suite.addTest(stringSuite);
- }
- return suite;
- }
-
- private static TestSuite suiteForString(String name, ByteSinkFactory factory,
- String string, String desc) {
- byte[] bytes = string.getBytes(Charsets.UTF_8);
- TestSuite suite = suiteForBytes(name, factory, desc, bytes);
- CharSinkFactory charSinkFactory = SourceSinkFactories.asCharSinkFactory(factory);
- suite.addTest(CharSinkTester.suiteForString(name + ".asCharSink[Charset]", charSinkFactory,
- string, desc));
- return suite;
- }
-
- private static TestSuite suiteForBytes(String name, ByteSinkFactory factory,
- String desc, byte[] bytes) {
- TestSuite suite = new TestSuite(name + " [" + desc + "]");
- for (final Method method : testMethods) {
- suite.addTest(new ByteSinkTester(factory, bytes, name, desc, method));
- }
- return suite;
- }
-
- private ByteSink sink;
-
- ByteSinkTester(ByteSinkFactory factory, byte[] data, String suiteName,
- String caseDesc, Method method) {
- super(factory, data, suiteName, caseDesc, method);
- }
-
- @Override
- protected void setUp() throws Exception {
- sink = factory.createSink();
- }
-
- public void testOpenStream() throws IOException {
- OutputStream out = sink.openStream();
- try {
- ByteStreams.copy(new ByteArrayInputStream(data), out);
- } finally {
- out.close();
- }
-
- assertContainsExpectedBytes();
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedOutputStream out = sink.openBufferedStream();
- try {
- ByteStreams.copy(new ByteArrayInputStream(data), out);
- } finally {
- out.close();
- }
-
- assertContainsExpectedBytes();
- }
-
- public void testWrite() throws IOException {
- sink.write(data);
-
- assertContainsExpectedBytes();
- }
-
- public void testWriteFrom_inputStream() throws IOException {
- sink.writeFrom(new ByteArrayInputStream(data));
-
- assertContainsExpectedBytes();
- }
-
- private void assertContainsExpectedBytes() throws IOException {
- assertArrayEquals(expected, factory.getSinkContents());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/ByteSourceTest.java b/guava-tests/test/com/google/common/io/ByteSourceTest.java
deleted file mode 100644
index 73919f1..0000000
--- a/guava-tests/test/com/google/common/io/ByteSourceTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.io.TestOption.CLOSE_THROWS;
-import static com.google.common.io.TestOption.OPEN_THROWS;
-import static com.google.common.io.TestOption.READ_THROWS;
-import static com.google.common.io.TestOption.SKIP_THROWS;
-import static com.google.common.io.TestOption.WRITE_THROWS;
-import static org.junit.Assert.assertArrayEquals;
-
-import com.google.common.base.Charsets;
-import com.google.common.hash.Hashing;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.EnumSet;
-
-/**
- * Tests for the default implementations of {@code ByteSource} methods.
- *
- * @author Colin Decker
- */
-public class ByteSourceTest extends IoTestCase {
-
- private static final byte[] bytes = newPreFilledByteArray(10000);
-
- private TestByteSource source;
-
- @Override
- protected void setUp() throws Exception {
- source = new TestByteSource(bytes);
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedInputStream in = source.openBufferedStream();
- assertTrue(source.wasStreamOpened());
- assertFalse(source.wasStreamClosed());
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ByteStreams.copy(in, out);
- in.close();
- out.close();
-
- assertTrue(source.wasStreamClosed());
- assertArrayEquals(bytes, out.toByteArray());
- }
-
- public void testSize() throws IOException {
- assertEquals(bytes.length, source.size());
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
-
- // test that we can get the size even if skip() isn't supported
- assertEquals(bytes.length, new TestByteSource(bytes, SKIP_THROWS).size());
- }
-
- public void testCopyTo_outputStream() throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- assertEquals(bytes.length, source.copyTo(out));
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
-
- assertArrayEquals(bytes, out.toByteArray());
- }
-
- public void testCopyTo_byteSink() throws IOException {
- TestByteSink sink = new TestByteSink();
-
- assertFalse(sink.wasStreamOpened() || sink.wasStreamClosed());
-
- assertEquals(bytes.length, source.copyTo(sink));
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
- assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
-
- assertArrayEquals(bytes, sink.getBytes());
- }
-
- public void testRead_toArray() throws IOException {
- assertArrayEquals(bytes, source.read());
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
- }
-
- public void testHash() throws IOException {
- ByteSource byteSource = new TestByteSource("hamburger\n".getBytes(Charsets.US_ASCII));
-
- // Pasted this expected string from `echo hamburger | md5sum`
- assertEquals("cfa0c5002275c90508338a5cdb2a9781", byteSource.hash(Hashing.md5()).toString());
- }
-
- public void testContentEquals() throws IOException {
- assertTrue(source.contentEquals(source));
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
-
- ByteSource equalSource = new TestByteSource(bytes);
- assertTrue(source.contentEquals(equalSource));
- assertTrue(new TestByteSource(bytes).contentEquals(source));
-
- ByteSource fewerBytes = new TestByteSource(newPreFilledByteArray(bytes.length / 2));
- assertFalse(source.contentEquals(fewerBytes));
-
- byte[] copy = bytes.clone();
- copy[9876] = 1;
- ByteSource oneByteOff = new TestByteSource(copy);
- assertFalse(source.contentEquals(oneByteOff));
- }
-
- public void testSlice() throws IOException {
- // Test preconditions
- try {
- source.slice(-1, 10);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- source.slice(0, -1);
- fail();
- } catch (IllegalArgumentException expected) {
- }
-
- assertCorrectSlice(0, 0, 0, 0);
- assertCorrectSlice(0, 0, 1, 0);
- assertCorrectSlice(100, 0, 10, 10);
- assertCorrectSlice(100, 0, 100, 100);
- assertCorrectSlice(100, 5, 10, 10);
- assertCorrectSlice(100, 5, 100, 95);
- assertCorrectSlice(100, 100, 0, 0);
- assertCorrectSlice(100, 100, 10, 0);
-
- try {
- assertCorrectSlice(100, 101, 10, 0);
- fail();
- } catch (EOFException expected) {
- }
- }
-
- /**
- * @param input the size of the input source
- * @param offset the first argument to {@link ByteStreams#slice}
- * @param length the second argument to {@link ByteStreams#slice}
- * @param expectRead the number of bytes we expect to read
- */
- private static void assertCorrectSlice(
- int input, int offset, long length, int expectRead) throws IOException {
- checkArgument(expectRead == (int) Math.max(0, Math.min(input, offset + length) - offset));
-
- byte[] expected = newPreFilledByteArray(offset, expectRead);
-
- ByteSource source = new TestByteSource(newPreFilledByteArray(input));
- ByteSource slice = source.slice(offset, length);
-
- assertArrayEquals(expected, slice.read());
- }
-
- public void testCopyToStream_doesNotCloseThatStream() throws IOException {
- TestOutputStream out = new TestOutputStream(ByteStreams.nullOutputStream());
- assertFalse(out.closed());
- source.copyTo(out);
- assertFalse(out.closed());
- }
-
- public void testClosesOnErrors_copyingToByteSinkThatThrows() {
- for (TestOption option : EnumSet.of(OPEN_THROWS, WRITE_THROWS, CLOSE_THROWS)) {
- TestByteSource okSource = new TestByteSource(bytes);
- try {
- okSource.copyTo(new TestByteSink(option));
- fail();
- } catch (IOException expected) {
- }
- // ensure stream was closed IF it was opened (depends on implementation whether or not it's
- // opened at all if sink.newOutputStream() throws).
- assertTrue("stream not closed when copying to sink with option: " + option,
- !okSource.wasStreamOpened() || okSource.wasStreamClosed());
- }
- }
-
- public void testClosesOnErrors_whenReadThrows() {
- TestByteSource failSource = new TestByteSource(bytes, READ_THROWS);
- try {
- failSource.copyTo(new TestByteSink());
- fail();
- } catch (IOException expected) {
- }
- assertTrue(failSource.wasStreamClosed());
- }
-
- public void testClosesOnErrors_copyingToOutputStreamThatThrows() {
- TestByteSource okSource = new TestByteSource(bytes);
- try {
- OutputStream out = new TestOutputStream(ByteStreams.nullOutputStream(), WRITE_THROWS);
- okSource.copyTo(out);
- fail();
- } catch (IOException expected) {
- }
- assertTrue(okSource.wasStreamClosed());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/ByteSourceTester.java b/guava-tests/test/com/google/common/io/ByteSourceTester.java
deleted file mode 100644
index 10cb9a7..0000000
--- a/guava-tests/test/com/google/common/io/ByteSourceTester.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
-import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
-import static org.junit.Assert.assertArrayEquals;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableList;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.Hashing;
-
-import junit.framework.TestSuite;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Random;
-
-/**
- * A generator of {@code TestSuite} instances for testing {@code ByteSource} implementations.
- * Generates tests of a all methods on a {@code ByteSource} given various inputs the source is
- * expected to contain as well as as sub-suites for testing the {@code CharSource} view and
- * {@code slice()} views in the same way.
- *
- * @author Colin Decker
- */
-public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteSourceFactory> {
-
- private static final ImmutableList<Method> testMethods
- = getTestMethods(ByteSourceTester.class);
-
- static TestSuite tests(String name, ByteSourceFactory factory, boolean testAsCharSource) {
- TestSuite suite = new TestSuite(name);
- for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
- if (testAsCharSource) {
- suite.addTest(suiteForString(factory, entry.getValue(), name, entry.getKey()));
- } else {
- suite.addTest(suiteForBytes(
- factory, entry.getValue().getBytes(Charsets.UTF_8), name, entry.getKey(), true));
- }
- }
- return suite;
- }
-
- private static TestSuite suiteForString(ByteSourceFactory factory, String string,
- String name, String desc) {
- TestSuite suite = suiteForBytes(factory, string.getBytes(Charsets.UTF_8), name, desc, true);
- CharSourceFactory charSourceFactory = SourceSinkFactories.asCharSourceFactory(factory);
- suite.addTest(CharSourceTester.suiteForString(charSourceFactory, string,
- name + ".asCharSource[Charset]", desc));
- return suite;
- }
-
- private static TestSuite suiteForBytes(ByteSourceFactory factory, byte[] bytes,
- String name, String desc, boolean slice) {
- TestSuite suite = new TestSuite(name + " [" + desc + "]");
- for (Method method : testMethods) {
- suite.addTest(new ByteSourceTester(factory, bytes, name, desc, method));
- }
-
- if (slice && bytes.length > 0) {
- // test a random slice() of the ByteSource
- Random random = new Random();
- byte[] expected = factory.getExpected(bytes);
- int off = random.nextInt(expected.length);
- int len = random.nextInt(expected.length - off);
- ByteSourceFactory sliced = SourceSinkFactories.asSlicedByteSourceFactory(factory, off, len);
- suite.addTest(suiteForBytes(sliced, bytes, name + ".slice[int, int]",
- desc, false));
- }
-
- return suite;
- }
-
- private ByteSource source;
-
- public ByteSourceTester(ByteSourceFactory factory, byte[] bytes,
- String suiteName, String caseDesc, Method method) {
- super(factory, bytes, suiteName, caseDesc, method);
- }
-
- @Override
- public void setUp() throws IOException {
- source = factory.createSource(data);
- }
-
- public void testOpenStream() throws IOException {
- InputStream in = source.openStream();
- try {
- byte[] readBytes = ByteStreams.toByteArray(in);
- assertExpectedBytes(readBytes);
- } finally {
- in.close();
- }
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedInputStream in = source.openBufferedStream();
- try {
- byte[] readBytes = ByteStreams.toByteArray(in);
- assertExpectedBytes(readBytes);
- } finally {
- in.close();
- }
- }
-
- public void testRead() throws IOException {
- byte[] readBytes = source.read();
- assertExpectedBytes(readBytes);
- }
-
- public void testCopyTo_outputStream() throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- source.copyTo(out);
- assertExpectedBytes(out.toByteArray());
- }
-
- public void testCopyTo_byteSink() throws IOException {
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- // HERESY! but it's ok just for this I guess
- source.copyTo(new ByteSink() {
- @Override
- public OutputStream openStream() throws IOException {
- return out;
- }
- });
- assertExpectedBytes(out.toByteArray());
- }
-
- public void testSize() throws IOException {
- assertEquals(expected.length, source.size());
- }
-
- public void testContentEquals() throws IOException {
- assertTrue(source.contentEquals(new ByteSource() {
- @Override
- public InputStream openStream() throws IOException {
- return new RandomAmountInputStream(
- new ByteArrayInputStream(expected), new Random());
- }
- }));
- }
-
- public void testHash() throws IOException {
- HashCode expectedHash = Hashing.md5().hashBytes(expected);
- assertEquals(expectedHash, source.hash(Hashing.md5()));
- }
-
- public void testSlice_illegalArguments() {
- try {
- source.slice(-1, 0);
- fail("expected IllegalArgumentException for call to slice with offset -1: " + source);
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- source.slice(0, -1);
- fail("expected IllegalArgumentException for call to slice with length -1: " + source);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- private void assertExpectedBytes(byte[] readBytes) {
- assertArrayEquals(expected, readBytes);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/ByteStreamsTest.java b/guava-tests/test/com/google/common/io/ByteStreamsTest.java
index 40349f6..ff0497a 100644
--- a/guava-tests/test/com/google/common/io/ByteStreamsTest.java
+++ b/guava-tests/test/com/google/common/io/ByteStreamsTest.java
@@ -22,11 +22,9 @@ import static com.google.common.io.ByteStreams.newInputStreamSupplier;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
-import com.google.common.hash.Hashing;
+import com.google.common.primitives.Bytes;
import com.google.common.testing.TestLogHandler;
-import junit.framework.TestSuite;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
@@ -40,8 +38,6 @@ import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.Random;
-import java.util.zip.CRC32;
-import java.util.zip.Checksum;
/**
* Unit test for {@link ByteStreams}.
@@ -50,14 +46,6 @@ import java.util.zip.Checksum;
*/
public class ByteStreamsTest extends IoTestCase {
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(ByteSourceTester.tests("ByteStreams.asByteSource[byte[]]",
- SourceSinkFactories.byteArraySourceFactory(), true));
- suite.addTestSuite(ByteStreamsTest.class);
- return suite;
- }
-
/** Provides an InputStream that throws an IOException on every read. */
static final InputSupplier<InputStream> BROKEN_READ
= new InputSupplier<InputStream>() {
@@ -135,8 +123,8 @@ public class ByteStreamsTest extends IoTestCase {
public void testByteSuppliers() throws IOException {
byte[] range = newPreFilledByteArray(200);
- assertEquals(range,
- ByteStreams.toByteArray(ByteStreams.newInputStreamSupplier(range)));
+ assertTrue(Arrays.equals(range,
+ ByteStreams.toByteArray(ByteStreams.newInputStreamSupplier(range))));
byte[] subRange = ByteStreams.toByteArray(
ByteStreams.newInputStreamSupplier(range, 100, 50));
@@ -171,13 +159,13 @@ public class ByteStreamsTest extends IoTestCase {
}));
}
- private static void equalHelper(boolean expect, int size1, int size2)
+ private void equalHelper(boolean expect, int size1, int size2)
throws IOException {
equalHelper(expect, newPreFilledByteArray(size1),
newPreFilledByteArray(size2));
}
- private static void equalHelper(boolean expect, byte[] a, byte[] b)
+ private void equalHelper(boolean expect, byte[] a, byte[] b)
throws IOException {
assertEquals(expect, ByteStreams.equal(
ByteStreams.newInputStreamSupplier(a),
@@ -314,7 +302,7 @@ public class ByteStreamsTest extends IoTestCase {
in.close();
// toByteArray
- assertEquals(range, ByteStreams.toByteArray(okRead));
+ assertTrue(Arrays.equals(range, ByteStreams.toByteArray(okRead)));
assertTrue(okRead.areClosed());
try {
@@ -352,66 +340,6 @@ public class ByteStreamsTest extends IoTestCase {
assertTrue(brokenWrite.areClosed());
}
- public void testCopySuppliersExceptions() {
- if (!Closer.SuppressingSuppressor.isAvailable()) {
- // test that exceptions are logged
-
- TestLogHandler logHandler = new TestLogHandler();
- Closeables.logger.addHandler(logHandler);
- try {
- for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
- runFailureTest(in, newByteArrayOutputStreamSupplier());
- assertTrue(logHandler.getStoredLogRecords().isEmpty());
-
- runFailureTest(in, BROKEN_CLOSE_OUTPUT);
- assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, getAndResetRecords(logHandler));
- }
-
- for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
- runFailureTest(newInputStreamSupplier(new byte[10]), out);
- assertTrue(logHandler.getStoredLogRecords().isEmpty());
-
- runFailureTest(BROKEN_CLOSE_INPUT, out);
- assertEquals(1, getAndResetRecords(logHandler));
- }
-
- for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
- for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
- runFailureTest(in, out);
- assertTrue(getAndResetRecords(logHandler) <= 1);
- }
- }
- } finally {
- Closeables.logger.removeHandler(logHandler);
- }
- } else {
- // test that exceptions are suppressed
-
- for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
- int suppressed = runSuppressionFailureTest(in, newByteArrayOutputStreamSupplier());
- assertEquals(0, suppressed);
-
- suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_OUTPUT);
- assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, suppressed);
- }
-
- for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
- int suppressed = runSuppressionFailureTest(newInputStreamSupplier(new byte[10]), out);
- assertEquals(0, suppressed);
-
- suppressed = runSuppressionFailureTest(BROKEN_CLOSE_INPUT, out);
- assertEquals(1, suppressed);
- }
-
- for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
- for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
- int suppressed = runSuppressionFailureTest(in, out);
- assertTrue(suppressed <= 1);
- }
- }
- }
- }
-
private static int getAndResetRecords(TestLogHandler logHandler) {
int records = logHandler.getStoredLogRecords().size();
logHandler.clear();
@@ -427,20 +355,6 @@ public class ByteStreamsTest extends IoTestCase {
}
}
- /**
- * @return the number of exceptions that were suppressed on the expected thrown exception
- */
- private static int runSuppressionFailureTest(
- InputSupplier<? extends InputStream> in, OutputSupplier<OutputStream> out) {
- try {
- copy(in, out);
- fail();
- } catch (IOException expected) {
- return CloserTest.getSuppressed(expected).length;
- }
- throw new AssertionError(); // can't happen
- }
-
private static OutputSupplier<OutputStream> newByteArrayOutputStreamSupplier() {
return new OutputSupplier<OutputStream>() {
@Override public OutputStream getOutput() {
@@ -457,7 +371,7 @@ public class ByteStreamsTest extends IoTestCase {
return out;
}
});
- assertEquals(expected, out.toByteArray());
+ assertTrue(Arrays.equals(expected, out.toByteArray()));
}
public void testCopy() throws Exception {
@@ -465,7 +379,7 @@ public class ByteStreamsTest extends IoTestCase {
byte[] expected = newPreFilledByteArray(100);
long num = ByteStreams.copy(new ByteArrayInputStream(expected), out);
assertEquals(100, num);
- assertEquals(expected, out.toByteArray());
+ assertTrue(Arrays.equals(expected, out.toByteArray()));
}
public void testCopyChannel() throws IOException {
@@ -476,7 +390,7 @@ public class ByteStreamsTest extends IoTestCase {
ReadableByteChannel inChannel =
Channels.newChannel(new ByteArrayInputStream(expected));
ByteStreams.copy(inChannel, outChannel);
- assertEquals(expected, out.toByteArray());
+ assertTrue(Arrays.equals(expected, out.toByteArray()));
}
public void testReadFully() throws IOException {
@@ -526,15 +440,15 @@ public class ByteStreamsTest extends IoTestCase {
Arrays.fill(b, (byte) 0);
ByteStreams.readFully(newTestStream(10), b, 0, 0);
- assertEquals(new byte[10], b);
+ assertTrue(Arrays.equals(new byte[10], b));
Arrays.fill(b, (byte) 0);
ByteStreams.readFully(newTestStream(10), b, 0, 10);
- assertEquals(newPreFilledByteArray(10), b);
+ assertTrue(Arrays.equals(newPreFilledByteArray(10), b));
Arrays.fill(b, (byte) 0);
ByteStreams.readFully(newTestStream(10), b, 0, 5);
- assertEquals(new byte[]{0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b);
+ assertTrue(Arrays.equals(new byte[]{0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b));
}
public void testSkipFully() throws IOException {
@@ -551,15 +465,16 @@ public class ByteStreamsTest extends IoTestCase {
}
}
- private static void skipHelper(long n, int expect, InputStream in)
+ private void skipHelper(long n, int expect, InputStream in)
throws IOException {
ByteStreams.skipFully(in, n);
assertEquals(expect, in.read());
in.close();
}
- private static final byte[] bytes =
- new byte[] { 0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10 };
+ // TODO(user): rename; violates rule that only immutable things can be all caps
+ private static final byte[] BYTES = new byte[] {
+ 0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10 };
public void testNewDataInput_empty() {
byte[] b = new byte[0];
@@ -572,7 +487,7 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_normal() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
assertEquals(0x12345678, in.readInt());
assertEquals(0x76543210, in.readInt());
try {
@@ -583,15 +498,15 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_readFully() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
- byte[] actual = new byte[bytes.length];
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ byte[] actual = new byte[BYTES.length];
in.readFully(actual);
- assertEquals(bytes, actual);
+ assertEquals(BYTES, actual);
}
-
+
public void testNewDataInput_readFullyAndThenSome() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
- byte[] actual = new byte[bytes.length * 2];
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ byte[] actual = new byte[BYTES.length * 2];
try {
in.readFully(actual);
fail();
@@ -599,17 +514,17 @@ public class ByteStreamsTest extends IoTestCase {
assertTrue(ex.getCause() instanceof EOFException);
}
}
-
+
public void testNewDataInput_readFullyWithOffset() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
byte[] actual = new byte[4];
in.readFully(actual, 2, 2);
assertEquals(0, actual[0]);
assertEquals(0, actual[1]);
- assertEquals(bytes[0], actual[2]);
- assertEquals(bytes[1], actual[3]);
+ assertEquals(BYTES[0], actual[2]);
+ assertEquals(BYTES[1], actual[3]);
}
-
+
public void testNewDataInput_readLine() {
ByteArrayDataInput in = ByteStreams.newDataInput(
"This is a line\r\nThis too\rand this\nand also this".getBytes(Charsets.UTF_8));
@@ -625,7 +540,7 @@ public class ByteStreamsTest extends IoTestCase {
assertEquals(Float.intBitsToFloat(0x12345678), in.readFloat(), 0.0);
assertEquals(Float.intBitsToFloat(0x76543210), in.readFloat(), 0.0);
}
-
+
public void testNewDataInput_readDouble() {
byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
ByteArrayDataInput in = ByteStreams.newDataInput(data);
@@ -647,7 +562,7 @@ public class ByteStreamsTest extends IoTestCase {
assertEquals('e', in.readChar());
assertEquals('d', in.readChar());
}
-
+
public void testNewDataInput_readUnsignedShort() {
byte[] data = {0, 0, 0, 1, (byte) 0xFF, (byte) 0xFF, 0x12, 0x34};
ByteArrayDataInput in = ByteStreams.newDataInput(data);
@@ -656,7 +571,7 @@ public class ByteStreamsTest extends IoTestCase {
assertEquals(65535, in.readUnsignedShort());
assertEquals(0x1234, in.readUnsignedShort());
}
-
+
public void testNewDataInput_readLong() {
byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
ByteArrayDataInput in = ByteStreams.newDataInput(data);
@@ -664,14 +579,14 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_readBoolean() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
assertTrue(in.readBoolean());
}
-
+
public void testNewDataInput_readByte() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
- for (int i = 0; i < bytes.length; i++) {
- assertEquals(bytes[i], in.readByte());
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ for (int i = 0; i < BYTES.length; i++) {
+ assertEquals(BYTES[i], in.readByte());
}
try {
in.readByte();
@@ -680,11 +595,11 @@ public class ByteStreamsTest extends IoTestCase {
assertTrue(ex.getCause() instanceof EOFException);
}
}
-
+
public void testNewDataInput_readUnsignedByte() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
- for (int i = 0; i < bytes.length; i++) {
- assertEquals(bytes[i], in.readUnsignedByte());
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ for (int i = 0; i < BYTES.length; i++) {
+ assertEquals(BYTES[i], in.readUnsignedByte());
}
try {
in.readUnsignedByte();
@@ -695,7 +610,7 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_offset() {
- ByteArrayDataInput in = ByteStreams.newDataInput(bytes, 2);
+ ByteArrayDataInput in = ByteStreams.newDataInput(BYTES, 2);
assertEquals(0x56787654, in.readInt());
try {
in.readInt();
@@ -722,39 +637,39 @@ public class ByteStreamsTest extends IoTestCase {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeInt(0x12345678);
out.writeInt(0x76543210);
- assertEquals(bytes, out.toByteArray());
+ assertTrue(Arrays.equals(BYTES, out.toByteArray()));
}
public void testNewDataOutput_sized() {
ByteArrayDataOutput out = ByteStreams.newDataOutput(4);
out.writeInt(0x12345678);
out.writeInt(0x76543210);
- assertEquals(bytes, out.toByteArray());
+ assertTrue(Arrays.equals(BYTES, out.toByteArray()));
}
public void testNewDataOutput_writeLong() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeLong(0x1234567876543210L);
- assertEquals(bytes, out.toByteArray());
+ assertTrue(Arrays.equals(BYTES, out.toByteArray()));
}
public void testNewDataOutput_writeByteArray() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
- out.write(bytes);
- assertEquals(bytes, out.toByteArray());
+ out.write(BYTES);
+ assertTrue(Arrays.equals(BYTES, out.toByteArray()));
}
public void testNewDataOutput_writeByte() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.write(0x12);
out.writeByte(0x34);
- assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
+ assertTrue(Arrays.equals(new byte[] {0x12, 0x34}, out.toByteArray()));
}
public void testNewDataOutput_writeByteOffset() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
- out.write(bytes, 4, 2);
- byte[] expected = {bytes[4], bytes[5]};
+ out.write(BYTES, 4, 2);
+ byte[] expected = {BYTES[4], BYTES[5]};
assertEquals(expected, out.toByteArray());
}
@@ -769,7 +684,7 @@ public class ByteStreamsTest extends IoTestCase {
public void testNewDataOutput_writeChar() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeChar('a');
- assertEquals(new byte[] {0, 97}, out.toByteArray());
+ assertTrue(Arrays.equals(new byte[] {0, 97}, out.toByteArray()));
}
public void testNewDataOutput_writeChars() {
@@ -794,51 +709,20 @@ public class ByteStreamsTest extends IoTestCase {
public void testNewDataOutput_writeShort() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeShort(0x1234);
- assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
+ assertTrue(Arrays.equals(new byte[] {0x12, 0x34}, out.toByteArray()));
}
public void testNewDataOutput_writeDouble() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeDouble(Double.longBitsToDouble(0x1234567876543210L));
- assertEquals(bytes, out.toByteArray());
+ assertEquals(BYTES, out.toByteArray());
}
-
+
public void testNewDataOutput_writeFloat() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeFloat(Float.intBitsToFloat(0x12345678));
out.writeFloat(Float.intBitsToFloat(0x76543210));
- assertEquals(bytes, out.toByteArray());
- }
-
- public void testChecksum() throws IOException {
- InputSupplier<ByteArrayInputStream> asciiBytes =
- ByteStreams.newInputStreamSupplier(ASCII.getBytes(Charsets.US_ASCII));
- InputSupplier<ByteArrayInputStream> i18nBytes =
- ByteStreams.newInputStreamSupplier(I18N.getBytes(Charsets.UTF_8));
-
- Checksum checksum = new CRC32();
- assertEquals(0L, checksum.getValue());
- assertEquals(3145994718L, ByteStreams.getChecksum(asciiBytes, checksum));
- assertEquals(0L, checksum.getValue());
- assertEquals(3145994718L, ByteStreams.getChecksum(asciiBytes, checksum));
- assertEquals(1138302340L, ByteStreams.getChecksum(i18nBytes, checksum));
- assertEquals(0L, checksum.getValue());
- }
-
- public void testHash() throws IOException {
- InputSupplier<ByteArrayInputStream> asciiBytes =
- ByteStreams.newInputStreamSupplier(ASCII.getBytes(Charsets.US_ASCII));
- InputSupplier<ByteArrayInputStream> i18nBytes =
- ByteStreams.newInputStreamSupplier(I18N.getBytes(Charsets.UTF_8));
-
- String init = "d41d8cd98f00b204e9800998ecf8427e";
- assertEquals(init, Hashing.md5().newHasher().hash().toString());
-
- String asciiHash = "e5df5a39f2b8cb71b24e1d8038f93131";
- assertEquals(asciiHash, ByteStreams.hash(asciiBytes, Hashing.md5()).toString());
-
- String i18nHash = "7fa826962ce2079c8334cd4ebf33aea4";
- assertEquals(i18nHash, ByteStreams.hash(i18nBytes, Hashing.md5()).toString());
+ assertEquals(BYTES, out.toByteArray());
}
public void testLength() throws IOException {
@@ -851,7 +735,7 @@ public class ByteStreamsTest extends IoTestCase {
ByteStreams.newInputStreamSupplier(new byte[0])));
}
- private static void lengthHelper(final long skipLimit) throws IOException {
+ private void lengthHelper(final long skipLimit) throws IOException {
assertEquals(100, ByteStreams.length(new InputSupplier<InputStream>() {
@Override
public InputStream getInput() {
@@ -911,9 +795,9 @@ public class ByteStreamsTest extends IoTestCase {
Math.max(0, Math.min(input, offset + length) - offset));
InputSupplier<? extends InputStream> supplier
= ByteStreams.newInputStreamSupplier(newPreFilledByteArray(input));
- assertEquals(
+ assertTrue(Arrays.equals(
newPreFilledByteArray(offset, expectRead),
- ByteStreams.toByteArray(ByteStreams.slice(supplier, offset, length)));
+ ByteStreams.toByteArray(ByteStreams.slice(supplier, offset, length))));
}
private static InputStream newTestStream(int n) {
@@ -964,35 +848,6 @@ public class ByteStreamsTest extends IoTestCase {
}
}
- public void testReadBytes() throws IOException {
- final byte[] array = newPreFilledByteArray(1000);
- assertEquals(array, ByteStreams.readBytes(
- new ByteArrayInputStream(array), new TestByteProcessor()));
- assertEquals(array, ByteStreams.readBytes(
- new InputSupplier<InputStream>() {
- @Override
- public InputStream getInput() {
- return new ByteArrayInputStream(array);
- }
- }, new TestByteProcessor()));
- }
-
- private class TestByteProcessor implements ByteProcessor<byte[]> {
- private final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- @Override
- public boolean processBytes(byte[] buf, int off, int len)
- throws IOException {
- out.write(buf, off, len);
- return true;
- }
-
- @Override
- public byte[] getResult() {
- return out.toByteArray();
- }
- }
-
public void testByteProcessorStopEarly() throws IOException {
byte[] array = newPreFilledByteArray(6000);
assertEquals((Integer) 42,
@@ -1000,9 +855,9 @@ public class ByteStreamsTest extends IoTestCase {
new ByteProcessor<Integer>() {
@Override
public boolean processBytes(byte[] buf, int off, int len) {
- assertEquals(
+ assertTrue(Arrays.equals(
copyOfRange(buf, off, off + len),
- newPreFilledByteArray(4096));
+ newPreFilledByteArray(4096)));
return false;
}
@@ -1013,123 +868,6 @@ public class ByteStreamsTest extends IoTestCase {
}));
}
- public void testNullOutputStream() throws Exception {
- // create a null output stream
- OutputStream nos = ByteStreams.nullOutputStream();
- // write to the output stream
- nos.write('n');
- String test = "Test string for NullOutputStream";
- nos.write(test.getBytes());
- nos.write(test.getBytes(), 2, 10);
- // nothing really to assert?
- assertSame(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream());
- }
-
- public void testLimit() throws Exception {
- byte[] big = newPreFilledByteArray(5);
- InputStream bin = new ByteArrayInputStream(big);
- InputStream lin = ByteStreams.limit(bin, 2);
-
- // also test available
- lin.mark(2);
- assertEquals(2, lin.available());
- int read = lin.read();
- assertEquals(big[0], read);
- assertEquals(1, lin.available());
- read = lin.read();
- assertEquals(big[1], read);
- assertEquals(0, lin.available());
- read = lin.read();
- assertEquals(-1, read);
-
- lin.reset();
- byte[] small = new byte[5];
- read = lin.read(small);
- assertEquals(2, read);
- assertEquals(big[0], small[0]);
- assertEquals(big[1], small[1]);
-
- lin.reset();
- read = lin.read(small, 2, 3);
- assertEquals(2, read);
- assertEquals(big[0], small[2]);
- assertEquals(big[1], small[3]);
- }
-
- public void testLimit_mark() throws Exception {
- byte[] big = newPreFilledByteArray(5);
- InputStream bin = new ByteArrayInputStream(big);
- InputStream lin = ByteStreams.limit(bin, 2);
-
- int read = lin.read();
- assertEquals(big[0], read);
- lin.mark(2);
-
- read = lin.read();
- assertEquals(big[1], read);
- read = lin.read();
- assertEquals(-1, read);
-
- lin.reset();
- read = lin.read();
- assertEquals(big[1], read);
- read = lin.read();
- assertEquals(-1, read);
- }
-
- public void testLimit_skip() throws Exception {
- byte[] big = newPreFilledByteArray(5);
- InputStream bin = new ByteArrayInputStream(big);
- InputStream lin = ByteStreams.limit(bin, 2);
-
- // also test available
- lin.mark(2);
- assertEquals(2, lin.available());
- lin.skip(1);
- assertEquals(1, lin.available());
-
- lin.reset();
- assertEquals(2, lin.available());
- lin.skip(3);
- assertEquals(0, lin.available());
- }
-
- public void testLimit_markNotSet() {
- byte[] big = newPreFilledByteArray(5);
- InputStream bin = new ByteArrayInputStream(big);
- InputStream lin = ByteStreams.limit(bin, 2);
-
- try {
- lin.reset();
- fail();
- } catch (IOException expected) {
- assertEquals("Mark not set", expected.getMessage());
- }
- }
-
- public void testLimit_markNotSupported() {
- InputStream lin = ByteStreams.limit(new UnmarkableInputStream(), 2);
-
- try {
- lin.reset();
- fail();
- } catch (IOException expected) {
- assertEquals("Mark not supported", expected.getMessage());
- }
- }
-
- private static class UnmarkableInputStream extends InputStream {
- @Override
- public int read() throws IOException {
- return 0;
- }
-
- @Override
- public boolean markSupported() {
- return false;
- }
- }
-
private static byte[] copyOfRange(byte[] in, int from, int to) {
byte[] out = new byte[to - from];
for (int i = 0; i < to - from; i++) {
@@ -1139,6 +877,6 @@ public class ByteStreamsTest extends IoTestCase {
}
private static void assertEquals(byte[] expected, byte[] actual) {
- assertTrue(Arrays.equals(expected, actual));
+ assertEquals(Bytes.asList(expected), Bytes.asList(actual));
}
}
diff --git a/guava-tests/test/com/google/common/io/CharSinkTest.java b/guava-tests/test/com/google/common/io/CharSinkTest.java
deleted file mode 100644
index 9fd88d3..0000000
--- a/guava-tests/test/com/google/common/io/CharSinkTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.TestOption.CLOSE_THROWS;
-import static com.google.common.io.TestOption.OPEN_THROWS;
-import static com.google.common.io.TestOption.READ_THROWS;
-import static com.google.common.io.TestOption.WRITE_THROWS;
-
-import com.google.common.collect.ImmutableList;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.EnumSet;
-
-/**
- * Tests for the default implementations of {@code CharSink} methods.
- *
- * @author Colin Decker
- */
-public class CharSinkTest extends IoTestCase {
-
- private static final String STRING = ASCII + I18N;
-
- private TestCharSink sink;
-
- @Override
- public void setUp() {
- sink = new TestCharSink();
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedWriter writer = sink.openBufferedStream();
- assertTrue(sink.wasStreamOpened());
- assertFalse(sink.wasStreamClosed());
-
- writer.write(STRING);
- writer.close();
-
- assertTrue(sink.wasStreamClosed());
- assertEquals(STRING, sink.getString());
- }
-
- public void testWrite_string() throws IOException {
- assertEquals("", sink.getString());
- sink.write(STRING);
-
- assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
- assertEquals(STRING, sink.getString());
- }
-
- public void testWriteFrom_reader() throws IOException {
- StringReader reader = new StringReader(STRING);
- sink.writeFrom(reader);
-
- assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
- assertEquals(STRING, sink.getString());
- }
-
- public void testWriteFromStream_doesNotCloseThatStream() throws IOException {
- TestReader in = new TestReader();
- assertFalse(in.closed());
- sink.writeFrom(in);
- assertFalse(in.closed());
- }
-
- public void testWriteLines_withSpecificSeparator() throws IOException {
- sink.writeLines(ImmutableList.of("foo", "bar", "baz"), "\n");
- assertEquals("foo\nbar\nbaz\n", sink.getString());
- }
-
- public void testWriteLines_withDefaultSeparator() throws IOException {
- sink.writeLines(ImmutableList.of("foo", "bar", "baz"));
- String separator = System.getProperty("line.separator");
- assertEquals("foo" + separator + "bar" + separator + "baz" + separator, sink.getString());
- }
-
- public void testClosesOnErrors_copyingFromCharSourceThatThrows() {
- for (TestOption option : EnumSet.of(OPEN_THROWS, READ_THROWS, CLOSE_THROWS)) {
- TestCharSource failSource = new TestCharSource(STRING, option);
- TestCharSink okSink = new TestCharSink();
- try {
- failSource.copyTo(okSink);
- fail();
- } catch (IOException expected) {
- }
- // ensure writer was closed IF it was opened (depends on implementation whether or not it's
- // opened at all if source.newReader() throws).
- assertTrue("stream not closed when copying from source with option: " + option,
- !okSink.wasStreamOpened() || okSink.wasStreamClosed());
- }
- }
-
- public void testClosesOnErrors_whenWriteThrows() {
- TestCharSink failSink = new TestCharSink(WRITE_THROWS);
- try {
- new TestCharSource(STRING).copyTo(failSink);
- fail();
- } catch (IOException expected) {
- }
- assertTrue(failSink.wasStreamClosed());
- }
-
- public void testClosesOnErrors_whenWritingFromReaderThatThrows() {
- TestCharSink okSink = new TestCharSink();
- try {
- okSink.writeFrom(new TestReader(READ_THROWS));
- fail();
- } catch (IOException expected) {
- }
- assertTrue(okSink.wasStreamClosed());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/CharSinkTester.java b/guava-tests/test/com/google/common/io/CharSinkTester.java
deleted file mode 100644
index 08d7e2c..0000000
--- a/guava-tests/test/com/google/common/io/CharSinkTester.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-
-import junit.framework.TestSuite;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-/**
- * A generator of {@code TestSuite} instances for testing {@code CharSink} implementations.
- * Generates tests of a all methods on a {@code CharSink} given various inputs written to it.
- *
- * @author Colin Decker
- */
-public class CharSinkTester extends SourceSinkTester<CharSink, String, CharSinkFactory> {
-
- private static final ImmutableList<Method> testMethods
- = getTestMethods(CharSinkTester.class);
-
- static TestSuite tests(String name, CharSinkFactory factory) {
- TestSuite suite = new TestSuite(name);
- for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
- String desc = entry.getKey();
- TestSuite stringSuite = suiteForString(name, factory, entry.getValue(), desc);
- suite.addTest(stringSuite);
- }
- return suite;
- }
-
- static TestSuite suiteForString(String name, CharSinkFactory factory,
- String string, String desc) {
- TestSuite stringSuite = new TestSuite(name + " [" + desc + "]");
- for (final Method method : testMethods) {
- stringSuite.addTest(new CharSinkTester(factory, string, name, desc, method));
- }
- return stringSuite;
- }
-
- private final ImmutableList<String> lines;
- private final ImmutableList<String> expectedLines;
-
- private CharSink sink;
-
- public CharSinkTester(CharSinkFactory factory, String string,
- String suiteName, String caseDesc, Method method) {
- super(factory, string, suiteName, caseDesc, method);
- this.lines = getLines(string);
- this.expectedLines = getLines(expected);
- }
-
- @Override
- protected void setUp() throws Exception {
- this.sink = factory.createSink();
- }
-
- public void testOpenStream() throws IOException {
- Writer writer = sink.openStream();
- try {
- writer.write(data);
- } finally {
- writer.close();
- }
-
- assertContainsExpectedString();
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedWriter writer = sink.openBufferedStream();
- try {
- writer.write(data);
- } finally {
- writer.close();
- }
-
- assertContainsExpectedString();
- }
-
- public void testWrite() throws IOException {
- sink.write(data);
-
- assertContainsExpectedString();
- }
-
- public void testWriteLines_systemDefaultSeparator() throws IOException {
- String separator = System.getProperty("line.separator");
- sink.writeLines(lines);
-
- assertContainsExpectedLines(separator);
- }
-
- public void testWriteLines_specificSeparator() throws IOException {
- String separator = "\r\n";
- sink.writeLines(lines, separator);
-
- assertContainsExpectedLines(separator);
- }
-
- private void assertContainsExpectedString() throws IOException {
- assertEquals(expected, factory.getSinkContents());
- }
-
- private void assertContainsExpectedLines(String separator) throws IOException {
- String expected = expectedLines.isEmpty()
- ? ""
- : Joiner.on(separator).join(expectedLines);
- if (!lines.isEmpty()) {
- // if we wrote any lines in writeLines(), there will be a trailing newline
- expected += separator;
- }
- assertEquals(expected, factory.getSinkContents());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/CharSourceTest.java b/guava-tests/test/com/google/common/io/CharSourceTest.java
deleted file mode 100644
index 6474d5a..0000000
--- a/guava-tests/test/com/google/common/io/CharSourceTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.TestOption.CLOSE_THROWS;
-import static com.google.common.io.TestOption.OPEN_THROWS;
-import static com.google.common.io.TestOption.READ_THROWS;
-import static com.google.common.io.TestOption.WRITE_THROWS;
-
-import com.google.common.collect.ImmutableList;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.EnumSet;
-
-/**
- * Tests for the default implementations of {@code CharSource} methods.
- *
- * @author Colin Decker
- */
-public class CharSourceTest extends IoTestCase {
-
- private static final String STRING = ASCII + I18N;
- private static final String LINES = "foo\nbar\r\nbaz\rsomething";
-
- private TestCharSource source;
-
- @Override
- public void setUp() {
- source = new TestCharSource(STRING);
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedReader reader = source.openBufferedStream();
- assertTrue(source.wasStreamOpened());
- assertFalse(source.wasStreamClosed());
-
- StringWriter writer = new StringWriter();
- char[] buf = new char[64];
- int read;
- while ((read = reader.read(buf)) != -1) {
- writer.write(buf, 0, read);
- }
- reader.close();
- writer.close();
-
- assertTrue(source.wasStreamClosed());
- assertEquals(STRING, writer.toString());
- }
-
- public void testCopyTo_appendable() throws IOException {
- StringBuilder builder = new StringBuilder();
-
- assertEquals(STRING.length(), source.copyTo(builder));
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
-
- assertEquals(STRING, builder.toString());
- }
-
- public void testCopyTo_charSink() throws IOException {
- TestCharSink sink = new TestCharSink();
-
- assertFalse(sink.wasStreamOpened() || sink.wasStreamClosed());
-
- assertEquals(STRING.length(), source.copyTo(sink));
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
- assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
-
- assertEquals(STRING, sink.getString());
- }
-
- public void testRead_toString() throws IOException {
- assertEquals(STRING, source.read());
- assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
- }
-
- public void testReadFirstLine() throws IOException {
- TestCharSource lines = new TestCharSource(LINES);
- assertEquals("foo", lines.readFirstLine());
- assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed());
- }
-
- public void testReadLines_toList() throws IOException {
- TestCharSource lines = new TestCharSource(LINES);
- assertEquals(ImmutableList.of("foo", "bar", "baz", "something"), lines.readLines());
- assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed());
- }
-
- public void testCopyToAppendable_doesNotCloseIfWriter() throws IOException {
- TestWriter writer = new TestWriter();
- assertFalse(writer.closed());
- source.copyTo(writer);
- assertFalse(writer.closed());
- }
-
- public void testClosesOnErrors_copyingToCharSinkThatThrows() {
- for (TestOption option : EnumSet.of(OPEN_THROWS, WRITE_THROWS, CLOSE_THROWS)) {
- TestCharSource okSource = new TestCharSource(STRING);
- try {
- okSource.copyTo(new TestCharSink(option));
- fail();
- } catch (IOException expected) {
- }
- // ensure reader was closed IF it was opened (depends on implementation whether or not it's
- // opened at all if sink.newWriter() throws).
- assertTrue("stream not closed when copying to sink with option: " + option,
- !okSource.wasStreamOpened() || okSource.wasStreamClosed());
- }
- }
-
- public void testClosesOnErrors_whenReadThrows() {
- TestCharSource failSource = new TestCharSource(STRING, READ_THROWS);
- try {
- failSource.copyTo(new TestCharSink());
- fail();
- } catch (IOException expected) {
- }
- assertTrue(failSource.wasStreamClosed());
- }
-
- public void testClosesOnErrors_copyingToWriterThatThrows() {
- TestCharSource okSource = new TestCharSource(STRING);
- try {
- okSource.copyTo(new TestWriter(WRITE_THROWS));
- fail();
- } catch (IOException expected) {
- }
- assertTrue(okSource.wasStreamClosed());
- }
-}
diff --git a/guava-tests/test/com/google/common/io/CharSourceTester.java b/guava-tests/test/com/google/common/io/CharSourceTester.java
deleted file mode 100644
index b0d6eed..0000000
--- a/guava-tests/test/com/google/common/io/CharSourceTester.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import junit.framework.TestSuite;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A generator of {@code TestSuite} instances for testing {@code CharSource} implementations.
- * Generates tests of a all methods on a {@code CharSource} given various inputs the source is
- * expected to contain.
- *
- * @author Colin Decker
- */
-public class CharSourceTester extends SourceSinkTester<CharSource, String, CharSourceFactory> {
-
- private static final ImmutableList<Method> testMethods
- = getTestMethods(CharSourceTester.class);
-
- static TestSuite tests(String name, CharSourceFactory factory) {
- TestSuite suite = new TestSuite(name);
- for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
- suite.addTest(suiteForString(factory, entry.getValue(), name, entry.getKey()));
- }
- return suite;
- }
-
- static TestSuite suiteForString(CharSourceFactory factory, String string,
- String name, String desc) {
- TestSuite suite = new TestSuite(name + " [" + desc + "]");
- for (Method method : testMethods) {
- suite.addTest(new CharSourceTester(factory, string, name, desc, method));
- }
- return suite;
- }
-
- private final ImmutableList<String> expectedLines;
-
- private CharSource source;
-
- public CharSourceTester(CharSourceFactory factory, String string,
- String suiteName, String caseDesc, Method method) {
- super(factory, string, suiteName, caseDesc, method);
- this.expectedLines = getLines(expected);
- }
-
- @Override
- protected void setUp() throws Exception {
- this.source = factory.createSource(data);
- }
-
- public void testOpenStream() throws IOException {
- Reader reader = source.openStream();
-
- StringWriter writer = new StringWriter();
- char[] buf = new char[64];
- int read;
- while ((read = reader.read(buf)) != -1) {
- writer.write(buf, 0, read);
- }
- reader.close();
- writer.close();
-
- assertExpectedString(writer.toString());
- }
-
- public void testOpenBufferedStream() throws IOException {
- BufferedReader reader = source.openBufferedStream();
-
- StringWriter writer = new StringWriter();
- char[] buf = new char[64];
- int read;
- while ((read = reader.read(buf)) != -1) {
- writer.write(buf, 0, read);
- }
- reader.close();
- writer.close();
-
- assertExpectedString(writer.toString());
- }
-
- public void testCopyTo_appendable() throws IOException {
- StringBuilder builder = new StringBuilder();
-
- assertEquals(expected.length(), source.copyTo(builder));
-
- assertExpectedString(builder.toString());
- }
-
- public void testCopyTo_charSink() throws IOException {
- TestCharSink sink = new TestCharSink();
-
- assertEquals(expected.length(), source.copyTo(sink));
-
- assertExpectedString(sink.getString());
- }
-
- public void testRead_toString() throws IOException {
- String string = source.read();
- assertExpectedString(string);
- }
-
- public void testReadFirstLine() throws IOException {
- if (expectedLines.isEmpty()) {
- assertNull(source.readFirstLine());
- } else {
- assertEquals(expectedLines.get(0), source.readFirstLine());
- }
- }
-
- public void testReadLines_toList() throws IOException {
- assertExpectedLines(source.readLines());
- }
-
- private void assertExpectedString(String string) {
- assertEquals(expected, string);
- }
-
- private void assertExpectedLines(List<String> list) {
- assertEquals(expectedLines, list);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/CharStreamsTest.java b/guava-tests/test/com/google/common/io/CharStreamsTest.java
index f0c84a2..c628afb 100644
--- a/guava-tests/test/com/google/common/io/CharStreamsTest.java
+++ b/guava-tests/test/com/google/common/io/CharStreamsTest.java
@@ -21,13 +21,10 @@ import static com.google.common.io.CharStreams.copy;
import static com.google.common.io.CharStreams.newReaderSupplier;
import com.google.common.base.Charsets;
-import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.TestLogHandler;
-import junit.framework.TestSuite;
-
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.FilterReader;
@@ -46,15 +43,6 @@ import java.util.List;
* @author Chris Nokleberg
*/
public class CharStreamsTest extends IoTestCase {
-
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(CharSourceTester.tests("CharStreams.asCharSource[String]",
- SourceSinkFactories.stringCharSourceFactory()));
- suite.addTestSuite(CharStreamsTest.class);
- return suite;
- }
-
private static final String TEXT
= "The quick brown fox jumped over the lazy dog.";
@@ -92,18 +80,18 @@ public class CharStreamsTest extends IoTestCase {
CharStreams.skipFully(reader, 6);
assertEquals(-1, reader.read());
}
-
+
private static class NonSkippingReader extends StringReader {
NonSkippingReader(String s) {
super(s);
}
-
+
@Override
public long skip(long n) {
return 0;
}
}
-
+
public void testReadLines_fromReadable() throws IOException {
byte[] bytes = "a\nb\nc".getBytes(Charsets.UTF_8.name());
List<String> lines = CharStreams.readLines(
@@ -230,66 +218,6 @@ public class CharStreamsTest extends IoTestCase {
assertTrue(brokenWrite.areClosed());
}
- public void testCopySuppliersExceptions() {
- if (!Closer.SuppressingSuppressor.isAvailable()) {
- // test that exceptions are logged
-
- TestLogHandler logHandler = new TestLogHandler();
- Closeables.logger.addHandler(logHandler);
- try {
- for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
- runFailureTest(in, newStringWriterSupplier());
- assertTrue(logHandler.getStoredLogRecords().isEmpty());
-
- runFailureTest(in, BROKEN_CLOSE_OUTPUT);
- assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, getAndResetRecords(logHandler));
- }
-
- for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
- runFailureTest(newReaderSupplier("ABC"), out);
- assertTrue(logHandler.getStoredLogRecords().isEmpty());
-
- runFailureTest(BROKEN_CLOSE_INPUT, out);
- assertEquals(1, getAndResetRecords(logHandler));
- }
-
- for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
- for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
- runFailureTest(in, out);
- assertTrue(getAndResetRecords(logHandler) <= 1);
- }
- }
- } finally {
- Closeables.logger.removeHandler(logHandler);
- }
- } else {
- // test that exceptions are suppressed
-
- for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
- int suppressed = runSuppressionFailureTest(in, newStringWriterSupplier());
- assertEquals(0, suppressed);
-
- suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_OUTPUT);
- assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, suppressed);
- }
-
- for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
- int suppressed = runSuppressionFailureTest(newReaderSupplier("ABC"), out);
- assertEquals(0, suppressed);
-
- suppressed = runSuppressionFailureTest(BROKEN_CLOSE_INPUT, out);
- assertEquals(1, suppressed);
- }
-
- for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
- for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
- int suppressed = runSuppressionFailureTest(in, out);
- assertTrue(suppressed <= 1);
- }
- }
- }
- }
-
private static int getAndResetRecords(TestLogHandler logHandler) {
int records = logHandler.getStoredLogRecords().size();
logHandler.clear();
@@ -305,20 +233,6 @@ public class CharStreamsTest extends IoTestCase {
}
}
- /**
- * @return the number of exceptions that were suppressed on the expected thrown exception
- */
- private static int runSuppressionFailureTest(
- InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out) {
- try {
- copy(in, out);
- fail();
- } catch (IOException expected) {
- return CloserTest.getSuppressed(expected).length;
- }
- throw new AssertionError(); // can't happen
- }
-
private static OutputSupplier<Writer> newStringWriterSupplier() {
return new OutputSupplier<Writer>() {
@Override public Writer getOutput() {
@@ -374,38 +288,6 @@ public class CharStreamsTest extends IoTestCase {
assertEquals(expected, sw.toString());
}
- public void testCopy() throws IOException {
- StringBuilder builder = new StringBuilder();
- long copied = CharStreams.copy(new StringReader(ASCII), builder);
- assertEquals(ASCII, builder.toString());
- assertEquals(ASCII.length(), copied);
-
- StringBuilder builder2 = new StringBuilder();
- copied = CharStreams.copy(new StringReader(I18N), builder2);
- assertEquals(I18N, builder2.toString());
- assertEquals(I18N.length(), copied);
- }
-
- /**
- * Test for Guava issue 1061: http://code.google.com/p/guava-libraries/issues/detail?id=1061
- *
- * <p>CharStreams.copy was failing to clear its CharBuffer after each read call, which effectively
- * reduced the available size of the buffer each time a call to read didn't fill up the available
- * space in the buffer completely. In general this is a performance problem since the buffer size
- * is permanently reduced, but with certain Reader implementations it could also cause the buffer
- * size to reach 0, causing an infinite loop.
- */
- public void testCopyWithReaderThatDoesNotFillBuffer() throws IOException {
- // need a long enough string for the buffer to hit 0 remaining before the copy completes
- String string = Strings.repeat("0123456789", 100);
- StringBuilder b = new StringBuilder();
- // the main assertion of this test is here... the copy will fail if the buffer size goes down
- // each time it is not filled completely
- long copied = CharStreams.copy(newNonBufferFillingReader(new StringReader(string)), b);
- assertEquals(string, b.toString());
- assertEquals(string.length(), copied);
- }
-
private static CheckCloseSupplier.Input<Reader> newCheckReader(
InputSupplier<? extends Reader> delegate) {
return new CheckCloseSupplier.Input<Reader>(delegate) {
@@ -433,24 +315,4 @@ public class CharStreamsTest extends IoTestCase {
}
};
}
-
- /**
- * Returns a reader wrapping the given reader that only reads half of the maximum number of
- * characters that it could read in read(char[], int, int).
- */
- private static Reader newNonBufferFillingReader(Reader reader) {
- return new FilterReader(reader) {
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- // if a buffer isn't being cleared correctly, this method will eventually start being called
- // with a len of 0 forever
- if (len <= 0) {
- fail("read called with a len of " + len);
- }
- // read fewer than the max number of chars to read
- // shouldn't be a problem unless the buffer is shrinking each call
- return in.read(cbuf, off, Math.max(len - 1024, 0));
- }
- };
- }
}
diff --git a/guava-tests/test/com/google/common/io/CloseablesTest.java b/guava-tests/test/com/google/common/io/CloseablesTest.java
index 3717a54..f75d4dc 100644
--- a/guava-tests/test/com/google/common/io/CloseablesTest.java
+++ b/guava-tests/test/com/google/common/io/CloseablesTest.java
@@ -25,13 +25,14 @@ import static org.easymock.EasyMock.verify;
import junit.framework.TestCase;
import java.io.Closeable;
+import java.io.Flushable;
import java.io.IOException;
/**
- * Unit tests for {@link Closeables}.
+ * Unit tests for {@link Closeables} and {@link Flushables}.
*
- * <p>Checks proper closing behavior, and ensures that
- * IOExceptions on Closeable.close() are not
+ * <p>Checks proper closing and flushing behavior, and ensures that
+ * IOExceptions on Closeable.close() or Flushable.flush() are not
* propagated out from the {@link Closeables#close} method if {@code
* swallowException} is true.
*
@@ -39,6 +40,7 @@ import java.io.IOException;
*/
public class CloseablesTest extends TestCase {
private Closeable mockCloseable;
+ private Flushable mockFlushable;
public void testClose_closeableClean() throws IOException {
// make sure that no exception is thrown regardless of value of
@@ -67,11 +69,43 @@ public class CloseablesTest extends TestCase {
public void testCloseQuietly_closeableWithEatenException()
throws IOException {
// make sure that no exception is thrown by CloseQuietly when the mock does
- // throw an exception on close
+ // throw an exception, either on close, on flush, or both.
setupCloseable(true);
Closeables.closeQuietly(mockCloseable);
}
+ public void testFlush_clean() throws IOException {
+ // make sure that no exception is thrown regardless of value of
+ // 'swallowException' when the mock does not throw an exception.
+ setupFlushable(false);
+ doFlush(mockFlushable, false, false);
+
+ setupFlushable(false);
+ doFlush(mockFlushable, true, false);
+ }
+
+ public void testFlush_flushableWithEatenException() throws IOException {
+ // make sure that no exception is thrown if 'swallowException' is true
+ // when the mock does throw an exception on flush.
+ setupFlushable(true);
+ doFlush(mockFlushable, true, false);
+ }
+
+ public void testFlush_flushableWithThrownException() throws IOException {
+ // make sure that the exception is thrown if 'swallowException' is false
+ // when the mock does throw an exception on flush.
+ setupFlushable(true);
+ doFlush(mockFlushable, false, true);
+ }
+
+ public void testFlushQuietly_flushableWithEatenException()
+ throws IOException {
+ // make sure that no exception is thrown by CloseQuietly when the mock does
+ // throw an exception on flush.
+ setupFlushable(true);
+ Flushables.flushQuietly(mockFlushable);
+ }
+
public void testCloseNull() throws IOException {
Closeables.close(null, true);
Closeables.close(null, false);
@@ -80,6 +114,7 @@ public class CloseablesTest extends TestCase {
@Override protected void setUp() throws Exception {
mockCloseable = createStrictMock(Closeable.class);
+ mockFlushable = createStrictMock(Flushable.class);
}
private void expectThrown() {
@@ -98,6 +133,17 @@ public class CloseablesTest extends TestCase {
replay(mockCloseable);
}
+ // Set up a flushable to expect to be flushed and closed, and optionally to
+ // throw an exception.
+ private void setupFlushable(boolean shouldThrowOnFlush) throws IOException {
+ reset(mockFlushable);
+ mockFlushable.flush();
+ if (shouldThrowOnFlush) {
+ expectThrown();
+ }
+ replay(mockFlushable);
+ }
+
private void doClose(Closeable closeable, boolean swallowException) {
doClose(closeable, swallowException, !swallowException);
}
@@ -119,4 +165,22 @@ public class CloseablesTest extends TestCase {
}
verify(closeable);
}
+
+ // Flush the flushable using the Flushables, passing in the swallowException
+ // parameter. expectThrown determines whether we expect an exception to
+ // be thrown by Flushables.flush;
+ private void doFlush(Flushable flushable, boolean swallowException,
+ boolean expectThrown) {
+ try {
+ Flushables.flush(flushable, swallowException);
+ if (expectThrown) {
+ fail("Didn't throw exception.");
+ }
+ } catch (IOException e) {
+ if (!expectThrown) {
+ fail("Threw exception");
+ }
+ }
+ verify(flushable);
+ }
}
diff --git a/guava-tests/test/com/google/common/io/CloserTest.java b/guava-tests/test/com/google/common/io/CloserTest.java
deleted file mode 100644
index e5e8326..0000000
--- a/guava-tests/test/com/google/common/io/CloserTest.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.testing.TestLogHandler;
-
-import junit.framework.TestCase;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.logging.LogRecord;
-
-import javax.annotation.Nullable;
-
-/**
- * Tests for {@link Closer}.
- *
- * @author Colin Decker
- */
-public class CloserTest extends TestCase {
-
- private TestSuppressor suppressor;
-
- @Override
- protected void setUp() throws Exception {
- suppressor = new TestSuppressor();
- }
-
- public void testCreate() {
- Closer closer = Closer.create();
- String javaVersion = System.getProperty("java.version");
- String secondPart = Iterables.get(Splitter.on('.').split(javaVersion), 1);
- int versionNumber = Integer.parseInt(secondPart);
- if (versionNumber < 7) {
- assertTrue(closer.suppressor instanceof Closer.LoggingSuppressor);
- } else {
- assertTrue(closer.suppressor instanceof Closer.SuppressingSuppressor);
- }
- }
-
- public void testNoExceptionsThrown() throws IOException {
- Closer closer = new Closer(suppressor);
-
- TestCloseable c1 = closer.register(TestCloseable.normal());
- TestCloseable c2 = closer.register(TestCloseable.normal());
- TestCloseable c3 = closer.register(TestCloseable.normal());
-
- assertFalse(c1.isClosed());
- assertFalse(c2.isClosed());
- assertFalse(c3.isClosed());
-
- closer.close();
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
- assertTrue(c3.isClosed());
-
- assertTrue(suppressor.suppressions.isEmpty());
- }
-
- public void testExceptionThrown_fromTryBlock() throws IOException {
- Closer closer = new Closer(suppressor);
-
- TestCloseable c1 = closer.register(TestCloseable.normal());
- TestCloseable c2 = closer.register(TestCloseable.normal());
-
- IOException exception = new IOException();
-
- try {
- try {
- throw exception;
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- } catch (Throwable expected) {
- assertSame(exception, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
-
- assertTrue(suppressor.suppressions.isEmpty());
- }
-
- public void testExceptionThrown_whenCreatingCloseables() throws IOException {
- Closer closer = new Closer(suppressor);
-
- TestCloseable c1 = null;
- TestCloseable c2 = null;
- TestCloseable c3 = null;
- try {
- try {
- c1 = closer.register(TestCloseable.normal());
- c2 = closer.register(TestCloseable.normal());
- c3 = closer.register(TestCloseable.throwsOnCreate());
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- } catch (Throwable expected) {
- assertTrue(expected instanceof IOException);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
- assertNull(c3);
-
- assertTrue(suppressor.suppressions.isEmpty());
- }
-
- public void testExceptionThrown_whileClosingLastCloseable() throws IOException {
- Closer closer = new Closer(suppressor);
-
- IOException exception = new IOException();
-
- // c1 is added first, closed last
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(exception));
- TestCloseable c2 = closer.register(TestCloseable.normal());
-
- try {
- closer.close();
- } catch (Throwable expected) {
- assertSame(exception, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
-
- assertTrue(suppressor.suppressions.isEmpty());
- }
-
- public void testExceptionThrown_whileClosingFirstCloseable() throws IOException {
- Closer closer = new Closer(suppressor);
-
- IOException exception = new IOException();
-
- // c2 is added last, closed first
- TestCloseable c1 = closer.register(TestCloseable.normal());
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(exception));
-
- try {
- closer.close();
- } catch (Throwable expected) {
- assertSame(exception, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
-
- assertTrue(suppressor.suppressions.isEmpty());
- }
-
- public void testCloseExceptionsSuppressed_whenExceptionThrownFromTryBlock() throws IOException {
- Closer closer = new Closer(suppressor);
-
- IOException tryException = new IOException();
- IOException c1Exception = new IOException();
- IOException c2Exception = new IOException();
-
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
-
- try {
- try {
- throw tryException;
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- } catch (Throwable expected) {
- assertSame(tryException, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
-
- assertSuppressed(
- new Suppression(c2, tryException, c2Exception),
- new Suppression(c1, tryException, c1Exception));
- }
-
- public void testCloseExceptionsSuppressed_whenExceptionThrownClosingFirstCloseable()
- throws IOException {
- Closer closer = new Closer(suppressor);
-
- IOException c1Exception = new IOException();
- IOException c2Exception = new IOException();
- IOException c3Exception = new IOException();
-
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
- TestCloseable c3 = closer.register(TestCloseable.throwsOnClose(c3Exception));
-
- try {
- closer.close();
- } catch (Throwable expected) {
- assertSame(c3Exception, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
- assertTrue(c3.isClosed());
-
- assertSuppressed(
- new Suppression(c2, c3Exception, c2Exception),
- new Suppression(c1, c3Exception, c1Exception));
- }
-
- public void testRuntimeExceptions() throws IOException {
- Closer closer = new Closer(suppressor);
-
- RuntimeException tryException = new RuntimeException();
- RuntimeException c1Exception = new RuntimeException();
- RuntimeException c2Exception = new RuntimeException();
-
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
-
- try {
- try {
- throw tryException;
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- } catch (Throwable expected) {
- assertSame(tryException, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
-
- assertSuppressed(
- new Suppression(c2, tryException, c2Exception),
- new Suppression(c1, tryException, c1Exception));
- }
-
- public void testErrors() throws IOException {
- Closer closer = new Closer(suppressor);
-
- Error c1Exception = new Error();
- Error c2Exception = new Error();
- Error c3Exception = new Error();
-
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
- TestCloseable c3 = closer.register(TestCloseable.throwsOnClose(c3Exception));
-
- try {
- closer.close();
- } catch (Throwable expected) {
- assertSame(c3Exception, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
- assertTrue(c3.isClosed());
-
- assertSuppressed(
- new Suppression(c2, c3Exception, c2Exception),
- new Suppression(c1, c3Exception, c1Exception));
- }
-
- public static void testLoggingSuppressor() throws IOException {
- TestLogHandler logHandler = new TestLogHandler();
-
- Closeables.logger.addHandler(logHandler);
- try {
- Closer closer = new Closer(new Closer.LoggingSuppressor());
-
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(new IOException()));
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(new RuntimeException()));
- try {
- throw closer.rethrow(new IOException("thrown"), IOException.class);
- } catch (IOException expected) {}
-
- assertTrue(logHandler.getStoredLogRecords().isEmpty());
-
- closer.close();
-
- assertEquals(2, logHandler.getStoredLogRecords().size());
-
- LogRecord record = logHandler.getStoredLogRecords().get(0);
- assertEquals("Suppressing exception thrown when closing " + c2, record.getMessage());
-
- record = logHandler.getStoredLogRecords().get(1);
- assertEquals("Suppressing exception thrown when closing " + c1, record.getMessage());
- } finally {
- Closeables.logger.removeHandler(logHandler);
- }
- }
-
- public static void testSuppressingSuppressorIfPossible() throws IOException {
- // can't test the JDK7 suppressor when not running on JDK7
- if (!Closer.SuppressingSuppressor.isAvailable()) {
- return;
- }
-
- Closer closer = new Closer(new Closer.SuppressingSuppressor());
-
- IOException thrownException = new IOException();
- IOException c1Exception = new IOException();
- RuntimeException c2Exception = new RuntimeException();
-
- TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
- TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
- try {
- try {
- throw thrownException;
- } catch (Throwable e) {
- throw closer.rethrow(thrownException, IOException.class);
- } finally {
- assertEquals(0, getSuppressed(thrownException).length);
- closer.close();
- }
- } catch (IOException expected) {
- assertSame(thrownException, expected);
- }
-
- assertTrue(c1.isClosed());
- assertTrue(c2.isClosed());
-
- ImmutableSet<Throwable> suppressed = ImmutableSet.copyOf(getSuppressed(thrownException));
- assertEquals(2, suppressed.size());
-
- assertEquals(ImmutableSet.of(c1Exception, c2Exception), suppressed);
- }
-
- static Throwable[] getSuppressed(Throwable throwable) {
- try {
- Method getSuppressed = Throwable.class.getDeclaredMethod("getSuppressed");
- return (Throwable[]) getSuppressed.invoke(throwable);
- } catch (Exception e) {
- throw new AssertionError(e); // only called if running on JDK7
- }
- }
-
- /**
- * Asserts that an exception was thrown when trying to close each of the given throwables and that
- * each such exception was suppressed because of the given thrown exception.
- */
- private void assertSuppressed(Suppression... expected) {
- assertEquals(ImmutableList.copyOf(expected), suppressor.suppressions);
- }
-
- /**
- * Suppressor that records suppressions.
- */
- private static class TestSuppressor implements Closer.Suppressor {
-
- private final List<Suppression> suppressions = Lists.newArrayList();
-
- @Override
- public void suppress(Closeable closeable, Throwable thrown, Throwable suppressed) {
- suppressions.add(new Suppression(closeable, thrown, suppressed));
- }
- }
-
- /**
- * Record of a call to suppress.
- */
- private static class Suppression {
- private final Closeable closeable;
- private final Throwable thrown;
- private final Throwable suppressed;
-
- private Suppression(Closeable closeable, Throwable thrown, Throwable suppressed) {
- this.closeable = closeable;
- this.thrown = thrown;
- this.suppressed = suppressed;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Suppression) {
- Suppression other = (Suppression) obj;
- return closeable.equals(other.closeable)
- && thrown.equals(other.thrown)
- && suppressed.equals(other.suppressed);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(closeable, thrown, suppressed);
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .add("closeable", closeable)
- .add("thrown", thrown)
- .add("suppressed", suppressed)
- .toString();
- }
- }
-
- private static class TestCloseable implements Closeable {
-
- private final Throwable throwOnClose;
- private boolean closed;
-
- static TestCloseable normal() throws IOException {
- return new TestCloseable(null);
- }
-
- static TestCloseable throwsOnClose(Throwable throwOnClose) throws IOException {
- return new TestCloseable(throwOnClose);
- }
-
- static TestCloseable throwsOnCreate() throws IOException {
- throw new IOException();
- }
-
- private TestCloseable(@Nullable Throwable throwOnClose) {
- this.throwOnClose = throwOnClose;
- }
-
- public boolean isClosed() {
- return closed;
- }
-
- @Override
- public void close() throws IOException {
- closed = true;
- if (throwOnClose != null) {
- Throwables.propagateIfPossible(throwOnClose, IOException.class);
- throw new AssertionError(throwOnClose);
- }
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/io/FlushablesTest.java b/guava-tests/test/com/google/common/io/FlushablesTest.java
deleted file mode 100644
index 34a3155..0000000
--- a/guava-tests/test/com/google/common/io/FlushablesTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static org.easymock.EasyMock.createStrictMock;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-
-import junit.framework.TestCase;
-
-import java.io.Flushable;
-import java.io.IOException;
-
-/**
- * Unit tests for {@link Flushables}.
- *
- * <p>Checks proper flushing behavior, and ensures that
- * IOExceptions on Flushable.flush() are not
- * propagated out from the {@link Flushables#flush} method if {@code
- * swallowException} is true.
- *
- * @author Michael Lancaster
- */
-public class FlushablesTest extends TestCase {
- private Flushable mockFlushable;
-
- public void testFlush_clean() throws IOException {
- // make sure that no exception is thrown regardless of value of
- // 'swallowException' when the mock does not throw an exception.
- setupFlushable(false);
- doFlush(mockFlushable, false, false);
-
- setupFlushable(false);
- doFlush(mockFlushable, true, false);
- }
-
- public void testFlush_flushableWithEatenException() throws IOException {
- // make sure that no exception is thrown if 'swallowException' is true
- // when the mock does throw an exception on flush.
- setupFlushable(true);
- doFlush(mockFlushable, true, false);
- }
-
- public void testFlush_flushableWithThrownException() throws IOException {
- // make sure that the exception is thrown if 'swallowException' is false
- // when the mock does throw an exception on flush.
- setupFlushable(true);
- doFlush(mockFlushable, false, true);
- }
-
- public void testFlushQuietly_flushableWithEatenException()
- throws IOException {
- // make sure that no exception is thrown by flushQuietly when the mock does
- // throw an exception on flush.
- setupFlushable(true);
- Flushables.flushQuietly(mockFlushable);
- }
-
- @Override protected void setUp() throws Exception {
- mockFlushable = createStrictMock(Flushable.class);
- }
-
- private void expectThrown() {
- expectLastCall().andThrow(new IOException("This should only appear in the "
- + "logs. It should not be rethrown."));
- }
-
- // Set up a flushable to expect to be flushed, and optionally to
- // throw an exception.
- private void setupFlushable(boolean shouldThrowOnFlush) throws IOException {
- reset(mockFlushable);
- mockFlushable.flush();
- if (shouldThrowOnFlush) {
- expectThrown();
- }
- replay(mockFlushable);
- }
-
- // Flush the flushable using the Flushables, passing in the swallowException
- // parameter. expectThrown determines whether we expect an exception to
- // be thrown by Flushables.flush;
- private void doFlush(Flushable flushable, boolean swallowException,
- boolean expectThrown) {
- try {
- Flushables.flush(flushable, swallowException);
- if (expectThrown) {
- fail("Didn't throw exception.");
- }
- } catch (IOException e) {
- if (!expectThrown) {
- fail("Threw exception");
- }
- }
- verify(flushable);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/PackageSanityTests.java b/guava-tests/test/com/google/common/io/PackageSanityTests.java
deleted file mode 100644
index a620b30..0000000
--- a/guava-tests/test/com/google/common/io/PackageSanityTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-import java.lang.reflect.Method;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- setDefault(BaseEncoding.class, BaseEncoding.base64());
- setDefault(int.class, 32);
- setDefault(String.class, "abcd");
- setDefault(Method.class, AbstractPackageSanityTests.class.getDeclaredMethods()[0]);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/RandomAmountInputStream.java b/guava-tests/test/com/google/common/io/RandomAmountInputStream.java
index 0e3ee15..2ffeea7 100644
--- a/guava-tests/test/com/google/common/io/RandomAmountInputStream.java
+++ b/guava-tests/test/com/google/common/io/RandomAmountInputStream.java
@@ -16,8 +16,6 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -28,8 +26,8 @@ class RandomAmountInputStream extends FilterInputStream {
private final Random random;
public RandomAmountInputStream(InputStream in, Random random) {
- super(checkNotNull(in));
- this.random = checkNotNull(random);
+ super(in);
+ this.random = random;
}
@Override public int read(byte[] b, int off, int len) throws IOException {
diff --git a/guava-tests/test/com/google/common/io/ResourcesTest.java b/guava-tests/test/com/google/common/io/ResourcesTest.java
index 47779a8..8aedfa3 100644
--- a/guava-tests/test/com/google/common/io/ResourcesTest.java
+++ b/guava-tests/test/com/google/common/io/ResourcesTest.java
@@ -17,13 +17,10 @@
package com.google.common.io;
import static com.google.common.base.CharMatcher.WHITESPACE;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestSuite;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -40,19 +37,17 @@ import java.util.List;
*/
public class ResourcesTest extends IoTestCase {
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(ByteSourceTester.tests("Resources.asByteSource[URL]",
- SourceSinkFactories.urlByteSourceFactory(), true));
- suite.addTest(CharSourceTester.tests("Resources.asCharSource[URL, Charset]",
- SourceSinkFactories.urlCharSourceFactory()));
- suite.addTestSuite(ResourcesTest.class);
- return suite;
- }
-
public void testUrlSupplier() throws IOException {
+ try {
+ Resources.newInputStreamSupplier(null);
+ fail("expected NPE");
+ } catch (NullPointerException expected) {
+ // expected
+ }
+
+ URL url = getClass().getResource("/com/google/common/io/Resources.class");
byte[] data = ByteStreams.toByteArray(
- Resources.newInputStreamSupplier(classfile(Resources.class)));
+ Resources.newInputStreamSupplier(url));
assertEquals(0xCAFEBABE,
new DataInputStream(new ByteArrayInputStream(data)).readInt());
}
@@ -63,9 +58,10 @@ public class ResourcesTest extends IoTestCase {
ASSERT.that(Resources.toString(resource, Charsets.US_ASCII))
.isNotEqualTo(I18N);
}
-
+
public void testToToByteArray() throws IOException {
- byte[] data = Resources.toByteArray(classfile(Resources.class));
+ URL url = getClass().getResource("/com/google/common/io/Resources.class");
+ byte[] data = Resources.toByteArray(url);
assertEquals(0xCAFEBABE,
new DataInputStream(new ByteArrayInputStream(data)).readInt());
}
@@ -106,7 +102,7 @@ public class ResourcesTest extends IoTestCase {
Resources.copy(resource, out);
assertEquals(I18N, out.toString("UTF-8"));
}
-
+
public void testGetResource_notFound() {
try {
Resources.getResource("no such resource");
@@ -115,12 +111,12 @@ public class ResourcesTest extends IoTestCase {
assertEquals("resource no such resource not found.", e.getMessage());
}
}
-
+
public void testGetResource() {
assertNotNull(
Resources.getResource("com/google/common/io/testdata/i18n.txt"));
}
-
+
public void testGetResource_relativePath_notFound() {
try {
Resources.getResource(
@@ -132,18 +128,8 @@ public class ResourcesTest extends IoTestCase {
e.getMessage());
}
}
-
+
public void testGetResource_relativePath() {
assertNotNull(Resources.getResource(getClass(), "testdata/i18n.txt"));
}
-
- public void testNulls() {
- new NullPointerTester()
- .setDefault(URL.class, classfile(ResourcesTest.class))
- .testAllPublicStaticMethods(Resources.class);
- }
-
- private static URL classfile(Class<?> c) {
- return c.getResource(c.getSimpleName() + ".class");
- }
}
diff --git a/guava-tests/test/com/google/common/io/SourceSinkFactories.java b/guava-tests/test/com/google/common/io/SourceSinkFactories.java
deleted file mode 100644
index 0ebfe28..0000000
--- a/guava-tests/test/com/google/common/io/SourceSinkFactories.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.io.SourceSinkFactory.ByteSinkFactory;
-import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
-import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
-import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
-
-import com.google.common.base.Charsets;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.CharBuffer;
-import java.util.Arrays;
-import java.util.logging.Logger;
-
-import javax.annotation.Nullable;
-
-/**
- * {@link SourceSinkFactory} implementations.
- *
- * @author Colin Decker
- */
-public class SourceSinkFactories {
-
- private SourceSinkFactories() {}
-
- public static CharSourceFactory stringCharSourceFactory() {
- return new StringSourceFactory();
- }
-
- public static ByteSourceFactory byteArraySourceFactory() {
- return new ByteArraySourceFactory();
- }
-
- public static ByteSourceFactory fileByteSourceFactory() {
- return new FileByteSourceFactory();
- }
-
- public static ByteSinkFactory fileByteSinkFactory() {
- return new FileByteSinkFactory(null);
- }
-
- public static ByteSinkFactory appendingFileByteSinkFactory() {
- String initialString = IoTestCase.ASCII + IoTestCase.I18N;
- return new FileByteSinkFactory(initialString.getBytes(Charsets.UTF_8));
- }
-
- public static CharSourceFactory fileCharSourceFactory() {
- return new FileCharSourceFactory();
- }
-
- public static CharSinkFactory fileCharSinkFactory() {
- return new FileCharSinkFactory(null);
- }
-
- public static CharSinkFactory appendingFileCharSinkFactory() {
- String initialString = IoTestCase.ASCII + IoTestCase.I18N;
- return new FileCharSinkFactory(initialString);
- }
-
- public static ByteSourceFactory urlByteSourceFactory() {
- return new UrlByteSourceFactory();
- }
-
- public static CharSourceFactory urlCharSourceFactory() {
- return new UrlCharSourceFactory();
- }
-
- public static CharSourceFactory asCharSourceFactory(final ByteSourceFactory factory) {
- checkNotNull(factory);
- return new CharSourceFactory() {
- @Override
- public CharSource createSource(String string) throws IOException {
- return factory.createSource(string.getBytes(Charsets.UTF_8))
- .asCharSource(Charsets.UTF_8);
- }
-
- @Override
- public String getExpected(String data) {
- return checkNotNull(data);
- }
-
- @Override
- public void tearDown() throws IOException {
- factory.tearDown();
- }
- };
- }
-
- public static CharSinkFactory asCharSinkFactory(final ByteSinkFactory factory) {
- checkNotNull(factory);
- return new CharSinkFactory() {
- @Override
- public CharSink createSink() throws IOException {
- return factory.createSink().asCharSink(Charsets.UTF_8);
- }
-
- @Override
- public String getSinkContents() throws IOException {
- return new String(factory.getSinkContents(), Charsets.UTF_8);
- }
-
- @Override
- public String getExpected(String data) {
- /*
- * Get what the byte sink factory would expect for no written bytes, then append expected
- * string to that.
- */
- byte[] factoryExpectedForNothing = factory.getExpected(new byte[0]);
- return new String(factoryExpectedForNothing, Charsets.UTF_8) + checkNotNull(data);
- }
-
- @Override
- public void tearDown() throws IOException {
- factory.tearDown();
- }
- };
- }
-
- public static ByteSourceFactory asSlicedByteSourceFactory(final ByteSourceFactory factory,
- final int off, final int len) {
- checkNotNull(factory);
- return new ByteSourceFactory() {
- @Override
- public ByteSource createSource(byte[] bytes) throws IOException {
- return factory.createSource(bytes).slice(off, len);
- }
-
- @Override
- public byte[] getExpected(byte[] bytes) {
- return Arrays.copyOfRange(factory.getExpected(bytes), off, off + len);
- }
-
- @Override
- public void tearDown() throws IOException {
- factory.tearDown();
- }
- };
- }
-
- private static class StringSourceFactory implements CharSourceFactory {
-
- @Override
- public CharSource createSource(String data) throws IOException {
- return CharStreams.asCharSource(data);
- }
-
- @Override
- public String getExpected(String data) {
- return data;
- }
-
- @Override
- public void tearDown() throws IOException {
- }
- }
-
- private static class ByteArraySourceFactory implements ByteSourceFactory {
-
- @Override
- public ByteSource createSource(byte[] bytes) throws IOException {
- return ByteStreams.asByteSource(bytes);
- }
-
- @Override
- public byte[] getExpected(byte[] bytes) {
- return bytes;
- }
-
- @Override
- public void tearDown() throws IOException {
- }
- }
-
- private abstract static class FileFactory {
-
- private static final Logger logger = Logger.getLogger(FileFactory.class.getName());
-
- private final ThreadLocal<File> fileThreadLocal = new ThreadLocal<File>();
-
- protected File createFile() throws IOException {
- File file = File.createTempFile("SinkSourceFile", "txt");
- fileThreadLocal.set(file);
- return file;
- }
-
- protected File getFile() {
- return fileThreadLocal.get();
- }
- public final void tearDown() throws IOException {
- if (!fileThreadLocal.get().delete()) {
- logger.warning("Unable to delete file: " + fileThreadLocal.get());
- }
- fileThreadLocal.remove();
- }
- }
-
- private static class FileByteSourceFactory extends FileFactory implements ByteSourceFactory {
-
- @Override
- public ByteSource createSource(byte[] bytes) throws IOException {
- checkNotNull(bytes);
- File file = createFile();
- OutputStream out = new FileOutputStream(file);
- try {
- out.write(bytes);
- } finally {
- out.close();
- }
- return Files.asByteSource(file);
- }
-
- @Override
- public byte[] getExpected(byte[] bytes) {
- return checkNotNull(bytes);
- }
- }
-
- private static class FileByteSinkFactory extends FileFactory implements ByteSinkFactory {
-
- private final byte[] initialBytes;
-
- private FileByteSinkFactory(@Nullable byte[] initialBytes) {
- this.initialBytes = initialBytes;
- }
-
- @Override
- public ByteSink createSink() throws IOException {
- File file = createFile();
- if (initialBytes != null) {
- FileOutputStream out = new FileOutputStream(file);
- try {
- out.write(initialBytes);
- } finally {
- out.close();
- }
- return Files.asByteSink(file, FileWriteMode.APPEND);
- }
- return Files.asByteSink(file);
- }
-
- @Override
- public byte[] getExpected(byte[] bytes) {
- if (initialBytes == null) {
- return checkNotNull(bytes);
- } else {
- byte[] result = new byte[initialBytes.length + bytes.length];
- System.arraycopy(initialBytes, 0, result, 0, initialBytes.length);
- System.arraycopy(bytes, 0, result, initialBytes.length, bytes.length);
- return result;
- }
- }
-
- @Override
- public byte[] getSinkContents() throws IOException {
- File file = getFile();
- InputStream in = new FileInputStream(file);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] buffer = new byte[100];
- int read;
- while ((read = in.read(buffer)) != -1) {
- out.write(buffer, 0, read);
- }
- return out.toByteArray();
- }
- }
-
- private static class FileCharSourceFactory extends FileFactory implements CharSourceFactory {
-
- @Override
- public CharSource createSource(String string) throws IOException {
- checkNotNull(string);
- File file = createFile();
- Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
- try {
- writer.write(string);
- } finally {
- writer.close();
- }
- return Files.asCharSource(file, Charsets.UTF_8);
- }
-
- @Override
- public String getExpected(String string) {
- return checkNotNull(string);
- }
- }
-
- private static class FileCharSinkFactory extends FileFactory implements CharSinkFactory {
-
- private final String initialString;
-
- private FileCharSinkFactory(@Nullable String initialString) {
- this.initialString = initialString;
- }
-
- @Override
- public CharSink createSink() throws IOException {
- File file = createFile();
- if (initialString != null) {
- Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
- try {
- writer.write(initialString);
- } finally {
- writer.close();
- }
- return Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND);
- }
- return Files.asCharSink(file, Charsets.UTF_8);
- }
-
- @Override
- public String getExpected(String string) {
- checkNotNull(string);
- return initialString == null
- ? string
- : initialString + string;
- }
-
- @Override
- public String getSinkContents() throws IOException {
- File file = getFile();
- Reader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8);
- StringBuilder builder = new StringBuilder();
- CharBuffer buffer = CharBuffer.allocate(100);
- while (reader.read(buffer) != -1) {
- buffer.flip();
- builder.append(buffer);
- buffer.clear();
- }
- return builder.toString();
- }
- }
-
- private static class UrlByteSourceFactory extends FileByteSourceFactory {
-
- @Override
- public ByteSource createSource(byte[] bytes) throws IOException {
- super.createSource(bytes);
- return Resources.asByteSource(getFile().toURI().toURL());
- }
- }
-
- private static class UrlCharSourceFactory extends FileCharSourceFactory {
-
- @Override
- public CharSource createSource(String string) throws IOException {
- super.createSource(string); // just ignore returned CharSource
- return Resources.asCharSource(getFile().toURI().toURL(), Charsets.UTF_8);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/io/SourceSinkFactory.java b/guava-tests/test/com/google/common/io/SourceSinkFactory.java
deleted file mode 100644
index 0c4fdd8..0000000
--- a/guava-tests/test/com/google/common/io/SourceSinkFactory.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * A test factory for byte or char sources or sinks. In addition to creating sources or sinks, the
- * factory specifies what content should be expected to be read from a source or contained in a sink
- * given the content data that was used to create the source or that was written to the sink.
- *
- * <p>A single {@code SourceSinkFactory} implementation generally corresponds to one specific way of
- * creating a source or sink, such as {@link Files#asByteSource(File)}. Implementations of
- * {@code SourceSinkFactory} for common.io are found in {@link SourceSinkFactories}.
- *
- * @param <S> the source or sink type
- * @param <T> the data type (byte[] or String)
- * @author Colin Decker
- */
-public interface SourceSinkFactory<S, T> {
-
- /**
- * Returns the data to expect the source or sink to contain given the data that was used to create
- * the source or written to the sink. Typically, this will just return the input directly, but in
- * some cases it may alter the input. For example, if the factory returns a sliced view of a
- * source created with some given bytes, this method would return a subsequence of the given
- * (byte[]) data.
- */
- T getExpected(T data);
-
- /**
- * Cleans up anything created when creating the source or sink.
- */
- public abstract void tearDown() throws IOException;
-
- /**
- * Factory for byte or char sources.
- */
- public interface SourceFactory<S, T> extends SourceSinkFactory<S, T> {
-
- /**
- * Creates a new source containing some or all of the given data.
- */
- S createSource(T data) throws IOException;
- }
-
- /**
- * Factory for byte or char sinks.
- */
- public interface SinkFactory<S, T> extends SourceSinkFactory<S, T> {
-
- /**
- * Creates a new sink.
- */
- S createSink() throws IOException;
-
- /**
- * Gets the current content of the created sink.
- */
- T getSinkContents() throws IOException;
- }
-
- /**
- * Factory for {@link ByteSource} instances.
- */
- public interface ByteSourceFactory extends SourceFactory<ByteSource, byte[]> {
- }
-
- /**
- * Factory for {@link ByteSink} instances.
- */
- public interface ByteSinkFactory extends SinkFactory<ByteSink, byte[]> {
- }
-
- /**
- * Factory for {@link CharSource} instances.
- */
- public interface CharSourceFactory extends SourceFactory<CharSource, String> {
- }
-
- /**
- * Factory for {@link CharSink} instances.
- */
- public interface CharSinkFactory extends SinkFactory<CharSink, String> {
- }
-}
diff --git a/guava-tests/test/com/google/common/io/SourceSinkTester.java b/guava-tests/test/com/google/common/io/SourceSinkTester.java
deleted file mode 100644
index ff3167b..0000000
--- a/guava-tests/test/com/google/common/io/SourceSinkTester.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.List;
-
-/**
- * @param <S> the source or sink type
- * @param <T> the data type (byte[] or String)
- * @param <F> the factory type
- * @author Colin Decker
- */
-public class SourceSinkTester<S, T, F extends SourceSinkFactory<S, T>> extends TestCase {
-
- static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing "
- + "elit. Cras fringilla elit ac ipsum adipiscing vulputate. Maecenas in lorem nulla, ac "
- + "sollicitudin quam. Praesent neque elit, sodales quis vestibulum vel, pellentesque nec "
- + "erat. Proin cursus commodo lacus eget congue. Aliquam erat volutpat. Fusce ut leo sed "
- + "risus tempor vehicula et a odio. Nam aliquet dolor viverra libero rutrum accumsan quis "
- + "in augue. Suspendisse id dui in lorem tristique placerat eget vel risus. Sed metus neque, "
- + "scelerisque in molestie ac, mattis quis lectus. Pellentesque viverra justo commodo quam "
- + "bibendum ut gravida leo accumsan. Nullam malesuada sagittis diam, quis suscipit mauris "
- + "euismod vulputate. Pellentesque ultrices tellus sed lorem aliquet pulvinar. Nam lorem "
- + "nunc, ultrices at auctor non, scelerisque eget turpis. Nullam eget varius erat. Sed a "
- + "lorem id arcu dictum euismod. Fusce lectus odio, elementum ullamcorper mattis viverra, "
- + "dictum sit amet lacus.\n"
- + "\n"
- + "Nunc quis lacus est. Sed aliquam pretium cursus. Sed eu libero eros. In hac habitasse "
- + "platea dictumst. Pellentesque molestie, nibh nec iaculis luctus, justo sem lobortis enim, "
- + "at feugiat leo magna nec libero. Mauris quis odio eget nisl rutrum cursus nec eget augue. "
- + "Sed nec arcu sem. In hac habitasse platea dictumst.";
-
- static final ImmutableMap<String, String> TEST_STRINGS
- = ImmutableMap.<String, String>builder()
- .put("empty", "")
- .put("1 char", "0")
- .put("1 word", "hello")
- .put("2 words", "hello world")
- .put("\\n line break", "hello\nworld")
- .put("\\r line break", "hello\rworld")
- .put("\\r\\n line break", "hello\r\nworld")
- .put("\\n at EOF", "hello\nworld\n")
- .put("\\r at EOF", "hello\nworld\r")
- .put("lorem ipsum", LOREM_IPSUM)
- .build();
-
- protected final F factory;
- protected final T data;
- protected final T expected;
-
- private final String suiteName;
- private final String caseDesc;
-
- SourceSinkTester(F factory, T data, String suiteName, String caseDesc, Method method) {
- super(method.getName());
- this.factory = checkNotNull(factory);
- this.data = checkNotNull(data);
- this.expected = checkNotNull(factory.getExpected(data));
- this.suiteName = checkNotNull(suiteName);
- this.caseDesc = checkNotNull(caseDesc);
- }
-
- @Override
- public String getName() {
- return super.getName() + " [" + suiteName + " [" + caseDesc + "]]";
- }
-
- protected static ImmutableList<String> getLines(final String string) {
- try {
- return new CharSource() {
- @Override
- public Reader openStream() throws IOException {
- return new StringReader(string);
- }
- }.readLines();
- } catch (IOException e) {
- throw new AssertionError();
- }
- }
-
- @Override
- public void tearDown() throws IOException {
- factory.tearDown();
- }
-
- static ImmutableList<Method> getTestMethods(Class<?> testClass) {
- List<Method> result = Lists.newArrayList();
- for (Method method : testClass.getDeclaredMethods()) {
- if (Modifier.isPublic(method.getModifiers())
- && method.getReturnType() == void.class
- && method.getParameterTypes().length == 0
- && method.getName().startsWith("test")) {
- result.add(method);
- }
- }
- return ImmutableList.copyOf(result);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestByteSink.java b/guava-tests/test/com/google/common/io/TestByteSink.java
deleted file mode 100644
index 47f34e9..0000000
--- a/guava-tests/test/com/google/common/io/TestByteSink.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import com.google.common.collect.ImmutableSet;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A byte sink for testing that has configurable behavior.
- *
- * @author Colin Decker
- */
-public class TestByteSink extends ByteSink implements TestStreamSupplier {
-
- private final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- private final ImmutableSet<TestOption> options;
-
- private boolean outputStreamOpened;
- private boolean outputStreamClosed;
-
- public TestByteSink(TestOption... options) {
- this.options = ImmutableSet.copyOf(options);
- }
-
- byte[] getBytes() {
- return bytes.toByteArray();
- }
-
- @Override
- public boolean wasStreamOpened() {
- return outputStreamOpened;
- }
-
- @Override
- public boolean wasStreamClosed() {
- return outputStreamClosed;
- }
-
- @Override
- public OutputStream openStream() throws IOException {
- outputStreamOpened = true;
- bytes.reset(); // truncate
- return new Out();
- }
-
- private final class Out extends TestOutputStream {
-
- public Out() throws IOException {
- super(bytes, options);
- }
-
- @Override
- public void close() throws IOException {
- outputStreamClosed = true;
- super.close();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestByteSource.java b/guava-tests/test/com/google/common/io/TestByteSource.java
deleted file mode 100644
index 08ca554..0000000
--- a/guava-tests/test/com/google/common/io/TestByteSource.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableSet;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Random;
-
-/**
- * A byte source for testing that has configurable behavior.
- *
- * @author Colin Decker
- */
-public final class TestByteSource extends ByteSource implements TestStreamSupplier {
-
- private final byte[] bytes;
- private final ImmutableSet<TestOption> options;
-
- private boolean inputStreamOpened;
- private boolean inputStreamClosed;
-
- TestByteSource(byte[] bytes, TestOption... options) {
- this.bytes = checkNotNull(bytes);
- this.options = ImmutableSet.copyOf(options);
- }
-
- @Override
- public boolean wasStreamOpened() {
- return inputStreamOpened;
- }
-
- @Override
- public boolean wasStreamClosed() {
- return inputStreamClosed;
- }
-
- @Override
- public InputStream openStream() throws IOException {
- inputStreamOpened = true;
- return new RandomAmountInputStream(new In(), new Random());
- }
-
- private final class In extends TestInputStream {
-
- public In() throws IOException {
- super(new ByteArrayInputStream(bytes), options);
- }
-
- @Override
- public void close() throws IOException {
- inputStreamClosed = true;
- super.close();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestCharSink.java b/guava-tests/test/com/google/common/io/TestCharSink.java
deleted file mode 100644
index 6f7686f..0000000
--- a/guava-tests/test/com/google/common/io/TestCharSink.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Charsets.UTF_8;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-
-/**
- * A char sink for testing that has configurable behavior.
- *
- * @author Colin Decker
- */
-public class TestCharSink extends CharSink implements TestStreamSupplier {
-
- private final TestByteSink byteSink;
-
- public TestCharSink(TestOption... options) {
- this.byteSink = new TestByteSink(options);
- }
-
- public String getString() {
- return new String(byteSink.getBytes(), UTF_8);
- }
-
- @Override
- public boolean wasStreamOpened() {
- return byteSink.wasStreamOpened();
- }
-
- @Override
- public boolean wasStreamClosed() {
- return byteSink.wasStreamClosed();
- }
-
- @Override
- public Writer openStream() throws IOException {
- // using TestByteSink's output stream to get option behavior, so flush to it on every write
- return new FilterWriter(new OutputStreamWriter(byteSink.openStream(), UTF_8)) {
- @Override
- public void write(int c) throws IOException {
- super.write(c);
- flush();
- }
-
- @Override
- public void write(char[] cbuf, int off, int len) throws IOException {
- super.write(cbuf, off, len);
- flush();
- }
-
- @Override
- public void write(String str, int off, int len) throws IOException {
- super.write(str, off, len);
- flush();
- }
- };
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestCharSource.java b/guava-tests/test/com/google/common/io/TestCharSource.java
deleted file mode 100644
index 37ee8dc..0000000
--- a/guava-tests/test/com/google/common/io/TestCharSource.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Charsets.UTF_8;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-/**
- * A char source for testing that has configurable options.
- *
- * @author Colin Decker
- */
-public class TestCharSource extends CharSource implements TestStreamSupplier {
-
- private final TestByteSource byteSource;
-
- public TestCharSource(String content, TestOption... options) {
- this.byteSource = new TestByteSource(content.getBytes(UTF_8), options);
- }
-
- @Override
- public boolean wasStreamOpened() {
- return byteSource.wasStreamOpened();
- }
-
- @Override
- public boolean wasStreamClosed() {
- return byteSource.wasStreamClosed();
- }
-
- @Override
- public Reader openStream() throws IOException {
- return new InputStreamReader(byteSource.openStream(), UTF_8);
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestInputStream.java b/guava-tests/test/com/google/common/io/TestInputStream.java
deleted file mode 100644
index 51aec6d..0000000
--- a/guava-tests/test/com/google/common/io/TestInputStream.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.io.TestOption.CLOSE_THROWS;
-import static com.google.common.io.TestOption.OPEN_THROWS;
-import static com.google.common.io.TestOption.READ_THROWS;
-import static com.google.common.io.TestOption.SKIP_THROWS;
-
-import com.google.common.collect.ImmutableSet;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-
-/**
- * @author Colin Decker
- */
-public class TestInputStream extends FilterInputStream {
-
- private final ImmutableSet<TestOption> options;
- private boolean closed;
-
- public TestInputStream(InputStream in, TestOption... options) throws IOException {
- this(in, Arrays.asList(options));
- }
-
- public TestInputStream(InputStream in, Iterable<TestOption> options) throws IOException {
- super(checkNotNull(in));
- this.options = ImmutableSet.copyOf(options);
- throwIf(OPEN_THROWS);
- }
-
- public boolean closed() {
- return closed;
- }
-
- @Override
- public int read() throws IOException {
- throwIf(closed);
- throwIf(READ_THROWS);
- return in.read();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- throwIf(closed);
- throwIf(READ_THROWS);
- return in.read(b, off, len);
- }
-
- @Override
- public long skip(long n) throws IOException {
- throwIf(closed);
- throwIf(SKIP_THROWS);
- return in.skip(n);
- }
-
- @Override
- public void close() throws IOException {
- closed = true;
- throwIf(CLOSE_THROWS);
- in.close();
- }
-
- private void throwIf(TestOption option) throws IOException {
- throwIf(options.contains(option));
- }
-
- private static void throwIf(boolean condition) throws IOException {
- if (condition) {
- throw new IOException();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestOption.java b/guava-tests/test/com/google/common/io/TestOption.java
deleted file mode 100644
index 89d7a77..0000000
--- a/guava-tests/test/com/google/common/io/TestOption.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-/**
- * Options controlling the behavior of sources/sinks/streams for testing.
- *
- * @author Colin Decker
- */
-public enum TestOption {
- OPEN_THROWS,
- SKIP_THROWS,
- READ_THROWS,
- WRITE_THROWS,
- CLOSE_THROWS
-}
diff --git a/guava-tests/test/com/google/common/io/TestOutputStream.java b/guava-tests/test/com/google/common/io/TestOutputStream.java
deleted file mode 100644
index 43fc4dc..0000000
--- a/guava-tests/test/com/google/common/io/TestOutputStream.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.io.TestOption.CLOSE_THROWS;
-import static com.google.common.io.TestOption.OPEN_THROWS;
-import static com.google.common.io.TestOption.WRITE_THROWS;
-
-import com.google.common.collect.ImmutableSet;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-
-/**
- * @author Colin Decker
- */
-public class TestOutputStream extends FilterOutputStream {
-
- private final ImmutableSet<TestOption> options;
- private boolean closed;
-
- public TestOutputStream(OutputStream out, TestOption... options) throws IOException {
- this(out, Arrays.asList(options));
- }
-
- public TestOutputStream(OutputStream out, Iterable<TestOption> options) throws IOException {
- super(checkNotNull(out));
- this.options = ImmutableSet.copyOf(options);
- throwIf(OPEN_THROWS);
- }
-
- public boolean closed() {
- return closed;
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- throwIf(closed);
- throwIf(WRITE_THROWS);
- super.write(b, off, len);
- }
-
- @Override
- public void write(int b) throws IOException {
- throwIf(closed);
- throwIf(WRITE_THROWS);
- super.write(b);
- }
-
- @Override
- public void close() throws IOException {
- closed = true;
- super.close();
- throwIf(CLOSE_THROWS);
- }
-
- private void throwIf(TestOption option) throws IOException {
- throwIf(options.contains(option));
- }
-
- private static void throwIf(boolean condition) throws IOException {
- if (condition) {
- throw new IOException();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestReader.java b/guava-tests/test/com/google/common/io/TestReader.java
deleted file mode 100644
index 73a7222..0000000
--- a/guava-tests/test/com/google/common/io/TestReader.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Charsets.UTF_8;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.ByteArrayInputStream;
-import java.io.FilterReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-/**
- * @author Colin Decker
- */
-public class TestReader extends FilterReader {
-
- private final TestInputStream in;
-
- public TestReader(TestOption... options) throws IOException {
- this(new TestInputStream(new ByteArrayInputStream(new byte[10]), options));
- }
-
- public TestReader(TestInputStream in) {
- super(new InputStreamReader(checkNotNull(in), UTF_8));
- this.in = in;
- }
-
- public boolean closed() {
- return in.closed();
- }
-}
diff --git a/guava-tests/test/com/google/common/io/TestStreamSupplier.java b/guava-tests/test/com/google/common/io/TestStreamSupplier.java
deleted file mode 100644
index 47af47b..0000000
--- a/guava-tests/test/com/google/common/io/TestStreamSupplier.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-/**
- * Interface for a supplier of streams that can report whether a stream was opened and whether that
- * stream was closed. Intended for use in a test where only a single stream should be opened and
- * possibly closed.
- *
- * @author Colin Decker
- */
-public interface TestStreamSupplier {
-
- /**
- * Returns whether or not a new stream was opened.
- */
- boolean wasStreamOpened();
-
- /**
- * Returns whether or not an open stream was closed.
- */
- boolean wasStreamClosed();
-}
diff --git a/guava-tests/test/com/google/common/io/TestWriter.java b/guava-tests/test/com/google/common/io/TestWriter.java
deleted file mode 100644
index 1ffe5af..0000000
--- a/guava-tests/test/com/google/common/io/TestWriter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Charsets.UTF_8;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-
-/**
- * @author Colin Decker
- */
-public class TestWriter extends FilterWriter {
-
- private final TestOutputStream out;
-
- public TestWriter(TestOption... options) throws IOException {
- this(new TestOutputStream(ByteStreams.nullOutputStream(), options));
- }
-
- public TestWriter(TestOutputStream out) {
- super(new OutputStreamWriter(checkNotNull(out), UTF_8));
- this.out = out;
- }
-
- @Override
- public void write(int c) throws IOException {
- super.write(c);
- flush(); // flush write to TestOutputStream to get its behavior
- }
-
- @Override
- public void write(char[] cbuf, int off, int len) throws IOException {
- super.write(cbuf, off, len);
- flush();
- }
-
- @Override
- public void write(String str, int off, int len) throws IOException {
- super.write(str, off, len);
- flush();
- }
-
- public boolean closed() {
- return out.closed();
- }
-}
diff --git a/guava-tests/test/com/google/common/math/BigIntegerMathTest.java b/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
index 7e1aa77..504d8c2 100644
--- a/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
+++ b/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
@@ -19,6 +19,8 @@ package com.google.common.math;
import static com.google.common.math.MathTesting.ALL_BIGINTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
import static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
+import static com.google.common.math.MathTesting.NEGATIVE_BIGINTEGER_CANDIDATES;
+import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.NONZERO_BIGINTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.POSITIVE_BIGINTEGER_CANDIDATES;
import static java.math.BigInteger.ONE;
@@ -34,8 +36,6 @@ import static java.math.RoundingMode.UNNECESSARY;
import static java.math.RoundingMode.UP;
import static java.util.Arrays.asList;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -49,15 +49,13 @@ import java.math.RoundingMode;
*
* @author Louis Wasserman
*/
-@GwtCompatible(emulated = true)
public class BigIntegerMathTest extends TestCase {
- @GwtIncompatible("TODO")
public void testConstantSqrt2PrecomputedBits() {
assertEquals(BigIntegerMath.sqrt(
BigInteger.ZERO.setBit(2 * BigIntegerMath.SQRT2_PRECOMPUTE_THRESHOLD + 1), FLOOR),
BigIntegerMath.SQRT2_PRECOMPUTED_BITS);
}
-
+
public void testIsPowerOfTwo() {
for (BigInteger x : ALL_BIGINTEGER_CANDIDATES) {
// Checks for a single bit set.
@@ -76,11 +74,13 @@ public class BigIntegerMathTest extends TestCase {
}
public void testLog2NegativeAlwaysThrows() {
- for (RoundingMode mode : ALL_ROUNDING_MODES) {
- try {
- BigIntegerMath.log2(BigInteger.valueOf(-1), mode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
+ for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
+ for (RoundingMode mode : ALL_ROUNDING_MODES) {
+ try {
+ BigIntegerMath.log2(x.negate(), mode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
}
}
@@ -151,7 +151,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10ZeroAlwaysThrows() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
try {
@@ -161,17 +160,17 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10NegativeAlwaysThrows() {
- for (RoundingMode mode : ALL_ROUNDING_MODES) {
- try {
- BigIntegerMath.log10(BigInteger.valueOf(-1), mode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
+ for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
+ for (RoundingMode mode : ALL_ROUNDING_MODES) {
+ try {
+ BigIntegerMath.log10(x.negate(), mode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
}
}
- @GwtIncompatible("TODO")
public void testLog10Floor() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(FLOOR, DOWN)) {
@@ -182,7 +181,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10Ceiling() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(CEILING, UP)) {
@@ -194,7 +192,6 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of log10(BigInteger, FLOOR).
- @GwtIncompatible("TODO")
public void testLog10Exact() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int logFloor = BigIntegerMath.log10(x, FLOOR);
@@ -208,7 +205,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10HalfUp() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int result = BigIntegerMath.log10(x, HALF_UP);
@@ -220,7 +216,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10HalfDown() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int result = BigIntegerMath.log10(x, HALF_DOWN);
@@ -233,7 +228,6 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of log10(BigInteger, {HALF_UP,HALF_DOWN}).
- @GwtIncompatible("TODO")
public void testLog10HalfEven() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int halfEven = BigIntegerMath.log10(x, HALF_EVEN);
@@ -244,7 +238,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10TrivialOnPowerOf10() {
BigInteger x = BigInteger.TEN.pow(100);
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -252,24 +245,23 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testSqrtZeroAlwaysZero() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
assertEquals(ZERO, BigIntegerMath.sqrt(ZERO, mode));
}
}
- @GwtIncompatible("TODO")
public void testSqrtNegativeAlwaysThrows() {
- for (RoundingMode mode : ALL_ROUNDING_MODES) {
- try {
- BigIntegerMath.sqrt(BigInteger.valueOf(-1), mode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
+ for (BigInteger x : NEGATIVE_BIGINTEGER_CANDIDATES) {
+ for (RoundingMode mode : ALL_ROUNDING_MODES) {
+ try {
+ BigIntegerMath.sqrt(x, mode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
}
}
- @GwtIncompatible("TODO")
public void testSqrtFloor() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(FLOOR, DOWN)) {
@@ -281,7 +273,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testSqrtCeiling() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(CEILING, UP)) {
@@ -294,7 +285,6 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of sqrt(BigInteger, FLOOR).
- @GwtIncompatible("TODO")
public void testSqrtExact() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger floor = BigIntegerMath.sqrt(x, FLOOR);
@@ -309,7 +299,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testSqrtHalfUp() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger result = BigIntegerMath.sqrt(x, HALF_UP);
@@ -325,7 +314,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testSqrtHalfDown() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger result = BigIntegerMath.sqrt(x, HALF_DOWN);
@@ -342,7 +330,6 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of sqrt(BigInteger, {HALF_UP,HALF_DOWN}).
- @GwtIncompatible("TODO")
public void testSqrtHalfEven() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger halfEven = BigIntegerMath.sqrt(x, HALF_EVEN);
@@ -353,7 +340,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testDivNonZero() {
for (BigInteger p : NONZERO_BIGINTEGER_CANDIDATES) {
for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
@@ -366,7 +352,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testDivNonZeroExact() {
for (BigInteger p : NONZERO_BIGINTEGER_CANDIDATES) {
for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
@@ -382,7 +367,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testZeroDivIsAlwaysZero() {
for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -391,7 +375,6 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testDivByZeroAlwaysFails() {
for (BigInteger p : ALL_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -405,7 +388,7 @@ public class BigIntegerMathTest extends TestCase {
public void testFactorial() {
BigInteger expected = BigInteger.ONE;
- for (int i = 1; i <= 200; i++) {
+ for (int i = 1; i <= 300; i++) {
expected = expected.multiply(BigInteger.valueOf(i));
assertEquals(expected, BigIntegerMath.factorial(i));
}
@@ -416,24 +399,17 @@ public class BigIntegerMathTest extends TestCase {
}
public void testFactorialNegative() {
- try {
- BigIntegerMath.factorial(-1);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testBinomialSmall() {
- runBinomialTest(0, 30);
- }
-
- @GwtIncompatible("too slow")
- public void testBinomialLarge() {
- runBinomialTest(31, 100);
+ for (int n : NEGATIVE_INTEGER_CANDIDATES) {
+ try {
+ BigIntegerMath.factorial(n);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
}
-
+
// Depends on the correctness of BigIntegerMath.factorial
- private static void runBinomialTest(int firstN, int lastN) {
- for (int n = firstN; n <= lastN; n++) {
+ public void testBinomial() {
+ for (int n = 0; n <= 50; n++) {
for (int k = 0; k <= n; k++) {
BigInteger expected = BigIntegerMath
.factorial(n)
@@ -457,10 +433,10 @@ public class BigIntegerMathTest extends TestCase {
}
}
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.setDefault(BigInteger.class, ONE);
+ tester.setDefault(RoundingMode.class, FLOOR);
tester.setDefault(int.class, 1);
tester.setDefault(long.class, 1L);
tester.testAllPublicStaticMethods(BigIntegerMath.class);
diff --git a/guava-tests/test/com/google/common/math/DoubleMathTest.java b/guava-tests/test/com/google/common/math/DoubleMathTest.java
index b2f9418..9fe6d90 100644
--- a/guava-tests/test/com/google/common/math/DoubleMathTest.java
+++ b/guava-tests/test/com/google/common/math/DoubleMathTest.java
@@ -16,11 +16,9 @@
package com.google.common.math;
-import static com.google.common.math.MathTesting.*;
import static com.google.common.math.MathTesting.ALL_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
import static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
-import static com.google.common.math.MathTesting.FINITE_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.FRACTIONAL_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.INTEGRAL_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
@@ -35,9 +33,6 @@ import static java.math.RoundingMode.UNNECESSARY;
import static java.math.RoundingMode.UP;
import static java.util.Arrays.asList;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.primitives.Doubles;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -46,7 +41,6 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Arrays;
-import java.util.List;
/**
* Tests for {@code DoubleMath}.
@@ -61,7 +55,7 @@ public class DoubleMathTest extends TestCase {
private static final BigDecimal MAX_LONG_AS_BIG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
private static final BigDecimal MIN_LONG_AS_BIG_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE);
- public void testConstantsMaxFactorial() {
+ public void testConstantsMaxFactorial(){
BigInteger MAX_DOUBLE_VALUE = BigDecimal.valueOf(Double.MAX_VALUE).toBigInteger();
assertTrue(BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL).compareTo(MAX_DOUBLE_VALUE) <= 0);
assertTrue(
@@ -71,10 +65,10 @@ public class DoubleMathTest extends TestCase {
public void testConstantsEverySixteenthFactorial() {
for (int i = 0, n = 0; n <= DoubleMath.MAX_FACTORIAL; i++, n += 16) {
assertEquals(
- BigIntegerMath.factorial(n).doubleValue(), DoubleMath.everySixteenthFactorial[i]);
+ BigIntegerMath.factorial(n).doubleValue(), DoubleMath.EVERY_SIXTEENTH_FACTORIAL[i]);
}
}
-
+
public void testRoundIntegralDoubleToInt() {
for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -356,19 +350,6 @@ public class DoubleMathTest extends TestCase {
}
}
- public void testRoundLog2Exact() {
- for (double x : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
- boolean isPowerOfTwo = StrictMath.pow(2.0, DoubleMath.log2(x, FLOOR)) == x;
- try {
- int log2 = DoubleMath.log2(x, UNNECESSARY);
- assertEquals(x, Math.scalb(1.0, log2));
- assertTrue(isPowerOfTwo);
- } catch (ArithmeticException e) {
- assertFalse(isPowerOfTwo);
- }
- }
- }
-
public void testRoundLog2ThrowsOnZerosInfinitiesAndNaN() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
for (double d :
@@ -414,12 +395,12 @@ public class DoubleMathTest extends TestCase {
}
}
- public void testLog2SemiMonotonic() {
+ public void testLog2SemiMonotonic(){
for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
assertTrue(DoubleMath.log2(d + 0.01) >= DoubleMath.log2(d));
}
}
-
+
public void testLog2Negative() {
for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
assertTrue(Double.isNaN(DoubleMath.log2(-d)));
@@ -494,120 +475,10 @@ public class DoubleMathTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
}
-
- private static final ImmutableList<Double> FINITE_TOLERANCE_CANDIDATES =
- ImmutableList.of(-0.0, 0.0, 1.0, 100.0, 10000.0, Double.MAX_VALUE);
-
- private static final Iterable<Double> TOLERANCE_CANDIDATES =
- Iterables.concat(FINITE_TOLERANCE_CANDIDATES, ImmutableList.of(Double.POSITIVE_INFINITY));
-
- private static final List<Double> BAD_TOLERANCE_CANDIDATES =
- Doubles.asList(-Double.MIN_VALUE, -Double.MIN_NORMAL, -1, -20, Double.NaN,
- Double.NEGATIVE_INFINITY, -0.001);
-
- public void testFuzzyEqualsFinite() {
- for (double a : FINITE_DOUBLE_CANDIDATES) {
- for (double b : FINITE_DOUBLE_CANDIDATES) {
- for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
- assertEquals(
- Math.abs(a - b) <= tolerance,
- DoubleMath.fuzzyEquals(a, b, tolerance));
- }
- }
- }
- }
-
- public void testFuzzyInfiniteVersusFiniteWithFiniteTolerance() {
- for (double inf : INFINITIES) {
- for (double a : FINITE_DOUBLE_CANDIDATES) {
- for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
- assertFalse(DoubleMath.fuzzyEquals(a, inf, tolerance));
- assertFalse(DoubleMath.fuzzyEquals(inf, a, tolerance));
- }
- }
- }
- }
-
- public void testFuzzyInfiniteVersusInfiniteWithFiniteTolerance() {
- for (double inf : INFINITIES) {
- for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
- assertTrue(DoubleMath.fuzzyEquals(inf, inf, tolerance));
- assertFalse(DoubleMath.fuzzyEquals(inf, -inf, tolerance));
- }
- }
- }
-
- public void testFuzzyEqualsInfiniteTolerance() {
- for (double a : DOUBLE_CANDIDATES_EXCEPT_NAN) {
- for (double b : DOUBLE_CANDIDATES_EXCEPT_NAN) {
- assertTrue(DoubleMath.fuzzyEquals(a, b, Double.POSITIVE_INFINITY));
- }
- }
- }
-
- public void testFuzzyEqualsOneNaN() {
- for (double a : DOUBLE_CANDIDATES_EXCEPT_NAN) {
- for (double tolerance : TOLERANCE_CANDIDATES) {
- assertFalse(DoubleMath.fuzzyEquals(a, Double.NaN, tolerance));
- assertFalse(DoubleMath.fuzzyEquals(Double.NaN, a, tolerance));
- }
- }
- }
-
- public void testFuzzyEqualsTwoNaNs() {
- for (double tolerance : TOLERANCE_CANDIDATES) {
- assertTrue(DoubleMath.fuzzyEquals(Double.NaN, Double.NaN, tolerance));
- }
- }
-
- public void testFuzzyEqualsZeroTolerance() {
- // make sure we test -0 tolerance
- for (double zero : Doubles.asList(0.0, -0.0)) {
- for (double a : ALL_DOUBLE_CANDIDATES) {
- for (double b : ALL_DOUBLE_CANDIDATES) {
- assertEquals(a == b || (Double.isNaN(a) && Double.isNaN(b)),
- DoubleMath.fuzzyEquals(a, b, zero));
- }
- }
- }
- }
-
- public void testFuzzyEqualsBadTolerance() {
- for (double tolerance : BAD_TOLERANCE_CANDIDATES) {
- try {
- DoubleMath.fuzzyEquals(1, 2, tolerance);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- }
- }
-
- public void testFuzzyCompare() {
- for (double a : ALL_DOUBLE_CANDIDATES) {
- for (double b : ALL_DOUBLE_CANDIDATES) {
- for (double tolerance : TOLERANCE_CANDIDATES) {
- int expected = DoubleMath.fuzzyEquals(a, b, tolerance) ? 0 : Double.compare(a, b);
- int actual = DoubleMath.fuzzyCompare(a, b, tolerance);
- assertEquals(Integer.signum(expected), Integer.signum(actual));
- }
- }
- }
- }
-
- public void testFuzzyCompareBadTolerance() {
- for (double tolerance : BAD_TOLERANCE_CANDIDATES) {
- try {
- DoubleMath.fuzzyCompare(1, 2, tolerance);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- // success
- }
- }
- }
-
- public void testNullPointers() {
+
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(RoundingMode.class, FLOOR);
tester.setDefault(double.class, 3.0);
tester.testAllPublicStaticMethods(DoubleMath.class);
}
diff --git a/guava-tests/test/com/google/common/math/DoubleUtilsTest.java b/guava-tests/test/com/google/common/math/DoubleUtilsTest.java
index 65952aa..f2f99a7 100644
--- a/guava-tests/test/com/google/common/math/DoubleUtilsTest.java
+++ b/guava-tests/test/com/google/common/math/DoubleUtilsTest.java
@@ -1,40 +1,39 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package com.google.common.math;
import static com.google.common.math.MathTesting.ALL_BIGINTEGER_CANDIDATES;
+import static com.google.common.math.MathTesting.ALL_DOUBLE_CANDIDATES;
+import static com.google.common.math.MathTesting.EXPONENTS;
import static com.google.common.math.MathTesting.FINITE_DOUBLE_CANDIDATES;
-import static com.google.common.math.MathTesting.POSITIVE_FINITE_DOUBLE_CANDIDATES;
-import junit.framework.TestCase;
+import java.math.BigInteger;
+import junit.framework.TestCase;
import sun.misc.FpUtils;
-import java.math.BigInteger;
-
-/**
- * Tests for {@link DoubleUtils}.
- *
- * @author Louis Wasserman
- */
public class DoubleUtilsTest extends TestCase {
+ public strictfp void testScalbPositiveExponent() {
+ for (int k : EXPONENTS) {
+ for (double d : ALL_DOUBLE_CANDIDATES) {
+ assertEquals(d * StrictMath.pow(2.0, k), DoubleUtils.scalb(d, k));
+ }
+ }
+ }
+
+ public void testGetExponent() {
+ for (double d : ALL_DOUBLE_CANDIDATES) {
+ assertEquals(FpUtils.getExponent(d), DoubleUtils.getExponent(d));
+ }
+ }
+
+ public void testNextUp() {
+ for (double d : FINITE_DOUBLE_CANDIDATES) {
+ assertEquals(FpUtils.nextUp(d), DoubleUtils.next(d, true));
+ }
+ }
+
public void testNextDown() {
for (double d : FINITE_DOUBLE_CANDIDATES) {
- assertEquals(FpUtils.nextDown(d), DoubleUtils.nextDown(d));
+ assertEquals(FpUtils.nextDown(d), DoubleUtils.next(d, false));
}
}
@@ -43,19 +42,4 @@ public class DoubleUtilsTest extends TestCase {
assertEquals(b.doubleValue(), DoubleUtils.bigToDouble(b));
}
}
-
- public void testEnsureNonNegative() {
- assertEquals(0.0, DoubleUtils.ensureNonNegative(0.0));
- for (double positiveValue : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
- assertEquals(positiveValue, DoubleUtils.ensureNonNegative(positiveValue));
- assertEquals(0.0, DoubleUtils.ensureNonNegative(-positiveValue));
- }
- assertEquals(Double.POSITIVE_INFINITY, DoubleUtils.ensureNonNegative(Double.POSITIVE_INFINITY));
- assertEquals(0.0, DoubleUtils.ensureNonNegative(Double.NEGATIVE_INFINITY));
- try {
- DoubleUtils.ensureNonNegative(Double.NaN);
- fail("Expected IllegalArgumentException from ensureNonNegative(Double.NaN)");
- } catch (IllegalArgumentException expected) {
- }
- }
}
diff --git a/guava-tests/test/com/google/common/math/IntMathTest.java b/guava-tests/test/com/google/common/math/IntMathTest.java
index dcfd8a9..7f773ea 100644
--- a/guava-tests/test/com/google/common/math/IntMathTest.java
+++ b/guava-tests/test/com/google/common/math/IntMathTest.java
@@ -23,7 +23,6 @@ import static com.google.common.math.MathTesting.EXPONENTS;
import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.NONZERO_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.POSITIVE_INTEGER_CANDIDATES;
-import static com.google.common.math.TestPlatform.intsCanGoOutOfRange;
import static java.math.BigInteger.valueOf;
import static java.math.RoundingMode.FLOOR;
import static java.math.RoundingMode.UNNECESSARY;
@@ -54,58 +53,48 @@ public class IntMathTest extends TestCase {
@GwtIncompatible("pow()")
public void testConstantsPowersOf10() {
- for (int i = 0; i < IntMath.powersOf10.length - 1; i++) {
- assertEquals(IntMath.pow(10, i), IntMath.powersOf10[i]);
- }
- }
-
- @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
- public void testMaxLog10ForLeadingZeros() {
- for (int i = 0; i < Integer.SIZE; i++) {
- assertEquals(
- BigIntegerMath.log10(BigInteger.ONE.shiftLeft(Integer.SIZE - i), FLOOR),
- IntMath.maxLog10ForLeadingZeros[i]);
+ for (int i = 0; i < IntMath.POWERS_OF_10.length; i++) {
+ assertEquals(IntMath.pow(10, i), IntMath.POWERS_OF_10[i]);
}
}
@GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
public void testConstantsHalfPowersOf10() {
- for (int i = 0; i < IntMath.halfPowersOf10.length; i++) {
- assert IntMath.halfPowersOf10[i]
+ for (int i = 0; i < IntMath.HALF_POWERS_OF_10.length; i++) {
+ assert IntMath.HALF_POWERS_OF_10[i]
== Math.min(Integer.MAX_VALUE,
BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR).longValue());
}
}
@GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
- public void testConstantsBiggestBinomials() {
- for (int k = 0; k < IntMath.biggestBinomials.length; k++) {
- assertTrue(fitsInInt(BigIntegerMath.binomial(IntMath.biggestBinomials[k], k)));
- assertTrue(IntMath.biggestBinomials[k] == Integer.MAX_VALUE
- || !fitsInInt(BigIntegerMath.binomial(IntMath.biggestBinomials[k] + 1, k)));
+ public void testConstantsBiggestBinomials(){
+ for (int k = 0; k < IntMath.BIGGEST_BINOMIALS.length; k++) {
+ assertTrue(fitsInInt(BigIntegerMath.binomial(IntMath.BIGGEST_BINOMIALS[k], k)));
+ assertTrue(IntMath.BIGGEST_BINOMIALS[k] == Integer.MAX_VALUE
+ || !fitsInInt(BigIntegerMath.binomial(IntMath.BIGGEST_BINOMIALS[k] + 1, k)));
// In the first case, any int is valid; in the second, we want to test that the next-bigger
// int overflows.
}
assertFalse(
fitsInInt(BigIntegerMath.binomial(
- 2 * IntMath.biggestBinomials.length, IntMath.biggestBinomials.length)));
+ 2 * IntMath.BIGGEST_BINOMIALS.length, IntMath.BIGGEST_BINOMIALS.length)));
}
-
+
@GwtIncompatible("sqrt")
public void testPowersSqrtMaxInt() {
assertEquals(IntMath.sqrt(Integer.MAX_VALUE, FLOOR), IntMath.FLOOR_SQRT_MAX_INT);
}
- @GwtIncompatible("java.math.BigInteger")
public void testIsPowerOfTwo() {
for (int x : ALL_INTEGER_CANDIDATES) {
// Checks for a single bit set.
- BigInteger bigX = BigInteger.valueOf(x);
- boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
+ boolean expected = x > 0 & (x & (x - 1)) == 0;
assertEquals(expected, IntMath.isPowerOfTwo(x));
}
}
+ @GwtIncompatible("log2")
public void testLog2ZeroAlwaysThrows() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
try {
@@ -115,6 +104,7 @@ public class IntMathTest extends TestCase {
}
}
+ @GwtIncompatible("log2")
public void testLog2NegativeAlwaysThrows() {
for (int x : NEGATIVE_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -127,6 +117,7 @@ public class IntMathTest extends TestCase {
}
// Relies on the correctness of BigIntegrerMath.log2 for all modes except UNNECESSARY.
+ @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
public void testLog2MatchesBigInteger() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -136,6 +127,7 @@ public class IntMathTest extends TestCase {
}
// Relies on the correctness of isPowerOfTwo(int).
+ @GwtIncompatible("log2")
public void testLog2Exact() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
// We only expect an exception if x was not a power of 2.
@@ -263,41 +255,36 @@ public class IntMathTest extends TestCase {
}
}
+ @GwtIncompatible("-2147483648/1 expected=2147483648")
public void testDivNonZero() {
for (int p : NONZERO_INTEGER_CANDIDATES) {
for (int q : NONZERO_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
- // Skip some tests that fail due to GWT's non-compliant int implementation.
- // TODO(cpovirk): does this test fail for only some rounding modes or for all?
- if (p == -2147483648 && q == -1 && intsCanGoOutOfRange()) {
- continue;
- }
int expected =
new BigDecimal(valueOf(p)).divide(new BigDecimal(valueOf(q)), 0, mode).intValue();
- assertEquals(p + "/" + q, force32(expected), IntMath.divide(p, q, mode));
+ assertEquals(p + "/" + q, expected, IntMath.divide(p, q, mode));
}
}
}
}
+ @GwtIncompatible("-2147483648/-1 not expected to divide evenly")
public void testDivNonZeroExact() {
for (int p : NONZERO_INTEGER_CANDIDATES) {
for (int q : NONZERO_INTEGER_CANDIDATES) {
- // Skip some tests that fail due to GWT's non-compliant int implementation.
- if (p == -2147483648 && q == -1 && intsCanGoOutOfRange()) {
- continue;
- }
boolean dividesEvenly = (p % q) == 0;
+
try {
assertEquals(p + "/" + q, p, IntMath.divide(p, q, UNNECESSARY) * q);
- assertTrue(p + "/" + q + " not expected to divide evenly", dividesEvenly);
+ assertTrue(p + "/" + q + " expected to divide evenly", dividesEvenly);
} catch (ArithmeticException e) {
- assertFalse(p + "/" + q + " expected to divide evenly", dividesEvenly);
+ assertFalse(p + "/" + q + " not expected to divide evenly", dividesEvenly);
}
}
}
}
+ @GwtIncompatible("pow()")
public void testZeroDivIsAlwaysZero() {
for (int q : NONZERO_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -306,6 +293,7 @@ public class IntMathTest extends TestCase {
}
}
+ @GwtIncompatible("pow()")
public void testDivByZeroAlwaysFails() {
for (int p : ALL_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -432,13 +420,14 @@ public class IntMathTest extends TestCase {
}
}
+ @GwtIncompatible("-2147483648^1 expected=2147483648")
public void testCheckedPow() {
for (int b : ALL_INTEGER_CANDIDATES) {
for (int k : EXPONENTS) {
BigInteger expectedResult = valueOf(b).pow(k);
boolean expectedSuccess = fitsInInt(expectedResult);
try {
- assertEquals(b + "^" + k, force32(expectedResult.intValue()), IntMath.checkedPow(b, k));
+ assertEquals(b + "^" + k, expectedResult.intValue(), IntMath.checkedPow(b, k));
assertTrue(b + "^" + k + " should have succeeded", expectedSuccess);
} catch (ArithmeticException e) {
assertFalse(b + "^" + k + " should have failed", expectedSuccess);
@@ -448,6 +437,7 @@ public class IntMathTest extends TestCase {
}
// Depends on the correctness of BigIntegerMath.factorial.
+ @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
public void testFactorial() {
for (int n = 0; n <= 50; n++) {
BigInteger expectedBig = BigIntegerMath.factorial(n);
@@ -456,6 +446,7 @@ public class IntMathTest extends TestCase {
}
}
+ @GwtIncompatible("factorial")
public void testFactorialNegative() {
for (int n : NEGATIVE_INTEGER_CANDIDATES) {
try {
@@ -501,87 +492,15 @@ public class IntMathTest extends TestCase {
}
}
- @GwtIncompatible("java.math.BigInteger")
- public void testMean() {
- // Odd-sized ranges have an obvious mean
- assertMean(2, 1, 3);
-
- assertMean(-2, -3, -1);
- assertMean(0, -1, 1);
- assertMean(1, -1, 3);
- assertMean((1 << 30) - 1, -1, Integer.MAX_VALUE);
-
- // Even-sized ranges should prefer the lower mean
- assertMean(2, 1, 4);
- assertMean(-3, -4, -1);
- assertMean(0, -1, 2);
- assertMean(0, Integer.MIN_VALUE + 2, Integer.MAX_VALUE);
- assertMean(0, 0, 1);
- assertMean(-1, -1, 0);
- assertMean(-1, Integer.MIN_VALUE, Integer.MAX_VALUE);
-
- // x == y == mean
- assertMean(1, 1, 1);
- assertMean(0, 0, 0);
- assertMean(-1, -1, -1);
- assertMean(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
- assertMean(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
-
- // Exhaustive checks
- for (int x : ALL_INTEGER_CANDIDATES) {
- for (int y : ALL_INTEGER_CANDIDATES) {
- assertMean(x, y);
- }
- }
- }
-
- /**
- * Helper method that asserts the arithmetic mean of x and y is equal
- * to the expectedMean.
- */
- private static void assertMean(int expectedMean, int x, int y) {
- assertEquals("The expectedMean should be the same as computeMeanSafely",
- expectedMean, computeMeanSafely(x, y));
- assertMean(x, y);
- }
-
- /**
- * Helper method that asserts the arithmetic mean of x and y is equal
- * to the result of computeMeanSafely.
- */
- private static void assertMean(int x, int y) {
- int expectedMean = computeMeanSafely(x, y);
- assertEquals(expectedMean, IntMath.mean(x, y));
- assertEquals("The mean of x and y should equal the mean of y and x",
- expectedMean, IntMath.mean(y, x));
- }
-
- /**
- * Computes the mean in a way that is obvious and resilient to
- * overflow by using BigInteger arithmetic.
- */
- private static int computeMeanSafely(int x, int y) {
- BigInteger bigX = BigInteger.valueOf(x);
- BigInteger bigY = BigInteger.valueOf(y);
- BigDecimal bigMean = new BigDecimal(bigX.add(bigY))
- .divide(BigDecimal.valueOf(2), BigDecimal.ROUND_FLOOR);
- // parseInt blows up on overflow as opposed to intValue() which does not.
- return Integer.parseInt(bigMean.toString());
- }
-
- private static boolean fitsInInt(BigInteger big) {
+ private boolean fitsInInt(BigInteger big) {
return big.bitLength() <= 31;
}
-
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.setDefault(int.class, 1);
+ tester.setDefault(RoundingMode.class, FLOOR);
tester.testAllPublicStaticMethods(IntMath.class);
}
-
- private static int force32(int value) {
- // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
- return value & 0xffffffff;
- }
}
diff --git a/guava-tests/test/com/google/common/math/LongMathTest.java b/guava-tests/test/com/google/common/math/LongMathTest.java
index 089bf03..3ab0a8e 100644
--- a/guava-tests/test/com/google/common/math/LongMathTest.java
+++ b/guava-tests/test/com/google/common/math/LongMathTest.java
@@ -30,8 +30,6 @@ import static java.math.BigInteger.valueOf;
import static java.math.RoundingMode.FLOOR;
import static java.math.RoundingMode.UNNECESSARY;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -45,92 +43,75 @@ import java.math.RoundingMode;
*
* @author Louis Wasserman
*/
-@GwtCompatible(emulated = true)
public class LongMathTest extends TestCase {
- @GwtIncompatible("TODO")
public void testConstantMaxPowerOfSqrt2Unsigned() {
assertEquals(BigIntegerMath.sqrt(BigInteger.ZERO.setBit(2 * Long.SIZE - 1), FLOOR).longValue(),
LongMath.MAX_POWER_OF_SQRT2_UNSIGNED);
}
- @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
- public void testMaxLog10ForLeadingZeros() {
- for (int i = 0; i < Long.SIZE; i++) {
- assertEquals(
- BigIntegerMath.log10(BigInteger.ONE.shiftLeft(Long.SIZE - i), FLOOR),
- LongMath.maxLog10ForLeadingZeros[i]);
- }
- }
-
- @GwtIncompatible("TODO")
public void testConstantsPowersOf10() {
- for (int i = 0; i < LongMath.powersOf10.length; i++) {
- assertEquals(LongMath.checkedPow(10, i), LongMath.powersOf10[i]);
+ for (int i = 0; i < LongMath.POWERS_OF_10.length; i++) {
+ assertEquals(LongMath.checkedPow(10, i), LongMath.POWERS_OF_10[i]);
}
try {
- LongMath.checkedPow(10, LongMath.powersOf10.length);
+ LongMath.checkedPow(10, LongMath.POWERS_OF_10.length);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
- @GwtIncompatible("TODO")
public void testConstantsHalfPowersOf10() {
- for (int i = 0; i < LongMath.halfPowersOf10.length; i++) {
+ for (int i = 0; i < LongMath.HALF_POWERS_OF_10.length; i++) {
assertEquals(BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR),
- BigInteger.valueOf(LongMath.halfPowersOf10[i]));
+ BigInteger.valueOf(LongMath.HALF_POWERS_OF_10[i]));
}
BigInteger nextBigger =
- BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * LongMath.halfPowersOf10.length + 1), FLOOR);
+ BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * LongMath.HALF_POWERS_OF_10.length + 1), FLOOR);
assertTrue(nextBigger.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0);
}
- @GwtIncompatible("TODO")
public void testConstantsSqrtMaxLong() {
assertEquals(LongMath.sqrt(Long.MAX_VALUE, FLOOR), LongMath.FLOOR_SQRT_MAX_LONG);
}
- @GwtIncompatible("TODO")
public void testConstantsFactorials() {
long expected = 1;
- for (int i = 0; i < LongMath.factorials.length; i++, expected *= i) {
- assertEquals(expected, LongMath.factorials[i]);
+ for (int i = 0; i < LongMath.FACTORIALS.length; i++, expected *= i) {
+ assertEquals(expected, LongMath.FACTORIALS[i]);
}
try {
LongMath.checkedMultiply(
- LongMath.factorials[LongMath.factorials.length - 1], LongMath.factorials.length);
+ LongMath.FACTORIALS[LongMath.FACTORIALS.length - 1], LongMath.FACTORIALS.length);
fail("Expected ArithmeticException");
} catch (ArithmeticException expect) {}
}
- @GwtIncompatible("TODO")
public void testConstantsBiggestBinomials() {
- for (int k = 0; k < LongMath.biggestBinomials.length; k++) {
- assertTrue(fitsInLong(BigIntegerMath.binomial(LongMath.biggestBinomials[k], k)));
- assertTrue(LongMath.biggestBinomials[k] == Integer.MAX_VALUE
- || !fitsInLong(BigIntegerMath.binomial(LongMath.biggestBinomials[k] + 1, k)));
+ for (int k = 0; k < LongMath.BIGGEST_BINOMIALS.length; k++) {
+ assertTrue(fitsInLong(BigIntegerMath.binomial(LongMath.BIGGEST_BINOMIALS[k], k)));
+ assertTrue(LongMath.BIGGEST_BINOMIALS[k] == Integer.MAX_VALUE
+ || !fitsInLong(BigIntegerMath.binomial(LongMath.BIGGEST_BINOMIALS[k] + 1, k)));
// In the first case, any long is valid; in the second, we want to test that the next-bigger
// long overflows.
}
- int k = LongMath.biggestBinomials.length;
+ int k = LongMath.BIGGEST_BINOMIALS.length;
assertFalse(fitsInLong(BigIntegerMath.binomial(2 * k, k)));
// 2 * k is the smallest value for which we don't replace k with (n-k).
}
- @GwtIncompatible("TODO")
public void testConstantsBiggestSimpleBinomials() {
- for (int k = 0; k < LongMath.biggestSimpleBinomials.length; k++) {
- assertTrue(LongMath.biggestSimpleBinomials[k] <= LongMath.biggestBinomials[k]);
- simpleBinomial(LongMath.biggestSimpleBinomials[k], k); // mustn't throw
- if (LongMath.biggestSimpleBinomials[k] < Integer.MAX_VALUE) {
+ for (int k = 0; k < LongMath.BIGGEST_SIMPLE_BINOMIALS.length; k++) {
+ assertTrue(LongMath.BIGGEST_SIMPLE_BINOMIALS[k] <= LongMath.BIGGEST_BINOMIALS[k]);
+ simpleBinomial(LongMath.BIGGEST_SIMPLE_BINOMIALS[k], k); // mustn't throw
+ if (LongMath.BIGGEST_SIMPLE_BINOMIALS[k] < Integer.MAX_VALUE) {
// unless all n are fair game with this k
try {
- simpleBinomial(LongMath.biggestSimpleBinomials[k] + 1, k);
+ simpleBinomial(LongMath.BIGGEST_SIMPLE_BINOMIALS[k] + 1, k);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
}
try {
- int k = LongMath.biggestSimpleBinomials.length;
+ int k = LongMath.BIGGEST_SIMPLE_BINOMIALS.length;
simpleBinomial(2 * k, k);
// 2 * k is the smallest value for which we don't replace k with (n-k).
fail("Expected ArithmeticException");
@@ -138,7 +119,6 @@ public class LongMathTest extends TestCase {
}
// Throws an ArithmeticException if "the simple implementation" of binomial coefficients overflows
- @GwtIncompatible("TODO")
private long simpleBinomial(int n, int k) {
long accum = 1;
for (int i = 0; i < k; i++) {
@@ -148,12 +128,10 @@ public class LongMathTest extends TestCase {
return accum;
}
- @GwtIncompatible("java.math.BigInteger")
public void testIsPowerOfTwo() {
for (long x : ALL_LONG_CANDIDATES) {
// Checks for a single bit set.
- BigInteger bigX = BigInteger.valueOf(x);
- boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
+ boolean expected = x > 0 & (x & (x - 1)) == 0L;
assertEquals(expected, LongMath.isPowerOfTwo(x));
}
}
@@ -202,7 +180,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10ZeroAlwaysThrows() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
try {
@@ -212,7 +189,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10NegativeAlwaysThrows() {
for (long x : NEGATIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -225,7 +201,6 @@ public class LongMathTest extends TestCase {
}
// Relies on the correctness of BigIntegerMath.log10 for all modes except UNNECESSARY.
- @GwtIncompatible("TODO")
public void testLog10MatchesBigInteger() {
for (long x : POSITIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -235,7 +210,6 @@ public class LongMathTest extends TestCase {
}
// Relies on the correctness of log10(long, FLOOR) and of pow(long, int).
- @GwtIncompatible("TODO")
public void testLog10Exact() {
for (long x : POSITIVE_LONG_CANDIDATES) {
int floor = LongMath.log10(x, FLOOR);
@@ -249,7 +223,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testLog10TrivialOnPowerOf10() {
long x = 1000000000000L;
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -257,7 +230,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testSqrtNegativeAlwaysThrows() {
for (long x : NEGATIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -270,7 +242,6 @@ public class LongMathTest extends TestCase {
}
// Relies on the correctness of BigIntegerMath.sqrt for all modes except UNNECESSARY.
- @GwtIncompatible("TODO")
public void testSqrtMatchesBigInteger() {
for (long x : POSITIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -282,7 +253,6 @@ public class LongMathTest extends TestCase {
}
/* Relies on the correctness of sqrt(long, FLOOR). */
- @GwtIncompatible("TODO")
public void testSqrtExactMatchesFloorOrThrows() {
for (long x : POSITIVE_LONG_CANDIDATES) {
long logFloor = LongMath.sqrt(x, FLOOR);
@@ -297,7 +267,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testPow() {
for (long i : ALL_LONG_CANDIDATES) {
for (int exp : EXPONENTS) {
@@ -308,7 +277,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testDivNonZero() {
for (long p : NONZERO_LONG_CANDIDATES) {
for (long q : NONZERO_LONG_CANDIDATES) {
@@ -321,7 +289,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testDivNonZeroExact() {
for (long p : NONZERO_LONG_CANDIDATES) {
for (long q : NONZERO_LONG_CANDIDATES) {
@@ -337,7 +304,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testZeroDivIsAlwaysZero() {
for (long q : NONZERO_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -346,7 +312,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testDivByZeroAlwaysFails() {
for (long p : ALL_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -358,7 +323,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testIntMod() {
for (long x : ALL_LONG_CANDIDATES) {
for (int m : POSITIVE_INTEGER_CANDIDATES) {
@@ -369,7 +333,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testIntModNegativeModulusFails() {
for (long x : ALL_LONG_CANDIDATES) {
for (int m : NEGATIVE_INTEGER_CANDIDATES) {
@@ -381,7 +344,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testIntModZeroModulusFails() {
for (long x : ALL_LONG_CANDIDATES) {
try {
@@ -391,7 +353,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testMod() {
for (long x : ALL_LONG_CANDIDATES) {
for (long m : POSITIVE_LONG_CANDIDATES) {
@@ -402,7 +363,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testModNegativeModulusFails() {
for (long x : ALL_LONG_CANDIDATES) {
for (long m : NEGATIVE_LONG_CANDIDATES) {
@@ -414,7 +374,7 @@ public class LongMathTest extends TestCase {
}
}
- public void testGCDExhaustive() {
+ public void testGCD() {
for (long a : POSITIVE_LONG_CANDIDATES) {
for (long b : POSITIVE_LONG_CANDIDATES) {
assertEquals(valueOf(a).gcd(valueOf(b)), valueOf(LongMath.gcd(a, b)));
@@ -422,7 +382,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testGCDZero() {
for (long a : POSITIVE_LONG_CANDIDATES) {
assertEquals(a, LongMath.gcd(a, 0));
@@ -431,7 +390,6 @@ public class LongMathTest extends TestCase {
assertEquals(0, LongMath.gcd(0, 0));
}
- @GwtIncompatible("TODO")
public void testGCDNegativePositiveThrows() {
for (long a : NEGATIVE_LONG_CANDIDATES) {
try {
@@ -445,7 +403,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testGCDNegativeZeroThrows() {
for (long a : NEGATIVE_LONG_CANDIDATES) {
try {
@@ -459,7 +416,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testCheckedAdd() {
for (long a : ALL_INTEGER_CANDIDATES) {
for (long b : ALL_INTEGER_CANDIDATES) {
@@ -475,7 +431,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testCheckedSubtract() {
for (long a : ALL_INTEGER_CANDIDATES) {
for (long b : ALL_INTEGER_CANDIDATES) {
@@ -491,7 +446,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testCheckedMultiply() {
for (long a : ALL_INTEGER_CANDIDATES) {
for (long b : ALL_INTEGER_CANDIDATES) {
@@ -507,7 +461,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testCheckedPow() {
for (long b : ALL_INTEGER_CANDIDATES) {
for (int exp : EXPONENTS) {
@@ -524,7 +477,6 @@ public class LongMathTest extends TestCase {
}
// Depends on the correctness of BigIntegerMath.factorial.
- @GwtIncompatible("TODO")
public void testFactorial() {
for (int n = 0; n <= 50; n++) {
BigInteger expectedBig = BigIntegerMath.factorial(n);
@@ -533,7 +485,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("TODO")
public void testFactorialNegative() {
for (int n : NEGATIVE_INTEGER_CANDIDATES) {
try {
@@ -554,17 +505,6 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("Slow")
- public void testBinomial_exhaustiveNotOverflowing() {
- // Tests all of the inputs to LongMath.binomial that won't cause it to overflow, that weren't
- // tested in the previous method, for k >= 3.
- for (int k = 3; k < LongMath.biggestBinomials.length; k++) {
- for (int n = 70; n <= LongMath.biggestBinomials[k]; n++) {
- assertEquals(BigIntegerMath.binomial(n, k).longValue(), LongMath.binomial(n, k));
- }
- }
- }
-
public void testBinomialOutside() {
for (int n = 0; n <= 50; n++) {
try {
@@ -587,81 +527,13 @@ public class LongMathTest extends TestCase {
}
}
- @GwtIncompatible("java.math.BigInteger")
- public void testMean() {
- // Odd-sized ranges have an obvious mean
- assertMean(2, 1, 3);
-
- assertMean(-2, -3, -1);
- assertMean(0, -1, 1);
- assertMean(1, -1, 3);
- assertMean((1L << 62) - 1, -1, Long.MAX_VALUE);
-
- // Even-sized ranges should prefer the lower mean
- assertMean(2, 1, 4);
- assertMean(-3, -4, -1);
- assertMean(0, -1, 2);
- assertMean(0, Long.MIN_VALUE + 2, Long.MAX_VALUE);
- assertMean(0, 0, 1);
- assertMean(-1, -1, 0);
- assertMean(-1, Long.MIN_VALUE, Long.MAX_VALUE);
-
- // x == y == mean
- assertMean(1, 1, 1);
- assertMean(0, 0, 0);
- assertMean(-1, -1, -1);
- assertMean(Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE);
- assertMean(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE);
-
- // Exhaustive checks
- for (long x : ALL_LONG_CANDIDATES) {
- for (long y : ALL_LONG_CANDIDATES) {
- assertMean(x, y);
- }
- }
- }
-
- /**
- * Helper method that asserts the arithmetic mean of x and y is equal
- * to the expectedMean.
- */
- private static void assertMean(long expectedMean, long x, long y) {
- assertEquals("The expectedMean should be the same as computeMeanSafely",
- expectedMean, computeMeanSafely(x, y));
- assertMean(x, y);
- }
-
- /**
- * Helper method that asserts the arithmetic mean of x and y is equal
- *to the result of computeMeanSafely.
- */
- private static void assertMean(long x, long y) {
- long expectedMean = computeMeanSafely(x, y);
- assertEquals(expectedMean, LongMath.mean(x, y));
- assertEquals("The mean of x and y should equal the mean of y and x",
- expectedMean, LongMath.mean(y, x));
- }
-
- /**
- * Computes the mean in a way that is obvious and resilient to
- * overflow by using BigInteger arithmetic.
- */
- private static long computeMeanSafely(long x, long y) {
- BigInteger bigX = BigInteger.valueOf(x);
- BigInteger bigY = BigInteger.valueOf(y);
- BigDecimal bigMean = new BigDecimal(bigX.add(bigY))
- .divide(BigDecimal.valueOf(2), BigDecimal.ROUND_FLOOR);
- // parseInt blows up on overflow as opposed to intValue() which does not.
- return Long.parseLong(bigMean.toString());
- }
-
- private static boolean fitsInLong(BigInteger big) {
+ private boolean fitsInLong(BigInteger big) {
return big.bitLength() <= 63;
}
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(RoundingMode.class, FLOOR);
tester.setDefault(int.class, 1);
tester.setDefault(long.class, 1L);
tester.testAllPublicStaticMethods(LongMath.class);
diff --git a/guava-tests/test/com/google/common/math/MathBenchmarking.java b/guava-tests/test/com/google/common/math/MathBenchmarking.java
deleted file mode 100644
index 856f995..0000000
--- a/guava-tests/test/com/google/common/math/MathBenchmarking.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import java.math.BigInteger;
-import java.util.Random;
-
-/**
- * Utilities for benchmarks.
- *
- * @author Louis Wasserman
- */
-final class MathBenchmarking {
- static final int ARRAY_SIZE = 0x10000;
- static final int ARRAY_MASK = 0x0ffff;
- static final Random RANDOM_SOURCE = new Random(314159265358979L);
- static final int MAX_EXPONENT = 100;
-
- /*
- * Duplicated from LongMath.
- * binomial(biggestBinomials[k], k) fits in a long, but not
- * binomial(biggestBinomials[k] + 1, k).
- */
- static final int[] biggestBinomials =
- {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 3810779, 121977, 16175, 4337, 1733,
- 887, 534, 361, 265, 206, 169, 143, 125, 111, 101, 94, 88, 83, 79, 76, 74, 72, 70, 69, 68,
- 67, 67, 66, 66, 66, 66};
-
- static BigInteger randomPositiveBigInteger(int numBits) {
- int digits = RANDOM_SOURCE.nextInt(numBits) + 1;
- return new BigInteger(digits, RANDOM_SOURCE).add(BigInteger.ONE);
- }
-
- static BigInteger randomNonNegativeBigInteger(int numBits) {
- int digits = RANDOM_SOURCE.nextInt(numBits) + 1;
- return new BigInteger(digits, RANDOM_SOURCE);
- }
-
- static BigInteger randomNonZeroBigInteger(int numBits) {
- BigInteger result = randomPositiveBigInteger(numBits);
- return RANDOM_SOURCE.nextBoolean() ? result : result.negate();
- }
-
- static BigInteger randomBigInteger(int numBits) {
- BigInteger result = randomNonNegativeBigInteger(numBits);
- return RANDOM_SOURCE.nextBoolean() ? result : result.negate();
- }
-
- static double randomDouble(int maxExponent) {
- double result = RANDOM_SOURCE.nextDouble();
- result = Math.scalb(result, RANDOM_SOURCE.nextInt(maxExponent + 1));
- return RANDOM_SOURCE.nextBoolean() ? result : -result;
- }
-
- /**
- * Returns a random integer between zero and {@code MAX_EXPONENT}.
- */
- static int randomExponent() {
- return RANDOM_SOURCE.nextInt(MAX_EXPONENT + 1);
- }
-
- static double randomPositiveDouble() {
- return Math.exp(randomDouble(6));
- }
-}
diff --git a/guava-tests/test/com/google/common/math/MathPreconditionsTest.java b/guava-tests/test/com/google/common/math/MathPreconditionsTest.java
deleted file mode 100644
index b776ee1..0000000
--- a/guava-tests/test/com/google/common/math/MathPreconditionsTest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import com.google.common.annotations.GwtCompatible;
-
-import junit.framework.TestCase;
-
-import java.math.BigInteger;
-
-/**
- * Unit tests for {@link MathPreconditions}.
- *
- * @author Ben Yu
- */
-@GwtCompatible
-public class MathPreconditionsTest extends TestCase {
-
- public void testCheckPositive_zeroInt() {
- try {
- MathPreconditions.checkPositive("int", 0);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_maxInt() {
- MathPreconditions.checkPositive("int", Integer.MAX_VALUE);
- }
-
- public void testCheckPositive_minInt() {
- try {
- MathPreconditions.checkPositive("int", Integer.MIN_VALUE);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_positiveInt() {
- MathPreconditions.checkPositive("int", 1);
- }
-
- public void testCheckPositive_negativeInt() {
- try {
- MathPreconditions.checkPositive("int", -1);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_zeroLong() {
- try {
- MathPreconditions.checkPositive("long", 0L);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_maxLong() {
- MathPreconditions.checkPositive("long", Long.MAX_VALUE);
- }
-
- public void testCheckPositive_minLong() {
- try {
- MathPreconditions.checkPositive("long", Long.MIN_VALUE);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_positiveLong() {
- MathPreconditions.checkPositive("long", 1);
- }
-
- public void testCheckPositive_negativeLong() {
- try {
- MathPreconditions.checkPositive("long", -1L);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_zeroBigInteger() {
- try {
- MathPreconditions.checkPositive("BigInteger", BigInteger.ZERO);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckPositive_postiveBigInteger() {
- MathPreconditions.checkPositive("BigInteger", BigInteger.ONE);
- }
-
- public void testCheckPositive_negativeBigInteger() {
- try {
- MathPreconditions.checkPositive("BigInteger", BigInteger.ZERO.negate());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_zeroInt() {
- MathPreconditions.checkNonNegative("int", 0);
- }
-
- public void testCheckNonNegative_maxInt() {
- MathPreconditions.checkNonNegative("int", Integer.MAX_VALUE);
- }
-
- public void testCheckNonNegative_minInt() {
- try {
- MathPreconditions.checkNonNegative("int", Integer.MIN_VALUE);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_positiveInt() {
- MathPreconditions.checkNonNegative("int", 1);
- }
-
- public void testCheckNonNegative_negativeInt() {
- try {
- MathPreconditions.checkNonNegative("int", -1);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_zeroLong() {
- MathPreconditions.checkNonNegative("long", 0L);
- }
-
- public void testCheckNonNegative_maxLong() {
- MathPreconditions.checkNonNegative("long", Long.MAX_VALUE);
- }
-
- public void testCheckNonNegative_minLong() {
- try {
- MathPreconditions.checkNonNegative("long", Long.MIN_VALUE);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_positiveLong() {
- MathPreconditions.checkNonNegative("long", 1L);
- }
-
- public void testCheckNonNegative_negativeLong() {
- try {
- MathPreconditions.checkNonNegative("int", -1L);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_zeroBigInteger() {
- MathPreconditions.checkNonNegative("BigInteger", BigInteger.ZERO);
- }
-
- public void testCheckNonNegative_positiveBigInteger() {
- MathPreconditions.checkNonNegative("BigInteger", BigInteger.ONE);
- }
-
- public void testCheckNonNegative_negativeBigInteger() {
- try {
- MathPreconditions.checkNonNegative("int", BigInteger.ONE.negate());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_zeroFloat() {
- MathPreconditions.checkNonNegative("float", 0f);
- }
-
- public void testCheckNonNegative_maxFloat() {
- MathPreconditions.checkNonNegative("float", Float.MAX_VALUE);
- }
-
- public void testCheckNonNegative_minFloat() {
- MathPreconditions.checkNonNegative("float", Float.MIN_VALUE);
- }
-
- public void testCheckNonNegative_positiveFloat() {
- MathPreconditions.checkNonNegative("float", 1f);
- }
-
- public void testCheckNonNegative_negativeFloat() {
- try {
- MathPreconditions.checkNonNegative("float", -1f);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_nanFloat() {
- try {
- MathPreconditions.checkNonNegative("float", Float.NaN);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_zeroDouble() {
- MathPreconditions.checkNonNegative("double", 0d);
- }
-
- public void testCheckNonNegative_maxDouble() {
- MathPreconditions.checkNonNegative("double", Double.MAX_VALUE);
- }
-
- public void testCheckNonNegative_minDouble() {
- MathPreconditions.checkNonNegative("double", Double.MIN_VALUE);
- }
-
- public void testCheckNonNegative_positiveDouble() {
- MathPreconditions.checkNonNegative("double", 1d);
- }
-
- public void testCheckNonNegative_negativeDouble() {
- try {
- MathPreconditions.checkNonNegative("double", -1d);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckNonNegative_nanDouble() {
- try {
- MathPreconditions.checkNonNegative("double", Double.NaN);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCheckRoundingUnnnecessary_success() {
- MathPreconditions.checkRoundingUnnecessary(true);
- }
-
- public void testCheckRoundingUnnecessary_failure() {
- try {
- MathPreconditions.checkRoundingUnnecessary(false);
- fail();
- } catch (ArithmeticException expected) {}
- }
-
- public void testCheckInRange_success() {
- MathPreconditions.checkInRange(true);
- }
-
- public void testCheckInRange_failure() {
- try {
- MathPreconditions.checkInRange(false);
- fail();
- } catch (ArithmeticException expected) {}
- }
-
- public void testCheckNoOverflow_success() {
- MathPreconditions.checkNoOverflow(true);
- }
-
- public void testCheckNoOverflow_failure() {
- try {
- MathPreconditions.checkNoOverflow(false);
- fail();
- } catch (ArithmeticException expected) {}
- }
-}
diff --git a/guava-tests/test/com/google/common/math/MathTesting.java b/guava-tests/test/com/google/common/math/MathTesting.java
index eee4a47..df4c5c4 100644
--- a/guava-tests/test/com/google/common/math/MathTesting.java
+++ b/guava-tests/test/com/google/common/math/MathTesting.java
@@ -40,8 +40,8 @@ import java.math.RoundingMode;
/**
* Exhaustive input sets for every integral type.
- *
- * @author Louis Wasserman
+ *
+ * @author lowasser@google.com (Louis Wasserman)
*/
@GwtCompatible
public class MathTesting {
@@ -52,8 +52,8 @@ public class MathTesting {
FLOOR, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN);
// Exponents to test for the pow() function.
- static final ImmutableList<Integer> EXPONENTS = ImmutableList.of(0, 1, 2, 3, 4, 7, 10, 15,
- 20, 25, 40, 70);
+ static final ImmutableList<Integer> EXPONENTS = ImmutableList.of(0, 1, 2, 3, 4, 5, 6, 7, 10, 15,
+ 20, 25, 30, 40, 70);
/* Helper function to make a Long value from an Integer. */
private static final Function<Integer, Long> TO_LONG = new Function<Integer, Long>() {
@@ -110,23 +110,23 @@ public class MathTesting {
ImmutableSet.Builder<Integer> intValues = ImmutableSet.builder();
// Add boundary values manually to avoid over/under flow (this covers 2^N for 0 and 31).
intValues.add(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
- // Add values up to 40. This covers cases like "square of a prime" and such.
- for (int i = 1; i <= 40; i++) {
+ // Add values up to 64. This covers cases like "square of a prime" and such.
+ for (int i = 1; i <= 64; i++) {
intValues.add(i);
}
// Now add values near 2^N for lots of values of N.
- for (int exponent : asList(2, 3, 4, 9, 15, 16, 17, 24, 25, 30)) {
+ for (int exponent : asList(2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 23, 24, 25)) {
int x = 1 << exponent;
intValues.add(x, x + 1, x - 1);
}
intValues.add(9999).add(10000).add(10001).add(1000000); // near powers of 10
intValues.add(5792).add(5793); // sqrt(2^25) rounded up and down
POSITIVE_INTEGER_CANDIDATES = intValues.build();
- NEGATIVE_INTEGER_CANDIDATES = ImmutableList.copyOf(Iterables.concat(
- Iterables.transform(POSITIVE_INTEGER_CANDIDATES, NEGATE_INT),
- ImmutableList.of(Integer.MIN_VALUE)));
- NONZERO_INTEGER_CANDIDATES = ImmutableList.copyOf(
- Iterables.concat(POSITIVE_INTEGER_CANDIDATES, NEGATIVE_INTEGER_CANDIDATES));
+ NEGATIVE_INTEGER_CANDIDATES =
+ Iterables.concat(Iterables.transform(POSITIVE_INTEGER_CANDIDATES, NEGATE_INT),
+ ImmutableList.of(Integer.MIN_VALUE));
+ NONZERO_INTEGER_CANDIDATES =
+ Iterables.concat(POSITIVE_INTEGER_CANDIDATES, NEGATIVE_INTEGER_CANDIDATES);
ALL_INTEGER_CANDIDATES = Iterables.concat(NONZERO_INTEGER_CANDIDATES, ImmutableList.of(0));
}
@@ -202,13 +202,9 @@ public class MathTesting {
static final ImmutableSet<Double> INTEGRAL_DOUBLE_CANDIDATES;
static final ImmutableSet<Double> FRACTIONAL_DOUBLE_CANDIDATES;
- static final Iterable<Double> INFINITIES = Doubles.asList(
- Double.POSITIVE_INFINITY,
- Double.NEGATIVE_INFINITY);
static final Iterable<Double> FINITE_DOUBLE_CANDIDATES;
static final Iterable<Double> POSITIVE_FINITE_DOUBLE_CANDIDATES;
static final Iterable<Double> ALL_DOUBLE_CANDIDATES;
- static final Iterable<Double> DOUBLE_CANDIDATES_EXCEPT_NAN;
static {
ImmutableSet.Builder<Double> integralBuilder = ImmutableSet.builder();
ImmutableSet.Builder<Double> fractionalBuilder = ImmutableSet.builder();
@@ -250,8 +246,8 @@ public class MathTesting {
return input.doubleValue() > 0.0;
}
});
- DOUBLE_CANDIDATES_EXCEPT_NAN = Iterables.concat(FINITE_DOUBLE_CANDIDATES, INFINITIES);
ALL_DOUBLE_CANDIDATES =
- Iterables.concat(DOUBLE_CANDIDATES_EXCEPT_NAN, asList(Double.NaN));
+ Iterables.concat(FINITE_DOUBLE_CANDIDATES,
+ asList(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN));
}
}
diff --git a/guava-tests/test/com/google/common/math/PackageSanityTests.java b/guava-tests/test/com/google/common/math/PackageSanityTests.java
deleted file mode 100644
index 4914af1..0000000
--- a/guava-tests/test/com/google/common/math/PackageSanityTests.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-tests/test/com/google/common/math/TestPlatform.java b/guava-tests/test/com/google/common/math/TestPlatform.java
deleted file mode 100644
index 63604b5..0000000
--- a/guava-tests/test/com/google/common/math/TestPlatform.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.math;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-class TestPlatform {
- static boolean intsCanGoOutOfRange() {
- return false;
- }
-}
diff --git a/guava-tests/test/com/google/common/net/HostAndPortTest.java b/guava-tests/test/com/google/common/net/HostAndPortTest.java
deleted file mode 100644
index 476a63b..0000000
--- a/guava-tests/test/com/google/common/net/HostAndPortTest.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.net;
-
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link HostAndPort}
- *
- * @author Paul Marks
- */
-public class HostAndPortTest extends TestCase {
-
- public void testFromStringWellFormed() {
- // Well-formed inputs.
- checkFromStringCase("google.com", 80, "google.com", 80, false);
- checkFromStringCase("google.com", 80, "google.com", 80, false);
- checkFromStringCase("192.0.2.1", 82, "192.0.2.1", 82, false);
- checkFromStringCase("[2001::1]", 84, "2001::1", 84, false);
- checkFromStringCase("2001::3", 86, "2001::3", 86, false);
- checkFromStringCase("host:", 80, "host", 80, false);
- }
-
- public void testFromStringBadDefaultPort() {
- // Well-formed strings with bad default ports.
- checkFromStringCase("gmail.com:81", -1, "gmail.com", 81, true);
- checkFromStringCase("192.0.2.2:83", -1, "192.0.2.2", 83, true);
- checkFromStringCase("[2001::2]:85", -1, "2001::2", 85, true);
- checkFromStringCase("goo.gl:65535", 65536, "goo.gl", 65535, true);
- // No port, bad default.
- checkFromStringCase("google.com", -1, "google.com", -1, false);
- checkFromStringCase("192.0.2.1", 65536, "192.0.2.1", -1, false);
- checkFromStringCase("[2001::1]", -1, "2001::1", -1, false);
- checkFromStringCase("2001::3", 65536, "2001::3", -1, false);
- }
-
- public void testFromStringUnusedDefaultPort() {
- // Default port, but unused.
- checkFromStringCase("gmail.com:81", 77, "gmail.com", 81, true);
- checkFromStringCase("192.0.2.2:83", 77, "192.0.2.2", 83, true);
- checkFromStringCase("[2001::2]:85", 77, "2001::2", 85, true);
- }
-
- public void testFromStringBadPort() {
- // Out-of-range ports.
- checkFromStringCase("google.com:65536", 1, null, 99, false);
- checkFromStringCase("google.com:9999999999", 1, null, 99, false);
- // Invalid port parts.
- checkFromStringCase("google.com:port", 1, null, 99, false);
- checkFromStringCase("google.com:-25", 1, null, 99, false);
- checkFromStringCase("google.com:+25", 1, null, 99, false);
- checkFromStringCase("google.com:25 ", 1, null, 99, false);
- checkFromStringCase("google.com:25\t", 1, null, 99, false);
- checkFromStringCase("google.com:0x25 ", 1, null, 99, false);
- }
-
- public void testFromStringUnparseableNonsense() {
- // Some nonsense that causes parse failures.
- checkFromStringCase("[goo.gl]", 1, null, 99, false);
- checkFromStringCase("[goo.gl]:80", 1, null, 99, false);
- checkFromStringCase("[", 1, null, 99, false);
- checkFromStringCase("[]:", 1, null, 99, false);
- checkFromStringCase("[]:80", 1, null, 99, false);
- checkFromStringCase("[]bad", 1, null, 99, false);
- }
-
- public void testFromStringParseableNonsense() {
- // Examples of nonsense that gets through.
- checkFromStringCase("[[:]]", 86, "[:]", 86, false);
- checkFromStringCase("x:y:z", 87, "x:y:z", 87, false);
- checkFromStringCase("", 88, "", 88, false);
- checkFromStringCase(":", 99, "", 99, false);
- checkFromStringCase(":123", -1, "", 123, true);
- checkFromStringCase("\nOMG\t", 89, "\nOMG\t", 89, false);
- }
-
- private static void checkFromStringCase(
- String hpString,
- int defaultPort,
- String expectHost,
- int expectPort,
- boolean expectHasExplicitPort) {
- HostAndPort hp;
- try {
- hp = HostAndPort.fromString(hpString);
- } catch (IllegalArgumentException e) {
- // Make sure we expected this.
- assertNull(expectHost);
- return;
- }
- assertNotNull(expectHost);
-
- // Apply withDefaultPort(), yielding hp2.
- final boolean badDefaultPort = (defaultPort < 0 || defaultPort > 65535);
- HostAndPort hp2 = null;
- try {
- hp2 = hp.withDefaultPort(defaultPort);
- assertFalse(badDefaultPort);
- } catch (IllegalArgumentException e) {
- assertTrue(badDefaultPort);
- }
-
- // Check the pre-withDefaultPort() instance.
- if (expectHasExplicitPort) {
- assertTrue(hp.hasPort());
- assertEquals(expectPort, hp.getPort());
- } else {
- assertFalse(hp.hasPort());
- try {
- hp.getPort();
- fail("Expected IllegalStateException");
- } catch (IllegalStateException expected) {
- }
- }
- assertEquals(expectHost, hp.getHostText());
-
- // Check the post-withDefaultPort() instance (if any).
- if (!badDefaultPort) {
- try {
- int port = hp2.getPort();
- assertTrue(expectPort != -1);
- assertEquals(expectPort, port);
- } catch (IllegalStateException e) {
- // Make sure we expected this to fail.
- assertEquals(-1, expectPort);
- }
- assertEquals(expectHost, hp2.getHostText());
- }
- }
-
- public void testFromParts() {
- HostAndPort hp = HostAndPort.fromParts("gmail.com", 81);
- assertEquals("gmail.com", hp.getHostText());
- assertTrue(hp.hasPort());
- assertEquals(81, hp.getPort());
-
- try {
- HostAndPort.fromParts("gmail.com:80", 81);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- HostAndPort.fromParts("gmail.com", -1);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testGetPortOrDefault() {
- assertEquals(80, HostAndPort.fromString("host:80").getPortOrDefault(123));
- assertEquals(123, HostAndPort.fromString("host").getPortOrDefault(123));
- }
-
- public void testHashCodeAndEquals() {
- HostAndPort hp1 = HostAndPort.fromString("foo::123");
- HostAndPort hp2 = HostAndPort.fromString("foo::123");
- HostAndPort hp3 = HostAndPort.fromString("[foo::123]");
- HostAndPort hp4 = HostAndPort.fromParts("[foo::123]", 80);
- HostAndPort hp5 = HostAndPort.fromString("[foo::123]:80");
- assertEquals(hp1.hashCode(), hp1.hashCode());
- assertEquals(hp1.hashCode(), hp2.hashCode());
- assertFalse(hp1.hashCode() == hp3.hashCode());
- assertFalse(hp3.hashCode() == hp4.hashCode());
- assertEquals(hp4.hashCode(), hp5.hashCode());
-
- assertTrue(hp1.equals(hp1));
- assertTrue(hp1.equals(hp2));
- assertFalse(hp1.equals(hp3));
- assertFalse(hp3.equals(hp4));
- assertTrue(hp4.equals(hp5));
- assertFalse(hp1.equals(null));
- }
-
- public void testRequireBracketsForIPv6() {
- // Bracketed IPv6 works fine.
- assertEquals("::1", HostAndPort.fromString("[::1]").requireBracketsForIPv6().getHostText());
- assertEquals("::1", HostAndPort.fromString("[::1]:80").requireBracketsForIPv6().getHostText());
- // Non-bracketed non-IPv6 works fine.
- assertEquals("x", HostAndPort.fromString("x").requireBracketsForIPv6().getHostText());
- assertEquals("x", HostAndPort.fromString("x:80").requireBracketsForIPv6().getHostText());
-
- // Non-bracketed IPv6 fails.
- try {
- HostAndPort.fromString("::1").requireBracketsForIPv6();
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testToString() {
- // With ports.
- assertEquals("foo:101", "" + HostAndPort.fromString("foo:101"));
- assertEquals(":102", HostAndPort.fromString(":102").toString());
- assertEquals("[1::2]:103", HostAndPort.fromParts("1::2", 103).toString());
- assertEquals("[::1]:104", HostAndPort.fromString("[::1]:104").toString());
-
- // Without ports.
- assertEquals("foo", "" + HostAndPort.fromString("foo"));
- assertEquals("", HostAndPort.fromString("").toString());
- assertEquals("[1::2]", HostAndPort.fromString("1::2").toString());
- assertEquals("[::1]", HostAndPort.fromString("[::1]").toString());
-
- // Garbage in, garbage out.
- assertEquals("[::]]:107", HostAndPort.fromParts("::]", 107).toString());
- assertEquals("[[:]]:108", HostAndPort.fromString("[[:]]:108").toString());
- }
-
- public void testSerialization() {
- SerializableTester.reserializeAndAssert(HostAndPort.fromParts("host", 80));
- SerializableTester.reserializeAndAssert(HostAndPort.fromString("host"));
- SerializableTester.reserializeAndAssert(HostAndPort.fromString("host:80"));
- SerializableTester.reserializeAndAssert(HostAndPort.fromString("[::1]:104"));
- SerializableTester.reserializeAndAssert(HostAndPort.fromParts("1::2", 103));
- }
-}
diff --git a/guava-tests/test/com/google/common/net/HostSpecifierTest.java b/guava-tests/test/com/google/common/net/HostSpecifierTest.java
index 12c7631..f66c128 100644
--- a/guava-tests/test/com/google/common/net/HostSpecifierTest.java
+++ b/guava-tests/test/com/google/common/net/HostSpecifierTest.java
@@ -87,7 +87,7 @@ public final class HostSpecifierTest extends TestCase {
return HostSpecifier.fromValid(specifier);
}
- public void testNulls() {
+ public void testNulls() throws Exception {
final NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(HostSpecifier.class);
diff --git a/guava-tests/test/com/google/common/net/HttpHeadersTest.java b/guava-tests/test/com/google/common/net/HttpHeadersTest.java
index 4bcf3ff..513767c 100644
--- a/guava-tests/test/com/google/common/net/HttpHeadersTest.java
+++ b/guava-tests/test/com/google/common/net/HttpHeadersTest.java
@@ -30,7 +30,7 @@ import java.util.List;
/**
* Tests for the HttpHeaders class.
*
- * @author Kurt Alfred Kluever
+ * @author Kurt Aflred Kluever
*/
public class HttpHeadersTest extends TestCase {
public void testConstantNameMatchesString() throws Exception {
@@ -47,8 +47,7 @@ public class HttpHeadersTest extends TestCase {
}
private static final ImmutableSet<String> UPPERCASE_ACRONYMS = ImmutableSet.of(
- "ID", "DNT", "GFE", "GSE", "IP", "MD5", "P3P", "TE", "UID", "URL",
- "WWW", "XSS");
+ "ID", "DNT", "GFE", "IP", "MD5", "P3P", "TE", "UID", "URL", "WWW", "XSS");
private static final Splitter SPLITTER = Splitter.on('_');
private static final Joiner JOINER = Joiner.on('-');
diff --git a/guava-tests/test/com/google/common/net/InetAddressesTest.java b/guava-tests/test/com/google/common/net/InetAddressesTest.java
index 90d3285..41564eb 100644
--- a/guava-tests/test/com/google/common/net/InetAddressesTest.java
+++ b/guava-tests/test/com/google/common/net/InetAddressesTest.java
@@ -32,7 +32,7 @@ import java.net.UnknownHostException;
*/
public class InetAddressesTest extends TestCase {
- public void testNulls() {
+ public void testNulls() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(InetAddresses.class);
@@ -241,15 +241,9 @@ public class InetAddressesTest extends TestCase {
assertEquals(expected, InetAddresses.forUriString("[3ffe:0:0:0:0:0:0:1]"));
}
- public void testForUriStringIPv4Mapped() {
- Inet4Address expected = (Inet4Address) InetAddresses.forString("192.0.2.1");
- assertEquals(expected, InetAddresses.forUriString("[::ffff:192.0.2.1]"));
- }
-
public void testIsUriInetAddress() {
assertTrue(InetAddresses.isUriInetAddress("192.168.1.1"));
assertTrue(InetAddresses.isUriInetAddress("[3ffe:0:0:0:0:0:0:1]"));
- assertTrue(InetAddresses.isUriInetAddress("[::ffff:192.0.2.1]"));
assertFalse(InetAddresses.isUriInetAddress("[192.168.1.1"));
assertFalse(InetAddresses.isUriInetAddress("192.168.1.1]"));
@@ -259,8 +253,6 @@ public class InetAddressesTest extends TestCase {
assertFalse(InetAddresses.isUriInetAddress("1:2e"));
assertFalse(InetAddresses.isUriInetAddress("[3ffe:0:0:0:0:0:0:1"));
assertFalse(InetAddresses.isUriInetAddress("3ffe:0:0:0:0:0:0:1]"));
- assertFalse(InetAddresses.isUriInetAddress("3ffe:0:0:0:0:0:0:1"));
- assertFalse(InetAddresses.isUriInetAddress("::ffff:192.0.2.1"));
}
public void testForUriStringBad() {
@@ -326,20 +318,6 @@ public class InetAddressesTest extends TestCase {
} catch (IllegalArgumentException e) {
// expected
}
-
- try {
- InetAddresses.forUriString("3ffe:0:0:0:0:0:0:1");
- fail("expected IllegalArgumentException"); // COV_NF_LINE
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- InetAddresses.forUriString("::ffff:192.0.2.1");
- fail("expected IllegalArgumentException"); // COV_NF_LINE
- } catch (IllegalArgumentException e) {
- // expected
- }
}
public void testCompatIPv4Addresses() {
@@ -489,14 +467,6 @@ public class InetAddressesTest extends TestCase {
assertEquals(flags, teredo.getFlags());
}
- public void testTeredoAddress_nullServer() {
- InetAddresses.TeredoInfo info = new InetAddresses.TeredoInfo(null, null, 80, 1000);
- assertEquals(InetAddresses.forString("0.0.0.0"), info.getServer());
- assertEquals(InetAddresses.forString("0.0.0.0"), info.getClient());
- assertEquals(80, info.getPort());
- assertEquals(1000, info.getFlags());
- }
-
public void testIsatapAddresses() {
InetAddress ipv4 = InetAddresses.forString("1.2.3.4");
String[] validIsatapAddresses = {
@@ -637,6 +607,14 @@ public class InetAddressesTest extends TestCase {
assertTrue(InetAddresses.coerceToInteger(coerced) <= 0xfffffffe);
}
+ public void testHash64To32() {
+ // Make sure the output looks reasonably sane.
+ assertEquals(532412650, InetAddresses.hash64To32(-1));
+ assertEquals(720020139, InetAddresses.hash64To32(0));
+ assertEquals(357654460, InetAddresses.hash64To32(1));
+ assertEquals(-1977349188, InetAddresses.hash64To32(0x7fffffffffffffffL));
+ }
+
public void testToInteger() {
InetAddress ipv4Addr = InetAddresses.forString("127.0.0.1");
assertEquals(0x7f000001, InetAddresses.coerceToInteger(ipv4Addr));
@@ -699,7 +677,7 @@ public class InetAddressesTest extends TestCase {
try {
address = InetAddresses.increment(address);
fail();
- } catch (IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
}
public void testIncrementIPv6() throws UnknownHostException {
@@ -722,6 +700,6 @@ public class InetAddressesTest extends TestCase {
try {
address = InetAddresses.increment(address);
fail();
- } catch (IllegalArgumentException expected) {}
+ } catch (IllegalArgumentException expected) { }
}
}
diff --git a/guava-tests/test/com/google/common/net/InternetDomainNameTest.java b/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
index 7291286..1fb869f 100644
--- a/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
+++ b/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
@@ -370,7 +370,7 @@ public final class InternetDomainNameTest extends TestCase {
}
public void testExclusion() {
- InternetDomainName domain = InternetDomainName.from("foo.nic.uk");
+ InternetDomainName domain = InternetDomainName.from("foo.nhs.uk");
assertTrue(domain.hasPublicSuffix());
assertEquals("uk", domain.publicSuffix().name());
@@ -378,16 +378,6 @@ public final class InternetDomainNameTest extends TestCase {
assertFalse(domain.publicSuffix().isPublicSuffix());
}
- public void testMultipleUnders() {
- // PSL has both *.uk and *.police.uk; the latter should win.
- // See http://code.google.com/p/guava-libraries/issues/detail?id=1176
-
- InternetDomainName domain = InternetDomainName.from("www.essex.police.uk");
- assertTrue(domain.hasPublicSuffix());
- assertEquals("essex.police.uk", domain.publicSuffix().name());
- assertEquals("www.essex.police.uk", domain.topPrivateDomain().name());
- }
-
public void testEquality() {
new EqualsTester()
.addEqualityGroup(
@@ -403,10 +393,11 @@ public final class InternetDomainNameTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
+ public void testNulls() throws Exception {
final NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(InternetDomainName.class);
tester.testAllPublicInstanceMethods(InternetDomainName.from("google.com"));
}
+
}
diff --git a/guava-tests/test/com/google/common/net/MediaTypeTest.java b/guava-tests/test/com/google/common/net/MediaTypeTest.java
deleted file mode 100644
index 12efed6..0000000
--- a/guava-tests/test/com/google/common/net/MediaTypeTest.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.net;
-
-import static com.google.common.base.Charsets.UTF_16;
-import static com.google.common.base.Charsets.UTF_8;
-import static com.google.common.net.MediaType.ANY_APPLICATION_TYPE;
-import static com.google.common.net.MediaType.ANY_AUDIO_TYPE;
-import static com.google.common.net.MediaType.ANY_IMAGE_TYPE;
-import static com.google.common.net.MediaType.ANY_TEXT_TYPE;
-import static com.google.common.net.MediaType.ANY_TYPE;
-import static com.google.common.net.MediaType.ANY_VIDEO_TYPE;
-import static com.google.common.net.MediaType.HTML_UTF_8;
-import static com.google.common.net.MediaType.JPEG;
-import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
-import static java.lang.reflect.Modifier.isFinal;
-import static java.lang.reflect.Modifier.isPublic;
-import static java.lang.reflect.Modifier.isStatic;
-import static java.util.Arrays.asList;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Throwables;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.Field;
-import java.nio.charset.Charset;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-
-/**
- * Tests for {@link MediaType}.
- *
- * @author Gregory Kick
- */
-@Beta
-@GwtCompatible(emulated = true)
-public class MediaTypeTest extends TestCase {
- @GwtIncompatible("reflection") public void testParse_useConstants() throws Exception {
- for (MediaType constant : getConstants()) {
- assertSame(constant, MediaType.parse(constant.toString()));
- }
- }
-
- @GwtIncompatible("reflection") public void testCreate_useConstants() throws Exception {
- for (MediaType constant : getConstants()) {
- assertSame(constant, MediaType.create(constant.type(), constant.subtype())
- .withParameters(constant.parameters()));
- }
- }
-
- @GwtIncompatible("reflection") public void testConstants_charset() throws Exception {
- for (Field field : getConstantFields()) {
- Optional<Charset> charset = ((MediaType) field.get(null)).charset();
- if (field.getName().endsWith("_UTF_8")) {
- assertEquals(Optional.of(UTF_8), charset);
- } else {
- assertEquals(Optional.absent(), charset);
- }
- }
- }
-
- @GwtIncompatible("reflection") private static FluentIterable<Field> getConstantFields() {
- return FluentIterable.from(asList(MediaType.class.getDeclaredFields()))
- .filter(new Predicate<Field>() {
- @Override public boolean apply(Field input) {
- int modifiers = input.getModifiers();
- return isPublic(modifiers) && isStatic(modifiers) && isFinal(modifiers)
- && MediaType.class.equals(input.getType());
- }
- });
- }
-
- @GwtIncompatible("reflection") private static FluentIterable<MediaType> getConstants() {
- return getConstantFields()
- .transform(new Function<Field, MediaType>() {
- @Override public MediaType apply(Field input) {
- try {
- return (MediaType) input.get(null);
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- }
- });
- }
-
- public void testCreate_invalidType() {
- try {
- MediaType.create("te><t", "plaintext");
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCreate_invalidSubtype() {
- try {
- MediaType.create("text", "pl@intext");
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCreate_wildcardTypeDeclaredSubtype() {
- try {
- MediaType.create("*", "text");
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testCreateApplicationType() {
- MediaType newType = MediaType.createApplicationType("yams");
- assertEquals("application", newType.type());
- assertEquals("yams", newType.subtype());
- }
-
- public void testCreateAudioType() {
- MediaType newType = MediaType.createAudioType("yams");
- assertEquals("audio", newType.type());
- assertEquals("yams", newType.subtype());
- }
-
- public void testCreateImageType() {
- MediaType newType = MediaType.createImageType("yams");
- assertEquals("image", newType.type());
- assertEquals("yams", newType.subtype());
- }
-
- public void testCreateTextType() {
- MediaType newType = MediaType.createTextType("yams");
- assertEquals("text", newType.type());
- assertEquals("yams", newType.subtype());
- }
-
- public void testCreateVideoType() {
- MediaType newType = MediaType.createVideoType("yams");
- assertEquals("video", newType.type());
- assertEquals("yams", newType.subtype());
- }
-
- public void testGetType() {
- assertEquals("text", MediaType.parse("text/plain").type());
- assertEquals("application",
- MediaType.parse("application/atom+xml; charset=utf-8").type());
- }
-
- public void testGetSubtype() {
- assertEquals("plain", MediaType.parse("text/plain").subtype());
- assertEquals("atom+xml",
- MediaType.parse("application/atom+xml; charset=utf-8").subtype());
- }
-
- private static final ImmutableListMultimap<String, String> PARAMETERS =
- ImmutableListMultimap.of("a", "1", "a", "2", "b", "3");
-
- public void testGetParameters() {
- assertEquals(ImmutableListMultimap.of(), MediaType.parse("text/plain").parameters());
- assertEquals(ImmutableListMultimap.of("charset", "utf-8"),
- MediaType.parse("application/atom+xml; charset=utf-8").parameters());
- assertEquals(PARAMETERS,
- MediaType.parse("application/atom+xml; a=1; a=2; b=3").parameters());
- }
-
- public void testWithoutParameters() {
- assertSame(MediaType.parse("image/gif"),
- MediaType.parse("image/gif").withoutParameters());
- assertEquals(MediaType.parse("image/gif"),
- MediaType.parse("image/gif; foo=bar").withoutParameters());
- }
-
- public void testWithParameters() {
- assertEquals(MediaType.parse("text/plain; a=1; a=2; b=3"),
- MediaType.parse("text/plain").withParameters(PARAMETERS));
- assertEquals(MediaType.parse("text/plain; a=1; a=2; b=3"),
- MediaType.parse("text/plain; a=1; a=2; b=3").withParameters(PARAMETERS));
- }
-
- public void testWithParameters_invalidAttribute() {
- MediaType mediaType = MediaType.parse("text/plain");
- ImmutableListMultimap<String, String> parameters =
- ImmutableListMultimap.of("a", "1", "@", "2", "b", "3");
- try {
- mediaType.withParameters(parameters);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testWithParameter() {
- assertEquals(MediaType.parse("text/plain; a=1"),
- MediaType.parse("text/plain").withParameter("a", "1"));
- assertEquals(MediaType.parse("text/plain; a=1"),
- MediaType.parse("text/plain; a=1; a=2").withParameter("a", "1"));
- assertEquals(MediaType.parse("text/plain; a=3"),
- MediaType.parse("text/plain; a=1; a=2").withParameter("a", "3"));
- assertEquals(MediaType.parse("text/plain; a=1; a=2; b=3"),
- MediaType.parse("text/plain; a=1; a=2").withParameter("b", "3"));
- }
-
- public void testWithParameter_invalidAttribute() {
- MediaType mediaType = MediaType.parse("text/plain");
- try {
- mediaType.withParameter("@", "2");
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testWithCharset() {
- assertEquals(MediaType.parse("text/plain; charset=utf-8"),
- MediaType.parse("text/plain").withCharset(UTF_8));
- assertEquals(MediaType.parse("text/plain; charset=utf-8"),
- MediaType.parse("text/plain; charset=utf-16").withCharset(UTF_8));
- }
-
- public void testHasWildcard() {
- assertFalse(PLAIN_TEXT_UTF_8.hasWildcard());
- assertFalse(JPEG.hasWildcard());
- assertTrue(ANY_TYPE.hasWildcard());
- assertTrue(ANY_APPLICATION_TYPE.hasWildcard());
- assertTrue(ANY_AUDIO_TYPE.hasWildcard());
- assertTrue(ANY_IMAGE_TYPE.hasWildcard());
- assertTrue(ANY_TEXT_TYPE.hasWildcard());
- assertTrue(ANY_VIDEO_TYPE.hasWildcard());
- }
-
- public void testIs() {
- assertTrue(PLAIN_TEXT_UTF_8.is(ANY_TYPE));
- assertTrue(JPEG.is(ANY_TYPE));
- assertTrue(ANY_TEXT_TYPE.is(ANY_TYPE));
- assertTrue(PLAIN_TEXT_UTF_8.is(ANY_TEXT_TYPE));
- assertTrue(PLAIN_TEXT_UTF_8.withoutParameters().is(ANY_TEXT_TYPE));
- assertFalse(JPEG.is(ANY_TEXT_TYPE));
- assertTrue(PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8));
- assertTrue(PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8.withoutParameters()));
- assertFalse(PLAIN_TEXT_UTF_8.withoutParameters().is(PLAIN_TEXT_UTF_8));
- assertFalse(PLAIN_TEXT_UTF_8.is(HTML_UTF_8));
- assertFalse(PLAIN_TEXT_UTF_8.withParameter("charset", "UTF-16").is(PLAIN_TEXT_UTF_8));
- assertFalse(PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8.withParameter("charset", "UTF-16")));
- }
-
- public void testParse_empty() {
- try {
- MediaType.parse("");
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testParse_badInput() {
- try {
- MediaType.parse("/");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("te<t/plain");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/pl@in");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain;");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; ");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=@");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=\"@");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=1;");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=1; ");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=1; b");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=1; b=");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- MediaType.parse("text/plain; a=\u2025");
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testGetCharset() {
- assertEquals(Optional.absent(), MediaType.parse("text/plain").charset());
- assertEquals(Optional.of(UTF_8),
- MediaType.parse("text/plain; charset=utf-8").charset());
- }
-
- @GwtIncompatible("Non-UTF-8 Charset") public void testGetCharset_utf16() {
- assertEquals(Optional.of(UTF_16),
- MediaType.parse("text/plain; charset=utf-16").charset());
- }
-
- public void testGetCharset_tooMany() {
- MediaType mediaType = MediaType.parse("text/plain; charset=utf-8; charset=utf-16");
- try {
- mediaType.charset();
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- public void testGetCharset_illegalCharset() {
- MediaType mediaType = MediaType.parse(
- "text/plain; charset=\"!@#$%^&*()\"");
- try {
- mediaType.charset();
- fail();
- } catch (IllegalCharsetNameException expected) {}
- }
-
- public void testGetCharset_unsupportedCharset() {
- MediaType mediaType = MediaType.parse(
- "text/plain; charset=utf-wtf");
- try {
- mediaType.charset();
- fail();
- } catch (UnsupportedCharsetException expected) {}
- }
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(MediaType.create("text", "plain"),
- MediaType.create("TEXT", "PLAIN"),
- MediaType.parse("text/plain"),
- MediaType.parse("TEXT/PLAIN"),
- MediaType.create("text", "plain").withParameter("a", "1").withoutParameters())
- .addEqualityGroup(
- MediaType.create("text", "plain").withCharset(UTF_8),
- MediaType.create("text", "plain").withParameter("CHARSET", "UTF-8"),
- MediaType.create("text", "plain").withParameters(
- ImmutableMultimap.of("charset", "utf-8")),
- MediaType.parse("text/plain;charset=utf-8"),
- MediaType.parse("text/plain; charset=utf-8"),
- MediaType.parse("text/plain; charset=utf-8"),
- MediaType.parse("text/plain; \tcharset=utf-8"),
- MediaType.parse("text/plain; \r\n\tcharset=utf-8"),
- MediaType.parse("text/plain; CHARSET=utf-8"),
- MediaType.parse("text/plain; charset=\"utf-8\""),
- MediaType.parse("text/plain; charset=\"\\u\\tf-\\8\""),
- MediaType.parse("text/plain; charset=UTF-8"))
- .addEqualityGroup(MediaType.parse("text/plain; charset=utf-8; charset=utf-8"))
- .addEqualityGroup(MediaType.create("text", "plain").withParameter("a", "value"),
- MediaType.create("text", "plain").withParameter("A", "value"))
- .addEqualityGroup(MediaType.create("text", "plain").withParameter("a", "VALUE"),
- MediaType.create("text", "plain").withParameter("A", "VALUE"))
- .addEqualityGroup(
- MediaType.create("text", "plain")
- .withParameters(ImmutableListMultimap.of("a", "1", "a", "2")),
- MediaType.create("text", "plain")
- .withParameters(ImmutableListMultimap.of("a", "2", "a", "1")))
- .addEqualityGroup(MediaType.create("text", "csv"))
- .addEqualityGroup(MediaType.create("application", "atom+xml"))
- .testEquals();
- }
-
- @GwtIncompatible("Non-UTF-8 Charset") public void testEquals_nonUtf8Charsets() {
- new EqualsTester()
- .addEqualityGroup(MediaType.create("text", "plain"))
- .addEqualityGroup(MediaType.create("text", "plain").withCharset(UTF_8))
- .addEqualityGroup(MediaType.create("text", "plain").withCharset(UTF_16))
- .testEquals();
- }
-
- @GwtIncompatible("com.google.common.testing.NullPointerTester")
- public void testNullPointer() {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicConstructors(MediaType.class);
- tester.testAllPublicStaticMethods(MediaType.class);
- tester.testAllPublicInstanceMethods(MediaType.parse("text/plain"));
- }
-
- public void testToString() {
- assertEquals("text/plain", MediaType.create("text", "plain").toString());
- assertEquals("text/plain; something=\"cr@zy\"; something-else=\"crazy with spaces\"",
- MediaType.create("text", "plain")
- .withParameter("something", "cr@zy")
- .withParameter("something-else", "crazy with spaces")
- .toString());
- }
-}
diff --git a/guava-tests/test/com/google/common/net/PackageSanityTests.java b/guava-tests/test/com/google/common/net/PackageSanityTests.java
deleted file mode 100644
index 3d18ad6..0000000
--- a/guava-tests/test/com/google/common/net/PackageSanityTests.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.net;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- setDefault(InternetDomainName.class, InternetDomainName.from("google.com"));
- }
-}
diff --git a/guava-tests/test/com/google/common/primitives/BooleansTest.java b/guava-tests/test/com/google/common/primitives/BooleansTest.java
index f6c5d99..b20a01c 100644
--- a/guava-tests/test/com/google/common/primitives/BooleansTest.java
+++ b/guava-tests/test/com/google/common/primitives/BooleansTest.java
@@ -39,7 +39,6 @@ import java.util.List;
public class BooleansTest extends TestCase {
private static final boolean[] EMPTY = {};
private static final boolean[] ARRAY_FALSE = {false};
- private static final boolean[] ARRAY_TRUE = {true};
private static final boolean[] ARRAY_FALSE_FALSE = {false, false};
private static final boolean[] ARRAY_FALSE_TRUE = {false, true};
@@ -70,16 +69,6 @@ public class BooleansTest extends TestCase {
}
public void testIndexOf() {
- assertEquals(-1, Booleans.indexOf(EMPTY, ARRAY_FALSE));
- assertEquals(-1, Booleans.indexOf(ARRAY_FALSE, ARRAY_FALSE_TRUE));
- assertEquals(0, Booleans.indexOf(ARRAY_FALSE_FALSE, ARRAY_FALSE));
- assertEquals(0, Booleans.indexOf(ARRAY_FALSE, ARRAY_FALSE));
- assertEquals(0, Booleans.indexOf(ARRAY_FALSE_TRUE, ARRAY_FALSE));
- assertEquals(1, Booleans.indexOf(ARRAY_FALSE_TRUE, ARRAY_TRUE));
- assertEquals(0, Booleans.indexOf(ARRAY_TRUE, new boolean[0]));
- }
-
- public void testIndexOf_arrays() {
assertEquals(-1, Booleans.indexOf(EMPTY, false));
assertEquals(-1, Booleans.indexOf(ARRAY_FALSE, true));
assertEquals(-1, Booleans.indexOf(ARRAY_FALSE_FALSE, true));
@@ -211,85 +200,14 @@ public class BooleansTest extends TestCase {
}
}
- public void testAsListIsEmpty() {
- assertTrue(Booleans.asList(EMPTY).isEmpty());
- assertFalse(Booleans.asList(ARRAY_FALSE).isEmpty());
- }
-
- public void testAsListSize() {
- assertEquals(0, Booleans.asList(EMPTY).size());
- assertEquals(1, Booleans.asList(ARRAY_FALSE).size());
- assertEquals(2, Booleans.asList(ARRAY_FALSE_TRUE).size());
- }
-
- public void testAsListIndexOf() {
- assertEquals(-1, Booleans.asList(EMPTY).indexOf("wrong type"));
- assertEquals(-1, Booleans.asList(EMPTY).indexOf(true));
- assertEquals(-1, Booleans.asList(ARRAY_FALSE).indexOf(true));
- assertEquals(0, Booleans.asList(ARRAY_FALSE).indexOf(false));
- assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).indexOf(true));
- }
-
- public void testAsListLastIndexOf() {
- assertEquals(-1, Booleans.asList(EMPTY).indexOf("wrong type"));
- assertEquals(-1, Booleans.asList(EMPTY).indexOf(true));
- assertEquals(-1, Booleans.asList(ARRAY_FALSE).lastIndexOf(true));
- assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).lastIndexOf(true));
- assertEquals(1, Booleans.asList(ARRAY_FALSE_FALSE).lastIndexOf(false));
- }
-
- public void testAsListContains() {
- assertFalse(Booleans.asList(EMPTY).contains("wrong type"));
- assertFalse(Booleans.asList(EMPTY).contains(true));
- assertFalse(Booleans.asList(ARRAY_FALSE).contains(true));
- assertTrue(Booleans.asList(ARRAY_TRUE).contains(true));
- assertTrue(Booleans.asList(ARRAY_FALSE_TRUE).contains(false));
- assertTrue(Booleans.asList(ARRAY_FALSE_TRUE).contains(true));
- }
-
- public void testAsListEquals() {
- assertEquals(Booleans.asList(EMPTY), Collections.emptyList());
- assertEquals(Booleans.asList(ARRAY_FALSE), Booleans.asList(ARRAY_FALSE));
- assertFalse(Booleans.asList(ARRAY_FALSE).equals(ARRAY_FALSE));
- assertFalse(Booleans.asList(ARRAY_FALSE).equals(null));
- assertFalse(Booleans.asList(ARRAY_FALSE).equals(Booleans.asList(ARRAY_FALSE_TRUE)));
- assertFalse(Booleans.asList(ARRAY_FALSE_FALSE).equals(Booleans.asList(ARRAY_FALSE_TRUE)));
- assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).lastIndexOf(true));
- List<Boolean> reference = Booleans.asList(ARRAY_FALSE);
- assertEquals(Booleans.asList(ARRAY_FALSE), reference);
- assertEquals(reference, reference);
- }
-
- public void testAsListHashcode() {
- assertEquals(1, Booleans.asList(EMPTY).hashCode());
- assertEquals(Booleans.asList(ARRAY_FALSE).hashCode(), Booleans.asList(ARRAY_FALSE).hashCode());
- List<Boolean> reference = Booleans.asList(ARRAY_FALSE);
- assertEquals(Booleans.asList(ARRAY_FALSE).hashCode(), reference.hashCode());
- }
-
- public void testAsListToString() {
- assertEquals("[false]", Booleans.asList(ARRAY_FALSE).toString());
- assertEquals("[false, true]", Booleans.asList(ARRAY_FALSE_TRUE).toString());
- }
-
- public void testAsListSet() {
- List<Boolean> list = Booleans.asList(ARRAY_FALSE);
- assertFalse(list.set(0, true));
- assertTrue(list.set(0, false));
- try {
- list.set(0, null);
- fail();
- } catch (NullPointerException expected) {
- }
- try {
- list.set(1, true);
- fail();
- } catch (IndexOutOfBoundsException expected) {
- }
+ public void testAsListEmpty() {
+ assertSame(Collections.emptyList(), Booleans.asList(EMPTY));
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Booleans.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(boolean[].class, new boolean[0]);
+ tester.testAllPublicStaticMethods(Booleans.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java
index 585c4c8..49ffa74 100644
--- a/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class ByteArrayAsListTest extends TestCase {
private static List<Byte> asList(Byte[] values) {
@@ -50,7 +49,6 @@ public class ByteArrayAsListTest extends TestCase {
return Bytes.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Byte>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/BytesTest.java b/guava-tests/test/com/google/common/primitives/BytesTest.java
index e268427..a30061c 100644
--- a/guava-tests/test/com/google/common/primitives/BytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/BytesTest.java
@@ -200,24 +200,6 @@ public class BytesTest extends TestCase {
}
}
- public void testToArray_withConversion() {
- byte[] array = {(byte) 0, (byte) 1, (byte) 2};
-
- List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
- List<Integer> ints = Arrays.asList(0, 1, 2);
- List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
- List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
- List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
-
- assertTrue(Arrays.equals(array, Bytes.toArray(bytes)));
- assertTrue(Arrays.equals(array, Bytes.toArray(shorts)));
- assertTrue(Arrays.equals(array, Bytes.toArray(ints)));
- assertTrue(Arrays.equals(array, Bytes.toArray(floats)));
- assertTrue(Arrays.equals(array, Bytes.toArray(longs)));
- assertTrue(Arrays.equals(array, Bytes.toArray(doubles)));
- }
-
public void testAsList_isAView() {
byte[] array = {(byte) 0, (byte) 1};
List<Byte> list = Bytes.asList(array);
@@ -255,7 +237,9 @@ public class BytesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Bytes.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(byte[].class, new byte[0]);
+ tester.testAllPublicStaticMethods(Bytes.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java
index c2eae49..23b88b1 100644
--- a/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class CharArrayAsListTest extends TestCase {
private static List<Character> asList(Character[] values) {
@@ -50,7 +49,6 @@ public class CharArrayAsListTest extends TestCase {
return Chars.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Character>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/CharsTest.java b/guava-tests/test/com/google/common/primitives/CharsTest.java
index e6d7439..adc1898 100644
--- a/guava-tests/test/com/google/common/primitives/CharsTest.java
+++ b/guava-tests/test/com/google/common/primitives/CharsTest.java
@@ -390,7 +390,9 @@ public class CharsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Chars.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(char[].class, new char[0]);
+ tester.testAllPublicStaticMethods(Chars.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java
index a20f7f5..1fa39d7 100644
--- a/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class DoubleArrayAsListTest extends TestCase {
private static List<Double> asList(Double[] values) {
@@ -50,7 +49,6 @@ public class DoubleArrayAsListTest extends TestCase {
return Doubles.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Double>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/DoublesTest.java b/guava-tests/test/com/google/common/primitives/DoublesTest.java
index 5e1e4c8..68fdc59 100644
--- a/guava-tests/test/com/google/common/primitives/DoublesTest.java
+++ b/guava-tests/test/com/google/common/primitives/DoublesTest.java
@@ -17,11 +17,10 @@
package com.google.common.primitives;
import static java.lang.Double.NaN;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.Helpers;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -51,10 +50,9 @@ public class DoublesTest extends TestCase {
private static final double GREATEST = Double.POSITIVE_INFINITY;
private static final double[] NUMBERS = new double[] {
- LEAST, -Double.MAX_VALUE, -1.0, -0.5, -0.1, -0.0, 0.0, 0.1, 0.5, 1.0,
- Double.MAX_VALUE, GREATEST, Double.MIN_NORMAL, -Double.MIN_NORMAL,
- Double.MIN_VALUE, -Double.MIN_VALUE, Integer.MIN_VALUE,
- Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE
+ LEAST, -Double.MAX_VALUE, -1.0, -0.0, 0.0, 1.0, Double.MAX_VALUE, GREATEST,
+ Double.MIN_NORMAL, -Double.MIN_NORMAL, Double.MIN_VALUE, -Double.MIN_VALUE,
+ Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE
};
private static final double[] VALUES
@@ -339,31 +337,13 @@ public class DoublesTest extends TestCase {
}
}
- public void testToArray_withConversion() {
- double[] array = {(double) 0, (double) 1, (double) 2};
-
- List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
- List<Integer> ints = Arrays.asList(0, 1, 2);
- List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
- List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
- List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
-
- assertTrue(Arrays.equals(array, Doubles.toArray(bytes)));
- assertTrue(Arrays.equals(array, Doubles.toArray(shorts)));
- assertTrue(Arrays.equals(array, Doubles.toArray(ints)));
- assertTrue(Arrays.equals(array, Doubles.toArray(floats)));
- assertTrue(Arrays.equals(array, Doubles.toArray(longs)));
- assertTrue(Arrays.equals(array, Doubles.toArray(doubles)));
- }
-
public void testAsList_isAView() {
double[] array = {(double) 0, (double) 1};
List<Double> list = Doubles.asList(array);
list.set(0, (double) 2);
assertTrue(Arrays.equals(new double[] {(double) 2, (double) 1}, array));
array[1] = (double) 3;
- ASSERT.that(list).has().allOf((double) 2, (double) 3).inOrder();
+ ASSERT.that(list).hasContentsInOrder((double) 2, (double) 3);
}
public void testAsList_toArray_roundTrip() {
@@ -393,108 +373,10 @@ public class DoublesTest extends TestCase {
assertSame(Collections.emptyList(), Doubles.asList(EMPTY));
}
- /**
- * A reference implementation for {@code tryParse} that just catches the exception from
- * {@link Double#valueOf}.
- */
- private static Double referenceTryParse(String input) {
- if (input.trim().length() < input.length()) {
- return null;
- }
- try {
- return Double.valueOf(input);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @GwtIncompatible("Doubles.tryParse")
- private static void checkTryParse(String input) {
- Double expected = referenceTryParse(input);
- assertEquals(expected, Doubles.tryParse(input));
- assertEquals(expected != null,
- Doubles.FLOATING_POINT_PATTERN.matcher(input).matches());
- }
-
- @GwtIncompatible("Doubles.tryParse")
- private static void checkTryParse(double expected, String input) {
- assertEquals(Double.valueOf(expected), Doubles.tryParse(input));
- assertTrue(Doubles.FLOATING_POINT_PATTERN.matcher(input).matches());
- }
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseHex() {
- for (String signChar : ImmutableList.of("", "+", "-")) {
- for (String hexPrefix : ImmutableList.of("0x", "0X")) {
- for (String iPart : ImmutableList.of("", "0", "1", "F", "f", "c4", "CE")) {
- for (String fPart : ImmutableList.of("", ".", ".F", ".52", ".a")) {
- for (String expMarker : ImmutableList.of("p", "P")) {
- for (String exponent : ImmutableList.of("0", "-5", "+20", "52")) {
- for (String typePart : ImmutableList.of("", "D", "F", "d", "f")) {
- checkTryParse(
- signChar + hexPrefix + iPart + fPart + expMarker + exponent + typePart);
- }
- }
- }
- }
- }
- }
- }
- }
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseAllCodePoints() {
- // Exercise non-ASCII digit test cases and the like.
- char[] tmp = new char[2];
- for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) {
- Character.toChars(i, tmp, 0);
- checkTryParse(String.copyValueOf(tmp, 0, Character.charCount(i)));
- }
- }
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseOfToStringIsOriginal() {
- for (double d : NUMBERS) {
- checkTryParse(d, Double.toString(d));
- }
- }
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseOfToHexStringIsOriginal() {
- for (double d : NUMBERS) {
- checkTryParse(d, Double.toHexString(d));
- }
- }
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseNaN() {
- checkTryParse("NaN");
- checkTryParse("+NaN");
- checkTryParse("-NaN");
- }
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseInfinity() {
- checkTryParse(Double.POSITIVE_INFINITY, "Infinity");
- checkTryParse(Double.POSITIVE_INFINITY, "+Infinity");
- checkTryParse(Double.NEGATIVE_INFINITY, "-Infinity");
- }
-
- private static final String[] BAD_TRY_PARSE_INPUTS =
- { "", "+-", "+-0", " 5", "32 ", " 55 ", "infinity", "POSITIVE_INFINITY", "0x9A", "0x9A.bE-5",
- ".", ".e5", "NaNd", "InfinityF" };
-
- @GwtIncompatible("Doubles.tryParse")
- public void testTryParseFailures() {
- for (String badInput : BAD_TRY_PARSE_INPUTS) {
- assertFalse(Doubles.FLOATING_POINT_PATTERN.matcher(badInput).matches());
- assertEquals(referenceTryParse(badInput), Doubles.tryParse(badInput));
- assertNull(Doubles.tryParse(badInput));
- }
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Doubles.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(double[].class, new double[0]);
+ tester.testAllPublicStaticMethods(Doubles.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java
index 06dd93b..ded5a77 100644
--- a/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class FloatArrayAsListTest extends TestCase {
private static List<Float> asList(Float[] values) {
@@ -50,7 +49,6 @@ public class FloatArrayAsListTest extends TestCase {
return Floats.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Float>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/FloatsTest.java b/guava-tests/test/com/google/common/primitives/FloatsTest.java
index e4d99ab..55f5bbc 100644
--- a/guava-tests/test/com/google/common/primitives/FloatsTest.java
+++ b/guava-tests/test/com/google/common/primitives/FloatsTest.java
@@ -17,11 +17,10 @@
package com.google.common.primitives;
import static java.lang.Float.NaN;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.Helpers;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -330,31 +329,13 @@ public class FloatsTest extends TestCase {
}
}
- public void testToArray_withConversion() {
- float[] array = {(float) 0, (float) 1, (float) 2};
-
- List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
- List<Integer> ints = Arrays.asList(0, 1, 2);
- List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
- List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
- List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
-
- assertTrue(Arrays.equals(array, Floats.toArray(bytes)));
- assertTrue(Arrays.equals(array, Floats.toArray(shorts)));
- assertTrue(Arrays.equals(array, Floats.toArray(ints)));
- assertTrue(Arrays.equals(array, Floats.toArray(floats)));
- assertTrue(Arrays.equals(array, Floats.toArray(longs)));
- assertTrue(Arrays.equals(array, Floats.toArray(doubles)));
- }
-
public void testAsList_isAView() {
float[] array = {(float) 0, (float) 1};
List<Float> list = Floats.asList(array);
list.set(0, (float) 2);
assertTrue(Arrays.equals(new float[] {(float) 2, (float) 1}, array));
array[1] = (float) 3;
- ASSERT.that(list).has().allOf((float) 2, (float) 3).inOrder();
+ ASSERT.that(list).hasContentsInOrder((float) 2, (float) 3);
}
public void testAsList_toArray_roundTrip() {
@@ -384,103 +365,10 @@ public class FloatsTest extends TestCase {
assertSame(Collections.emptyList(), Floats.asList(EMPTY));
}
- /**
- * A reference implementation for {@code tryParse} that just catches the exception from
- * {@link Float#valueOf}.
- */
- private static Float referenceTryParse(String input) {
- if (input.trim().length() < input.length()) {
- return null;
- }
- try {
- return Float.valueOf(input);
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
- @GwtIncompatible("Floats.tryParse")
- private static void checkTryParse(String input) {
- assertEquals(referenceTryParse(input), Floats.tryParse(input));
- }
-
- @GwtIncompatible("Floats.tryParse")
- private static void checkTryParse(float expected, String input) {
- assertEquals(Float.valueOf(expected), Floats.tryParse(input));
- }
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseHex() {
- for (String signChar : ImmutableList.of("", "+", "-")) {
- for (String hexPrefix : ImmutableList.of("0x", "0X")) {
- for (String iPart : ImmutableList.of("", "0", "1", "F", "f", "c4", "CE")) {
- for (String fPart : ImmutableList.of("", ".", ".F", ".52", ".a")) {
- for (String expMarker : ImmutableList.of("p", "P")) {
- for (String exponent : ImmutableList.of("0", "-5", "+20", "52")) {
- for (String typePart : ImmutableList.of("", "D", "F", "d", "f")) {
- checkTryParse(
- signChar + hexPrefix + iPart + fPart + expMarker + exponent + typePart);
- }
- }
- }
- }
- }
- }
- }
- }
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseAllCodePoints() {
- // Exercise non-ASCII digit test cases and the like.
- char[] tmp = new char[2];
- for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) {
- Character.toChars(i, tmp, 0);
- checkTryParse(String.copyValueOf(tmp, 0, Character.charCount(i)));
- }
- }
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseOfToStringIsOriginal() {
- for (float f : NUMBERS) {
- checkTryParse(f, Float.toString(f));
- }
- }
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseOfToHexStringIsOriginal() {
- for (float f : NUMBERS) {
- checkTryParse(f, Float.toHexString(f));
- }
- }
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseNaN() {
- checkTryParse("NaN");
- checkTryParse("+NaN");
- checkTryParse("-NaN");
- }
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseInfinity() {
- checkTryParse(Float.POSITIVE_INFINITY, "Infinity");
- checkTryParse(Float.POSITIVE_INFINITY, "+Infinity");
- checkTryParse(Float.NEGATIVE_INFINITY, "-Infinity");
- }
-
- private static final String[] BAD_TRY_PARSE_INPUTS =
- { "", "+-", "+-0", " 5", "32 ", " 55 ", "infinity", "POSITIVE_INFINITY", "0x9A", "0x9A.bE-5",
- ".", ".e5", "NaNd", "InfinityF" };
-
- @GwtIncompatible("Floats.tryParse")
- public void testTryParseFailures() {
- for (String badInput : BAD_TRY_PARSE_INPUTS) {
- assertEquals(referenceTryParse(badInput), Floats.tryParse(badInput));
- assertNull(Floats.tryParse(badInput));
- }
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Floats.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(float[].class, new float[0]);
+ tester.testAllPublicStaticMethods(Floats.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java
index efdbbb2..d384149 100644
--- a/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
@SuppressWarnings("cast") // redundant casts are intentional and harmless
public class IntArrayAsListTest extends TestCase {
@@ -51,7 +50,6 @@ public class IntArrayAsListTest extends TestCase {
return Ints.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Integer>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/IntsTest.java b/guava-tests/test/com/google/common/primitives/IntsTest.java
index 6ac5185..8265b80 100644
--- a/guava-tests/test/com/google/common/primitives/IntsTest.java
+++ b/guava-tests/test/com/google/common/primitives/IntsTest.java
@@ -76,7 +76,7 @@ public class IntsTest extends TestCase {
assertEquals(LEAST, Ints.saturatedCast(Long.MIN_VALUE));
}
- private static void assertCastFails(long value) {
+ private void assertCastFails(long value) {
try {
Ints.checkedCast(value);
fail("Cast to int should have failed: " + value);
@@ -356,24 +356,6 @@ public class IntsTest extends TestCase {
}
}
- public void testToArray_withConversion() {
- int[] array = {0, 1, 2};
-
- List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
- List<Integer> ints = Arrays.asList(0, 1, 2);
- List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
- List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
- List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
-
- assertTrue(Arrays.equals(array, Ints.toArray(bytes)));
- assertTrue(Arrays.equals(array, Ints.toArray(shorts)));
- assertTrue(Arrays.equals(array, Ints.toArray(ints)));
- assertTrue(Arrays.equals(array, Ints.toArray(floats)));
- assertTrue(Arrays.equals(array, Ints.toArray(longs)));
- assertTrue(Arrays.equals(array, Ints.toArray(doubles)));
- }
-
public void testAsList_isAView() {
int[] array = {(int) 0, (int) 1};
List<Integer> list = Ints.asList(array);
@@ -411,8 +393,10 @@ public class IntsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Ints.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(int[].class, new int[0]);
+ tester.testAllPublicStaticMethods(Ints.class);
}
@GwtIncompatible("AndroidInteger")
diff --git a/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java
index c5049c4..1fa140f 100644
--- a/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class LongArrayAsListTest extends TestCase {
private static List<Long> asList(Long[] values) {
@@ -50,7 +49,6 @@ public class LongArrayAsListTest extends TestCase {
return Longs.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Long>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/LongsTest.java b/guava-tests/test/com/google/common/primitives/LongsTest.java
index c5098c4..b92dd67 100644
--- a/guava-tests/test/com/google/common/primitives/LongsTest.java
+++ b/guava-tests/test/com/google/common/primitives/LongsTest.java
@@ -16,9 +16,6 @@
package com.google.common.primitives;
-import static java.lang.Long.MAX_VALUE;
-import static java.lang.Long.MIN_VALUE;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.Helpers;
@@ -27,7 +24,6 @@ import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
-import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -48,8 +44,11 @@ public class LongsTest extends TestCase {
private static final long[] ARRAY234
= {(long) 2, (long) 3, (long) 4};
+ private static final long LEAST = Long.MIN_VALUE;
+ private static final long GREATEST = Long.MAX_VALUE;
+
private static final long[] VALUES =
- { MIN_VALUE, (long) -1, (long) 0, (long) 1, MAX_VALUE };
+ { LEAST, (long) -1, (long) 0, (long) 1, GREATEST };
@GwtIncompatible("Long.hashCode returns different values in GWT.")
public void testHashCode() {
@@ -151,8 +150,8 @@ public class LongsTest extends TestCase {
}
public void testMax() {
- assertEquals(MIN_VALUE, Longs.max(MIN_VALUE));
- assertEquals(MAX_VALUE, Longs.max(MAX_VALUE));
+ assertEquals(LEAST, Longs.max(LEAST));
+ assertEquals(GREATEST, Longs.max(GREATEST));
assertEquals((long) 9, Longs.max(
(long) 8, (long) 6, (long) 7,
(long) 5, (long) 3, (long) 0, (long) 9));
@@ -167,8 +166,8 @@ public class LongsTest extends TestCase {
}
public void testMin() {
- assertEquals(MIN_VALUE, Longs.min(MIN_VALUE));
- assertEquals(MAX_VALUE, Longs.min(MAX_VALUE));
+ assertEquals(LEAST, Longs.min(LEAST));
+ assertEquals(GREATEST, Longs.min(GREATEST));
assertEquals((long) 0, Longs.min(
(long) 8, (long) 6, (long) 7,
(long) 5, (long) 3, (long) 0, (long) 9));
@@ -189,23 +188,19 @@ public class LongsTest extends TestCase {
Longs.concat(ARRAY1, ARRAY234)));
}
- private static void assertByteArrayEquals(byte[] expected, byte[] actual) {
- assertTrue(
- "Expected: " + Arrays.toString(expected) + ", but got: " + Arrays.toString(actual),
- Arrays.equals(expected, actual));
- }
-
+ @GwtIncompatible("Longs.toByteArray")
public void testToByteArray() {
- assertByteArrayEquals(
+ assertTrue(Arrays.equals(
new byte[] {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19},
- Longs.toByteArray(0x1213141516171819L));
- assertByteArrayEquals(
+ Longs.toByteArray(0x1213141516171819L)));
+ assertTrue(Arrays.equals(
new byte[] {
(byte) 0xFF, (byte) 0xEE, (byte) 0xDD, (byte) 0xCC,
(byte) 0xBB, (byte) 0xAA, (byte) 0x99, (byte) 0x88},
- Longs.toByteArray(0xFFEEDDCCBBAA9988L));
+ Longs.toByteArray(0xFFEEDDCCBBAA9988L)));
}
+ @GwtIncompatible("Longs.fromByteArray")
public void testFromByteArray() {
assertEquals(0x1213141516171819L, Longs.fromByteArray(
new byte[] {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x33}));
@@ -221,6 +216,7 @@ public class LongsTest extends TestCase {
}
}
+ @GwtIncompatible("Longs.fromBytes")
public void testFromBytes() {
assertEquals(0x1213141516171819L, Longs.fromBytes(
(byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15,
@@ -230,6 +226,7 @@ public class LongsTest extends TestCase {
(byte) 0xBB, (byte) 0xAA, (byte) 0x99, (byte) 0x88));
}
+ @GwtIncompatible("Longs.fromByteArray, Longs.toByteArray")
public void testByteArrayRoundTrips() {
Random r = new Random(5);
byte[] b = new byte[Longs.BYTES];
@@ -279,14 +276,14 @@ public class LongsTest extends TestCase {
public void testLexicographicalComparator() {
List<long[]> ordered = Arrays.asList(
new long[] {},
- new long[] {MIN_VALUE},
- new long[] {MIN_VALUE, MIN_VALUE},
- new long[] {MIN_VALUE, (long) 1},
+ new long[] {LEAST},
+ new long[] {LEAST, LEAST},
+ new long[] {LEAST, (long) 1},
new long[] {(long) 1},
- new long[] {(long) 1, MIN_VALUE},
- new long[] {MAX_VALUE, MAX_VALUE - (long) 1},
- new long[] {MAX_VALUE, MAX_VALUE},
- new long[] {MAX_VALUE, MAX_VALUE, MAX_VALUE});
+ new long[] {(long) 1, LEAST},
+ new long[] {GREATEST, GREATEST - (long) 1},
+ new long[] {GREATEST, GREATEST},
+ new long[] {GREATEST, GREATEST, GREATEST});
Comparator<long[]> comparator = Longs.lexicographicalComparator();
Helpers.testComparator(comparator, ordered);
@@ -339,24 +336,6 @@ public class LongsTest extends TestCase {
}
}
- public void testToArray_withConversion() {
- long[] array = {(long) 0, (long) 1, (long) 2};
-
- List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
- List<Integer> ints = Arrays.asList(0, 1, 2);
- List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
- List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
- List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
-
- assertTrue(Arrays.equals(array, Longs.toArray(bytes)));
- assertTrue(Arrays.equals(array, Longs.toArray(shorts)));
- assertTrue(Arrays.equals(array, Longs.toArray(ints)));
- assertTrue(Arrays.equals(array, Longs.toArray(floats)));
- assertTrue(Arrays.equals(array, Longs.toArray(longs)));
- assertTrue(Arrays.equals(array, Longs.toArray(doubles)));
- }
-
public void testAsList_isAView() {
long[] array = {(long) 0, (long) 1};
List<Long> list = Longs.asList(array);
@@ -394,35 +373,9 @@ public class LongsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Longs.class);
- }
-
- @GwtIncompatible("AndroidInteger")
- public void testTryParse() {
- tryParseAndAssertEquals(0L, "0");
- tryParseAndAssertEquals(0L, "-0");
- tryParseAndAssertEquals(1L, "1");
- tryParseAndAssertEquals(-1L, "-1");
- tryParseAndAssertEquals(8900L, "8900");
- tryParseAndAssertEquals(-8900L, "-8900");
- tryParseAndAssertEquals(MAX_VALUE, Long.toString(MAX_VALUE));
- tryParseAndAssertEquals(MIN_VALUE, Long.toString(MIN_VALUE));
- assertNull(Longs.tryParse(""));
- assertNull(Longs.tryParse("-"));
- assertNull(Longs.tryParse("+1"));
- assertNull(Longs.tryParse("999999999999999999999999"));
- assertNull("Max integer + 1",
- Longs.tryParse(BigInteger.valueOf(MAX_VALUE).add(BigInteger.ONE).toString()));
- assertNull("Min integer - 1",
- Longs.tryParse(BigInteger.valueOf(MIN_VALUE).subtract(BigInteger.ONE).toString()));
- }
-
- /**
- * Applies {@link Longs#tryParse(String)} to the given string and asserts that
- * the result is as expected.
- */
- private static void tryParseAndAssertEquals(Long expected, String value) {
- assertEquals(expected, Longs.tryParse(value));
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(long[].class, new long[0]);
+ tester.testAllPublicStaticMethods(Longs.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/PackageSanityTests.java b/guava-tests/test/com/google/common/primitives/PackageSanityTests.java
deleted file mode 100644
index 3f3e745..0000000
--- a/guava-tests/test/com/google/common/primitives/PackageSanityTests.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.primitives;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Tests basic sanity for each class in the package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {
- public PackageSanityTests() {
- setDefault(String.class, "string");
- }
-}
diff --git a/guava-tests/test/com/google/common/primitives/PrimitivesTest.java b/guava-tests/test/com/google/common/primitives/PrimitivesTest.java
index b3ef33c..9fba2aa 100644
--- a/guava-tests/test/com/google/common/primitives/PrimitivesTest.java
+++ b/guava-tests/test/com/google/common/primitives/PrimitivesTest.java
@@ -76,7 +76,7 @@ public class PrimitivesTest extends TestCase {
}
}
- public void testNullPointerExceptions() {
+ public void testNullPointerExceptions() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Primitives.class);
}
diff --git a/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java
index 78086e4..3fb6a4d 100644
--- a/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java
@@ -19,7 +19,6 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -39,7 +38,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public class ShortArrayAsListTest extends TestCase {
private static List<Short> asList(Short[] values) {
@@ -50,7 +49,6 @@ public class ShortArrayAsListTest extends TestCase {
return Shorts.asList(temp);
}
- @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Short>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/ShortsTest.java b/guava-tests/test/com/google/common/primitives/ShortsTest.java
index 3cc7b61..e98510a 100644
--- a/guava-tests/test/com/google/common/primitives/ShortsTest.java
+++ b/guava-tests/test/com/google/common/primitives/ShortsTest.java
@@ -76,7 +76,7 @@ public class ShortsTest extends TestCase {
assertEquals(LEAST, Shorts.saturatedCast(Long.MIN_VALUE));
}
- private static void assertCastFails(long value) {
+ private void assertCastFails(long value) {
try {
Shorts.checkedCast(value);
fail("Cast to short should have failed: " + value);
@@ -363,24 +363,6 @@ public class ShortsTest extends TestCase {
}
}
- public void testToArray_withConversion() {
- short[] array = {(short) 0, (short) 1, (short) 2};
-
- List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
- List<Integer> ints = Arrays.asList(0, 1, 2);
- List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
- List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
- List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
-
- assertTrue(Arrays.equals(array, Shorts.toArray(bytes)));
- assertTrue(Arrays.equals(array, Shorts.toArray(shorts)));
- assertTrue(Arrays.equals(array, Shorts.toArray(ints)));
- assertTrue(Arrays.equals(array, Shorts.toArray(floats)));
- assertTrue(Arrays.equals(array, Shorts.toArray(longs)));
- assertTrue(Arrays.equals(array, Shorts.toArray(doubles)));
- }
-
public void testAsList_isAView() {
short[] array = {(short) 0, (short) 1};
List<Short> list = Shorts.asList(array);
@@ -418,7 +400,9 @@ public class ShortsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Shorts.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(short[].class, new short[0]);
+ tester.testAllPublicStaticMethods(Shorts.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/SignedBytesTest.java b/guava-tests/test/com/google/common/primitives/SignedBytesTest.java
index 8e205fe..18863a5 100644
--- a/guava-tests/test/com/google/common/primitives/SignedBytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/SignedBytesTest.java
@@ -65,7 +65,7 @@ public class SignedBytesTest extends TestCase {
assertEquals(LEAST, SignedBytes.saturatedCast(Long.MIN_VALUE));
}
- private static void assertCastFails(long value) {
+ private void assertCastFails(long value) {
try {
SignedBytes.checkedCast(value);
fail("Cast to byte should have failed: " + value);
@@ -155,7 +155,9 @@ public class SignedBytesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(SignedBytes.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(byte[].class, new byte[0]);
+ tester.testAllPublicStaticMethods(SignedBytes.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
index 916db9e..88ef454 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
@@ -30,7 +30,6 @@ import java.util.List;
* Unit test for {@link UnsignedBytes}.
*
* @author Kevin Bourrillion
- * @author Louis Wasserman
*/
public class UnsignedBytesTest extends TestCase {
private static final byte LEAST = 0;
@@ -71,7 +70,7 @@ public class UnsignedBytesTest extends TestCase {
assertEquals(LEAST, UnsignedBytes.saturatedCast(Long.MIN_VALUE));
}
- private static void assertCastFails(long value) {
+ private void assertCastFails(long value) {
try {
UnsignedBytes.checkedCast(value);
fail("Cast to byte should have failed: " + value);
@@ -124,95 +123,6 @@ public class UnsignedBytesTest extends TestCase {
assertEquals(GREATEST, UnsignedBytes.min(GREATEST));
assertEquals((byte) 0, UnsignedBytes.min(
(byte) 0, (byte) -128, (byte) -1, (byte) 127, (byte) 1));
- assertEquals((byte) 0, UnsignedBytes.min(
- (byte) -1, (byte) 127, (byte) 1, (byte) -128, (byte) 0));
- }
-
- private static void assertParseFails(String value) {
- try {
- UnsignedBytes.parseUnsignedByte(value);
- fail();
- } catch (NumberFormatException expected) {
- }
- }
-
- public void testParseUnsignedByte() {
- // We can easily afford to test this exhaustively.
- for (int i = 0; i <= 0xff; i++) {
- assertEquals((byte) i, UnsignedBytes.parseUnsignedByte(Integer.toString(i)));
- }
- assertParseFails("1000");
- assertParseFails("-1");
- assertParseFails("-128");
- assertParseFails("256");
- }
-
- public void testMaxValue() {
- assertTrue(UnsignedBytes
- .compare(UnsignedBytes.MAX_VALUE, (byte) (UnsignedBytes.MAX_VALUE + 1)) > 0);
- }
-
- private static void assertParseFails(String value, int radix) {
- try {
- UnsignedBytes.parseUnsignedByte(value, radix);
- fail();
- } catch (NumberFormatException expected) {
- }
- }
-
- public void testParseUnsignedByteWithRadix() throws NumberFormatException {
- // We can easily afford to test this exhaustively.
- for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
- for (int i = 0; i <= 0xff; i++) {
- assertEquals((byte) i, UnsignedBytes.parseUnsignedByte(Integer.toString(i, radix), radix));
- }
- assertParseFails(Integer.toString(1000, radix), radix);
- assertParseFails(Integer.toString(-1, radix), radix);
- assertParseFails(Integer.toString(-128, radix), radix);
- assertParseFails(Integer.toString(256, radix), radix);
- }
- }
-
- public void testParseUnsignedByteThrowsExceptionForInvalidRadix() {
- // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
- // inclusive.
- try {
- UnsignedBytes.parseUnsignedByte("0", Character.MIN_RADIX - 1);
- fail();
- } catch (NumberFormatException nfe) {
- // expected
- }
-
- try {
- UnsignedBytes.parseUnsignedByte("0", Character.MAX_RADIX + 1);
- fail();
- } catch (NumberFormatException nfe) {
- // expected
- }
-
- // The radix is used as an array index, so try a negative value.
- try {
- UnsignedBytes.parseUnsignedByte("0", -1);
- fail();
- } catch (NumberFormatException nfe) {
- // expected
- }
- }
-
- public void testToString() {
- // We can easily afford to test this exhaustively.
- for (int i = 0; i <= 0xff; i++) {
- assertEquals(Integer.toString(i), UnsignedBytes.toString((byte) i));
- }
- }
-
- public void testToStringWithRadix() {
- // We can easily afford to test this exhaustively.
- for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
- for (int i = 0; i <= 0xff; i++) {
- assertEquals(Integer.toString(i, radix), UnsignedBytes.toString((byte) i, radix));
- }
- }
}
public void testJoin() {
@@ -254,7 +164,9 @@ public class UnsignedBytesTest extends TestCase {
assertSame(javaImpl, SerializableTester.reserialize(javaImpl));
}
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(UnsignedBytes.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(byte[].class, new byte[0]);
+ tester.testAllPublicStaticMethods(UnsignedBytes.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java b/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java
index 6297261..fece9c9 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -14,6 +14,8 @@
package com.google.common.primitives;
+import junit.framework.TestCase;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet;
@@ -21,90 +23,47 @@ import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.TestCase;
-
-import java.math.BigInteger;
-
/**
* Tests for {@code UnsignedInteger}.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
public class UnsignedIntegerTest extends TestCase {
private static final ImmutableSet<Integer> TEST_INTS;
- private static final ImmutableSet<Long> TEST_LONGS;
private static int force32(int value) {
- // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
+ // GWT doesn't overflow values to make them 32-bit, so we need to force it.
return value & 0xffffffff;
}
static {
ImmutableSet.Builder<Integer> testIntsBuilder = ImmutableSet.builder();
- ImmutableSet.Builder<Long> testLongsBuilder = ImmutableSet.builder();
for (int i = -3; i <= 3; i++) {
- testIntsBuilder
- .add(i)
- .add(force32(Integer.MIN_VALUE + i))
- .add(force32(Integer.MAX_VALUE + i));
- testLongsBuilder
- .add((long) i)
- .add((long) Integer.MIN_VALUE + i)
- .add((long) Integer.MAX_VALUE + i)
- .add((1L << 32) + i);
+ testIntsBuilder.add(i).add(-i).add(force32(Integer.MIN_VALUE + i))
+ .add(force32(Integer.MAX_VALUE + i));
}
TEST_INTS = testIntsBuilder.build();
- TEST_LONGS = testLongsBuilder.build();
}
- public void testFromIntBitsAndIntValueAreInverses() {
+ public void testAsUnsignedAndIntValueAreInverses() {
for (int value : TEST_INTS) {
- assertEquals(UnsignedInts.toString(value), value, UnsignedInteger.fromIntBits(value)
+ assertEquals(UnsignedInts.toString(value), value, UnsignedInteger.asUnsigned(value)
.intValue());
}
}
- public void testFromIntBitsLongValue() {
+ public void testAsUnsignedLongValue() {
for (int value : TEST_INTS) {
long expected = value & 0xffffffffL;
- assertEquals(UnsignedInts.toString(value), expected, UnsignedInteger.fromIntBits(value)
+ assertEquals(UnsignedInts.toString(value), expected, UnsignedInteger.asUnsigned(value)
.longValue());
}
}
-
- public void testValueOfLong() {
- long min = 0;
- long max = (1L << 32) - 1;
- for (long value : TEST_LONGS) {
- boolean expectSuccess = value >= min && value <= max;
- try {
- assertEquals(value, UnsignedInteger.valueOf(value).longValue());
- assertTrue(expectSuccess);
- } catch (IllegalArgumentException e) {
- assertFalse(expectSuccess);
- }
- }
- }
-
- public void testValueOfBigInteger() {
- long min = 0;
- long max = (1L << 32) - 1;
- for (long value : TEST_LONGS) {
- boolean expectSuccess = value >= min && value <= max;
- try {
- assertEquals(value, UnsignedInteger.valueOf(BigInteger.valueOf(value))
- .longValue());
- assertTrue(expectSuccess);
- } catch (IllegalArgumentException e) {
- assertFalse(expectSuccess);
- }
- }
- }
public void testToString() {
for (int value : TEST_INTS) {
- UnsignedInteger unsignedValue = UnsignedInteger.fromIntBits(value);
+ UnsignedInteger unsignedValue = UnsignedInteger.asUnsigned(value);
assertEquals(unsignedValue.bigIntegerValue().toString(), unsignedValue.toString());
}
}
@@ -113,7 +72,7 @@ public class UnsignedIntegerTest extends TestCase {
public void testToStringRadix() {
for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
for (int l : TEST_INTS) {
- UnsignedInteger value = UnsignedInteger.fromIntBits(l);
+ UnsignedInteger value = UnsignedInteger.asUnsigned(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -123,7 +82,7 @@ public class UnsignedIntegerTest extends TestCase {
int[] radices = {2, 3, 5, 7, 10, 12, 16, 21, 31, 36};
for (int radix : radices) {
for (int l : TEST_INTS) {
- UnsignedInteger value = UnsignedInteger.fromIntBits(l);
+ UnsignedInteger value = UnsignedInteger.asUnsigned(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -131,66 +90,66 @@ public class UnsignedIntegerTest extends TestCase {
public void testFloatValue() {
for (int value : TEST_INTS) {
- UnsignedInteger unsignedValue = UnsignedInteger.fromIntBits(value);
+ UnsignedInteger unsignedValue = UnsignedInteger.asUnsigned(value);
assertEquals(unsignedValue.bigIntegerValue().floatValue(), unsignedValue.floatValue());
}
}
public void testDoubleValue() {
for (int value : TEST_INTS) {
- UnsignedInteger unsignedValue = UnsignedInteger.fromIntBits(value);
+ UnsignedInteger unsignedValue = UnsignedInteger.asUnsigned(value);
assertEquals(unsignedValue.bigIntegerValue().doubleValue(), unsignedValue.doubleValue());
}
}
- public void testPlus() {
+ public void testAdd() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
- UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
int expected = aUnsigned.bigIntegerValue().add(bUnsigned.bigIntegerValue()).intValue();
- UnsignedInteger unsignedSum = aUnsigned.plus(bUnsigned);
+ UnsignedInteger unsignedSum = aUnsigned.add(bUnsigned);
assertEquals(expected, unsignedSum.intValue());
}
}
}
- public void testMinus() {
+ public void testSubtract() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
- UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
int expected =
force32(aUnsigned.bigIntegerValue().subtract(bUnsigned.bigIntegerValue()).intValue());
- UnsignedInteger unsignedSub = aUnsigned.minus(bUnsigned);
+ UnsignedInteger unsignedSub = aUnsigned.subtract(bUnsigned);
assertEquals(expected, unsignedSub.intValue());
}
}
}
@GwtIncompatible("multiply")
- public void testTimes() {
+ public void testMultiply() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
- UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
int expected =
force32(aUnsigned.bigIntegerValue().multiply(bUnsigned.bigIntegerValue()).intValue());
- UnsignedInteger unsignedMul = aUnsigned.times(bUnsigned);
+ UnsignedInteger unsignedMul = aUnsigned.multiply(bUnsigned);
assertEquals(aUnsigned + " * " + bUnsigned, expected, unsignedMul.intValue());
}
}
}
- public void testDividedBy() {
+ public void testDivide() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
if (b != 0) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
- UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
int expected =
aUnsigned.bigIntegerValue().divide(bUnsigned.bigIntegerValue()).intValue();
- UnsignedInteger unsignedDiv = aUnsigned.dividedBy(bUnsigned);
+ UnsignedInteger unsignedDiv = aUnsigned.divide(bUnsigned);
assertEquals(expected, unsignedDiv.intValue());
}
}
@@ -200,32 +159,31 @@ public class UnsignedIntegerTest extends TestCase {
public void testDivideByZeroThrows() {
for (int a : TEST_INTS) {
try {
- UnsignedInteger.fromIntBits(a).divide(UnsignedInteger.ZERO);
+ UnsignedInteger.asUnsigned(a).divide(UnsignedInteger.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
}
- public void testMod() {
+ public void testRemainder() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
if (b != 0) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
- UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
int expected =
- aUnsigned.bigIntegerValue().mod(bUnsigned.bigIntegerValue()).intValue();
- UnsignedInteger unsignedRem = aUnsigned.mod(bUnsigned);
+ aUnsigned.bigIntegerValue().remainder(bUnsigned.bigIntegerValue()).intValue();
+ UnsignedInteger unsignedRem = aUnsigned.remainder(bUnsigned);
assertEquals(expected, unsignedRem.intValue());
}
}
}
}
- @SuppressWarnings("ReturnValueIgnored")
- public void testModByZero() {
+ public void testRemainderByZero() {
for (int a : TEST_INTS) {
try {
- UnsignedInteger.fromIntBits(a).mod(UnsignedInteger.ZERO);
+ UnsignedInteger.asUnsigned(a).remainder(UnsignedInteger.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
@@ -234,8 +192,8 @@ public class UnsignedIntegerTest extends TestCase {
public void testCompare() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
- UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
assertEquals(aUnsigned.bigIntegerValue().compareTo(bUnsigned.bigIntegerValue()),
aUnsigned.compareTo(bUnsigned));
}
@@ -243,11 +201,11 @@ public class UnsignedIntegerTest extends TestCase {
}
@GwtIncompatible("too slow")
- public void testEquals() {
+ public void testEqualsAndValueOf() {
EqualsTester equalsTester = new EqualsTester();
for (int a : TEST_INTS) {
long value = a & 0xffffffffL;
- equalsTester.addEqualityGroup(UnsignedInteger.fromIntBits(a), UnsignedInteger.valueOf(value),
+ equalsTester.addEqualityGroup(UnsignedInteger.asUnsigned(a), UnsignedInteger.valueOf(value),
UnsignedInteger.valueOf(Long.toString(value)),
UnsignedInteger.valueOf(Long.toString(value, 16), 16));
}
@@ -256,7 +214,7 @@ public class UnsignedIntegerTest extends TestCase {
public void testIntValue() {
for (int a : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
int intValue = aUnsigned.bigIntegerValue().intValue();
assertEquals(intValue, aUnsigned.intValue());
}
@@ -265,12 +223,14 @@ public class UnsignedIntegerTest extends TestCase {
@GwtIncompatible("serialization")
public void testSerialization() {
for (int a : TEST_INTS) {
- SerializableTester.reserializeAndAssert(UnsignedInteger.fromIntBits(a));
+ SerializableTester.reserializeAndAssert(UnsignedInteger.asUnsigned(a));
}
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(UnsignedInteger.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(UnsignedInteger.class, UnsignedInteger.ONE);
+ tester.testAllPublicStaticMethods(UnsignedInteger.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java b/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java
index d1fd13c..4ab36de 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -14,21 +14,17 @@
package com.google.common.primitives;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.testing.NullPointerTester;
+import java.util.Random;
import junit.framework.TestCase;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Random;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.testing.NullPointerTester;
/**
* Tests for UnsignedInts
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
@@ -45,9 +41,6 @@ public class UnsignedIntsTest extends TestCase {
0xfffffffdL,
0xfffffffeL,
0xffffffffL};
-
- private static final int LEAST = (int) 0L;
- private static final int GREATEST = (int) 0xffffffffL;
public void testToLong() {
for (long a : UNSIGNED_INTS) {
@@ -64,57 +57,6 @@ public class UnsignedIntsTest extends TestCase {
}
}
}
-
- public void testMax_noArgs() {
- try {
- UnsignedInts.max();
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testMax() {
- assertEquals(LEAST, UnsignedInts.max(LEAST));
- assertEquals(GREATEST, UnsignedInts.max(GREATEST));
- assertEquals((int) 0xff1a618bL, UnsignedInts.max(
- (int) 8L, (int) 6L, (int) 7L,
- (int) 0x12345678L, (int) 0x5a4316b8L,
- (int) 0xff1a618bL, (int) 0L));
- }
-
- public void testMin_noArgs() {
- try {
- UnsignedInts.min();
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testMin() {
- assertEquals(LEAST, UnsignedInts.min(LEAST));
- assertEquals(GREATEST, UnsignedInts.min(GREATEST));
- assertEquals((int) 0L, UnsignedInts.min(
- (int) 8L, (int) 6L, (int) 7L,
- (int) 0x12345678L, (int) 0x5a4316b8L,
- (int) 0xff1a618bL, (int) 0L));
- }
-
- public void testLexicographicalComparator() {
- List<int[]> ordered = Arrays.asList(
- new int[] {},
- new int[] {LEAST},
- new int[] {LEAST, LEAST},
- new int[] {LEAST, (int) 1L},
- new int[] {(int) 1L},
- new int[] {(int) 1L, LEAST},
- new int[] {GREATEST, (GREATEST - (int) 1L)},
- new int[] {GREATEST, GREATEST},
- new int[] {GREATEST, GREATEST, GREATEST}
- );
-
- Comparator<int[]> comparator = UnsignedInts.lexicographicalComparator();
- Helpers.testComparator(comparator, ordered);
- }
public void testDivide() {
for (long a : UNSIGNED_INTS) {
@@ -171,7 +113,7 @@ public class UnsignedIntsTest extends TestCase {
} catch (NumberFormatException expected) {}
}
- public void testParseIntWithRadix() throws NumberFormatException {
+ public void testParseLongWithRadix() throws NumberFormatException {
for (long a : UNSIGNED_INTS) {
for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a, radix), radix));
@@ -194,7 +136,7 @@ public class UnsignedIntsTest extends TestCase {
}
}
- public void testParseIntThrowsExceptionForInvalidRadix() {
+ public void testParseLongThrowsExceptionForInvalidRadix() {
// Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
// inclusive.
try {
@@ -214,43 +156,6 @@ public class UnsignedIntsTest extends TestCase {
} catch (NumberFormatException expected) {}
}
- public void testDecodeInt() {
- assertEquals(0xffffffff, UnsignedInts.decode("0xffffffff"));
- assertEquals(01234567, UnsignedInts.decode("01234567")); // octal
- assertEquals(0x12345678, UnsignedInts.decode("#12345678"));
- assertEquals(76543210, UnsignedInts.decode("76543210"));
- assertEquals(0x13579135, UnsignedInts.decode("0x13579135"));
- assertEquals(0x13579135, UnsignedInts.decode("0X13579135"));
- assertEquals(0, UnsignedInts.decode("0"));
- }
-
- public void testDecodeIntFails() {
- try {
- // One more than maximum value
- UnsignedInts.decode("0xfffffffff");
- fail();
- } catch (NumberFormatException expected) {
- }
-
- try {
- UnsignedInts.decode("-5");
- fail();
- } catch (NumberFormatException expected) {
- }
-
- try {
- UnsignedInts.decode("-0x5");
- fail();
- } catch (NumberFormatException expected) {
- }
-
- try {
- UnsignedInts.decode("-05");
- fail();
- } catch (NumberFormatException expected) {
- }
- }
-
public void testToString() {
int[] bases = {2, 5, 7, 8, 10, 16};
for (long a : UNSIGNED_INTS) {
@@ -260,21 +165,10 @@ public class UnsignedIntsTest extends TestCase {
}
}
- public void testJoin() {
- assertEquals("", join());
- assertEquals("1", join(1));
- assertEquals("1,2", join(1, 2));
- assertEquals("4294967295,2147483648", join(-1, Integer.MIN_VALUE));
-
- assertEquals("123", UnsignedInts.join("", 1, 2, 3));
- }
-
- private static String join(int... values) {
- return UnsignedInts.join(",", values);
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(UnsignedInts.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(int[].class, new int[0]);
+ tester.testAllPublicStaticMethods(UnsignedInts.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java b/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java
index 1df86cb..81f1644 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java
@@ -14,6 +14,10 @@
package com.google.common.primitives;
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet;
@@ -21,10 +25,6 @@ import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
-import junit.framework.TestCase;
-
-import java.math.BigInteger;
-
/**
* Tests for {@code UnsignedLong}.
*
@@ -33,11 +33,9 @@ import java.math.BigInteger;
@GwtCompatible(emulated = true)
public class UnsignedLongTest extends TestCase {
private static final ImmutableSet<Long> TEST_LONGS;
- private static final ImmutableSet<BigInteger> TEST_BIG_INTEGERS;
static {
ImmutableSet.Builder<Long> testLongsBuilder = ImmutableSet.builder();
- ImmutableSet.Builder<BigInteger> testBigIntegersBuilder = ImmutableSet.builder();
for (long i = -3; i <= 3; i++) {
testLongsBuilder
.add(i)
@@ -45,24 +43,14 @@ public class UnsignedLongTest extends TestCase {
.add(Long.MIN_VALUE + i)
.add(Integer.MIN_VALUE + i)
.add(Integer.MAX_VALUE + i);
- BigInteger bigI = BigInteger.valueOf(i);
- testBigIntegersBuilder
- .add(bigI)
- .add(BigInteger.valueOf(Long.MAX_VALUE).add(bigI))
- .add(BigInteger.valueOf(Long.MIN_VALUE).add(bigI))
- .add(BigInteger.valueOf(Integer.MAX_VALUE).add(bigI))
- .add(BigInteger.valueOf(Integer.MIN_VALUE).add(bigI))
- .add(BigInteger.ONE.shiftLeft(63).add(bigI))
- .add(BigInteger.ONE.shiftLeft(64).add(bigI));
}
TEST_LONGS = testLongsBuilder.build();
- TEST_BIG_INTEGERS = testBigIntegersBuilder.build();
}
public void testAsUnsignedAndLongValueAreInverses() {
for (long value : TEST_LONGS) {
assertEquals(
- UnsignedLongs.toString(value), value, UnsignedLong.fromLongBits(value).longValue());
+ UnsignedLongs.toString(value), value, UnsignedLong.asUnsigned(value).longValue());
}
}
@@ -72,40 +60,13 @@ public class UnsignedLongTest extends TestCase {
? BigInteger.valueOf(value)
: BigInteger.valueOf(value).add(BigInteger.ZERO.setBit(64));
assertEquals(UnsignedLongs.toString(value), expected,
- UnsignedLong.fromLongBits(value).bigIntegerValue());
- }
- }
-
- public void testValueOfLong() {
- for (long value : TEST_LONGS) {
- boolean expectSuccess = value >= 0;
- try {
- assertEquals(value, UnsignedLong.valueOf(value).longValue());
- assertTrue(expectSuccess);
- } catch (IllegalArgumentException e) {
- assertFalse(expectSuccess);
- }
- }
- }
-
- public void testValueOfBigInteger() {
- BigInteger min = BigInteger.ZERO;
- BigInteger max = UnsignedLong.MAX_VALUE.bigIntegerValue();
- for (BigInteger big : TEST_BIG_INTEGERS) {
- boolean expectSuccess =
- big.compareTo(min) >= 0 && big.compareTo(max) <= 0;
- try {
- assertEquals(big, UnsignedLong.valueOf(big).bigIntegerValue());
- assertTrue(expectSuccess);
- } catch (IllegalArgumentException e) {
- assertFalse(expectSuccess);
- }
+ UnsignedLong.asUnsigned(value).bigIntegerValue());
}
}
public void testToString() {
for (long value : TEST_LONGS) {
- UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value);
+ UnsignedLong unsignedValue = UnsignedLong.asUnsigned(value);
assertEquals(unsignedValue.bigIntegerValue().toString(), unsignedValue.toString());
}
}
@@ -114,7 +75,7 @@ public class UnsignedLongTest extends TestCase {
public void testToStringRadix() {
for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
for (long l : TEST_LONGS) {
- UnsignedLong value = UnsignedLong.fromLongBits(l);
+ UnsignedLong value = UnsignedLong.asUnsigned(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -124,7 +85,7 @@ public class UnsignedLongTest extends TestCase {
int[] radices = {2, 3, 5, 7, 10, 12, 16, 21, 31, 36};
for (int radix : radices) {
for (long l : TEST_LONGS) {
- UnsignedLong value = UnsignedLong.fromLongBits(l);
+ UnsignedLong value = UnsignedLong.asUnsigned(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -132,112 +93,110 @@ public class UnsignedLongTest extends TestCase {
public void testFloatValue() {
for (long value : TEST_LONGS) {
- UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value);
+ UnsignedLong unsignedValue = UnsignedLong.asUnsigned(value);
assertEquals(unsignedValue.bigIntegerValue().floatValue(), unsignedValue.floatValue());
}
}
public void testDoubleValue() {
for (long value : TEST_LONGS) {
- UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value);
+ UnsignedLong unsignedValue = UnsignedLong.asUnsigned(value);
assertEquals(unsignedValue.bigIntegerValue().doubleValue(), unsignedValue.doubleValue());
}
}
- public void testPlus() {
+ public void testAdd() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
- UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
long expected = aUnsigned
.bigIntegerValue()
.add(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedSum = aUnsigned.plus(bUnsigned);
+ UnsignedLong unsignedSum = aUnsigned.add(bUnsigned);
assertEquals(expected, unsignedSum.longValue());
}
}
}
- public void testMinus() {
+ public void testSubtract() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
- UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
long expected = aUnsigned
.bigIntegerValue()
.subtract(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedSub = aUnsigned.minus(bUnsigned);
+ UnsignedLong unsignedSub = aUnsigned.subtract(bUnsigned);
assertEquals(expected, unsignedSub.longValue());
}
}
}
- public void testTimes() {
+ public void testMultiply() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
- UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
long expected = aUnsigned
.bigIntegerValue()
.multiply(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedMul = aUnsigned.times(bUnsigned);
+ UnsignedLong unsignedMul = aUnsigned.multiply(bUnsigned);
assertEquals(expected, unsignedMul.longValue());
}
}
}
- public void testDividedBy() {
+ public void testDivide() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
if (b != 0) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
- UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
long expected = aUnsigned
.bigIntegerValue()
.divide(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedDiv = aUnsigned.dividedBy(bUnsigned);
+ UnsignedLong unsignedDiv = aUnsigned.divide(bUnsigned);
assertEquals(expected, unsignedDiv.longValue());
}
}
}
}
- @SuppressWarnings("ReturnValueIgnored")
public void testDivideByZeroThrows() {
for (long a : TEST_LONGS) {
try {
- UnsignedLong.fromLongBits(a).dividedBy(UnsignedLong.ZERO);
+ UnsignedLong.asUnsigned(a).divide(UnsignedLong.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
}
- public void testMod() {
+ public void testRemainder() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
if (b != 0) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
- UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
long expected = aUnsigned
.bigIntegerValue()
.remainder(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedRem = aUnsigned.mod(bUnsigned);
+ UnsignedLong unsignedRem = aUnsigned.remainder(bUnsigned);
assertEquals(expected, unsignedRem.longValue());
}
}
}
}
- @SuppressWarnings("ReturnValueIgnored")
- public void testModByZero() {
+ public void testRemainderByZero() {
for (long a : TEST_LONGS) {
try {
- UnsignedLong.fromLongBits(a).mod(UnsignedLong.ZERO);
+ UnsignedLong.asUnsigned(a).remainder(UnsignedLong.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
@@ -246,8 +205,8 @@ public class UnsignedLongTest extends TestCase {
public void testCompare() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
- UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
assertEquals(aUnsigned.bigIntegerValue().compareTo(bUnsigned.bigIntegerValue()),
aUnsigned.compareTo(bUnsigned));
}
@@ -255,12 +214,12 @@ public class UnsignedLongTest extends TestCase {
}
@GwtIncompatible("too slow")
- public void testEquals() {
+ public void testEqualsAndValueOf() {
EqualsTester equalsTester = new EqualsTester();
for (long a : TEST_LONGS) {
BigInteger big =
(a >= 0) ? BigInteger.valueOf(a) : BigInteger.valueOf(a).add(BigInteger.ZERO.setBit(64));
- equalsTester.addEqualityGroup(UnsignedLong.fromLongBits(a), UnsignedLong.valueOf(big),
+ equalsTester.addEqualityGroup(UnsignedLong.asUnsigned(a), UnsignedLong.valueOf(big),
UnsignedLong.valueOf(big.toString()), UnsignedLong.valueOf(big.toString(16), 16));
}
equalsTester.testEquals();
@@ -268,7 +227,7 @@ public class UnsignedLongTest extends TestCase {
public void testIntValue() {
for (long a : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
int intValue = aUnsigned.bigIntegerValue().intValue();
assertEquals(intValue, aUnsigned.intValue());
}
@@ -277,12 +236,14 @@ public class UnsignedLongTest extends TestCase {
@GwtIncompatible("serialization")
public void testSerialization() {
for (long a : TEST_LONGS) {
- SerializableTester.reserializeAndAssert(UnsignedLong.fromLongBits(a));
+ SerializableTester.reserializeAndAssert(UnsignedLong.asUnsigned(a));
}
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(UnsignedLong.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(UnsignedLong.class, UnsignedLong.ONE);
+ tester.testAllPublicStaticMethods(UnsignedLong.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java b/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java
index 7abee87..5928f7e 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -16,97 +16,43 @@ package com.google.common.primitives;
import static java.math.BigInteger.ONE;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.Helpers;
-import com.google.common.testing.NullPointerTester;
+import java.math.BigInteger;
+import java.util.Random;
import junit.framework.TestCase;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Random;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.testing.NullPointerTester;
/**
* Tests for UnsignedLongs
- *
+ *
* @author Brian Milch
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
public class UnsignedLongsTest extends TestCase {
- private static final long LEAST = 0L;
- private static final long GREATEST = 0xffffffffffffffffL;
-
+
public void testCompare() {
// max value
- assertTrue(UnsignedLongs.compare(0, 0xffffffffffffffffL) < 0);
- assertTrue(UnsignedLongs.compare(0xffffffffffffffffL, 0) > 0);
+ assertTrue((UnsignedLongs.compare(0, 0xffffffffffffffffL) < 0));
+ assertTrue((UnsignedLongs.compare(0xffffffffffffffffL, 0) > 0));
// both with high bit set
- assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xffffffffffffffffL) < 0);
- assertTrue(UnsignedLongs.compare(0xffffffffffffffffL, 0xff1a618b7f65ea12L) > 0);
+ assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xffffffffffffffffL) < 0));
+ assertTrue((UnsignedLongs.compare(0xffffffffffffffffL, 0xff1a618b7f65ea12L) > 0));
// one with high bit set
- assertTrue(UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0xff1a618b7f65ea12L) < 0);
- assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0x5a4316b8c153ac4dL) > 0);
+ assertTrue((UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0xff1a618b7f65ea12L) < 0));
+ assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0x5a4316b8c153ac4dL) > 0));
// neither with high bit set
- assertTrue(UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0x6cf78a4b139a4e2aL) < 0);
- assertTrue(UnsignedLongs.compare(0x6cf78a4b139a4e2aL, 0x5a4316b8c153ac4dL) > 0);
+ assertTrue((UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0x6cf78a4b139a4e2aL) < 0));
+ assertTrue((UnsignedLongs.compare(0x6cf78a4b139a4e2aL, 0x5a4316b8c153ac4dL) > 0));
// same value
- assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xff1a618b7f65ea12L) == 0);
- }
-
- public void testMax_noArgs() {
- try {
- UnsignedLongs.max();
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testMax() {
- assertEquals(LEAST, UnsignedLongs.max(LEAST));
- assertEquals(GREATEST, UnsignedLongs.max(GREATEST));
- assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.max(
- 0x5a4316b8c153ac4dL, 8L, 100L,
- 0L, 0x6cf78a4b139a4e2aL, 0xff1a618b7f65ea12L));
- }
-
- public void testMin_noArgs() {
- try {
- UnsignedLongs.min();
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- public void testMin() {
- assertEquals(LEAST, UnsignedLongs.min(LEAST));
- assertEquals(GREATEST, UnsignedLongs.min(GREATEST));
- assertEquals(0L, UnsignedLongs.min(
- 0x5a4316b8c153ac4dL, 8L, 100L,
- 0L, 0x6cf78a4b139a4e2aL, 0xff1a618b7f65ea12L));
- }
-
- public void testLexicographicalComparator() {
- List<long[]> ordered = Arrays.asList(
- new long[] {},
- new long[] {LEAST},
- new long[] {LEAST, LEAST},
- new long[] {LEAST, (long) 1},
- new long[] {(long) 1},
- new long[] {(long) 1, LEAST},
- new long[] {GREATEST, GREATEST - (long) 1},
- new long[] {GREATEST, GREATEST},
- new long[] {GREATEST, GREATEST, GREATEST});
-
- Comparator<long[]> comparator = UnsignedLongs.lexicographicalComparator();
- Helpers.testComparator(comparator, ordered);
+ assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xff1a618b7f65ea12L) == 0));
}
public void testDivide() {
@@ -138,65 +84,33 @@ public class UnsignedLongsTest extends TestCase {
long dividend = r.nextLong();
long divisor = r.nextLong();
// Test that the Euclidean property is preserved:
- assertEquals(0,
- dividend - (divisor * UnsignedLongs.divide(dividend, divisor)
- + UnsignedLongs.remainder(dividend, divisor)));
+ assertTrue(dividend - (divisor * UnsignedLongs.divide(dividend, divisor)
+ + UnsignedLongs.remainder(dividend, divisor)) == 0);
}
}
public void testParseLong() {
- assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("18446744073709551615"));
- assertEquals(0x7fffffffffffffffL, UnsignedLongs.parseUnsignedLong("9223372036854775807"));
- assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.parseUnsignedLong("18382112080831834642"));
- assertEquals(0x5a4316b8c153ac4dL, UnsignedLongs.parseUnsignedLong("6504067269626408013"));
- assertEquals(0x6cf78a4b139a4e2aL, UnsignedLongs.parseUnsignedLong("7851896530399809066"));
-
try {
- // One more than maximum value
- UnsignedLongs.parseUnsignedLong("18446744073709551616");
- fail();
- } catch (NumberFormatException expected) {
+ assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("18446744073709551615"));
+ assertEquals(0x7fffffffffffffffL, UnsignedLongs.parseUnsignedLong("9223372036854775807"));
+ assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.parseUnsignedLong("18382112080831834642"));
+ assertEquals(0x5a4316b8c153ac4dL, UnsignedLongs.parseUnsignedLong("6504067269626408013"));
+ assertEquals(0x6cf78a4b139a4e2aL, UnsignedLongs.parseUnsignedLong("7851896530399809066"));
+ } catch (NumberFormatException e) {
+ fail(e.getMessage());
}
- }
- public void testDecodeLong() {
- assertEquals(0xffffffffffffffffL, UnsignedLongs.decode("0xffffffffffffffff"));
- assertEquals(01234567, UnsignedLongs.decode("01234567")); // octal
- assertEquals(0x1234567890abcdefL, UnsignedLongs.decode("#1234567890abcdef"));
- assertEquals(987654321012345678L, UnsignedLongs.decode("987654321012345678"));
- assertEquals(0x135791357913579L, UnsignedLongs.decode("0x135791357913579"));
- assertEquals(0x135791357913579L, UnsignedLongs.decode("0X135791357913579"));
- assertEquals(0L, UnsignedLongs.decode("0"));
- }
-
- public void testDecodeLongFails() {
+ boolean overflowCaught = false;
try {
// One more than maximum value
- UnsignedLongs.decode("0xfffffffffffffffff");
- fail();
- } catch (NumberFormatException expected) {
- }
-
- try {
- UnsignedLongs.decode("-5");
- fail();
- } catch (NumberFormatException expected) {
- }
-
- try {
- UnsignedLongs.decode("-0x5");
- fail();
- } catch (NumberFormatException expected) {
- }
-
- try {
- UnsignedLongs.decode("-05");
- fail();
- } catch (NumberFormatException expected) {
+ UnsignedLongs.parseUnsignedLong("18446744073709551616");
+ } catch (NumberFormatException e) {
+ overflowCaught = true;
}
+ assertTrue(overflowCaught);
}
- public void testParseLongWithRadix() {
+ public void testParseLongWithRadix() throws NumberFormatException {
assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("ffffffffffffffff", 16));
assertEquals(0x1234567890abcdefL, UnsignedLongs.parseUnsignedLong("1234567890abcdef", 16));
@@ -213,36 +127,35 @@ public class UnsignedLongsTest extends TestCase {
String overflowAsString = overflow.toString(radix);
UnsignedLongs.parseUnsignedLong(overflowAsString, radix);
fail();
- } catch (NumberFormatException expected) {
+ } catch (NumberFormatException nfe) {
+ // expected
}
}
-
- try {
- UnsignedLongs.parseUnsignedLong("1234567890abcdef1", 16);
- fail();
- } catch (NumberFormatException expected) {
- }
}
public void testParseLongThrowsExceptionForInvalidRadix() {
- // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX, inclusive.
+ // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
+ // inclusive.
try {
UnsignedLongs.parseUnsignedLong("0", Character.MIN_RADIX - 1);
fail();
- } catch (NumberFormatException expected) {
+ } catch (NumberFormatException nfe) {
+ // expected
}
try {
UnsignedLongs.parseUnsignedLong("0", Character.MAX_RADIX + 1);
fail();
- } catch (NumberFormatException expected) {
+ } catch (NumberFormatException nfe) {
+ // expected
}
// The radix is used as an array index, so try a negative value.
try {
UnsignedLongs.parseUnsignedLong("0", -1);
fail();
- } catch (NumberFormatException expected) {
+ } catch (NumberFormatException nfe) {
+ // expected
}
}
@@ -252,9 +165,8 @@ public class UnsignedLongsTest extends TestCase {
"7fffffffffffffff",
"ff1a618b7f65ea12",
"5a4316b8c153ac4d",
- "6cf78a4b139a4e2a"
- };
- int[] bases = { 2, 5, 7, 8, 10, 16 };
+ "6cf78a4b139a4e2a"};
+ int[] bases = {2, 5, 7, 8, 10, 16};
for (int base : bases) {
for (String x : tests) {
BigInteger xValue = new BigInteger(x, 16);
@@ -264,19 +176,11 @@ public class UnsignedLongsTest extends TestCase {
}
}
- public void testJoin() {
- assertEquals("", UnsignedLongs.join(","));
- assertEquals("1", UnsignedLongs.join(",", 1));
- assertEquals("1,2", UnsignedLongs.join(",", 1, 2));
- assertEquals("18446744073709551615,9223372036854775808",
- UnsignedLongs.join(",", -1, Long.MIN_VALUE));
- assertEquals("123", UnsignedLongs.join("", 1, 2, 3));
- assertEquals("184467440737095516159223372036854775808",
- UnsignedLongs.join("", -1, Long.MIN_VALUE));
- }
-
@GwtIncompatible("NullPointerTester")
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(UnsignedLongs.class);
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(long[].class, new long[0]);
+ tester.setDefault(BigInteger.class, BigInteger.ZERO);
+ tester.testAllPublicStaticMethods(UnsignedLongs.class);
}
}
diff --git a/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java b/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java
deleted file mode 100644
index 5c3f5fd..0000000
--- a/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.testing.EqualsTester;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.List;
-
-/**
- * Tests for {@link AbstractInvocationHandler}.
- *
- * @author Ben Yu
- */
-public class AbstractInvocationHandlerTest extends TestCase {
-
- private static final ImmutableList<String> LIST1 = ImmutableList.of("one", "two");
- private static final ImmutableList<String> LIST2 = ImmutableList.of("three");
-
- public void testDelegate() {
- assertEquals(LIST1, ImmutableList.copyOf(newDelegatingList(LIST1)));
- assertEquals(LIST1, ImmutableList.copyOf(newDelegatingListWithEquals(LIST1)));
- }
-
- public void testToString() {
- List<String> proxy = newDelegatingList(LIST1);
- assertEquals(Proxy.getInvocationHandler(proxy).toString(), proxy.toString());
- }
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(newDelegatingList(LIST1))
- // Actually, this violates List#equals contract.
- // But whatever, no one is going to proxy List (hopefully).
- .addEqualityGroup(newDelegatingList(LIST1))
- .addEqualityGroup(newDelegatingList(LIST2))
- .addEqualityGroup(newDelegatingListWithEquals(LIST1), newDelegatingListWithEquals(LIST1))
- .addEqualityGroup(
- newDelegatingListWithEquals(LIST2),
- newProxyWithSubHandler1(LIST2), // Makes sure type of handler doesn't affect equality
- newProxyWithSubHandler2(LIST2))
- .addEqualityGroup(newDelegatingIterableWithEquals(LIST2)) // different interface
- .testEquals();
- }
-
- @SuppressWarnings("unchecked") // proxy of List<String>
- private static List<String> newDelegatingList(List<String> delegate) {
- return Reflection.newProxy(List.class, new DelegatingInvocationHandler(delegate));
- }
-
- @SuppressWarnings("unchecked") // proxy of List<String>
- private static List<String> newDelegatingListWithEquals(List<String> delegate) {
- return Reflection.newProxy(List.class, new DelegatingInvocationHandlerWithEquals(delegate));
- }
-
- @SuppressWarnings("unchecked") // proxy of Iterable<String>
- private static Iterable<String> newDelegatingIterableWithEquals(Iterable<String> delegate) {
- return Reflection.newProxy(Iterable.class, new DelegatingInvocationHandlerWithEquals(delegate));
- }
-
- @SuppressWarnings("unchecked") // proxy of List<String>
- private static List<String> newProxyWithSubHandler1(List<String> delegate) {
- return Reflection.newProxy(List.class, new SubHandler1(delegate));
- }
-
- @SuppressWarnings("unchecked") // proxy of List<String>
- private static List<String> newProxyWithSubHandler2(List<String> delegate) {
- return Reflection.newProxy(List.class, new SubHandler2(delegate));
- }
-
- private static class DelegatingInvocationHandler extends AbstractInvocationHandler {
- final Object delegate;
-
- DelegatingInvocationHandler(Object delegate) {
- this.delegate = checkNotNull(delegate);
- }
-
- @Override protected Object handleInvocation(Object proxy, Method method, Object[] args)
- throws Throwable {
- return method.invoke(delegate, args);
- }
-
- @Override public String toString() {
- return "some arbitrary string";
- }
- }
-
- private static class DelegatingInvocationHandlerWithEquals extends DelegatingInvocationHandler {
-
- DelegatingInvocationHandlerWithEquals(Object delegate) {
- super(delegate);
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof DelegatingInvocationHandlerWithEquals) {
- DelegatingInvocationHandlerWithEquals that = (DelegatingInvocationHandlerWithEquals) obj;
- return delegate.equals(that.delegate);
- } else {
- return false;
- }
- }
-
- @Override public int hashCode() {
- return delegate.hashCode();
- }
- }
-
- private static class SubHandler1 extends DelegatingInvocationHandlerWithEquals {
- SubHandler1(Object delegate) {
- super(delegate);
- }
- }
-
- private static class SubHandler2 extends DelegatingInvocationHandlerWithEquals {
- SubHandler2(Object delegate) {
- super(delegate);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/ClassPathTest.java b/guava-tests/test/com/google/common/reflect/ClassPathTest.java
deleted file mode 100644
index b1bf897..0000000
--- a/guava-tests/test/com/google/common/reflect/ClassPathTest.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.ClassPath.ClassInfo;
-import com.google.common.reflect.ClassPath.ResourceInfo;
-import com.google.common.reflect.subpackage.ClassInSubPackage;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Map;
-import java.util.Set;
-import java.util.jar.Manifest;
-
-/**
- * Functional tests of {@link ClassPath}.
- */
-public class ClassPathTest extends TestCase {
-
- public void testGetResources() throws Exception {
- Map<String, ResourceInfo> byName = Maps.newHashMap();
- Map<String, ResourceInfo> byToString = Maps.newHashMap();
- ClassPath classpath = ClassPath.from(getClass().getClassLoader());
- for (ResourceInfo resource : classpath.getResources()) {
- byName.put(resource.getResourceName(), resource);
- byToString.put(resource.toString(), resource);
- assertNotNull(resource.url());
- }
- String testResourceName = "com/google/common/reflect/test.txt";
- ASSERT.that(byName.keySet()).has().allOf(
- "com/google/common/reflect/ClassPath.class",
- "com/google/common/reflect/ClassPathTest.class",
- "com/google/common/reflect/ClassPathTest$Nested.class",
- testResourceName);
- assertFalse(byName.keySet().contains("META-INF/MANIFEST.MF"));
- ASSERT.that(byToString.keySet()).has().allOf(
- "com.google.common.reflect.ClassPath",
- "com.google.common.reflect.ClassPathTest",
- "com/google/common/reflect/ClassPathTest$Nested.class",
- testResourceName);
- assertFalse(byToString.keySet().contains("META-INF/MANIFEST.MF"));
- assertEquals(getClass().getClassLoader().getResource(testResourceName),
- byName.get("com/google/common/reflect/test.txt").url());
- }
-
- public void testGetClasses() throws Exception {
- Set<String> names = Sets.newHashSet();
- Set<String> strings = Sets.newHashSet();
- Set<Class<?>> classes = Sets.newHashSet();
- Set<String> packageNames = Sets.newHashSet();
- Set<String> simpleNames = Sets.newHashSet();
- ClassPath classpath = ClassPath.from(getClass().getClassLoader());
- for (ClassInfo classInfo
- : classpath.getTopLevelClasses(ClassPathTest.class.getPackage().getName())) {
- names.add(classInfo.getName());
- strings.add(classInfo.toString());
- classes.add(classInfo.load());
- packageNames.add(classInfo.getPackageName());
- simpleNames.add(classInfo.getSimpleName());
- }
- ASSERT.that(names).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName());
- ASSERT.that(strings).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName());
- ASSERT.that(classes).has().allOf(ClassPath.class, ClassPathTest.class);
- ASSERT.that(packageNames).has().item(ClassPath.class.getPackage().getName());
- ASSERT.that(simpleNames).has().allOf("ClassPath", "ClassPathTest");
- assertFalse(classes.contains(ClassInSubPackage.class));
- }
-
- public void testGetClassesRecursive() throws Exception {
- Set<Class<?>> classes = Sets.newHashSet();
- ClassPath classpath = ClassPath.from(ClassPathTest.class.getClassLoader());
- for (ClassInfo classInfo
- : classpath.getTopLevelClassesRecursive(ClassPathTest.class.getPackage().getName())) {
- classes.add(classInfo.load());
- }
- ASSERT.that(classes).has().allOf(ClassPathTest.class, ClassInSubPackage.class);
- }
-
- public void testGetClasses_diamond() throws Exception {
- ClassLoader parent = ClassPathTest.class.getClassLoader();
- ClassLoader sub1 = new ClassLoader(parent) {};
- ClassLoader sub2 = new ClassLoader(parent) {};
- assertEquals(findClass(ClassPath.from(sub1).getTopLevelClasses(), ClassPathTest.class),
- findClass(ClassPath.from(sub2).getTopLevelClasses(), ClassPathTest.class));
- }
-
- public void testEquals() {
- new EqualsTester()
- .addEqualityGroup(classInfo(ClassPathTest.class), classInfo(ClassPathTest.class))
- .addEqualityGroup(classInfo(Test.class), classInfo(Test.class, getClass().getClassLoader()))
- .addEqualityGroup(
- new ResourceInfo("a/b/c.txt", getClass().getClassLoader()),
- new ResourceInfo("a/b/c.txt", getClass().getClassLoader()))
- .addEqualityGroup(
- new ResourceInfo("x.txt", getClass().getClassLoader()))
- .testEquals();
- }
-
- public void testClassPathEntries_emptyURLClassLoader_noParent() {
- ASSERT.that(ClassPath.getClassPathEntries(new URLClassLoader(new URL[0], null)).keySet())
- .isEmpty();
- }
-
- public void testClassPathEntries_URLClassLoader_noParent() throws Exception {
- URL url1 = new URL("file:/a");
- URL url2 = new URL("file:/b");
- URLClassLoader classloader = new URLClassLoader(new URL[] {url1, url2}, null);
- assertEquals(
- ImmutableMap.of(url1.toURI(), classloader, url2.toURI(), classloader),
- ClassPath.getClassPathEntries(classloader));
- }
-
- public void testClassPathEntries_URLClassLoader_withParent() throws Exception {
- URL url1 = new URL("file:/a");
- URL url2 = new URL("file:/b");
- URLClassLoader parent = new URLClassLoader(new URL[] {url1}, null);
- URLClassLoader child = new URLClassLoader(new URL[] {url2}, parent) {};
- ImmutableMap<URI, ClassLoader> classPathEntries = ClassPath.getClassPathEntries(child);
- assertEquals(ImmutableMap.of(url1.toURI(), parent, url2.toURI(), child), classPathEntries);
- ASSERT.that(classPathEntries.keySet()).has().allOf(url1.toURI(), url2.toURI()).inOrder();
- }
-
- public void testClassPathEntries_duplicateUri_parentWins() throws Exception {
- URL url = new URL("file:/a");
- URLClassLoader parent = new URLClassLoader(new URL[] {url}, null);
- URLClassLoader child = new URLClassLoader(new URL[] {url}, parent) {};
- assertEquals(ImmutableMap.of(url.toURI(), parent), ClassPath.getClassPathEntries(child));
- }
-
- public void testClassPathEntries_notURLClassLoader_noParent() {
- ASSERT.that(ClassPath.getClassPathEntries(new ClassLoader(null) {}).keySet()).isEmpty();
- }
-
- public void testClassPathEntries_notURLClassLoader_withParent() throws Exception {
- URL url = new URL("file:/a");
- URLClassLoader parent = new URLClassLoader(new URL[] {url}, null);
- assertEquals(
- ImmutableMap.of(url.toURI(), parent),
- ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
- }
-
- public void testClassPathEntries_notURLClassLoader_withParentAndGrandParent() throws Exception {
- URL url1 = new URL("file:/a");
- URL url2 = new URL("file:/b");
- URLClassLoader grandParent = new URLClassLoader(new URL[] {url1}, null);
- URLClassLoader parent = new URLClassLoader(new URL[] {url2}, grandParent);
- assertEquals(
- ImmutableMap.of(url1.toURI(), grandParent, url2.toURI(), parent),
- ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
- }
-
- public void testClassPathEntries_notURLClassLoader_withGrandParent() throws Exception {
- URL url = new URL("file:/a");
- URLClassLoader grandParent = new URLClassLoader(new URL[] {url}, null);
- ClassLoader parent = new ClassLoader(grandParent) {};
- assertEquals(
- ImmutableMap.of(url.toURI(), grandParent),
- ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
- }
-
- public void testBrowseFromFile_fileNotExists() throws IOException {
- ClassLoader classLoader = ClassPathTest.class.getClassLoader();
- ImmutableSet.Builder<ResourceInfo> resources = ImmutableSet.builder();
- ClassPath.browseFrom(new File("no/such/file/anywhere"), classLoader, resources);
- ASSERT.that(resources.build()).isEmpty();
- }
-
- public void testBrowseFromFile_notJarFile() throws IOException {
- ClassLoader classLoader = ClassPathTest.class.getClassLoader();
- ImmutableSet.Builder<ResourceInfo> resources = ImmutableSet.builder();
- File notJar = File.createTempFile("not_a_jar", "txt");
- try {
- ClassPath.browseFrom(notJar, classLoader, resources);
- } finally {
- notJar.delete();
- }
- ASSERT.that(resources.build()).isEmpty();
- }
-
- public void testGetClassPathEntry() throws URISyntaxException {
- assertEquals(URI.create("file:/usr/test/dep.jar"),
- ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "file:/usr/test/dep.jar"));
- assertEquals(URI.create("file:/home/build/a.jar"),
- ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "a.jar"));
- assertEquals(URI.create("file:/home/build/x/y/z"),
- ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z"));
- assertEquals(URI.create("file:/home/build/x/y/z.jar"),
- ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z.jar"));
- }
-
- public void testGetClassPathFromManifest_nullManifest() {
- ASSERT.that(ClassPath.getClassPathFromManifest(new File("some.jar"), null)).isEmpty();
- }
-
- public void testGetClassPathFromManifest_noClassPath() throws IOException {
- File jarFile = new File("base.jar");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest("")))
- .isEmpty();
- }
-
- public void testGetClassPathFromManifest_emptyClassPath() throws IOException {
- File jarFile = new File("base.jar");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifestClasspath("")))
- .isEmpty();
- }
-
- public void testGetClassPathFromManifest_badClassPath() throws IOException {
- File jarFile = new File("base.jar");
- Manifest manifest = manifestClasspath("an_invalid^path");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .isEmpty();
- }
-
- public void testGetClassPathFromManifest_relativeDirectory() throws IOException {
- File jarFile = new File("base/some.jar");
- // with/relative/directory is the Class-Path value in the mf file.
- Manifest manifest = manifestClasspath("with/relative/dir");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("base/with/relative/dir").toURI()).inOrder();
- }
-
- public void testGetClassPathFromManifest_relativeJar() throws IOException {
- File jarFile = new File("base/some.jar");
- // with/relative/directory is the Class-Path value in the mf file.
- Manifest manifest = manifestClasspath("with/relative.jar");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("base/with/relative.jar").toURI()).inOrder();
- }
-
- public void testGetClassPathFromManifest_jarInCurrentDirectory() throws IOException {
- File jarFile = new File("base/some.jar");
- // with/relative/directory is the Class-Path value in the mf file.
- Manifest manifest = manifestClasspath("current.jar");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("base/current.jar").toURI()).inOrder();
- }
-
- public void testGetClassPathFromManifest_absoluteDirectory() throws IOException {
- File jarFile = new File("base/some.jar");
- Manifest manifest = manifestClasspath("file:/with/absolute/dir");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("/with/absolute/dir").toURI()).inOrder();
- }
-
- public void testGetClassPathFromManifest_absoluteJar() throws IOException {
- File jarFile = new File("base/some.jar");
- Manifest manifest = manifestClasspath("file:/with/absolute.jar");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("/with/absolute.jar").toURI()).inOrder();
- }
-
- public void testGetClassPathFromManifest_multiplePaths() throws IOException {
- File jarFile = new File("base/some.jar");
- Manifest manifest = manifestClasspath("file:/with/absolute.jar relative.jar relative/dir");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(
- new File("/with/absolute.jar").toURI(),
- new File("base/relative.jar").toURI(),
- new File("base/relative/dir").toURI())
- .inOrder();
- }
-
- public void testGetClassPathFromManifest_leadingBlanks() throws IOException {
- File jarFile = new File("base/some.jar");
- Manifest manifest = manifestClasspath(" relative.jar");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("base/relative.jar").toURI()).inOrder();
- }
-
- public void testGetClassPathFromManifest_trailingBlanks() throws IOException {
- File jarFile = new File("base/some.jar");
- Manifest manifest = manifestClasspath("relative.jar ");
- ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
- .has().allOf(new File("base/relative.jar").toURI()).inOrder();
- }
-
- public void testGetClassName() {
- assertEquals("abc.d.Abc", ClassPath.getClassName("abc/d/Abc.class"));
- }
-
- public void testResourceInfo_of() {
- assertEquals(ClassInfo.class, resourceInfo(ClassPathTest.class).getClass());
- assertEquals(ClassInfo.class, resourceInfo(ClassPath.class).getClass());
- assertEquals(ResourceInfo.class, resourceInfo(Nested.class).getClass());
- }
-
- public void testGetSimpleName() {
- assertEquals("Foo",
- new ClassInfo("Foo.class", getClass().getClassLoader()).getSimpleName());
- assertEquals("Foo",
- new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getSimpleName());
- }
-
- public void testGetPackageName() {
- assertEquals("",
- new ClassInfo("Foo.class", getClass().getClassLoader()).getPackageName());
- assertEquals("a.b",
- new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getPackageName());
- }
-
- private static class Nested {}
-
- public void testNulls() throws IOException {
- new NullPointerTester().testAllPublicStaticMethods(ClassPath.class);
- new NullPointerTester()
- .testAllPublicInstanceMethods(ClassPath.from(getClass().getClassLoader()));
- }
-
- private static ClassPath.ClassInfo findClass(
- Iterable<ClassPath.ClassInfo> classes, Class<?> cls) {
- for (ClassPath.ClassInfo classInfo : classes) {
- if (classInfo.getName().equals(cls.getName())) {
- return classInfo;
- }
- }
- throw new AssertionError("failed to find " + cls);
- }
-
- private static ResourceInfo resourceInfo(Class<?> cls) {
- return ResourceInfo.of(cls.getName().replace('.', '/') + ".class", cls.getClassLoader());
- }
-
- private static ClassInfo classInfo(Class<?> cls) {
- return classInfo(cls, cls.getClassLoader());
- }
-
- private static ClassInfo classInfo(Class<?> cls, ClassLoader classLoader) {
- return new ClassInfo(cls.getName().replace('.', '/') + ".class", classLoader);
- }
-
- private static Manifest manifestClasspath(String classpath) throws IOException {
- return manifest("Class-Path: " + classpath + "\n");
- }
-
- private static Manifest manifest(String content) throws IOException {
- InputStream in = new ByteArrayInputStream(content.getBytes(Charsets.US_ASCII));
- Manifest manifest = new Manifest();
- manifest.read(in);
- return manifest;
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/ElementTest.java b/guava-tests/test/com/google/common/reflect/ElementTest.java
deleted file mode 100644
index a34693a..0000000
--- a/guava-tests/test/com/google/common/reflect/ElementTest.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Constructor;
-
-/**
- * Unit tests of {@link Element}.
- *
- * @author Ben Yu
- */
-public class ElementTest extends TestCase {
-
- public void testPrivateField() throws Exception {
- Element element = A.field("privateField");
- assertTrue(element.isPrivate());
- assertFalse(element.isAbstract());
- assertFalse(element.isPackagePrivate());
- assertFalse(element.isProtected());
- assertFalse(element.isPublic());
- assertFalse(element.isFinal());
- assertFalse(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testPackagePrivateField() throws Exception {
- Element element = A.field("packagePrivateField");
- assertFalse(element.isPrivate());
- assertTrue(element.isPackagePrivate());
- assertFalse(element.isProtected());
- assertFalse(element.isPublic());
- assertFalse(element.isFinal());
- assertFalse(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testProtectedField() throws Exception {
- Element element = A.field("protectedField");
- assertFalse(element.isPrivate());
- assertFalse(element.isPackagePrivate());
- assertTrue(element.isProtected());
- assertFalse(element.isPublic());
- assertFalse(element.isFinal());
- assertFalse(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testPublicField() throws Exception {
- Element element = A.field("publicField");
- assertFalse(element.isPrivate());
- assertFalse(element.isPackagePrivate());
- assertFalse(element.isProtected());
- assertTrue(element.isPublic());
- assertFalse(element.isFinal());
- assertFalse(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testFinalField() throws Exception {
- Element element = A.field("finalField");
- assertTrue(element.isFinal());
- assertFalse(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testStaticField() throws Exception {
- Element element = A.field("staticField");
- assertTrue(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testVolatileField() throws Exception {
- Element element = A.field("volatileField");
- assertTrue(element.isVolatile());
- }
-
- public void testTransientField() throws Exception {
- Element element = A.field("transientField");
- assertTrue(element.isTransient());
- }
-
- public void testConstructor() throws Exception {
- Element element = A.constructor();
- assertTrue(element.isPublic());
- assertFalse(element.isPackagePrivate());
- assertFalse(element.isAbstract());
- assertFalse(element.isStatic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testAbstractMethod() throws Exception {
- Element element = A.method("abstractMethod");
- assertTrue(element.isPackagePrivate());
- assertTrue(element.isAbstract());
- assertFalse(element.isFinal());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testOverridableMethod() throws Exception {
- Element element = A.method("overridableMethod");
- assertTrue(element.isPackagePrivate());
- assertFalse(element.isAbstract());
- assertFalse(element.isFinal());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testPrivateMethod() throws Exception {
- Element element = A.method("privateMethod");
- assertFalse(element.isAbstract());
- assertTrue(element.isPrivate());
- assertFalse(element.isPackagePrivate());
- assertFalse(element.isPublic());
- assertFalse(element.isProtected());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testProtectedMethod() throws Exception {
- Element element = A.method("protectedMethod");
- assertFalse(element.isAbstract());
- assertFalse(element.isPrivate());
- assertFalse(element.isPackagePrivate());
- assertFalse(element.isFinal());
- assertFalse(element.isPublic());
- assertTrue(element.isProtected());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testFinalMethod() throws Exception {
- Element element = A.method("publicFinalMethod");
- assertFalse(element.isAbstract());
- assertFalse(element.isPrivate());
- assertTrue(element.isFinal());
- assertTrue(element.isPublic());
- assertTrue(element.isAnnotationPresent(Tested.class));
- }
-
- public void testNativeMethod() throws Exception {
- Element element = A.method("nativeMethod");
- assertTrue(element.isNative());
- assertTrue(element.isPackagePrivate());
- }
-
- public void testSynchronizedMethod() throws Exception {
- Element element = A.method("synchronizedMethod");
- assertTrue(element.isSynchronized());
- }
-
- public void testUnannotatedMethod() throws Exception {
- Element element = A.method("notAnnotatedMethod");
- assertFalse(element.isAnnotationPresent(Tested.class));
- }
-
- public void testEquals() throws Exception {
- new EqualsTester()
- .addEqualityGroup(A.field("privateField"), A.field("privateField"))
- .addEqualityGroup(A.field("publicField"))
- .addEqualityGroup(A.constructor(), A.constructor())
- .addEqualityGroup(A.method("privateMethod"), A.method("privateMethod"))
- .addEqualityGroup(A.method("publicFinalMethod"))
- .testEquals();
- }
-
- public void testNulls() {
- new NullPointerTester()
- .testAllPublicStaticMethods(Element.class);
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- private @interface Tested {}
-
- private static abstract class A {
- @Tested private boolean privateField;
- @Tested int packagePrivateField;
- @Tested protected int protectedField;
- @Tested public String publicField;
- @Tested private static Iterable<String> staticField;
- @Tested private final Object finalField;
- private volatile char volatileField;
- private transient long transientField;
-
- @Tested public A(Object finalField) {
- this.finalField = finalField;
- }
-
- @Tested abstract void abstractMethod();
-
- @Tested void overridableMethod() {}
-
- @Tested protected void protectedMethod() {}
-
- @Tested private void privateMethod() {}
-
- @Tested public final void publicFinalMethod() {}
-
- void notAnnotatedMethod() {}
-
- static Element field(String name) throws Exception {
- Element element = new Element(A.class.getDeclaredField(name));
- assertEquals(name, element.getName());
- assertEquals(A.class, element.getDeclaringClass());
- return element;
- }
-
- static Element constructor() throws Exception {
- Constructor<?> constructor = A.class.getDeclaredConstructor(Object.class);
- Element element = new Element(constructor);
- assertEquals(constructor.getName(), element.getName());
- assertEquals(A.class, element.getDeclaringClass());
- return element;
- }
-
- static Element method(String name, Class<?>... parameterTypes) throws Exception {
- Element element = new Element(A.class.getDeclaredMethod(name, parameterTypes));
- assertEquals(name, element.getName());
- assertEquals(A.class, element.getDeclaringClass());
- return element;
- }
-
- native void nativeMethod();
-
- synchronized void synchronizedMethod() {}
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java b/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java
deleted file mode 100644
index 7422fba..0000000
--- a/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestMapGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Unit test for {@link ImmutableTypeToInstanceMap}.
- *
- * @author Ben Yu
- */
-public class ImmutableTypeToInstanceMapTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(ImmutableTypeToInstanceMapTest.class);
-
- suite.addTest(MapTestSuiteBuilder
- .using(new TestTypeToInstanceMapGenerator() {
- // Other tests will verify what real, warning-free usage looks like
- // but here we have to do some serious fudging
- @Override
- @SuppressWarnings("unchecked")
- public Map<TypeToken, Object> create(Object... elements) {
- ImmutableTypeToInstanceMap.Builder<Object> builder
- = ImmutableTypeToInstanceMap.builder();
- for (Object object : elements) {
- Entry<TypeToken, Object> entry = (Entry<TypeToken, Object>) object;
- builder.put(entry.getKey(), entry.getValue());
- }
- return (Map) builder.build();
- }
- })
- .named("ImmutableTypeToInstanceMap")
- .withFeatures(
- MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- MapFeature.RESTRICTS_KEYS,
- CollectionFeature.KNOWN_ORDER,
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- return suite;
- }
-
- public void testEmpty() {
- assertEquals(0, ImmutableTypeToInstanceMap.of().size());
- }
-
- public void testPrimitiveAndWrapper() {
- ImmutableTypeToInstanceMap<Number> map = ImmutableTypeToInstanceMap.<Number>builder()
- .put(Integer.class, 0)
- .put(int.class, 1)
- .build();
- assertEquals(2, map.size());
-
- assertEquals(0, (int) map.getInstance(Integer.class));
- assertEquals(0, (int) map.getInstance(TypeToken.of(Integer.class)));
- assertEquals(1, (int) map.getInstance(int.class));
- assertEquals(1, (int) map.getInstance(TypeToken.of(int.class)));
- }
-
- public void testParameterizedType() {
- TypeToken<ImmutableList<Integer>> type = new TypeToken<ImmutableList<Integer>>() {};
- ImmutableTypeToInstanceMap<Iterable<?>> map = ImmutableTypeToInstanceMap.<Iterable<?>>builder()
- .put(type, ImmutableList.of(1))
- .build();
- assertEquals(1, map.size());
- assertEquals(ImmutableList.of(1), map.getInstance(type));
- }
-
- public void testGeneriArrayType() {
- @SuppressWarnings("unchecked") // Trying to test generic array
- ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)};
- TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {};
- ImmutableTypeToInstanceMap<Iterable<?>[]> map =
- ImmutableTypeToInstanceMap.<Iterable<?>[]>builder()
- .put(type, array)
- .build();
- assertEquals(1, map.size());
- ASSERT.that(map.getInstance(type)).has().allOf(array[0]).inOrder();
- }
-
- public void testWildcardType() {
- TypeToken<ImmutableList<?>> type = new TypeToken<ImmutableList<?>>() {};
- ImmutableTypeToInstanceMap<Iterable<?>> map = ImmutableTypeToInstanceMap.<Iterable<?>>builder()
- .put(type, ImmutableList.of(1))
- .build();
- assertEquals(1, map.size());
- assertEquals(ImmutableList.of(1), map.getInstance(type));
- }
-
- public void testGetInstance_containsTypeVariable() {
- ImmutableTypeToInstanceMap<Iterable<Number>> map = ImmutableTypeToInstanceMap.of();
- try {
- map.getInstance(this.<Number>anyIterableType());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testPut_containsTypeVariable() {
- ImmutableTypeToInstanceMap.Builder<Iterable<Integer>> builder =
- ImmutableTypeToInstanceMap.builder();
- try {
- builder.put(this.<Integer>anyIterableType(), ImmutableList.of(1));
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- private <T> TypeToken<Iterable<T>> anyIterableType() {
- return new TypeToken<Iterable<T>>() {};
- }
-
- abstract static class TestTypeToInstanceMapGenerator
- implements TestMapGenerator<TypeToken, Object> {
-
- @Override public TypeToken[] createKeyArray(int length) {
- return new TypeToken[length];
- }
-
- @Override public Object[] createValueArray(int length) {
- return new Object[length];
- }
-
- @Override
- public SampleElements<Entry<TypeToken, Object>> samples() {
- Entry<TypeToken, Object> entry1 =
- Maps.immutableEntry((TypeToken) TypeToken.of(Integer.class), (Object) 0);
- Entry<TypeToken, Object> entry2 =
- Maps.immutableEntry((TypeToken) TypeToken.of(Number.class), (Object) 1);
- Entry<TypeToken, Object> entry3 =
- Maps.immutableEntry((TypeToken) new TypeToken<ImmutableList<Integer>>() {},
- (Object) ImmutableList.of(2));
- Entry<TypeToken, Object> entry4 =
- Maps.immutableEntry((TypeToken) new TypeToken<int[]>() {}, (Object) new int[] {3});
- Entry<TypeToken, Object> entry5 =
- Maps.immutableEntry((TypeToken) new TypeToken<Iterable<?>>() {},
- (Object) ImmutableList.of("4"));
- return new SampleElements<Entry<TypeToken, Object>>(
- entry1, entry2, entry3, entry4, entry5
- );
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Entry<TypeToken, Object>[] createArray(int length) {
- return new Entry[length];
- }
-
- @Override
- public Iterable<Entry<TypeToken, Object>> order(List<Entry<TypeToken, Object>> insertionOrder) {
- return insertionOrder;
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/InvokableTest.java b/guava-tests/test/com/google/common/reflect/InvokableTest.java
deleted file mode 100644
index cad4616..0000000
--- a/guava-tests/test/com/google/common/reflect/InvokableTest.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.TypeVariable;
-import java.util.Collections;
-
-import javax.annotation.Nullable;
-
-/**
- * Unit tests for {@link Invokable}.
- *
- * @author Ben Yu
- */
-public class InvokableTest extends TestCase {
-
- public void testConstructor_returnType() throws Exception {
- assertEquals(Prepender.class,
- Prepender.constructor().getReturnType().getType());
- }
-
- public void testConstructor_exceptionTypes() throws Exception {
- assertEquals(ImmutableList.of(TypeToken.of(NullPointerException.class)),
- Prepender.constructor(String.class, int.class).getExceptionTypes());
- }
-
- public void testConstructor_typeParameters() throws Exception {
- TypeVariable<?>[] variables =
- Prepender.constructor().getTypeParameters();
- assertEquals(1, variables.length);
- assertEquals("A", variables[0].getName());
- }
-
- public void testConstructor_parameters() throws Exception {
- Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class);
- ImmutableList<Parameter> parameters = delegate.getParameters();
- assertEquals(2, parameters.size());
- assertEquals(String.class, parameters.get(0).getType().getType());
- assertTrue(parameters.get(0).isAnnotationPresent(NotBlank.class));
- assertEquals(int.class, parameters.get(1).getType().getType());
- assertFalse(parameters.get(1).isAnnotationPresent(NotBlank.class));
- new EqualsTester()
- .addEqualityGroup(parameters.get(0))
- .addEqualityGroup(parameters.get(1))
- .testEquals();
- }
-
- public void testConstructor_call() throws Exception {
- Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class);
- Prepender prepender = delegate.invoke(null, "a", 1);
- assertEquals("a", prepender.prefix);
- assertEquals(1, prepender.times);
- }
-
- public void testConstructor_returning() throws Exception {
- Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class)
- .returning(Prepender.class);
- Prepender prepender = delegate.invoke(null, "a", 1);
- assertEquals("a", prepender.prefix);
- assertEquals(1, prepender.times);
- }
-
- public void testConstructor_invalidReturning() throws Exception {
- Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class);
- try {
- delegate.returning(SubPrepender.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testStaticMethod_returnType() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
- assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
- }
-
- public void testStaticMethod_exceptionTypes() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
- assertEquals(ImmutableList.of(), delegate.getExceptionTypes());
- }
-
- public void testStaticMethod_typeParameters() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
- TypeVariable<?>[] variables = delegate.getTypeParameters();
- assertEquals(1, variables.length);
- assertEquals("T", variables[0].getName());
- }
-
- public void testStaticMethod_parameters() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
- ImmutableList<Parameter> parameters = delegate.getParameters();
- assertEquals(2, parameters.size());
- assertEquals(String.class, parameters.get(0).getType().getType());
- assertTrue(parameters.get(0).isAnnotationPresent(NotBlank.class));
- assertEquals(new TypeToken<Iterable<String>>() {}, parameters.get(1).getType());
- assertFalse(parameters.get(1).isAnnotationPresent(NotBlank.class));
- new EqualsTester()
- .addEqualityGroup(parameters.get(0))
- .addEqualityGroup(parameters.get(1))
- .testEquals();
- }
-
- public void testStaticMethod_call() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
- @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
- Iterable<String> result = (Iterable<String>)
- delegate.invoke(null, "a", ImmutableList.of("b", "c"));
- assertEquals(ImmutableList.of("a", "b", "c"), ImmutableList.copyOf(result));
- }
-
- public void testStaticMethod_returning() throws Exception {
- Invokable<?, Iterable<String>> delegate = Prepender.method(
- "prepend", String.class, Iterable.class)
- .returning(new TypeToken<Iterable<String>>() {});
- assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
- Iterable<String> result = delegate.invoke(null, "a", ImmutableList.of("b", "c"));
- assertEquals(ImmutableList.of("a", "b", "c"), ImmutableList.copyOf(result));
- }
-
- public void testStaticMethod_returningRawType() throws Exception {
- @SuppressWarnings("rawtypes") // the purpose is to test raw type
- Invokable<?, Iterable> delegate = Prepender.method(
- "prepend", String.class, Iterable.class)
- .returning(Iterable.class);
- assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
- @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
- Iterable<String> result = delegate.invoke(null, "a", ImmutableList.of("b", "c"));
- assertEquals(ImmutableList.of("a", "b", "c"), ImmutableList.copyOf(result));
- }
-
- public void testStaticMethod_invalidReturning() throws Exception {
- Invokable<?, Object> delegate = Prepender.method("prepend", String.class, Iterable.class);
- try {
- delegate.returning(new TypeToken<Iterable<Integer>>() {});
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testInstanceMethod_returnType() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
- assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
- }
-
- public void testInstanceMethod_exceptionTypes() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
- assertEquals(
- ImmutableList.of(
- TypeToken.of(IllegalArgumentException.class),
- TypeToken.of(NullPointerException.class)),
- delegate.getExceptionTypes());
- }
-
- public void testInstanceMethod_typeParameters() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
- assertEquals(0, delegate.getTypeParameters().length);
- }
-
- public void testInstanceMethod_parameters() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
- ImmutableList<Parameter> parameters = delegate.getParameters();
- assertEquals(1, parameters.size());
- assertEquals(new TypeToken<Iterable<String>>() {}, parameters.get(0).getType());
- assertEquals(0, parameters.get(0).getAnnotations().length);
- new EqualsTester()
- .addEqualityGroup(parameters.get(0))
- .testEquals();
- }
-
- public void testInstanceMethod_call() throws Exception {
- Invokable<Prepender, ?> delegate = Prepender.method("prepend", Iterable.class);
- @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
- Iterable<String> result = (Iterable<String>)
- delegate.invoke(new Prepender("a", 2), ImmutableList.of("b", "c"));
- assertEquals(ImmutableList.of("a", "a", "b", "c"), ImmutableList.copyOf(result));
- }
-
- public void testInstanceMethod_returning() throws Exception {
- Invokable<Prepender, Iterable<String>> delegate = Prepender.method(
- "prepend", Iterable.class)
- .returning(new TypeToken<Iterable<String>>() {});
- assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
- Iterable<String> result = delegate.invoke(new Prepender("a", 2), ImmutableList.of("b", "c"));
- assertEquals(ImmutableList.of("a", "a", "b", "c"), ImmutableList.copyOf(result));
- }
-
- public void testInstanceMethod_returningRawType() throws Exception {
- @SuppressWarnings("rawtypes") // the purpose is to test raw type
- Invokable<Prepender, Iterable> delegate = Prepender.method("prepend", Iterable.class)
- .returning(Iterable.class);
- assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
- @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
- Iterable<String> result = delegate.invoke(
- new Prepender("a", 2), ImmutableList.of("b", "c"));
- assertEquals(ImmutableList.of("a", "a", "b", "c"), ImmutableList.copyOf(result));
- }
-
- public void testInstanceMethod_invalidReturning() throws Exception {
- Invokable<?, Object> delegate = Prepender.method("prepend", Iterable.class);
- try {
- delegate.returning(new TypeToken<Iterable<Integer>>() {});
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testPrivateInstanceMethod_isOverridable() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("privateMethod");
- assertTrue(delegate.isPrivate());
- assertFalse(delegate.isOverridable());
- assertFalse(delegate.isVarArgs());
- }
-
- public void testPrivateFinalInstanceMethod_isOverridable() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("privateFinalMethod");
- assertTrue(delegate.isPrivate());
- assertTrue(delegate.isFinal());
- assertFalse(delegate.isOverridable());
- assertFalse(delegate.isVarArgs());
- }
-
- public void testStaticMethod_isOverridable() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("staticMethod");
- assertTrue(delegate.isStatic());
- assertFalse(delegate.isOverridable());
- assertFalse(delegate.isVarArgs());
- }
-
- public void testStaticFinalMethod_isFinal() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("staticFinalMethod");
- assertTrue(delegate.isStatic());
- assertTrue(delegate.isFinal());
- assertFalse(delegate.isOverridable());
- assertFalse(delegate.isVarArgs());
- }
-
- static class Foo {}
-
- public void testConstructor_isOverridablel() throws Exception {
- Invokable<?, ?> delegate = Invokable.from(Foo.class.getDeclaredConstructor());
- assertFalse(delegate.isOverridable());
- assertFalse(delegate.isVarArgs());
- }
-
- public void testMethod_isVarArgs() throws Exception {
- Invokable<?, ?> delegate = Prepender.method("privateVarArgsMethod", String[].class);
- assertTrue(delegate.isVarArgs());
- }
-
- public void testConstructor_isVarArgs() throws Exception {
- Invokable<?, ?> delegate = Prepender.constructor(String[].class);
- assertTrue(delegate.isVarArgs());
- }
-
- public void testGetOwnerType_constructor() throws Exception {
- Invokable<String, String> invokable = Invokable.from(String.class.getConstructor());
- assertEquals(TypeToken.of(String.class), invokable.getOwnerType());
- }
-
- public void testGetOwnerType_method() throws Exception {
- Invokable<?, ?> invokable = Invokable.from(String.class.getMethod("length"));
- assertEquals(TypeToken.of(String.class), invokable.getOwnerType());
- }
-
- private static final class FinalClass {
- @SuppressWarnings("unused") // used by reflection
- void notFinalMethod() {}
- }
-
- public void testNonFinalMethodInFinalClass_isOverridable() throws Exception {
- Invokable<?, ?> delegate = Invokable.from(
- FinalClass.class.getDeclaredMethod("notFinalMethod"));
- assertFalse(delegate.isOverridable());
- assertFalse(delegate.isVarArgs());
- }
-
- private class InnerWithDefaultConstructor {
- class NestedInner {}
- }
-
- public void testInnerClassDefaultConstructor() throws Exception {
- Constructor<?> constructor =
- InnerWithDefaultConstructor.class.getDeclaredConstructors() [0];
- assertEquals(0, Invokable.from(constructor).getParameters().size());
- }
-
- public void testNestedInnerClassDefaultConstructor() throws Exception {
- Constructor<?> constructor =
- InnerWithDefaultConstructor.NestedInner.class.getDeclaredConstructors() [0];
- assertEquals(0, Invokable.from(constructor).getParameters().size());
- }
-
- private class InnerWithOneParameterConstructor {
- @SuppressWarnings("unused") // called by reflection
- public InnerWithOneParameterConstructor(String s) {}
- }
-
- public void testInnerClassWithOneParameterConstructor() throws Exception {
- Constructor<?> constructor =
- InnerWithOneParameterConstructor.class.getDeclaredConstructors()[0];
- Invokable<?, ?> invokable = Invokable.from(constructor);
- assertEquals(1, invokable.getParameters().size());
- assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
- }
-
- private class InnerWithAnnotatedConstructorParameter {
- @SuppressWarnings("unused") // called by reflection
- InnerWithAnnotatedConstructorParameter(@Nullable String s) {}
- }
-
- public void testInnerClassWithAnnotatedConstructorParameter() throws Exception {
- Constructor<?> constructor =
- InnerWithAnnotatedConstructorParameter.class.getDeclaredConstructors() [0];
- Invokable<?, ?> invokable = Invokable.from(constructor);
- assertEquals(1, invokable.getParameters().size());
- assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
- }
-
- private class InnerWithGenericConstructorParameter {
- @SuppressWarnings("unused") // called by reflection
- InnerWithGenericConstructorParameter(Iterable<String> it, String s) {}
- }
-
- public void testInnerClassWithGenericConstructorParameter() throws Exception {
- Constructor<?> constructor =
- InnerWithGenericConstructorParameter.class.getDeclaredConstructors() [0];
- Invokable<?, ?> invokable = Invokable.from(constructor);
- assertEquals(2, invokable.getParameters().size());
- assertEquals(new TypeToken<Iterable<String>>() {},
- invokable.getParameters().get(0).getType());
- assertEquals(TypeToken.of(String.class),
- invokable.getParameters().get(1).getType());
- }
-
- public void testAnonymousClassDefaultConstructor() throws Exception {
- final int i = 1;
- final String s = "hello world";
- Class<?> anonymous = new Runnable() {
- @Override public void run() {
- System.out.println(s + i);
- }
- }.getClass();
- Constructor<?> constructor =
- anonymous.getDeclaredConstructors() [0];
- assertEquals(0, Invokable.from(constructor).getParameters().size());
- }
-
- public void testAnonymousClassWithTwoParametersConstructor() throws Exception {
- abstract class Base {
- @SuppressWarnings("unused") // called by reflection
- Base(String s, int i) {}
- }
- Class<?> anonymous = new Base("test", 0) {}.getClass();
- Constructor<?> constructor =
- anonymous.getDeclaredConstructors() [0];
- assertEquals(2, Invokable.from(constructor).getParameters().size());
- }
-
- public void testLocalClassDefaultConstructor() throws Exception {
- final int i = 1;
- final String s = "hello world";
- class LocalWithDefaultConstructor implements Runnable {
- @Override public void run() {
- System.out.println(s + i);
- }
- }
- Constructor<?> constructor =
- LocalWithDefaultConstructor.class.getDeclaredConstructors() [0];
- assertEquals(0, Invokable.from(constructor).getParameters().size());
- }
-
- public void testStaticAnonymousClassDefaultConstructor() throws Exception {
- doTestStaticAnonymousClassDefaultConstructor();
- }
-
- private static void doTestStaticAnonymousClassDefaultConstructor() throws Exception {
- final int i = 1;
- final String s = "hello world";
- Class<?> anonymous = new Runnable() {
- @Override public void run() {
- System.out.println(s + i);
- }
- }.getClass();
- Constructor<?> constructor =
- anonymous.getDeclaredConstructors() [0];
- assertEquals(0, Invokable.from(constructor).getParameters().size());
- }
-
- public void testLocalClassWithOneParameterConstructor() throws Exception {
- final int i = 1;
- final String s = "hello world";
- class LocalWithOneParameterConstructor {
- @SuppressWarnings("unused") // called by reflection
- public LocalWithOneParameterConstructor(String x) {
- System.out.println(s + i);
- }
- }
- Constructor<?> constructor =
- LocalWithOneParameterConstructor.class.getDeclaredConstructors()[0];
- Invokable<?, ?> invokable = Invokable.from(constructor);
- assertEquals(1, invokable.getParameters().size());
- assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
- }
-
- public void testLocalClassWithAnnotatedConstructorParameter() throws Exception {
- class LocalWithAnnotatedConstructorParameter {
- @SuppressWarnings("unused") // called by reflection
- LocalWithAnnotatedConstructorParameter(@Nullable String s) {}
- }
- Constructor<?> constructor =
- LocalWithAnnotatedConstructorParameter.class.getDeclaredConstructors() [0];
- Invokable<?, ?> invokable = Invokable.from(constructor);
- assertEquals(1, invokable.getParameters().size());
- assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
- }
-
- public void testLocalClassWithGenericConstructorParameter() throws Exception {
- class LocalWithGenericConstructorParameter {
- @SuppressWarnings("unused") // called by reflection
- LocalWithGenericConstructorParameter(Iterable<String> it, String s) {}
- }
- Constructor<?> constructor =
- LocalWithGenericConstructorParameter.class.getDeclaredConstructors() [0];
- Invokable<?, ?> invokable = Invokable.from(constructor);
- assertEquals(2, invokable.getParameters().size());
- assertEquals(new TypeToken<Iterable<String>>() {},
- invokable.getParameters().get(0).getType());
- assertEquals(TypeToken.of(String.class),
- invokable.getParameters().get(1).getType());
- }
-
- public void testEquals() throws Exception {
- new EqualsTester()
- .addEqualityGroup(Prepender.constructor(), Prepender.constructor())
- .addEqualityGroup(Prepender.constructor(String.class, int.class))
- .addEqualityGroup(Prepender.method("privateMethod"), Prepender.method("privateMethod"))
- .addEqualityGroup(Prepender.method("privateFinalMethod"))
- .testEquals();
- }
-
- public void testNulls() {
- new NullPointerTester().testAllPublicStaticMethods(Invokable.class);
- new NullPointerTester().testAllPublicInstanceMethods(Prepender.method("staticMethod"));
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- private @interface NotBlank {}
-
- /** Class for testing constructor, static method and instance method. */
- @SuppressWarnings("unused") // most are called by reflection
- private static class Prepender {
-
- private final String prefix;
- private final int times;
-
- Prepender(@NotBlank String prefix, int times) throws NullPointerException {
- this.prefix = prefix;
- this.times = times;
- }
-
- Prepender(String... varargs) {
- this(null, 0);
- }
-
- // just for testing
- private <A> Prepender() {
- this(null, 0);
- }
-
- static <T> Iterable<String> prepend(@NotBlank String first, Iterable<String> tail) {
- return Iterables.concat(ImmutableList.of(first), tail);
- }
-
- Iterable<String> prepend(Iterable<String> tail)
- throws IllegalArgumentException, NullPointerException {
- return Iterables.concat(Collections.nCopies(times, prefix), tail);
- }
-
- static Invokable<?, Prepender> constructor(Class<?>... parameterTypes) throws Exception {
- Constructor<Prepender> constructor = Prepender.class.getDeclaredConstructor(parameterTypes);
- return Invokable.from(constructor);
- }
-
- static Invokable<Prepender, Object> method(String name, Class<?>... parameterTypes) {
- try {
- Method method = Prepender.class.getDeclaredMethod(name, parameterTypes);
- @SuppressWarnings("unchecked") // The method is from Prepender.
- Invokable<Prepender, Object> invokable = (Invokable<Prepender, Object>)
- Invokable.from(method);
- return invokable;
- } catch (NoSuchMethodException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private void privateMethod() {}
-
- private final void privateFinalMethod() {}
-
- static void staticMethod() {}
-
- static final void staticFinalMethod() {}
-
- private void privateVarArgsMethod(String... varargs) {}
- }
-
- private static class SubPrepender extends Prepender {
- @SuppressWarnings("unused") // needed to satisfy compiler, never called
- public SubPrepender() throws NullPointerException {
- throw new AssertionError();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java b/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java
deleted file mode 100644
index 18e0058..0000000
--- a/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
-import com.google.common.collect.testing.testers.MapPutTester;
-import com.google.common.reflect.ImmutableTypeToInstanceMapTest.TestTypeToInstanceMapGenerator;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Unit test of {@link MutableTypeToInstanceMap}.
- *
- * @author Ben Yu
- */
-public class MutableTypeToInstanceMapTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(MutableTypeToInstanceMapTest.class);
-
- // Suppress this one because the tester framework doesn't understand that
- // *some* remappings will be allowed and others not.
- Method remapTest = null;
- try {
- remapTest = MapPutTester.class.getMethod(
- "testPut_replaceNullValueWithNonNullSupported");
- } catch (NoSuchMethodException e) {
- throw new AssertionError();
- }
-
- suite.addTest(MapTestSuiteBuilder
- .using(new TestTypeToInstanceMapGenerator() {
- // Other tests will verify what real, warning-free usage looks like
- // but here we have to do some serious fudging
- @Override
- @SuppressWarnings("unchecked")
- public Map<TypeToken, Object> create(Object... elements) {
- MutableTypeToInstanceMap<Object> map
- = new MutableTypeToInstanceMap<Object>();
- for (Object object : elements) {
- Entry<TypeToken, Object> entry = (Entry<TypeToken, Object>) object;
- map.putInstance(entry.getKey(), entry.getValue());
- }
- return (Map) map;
- }
- })
- .named("MutableTypeToInstanceMap")
- .withFeatures(
- MapFeature.SUPPORTS_REMOVE,
- MapFeature.RESTRICTS_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_QUERIES)
- .suppressing(remapTest)
- .createTestSuite());
-
- return suite;
- }
-
- private TypeToInstanceMap<Object> map;
-
- @Override protected void setUp() throws Exception {
- map = new MutableTypeToInstanceMap<Object>();
- }
-
- public void testPutThrows() {
- try {
- map.put(TypeToken.of(Integer.class), new Integer(5));
- fail();
- } catch (UnsupportedOperationException expected) {}
- }
-
- public void testPutAllThrows() {
- try {
- map.putAll(ImmutableMap.of(TypeToken.of(Integer.class), new Integer(5)));
- fail();
- } catch (UnsupportedOperationException expected) {}
- }
-
- public void testPutAndGetInstance() {
- assertNull(map.putInstance(Integer.class, new Integer(5)));
-
- Integer oldValue = map.putInstance(Integer.class, new Integer(7));
- assertEquals(5, (int) oldValue);
-
- Integer newValue = map.getInstance(Integer.class);
- assertEquals(7, (int) newValue);
- assertEquals(7, (int) map.getInstance(TypeToken.of(Integer.class)));
-
- // Won't compile: map.putInstance(Double.class, new Long(42));
- }
-
- public void testNull() {
- try {
- map.putInstance((TypeToken) null, new Integer(1));
- fail();
- } catch (NullPointerException expected) {
- }
- map.putInstance(Integer.class, null);
- assertNull(map.get(Integer.class));
- assertNull(map.getInstance(Integer.class));
-
- map.putInstance(Long.class, null);
- assertNull(map.get(Long.class));
- assertNull(map.getInstance(Long.class));
- }
-
- public void testPrimitiveAndWrapper() {
- assertNull(map.getInstance(int.class));
- assertNull(map.getInstance(Integer.class));
-
- assertNull(map.putInstance(int.class, 0));
- assertNull(map.putInstance(Integer.class, 1));
- assertEquals(2, map.size());
-
- assertEquals(0, (int) map.getInstance(int.class));
- assertEquals(1, (int) map.getInstance(Integer.class));
-
- assertEquals(0, (int) map.putInstance(int.class, null));
- assertEquals(1, (int) map.putInstance(Integer.class, null));
-
- assertNull(map.getInstance(int.class));
- assertNull(map.getInstance(Integer.class));
- assertEquals(2, map.size());
- }
-
- public void testParameterizedType() {
- TypeToken<ImmutableList<Integer>> type = new TypeToken<ImmutableList<Integer>>() {};
- map.putInstance(type, ImmutableList.of(1));
- assertEquals(1, map.size());
- assertEquals(ImmutableList.of(1), map.getInstance(type));
- }
-
- public void testGeneriArrayType() {
- @SuppressWarnings("unchecked") // Trying to test generic array
- ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)};
- TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {};
- map.putInstance(type, array);
- assertEquals(1, map.size());
- ASSERT.that(map.getInstance(type)).has().allOf(array[0]).inOrder();
- }
-
- public void testWildcardType() {
- TypeToken<ImmutableList<?>> type = new TypeToken<ImmutableList<?>>() {};
- map.putInstance(type, ImmutableList.of(1));
- assertEquals(1, map.size());
- assertEquals(ImmutableList.of(1), map.getInstance(type));
- }
-
- public void testGetInstance_withTypeVariable() {
- try {
- map.getInstance(this.<Number>anyIterableType());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testPutInstance_withTypeVariable() {
- try {
- map.putInstance(this.<Integer>anyIterableType(), ImmutableList.of(1));
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- private <T> TypeToken<Iterable<T>> anyIterableType() {
- return new TypeToken<Iterable<T>>() {};
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/PackageSanityTests.java b/guava-tests/test/com/google/common/reflect/PackageSanityTests.java
deleted file mode 100644
index 8398be5..0000000
--- a/guava-tests/test/com/google/common/reflect/PackageSanityTests.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Tests nulls for the entire package.
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-tests/test/com/google/common/reflect/ParameterTest.java b/guava-tests/test/com/google/common/reflect/ParameterTest.java
deleted file mode 100644
index 88d04b7..0000000
--- a/guava-tests/test/com/google/common/reflect/ParameterTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.Method;
-
-/**
- * Tests for {@link Parameter}.
- *
- * @author Ben Yu
- */
-public class ParameterTest extends TestCase {
-
- public void testNulls() {
- for (Method method : ParameterTest.class.getDeclaredMethods()) {
- for (Parameter param : Invokable.from(method).getParameters()) {
- new NullPointerTester().testAllPublicInstanceMethods(param);
- }
- }
- }
-
- public void testEquals() {
- EqualsTester tester = new EqualsTester();
- for (Method method : ParameterTest.class.getDeclaredMethods()) {
- for (Parameter param : Invokable.from(method).getParameters()) {
- tester.addEqualityGroup(param);
- }
- }
- tester.testEquals();
- }
-
- @SuppressWarnings("unused")
- private void someMethod(int i, int j) {}
-
- @SuppressWarnings("unused")
- private void anotherMethod(int i, String s) {}
-}
diff --git a/guava-tests/test/com/google/common/reflect/ReflectionTest.java b/guava-tests/test/com/google/common/reflect/ReflectionTest.java
deleted file mode 100644
index 2923b47..0000000
--- a/guava-tests/test/com/google/common/reflect/ReflectionTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2006 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-/** Tests for {@link Reflection} */
-public class ReflectionTest extends TestCase {
-
- public void testGetPackageName() throws Exception {
- assertEquals("java.lang", Reflection.getPackageName(Iterable.class));
- assertEquals("java", Reflection.getPackageName("java.MyType"));
- assertEquals("java.lang", Reflection.getPackageName(Iterable.class.getName()));
- assertEquals("", Reflection.getPackageName("NoPackage"));
- assertEquals("java.util", Reflection.getPackageName(Map.Entry.class));
- }
-
- public void testNewProxy() throws Exception {
- Runnable runnable = Reflection.newProxy(Runnable.class, X_RETURNER);
- assertEquals("x", runnable.toString());
- }
-
- public void testNewProxyCantWorkOnAClass() throws Exception {
- try {
- Reflection.newProxy(Object.class, X_RETURNER);
- fail();
- } catch (IllegalArgumentException expected) {
- }
- }
-
- private static final InvocationHandler X_RETURNER = new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- return "x";
- }
- };
-
- private static int classesInitialized = 0;
- private static class A {
- static {
- ++classesInitialized;
- }
- }
- private static class B {
- static {
- ++classesInitialized;
- }
- }
- private static class C {
- static {
- ++classesInitialized;
- }
- }
-
- public void testInitialize() {
- assertEquals("This test can't be included twice in the same suite.", 0, classesInitialized);
-
- Reflection.initialize(A.class);
- assertEquals(1, classesInitialized);
-
- Reflection.initialize(
- A.class, // Already initialized (above)
- B.class,
- C.class);
- assertEquals(3, classesInitialized);
- }
-
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(Reflection.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/TypeParameterTest.java b/guava-tests/test/com/google/common/reflect/TypeParameterTest.java
deleted file mode 100644
index 9ac8a4a..0000000
--- a/guava-tests/test/com/google/common/reflect/TypeParameterTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.TypeVariable;
-
-/**
- * Unit test for {@link TypeParameter}.
- *
- * @author Ben Yu
- */
-public class TypeParameterTest extends TestCase {
-
- public <T> void testCaptureTypeParameter() throws Exception {
- TypeVariable<?> variable = new TypeParameter<T>() {}.typeVariable;
- TypeVariable<?> expected = TypeParameterTest.class
- .getDeclaredMethod("testCaptureTypeParameter")
- .getTypeParameters()[0];
- assertEquals(expected, variable);
- }
-
- public void testConcreteTypeRejected() {
- try {
- new TypeParameter<String>() {};
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <A, B> void testEquals() throws Exception {
- Method method = TypeParameterTest.class.getDeclaredMethod("testEquals");
- new EqualsTester()
- .addEqualityGroup(
- new TypeParameter<A>() {}, new TypeParameter<A>() {})
- .addEqualityGroup(new TypeParameter<B>() {})
- .testEquals();
- }
-
- public void testNullPointers() {
- new NullPointerTester().testAllPublicStaticMethods(TypeParameter.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/TypeResolverTest.java b/guava-tests/test/com/google/common/reflect/TypeResolverTest.java
deleted file mode 100644
index 84b1b5e..0000000
--- a/guava-tests/test/com/google/common/reflect/TypeResolverTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit tests of {@link TypeResolver}.
- *
- * @author Ben Yu
- */
-public class TypeResolverTest extends TestCase {
-
- public void testWhere_noMapping() {
- Type t = aTypeVariable();
- assertEquals(t, new TypeResolver().resolveType(t));
- }
-
- public void testWhere_typeVariableMapping() {
- Type t = aTypeVariable();
- assertEquals(String.class, new TypeResolver().where(t, String.class).resolveType(t));
- }
-
- public <T> void testWhere_indirectMapping() {
- Type t1 = new TypeCapture<T>() {}.capture();
- Type t2 = aTypeVariable();
- assertEquals(String.class,
- new TypeResolver().where(t1, t2).where(t2, String.class).resolveType(t1));
- }
-
- public void testWhere_typeVariableSelfMapping() {
- TypeResolver resolver = new TypeResolver();
- Type t = aTypeVariable();
- assertEquals(t, resolver.where(t, t).resolveType(t));
- }
-
- public <T> void testWhere_parameterizedSelfMapping() {
- TypeResolver resolver = new TypeResolver();
- Type t = new TypeCapture<List<T>>() {}.capture();
- assertEquals(t, resolver.where(t, t).resolveType(t));
- }
-
- public <T> void testWhere_genericArraySelfMapping() {
- TypeResolver resolver = new TypeResolver();
- Type t = new TypeCapture<T[]>() {}.capture();
- assertEquals(t, resolver.where(t, t).resolveType(t));
- }
-
- public <T> void testWhere_rawClassSelfMapping() {
- TypeResolver resolver = new TypeResolver();
- assertEquals(String.class,
- resolver.where(String.class, String.class).resolveType(String.class));
- }
-
- public <T> void testWhere_wildcardSelfMapping() {
- TypeResolver resolver = new TypeResolver();
- Type t = aWildcardType();
- assertEquals(t, resolver.where(t, t).resolveType(t));
- }
-
- public <T> void testWhere_duplicateMapping() {
- Type t = aTypeVariable();
- TypeResolver resolver = new TypeResolver().where(t, String.class);
- try {
- resolver.where(t, String.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T1, T2 extends List<T1>> void testWhere_recursiveMapping() {
- Type t1 = new TypeCapture<T1>() {}.capture();
- Type t2 = new TypeCapture<T2>() {}.capture();
- assertEquals(t2, new TypeResolver().where(t1, t2).resolveType(t1));
- }
-
- public <T> void testWhere_genericArrayMapping() {
- Type t = new TypeCapture<T>() {}.capture();
- assertEquals(String.class, new TypeResolver()
- .where(new TypeCapture<T[]>() {}.capture(), String[].class)
- .resolveType(t));
- }
-
- public <T> void testWhere_primitiveArrayMapping() {
- Type t = new TypeCapture<T>() {}.capture();
- assertEquals(int.class,
- new TypeResolver().where(new TypeCapture<T[]>() {}.capture(), int[].class).resolveType(t));
- }
-
- public <T> void testWhere_parameterizedTypeMapping() {
- Type t = new TypeCapture<T>() {}.capture();
- assertEquals(String.class, new TypeResolver()
- .where(new TypeCapture<List<T>>() {}.capture(),
- new TypeCapture<List<String>>() {}.capture())
- .resolveType(t));
- assertEquals(Types.subtypeOf(String.class), new TypeResolver()
- .where(new TypeCapture<List<T>>() {}.capture(),
- new TypeCapture<List<? extends String>>() {}.capture())
- .resolveType(t));
- assertEquals(Types.supertypeOf(String.class), new TypeResolver()
- .where(new TypeCapture<List<T>>() {}.capture(),
- new TypeCapture<List<? super String>>() {}.capture())
- .resolveType(t));
- }
-
- public <T> void testWhere_wildcardTypeMapping() {
- Type t = new TypeCapture<T>() {}.capture();
- assertEquals(String.class, new TypeResolver()
- .where(new TypeCapture<List<? extends T>>() {}.capture(),
- new TypeCapture<List<? extends String>>() {}.capture())
- .resolveType(t));
- assertEquals(String.class, new TypeResolver()
- .where(new TypeCapture<List<? super T>>() {}.capture(),
- new TypeCapture<List<? super String>>() {}.capture())
- .resolveType(t));
- }
-
- public <T> void testWhere_incompatibleGenericArrayMapping() {
- try {
- new TypeResolver().where(new TypeCapture<T[]>() {}.capture(), String.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_incompatibleParameterizedTypeMapping() {
- try {
- new TypeResolver().where(new TypeCapture<Iterable<T>>() {}.capture(), List.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_impossibleParameterizedTypeMapping() {
- try {
- new TypeResolver().where(
- new TypeCapture<List<T>>() {}.capture(),
- new TypeCapture<Map<String, Integer>>() {}.capture());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_incompatibleWildcardUpperBound() {
- try {
- new TypeResolver().where(
- new TypeCapture<List<? extends String>>() {}.capture(),
- new TypeCapture<List<? extends Integer>>() {}.capture());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_incompatibleWildcardLowerBound() {
- try {
- new TypeResolver().where(
- new TypeCapture<List<? super String>>() {}.capture(),
- new TypeCapture<List<? super Integer>>() {}.capture());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_incompatibleWildcardBounds() {
- try {
- new TypeResolver().where(
- new TypeCapture<List<? extends T>>() {}.capture(),
- new TypeCapture<List<? super String>>() {}.capture());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_wrongOrder() {
- try {
- new TypeResolver().where(String.class, aTypeVariable());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_mapFromConcreteParameterizedType() {
- try {
- new TypeResolver().where(new TypeCapture<List<String>>() {}.capture(), aTypeVariable());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T> void testWhere_mapFromConcreteGenericArrayType() {
- try {
- new TypeResolver().where(new TypeCapture<List<String>>() {}.capture(), aTypeVariable());
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- private static <T> Type aTypeVariable() {
- return new TypeCapture<T>() {}.capture();
- }
-
- private static <T> Type aWildcardType() {
- ParameterizedType parameterizedType = (ParameterizedType)
- new TypeCapture<List<? extends T>>() {}.capture();
- return parameterizedType.getActualTypeArguments()[0];
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java b/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java
deleted file mode 100644
index 6d51494..0000000
--- a/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit test for {@link TypeToken} and {@link TypeResolver}.
- *
- * @author Ben Yu
- */
-public class TypeTokenResolutionTest extends TestCase {
-
- private static class Foo<A, B> {
-
- Class<? super A> getClassA() {
- return new TypeToken<A>(getClass()) {}.getRawType();
- }
-
- Class<? super B> getClassB() {
- return new TypeToken<B>(getClass()) {}.getRawType();
- }
-
- Class<? super A[]> getArrayClassA() {
- return new TypeToken<A[]>(getClass()) {}.getRawType();
- }
-
- Type getArrayTypeA() {
- return new TypeToken<A[]>(getClass()) {}.getType();
- }
-
- Class<? super B[]> getArrayClassB() {
- return new TypeToken<B[]>(getClass()) {}.getRawType();
- }
- }
-
- public void testSimpleTypeToken() {
- Foo<String, Integer> foo = new Foo<String, Integer>() {};
- assertEquals(String.class, foo.getClassA());
- assertEquals(Integer.class, foo.getClassB());
- assertEquals(String[].class, foo.getArrayClassA());
- assertEquals(Integer[].class, foo.getArrayClassB());
- }
-
- public void testCompositeTypeToken() {
- Foo<String[], List<int[]>> foo = new Foo<String[], List<int[]>>() {};
- assertEquals(String[].class, foo.getClassA());
- assertEquals(List.class, foo.getClassB());
- assertEquals(String[][].class, foo.getArrayClassA());
- assertEquals(List[].class, foo.getArrayClassB());
- }
-
- private static class StringFoo<T> extends Foo<String, T> {}
-
- public void testPartialSpecialization() {
- StringFoo<Integer> foo = new StringFoo<Integer>() {};
- assertEquals(String.class, foo.getClassA());
- assertEquals(Integer.class, foo.getClassB());
- assertEquals(String[].class, foo.getArrayClassA());
- assertEquals(Integer[].class, foo.getArrayClassB());
- assertEquals(new TypeToken<String[]>() {}.getType(), foo.getArrayTypeA());
- }
-
- public void testTypeArgNotFound() {
- StringFoo<Integer> foo = new StringFoo<Integer>();
- assertEquals(String.class, foo.getClassA());
- assertEquals(String[].class, foo.getArrayClassA());
- assertEquals(Object.class, foo.getClassB());
- assertEquals(Object[].class, foo.getArrayClassB());
- }
-
- private static abstract class Bar<T> {}
-
- private abstract static class Parameterized<O, T, P> {
- ParameterizedType parameterizedType() {
- return new ParameterizedType() {
- @Override public Type[] getActualTypeArguments() {
- return new Type[]{new TypeCapture<P>() {}.capture()};
- }
- @Override public Type getOwnerType() {
- return new TypeCapture<O>() {}.capture();
- }
- @Override public Type getRawType() {
- return new TypeCapture<T>() {}.capture();
- }
- };
- }
- }
-
- public void testResolveType_parameterizedType() {
- @SuppressWarnings("rawtypes") // trying to test raw type
- Parameterized<?, ?, ?> parameterized =
- new Parameterized<TypeTokenResolutionTest, Bar, String>() {};
- TypeResolver typeResolver = TypeResolver.accordingTo(parameterized.getClass());
- ParameterizedType resolved = (ParameterizedType) typeResolver.resolveType(
- parameterized.parameterizedType());
- assertEquals(TypeTokenResolutionTest.class, resolved.getOwnerType());
- assertEquals(Bar.class, resolved.getRawType());
- ASSERT.that(resolved.getActualTypeArguments()).has().item(String.class);
- }
-
- private interface StringListPredicate extends Predicate<List<String>> {}
-
- private interface IntegerSupplier extends Supplier<Integer> {}
-
- // Intentionally duplicate the Predicate interface to test that it won't cause
- // exceptions
- private interface IntegerStringFunction extends IntegerSupplier,
- Predicate<List<String>>, StringListPredicate {}
-
- public void testGenericInterface() {
- // test the 1st generic interface on the class
- Type fType = Supplier.class.getTypeParameters()[0];
- assertEquals(Integer.class,
- TypeToken.of(IntegerStringFunction.class).resolveType(fType)
- .getRawType());
-
- // test the 2nd generic interface on the class
- Type predicateParameterType = Predicate.class.getTypeParameters()[0];
- assertEquals(new TypeToken<List<String>>() {}.getType(),
- TypeToken.of(IntegerStringFunction.class).resolveType(predicateParameterType)
- .getType());
- }
-
- private static abstract class StringIntegerFoo extends Foo<String, Integer> {}
-
- public void testConstructor_typeArgsResolvedFromAncestorClass() {
- assertEquals(String.class, new StringIntegerFoo() {}.getClassA());
- assertEquals(Integer.class, new StringIntegerFoo() {}.getClassB());
- }
-
- private static class Owner<T> {
- private static abstract class Nested<X> {
- Class<? super X> getTypeArgument() {
- return new TypeToken<X>(getClass()) {}.getRawType();
- }
- }
-
- private abstract class Inner<Y> extends Nested<Y> {
- Class<? super T> getOwnerType() {
- return new TypeToken<T>(getClass()) {}.getRawType();
- }
- }
- }
-
- public void testResolveNestedClass() {
- assertEquals(String.class, new Owner.Nested<String>() {}.getTypeArgument());
- }
-
- public void testResolveInnerClass() {
- assertEquals(String.class,
- new Owner<Integer>().new Inner<String>() {}.getTypeArgument());
- }
-
- public void testResolveOwnerClass() {
- assertEquals(Integer.class,
- new Owner<Integer>().new Inner<String>() {}.getOwnerType());
- }
-
- private static class Mapping<F, T> {
-
- final Type f = new TypeToken<F>(getClass()) {}.getType();
- final Type t = new TypeToken<T>(getClass()) {}.getType();
-
- Type getFromType() {
- return new TypeToken<F>(getClass()) {}.getType();
- }
-
- Type getToType() {
- return new TypeToken<T>(getClass()) {}.getType();
- }
-
- Mapping<T, F> flip() {
- return new Mapping<T, F>() {};
- }
-
- Mapping<F, T> selfMapping() {
- return new Mapping<F, T>() {};
- }
- }
-
- public void testCyclicMapping() {
- Mapping<Integer, String> mapping = new Mapping<Integer, String>();
- assertEquals(mapping.f, mapping.getFromType());
- assertEquals(mapping.t, mapping.getToType());
- assertEquals(mapping.f, mapping.flip().getFromType());
- assertEquals(mapping.t, mapping.flip().getToType());
- assertEquals(mapping.f, mapping.selfMapping().getFromType());
- assertEquals(mapping.t, mapping.selfMapping().getToType());
- }
-
- private static class ParameterizedOuter<T> {
-
- @SuppressWarnings("unused") // used by reflection
- public Inner field;
-
- class Inner {}
- }
-
- public void testInnerClassWithParameterizedOwner() throws Exception {
- Type fieldType = ParameterizedOuter.class.getField("field")
- .getGenericType();
- assertEquals(fieldType,
- TypeToken.of(ParameterizedOuter.class).resolveType(fieldType).getType());
- }
-
- private interface StringIterable extends Iterable<String> {}
-
- public void testResolveType() {
- assertEquals(String.class, TypeToken.of(this.getClass()).resolveType(String.class).getType());
- assertEquals(String.class,
- TypeToken.of(StringIterable.class)
- .resolveType(Iterable.class.getTypeParameters()[0]).getType());
- assertEquals(String.class,
- TypeToken.of(StringIterable.class)
- .resolveType(Iterable.class.getTypeParameters()[0]).getType());
- try {
- TypeToken.of(this.getClass()).resolveType(null);
- fail();
- } catch (NullPointerException expected) {}
- }
-
- public void testConextIsParameterizedType() throws Exception {
- class Context {
- @SuppressWarnings("unused") // used by reflection
- Map<String, Integer> returningMap() {
- throw new AssertionError();
- }
- }
- Type context = Context.class.getDeclaredMethod("returningMap")
- .getGenericReturnType();
- Type keyType = Map.class.getTypeParameters()[0];
- Type valueType = Map.class.getTypeParameters()[1];
-
- // context is parameterized type
- assertEquals(String.class, TypeToken.of(context).resolveType(keyType).getType());
- assertEquals(Integer.class,
- TypeToken.of(context).resolveType(valueType).getType());
-
- // context is type variable
- assertEquals(keyType, TypeToken.of(keyType).resolveType(keyType).getType());
- assertEquals(valueType, TypeToken.of(valueType).resolveType(valueType).getType());
- }
-
- private static final class GenericArray<T> {
- final Type t = new TypeToken<T>(getClass()) {}.getType();
- final Type array = new TypeToken<T[]>(getClass()) {}.getType();
- }
-
- public void testGenericArrayType() {
- GenericArray<?> genericArray = new GenericArray<Integer>();
- assertEquals(GenericArray.class.getTypeParameters()[0], genericArray.t);
- assertEquals(Types.newArrayType(genericArray.t),
- genericArray.array);
- }
-
- public void testClassWrapper() {
- TypeToken<String> typeExpression = TypeToken.of(String.class);
- assertEquals(String.class, typeExpression.getType());
- assertEquals(String.class, typeExpression.getRawType());
- }
-
- private static class Red<A> {
- private class Orange {
- Class<?> getClassA() {
- return new TypeToken<A>(getClass()) {}.getRawType();
- }
-
- Red<A> getSelfB() {
- return Red.this;
- }
- }
-
- Red<A> getSelfA() {
- return this;
- }
-
- private class Yellow<B> extends Red<B>.Orange {
- Yellow(Red<B> red) {
- red.super();
- }
-
- Class<?> getClassB() {
- return new TypeToken<B>(getClass()) {}.getRawType();
- }
-
- Red<A> getA() {
- return getSelfA();
- }
-
- Red<B> getB() {
- return getSelfB();
- }
- }
-
- Class<?> getClassDirect() {
- return new TypeToken<A>(getClass()) {}.getRawType();
- }
- }
-
- public void test1() {
- Red<String> redString = new Red<String>() {};
- Red<Integer> redInteger = new Red<Integer>() {};
- assertEquals(String.class, redString.getClassDirect());
- assertEquals(Integer.class, redInteger.getClassDirect());
-
- Red<String>.Yellow<Integer> yellowInteger =
- redString.new Yellow<Integer>(redInteger) {};
- assertEquals(Integer.class, yellowInteger.getClassA());
- assertEquals(Integer.class, yellowInteger.getClassB());
- assertEquals(String.class, yellowInteger.getA().getClassDirect());
- assertEquals(Integer.class, yellowInteger.getB().getClassDirect());
- }
-
- public void test2() {
- Red<String> redString = new Red<String>();
- Red<Integer> redInteger = new Red<Integer>();
- Red<String>.Yellow<Integer> yellowInteger =
- redString.new Yellow<Integer>(redInteger) {};
- assertEquals(Integer.class, yellowInteger.getClassA());
- assertEquals(Integer.class, yellowInteger.getClassB());
- }
-
- private static <T> Type staticMethodWithLocalClass() {
- class MyLocalClass {
- Type getType() {
- return new TypeToken<T>(getClass()) {}.getType();
- }
- }
- return new MyLocalClass().getType();
- }
-
- public void testLocalClassInsideStaticMethod() {
- assertNotNull(staticMethodWithLocalClass());
- }
-
- public void testLocalClassInsideNonStaticMethod() {
- class MyLocalClass<T> {
- Type getType() {
- return new TypeToken<T>(getClass()) {}.getType();
- }
- }
- assertNotNull(new MyLocalClass<String>().getType());
- }
-
- private static <T> Type staticMethodWithAnonymousClass() {
- return new Object() {
- Type getType() {
- return new TypeToken<T>(getClass()) {}.getType();
- }
- }.getType();
- }
-
- public void testAnonymousClassInsideStaticMethod() {
- assertNotNull(staticMethodWithAnonymousClass());
- }
-
- public void testAnonymousClassInsideNonStaticMethod() {
- assertNotNull(new Object() {
- Type getType() {
- return new TypeToken<Object>() {}.getType();
- }
- }.getType());
- }
-
- public void testStaticContext() {
- assertEquals(Map.class, mapType().getRawType());
- }
-
- private abstract static class Holder<T> {
- Type getContentType() {
- return new TypeToken<T>(getClass()) {}.getType();
- }
- }
-
- public void testResolvePrimitiveArrayType() {
- assertEquals(new TypeToken<int[]>() {}.getType(),
- new Holder<int[]>() {}.getContentType());
- assertEquals(new TypeToken<int[][]> () {}.getType(),
- new Holder<int[][]>() {}.getContentType());
- }
-
- public void testResolveToGenericArrayType() {
- GenericArrayType arrayType = (GenericArrayType)
- new Holder<List<int[][]>[]>() {}.getContentType();
- ParameterizedType listType = (ParameterizedType)
- arrayType.getGenericComponentType();
- assertEquals(List.class, listType.getRawType());
- assertEquals(Types.newArrayType(int[].class),
- listType.getActualTypeArguments()[0]);
- }
-
- private abstract class WithGenericBound<A> {
-
- @SuppressWarnings("unused")
- public <B extends A> void withTypeVariable(List<B> list) {}
-
- @SuppressWarnings("unused")
- public <E extends Enum<E>> void withRecursiveBound(List<E> list) {}
-
- @SuppressWarnings("unused")
- public <K extends List<V>, V extends List<K>> void withMutualRecursiveBound(
- List<Map<K, V>> list) {}
-
- @SuppressWarnings("unused")
- void withWildcardLowerBound(List<? super A> list) {}
-
- @SuppressWarnings("unused")
- void withWildcardUpperBound(List<? extends A> list) {}
-
- Type getTargetType(String methodName) throws Exception {
- ParameterizedType parameterType = (ParameterizedType)
- WithGenericBound.class.getDeclaredMethod(methodName, List.class)
- .getGenericParameterTypes()[0];
- parameterType = (ParameterizedType)
- TypeToken.of(this.getClass()).resolveType(parameterType).getType();
- return parameterType.getActualTypeArguments()[0];
- }
- }
-
- public void testWithGenericBoundInTypeVariable() throws Exception {
- TypeVariable<?> typeVariable = (TypeVariable<?>)
- new WithGenericBound<String>() {}.getTargetType("withTypeVariable");
- assertEquals(String.class, typeVariable.getBounds()[0]);
- }
-
- public void testWithRecursiveBoundInTypeVariable() throws Exception {
- TypeVariable<?> typeVariable = (TypeVariable<?>)
- new WithGenericBound<String>() {}.getTargetType("withRecursiveBound");
- assertEquals(Types.newParameterizedType(Enum.class, typeVariable),
- typeVariable.getBounds()[0]);
- }
-
- public void testWithMutualRecursiveBoundInTypeVariable() throws Exception {
- ParameterizedType paramType = (ParameterizedType)
- new WithGenericBound<String>() {}
- .getTargetType("withMutualRecursiveBound");
- TypeVariable<?> k = (TypeVariable<?>) paramType.getActualTypeArguments()[0];
- TypeVariable<?> v = (TypeVariable<?>) paramType.getActualTypeArguments()[1];
- assertEquals(Types.newParameterizedType(List.class, v), k.getBounds()[0]);
- assertEquals(Types.newParameterizedType(List.class, k), v.getBounds()[0]);
- }
-
- public void testWithGenericLowerBoundInWildcard() throws Exception {
- WildcardType wildcardType = (WildcardType)
- new WithGenericBound<String>() {}
- .getTargetType("withWildcardLowerBound");
- assertEquals(String.class, wildcardType.getLowerBounds()[0]);
- }
-
- public void testWithGenericUpperBoundInWildcard() throws Exception {
- WildcardType wildcardType = (WildcardType)
- new WithGenericBound<String>() {}
- .getTargetType("withWildcardUpperBound");
- assertEquals(String.class, wildcardType.getUpperBounds()[0]);
- }
-
- public void testInterfaceTypeParameterResolution() throws Exception {
- assertEquals(String.class,
- TypeToken.of(new TypeToken<ArrayList<String>>() {}.getType())
- .resolveType(List.class.getTypeParameters()[0]).getType());
- }
-
- private static TypeToken<Map<Object, Object>> mapType() {
- return new TypeToken<Map<Object, Object>>() {};
- }
-
- // Looks like recursive, but legit.
- private interface WithFalseRecursiveType<K, V> {
- WithFalseRecursiveType<List<V>, String> keyShouldNotResolveToStringList();
- WithFalseRecursiveType<List<K>, List<V>> shouldNotCauseInfiniteLoop();
- SubTypeOfWithFalseRecursiveType<List<V>, List<K>> evenSubTypeWorks();
- }
-
- private interface SubTypeOfWithFalseRecursiveType<K1, V1>
- extends WithFalseRecursiveType<List<K1>, List<V1>> {
- SubTypeOfWithFalseRecursiveType<V1, K1> revertKeyAndValueTypes();
- }
-
- public void testFalseRecursiveType_mappingOnTheSameDeclarationNotUsed() {
- Type returnType = genericReturnType(
- WithFalseRecursiveType.class, "keyShouldNotResolveToStringList");
- TypeToken<?> keyType = TypeToken.of(returnType)
- .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
- assertEquals("java.util.List<V>", keyType.getType().toString());
- }
-
- public void testFalseRecursiveType_notRealRecursiveMapping() {
- Type returnType = genericReturnType(
- WithFalseRecursiveType.class, "shouldNotCauseInfiniteLoop");
- TypeToken<?> keyType = TypeToken.of(returnType)
- .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
- assertEquals("java.util.List<K>", keyType.getType().toString());
- }
-
- public void testFalseRecursiveType_referenceOfSubtypeDoesNotConfuseMe() {
- Type returnType = genericReturnType(
- WithFalseRecursiveType.class, "evenSubTypeWorks");
- TypeToken<?> keyType = TypeToken.of(returnType)
- .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
- assertEquals("java.util.List<java.util.List<V>>", keyType.getType().toString());
- }
-
- public void testFalseRecursiveType_intermediaryTypeMappingDoesNotConfuseMe() {
- Type returnType = genericReturnType(
- SubTypeOfWithFalseRecursiveType.class, "revertKeyAndValueTypes");
- TypeToken<?> keyType = TypeToken.of(returnType)
- .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
- assertEquals("java.util.List<K1>", keyType.getType().toString());
- }
-
- private static Type genericReturnType(Class<?> cls, String methodName) {
- try {
- return cls.getMethod(methodName).getGenericReturnType();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/TypeTokenTest.java b/guava-tests/test/com/google/common/reflect/TypeTokenTest.java
deleted file mode 100644
index 1f8ceea..0000000
--- a/guava-tests/test/com/google/common/reflect/TypeTokenTest.java
+++ /dev/null
@@ -1,1517 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestCase;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Test cases for {@link TypeToken}.
- *
- * @author Sven Mawson
- * @author Ben Yu
- */
-public class TypeTokenTest extends TestCase {
-
- private abstract static class StringList implements List<String> {}
-
- private abstract static class IntegerList implements List<Integer> {}
-
- public void testValueEqualityNotInstanceEquality() {
- TypeToken<List<String>> a = new TypeToken<List<String>>() {};
- TypeToken<List<String>> b = new TypeToken<List<String>>() {};
- assertEquals(a, b);
- }
-
- public <T> void testVariableTypeTokenNotAllowed() {
- try {
- new TypeToken<T>() {};
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- public void testRawTypeIsCorrect() {
- TypeToken<List<String>> token = new TypeToken<List<String>>() {};
- assertEquals(List.class, token.getRawType());
- }
-
- public void testTypeIsCorrect() {
- TypeToken<List<String>> token = new TypeToken<List<String>>() {};
- assertEquals(StringList.class.getGenericInterfaces()[0], token.getType());
- }
-
- public void testGetClass() {
- TypeToken<List> token = TypeToken.of(List.class);
- assertEquals(new TypeToken<List>() {}, token);
- }
-
- public void testGetType() {
- TypeToken<?> t = TypeToken.of(StringList.class.getGenericInterfaces()[0]);
- assertEquals(new TypeToken<List<String>>() {}, t);
- }
-
- public void testNonStaticLocalClass() {
- class Local<T> {}
- TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
- assertEquals(Types.newParameterizedType(Local.class, String.class),
- type.getType());
- assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
- }
-
- public void testStaticLocalClass() {
- doTestStaticLocalClass();
- }
-
- private static void doTestStaticLocalClass() {
- class Local<T> {}
- TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
- assertEquals(Types.newParameterizedType(Local.class, String.class),
- type.getType());
- assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
- }
-
- public void testGenericArrayType() throws Exception {
- TypeToken<List<String>[]> token = new TypeToken<List<String>[]>() {};
- assertEquals(List[].class, token.getRawType());
- assertTrue(token.getType() instanceof GenericArrayType);
- }
-
- public void testMultiDimensionalGenericArrayType() throws Exception {
- TypeToken<List<Long>[][][]> token = new TypeToken<List<Long>[][][]>() {};
- assertEquals(List[][][].class, token.getRawType());
- assertTrue(token.getType() instanceof GenericArrayType);
- }
-
- public <T> void testGenericVariableTypeArrays() throws Exception {
- assertEquals("T[]", new TypeToken<T[]>() {}.toString());
- }
-
- public void testResolveType() throws Exception {
- Method getFromList = List.class.getMethod("get", int.class);
- TypeToken<?> returnType = new TypeToken<List<String>>() {}
- .resolveType(getFromList.getGenericReturnType());
- assertEquals(String.class, returnType.getType());
- }
-
- public <F extends Enum<F> & Function<String, Integer> & Iterable<Long>>
- void testResolveType_fromTypeVariable() throws Exception {
- TypeToken<?> f = TypeToken.of(new TypeCapture<F>() {}.capture());
- assertEquals(String.class,
- f.resolveType(Function.class.getTypeParameters()[0]).getType());
- assertEquals(Integer.class,
- f.resolveType(Function.class.getTypeParameters()[1]).getType());
- assertEquals(Long.class,
- f.resolveType(Iterable.class.getTypeParameters()[0]).getType());
- }
-
- public <E extends Comparable<Iterable<String>> & Iterable<Integer>>
- void testResolveType_fromTypeVariable_onlyDirectBoundsAreUsed() throws Exception {
- TypeToken<?> e = TypeToken.of(new TypeCapture<E>() {}.capture());
- assertEquals(Integer.class,
- e.resolveType(Iterable.class.getTypeParameters()[0]).getType());
- }
-
- public void testResolveType_fromWildcard() throws Exception {
- ParameterizedType withWildcardType = (ParameterizedType)
- new TypeCapture<Comparable<? extends Iterable<String>>>() {}.capture();
- TypeToken<?> wildcardType = TypeToken.of(withWildcardType.getActualTypeArguments()[0]);
- assertEquals(String.class,
- wildcardType.resolveType(Iterable.class.getTypeParameters()[0]).getType());
- }
-
- public void testGetTypes_noSuperclass() {
- TypeToken<Object>.TypeSet types = new TypeToken<Object>() {}.getTypes();
- ASSERT.that(types).has().item(TypeToken.of(Object.class));
- ASSERT.that(types.rawTypes()).has().item(Object.class);
- ASSERT.that(types.interfaces()).isEmpty();
- ASSERT.that(types.interfaces().rawTypes()).isEmpty();
- ASSERT.that(types.classes()).has().item(TypeToken.of(Object.class));
- ASSERT.that(types.classes().rawTypes()).has().item(Object.class);
- }
-
- public void testGetTypes_fromInterface() {
- TypeToken<Interface1>.TypeSet types = new TypeToken<Interface1>() {}.getTypes();
- ASSERT.that(types).has().item(TypeToken.of(Interface1.class));
- ASSERT.that(types.rawTypes()).has().item(Interface1.class);
- ASSERT.that(types.interfaces()).has().item(TypeToken.of(Interface1.class));
- ASSERT.that(types.interfaces().rawTypes()).has().item(Interface1.class);
- ASSERT.that(types.classes()).isEmpty();
- ASSERT.that(types.classes().rawTypes()).isEmpty();
- }
-
- public void testGetTypes_fromPrimitive() {
- TypeToken<Integer>.TypeSet types = TypeToken.of(int.class).getTypes();
- ASSERT.that(types).has().item(TypeToken.of(int.class));
- ASSERT.that(types.rawTypes()).has().item(int.class);
- ASSERT.that(types.interfaces()).isEmpty();
- ASSERT.that(types.interfaces().rawTypes()).isEmpty();
- ASSERT.that(types.classes()).has().item(TypeToken.of(int.class));
- ASSERT.that(types.classes().rawTypes()).has().item(int.class);
- }
-
- public void testGetTypes_withInterfacesAndSuperclasses() {
- abstract class Class2 extends Class1 implements Interface12 {}
- abstract class Class3<T> extends Class2 implements Interface3<T> {}
- TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
- ASSERT.that(types).has().allOf(
- new TypeToken<Class3<String>>() {},
- new TypeToken<Interface3<String>>() {},
- new TypeToken<Iterable<String>>() {},
- TypeToken.of(Class2.class),
- TypeToken.of(Interface12.class),
- TypeToken.of(Interface1.class),
- TypeToken.of(Interface2.class),
- TypeToken.of(Class1.class),
- TypeToken.of(Object.class));
- ASSERT.that(types.interfaces()).has().allOf(
- new TypeToken<Interface3<String>>() {},
- TypeToken.of(Interface12.class),
- TypeToken.of(Interface1.class),
- TypeToken.of(Interface2.class),
- new TypeToken<Iterable<String>>() {});
- ASSERT.that(types.classes()).has().allOf(
- new TypeToken<Class3<String>>() {},
- TypeToken.of(Class2.class),
- TypeToken.of(Class1.class),
- TypeToken.of(Object.class));
- assertSubtypeFirst(types);
- }
-
- public void testGetTypes_rawTypes_withInterfacesAndSuperclasses() {
- abstract class Class2 extends Class1 implements Interface12 {}
- abstract class Class3<T> extends Class2 implements Interface3<T> {}
- TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
- ASSERT.that(types.rawTypes()).has().allOf(
- Class3.class, Interface3.class,
- Iterable.class,
- Class2.class,
- Interface12.class,
- Interface1.class,
- Interface2.class,
- Class1.class,
- Object.class);
- ASSERT.that(types.interfaces().rawTypes()).has().allOf(
- Interface3.class,
- Interface12.class,
- Interface1.class,
- Interface2.class,
- Iterable.class);
- ASSERT.that(types.classes().rawTypes()).has().allOf(
- Class3.class,
- Class2.class,
- Class1.class,
- Object.class);
- assertSubtypeFirst(types);
- }
-
- public <A extends Class1 & Interface1, B extends A>
- void testGetTypes_ignoresTypeVariablesByDefault() {
- TypeToken.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
- ASSERT.that(types).has().allOf(
- TypeToken.of(Interface1.class), TypeToken.of(Class1.class),
- TypeToken.of(Object.class));
- assertSubtypeFirst(types);
- ASSERT.that(types.interfaces()).has().allOf(
- TypeToken.of(Interface1.class)).inOrder();
- ASSERT.that(types.classes()).has().allOf(
- TypeToken.of(Class1.class), TypeToken.of(Object.class)).inOrder();
- }
-
- public <A extends Class1 & Interface1, B extends A>
- void testGetTypes_rawTypes_ignoresTypeVariablesByDefault() {
- TypeToken.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
- ASSERT.that(types.rawTypes()).has().allOf(
- Interface1.class, Class1.class,
- Object.class);
- ASSERT.that(types.interfaces().rawTypes()).has().allOf(
- Interface1.class).inOrder();
- ASSERT.that(types.classes().rawTypes()).has().allOf(
- Class1.class, Object.class).inOrder();
- }
-
- public <A extends Interface1 & Interface2 & Interface3<String>>
- void testGetTypes_manyBounds() {
- TypeToken.TypeSet types = TypeToken.of(new TypeCapture<A>() {}.capture()).getTypes();
- ASSERT.that(types.rawTypes()).has().allOf(
- Interface1.class, Interface2.class, Interface3.class, Iterable.class);
- }
-
- private static void assertSubtypeFirst(TypeToken<?>.TypeSet types) {
- assertSubtypeTokenBeforeSupertypeToken(types);
- assertSubtypeTokenBeforeSupertypeToken(types.interfaces());
- assertSubtypeTokenBeforeSupertypeToken(types.classes());
- assertSubtypeBeforeSupertype(types.rawTypes());
- assertSubtypeBeforeSupertype(types.interfaces().rawTypes());
- assertSubtypeBeforeSupertype(types.classes().rawTypes());
- }
-
- private static void assertSubtypeTokenBeforeSupertypeToken(
- Iterable<? extends TypeToken<?>> types) {
- int i = 0;
- for (TypeToken<?> left : types) {
- int j = 0;
- for (TypeToken<?> right : types) {
- if (left.isAssignableFrom(right)) {
- assertTrue(left + " should be after " + right, i >= j);
- }
- j++;
- }
- i++;
- }
- }
-
- private static void assertSubtypeBeforeSupertype(Iterable<? extends Class<?>> types) {
- int i = 0;
- for (Class<?> left : types) {
- int j = 0;
- for (Class<?> right : types) {
- if (left.isAssignableFrom(right)) {
- assertTrue(left + " should be after " + right, i >= j);
- }
- j++;
- }
- i++;
- }
- }
-
- // Tests to make sure assertSubtypeBeforeSupertype() works.
-
- public void testAssertSubtypeTokenBeforeSupertypeToken_empty() {
- assertSubtypeTokenBeforeSupertypeToken(ImmutableList.<TypeToken<?>>of());
- }
-
- public void testAssertSubtypeTokenBeforeSupertypeToken_oneType() {
- assertSubtypeTokenBeforeSupertypeToken(ImmutableList.of(TypeToken.of(String.class)));
- }
-
- public void testAssertSubtypeTokenBeforeSupertypeToken_subtypeFirst() {
- assertSubtypeTokenBeforeSupertypeToken(
- ImmutableList.of(TypeToken.of(String.class), TypeToken.of(CharSequence.class)));
- }
-
- public void testAssertSubtypeTokenBeforeSupertypeToken_supertypeFirst() {
- try {
- assertSubtypeTokenBeforeSupertypeToken(
- ImmutableList.of(TypeToken.of(CharSequence.class), TypeToken.of(String.class)));
- } catch (AssertionError expected) {
- return;
- }
- fail();
- }
-
- public void testAssertSubtypeTokenBeforeSupertypeToken_duplicate() {
- try {
- assertSubtypeTokenBeforeSupertypeToken(
- ImmutableList.of(TypeToken.of(String.class), TypeToken.of(String.class)));
- } catch (AssertionError expected) {
- return;
- }
- fail();
- }
-
- public void testAssertSubtypeBeforeSupertype_empty() {
- assertSubtypeBeforeSupertype(ImmutableList.<Class<?>>of());
- }
-
- public void testAssertSubtypeBeforeSupertype_oneType() {
- assertSubtypeBeforeSupertype(ImmutableList.of(String.class));
- }
-
- public void testAssertSubtypeBeforeSupertype_subtypeFirst() {
- assertSubtypeBeforeSupertype(
- ImmutableList.of(String.class, CharSequence.class));
- }
-
- public void testAssertSubtypeBeforeSupertype_supertypeFirst() {
- try {
- assertSubtypeBeforeSupertype(
- ImmutableList.of(CharSequence.class, String.class));
- } catch (AssertionError expected) {
- return;
- }
- fail();
- }
-
- public void testAssertSubtypeBeforeSupertype_duplicate() {
- try {
- assertSubtypeBeforeSupertype(
- ImmutableList.of(String.class, String.class));
- } catch (AssertionError expected) {
- return;
- }
- fail();
- }
-
- public void testGetGenericSuperclass_noSuperclass() {
- assertNull(new TypeToken<Object>() {}.getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class),
- new TypeToken<Object[]>() {}.getGenericSuperclass());
- assertNull(new TypeToken<List<String>>() {}.getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class),
- new TypeToken<List<String>[]>() {}.getGenericSuperclass());
- }
-
- public void testGetGenericSuperclass_withSuperclass() {
- TypeToken<? super ArrayList<String>> superToken =
- new TypeToken<ArrayList<String>>() {}.getGenericSuperclass();
- assertEquals(ArrayList.class.getSuperclass(), superToken.getRawType());
- assertEquals(String.class,
- ((ParameterizedType) superToken.getType()).getActualTypeArguments()[0]);
- assertEquals(TypeToken.of(Base.class), TypeToken.of(Sub.class).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), TypeToken.of(Sub[].class).getGenericSuperclass());
- }
-
- public <T> void testGetGenericSuperclass_typeVariable_unbounded() {
- assertEquals(TypeToken.of(Object.class),
- TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
- }
-
- public <T extends ArrayList<String> & CharSequence>
- void testGetGenericSuperclass_typeVariable_boundIsClass() {
- assertEquals(new TypeToken<ArrayList<String>>() {},
- TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
- }
-
- public <T extends Enum<T> & CharSequence>
- void testGetGenericSuperclass_typeVariable_boundIsFBoundedClass() {
- assertEquals(new TypeToken<Enum<T>>() {},
- TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
- }
-
- public <T extends List<String> & CharSequence>
- void testGetGenericSuperclass_typeVariable_boundIsInterface() {
- assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
- }
-
- public <T extends ArrayList<String> & CharSequence, T1 extends T>
- void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass() {
- assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
- TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
- }
-
- public <T extends List<String> & CharSequence, T1 extends T>
- void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndInterface() {
- assertNull(TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
- assertEquals(TypeToken.of(Object.class), new TypeToken<T1[]>() {}.getGenericSuperclass());
- }
-
- public void testGetGenericSuperclass_wildcard_lowerBounded() {
- assertEquals(TypeToken.of(Object.class),
- TypeToken.of(Types.supertypeOf(String.class)).getGenericSuperclass());
- assertEquals(new TypeToken<Object>() {},
- TypeToken.of(Types.supertypeOf(String[].class)).getGenericSuperclass());
- assertEquals(new TypeToken<Object>() {},
- TypeToken.of(Types.supertypeOf(CharSequence.class)).getGenericSuperclass());
- }
-
- public void testGetGenericSuperclass_wildcard_boundIsClass() {
- assertEquals(TypeToken.of(Object.class),
- TypeToken.of(Types.subtypeOf(Object.class)).getGenericSuperclass());
- assertEquals(new TypeToken<Object[]>() {},
- TypeToken.of(Types.subtypeOf(Object[].class)).getGenericSuperclass());
- }
-
- public void testGetGenericSuperclass_wildcard_boundIsInterface() {
- assertNull(TypeToken.of(Types.subtypeOf(CharSequence.class)).getGenericSuperclass());
- assertEquals(new TypeToken<CharSequence[]>() {},
- TypeToken.of(Types.subtypeOf(CharSequence[].class)).getGenericSuperclass());
- }
-
- public <T> void testGetGenericInterfaces_typeVariable_unbounded() {
- ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
- .isEmpty();
- assertHasArrayInterfaces(new TypeToken<T[]>() {});
- }
-
- public <T extends NoInterface> void testGetGenericInterfaces_typeVariable_boundIsClass() {
- ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
- .isEmpty();
- assertHasArrayInterfaces(new TypeToken<T[]>() {});
- }
-
- public <T extends NoInterface&Iterable<String>>
- void testGetGenericInterfaces_typeVariable_boundsAreClassWithInterface() {
- ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
- .iteratesOverSequence(new TypeToken<Iterable<String>>() {});
- assertHasArrayInterfaces(new TypeToken<T[]>() {});
- }
-
- public <T extends CharSequence&Iterable<String>>
- void testGetGenericInterfaces_typeVariable_boundsAreInterfaces() {
- ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
- .iteratesOverSequence(
- TypeToken.of(CharSequence.class), new TypeToken<Iterable<String>>() {});
- assertHasArrayInterfaces(new TypeToken<T[]>() {});
- }
-
- public <T extends CharSequence&Iterable<T>>
- void testGetGenericInterfaces_typeVariable_boundsAreFBoundedInterfaces() {
- ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
- .iteratesOverSequence(TypeToken.of(CharSequence.class), new TypeToken<Iterable<T>>() {});
- assertHasArrayInterfaces(new TypeToken<T[]>() {});
- }
-
- public <T extends Base&Iterable<T>>
- void testGetGenericInterfaces_typeVariable_boundsAreClassWithFBoundedInterface() {
- ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
- .iteratesOverSequence(new TypeToken<Iterable<T>>() {});
- assertHasArrayInterfaces(new TypeToken<T[]>() {});
- }
-
- public <T extends NoInterface, T1 extends T, T2 extends T1>
- void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndClass() {
- ASSERT.that(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces())
- .isEmpty();
- assertHasArrayInterfaces(new TypeToken<T2[]>() {});
- }
-
- public <T extends Iterable<T>, T1 extends T, T2 extends T1>
- void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndInterface() {
- ASSERT.that(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces())
- .iteratesOverSequence(TypeToken.of(new TypeCapture<T1>() {}.capture()));
- assertHasArrayInterfaces(new TypeToken<T2[]>() {});
- }
-
- public void testGetGenericInterfaces_wildcard_lowerBounded() {
- ASSERT.that(TypeToken.of(Types.supertypeOf(String.class)).getGenericInterfaces())
- .isEmpty();
- ASSERT.that(TypeToken.of(Types.supertypeOf(String[].class)).getGenericInterfaces())
- .isEmpty();
- }
-
- public void testGetGenericInterfaces_wildcard_boundIsClass() {
- ASSERT.that(TypeToken.of(Types.subtypeOf(Object.class)).getGenericInterfaces())
- .isEmpty();
- ASSERT.that(TypeToken.of(Types.subtypeOf(Object[].class)).getGenericInterfaces())
- .isEmpty();
- }
-
- public void testGetGenericInterfaces_wildcard_boundIsInterface() {
- TypeToken<Iterable<String>> interfaceType = new TypeToken<Iterable<String>>() {};
- ASSERT.that(TypeToken.of(Types.subtypeOf(interfaceType.getType())).getGenericInterfaces())
- .iteratesOverSequence(interfaceType);
- assertHasArrayInterfaces(new TypeToken<Iterable<String>[]>() {});
- }
-
- public void testGetGenericInterfaces_noInterface() {
- ASSERT.that(new TypeToken<NoInterface>() {}.getGenericInterfaces())
- .isEmpty();
- assertHasArrayInterfaces(new TypeToken<NoInterface[]>() {});
- }
-
- public void testGetGenericInterfaces_withInterfaces() {
- Map<Class<?>, Type> interfaceMap = Maps.newHashMap();
- for (TypeToken<?> interfaceType:
- new TypeToken<Implementation<Integer, String>>() {}.getGenericInterfaces()) {
- interfaceMap.put(interfaceType.getRawType(), interfaceType.getType());
- }
- assertEquals(ImmutableMap.of(
- Iterable.class, new TypeToken<Iterable<String>>() {}.getType(),
- Map.class, new TypeToken<Map<Integer, String>>() {}.getType()),
- interfaceMap);
- }
-
- private interface Interface1 {}
- private interface Interface2 {}
- private interface Interface3<T> extends Iterable<T> {}
- private interface Interface12 extends Interface1, Interface2 {}
- private static class Class1 implements Interface1 {}
-
- private static final class NoInterface {}
-
- private abstract static class Implementation<K, V>
- implements Iterable<V>, Map<K, V> {}
-
- private abstract static class First<T> {}
-
- private abstract static class Second<D> extends First<D> {}
-
- private abstract static class Third<T, D> extends Second<T> {}
-
- private abstract static class Fourth<T, D> extends Third<D, T> {}
-
- private static class ConcreteIS extends Fourth<Integer, String> {}
-
- private static class ConcreteSI extends Fourth<String, Integer> {}
-
- public void testAssignableClassToClass() {
- TypeToken<List> tokL = new TypeToken<List>() {};
- assertTrue(tokL.isAssignableFrom(List.class));
- assertTrue(tokL.isAssignableFrom(ArrayList.class));
- assertFalse(tokL.isAssignableFrom(List[].class));
-
- TypeToken<Number> tokN = new TypeToken<Number>() {};
- assertTrue(tokN.isAssignableFrom(Number.class));
- assertTrue(tokN.isAssignableFrom(Integer.class));
- }
-
- public <T> void testAssignableParameterizedTypeToObject() {
- assertTrue(TypeToken.of(Object.class).isAssignableFrom(
- TypeToken.of(new TypeCapture<T>() {}.capture())));
- assertFalse(TypeToken.of(int.class).isAssignableFrom(
- TypeToken.of(new TypeCapture<T>() {}.capture())));
- }
-
- public <T, T1 extends T> void testAssignableGenericArrayToGenericArray() {
- assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[]>() {}));
- assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T1[]>() {}));
- assertFalse(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[][]>() {}));
- }
-
- public void testAssignableWildcardBoundedByArrayToArrayClass() throws Exception {
- Type wildcardType = Types.subtypeOf(Object[].class);
- assertTrue(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
- assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
- assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
- assertFalse(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
- }
-
- public void testAssignableArrayClassToBoundedWildcard() throws Exception {
- TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
- TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
- assertTrue(upperBounded.isAssignableFrom(Object[].class));
- assertTrue(upperBounded.isAssignableFrom(Object[][].class));
- assertTrue(upperBounded.isAssignableFrom(String[].class));
- assertTrue(lowerBounded.isAssignableFrom(Object[].class));
- assertTrue(lowerBounded.isAssignableFrom(Object.class));
- assertFalse(lowerBounded.isAssignableFrom(Object[][].class));
- assertFalse(lowerBounded.isAssignableFrom(String[].class));
- }
-
- public void testAssignableWildcardBoundedByIntArrayToArrayClass() throws Exception {
- Type wildcardType = Types.subtypeOf(int[].class);
- assertTrue(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
- assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
- assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
- assertFalse(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
- }
-
- public void testAssignableWildcardToWildcard() throws Exception {
- TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
- TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
- assertFalse(lowerBounded.isAssignableFrom(upperBounded));
- assertTrue(lowerBounded.isAssignableFrom(lowerBounded));
- assertTrue(upperBounded.isAssignableFrom(upperBounded));
- assertFalse(upperBounded.isAssignableFrom(lowerBounded));
- }
-
- public <T> void testAssignableGenericArrayToArrayClass() {
- assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[]>() {}));
- assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[][]>() {}));
- assertTrue(TypeToken.of(Object[][].class).isAssignableFrom(new TypeToken<T[][]>() {}));
- }
-
- public void testAssignableParameterizedTypeToClass() {
- TypeToken<List> tokL = new TypeToken<List>() {};
- assertTrue(tokL.isAssignableFrom(StringList.class));
- assertTrue(tokL.isAssignableFrom(
- StringList.class.getGenericInterfaces()[0]));
-
- TypeToken<Second> tokS = new TypeToken<Second>() {};
- assertTrue(tokS.isAssignableFrom(Second.class));
- assertTrue(tokS.isAssignableFrom(Third.class.getGenericSuperclass()));
- }
-
- public void testAssignableArrayToClass() throws Exception {
- TypeToken<List[]> tokL = new TypeToken<List[]>() {};
- assertTrue(tokL.isAssignableFrom(List[].class));
- assertFalse(tokL.isAssignableFrom(List.class));
-
- TypeToken<Second[]> tokS = new TypeToken<Second[]>() {};
- assertTrue(tokS.isAssignableFrom(Second[].class));
- assertTrue(tokS.isAssignableFrom(Third[].class));
- }
-
- public void testAssignableTokenToClass() {
- TypeToken<List> tokL = new TypeToken<List>() {};
- assertTrue(tokL.isAssignableFrom(new TypeToken<List>() {}));
- assertTrue(tokL.isAssignableFrom(new TypeToken<List<String>>() {}));
- assertTrue(tokL.isAssignableFrom(new TypeToken<List<?>>() {}));
-
- TypeToken<Second> tokS = new TypeToken<Second>() {};
- assertTrue(tokS.isAssignableFrom(new TypeToken<Second>() {}));
- assertTrue(tokS.isAssignableFrom(new TypeToken<Third>() {}));
- assertTrue(tokS.isAssignableFrom(
- new TypeToken<Third<String, Integer>>() {}));
-
- TypeToken<List[]> tokA = new TypeToken<List[]>() {};
- assertTrue(tokA.isAssignableFrom(new TypeToken<List[]>() {}));
- assertTrue(tokA.isAssignableFrom(new TypeToken<List<String>[]>() {}));
- assertTrue(tokA.isAssignableFrom(new TypeToken<List<?>[]>() {}));
- }
-
- public void testAssignableClassToType() {
- TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
- assertTrue(tokenL.isAssignableFrom(StringList.class));
- assertFalse(tokenL.isAssignableFrom(List.class));
-
- TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
- assertTrue(tokenF.isAssignableFrom(ConcreteIS.class));
- assertFalse(tokenF.isAssignableFrom(ConcreteSI.class));
- }
-
- public void testAssignableClassToArrayType() {
- TypeToken<List<String>[]> tokenL = new TypeToken<List<String>[]>() {};
- assertTrue(tokenL.isAssignableFrom(StringList[].class));
- assertFalse(tokenL.isAssignableFrom(List[].class));
- }
-
- public void testAssignableParameterizedTypeToType() {
- TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
- assertTrue(tokenL.isAssignableFrom(
- StringList.class.getGenericInterfaces()[0]));
- assertFalse(tokenL.isAssignableFrom(
- IntegerList.class.getGenericInterfaces()[0]));
-
- TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
- assertTrue(tokenF.isAssignableFrom(
- ConcreteIS.class.getGenericSuperclass()));
- assertFalse(tokenF.isAssignableFrom(
- ConcreteSI.class.getGenericSuperclass()));
- }
-
- public void testGenericArrayTypeToArrayType() throws Exception {
- TypeToken<List<String>[]> tokL = new TypeToken<List<String>[]>() {};
- TypeToken<ArrayList<String>[]> token =
- new TypeToken<ArrayList<String>[]>() {};
- assertTrue(tokL.isAssignableFrom(tokL.getType()));
- assertTrue(tokL.isAssignableFrom(token.getType()));
- }
-
- public void testAssignableTokenToType() {
- TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
- assertTrue(tokenL.isAssignableFrom(new TypeToken<List<String>>() {}));
- assertTrue(tokenL.isAssignableFrom(new TypeToken<ArrayList<String>>() {}));
- assertTrue(tokenL.isAssignableFrom(new TypeToken<StringList>() {}));
-
- TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
- assertTrue(tokenF.isAssignableFrom(new TypeToken<Second<String>>() {}));
- assertTrue(tokenF.isAssignableFrom(
- new TypeToken<Third<String, Integer>>() {}));
- assertFalse(tokenF.isAssignableFrom(
- new TypeToken<Third<Integer, String>>() {}));
- assertTrue(tokenF.isAssignableFrom(
- new TypeToken<Fourth<Integer, String>>() {}));
- assertFalse(tokenF.isAssignableFrom(
- new TypeToken<Fourth<String, Integer>>() {}));
- assertTrue(tokenF.isAssignableFrom(new TypeToken<ConcreteIS>() {}));
- assertFalse(tokenF.isAssignableFrom(new TypeToken<ConcreteSI>() {}));
- }
-
- public void testAssignableWithWildcards() {
- TypeToken<?> unboundedToken = new TypeToken<List<?>>() {};
- TypeToken<?> upperBoundToken = new TypeToken<List<? extends Number>>() {};
- TypeToken<?> lowerBoundToken = new TypeToken<List<? super Number>>() {};
- TypeToken<?> concreteToken = new TypeToken<List<Number>>() {};
- TypeToken<?> subtypeToken = new TypeToken<List<Integer>>() {};
- TypeToken<?> supertypeToken = new TypeToken<List<Serializable>>() {};
- List<TypeToken<?>> allTokens = ImmutableList.of(
- unboundedToken, upperBoundToken, lowerBoundToken,
- concreteToken, subtypeToken, supertypeToken);
-
- for (TypeToken<?> typeToken : allTokens) {
- assertTrue(typeToken.toString(), unboundedToken.isAssignableFrom(typeToken));
- }
-
- assertFalse(upperBoundToken.isAssignableFrom(unboundedToken));
- assertTrue(upperBoundToken.isAssignableFrom(upperBoundToken));
- assertFalse(upperBoundToken.isAssignableFrom(lowerBoundToken));
- assertTrue(upperBoundToken.isAssignableFrom(concreteToken));
- assertTrue(upperBoundToken.isAssignableFrom(subtypeToken));
- assertFalse(upperBoundToken.isAssignableFrom(supertypeToken));
-
- assertFalse(lowerBoundToken.isAssignableFrom(unboundedToken));
- assertFalse(lowerBoundToken.isAssignableFrom(upperBoundToken));
- assertTrue(lowerBoundToken.isAssignableFrom(lowerBoundToken));
- assertTrue(lowerBoundToken.isAssignableFrom(concreteToken));
- assertFalse(lowerBoundToken.isAssignableFrom(subtypeToken));
- assertTrue(lowerBoundToken.isAssignableFrom(supertypeToken));
-
- for (TypeToken<?> typeToken : allTokens) {
- assertEquals(typeToken.toString(),
- typeToken == concreteToken, concreteToken.isAssignableFrom(typeToken));
- }
-
- for (TypeToken<?> typeToken : allTokens) {
- assertEquals(typeToken.toString(),
- typeToken == subtypeToken, subtypeToken.isAssignableFrom(typeToken));
- }
-
- for (TypeToken<?> typeToken : allTokens) {
- assertEquals(typeToken.toString(),
- typeToken == supertypeToken, supertypeToken.isAssignableFrom(typeToken));
- }
- }
-
- public <N1 extends Number, N2 extends Number, N11 extends N1>
- void testIsAssignableFrom_typeVariable() {
- assertAssignable(TypeToken.of(new TypeCapture<N1>() {}.capture()),
- TypeToken.of(new TypeCapture<N1>() {}.capture()));
- assertNotAssignable(new TypeToken<List<N11>>() {},
- new TypeToken<List<N1>>() {});
- assertNotAssignable(new TypeToken<Number>() {},
- TypeToken.of(new TypeCapture<N1>() {}.capture()));
- assertAssignable(TypeToken.of(new TypeCapture<N11>() {}.capture()),
- TypeToken.of(new TypeCapture<N1>() {}.capture()));
- assertNotAssignable(TypeToken.of(new TypeCapture<N2>() {}.capture()),
- TypeToken.of(new TypeCapture<N1>() {}.capture()));
- }
-
- public <N1 extends Number, N2 extends Number, N11 extends N1>
- void testIsAssignableFrom_equalWildcardTypes() {
- assertAssignable(new TypeToken<List<? extends N1>>() {},
- new TypeToken<List<? extends N1>>() {});
- assertAssignable(new TypeToken<List<? super N1>>() {},
- new TypeToken<List<? super N1>>() {});
- assertAssignable(new TypeToken<List<? extends Number>>() {},
- new TypeToken<List<? extends Number>>() {});
- assertAssignable(new TypeToken<List<? super Number>>() {},
- new TypeToken<List<? super Number>>() {});
- }
-
- public <N> void testIsAssignableFrom_wildcard_noBound() {
- assertAssignable(new TypeToken<List<? super N>>() {},
- new TypeToken<List<?>>() {});
- assertAssignable(new TypeToken<List<N>>() {},
- new TypeToken<List<?>>() {});
- }
-
- public <N1 extends Number, N2 extends Number, N11 extends N1>
- void testIsAssignableFrom_wildcardType_upperBoundMatch() {
- // ? extends T
- assertAssignable(new TypeToken<List<N11>>() {},
- new TypeToken<List<? extends N1>>() {});
- assertNotAssignable(new TypeToken<List<N1>>() {},
- new TypeToken<List<? extends N11>>() {});
- assertNotAssignable(new TypeToken<List<Number>>() {},
- new TypeToken<List<? extends N11>>() {});
-
- // ? extends Number
- assertAssignable(new TypeToken<List<N1>>() {},
- new TypeToken<List<? extends Number>>() {});
- assertAssignable(new TypeToken<ArrayList<N1>>() {},
- new TypeToken<List<? extends Number>>() {});
- assertAssignable(new TypeToken<List<? extends N11>>() {},
- new TypeToken<List<? extends Number>>() {});
- }
-
- public <N1 extends Number, N2 extends Number, N11 extends N1>
- void testIsAssignableFrom_wildcardType_lowerBoundMatch() {
- // ? super T
- assertAssignable(new TypeToken<List<N1>>() {},
- new TypeToken<List<? super N11>>() {});
- assertAssignable(new TypeToken<ArrayList<Number>>() {},
- new TypeToken<List<? super N1>>() {});
- assertNotAssignable(new TypeToken<ArrayList<? super N11>>() {},
- new TypeToken<List<? super Number>>() {});
- assertAssignable(new TypeToken<ArrayList<? super N1>>() {},
- new TypeToken<List<? super N11>>() {});
- assertAssignable(new TypeToken<ArrayList<? super Number>>() {},
- new TypeToken<List<? super N11>>() {});
-
- // ? super Number
- assertNotAssignable(new TypeToken<ArrayList<N11>>() {},
- new TypeToken<List<? super Number>>() {});
- assertAssignable(new TypeToken<ArrayList<Number>>() {},
- new TypeToken<List<? super Number>>() {});
- assertAssignable(new TypeToken<ArrayList<Object>>() {},
- new TypeToken<List<? super Number>>() {});
- }
-
- public <L extends List<R>, R extends List<L>>
- void testIsAssignableFrom_recursiveTypeVariableBounds() {
- assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
- TypeToken.of(new TypeCapture<L>() {}.capture()));
- assertNotAssignable(TypeToken.of(new TypeCapture<R>() {}.capture()),
- TypeToken.of(new TypeCapture<L>() {}.capture()));
- assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
- new TypeToken<List<R>>() {});
- }
-
- public void testIsAssignableFrom_resolved() {
- assertFalse(Assignability.of().isAssignable());
- assertTrue(new Assignability<Integer, Integer>() {}.isAssignable());
- assertTrue(new Assignability<Integer, Object>() {}.isAssignable());
- assertFalse(new Assignability<Integer, String>() {}.isAssignable());
- TypeTokenTest.<Number, Integer>assignabilityTestWithTypeVariables();
- }
-
- private static <N1 extends Number, N11 extends N1>
- void assignabilityTestWithTypeVariables() {
- assertTrue(new Assignability<N11, N1>() {}.isAssignable());
- assertTrue(new Assignability<N11, Number>() {}.isAssignable());
- assertFalse(new Assignability<Number, N11>() {}.isAssignable());
- }
-
- public void testIsArray_arrayClasses() {
- assertTrue(TypeToken.of(Object[].class).isArray());
- assertTrue(TypeToken.of(Object[][].class).isArray());
- assertTrue(TypeToken.of(char[].class).isArray());
- assertTrue(TypeToken.of(char[][].class).isArray());
- assertTrue(TypeToken.of(byte[].class).isArray());
- assertTrue(TypeToken.of(short[].class).isArray());
- assertTrue(TypeToken.of(int[].class).isArray());
- assertTrue(TypeToken.of(long[].class).isArray());
- assertTrue(TypeToken.of(float[].class).isArray());
- assertTrue(TypeToken.of(double[].class).isArray());
- assertFalse(TypeToken.of(Object.class).isArray());
- assertFalse(TypeToken.of(void.class).isArray());
- }
-
- public <T> void testIsArray_genericArrayClasses() {
- assertFalse(TypeToken.of(new TypeCapture<T>() {}.capture()).isArray());
- assertTrue(new TypeToken<T[]>() {}.isArray());
- assertTrue(new TypeToken<T[][]>() {}.isArray());
- }
-
- public void testIsArray_wildcardType() throws Exception {
- assertTrue(TypeToken.of(Types.subtypeOf(Object[].class)).isArray());
- assertTrue(TypeToken.of(Types.subtypeOf(int[].class)).isArray());
- assertFalse(TypeToken.of(Types.subtypeOf(Object.class)).isArray());
- assertFalse(TypeToken.of(Types.supertypeOf(Object[].class)).isArray());
- }
-
- public void testGetComponentType_arrayClasses() {
- assertEquals(Object.class, TypeToken.of(Object[].class).getComponentType().getType());
- assertEquals(Object[].class, TypeToken.of(Object[][].class).getComponentType().getType());
- assertEquals(char.class, TypeToken.of(char[].class).getComponentType().getType());
- assertEquals(char[].class, TypeToken.of(char[][].class).getComponentType().getType());
- assertEquals(byte.class, TypeToken.of(byte[].class).getComponentType().getType());
- assertEquals(short.class, TypeToken.of(short[].class).getComponentType().getType());
- assertEquals(int.class, TypeToken.of(int[].class).getComponentType().getType());
- assertEquals(long.class, TypeToken.of(long[].class).getComponentType().getType());
- assertEquals(float.class, TypeToken.of(float[].class).getComponentType().getType());
- assertEquals(double.class, TypeToken.of(double[].class).getComponentType().getType());
- assertNull(TypeToken.of(Object.class).getComponentType());
- assertNull(TypeToken.of(void.class).getComponentType());
- }
-
- public <T> void testGetComponentType_genericArrayClasses() {
- assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getComponentType());
- assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
- new TypeToken<T[]>() {}.getComponentType());
- assertEquals(new TypeToken<T[]>() {}, new TypeToken<T[][]>() {}.getComponentType());
- }
-
- public void testGetComponentType_wildcardType() throws Exception {
- assertEquals(Types.subtypeOf(Object.class),
- TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType());
- assertEquals(Types.subtypeOf(Object[].class),
- Types.newArrayType(
- TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType()));
- assertEquals(int.class,
- TypeToken.of(Types.subtypeOf(int[].class)).getComponentType().getType());
- assertNull(TypeToken.of(Types.subtypeOf(Object.class)).getComponentType());
- assertNull(TypeToken.of(Types.supertypeOf(Object[].class)).getComponentType());
- }
-
- private interface NumberList<T extends Number> {}
-
- public void testImplicitUpperBoundForWildcards() {
- assertAssignable(
- new TypeToken<NumberList<? extends Number>>() {},
- new TypeToken<NumberList<?>>() {});
- assertAssignable(
- new TypeToken<NumberList<? super Integer>>() {},
- new TypeToken<NumberList<?>>() {});
- }
-
- public <T extends Readable & Appendable> void testMultiBound() {
- assertAssignable(new TypeToken<List<T>>() {},
- new TypeToken<List<? extends Readable>>() {});
- assertAssignable(new TypeToken<List<T>>() {},
- new TypeToken<List<? extends Appendable>>() {});
- }
-
- public void testToGenericType() {
- assertEquals(TypeToken.of(String.class), TypeToken.toGenericType(String.class));
- assertEquals(new TypeToken<int[]>() {}, TypeToken.toGenericType(int[].class));
- TypeToken<? extends Iterable> genericType = TypeToken.toGenericType(Iterable.class);
- assertEquals(Iterable.class, genericType.getRawType());
- assertEquals(Types.newParameterizedType(Iterable.class, Iterable.class.getTypeParameters()[0]),
- genericType.getType());
- }
-
- private interface ListIterable<T> extends Iterable<List<T>> {}
- private interface StringListIterable extends ListIterable<String> {}
- private interface ListArrayIterable<T> extends Iterable<List<T>[]> {}
- private interface StringListArrayIterable extends ListIterable<String> {}
-
- public void testGetSupertype_withTypeVariable() {
- ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
- Types.newParameterizedType(List.class, ListIterable.class.getTypeParameters()[0]));
- assertEquals(expectedType,
- TypeToken.of(ListIterable.class).getSupertype(Iterable.class).getType());
- }
-
- public void testGetSupertype_withoutTypeVariable() {
- ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
- Types.newParameterizedType(List.class, String.class));
- assertEquals(expectedType,
- TypeToken.of(StringListIterable.class).getSupertype(Iterable.class).getType());
- }
-
- public void testGetSupertype_chained() {
- @SuppressWarnings("unchecked") // StringListIterable extensd ListIterable<String>
- TypeToken<ListIterable<String>> listIterableType = (TypeToken<ListIterable<String>>)
- TypeToken.of(StringListIterable.class).getSupertype(ListIterable.class);
- ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
- Types.newParameterizedType(List.class, String.class));
- assertEquals(expectedType, listIterableType.getSupertype(Iterable.class).getType());
- }
-
- public void testGetSupertype_withArray() {
- assertEquals(new TypeToken<Iterable<List<String>>[]>() {},
- TypeToken.of(StringListIterable[].class).getSupertype(Iterable[].class));
- assertEquals(int[].class, TypeToken.of(int[].class).getSupertype(int[].class).getType());
- assertEquals(Object.class, TypeToken.of(int[].class).getSupertype(Object.class).getType());
- assertEquals(int[][].class, TypeToken.of(int[][].class).getSupertype(int[][].class).getType());
- assertEquals(Object[].class,
- TypeToken.of(String[].class).getSupertype(Object[].class).getType());
- assertEquals(Object.class, TypeToken.of(String[].class).getSupertype(Object.class).getType());
- }
-
- public void testGetSupertype_fromWildcard() {
- @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
- TypeToken<? extends List<String>> type = (TypeToken<? extends List<String>>)
- TypeToken.of(Types.subtypeOf(new TypeToken<List<String>>() {}.getType()));
- assertEquals(new TypeToken<Iterable<String>>() {}, type.getSupertype(Iterable.class));
- }
-
- public <T extends Iterable<String>> void testGetSupertype_fromTypeVariable() {
- @SuppressWarnings("unchecked") // to construct TypeToken<T> from TypeToken.of()
- TypeToken<T> typeVariableToken = (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture());
- assertEquals(new TypeToken<Iterable<String>>() {},
- typeVariableToken.getSupertype(Iterable.class));
- }
-
- @SuppressWarnings("rawtypes") // purpose is to test raw type
- public void testGetSupertype_fromRawClass() {
- assertEquals(Types.newParameterizedType(Iterable.class, List.class.getTypeParameters()[0]),
- new TypeToken<List>() {}.getSupertype(Iterable.class).getType());
- }
-
- @SuppressWarnings("rawtypes") // purpose is to test raw type
- public void testGetSupertype_notSupertype() {
- try {
- new TypeToken<List<String>>() {}.getSupertype((Class) String.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testGetSupertype_fromArray() {
- assertEquals(new TypeToken<Iterable<String>[]>() {},
- new TypeToken<List<String>[]>() {}.getSupertype(Iterable[].class));
- }
-
- private interface ListMap<K, V> extends Map<K, List<V>> {}
-
- public void testGetSupertype_fullyGenericType() {
- ParameterizedType expectedType = Types.newParameterizedType(Map.class,
- ListMap.class.getTypeParameters()[0],
- Types.newParameterizedType(List.class, ListMap.class.getTypeParameters()[1]));
- assertEquals(expectedType,
- TypeToken.of(ListMap.class).getSupertype(Map.class).getType());
- }
-
- public void testGetSupertype_fullySpecializedType() {
- Type expectedType = new TypeToken<Map<String, List<Object>>>() {}.getType();
- assertEquals(expectedType,
- new TypeToken<ListMap<String, Object>>() {}.getSupertype(Map.class).getType());
- }
-
- private interface StringListMap<V> extends ListMap<String, V> {}
-
- public <V> void testGetSupertype_partiallySpecializedType() {
- Type expectedType = new TypeToken<Map<String, List<V>>>() {}.getType();
- assertEquals(expectedType,
- new TypeToken<StringListMap<V>>() {}.getSupertype(Map.class).getType());
- }
-
- public void testGetSubtype_withTypeVariable() {
- assertEquals(new TypeToken<ListIterable<String>>() {},
- new TypeToken<Iterable<List<String>>>() {}.getSubtype(ListIterable.class));
- assertEquals(new TypeToken<ListArrayIterable<String>>() {},
- new TypeToken<Iterable<List<String>[]>>() {}.getSubtype(ListArrayIterable.class));
- assertEquals(new TypeToken<ListArrayIterable<String>[]>() {},
- new TypeToken<Iterable<List<String>[]>[]>() {}.getSubtype(ListArrayIterable[].class));
- }
-
- public void testGetSubtype_withoutTypeVariable() {
- assertEquals(StringListIterable.class,
- TypeToken.of(Iterable.class).getSubtype(StringListIterable.class).getType());
- assertEquals(StringListIterable[].class,
- TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class).getType());
- assertEquals(TypeToken.of(StringListArrayIterable.class),
- new TypeToken<Iterable<List<String>>>() {}.getSubtype(StringListArrayIterable.class));
- assertEquals(TypeToken.of(StringListArrayIterable[].class),
- new TypeToken<Iterable<List<String>>[]>() {}.getSubtype(StringListArrayIterable[].class));
- }
-
- public void testGetSubtype_withArray() {
- assertEquals(TypeToken.of(StringListIterable[].class),
- TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class));
- assertEquals(TypeToken.of(String[].class),
- TypeToken.of(Object[].class).getSubtype(String[].class));
- assertEquals(TypeToken.of(int[].class),
- TypeToken.of(Object.class).getSubtype(int[].class));
- }
-
- public void testGetSubtype_fromWildcard() {
- @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
- TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
- TypeToken.of(Types.supertypeOf(new TypeToken<Iterable<String>>() {}.getType()));
- assertEquals(new TypeToken<List<String>>() {}, type.getSubtype(List.class));
- }
-
- public void testGetSubtype_fromWildcard_lowerBoundNotSupertype() {
- @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
- TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
- TypeToken.of(Types.supertypeOf(new TypeToken<ImmutableList<String>>() {}.getType()));
- try {
- type.getSubtype(List.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testGetSubtype_fromWildcard_upperBounded() {
- @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
- TypeToken<? extends Iterable<String>> type = (TypeToken<? extends Iterable<String>>)
- TypeToken.of(Types.subtypeOf(new TypeToken<Iterable<String>>() {}.getType()));
- try {
- type.getSubtype(Iterable.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public <T extends Iterable<String>> void testGetSubtype_fromTypeVariable() {
- try {
- TypeToken.of(new TypeCapture<T>() {}.capture()).getSubtype(List.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- @SuppressWarnings("rawtypes") // purpose is to test raw type
- public void testGetSubtype_fromRawClass() {
- assertEquals(List.class, new TypeToken<Iterable>() {}.getSubtype(List.class).getType());
- }
-
- public void testGetSubtype_fromArray() {
- assertEquals(new TypeToken<List<String>[]>() {},
- new TypeToken<Iterable<String>[]>() {}.getSubtype(List[].class));
- }
-
- @SuppressWarnings("unchecked") // To construct TypeToken<T> with TypeToken.of()
- public <T> void testWhere_circleRejected() {
- TypeToken<List<T>> type = new TypeToken<List<T>>() {};
- try {
- type.where(new TypeParameter<T>() {},
- (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture()));
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testWhere() {
- assertEquals(
- new TypeToken<Map<String, Integer>>() {},
- mapOf(String.class, Integer.class));
- assertEquals(new TypeToken<int[]>() {}, arrayOf(int.class));
- assertEquals(int[].class, arrayOf(int.class).getRawType());
- }
-
- @SuppressWarnings("unused") // used by reflection
- private static class Holder<T> {
- T element;
- List<T> list;
- List<T>[] matrix;
-
- void setList(List<T> list) {
- this.list = list;
- }
- }
-
- public void testWildcardCaptured_methodParameter_upperBound() throws Exception {
- TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
- TypeToken<?> parameterType = type.resolveType(
- Holder.class.getDeclaredMethod("setList", List.class).getGenericParameterTypes()[0]);
- assertEquals(List.class, parameterType.getRawType());
- assertFalse(parameterType.getType().toString(),
- parameterType.isAssignableFrom(new TypeToken<List<Integer>>() {}));
- }
-
- public void testWildcardCaptured_field_upperBound() throws Exception {
- TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
- TypeToken<?> matrixType = type.resolveType(
- Holder.class.getDeclaredField("matrix").getGenericType());
- assertEquals(List[].class, matrixType.getRawType());
- ASSERT.that(matrixType.getType())
- .isNotEqualTo(new TypeToken<List<?>[]>() {}.getType());
- }
-
- public void testArrayClassPreserved() {
- assertEquals(int[].class, TypeToken.of(int[].class).getType());
- assertEquals(int[][].class, TypeToken.of(int[][].class).getType());
- assertEquals(String[].class, TypeToken.of(String[].class).getType());
- assertEquals(Integer.class, new TypeToken<Integer>() {}.getType());
- assertEquals(Integer.class, TypeToken.of(Integer.class).getType());
- }
-
- public void testMethod_getOwnerType() throws NoSuchMethodException {
- Method sizeMethod = List.class.getMethod("size");
- assertEquals(TypeToken.of(List.class),
- TypeToken.of(List.class).method(sizeMethod).getOwnerType());
- assertEquals(new TypeToken<List<String>>() {},
- new TypeToken<List<String>>() {}.method(sizeMethod).getOwnerType());
- }
-
- public void testMethod_notDeclaredByType() throws NoSuchMethodException {
- Method sizeMethod = Map.class.getMethod("size");
- try {
- TypeToken.of(List.class).method(sizeMethod);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testMethod_declaredBySuperclass() throws Exception {
- Method toStringMethod = Object.class.getMethod("toString");
- ImmutableList<String> list = ImmutableList.of("foo");
- assertEquals(list.toString(), TypeToken.of(List.class).method(toStringMethod).invoke(list));
- }
-
- public <T extends Number & List<String>> void testMethod_returnType_resolvedAgainstTypeBound()
- throws NoSuchMethodException {
- Method getMethod = List.class.getMethod("get", int.class);
- Invokable<T, String> Invokable = new TypeToken<T>(getClass()) {}
- .method(getMethod)
- .returning(String.class);
- assertEquals(TypeToken.of(String.class), Invokable.getReturnType());
- }
-
- public <T extends List<String>> void testMethod_parameterTypes()
- throws NoSuchMethodException {
- Method setMethod = List.class.getMethod("set", int.class, Object.class);
- Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(setMethod);
- ImmutableList<Parameter> params = invokable.getParameters();
- assertEquals(2, params.size());
- assertEquals(TypeToken.of(int.class), params.get(0).getType());
- assertEquals(TypeToken.of(String.class), params.get(1).getType());
- }
-
- private interface Loser<E extends Throwable> {
- void lose() throws E;
- }
-
- public <T extends Loser<AssertionError>> void testMethod_exceptionTypes()
- throws NoSuchMethodException {
- Method failMethod = Loser.class.getMethod("lose");
- Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(failMethod);
- ASSERT.that(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
- }
-
- public void testConstructor_getOwnerType() throws NoSuchMethodException {
- @SuppressWarnings("rawtypes") // raw class ArrayList.class
- Constructor<ArrayList> constructor = ArrayList.class.getConstructor();
- assertEquals(TypeToken.of(ArrayList.class),
- TypeToken.of(ArrayList.class).constructor(constructor).getOwnerType());
- assertEquals(new TypeToken<ArrayList<String>>() {},
- new TypeToken<ArrayList<String>>() {}.constructor(constructor).getOwnerType());
- }
-
- public void testConstructor_notDeclaredByType() throws NoSuchMethodException {
- Constructor<String> constructor = String.class.getConstructor();
- try {
- TypeToken.of(Object.class).constructor(constructor);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testConstructor_declaredBySuperclass() throws NoSuchMethodException {
- Constructor<Object> constructor = Object.class.getConstructor();
- try {
- TypeToken.of(String.class).constructor(constructor);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- private static class Container<T> {
- @SuppressWarnings("unused")
- public Container(T data) {}
- }
-
- public <T extends Container<String>> void testConstructor_parameterTypes()
- throws NoSuchMethodException {
- @SuppressWarnings("rawtypes") // Reflection API skew
- Constructor<Container> constructor = Container.class.getConstructor(Object.class);
- Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
- ImmutableList<Parameter> params = invokable.getParameters();
- assertEquals(1, params.size());
- assertEquals(TypeToken.of(String.class), params.get(0).getType());
- }
-
- private static class CannotConstruct<E extends Throwable> {
- @SuppressWarnings("unused")
- public CannotConstruct() throws E {}
- }
-
- public <T extends CannotConstruct<AssertionError>> void testConstructor_exceptionTypes()
- throws NoSuchMethodException {
- @SuppressWarnings("rawtypes") // Reflection API skew
- Constructor<CannotConstruct> constructor = CannotConstruct.class.getConstructor();
- Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
- ASSERT.that(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
- }
-
- private abstract static class RawTypeConsistencyTester<T extends Enum<T> & CharSequence> {
- abstract T returningT();
- abstract void acceptT(T t);
- abstract <X extends T> X returningX();
- abstract <X> void acceptX(X x);
- abstract <T2 extends Enum<T2> & CharSequence> T2 returningT2();
- abstract <T2 extends CharSequence&Iterable<T2>> void acceptT2(T2 t2);
-
- static void verifyConsitentRawType() {
- for (Method method : RawTypeConsistencyTester.class.getDeclaredMethods()) {
- assertEquals(method.getReturnType(), TypeToken.getRawType(method.getGenericReturnType()));
- for (int i = 0; i < method.getParameterTypes().length; i++) {
- assertEquals(method.getParameterTypes()[i],
- TypeToken.getRawType(method.getGenericParameterTypes()[i]));
- }
- }
- }
- }
-
- public void testRawTypes() throws Exception {
- RawTypeConsistencyTester.verifyConsitentRawType();
- assertEquals(Object.class, TypeToken.getRawType(Types.subtypeOf(Object.class)));
- assertEquals(CharSequence.class, TypeToken.getRawType(Types.subtypeOf(CharSequence.class)));
- assertEquals(Object.class, TypeToken.getRawType(Types.supertypeOf(CharSequence.class)));
- }
-
- private abstract static class IKnowMyType<T> {
- TypeToken<T> type() {
- return new TypeToken<T>(getClass()) {};
- }
- }
-
- public void testTypeResolution() {
- assertEquals(String.class,
- new IKnowMyType<String>() {}.type().getType());
- assertEquals(new TypeToken<Map<String, Integer>>() {},
- new IKnowMyType<Map<String, Integer>>() {}.type());
- }
-
- public <A extends Iterable<? extends String>, B extends A> void testSerializable() {
- reserialize(TypeToken.of(String.class));
- reserialize(TypeToken.of(String.class).getTypes());
- reserialize(TypeToken.of(String.class).getTypes().classes());
- reserialize(TypeToken.of(String.class).getTypes().interfaces());
- reserialize(TypeToken.of(String.class).getTypes().rawTypes());
- reserialize(TypeToken.of(String.class).getTypes().classes().rawTypes());
- reserialize(TypeToken.of(String.class).getTypes().interfaces().rawTypes());
- reserialize(new TypeToken<int[]>() {});
- reserialize(new TypeToken<Map<String, Integer>>() {});
- reserialize(new IKnowMyType<Map<? super String, ? extends int[]>>() {}.type());
- reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes().rawTypes());
- try {
- SerializableTester.reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()));
- fail();
- } catch (RuntimeException expected) {}
- }
-
- public <A> void testSerializable_typeVariableNotSupported() {
- try {
- new ITryToSerializeMyTypeVariable<String>().go();
- fail();
- } catch (RuntimeException expected) {}
- }
-
- private static class ITryToSerializeMyTypeVariable<T> {
- void go() {
- SerializableTester.reserialize(TypeToken.of(new TypeCapture<T>() {}.capture()));
- }
- }
-
- private static <T> T reserialize(T object) {
- T copy = SerializableTester.reserialize(object);
- new EqualsTester()
- .addEqualityGroup(object, copy)
- .testEquals();
- return copy;
- }
-
- public void testTypeResolutionAfterReserialized() {
- reserialize(new TypeToken<String>() {});
- reserialize(new TypeToken<Map<String, Integer>>() {});
- TypeToken<Map<String, Integer>> reserialized = reserialize(
- new TypeToken<Map<String, Integer>>() {});
- assertEquals(reserialized, substitute(reserialized, String.class));
- }
-
- private static <T, X> TypeToken<T> substitute(TypeToken<T> type, Class<X> arg) {
- return type.where(new TypeParameter<X>() {}, arg);
- }
-
- private abstract static class ToReproduceGenericSignatureFormatError<V> {
- private abstract class BaseOuter {
- abstract class BaseInner {}
- }
- private abstract class SubOuter extends BaseOuter {
- private abstract class SubInner extends BaseInner {}
- }
-
- }
-
- // For Guava bug http://code.google.com/p/guava-libraries/issues/detail?id=1025
- public void testDespiteGenericSignatureFormatError() {
- ImmutableSet.copyOf(
- TypeToken.of(ToReproduceGenericSignatureFormatError.SubOuter.SubInner.class)
- .getTypes()
- .rawTypes());
- }
-
- private abstract static class Entry<K, V> {
- TypeToken<K> keyType() {
- return new TypeToken<K>(getClass()) {};
- }
- TypeToken<V> valueType() {
- return new TypeToken<V>(getClass()) {};
- }
- }
-
- // The A and B type parameters are used inside the test to test type variable
- public <A, B> void testEquals() {
- new EqualsTester()
- .addEqualityGroup(
- TypeToken.of(String.class),
- TypeToken.of(String.class),
- new Entry<String, Integer>() {}.keyType(),
- new Entry<Integer, String>() {}.valueType(),
- new TypeToken<String>() {},
- new TypeToken<String>() {})
- .addEqualityGroup(
- TypeToken.of(Integer.class),
- new TypeToken<Integer>() {},
- new Entry<Integer, String>() {}.keyType(),
- new Entry<String, Integer>() {}.valueType())
- .addEqualityGroup(
- new TypeToken<List<String>>() {},
- new TypeToken<List<String>>() {})
- .addEqualityGroup(
- new TypeToken<List<?>>() {},
- new TypeToken<List<?>>() {})
- .addEqualityGroup(
- new TypeToken<Map<A, ?>>() {},
- new TypeToken<Map<A, ?>>() {})
- .addEqualityGroup(
- new TypeToken<Map<B, ?>>() {})
- .addEqualityGroup(
- TypeToken.of(new TypeCapture<A>() {}.capture()),
- TypeToken.of(new TypeCapture<A>() {}.capture()))
- .addEqualityGroup(TypeToken.of(new TypeCapture<B>() {}.capture()))
- .testEquals();
- }
-
- // T is used inside to test type variable
- public <T> void testToString() {
- assertEquals(String.class.getName(), new TypeToken<String>() {}.toString());
- assertEquals("T", TypeToken.of(new TypeCapture<T>() {}.capture()).toString());
- assertEquals("java.lang.String", new Entry<String, Integer>() {}.keyType().toString());
- }
-
- private static <K, V> TypeToken<Map<K, V>> mapOf(Class<K> keyType, Class<V> valueType) {
- return new TypeToken<Map<K, V>>() {}
- .where(new TypeParameter<K>() {}, keyType)
- .where(new TypeParameter<V>() {}, valueType);
- }
-
- private static <T> TypeToken<T[]> arrayOf(Class<T> componentType) {
- return new TypeToken<T[]>() {}
- .where(new TypeParameter<T>() {}, componentType);
- }
-
- public <T> void testNulls() {
- new NullPointerTester()
- .testAllPublicStaticMethods(TypeToken.class);
- new NullPointerTester()
- .setDefault(TypeParameter.class, new TypeParameter<T>() {})
- .testAllPublicInstanceMethods(TypeToken.of(String.class));
- }
-
- private static class Assignability<From, To> {
-
- boolean isAssignable() {
- return new TypeToken<To>(getClass()) {}.isAssignableFrom(new TypeToken<From>(getClass()) {});
- }
-
- static <From, To> Assignability<From, To> of() {
- return new Assignability<From, To>();
- }
- }
-
- private static void assertAssignable(TypeToken<?> from, TypeToken<?> to) {
- assertTrue(
- from.getType() + " is expected to be assignable to " + to.getType(),
- to.isAssignableFrom(from));
- }
-
- private static void assertNotAssignable(TypeToken<?> from, TypeToken<?> to) {
- assertFalse(
- from.getType() + " shouldn't be assignable to " + to.getType(),
- to.isAssignableFrom(from));
- }
-
- private static void assertHasArrayInterfaces(TypeToken<?> arrayType) {
- assertEquals(arrayInterfaces(), ImmutableSet.copyOf(arrayType.getGenericInterfaces()));
- }
-
- private static ImmutableSet<TypeToken<?>> arrayInterfaces() {
- ImmutableSet.Builder<TypeToken<?>> builder = ImmutableSet.builder();
- for (Class<?> interfaceType : Object[].class.getInterfaces()) {
- builder.add(TypeToken.of(interfaceType));
- }
- return builder.build();
- }
-
- private interface BaseInterface {}
- private static class Base implements BaseInterface {}
- private static class Sub extends Base {}
-}
diff --git a/guava-tests/test/com/google/common/reflect/TypesTest.java b/guava-tests/test/com/google/common/reflect/TypesTest.java
deleted file mode 100644
index 096951b..0000000
--- a/guava-tests/test/com/google/common/reflect/TypesTest.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static java.util.Arrays.asList;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.NullPointerTester;
-import com.google.common.testing.NullPointerTester.Visibility;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestCase;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Tests for {@link Types}.
- *
- * @author Ben Yu
- */
-public class TypesTest extends TestCase {
-
- public void testNewParameterizedType_ownerTypeImplied() throws Exception {
- ParameterizedType jvmType = (ParameterizedType)
- new TypeCapture<Map.Entry<String, Integer>>() {}.capture();
- ParameterizedType ourType = Types.newParameterizedType(
- Map.Entry.class, String.class, Integer.class);
- assertEquals(jvmType, ourType);
- assertEquals(Map.class, ourType.getOwnerType());
- }
-
- public void testNewParameterizedType() {
- ParameterizedType jvmType = (ParameterizedType)
- new TypeCapture<HashMap<String, int[][]>>() {}.capture();
- ParameterizedType ourType = Types.newParameterizedType(
- HashMap.class, String.class, int[][].class);
-
- new EqualsTester()
- .addEqualityGroup(jvmType, ourType)
- .testEquals();
- assertEquals(jvmType.toString(), ourType.toString());
- assertEquals(jvmType.hashCode(), ourType.hashCode());
- assertEquals(HashMap.class, ourType.getRawType());
- ASSERT.that(ourType.getActualTypeArguments())
- .iteratesOverSequence(jvmType.getActualTypeArguments());
- assertEquals(Arrays.asList(
- String.class,
- Types.newArrayType(Types.newArrayType(int.class))),
- Arrays.asList(ourType.getActualTypeArguments()));
- assertEquals(null, ourType.getOwnerType());
- }
-
- public void testNewParameterizedType_nonStaticLocalClass() {
- class LocalClass<T> {}
- Type jvmType = new LocalClass<String>() {}.getClass().getGenericSuperclass();
- Type ourType = Types.newParameterizedType(LocalClass.class, String.class);
- assertEquals(jvmType, ourType);
- }
-
- public void testNewParameterizedType_staticLocalClass() {
- doTestNewParameterizedType_staticLocalClass();
- }
-
- private static void doTestNewParameterizedType_staticLocalClass() {
- class LocalClass<T> {}
- Type jvmType = new LocalClass<String>() {}.getClass().getGenericSuperclass();
- Type ourType = Types.newParameterizedType(LocalClass.class, String.class);
- assertEquals(jvmType, ourType);
- }
-
- public void testNewParameterizedTypeWithOwner() {
- ParameterizedType jvmType = (ParameterizedType)
- new TypeCapture<Map.Entry<String, int[][]>>() {}.capture();
- ParameterizedType ourType = Types.newParameterizedTypeWithOwner(
- Map.class, Map.Entry.class, String.class, int[][].class);
-
- new EqualsTester()
- .addEqualityGroup(jvmType, ourType)
- .addEqualityGroup(new TypeCapture<Map.Entry<String, String>>() {}.capture())
- .addEqualityGroup(new TypeCapture<Map<String, Integer>>() {}.capture())
- .testEquals();
- assertEquals(jvmType.toString(), ourType.toString());
- assertEquals(Map.class, ourType.getOwnerType());
- assertEquals(Map.Entry.class, ourType.getRawType());
- ASSERT.that(ourType.getActualTypeArguments())
- .iteratesOverSequence(jvmType.getActualTypeArguments());
- }
-
- public void testNewParameterizedType_serializable() {
- SerializableTester.reserializeAndAssert(Types.newParameterizedType(
- Map.Entry.class, String.class, Integer.class));
- }
-
- public void testNewParameterizedType_ownerMismatch() {
- try {
- Types.newParameterizedTypeWithOwner(
- Number.class, List.class, String.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNewParameterizedType_ownerMissing() {
- assertEquals(
- Types.newParameterizedType(Map.Entry.class, String.class, Integer.class),
- Types.newParameterizedTypeWithOwner(
- null, Map.Entry.class, String.class, Integer.class));
- }
-
- public void testNewParameterizedType_invalidTypeParameters() {
- try {
- Types.newParameterizedTypeWithOwner(
- Map.class, Map.Entry.class, String.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNewParameterizedType_primitiveTypeParameters() {
- try {
- Types.newParameterizedTypeWithOwner(
- Map.class, Map.Entry.class, int.class, int.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNewArrayType() {
- Type jvmType1 = new TypeCapture<List<String>[]>() {}.capture();
- GenericArrayType ourType1 = (GenericArrayType) Types.newArrayType(
- Types.newParameterizedType(List.class, String.class));
- Type jvmType2 = new TypeCapture<List[]>() {}.capture();
- Type ourType2 = Types.newArrayType(List.class);
- new EqualsTester()
- .addEqualityGroup(jvmType1, ourType1)
- .addEqualityGroup(jvmType2, ourType2)
- .testEquals();
- assertEquals(new TypeCapture<List<String>>() {}.capture(),
- ourType1.getGenericComponentType());
- assertEquals(jvmType1.toString(), ourType1.toString());
- assertEquals(jvmType2.toString(), ourType2.toString());
- }
-
- public void testNewArrayTypeOfArray() {
- Type jvmType = new TypeCapture<int[][]>() {}.capture();
- Type ourType = Types.newArrayType(int[].class);
- assertEquals(jvmType.toString(), ourType.toString());
- new EqualsTester()
- .addEqualityGroup(jvmType, ourType)
- .testEquals();
- }
-
- public void testNewArrayType_primitive() {
- Type jvmType = new TypeCapture<int[]>() {}.capture();
- Type ourType = Types.newArrayType(int.class);
- assertEquals(jvmType.toString(), ourType.toString());
- new EqualsTester()
- .addEqualityGroup(jvmType, ourType)
- .testEquals();
- }
-
- public void testNewArrayType_upperBoundedWildcard() {
- Type wildcard = Types.subtypeOf(Number.class);
- assertEquals(Types.subtypeOf(Number[].class), Types.newArrayType(wildcard));
- }
-
- public void testNewArrayType_lowerBoundedWildcard() {
- Type wildcard = Types.supertypeOf(Number.class);
- assertEquals(Types.supertypeOf(Number[].class), Types.newArrayType(wildcard));
- }
-
- public void testNewArrayType_serializable() {
- SerializableTester.reserializeAndAssert(
- Types.newArrayType(int[].class));
- }
-
- private static class WithWildcardType {
-
- @SuppressWarnings("unused")
- void withoutBound(List<?> list) {}
-
- @SuppressWarnings("unused")
- void withObjectBound(List<? extends Object> list) {}
-
- @SuppressWarnings("unused")
- void withUpperBound(List<? extends int[][]> list) {}
-
- @SuppressWarnings("unused")
- void withLowerBound(List<? super String[][]> list) {}
-
- static WildcardType getWildcardType(String methodName) throws Exception {
- ParameterizedType parameterType = (ParameterizedType)
- WithWildcardType.class
- .getDeclaredMethod(methodName, List.class)
- .getGenericParameterTypes()[0];
- return (WildcardType) parameterType.getActualTypeArguments()[0];
- }
- }
-
- public void testNewWildcardType() throws Exception {
- WildcardType noBoundJvmType =
- WithWildcardType.getWildcardType("withoutBound");
- WildcardType objectBoundJvmType =
- WithWildcardType.getWildcardType("withObjectBound");
- WildcardType upperBoundJvmType =
- WithWildcardType.getWildcardType("withUpperBound");
- WildcardType lowerBoundJvmType =
- WithWildcardType.getWildcardType("withLowerBound");
- WildcardType objectBound =
- Types.subtypeOf(Object.class);
- WildcardType upperBound =
- Types.subtypeOf(int[][].class);
- WildcardType lowerBound =
- Types.supertypeOf(String[][].class);
-
- assertEqualWildcardType(noBoundJvmType, objectBound);
- assertEqualWildcardType(objectBoundJvmType, objectBound);
- assertEqualWildcardType(upperBoundJvmType, upperBound);
- assertEqualWildcardType(lowerBoundJvmType, lowerBound);
-
- new EqualsTester()
- .addEqualityGroup(
- noBoundJvmType, objectBoundJvmType, objectBound)
- .addEqualityGroup(upperBoundJvmType, upperBound)
- .addEqualityGroup(lowerBoundJvmType, lowerBound)
- .testEquals();
- }
-
- public void testNewWildcardType_primitiveTypeBound() {
- try {
- Types.subtypeOf(int.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNewWildcardType_serializable() {
- SerializableTester.reserializeAndAssert(
- Types.supertypeOf(String.class));
- SerializableTester.reserializeAndAssert(
- Types.subtypeOf(String.class));
- SerializableTester.reserializeAndAssert(
- Types.subtypeOf(Object.class));
- }
-
- private static void assertEqualWildcardType(
- WildcardType expected, WildcardType actual) {
- assertEquals(expected.toString(), actual.toString());
- assertEquals(actual.toString(), expected.hashCode(), actual.hashCode());
- ASSERT.that(actual.getLowerBounds())
- .has().allFrom(asList(expected.getLowerBounds())).inOrder();
- ASSERT.that(actual.getUpperBounds())
- .has().allFrom(asList(expected.getUpperBounds())).inOrder();
- }
-
- private static class WithTypeVariable {
-
- @SuppressWarnings("unused")
- <T> void withoutBound(List<T> list) {}
-
- @SuppressWarnings("unused")
- <T extends Object> void withObjectBound(List<T> list) {}
-
- @SuppressWarnings("unused")
- <T extends Number & CharSequence> void withUpperBound(List<T> list) {}
-
- static TypeVariable<?> getTypeVariable(String methodName) throws Exception {
- ParameterizedType parameterType = (ParameterizedType)
- WithTypeVariable.class
- .getDeclaredMethod(methodName, List.class)
- .getGenericParameterTypes()[0];
- return (TypeVariable<?>) parameterType.getActualTypeArguments()[0];
- }
- }
-
- public void testNewTypeVariable() throws Exception {
- TypeVariable<?> noBoundJvmType =
- WithTypeVariable.getTypeVariable("withoutBound");
- TypeVariable<?> objectBoundJvmType =
- WithTypeVariable.getTypeVariable("withObjectBound");
- TypeVariable<?> upperBoundJvmType =
- WithTypeVariable.getTypeVariable("withUpperBound");
- TypeVariable<?> noBound = withBounds(noBoundJvmType);
- TypeVariable<?> objectBound = withBounds(objectBoundJvmType, Object.class);
- TypeVariable<?> upperBound = withBounds(
- upperBoundJvmType, Number.class, CharSequence.class);
-
- assertEqualTypeVariable(noBoundJvmType, noBound);
- assertEqualTypeVariable(noBoundJvmType,
- withBounds(noBoundJvmType, Object.class));
- assertEqualTypeVariable(objectBoundJvmType, objectBound);
- assertEqualTypeVariable(upperBoundJvmType, upperBound);
-
- new EqualsTester()
- .addEqualityGroup(noBoundJvmType, noBound)
- .addEqualityGroup(objectBoundJvmType, objectBound)
- .addEqualityGroup(
- upperBoundJvmType, upperBound,
- withBounds(upperBoundJvmType, CharSequence.class)) // bounds ignored
- .testEquals();
- }
-
- public void testNewTypeVariable_primitiveTypeBound() {
- try {
- Types.newTypeVariable(List.class, "E", int.class);
- fail();
- } catch (IllegalArgumentException expected) {}
- }
-
- public void testNewTypeVariable_serializable() throws Exception {
- try {
- SerializableTester.reserialize(Types.newTypeVariable(List.class, "E"));
- fail();
- } catch (RuntimeException expected) {}
- }
-
- private static <D extends GenericDeclaration> TypeVariable<D> withBounds(
- TypeVariable<D> typeVariable, Type... bounds) {
- return Types.newTypeVariable(
- typeVariable.getGenericDeclaration(), typeVariable.getName(), bounds);
- }
-
- private static void assertEqualTypeVariable(
- TypeVariable<?> expected, TypeVariable<?> actual) {
- assertEquals(expected.toString(), actual.toString());
- assertEquals(expected.getName(), actual.getName());
- assertEquals(
- expected.getGenericDeclaration(), actual.getGenericDeclaration());
- assertEquals(actual.toString(), expected.hashCode(), actual.hashCode());
- ASSERT.that(actual.getBounds()).has().allFrom(asList(expected.getBounds())).inOrder();
- }
-
- /**
- * Working with arrays requires defensive code. Verify that we clone the
- * type array for both input and output.
- */
- public void testNewParameterizedTypeImmutability() {
- Type[] typesIn = { String.class, Integer.class };
- ParameterizedType parameterizedType
- = Types.newParameterizedType(Map.class, typesIn);
- typesIn[0] = null;
- typesIn[1] = null;
-
- Type[] typesOut = parameterizedType.getActualTypeArguments();
- typesOut[0] = null;
- typesOut[1] = null;
-
- assertEquals(String.class, parameterizedType.getActualTypeArguments()[0]);
- assertEquals(Integer.class, parameterizedType.getActualTypeArguments()[1]);
- }
-
- public void testNewParameterizedTypeWithWrongNumberOfTypeArguments() {
- try {
- Types.newParameterizedType(
- Map.class, String.class, Integer.class, Long.class);
- fail();
- } catch(IllegalArgumentException expected) {}
- }
-
- public void testContainsTypeVariable_class() {
- assertFalse(Types.containsTypeVariable(String.class));
- assertFalse(Types.containsTypeVariable(String[].class));
- assertFalse(Types.containsTypeVariable(int[].class));
- }
-
- public void testContainsTypeVariable_parameterizedType() {
- assertFalse(Types.containsTypeVariable(new TypeCapture<Iterable<String>>() {}.capture()));
- }
-
- public void testContainsTypeVariable_wildcardType() {
- assertFalse(Types.containsTypeVariable(
- new TypeCapture<Iterable<? extends String>>() {}.capture()));
- assertFalse(Types.containsTypeVariable(
- new TypeCapture<Iterable<? super String>>() {}.capture()));
- }
-
- public void testContainsTypeVariable_genericArrayType() {
- assertFalse(Types.containsTypeVariable(
- new TypeCapture<Iterable<? extends String>[]>() {}.capture()));
- }
-
- public <T> void testContainsTypeVariable_withTypeVariable() {
- assertTrue(Types.containsTypeVariable(new TypeCapture<T>() {}.capture()));
- assertTrue(Types.containsTypeVariable(new TypeCapture<T[]>() {}.capture()));
- assertTrue(Types.containsTypeVariable(new TypeCapture<Iterable<T>>() {}.capture()));
- assertTrue(Types.containsTypeVariable(new TypeCapture<Map<String, T>>() {}.capture()));
- assertTrue(Types.containsTypeVariable(
- new TypeCapture<Map<String, ? extends T>>() {}.capture()));
- assertTrue(Types.containsTypeVariable(
- new TypeCapture<Map<String, ? super T[]>>() {}.capture()));
- }
-
- public void testToString() {
- assertEquals(int[].class.getName(), Types.toString(int[].class));
- assertEquals(int[][].class.getName(), Types.toString(int[][].class));
- assertEquals(String[].class.getName(), Types.toString(String[].class));
- Type elementType = List.class.getTypeParameters()[0];
- assertEquals(elementType.toString(), Types.toString(elementType));
- }
-
- public void testNullPointers() {
- new NullPointerTester().testStaticMethods(Types.class, Visibility.PACKAGE);
- }
-}
diff --git a/guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java b/guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java
deleted file mode 100644
index 5094193..0000000
--- a/guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect.subpackage;
-
-public class ClassInSubPackage {}
diff --git a/guava-tests/test/com/google/common/reflect/test.txt b/guava-tests/test/com/google/common/reflect/test.txt
deleted file mode 100644
index 189e613..0000000
--- a/guava-tests/test/com/google/common/reflect/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is a resource file for testing purpose.
diff --git a/guava-testlib/test/com/google/common/testing/EqualsTesterTest.java b/guava-tests/test/com/google/common/testing/EqualsTesterTest.java
index e2ec18a..e2ec18a 100644
--- a/guava-testlib/test/com/google/common/testing/EqualsTesterTest.java
+++ b/guava-tests/test/com/google/common/testing/EqualsTesterTest.java
diff --git a/guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java b/guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java
index 14ce0e8..0bfb8f1 100644
--- a/guava-testlib/test/com/google/common/testing/EquivalenceTesterTest.java
+++ b/guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java
@@ -17,7 +17,6 @@
package com.google.common.testing;
import static com.google.common.base.Preconditions.checkState;
-import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Equivalence;
@@ -102,9 +101,8 @@ public class EquivalenceTesterTest extends TestCase {
try {
tester.addEquivalenceGroup(group1Item1, group1Item2).test();
} catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains(
- "TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
- + "TestObject{group=1, item=1} [group 1, item 1]");
+ assertEquals("TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
+ + "TestObject{group=1, item=1} [group 1, item 1]", expected.getMessage());
return;
}
fail();
@@ -131,9 +129,8 @@ public class EquivalenceTesterTest extends TestCase {
try {
tester.addEquivalenceGroup(group1Item1, group1Item2, group1Item3).test();
} catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains(
- "TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
- + "TestObject{group=1, item=3} [group 1, item 3]");
+ assertEquals("TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
+ + "TestObject{group=1, item=3} [group 1, item 3]", expected.getMessage());
return;
}
fail();
@@ -154,9 +151,8 @@ public class EquivalenceTesterTest extends TestCase {
try {
tester.addEquivalenceGroup(group1Item1).addEquivalenceGroup(group2Item1).test();
} catch (AssertionFailedError expected) {
- ASSERT.that(expected.getMessage()).contains(
- "TestObject{group=1, item=1} [group 1, item 1] must be inequivalent to "
- + "TestObject{group=2, item=1} [group 2, item 1]");
+ assertEquals("TestObject{group=1, item=1} [group 1, item 1] must be inequivalent to "
+ + "TestObject{group=2, item=1} [group 2, item 1]", expected.getMessage());
return;
}
fail();
diff --git a/guava-tests/test/com/google/common/testing/FakeTickerTest.java b/guava-tests/test/com/google/common/testing/FakeTickerTest.java
new file mode 100644
index 0000000..10a1886
--- /dev/null
+++ b/guava-tests/test/com/google/common/testing/FakeTickerTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.testing;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Unit test for {@link FakeTicker}.
+ *
+ * @author benyu@google.com (Jige Yu)
+ */
+@GwtCompatible(emulated = true)
+public class FakeTickerTest extends TestCase {
+
+ public void testAdvance() {
+ FakeTicker ticker = new FakeTicker();
+ assertEquals(0, ticker.read());
+ assertSame(ticker, ticker.advance(10));
+ assertEquals(10, ticker.read());
+ ticker.advance(1, TimeUnit.MILLISECONDS);
+ assertEquals(1000010L, ticker.read());
+ }
+
+ @GwtIncompatible("concurrency")
+
+ public void testConcurrentAdvance() throws Exception {
+ final FakeTicker ticker = new FakeTicker();
+
+ int numberOfThreads = 64;
+ ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
+ final CountDownLatch startLatch = new CountDownLatch(numberOfThreads);
+ final CountDownLatch doneLatch = new CountDownLatch(numberOfThreads);
+ for (int i = numberOfThreads; i > 0; i--) {
+ executorService.submit(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ // adds two nanoseconds to the ticker
+ startLatch.countDown();
+ startLatch.await();
+ ticker.advance(1L);
+ Thread.sleep(10);
+ ticker.advance(1L);
+ doneLatch.countDown();
+ return null;
+ }
+ });
+ }
+ doneLatch.await();
+ assertEquals(numberOfThreads * 2, ticker.read());
+ }
+}
diff --git a/guava-testlib/test/com/google/common/testing/GcFinalizationTest.java b/guava-tests/test/com/google/common/testing/GcFinalizationTest.java
index 117186f..35299f5 100644
--- a/guava-testlib/test/com/google/common/testing/GcFinalizationTest.java
+++ b/guava-tests/test/com/google/common/testing/GcFinalizationTest.java
@@ -1,18 +1,4 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.testing;
@@ -29,8 +15,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Tests for {@link GcFinalization}.
*
- * @author Martin Buchholz
- * @author mike nonemacher
+ * @author martinrb@google.com (Martin Buchholz)
+ * @author schmoe@google.com (mike nonemacher)
*/
public class GcFinalizationTest extends TestCase {
@@ -42,7 +28,7 @@ public class GcFinalizationTest extends TestCase {
public void testAwait_CountDownLatch() {
final CountDownLatch latch = new CountDownLatch(1);
Object x = new Object() {
- @Override protected void finalize() { latch.countDown(); }
+ protected void finalize() { latch.countDown(); }
};
x = null; // Hint to the JIT that x is unreachable
GcFinalization.await(latch);
@@ -52,7 +38,7 @@ public class GcFinalizationTest extends TestCase {
public void testAwaitDone_Future() {
final SettableFuture<Void> future = SettableFuture.create();
Object x = new Object() {
- @Override protected void finalize() { future.set(null); }
+ protected void finalize() { future.set(null); }
};
x = null; // Hint to the JIT that x is unreachable
GcFinalization.awaitDone(future);
@@ -63,7 +49,7 @@ public class GcFinalizationTest extends TestCase {
public void testAwaitDone_Future_Cancel() {
final SettableFuture<Void> future = SettableFuture.create();
Object x = new Object() {
- @Override protected void finalize() { future.cancel(false); }
+ protected void finalize() { future.cancel(false); }
};
x = null; // Hint to the JIT that x is unreachable
GcFinalization.awaitDone(future);
@@ -189,28 +175,4 @@ public class GcFinalizationTest extends TestCase {
}
}
- /**
- * awaitFullGc() is not quite as reliable a way to ensure calling of a
- * specific finalize method as the more direct await* methods, but should be
- * reliable enough in practice to avoid flakiness of this test. (And if it
- * isn't, we'd like to know about it first!)
- */
- public void testAwaitFullGc() {
- final CountDownLatch finalizerRan = new CountDownLatch(1);
- final WeakReference<Object> ref = new WeakReference<Object>(
- new Object() {
- @Override protected void finalize() { finalizerRan.countDown(); }
- });
-
- // Don't copy this into your own test!
- // Use e.g. awaitClear or await(CountDownLatch) instead.
- GcFinalization.awaitFullGc();
-
- // If this test turns out to be flaky, add a second call to awaitFullGc()
- // GcFinalization.awaitFullGc();
-
- assertEquals(0, finalizerRan.getCount());
- assertNull(ref.get());
- }
-
}
diff --git a/guava-tests/test/com/google/common/testing/NullPointerTesterTest.java b/guava-tests/test/com/google/common/testing/NullPointerTesterTest.java
new file mode 100644
index 0000000..7d0ea99
--- /dev/null
+++ b/guava-tests/test/com/google/common/testing/NullPointerTesterTest.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2005 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.testing;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+/**
+ * Unit test for {@link NullPointerTester}.
+ *
+ * @author Kevin Bourrillion
+ * @author Mick Killianey
+ */
+public class NullPointerTesterTest extends TestCase {
+
+ private NullPointerTester tester;
+
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ tester = new NullPointerTester();
+ }
+
+ /** Non-NPE RuntimeException. */
+ public static class FooException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+ /**
+ * Class for testing all permutations of static/non-static one-argument
+ * methods using methodParameter().
+ */
+ public static class OneArg {
+
+ public static void staticOneArgCorrectlyThrowsNpe(String s) {
+ checkNotNull(s); // expect NPE here on null
+ }
+ public static void staticOneArgThrowsOtherThanNpe(String s) {
+ throw new FooException(); // should catch as failure
+ }
+ public static void staticOneArgShouldThrowNpeButDoesnt(String s) {
+ // should catch as failure
+ }
+ public static void
+ staticOneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
+ // null? no problem
+ }
+ public static void
+ staticOneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
+ throw new FooException(); // ok, as long as it's not NullPointerException
+ }
+ public static void
+ staticOneArgNullableThrowsNPE(@Nullable String s) {
+ checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
+ }
+
+ public void oneArgCorrectlyThrowsNpe(String s) {
+ checkNotNull(s); // expect NPE here on null
+ }
+ public void oneArgThrowsOtherThanNpe(String s) {
+ throw new FooException(); // should catch as failure
+ }
+ public void oneArgShouldThrowNpeButDoesnt(String s) {
+ // should catch as failure
+ }
+ public void oneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
+ // null? no problem
+ }
+ public void oneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
+ throw new FooException(); // ok, as long as it's not NullPointerException
+ }
+ public void oneArgNullableThrowsNPE(@Nullable String s) {
+ checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
+ }
+ }
+
+ private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_PASS = {
+ "staticOneArgCorrectlyThrowsNpe",
+ "staticOneArgNullableCorrectlyDoesNotThrowNPE",
+ "staticOneArgNullableCorrectlyThrowsOtherThanNPE",
+ "staticOneArgNullableThrowsNPE",
+ };
+ private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
+ "staticOneArgThrowsOtherThanNpe",
+ "staticOneArgShouldThrowNpeButDoesnt",
+ };
+ private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS = {
+ "oneArgCorrectlyThrowsNpe",
+ "oneArgNullableCorrectlyDoesNotThrowNPE",
+ "oneArgNullableCorrectlyThrowsOtherThanNPE",
+ "oneArgNullableThrowsNPE",
+ };
+ private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
+ "oneArgThrowsOtherThanNpe",
+ "oneArgShouldThrowNpeButDoesnt",
+ };
+
+ public void testStaticOneArgMethodsThatShouldPass() throws Exception {
+ for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_PASS) {
+ Method method = OneArg.class.getMethod(methodName, String.class);
+ try {
+ tester.testMethodParameter(OneArg.class, method, 0);
+ } catch (AssertionFailedError unexpected) {
+ fail("Should not have flagged method " + methodName);
+ }
+ }
+ }
+
+ public void testStaticOneArgMethodsThatShouldFail() throws Exception {
+ for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
+ Method method = OneArg.class.getMethod(methodName, String.class);
+ boolean foundProblem = false;
+ try {
+ tester.testMethodParameter(OneArg.class, method, 0);
+ } catch (AssertionFailedError expected) {
+ foundProblem = true;
+ }
+ assertTrue("Should report error in method " + methodName, foundProblem);
+ }
+ }
+
+ public void testNonStaticOneArgMethodsThatShouldPass() throws Exception {
+ OneArg foo = new OneArg();
+ for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS) {
+ Method method = OneArg.class.getMethod(methodName, String.class);
+ try {
+ tester.testMethodParameter(foo, method, 0);
+ } catch (AssertionFailedError unexpected) {
+ fail("Should not have flagged method " + methodName);
+ }
+ }
+ }
+
+ public void testNonStaticOneArgMethodsThatShouldFail() throws Exception {
+ OneArg foo = new OneArg();
+ for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
+ Method method = OneArg.class.getMethod(methodName, String.class);
+ boolean foundProblem = false;
+ try {
+ tester.testMethodParameter(foo, method, 0);
+ } catch (AssertionFailedError expected) {
+ foundProblem = true;
+ }
+ assertTrue("Should report error in method " + methodName, foundProblem);
+ }
+ }
+
+ /**
+ * Class for testing all permutations of nullable/non-nullable two-argument
+ * methods using testMethod().
+ *
+ * normalNormal: two params, neither is Nullable
+ * nullableNormal: only first param is Nullable
+ * normalNullable: only second param is Nullable
+ * nullableNullable: both params are Nullable
+ */
+ public static class TwoArg {
+ /** Action to take on a null param. */
+ public enum Action {
+ THROW_A_NPE {
+ @Override public void act() {
+ throw new NullPointerException();
+ }
+ },
+ THROW_OTHER {
+ @Override public void act() {
+ throw new FooException();
+ }
+ },
+ JUST_RETURN {
+ @Override public void act() {}
+ };
+
+ public abstract void act();
+ }
+ Action actionWhenFirstParamIsNull;
+ Action actionWhenSecondParamIsNull;
+
+ public TwoArg(
+ Action actionWhenFirstParamIsNull,
+ Action actionWhenSecondParamIsNull) {
+ this.actionWhenFirstParamIsNull = actionWhenFirstParamIsNull;
+ this.actionWhenSecondParamIsNull = actionWhenSecondParamIsNull;
+ }
+
+ /** Method that decides how to react to parameters. */
+ public void reactToNullParameters(Object first, Object second) {
+ if (first == null) {
+ actionWhenFirstParamIsNull.act();
+ }
+ if (second == null) {
+ actionWhenSecondParamIsNull.act();
+ }
+ }
+
+ /** Two-arg method with no Nullable params. */
+ public void normalNormal(String first, Integer second) {
+ reactToNullParameters(first, second);
+ }
+
+ /** Two-arg method with the second param Nullable. */
+ public void normalNullable(String first, @Nullable Integer second) {
+ reactToNullParameters(first, second);
+ }
+
+ /** Two-arg method with the first param Nullable. */
+ public void nullableNormal(@Nullable String first, Integer second) {
+ reactToNullParameters(first, second);
+ }
+
+ /** Two-arg method with the both params Nullable. */
+ public void nullableNullable(
+ @Nullable String first, @Nullable Integer second) {
+ reactToNullParameters(first, second);
+ }
+
+ /** To provide sanity during debugging. */
+ @Override public String toString() {
+ return String.format("Bar(%s, %s)",
+ actionWhenFirstParamIsNull, actionWhenSecondParamIsNull);
+ }
+ }
+
+ public void verifyBarPass(Method method, TwoArg bar) throws Exception {
+ try {
+ tester.testMethod(bar, method);
+ } catch (AssertionFailedError incorrectError) {
+ String errorMessage = String.format(
+ "Should not have flagged method %s for %s", method.getName(), bar);
+ assertNull(errorMessage, incorrectError);
+ }
+ }
+
+ public void verifyBarFail(Method method, TwoArg bar) throws Exception {
+ try {
+ tester.testMethod(bar, method);
+ } catch (AssertionFailedError expected) {
+ return; // good...we wanted a failure
+ }
+ String errorMessage = String.format(
+ "Should have flagged method %s for %s", method.getName(), bar);
+ fail(errorMessage);
+ }
+
+ public void testTwoArgNormalNormal() throws Exception {
+ Method method = TwoArg.class.getMethod(
+ "normalNormal", String.class, Integer.class);
+ for (TwoArg.Action first : TwoArg.Action.values()) {
+ for (TwoArg.Action second : TwoArg.Action.values()) {
+ TwoArg bar = new TwoArg(first, second);
+ if (first.equals(TwoArg.Action.THROW_A_NPE)
+ && second.equals(TwoArg.Action.THROW_A_NPE)) {
+ verifyBarPass(method, bar); // require both params to throw NPE
+ } else {
+ verifyBarFail(method, bar);
+ }
+ }
+ }
+ }
+
+ public void testTwoArgNormalNullable() throws Exception {
+ Method method = TwoArg.class.getMethod(
+ "normalNullable", String.class, Integer.class);
+ for (TwoArg.Action first : TwoArg.Action.values()) {
+ for (TwoArg.Action second : TwoArg.Action.values()) {
+ TwoArg bar = new TwoArg(first, second);
+ if (first.equals(TwoArg.Action.THROW_A_NPE)) {
+ verifyBarPass(method, bar); // only pass if 1st param throws NPE
+ } else {
+ verifyBarFail(method, bar);
+ }
+ }
+ }
+ }
+
+ public void testTwoArgNullableNormal() throws Exception {
+ Method method = TwoArg.class.getMethod(
+ "nullableNormal", String.class, Integer.class);
+ for (TwoArg.Action first : TwoArg.Action.values()) {
+ for (TwoArg.Action second : TwoArg.Action.values()) {
+ TwoArg bar = new TwoArg(first, second);
+ if (second.equals(TwoArg.Action.THROW_A_NPE)) {
+ verifyBarPass(method, bar); // only pass if 2nd param throws NPE
+ } else {
+ verifyBarFail(method, bar);
+ }
+ }
+ }
+ }
+
+ public void testTwoArgNullableNullable() throws Exception {
+ Method method = TwoArg.class.getMethod(
+ "nullableNullable", String.class, Integer.class);
+ for (TwoArg.Action first : TwoArg.Action.values()) {
+ for (TwoArg.Action second : TwoArg.Action.values()) {
+ TwoArg bar = new TwoArg(first, second);
+ verifyBarPass(method, bar); // All args nullable: anything goes!
+ }
+ }
+ }
+
+ /*
+ * This next part consists of several sample classes that provide
+ * demonstrations of conditions that cause NullPointerTester
+ * to succeed/fail.
+ *
+ * Add naughty classes to failClasses to verify that NullPointerTest
+ * raises an AssertionFailedError.
+ *
+ * Add acceptable classes to passClasses to verify that NullPointerTest
+ * doesn't complain.
+ */
+
+ /** List of classes that NullPointerTester should pass as acceptable. */
+ static List<Class<?>> failClasses = Lists.newArrayList();
+
+ /** List of classes that NullPointerTester should flag as problematic. */
+ static List<Class<?>> passClasses = Lists.newArrayList();
+
+ /** Lots of well-behaved methods. */
+ public static class PassObject {
+ public static void doThrow(Object arg) {
+ if (arg == null) {
+ throw new FooException();
+ }
+ }
+ public void noArg() {}
+ public void oneArg(String s) { checkNotNull(s); }
+ public void oneNullableArg(@Nullable String s) {}
+ public void oneNullableArgThrows(@Nullable String s) { doThrow(s); }
+
+ public void twoArg(String s, Integer i) { checkNotNull(s); i.intValue(); }
+ public void twoMixedArgs(String s, @Nullable Integer i) { checkNotNull(s); }
+ public void twoMixedArgsThrows(String s, @Nullable Integer i) {
+ checkNotNull(s); doThrow(i);
+ }
+ public void twoMixedArgs(@Nullable Integer i, String s) { checkNotNull(s); }
+ public void twoMixedArgsThrows(@Nullable Integer i, String s) {
+ checkNotNull(s); doThrow(i);
+ }
+ public void twoNullableArgs(@Nullable String s,
+ @javax.annotation.Nullable Integer i) { }
+ public void twoNullableArgsThrowsFirstArg(
+ @Nullable String s, @Nullable Integer i) {
+ doThrow(s);
+ }
+ public void twoNullableArgsThrowsSecondArg(
+ @Nullable String s, @Nullable Integer i) {
+ doThrow(i);
+ }
+ public static void staticOneArg(String s) { checkNotNull(s); }
+ public static void staticOneNullableArg(@Nullable String s) { }
+ public static void staticOneNullableArgThrows(@Nullable String s) {
+ doThrow(s);
+ }
+ }
+ static { passClasses.add(PassObject.class); }
+
+ static class FailOneArgDoesntThrowNPE extends PassObject {
+ @Override public void oneArg(String s) {
+ // Fail: missing NPE for s
+ }
+ }
+ static { failClasses.add(FailOneArgDoesntThrowNPE.class); }
+
+ static class FailOneArgThrowsWrongType extends PassObject {
+ @Override public void oneArg(String s) {
+ doThrow(s); // Fail: throwing non-NPE exception for null s
+ }
+ }
+ static { failClasses.add(FailOneArgThrowsWrongType.class); }
+
+ static class PassOneNullableArgThrowsNPE extends PassObject {
+ @Override public void oneNullableArg(@Nullable String s) {
+ checkNotNull(s); // ok to throw NPE
+ }
+ }
+ static { passClasses.add(PassOneNullableArgThrowsNPE.class); }
+
+ static class FailTwoArgsFirstArgDoesntThrowNPE extends PassObject {
+ @Override public void twoArg(String s, Integer i) {
+ // Fail: missing NPE for s
+ i.intValue();
+ }
+ }
+ static { failClasses.add(FailTwoArgsFirstArgDoesntThrowNPE.class); }
+
+ static class FailTwoArgsFirstArgThrowsWrongType extends PassObject {
+ @Override public void twoArg(String s, Integer i) {
+ doThrow(s); // Fail: throwing non-NPE exception for null s
+ i.intValue();
+ }
+ }
+ static { failClasses.add(FailTwoArgsFirstArgThrowsWrongType.class); }
+
+ static class FailTwoArgsSecondArgDoesntThrowNPE extends PassObject {
+ @Override public void twoArg(String s, Integer i) {
+ checkNotNull(s);
+ // Fail: missing NPE for i
+ }
+ }
+ static { failClasses.add(FailTwoArgsSecondArgDoesntThrowNPE.class); }
+
+ static class FailTwoArgsSecondArgThrowsWrongType extends PassObject {
+ @Override public void twoArg(String s, Integer i) {
+ checkNotNull(s);
+ doThrow(i); // Fail: throwing non-NPE exception for null i
+ }
+ }
+ static { failClasses.add(FailTwoArgsSecondArgThrowsWrongType.class); }
+
+ static class FailTwoMixedArgsFirstArgDoesntThrowNPE extends PassObject {
+ @Override public void twoMixedArgs(String s, @Nullable Integer i) {
+ // Fail: missing NPE for s
+ }
+ }
+ static { failClasses.add(FailTwoMixedArgsFirstArgDoesntThrowNPE.class); }
+
+ static class FailTwoMixedArgsFirstArgThrowsWrongType extends PassObject {
+ @Override public void twoMixedArgs(String s, @Nullable Integer i) {
+ doThrow(s); // Fail: throwing non-NPE exception for null s
+ }
+ }
+ static { failClasses.add(FailTwoMixedArgsFirstArgThrowsWrongType.class); }
+
+ static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject {
+ @Override public void twoMixedArgs(String s, @Nullable Integer i) {
+ checkNotNull(s);
+ i.intValue(); // ok to throw NPE?
+ }
+ }
+ static { passClasses.add(PassTwoMixedArgsNullableArgThrowsNPE.class); }
+
+ static class PassTwoMixedArgSecondNullableArgThrowsOther extends PassObject {
+ @Override public void twoMixedArgs(String s, @Nullable Integer i) {
+ checkNotNull(s);
+ doThrow(i); // ok to throw non-NPE exception for null i
+ }
+ }
+ static { passClasses.add(PassTwoMixedArgSecondNullableArgThrowsOther.class); }
+
+ static class FailTwoMixedArgsSecondArgDoesntThrowNPE extends PassObject {
+ @Override public void twoMixedArgs(@Nullable Integer i, String s) {
+ // Fail: missing NPE for null s
+ }
+ }
+ static { failClasses.add(FailTwoMixedArgsSecondArgDoesntThrowNPE.class); }
+
+ static class FailTwoMixedArgsSecondArgThrowsWrongType extends PassObject {
+ @Override public void twoMixedArgs(@Nullable Integer i, String s) {
+ doThrow(s); // Fail: throwing non-NPE exception for null s
+ }
+ }
+ static { failClasses.add(FailTwoMixedArgsSecondArgThrowsWrongType.class); }
+
+ static class PassTwoNullableArgsFirstThrowsNPE extends PassObject {
+ @Override public void twoNullableArgs(
+ @Nullable String s, @Nullable Integer i) {
+ checkNotNull(s); // ok to throw NPE?
+ }
+ }
+ static { passClasses.add(PassTwoNullableArgsFirstThrowsNPE.class); }
+
+ static class PassTwoNullableArgsFirstThrowsOther extends PassObject {
+ @Override public void twoNullableArgs(
+ @Nullable String s, @Nullable Integer i) {
+ doThrow(s); // ok to throw non-NPE exception for null s
+ }
+ }
+ static { passClasses.add(PassTwoNullableArgsFirstThrowsOther.class); }
+
+ static class PassTwoNullableArgsSecondThrowsNPE extends PassObject {
+ @Override public void twoNullableArgs(
+ @Nullable String s, @Nullable Integer i) {
+ i.intValue(); // ok to throw NPE?
+ }
+ }
+ static { passClasses.add(PassTwoNullableArgsSecondThrowsNPE.class); }
+
+ static class PassTwoNullableArgsSecondThrowsOther extends PassObject {
+ @Override public void twoNullableArgs(
+ @Nullable String s, @Nullable Integer i) {
+ doThrow(i); // ok to throw non-NPE exception for null i
+ }
+ }
+ static { passClasses.add(PassTwoNullableArgsSecondThrowsOther.class); }
+
+ static class PassTwoNullableArgsNeitherThrowsAnything extends PassObject {
+ @Override public void twoNullableArgs(
+ @Nullable String s, @Nullable Integer i) {
+ // ok to do nothing
+ }
+ }
+ static { passClasses.add(PassTwoNullableArgsNeitherThrowsAnything.class); }
+
+ /** Sanity check: it's easy to make typos. */
+ private void checkClasses(String message, List<Class<?>> classes) {
+ Set<Class<?>> set = Sets.newHashSet(classes);
+ for (Class<?> clazz : classes) {
+ if (!set.remove(clazz)) {
+ fail(String.format("%s: %s appears twice. Typo?",
+ message, clazz.getSimpleName()));
+ }
+ }
+ }
+
+ public void testDidntMakeTypoInTestCases() {
+ checkClasses("passClass", passClasses);
+ checkClasses("failClasses", failClasses);
+ List<Class<?>> allClasses = Lists.newArrayList(passClasses);
+ allClasses.addAll(failClasses);
+ checkClasses("allClasses", allClasses);
+ }
+
+ public void testShouldNotFindProblemInPassClass() throws Exception {
+ for (Class<?> passClass : passClasses) {
+ Object instance = passClass.newInstance();
+ try {
+ tester.testAllPublicInstanceMethods(instance);
+ } catch (AssertionFailedError e) {
+ assertNull("Should not detect problem in " + passClass.getSimpleName(),
+ e);
+ }
+ }
+ }
+
+ public void testShouldFindProblemInFailClass() throws Exception {
+ for (Class<?> failClass : failClasses) {
+ Object instance = failClass.newInstance();
+ boolean foundProblem = false;
+ try {
+ tester.testAllPublicInstanceMethods(instance);
+ } catch (AssertionFailedError e) {
+ foundProblem = true;
+ }
+ assertTrue("Should detect problem in " + failClass.getSimpleName(),
+ foundProblem);
+ }
+ }
+
+ private static class PrivateClassWithPrivateConstructor {
+ private PrivateClassWithPrivateConstructor(@Nullable Integer argument) {}
+ }
+
+ public void testPrivateClass() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ for (Constructor<?> constructor
+ : PrivateClassWithPrivateConstructor.class.getDeclaredConstructors()) {
+ tester.testConstructor(constructor);
+ }
+ }
+
+ private interface Foo<T> {
+ void doSomething(T bar, Integer baz);
+ }
+
+ private static class StringFoo implements Foo<String> {
+
+ @Override public void doSomething(String bar, Integer baz) {
+ checkNotNull(bar);
+ checkNotNull(baz);
+ }
+ }
+
+ public void testBidgeMethodIgnored() throws Exception {
+ new NullPointerTester().testAllPublicInstanceMethods(new StringFoo());
+ }
+
+ /*
+ *
+ * TODO(kevinb): This is only a very small start.
+ * Must come back and finish.
+ *
+ */
+
+}
diff --git a/guava-testlib/test/com/google/common/testing/SerializableTesterTest.java b/guava-tests/test/com/google/common/testing/SerializableTesterTest.java
index d62860b..d62860b 100644
--- a/guava-testlib/test/com/google/common/testing/SerializableTesterTest.java
+++ b/guava-tests/test/com/google/common/testing/SerializableTesterTest.java
diff --git a/guava-testlib/test/com/google/common/testing/TearDownStackTest.java b/guava-tests/test/com/google/common/testing/TearDownStackTest.java
index 8a0a8f3..ee26536 100644
--- a/guava-testlib/test/com/google/common/testing/TearDownStackTest.java
+++ b/guava-tests/test/com/google/common/testing/TearDownStackTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Guava Authors
+ * Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-testlib/test/com/google/common/testing/TestLogHandlerTest.java b/guava-tests/test/com/google/common/testing/TestLogHandlerTest.java
index f193e1f..9dd4ad3 100644
--- a/guava-testlib/test/com/google/common/testing/TestLogHandlerTest.java
+++ b/guava-tests/test/com/google/common/testing/TestLogHandlerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Guava Authors
+ * Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java
index 9b14c7d..d7fd91e 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java
@@ -17,8 +17,6 @@
package com.google.common.util.concurrent;
import com.google.common.base.Throwables;
-import com.google.common.testing.TearDown;
-import com.google.common.testing.TearDownStack;
import junit.framework.TestCase;
@@ -26,8 +24,6 @@ import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -39,7 +35,6 @@ import java.util.concurrent.TimeoutException;
*/
public class AbstractExecutionThreadServiceTest extends TestCase {
- private final TearDownStack tearDownStack = new TearDownStack(true);
private final CountDownLatch enterRun = new CountDownLatch(1);
private final CountDownLatch exitRun = new CountDownLatch(1);
@@ -59,10 +54,6 @@ public class AbstractExecutionThreadServiceTest extends TestCase {
}
};
- @Override protected final void tearDown() {
- tearDownStack.runTearDown();
- }
-
public void testServiceStartStop() throws Exception {
WaitOnRunService service = new WaitOnRunService();
assertFalse(service.startUpCalled);
@@ -308,80 +299,4 @@ public class AbstractExecutionThreadServiceTest extends TestCase {
}
}
- public void testStopWhileStarting_runNotCalled() throws Exception {
- final CountDownLatch started = new CountDownLatch(1);
- FakeService service = new FakeService() {
- @Override protected void startUp() throws Exception {
- super.startUp();
- started.await();
- }
- };
- service.start();
- ListenableFuture<Service.State> stopped = service.stop();
- started.countDown();
- assertEquals(Service.State.TERMINATED, stopped.get());
- assertEquals(Service.State.TERMINATED, service.state());
- assertEquals(1, service.startupCalled);
- assertEquals(0, service.runCalled);
- assertEquals(1, service.shutdownCalled);
- }
-
- public void testStop_noStart() {
- FakeService service = new FakeService();
- assertEquals(Service.State.TERMINATED, service.stopAndWait());
- assertEquals(Service.State.TERMINATED, service.state());
- assertEquals(0, service.startupCalled);
- assertEquals(0, service.runCalled);
- assertEquals(0, service.shutdownCalled);
- }
-
- public void testDefaultService() {
- AbstractExecutionThreadService service = new AbstractExecutionThreadService() {
- @Override protected void run() throws Exception {}
- };
- assertEquals(Service.State.RUNNING, service.startAndWait());
- assertEquals(Service.State.TERMINATED, service.stopAndWait());
- }
-
- private class FakeService extends AbstractExecutionThreadService implements TearDown {
-
- private final ExecutorService executor = Executors.newSingleThreadExecutor();
-
- FakeService() {
- tearDownStack.addTearDown(this);
- }
-
- volatile int startupCalled = 0;
- volatile int shutdownCalled = 0;
- volatile int runCalled = 0;
-
- @Override protected void startUp() throws Exception {
- assertEquals(0, startupCalled);
- assertEquals(0, runCalled);
- assertEquals(0, shutdownCalled);
- startupCalled++;
- }
-
- @Override protected void run() throws Exception {
- assertEquals(1, startupCalled);
- assertEquals(0, runCalled);
- assertEquals(0, shutdownCalled);
- runCalled++;
- }
-
- @Override protected void shutDown() throws Exception {
- assertEquals(1, startupCalled);
- assertEquals(0, shutdownCalled);
- assertEquals(Service.State.STOPPING, state());
- shutdownCalled++;
- }
-
- @Override protected Executor executor() {
- return executor;
- }
-
- @Override public void tearDown() throws Exception {
- executor.shutdown();
- }
- }
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
index 4024a8e..a7dd412 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
@@ -16,12 +16,11 @@
package com.google.common.util.concurrent;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
-import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -64,37 +63,23 @@ public class AbstractFutureTest extends TestCase {
checkStackTrace(ee2);
}
- public void testCancel_notDoneNoInterrupt() throws Exception {
+ public void testCancel_notDoneNoInterrupt() {
InterruptibleFuture future = new InterruptibleFuture();
assertTrue(future.cancel(false));
assertTrue(future.isCancelled());
assertTrue(future.isDone());
- assertFalse(future.wasInterrupted());
- assertFalse(future.interruptTaskWasCalled);
- try {
- future.get();
- fail("Expected CancellationException");
- } catch (CancellationException e) {
- assertNotNull(e.getCause());
- }
+ assertFalse(future.wasInterrupted);
}
- public void testCancel_notDoneInterrupt() throws Exception {
+ public void testCancel_notDoneInterrupt() {
InterruptibleFuture future = new InterruptibleFuture();
assertTrue(future.cancel(true));
assertTrue(future.isCancelled());
assertTrue(future.isDone());
- assertTrue(future.wasInterrupted());
- assertTrue(future.interruptTaskWasCalled);
- try {
- future.get();
- fail("Expected CancellationException");
- } catch (CancellationException e) {
- assertNotNull(e.getCause());
- }
+ assertTrue(future.wasInterrupted);
}
- public void testCancel_done() throws Exception {
+ public void testCancel_done() {
AbstractFuture<String> future = new AbstractFuture<String>() {
{
set("foo");
@@ -192,11 +177,10 @@ public class AbstractFutureTest extends TestCase {
private static final class InterruptibleFuture
extends AbstractFuture<String> {
- boolean interruptTaskWasCalled;
+ boolean wasInterrupted;
@Override protected void interruptTask() {
- assertFalse(interruptTaskWasCalled);
- interruptTaskWasCalled = true;
+ wasInterrupted = true;
}
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
index 2939661..8131a37 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
@@ -16,200 +16,112 @@
package com.google.common.util.concurrent;
-import static org.truth0.Truth.ASSERT;
-
-import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Service.State;
import junit.framework.TestCase;
-import java.util.List;
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
- * Tests for {@link AbstractIdleService}.
+ * Unit test for {@link AbstractIdleService}.
*
* @author Chris Nokleberg
- * @author Ben Yu
*/
public class AbstractIdleServiceTest extends TestCase {
-
- // Functional tests using real thread. We only verify publicly visible state.
- // Interaction assertions are done by the single-threaded unit tests.
-
- public static class FunctionalTest extends TestCase {
-
- private static class DefaultService extends AbstractIdleService {
- @Override protected void startUp() throws Exception {}
- @Override protected void shutDown() throws Exception {}
+ private Thread executorThread;
+ private Throwable thrownByExecutorThread;
+ private final Executor executor = new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ executorThread = new Thread(command);
+ executorThread.setUncaughtExceptionHandler(
+ new UncaughtExceptionHandler() {
+ @Override
+ public void uncaughtException(Thread thread, Throwable e) {
+ thrownByExecutorThread = e;
+ }
+ });
+ executorThread.start();
}
+ };
- public void testServiceStartStop() throws Exception {
- AbstractIdleService service = new DefaultService();
- assertEquals(Service.State.RUNNING, service.startAndWait());
- assertEquals(Service.State.RUNNING, service.state());
- assertEquals(Service.State.TERMINATED, service.stopAndWait());
- assertEquals(Service.State.TERMINATED, service.state());
- }
-
- public void testStart_failed() throws Exception {
- final Exception exception = new Exception("deliberate");
- AbstractIdleService service = new DefaultService() {
- @Override protected void startUp() throws Exception {
- throw exception;
- }
- };
- try {
- service.startAndWait();
- fail();
- } catch (RuntimeException e) {
- assertSame(exception, e.getCause());
- }
- assertEquals(Service.State.FAILED, service.state());
- }
+ public void testServiceStartStop() throws Exception {
+ NullService service = new NullService();
+ assertFalse(service.startUpCalled);
- public void testStop_failed() throws Exception {
- final Exception exception = new Exception("deliberate");
- AbstractIdleService service = new DefaultService() {
- @Override protected void shutDown() throws Exception {
- throw exception;
- }
- };
- service.startAndWait();
- try {
- service.stopAndWait();
- fail();
- } catch (RuntimeException e) {
- assertSame(exception, e.getCause());
- }
- assertEquals(Service.State.FAILED, service.state());
- }
- }
-
- public void testStart() {
- TestService service = new TestService();
- assertEquals(0, service.startUpCalled);
- service.startAndWait();
- assertEquals(1, service.startUpCalled);
+ service.start().get();
+ assertTrue(service.startUpCalled);
assertEquals(Service.State.RUNNING, service.state());
- ASSERT.that(service.transitionStates).has().allOf(Service.State.STARTING).inOrder();
- }
-
- public void testStart_failed() {
- final Exception exception = new Exception("deliberate");
- TestService service = new TestService() {
- @Override protected void startUp() throws Exception {
- super.startUp();
- throw exception;
- }
- };
- assertEquals(0, service.startUpCalled);
- try {
- service.startAndWait();
- fail();
- } catch (RuntimeException e) {
- assertSame(exception, e.getCause());
- }
- assertEquals(1, service.startUpCalled);
- assertEquals(Service.State.FAILED, service.state());
- ASSERT.that(service.transitionStates).has().allOf(Service.State.STARTING).inOrder();
- }
- public void testStop_withoutStart() {
- TestService service = new TestService();
- service.stopAndWait();
- assertEquals(0, service.startUpCalled);
- assertEquals(0, service.shutDownCalled);
+ service.stop().get();
+ assertTrue(service.shutDownCalled);
assertEquals(Service.State.TERMINATED, service.state());
- ASSERT.that(service.transitionStates).isEmpty();
+ executorThread.join();
+ assertNull(thrownByExecutorThread);
}
- public void testStop_afterStart() {
- TestService service = new TestService();
- service.startAndWait();
- assertEquals(1, service.startUpCalled);
- assertEquals(0, service.shutDownCalled);
- service.stopAndWait();
- assertEquals(1, service.startUpCalled);
- assertEquals(1, service.shutDownCalled);
- assertEquals(Service.State.TERMINATED, service.state());
- ASSERT.that(service.transitionStates)
- .has().allOf(Service.State.STARTING, Service.State.STOPPING).inOrder();
- }
-
- public void testStop_failed() {
- final Exception exception = new Exception("deliberate");
- TestService service = new TestService() {
- @Override protected void shutDown() throws Exception {
- super.shutDown();
- throw exception;
- }
- };
- service.startAndWait();
- assertEquals(1, service.startUpCalled);
- assertEquals(0, service.shutDownCalled);
- try {
- service.stopAndWait();
- fail();
- } catch (RuntimeException e) {
- assertSame(exception, e.getCause());
- }
- assertEquals(1, service.startUpCalled);
- assertEquals(1, service.shutDownCalled);
- assertEquals(Service.State.FAILED, service.state());
- ASSERT.that(service.transitionStates)
- .has().allOf(Service.State.STARTING, Service.State.STOPPING).inOrder();
- }
-
- public void testServiceToString() {
- AbstractIdleService service = new TestService();
- assertEquals("TestService [NEW]", service.toString());
- service.startAndWait();
- assertEquals("TestService [RUNNING]", service.toString());
- service.stopAndWait();
- assertEquals("TestService [TERMINATED]", service.toString());
+ public void testServiceToString() throws Exception {
+ NullService service = new NullService();
+ assertEquals("NullService [" + Service.State.NEW + "]", service.toString());
+ service.start().get();
+ assertEquals("NullService [" + Service.State.RUNNING + "]", service.toString());
+ service.stop().get();
+ assertEquals("NullService [" + Service.State.TERMINATED + "]", service.toString());
}
public void testTimeout() throws Exception {
// Create a service whose executor will never run its commands
- Service service = new TestService() {
- @Override protected Executor executor() {
+ Service service = new NullService() {
+ @Override protected Executor executor(Service.State state) {
return new Executor() {
- @Override public void execute(Runnable command) {}
+ @Override public void execute(Runnable command) {
+ }
};
}
};
+
try {
service.start().get(1, TimeUnit.MILLISECONDS);
fail("Expected timeout");
} catch (TimeoutException e) {
- ASSERT.that(e.getMessage()).contains(Service.State.STARTING.toString());
+ assertTrue(e.getMessage().contains(State.STARTING.toString()));
}
}
- private static class TestService extends AbstractIdleService {
- int startUpCalled = 0;
- int shutDownCalled = 0;
- final List<State> transitionStates = Lists.newArrayList();
+ private class NullService extends AbstractIdleService {
+ boolean startUpCalled = false;
+ boolean shutDownCalled = false;
+ State expectedShutdownState = State.STOPPING;
- @Override protected void startUp() throws Exception {
- assertEquals(0, startUpCalled);
- assertEquals(0, shutDownCalled);
- startUpCalled++;
+ @Override protected void startUp() {
+ assertFalse(startUpCalled);
+ assertFalse(shutDownCalled);
+ startUpCalled = true;
assertEquals(State.STARTING, state());
}
- @Override protected void shutDown() throws Exception {
- assertEquals(1, startUpCalled);
- assertEquals(0, shutDownCalled);
- shutDownCalled++;
- assertEquals(State.STOPPING, state());
+ @Override protected void shutDown() {
+ assertTrue(startUpCalled);
+ assertFalse(shutDownCalled);
+ shutDownCalled = true;
+ assertEquals(expectedShutdownState, state());
}
- @Override protected Executor executor() {
- transitionStates.add(state());
- return MoreExecutors.sameThreadExecutor();
+ @Override protected Executor executor(Service.State state) {
+ switch (state) {
+ case STARTING:
+ assertFalse(startUpCalled);
+ return executor;
+ case STOPPING:
+ assertTrue(startUpCalled);
+ assertFalse(shutDownCalled);
+ return executor;
+ default:
+ throw new IllegalStateException("unexpected state " + state);
+ }
}
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
index 95f9fa8..c839e44 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
@@ -21,7 +21,6 @@ import com.google.common.util.concurrent.Service.State;
import junit.framework.TestCase;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
@@ -29,6 +28,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
+
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -65,7 +65,9 @@ public class AbstractScheduledServiceTest extends TestCase {
}
private class NullService extends AbstractScheduledService {
- @Override protected void runOneIteration() throws Exception {}
+ @Override protected void runOneIteration() throws Exception { }
+ @Override protected void startUp() throws Exception { }
+ @Override protected void shutDown() throws Exception { }
@Override protected Scheduler scheduler() { return configuration; }
@Override protected ScheduledExecutorService executor() { return executor; }
}
@@ -148,85 +150,6 @@ public class AbstractScheduledServiceTest extends TestCase {
assertEquals(1, service.numberOfTimesExecutorCalled.get());
}
- public void testDefaultExecutorIsShutdownWhenServiceIsStopped() throws Exception {
- final CountDownLatch terminationLatch = new CountDownLatch(1);
- AbstractScheduledService service = new AbstractScheduledService() {
- volatile ScheduledExecutorService executorService;
- @Override protected void runOneIteration() throws Exception {}
-
- @Override protected ScheduledExecutorService executor() {
- if (executorService == null) {
- executorService = super.executor();
- // Add a listener that will be executed after the listener that shuts down the executor.
- addListener(new Listener() {
- @Override public void starting() {}
- @Override public void running() {}
- @Override public void stopping(State from) {}
- @Override public void terminated(State from) {
- terminationLatch.countDown();
- }
- @Override public void failed(State from, Throwable failure) {}
- }, MoreExecutors.sameThreadExecutor());
- }
- return executorService;
- }
-
- @Override protected Scheduler scheduler() {
- return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS);
- }};
-
- service.start();
- assertFalse(service.executor().isShutdown());
- service.startAndWait();
- service.stop();
- terminationLatch.await();
- assertTrue(service.executor().isShutdown());
- assertTrue(service.executor().awaitTermination(100, TimeUnit.MILLISECONDS));
- }
-
- public void testDefaultExecutorIsShutdownWhenServiceFails() throws Exception {
- final CountDownLatch failureLatch = new CountDownLatch(1);
- AbstractScheduledService service = new AbstractScheduledService() {
- volatile ScheduledExecutorService executorService;
- @Override protected void runOneIteration() throws Exception {}
-
- @Override protected void startUp() throws Exception {
- throw new Exception("Failed");
- }
-
- @Override protected ScheduledExecutorService executor() {
- if (executorService == null) {
- executorService = super.executor();
- // Add a listener that will be executed after the listener that shuts down the executor.
- addListener(new Listener() {
- @Override public void starting() {}
- @Override public void running() {}
- @Override public void stopping(State from) {}
- @Override public void terminated(State from) {
- }
- @Override public void failed(State from, Throwable failure) {
- failureLatch.countDown();
- }
- }, MoreExecutors.sameThreadExecutor());
- }
- return executorService;
- }
-
- @Override protected Scheduler scheduler() {
- return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS);
- }};
-
- try {
- service.startAndWait();
- fail("Expected service to fail during startup");
- } catch (UncheckedExecutionException e) {
- // expected
- }
- failureLatch.await();
- assertTrue(service.executor().isShutdown());
- assertTrue(service.executor().awaitTermination(100, TimeUnit.MILLISECONDS));
- }
-
public void testSchedulerOnlyCalledOnce() throws Exception {
TestService service = new TestService();
service.startAndWait();
@@ -405,7 +328,7 @@ public class AbstractScheduledServiceTest extends TestCase {
public void testBig() throws Exception {
TestAbstractScheduledCustomService service = new TestAbstractScheduledCustomService() {
@Override protected Scheduler scheduler() {
- return new AbstractScheduledService.CustomScheduler() {
+ return new AbstractScheduledService.CustomScheduler(){
@Override
protected Schedule getNextSchedule() throws Exception {
// Explicitly yield to increase the probability of a pathological scheduling.
@@ -446,9 +369,9 @@ public class AbstractScheduledServiceTest extends TestCase {
return Executors.newScheduledThreadPool(10);
}
- @Override protected void startUp() throws Exception {}
+ @Override protected void startUp() throws Exception { }
- @Override protected void shutDown() throws Exception {}
+ @Override protected void shutDown() throws Exception { }
@Override protected Scheduler scheduler() {
return new CustomScheduler() {
@@ -492,6 +415,10 @@ public class AbstractScheduledServiceTest extends TestCase {
return Executors.newScheduledThreadPool(10);
}
+ @Override protected void startUp() throws Exception { }
+
+ @Override protected void shutDown() throws Exception { }
+
@Override protected Scheduler scheduler() {
return new CustomScheduler() {
@Override
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
index 99e2ffb..c4d4f8e 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
@@ -19,21 +19,12 @@ package com.google.common.util.concurrent;
import static java.lang.Thread.currentThread;
import static java.util.concurrent.TimeUnit.SECONDS;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Service.Listener;
-import com.google.common.util.concurrent.Service.State;
-
+import junit.framework.Assert;
import junit.framework.TestCase;
import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
/**
* Unit test for {@link AbstractService}.
@@ -45,59 +36,43 @@ public class AbstractServiceTest extends TestCase {
private Thread executionThread;
private Throwable thrownByExecutionThread;
- public void testNoOpServiceStartStop() throws Exception {
+ public void testNoOpServiceStartStop() {
NoOpService service = new NoOpService();
- RecordingListener listener = RecordingListener.record(service);
-
- assertEquals(State.NEW, service.state());
+ Assert.assertEquals(Service.State.NEW, service.state());
assertFalse(service.isRunning());
assertFalse(service.running);
service.start();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
assertTrue(service.isRunning());
assertTrue(service.running);
service.stop();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
assertFalse(service.isRunning());
assertFalse(service.running);
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.STOPPING,
- State.TERMINATED),
- listener.getStateHistory());
}
public void testNoOpServiceStartAndWaitStopAndWait() throws Exception {
NoOpService service = new NoOpService();
service.start().get();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.stop().get();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopIdempotence() throws Exception {
NoOpService service = new NoOpService();
- RecordingListener listener = RecordingListener.record(service);
+
service.start();
service.start();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.stop();
service.stop();
- assertEquals(State.TERMINATED, service.state());
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.STOPPING,
- State.TERMINATED),
- listener.getStateHistory());
+ assertEquals(Service.State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopIdempotenceAfterWait() throws Exception {
@@ -105,11 +80,11 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.stop().get();
service.stop();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopIdempotenceDoubleWait() throws Exception {
@@ -117,11 +92,11 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start().get();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.stop().get();
service.stop().get();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopAndWaitUninterruptible()
@@ -131,10 +106,10 @@ public class AbstractServiceTest extends TestCase {
currentThread().interrupt();
try {
service.startAndWait();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.stopAndWait();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
assertTrue(currentThread().isInterrupted());
} finally {
@@ -158,125 +133,49 @@ public class AbstractServiceTest extends TestCase {
}
}
- public void testManualServiceStartStop() throws Exception {
+ public void testManualServiceStartStop() {
ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
service.start();
- assertEquals(State.STARTING, service.state());
+ assertEquals(Service.State.STARTING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStartCalled);
service.notifyStarted(); // usually this would be invoked by another thread
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
assertTrue(service.isRunning());
service.stop();
- assertEquals(State.STOPPING, service.state());
+ assertEquals(Service.State.STOPPING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStopCalled);
service.notifyStopped(); // usually this would be invoked by another thread
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
assertFalse(service.isRunning());
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.STOPPING,
- State.TERMINATED),
- listener.getStateHistory());
-
}
- public void testManualServiceNotifyStoppedWhileRunning() throws Exception {
+ public void testManualServiceStopWhileStarting() {
ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
service.start();
- service.notifyStarted();
- service.notifyStopped();
- assertEquals(State.TERMINATED, service.state());
- assertFalse(service.isRunning());
- assertFalse(service.doStopCalled);
-
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.TERMINATED),
- listener.getStateHistory());
- }
-
- public void testManualServiceStopWhileStarting() throws Exception {
- ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
-
- service.start();
- assertEquals(State.STARTING, service.state());
+ assertEquals(Service.State.STARTING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStartCalled);
service.stop();
- assertEquals(State.STOPPING, service.state());
+ assertEquals(Service.State.STOPPING, service.state());
assertFalse(service.isRunning());
assertFalse(service.doStopCalled);
service.notifyStarted();
- assertEquals(State.STOPPING, service.state());
+ assertEquals(Service.State.STOPPING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStopCalled);
service.notifyStopped();
- assertEquals(State.TERMINATED, service.state());
- assertFalse(service.isRunning());
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.STOPPING,
- State.TERMINATED),
- listener.getStateHistory());
- }
-
- public void testManualServiceStopWhileNew() throws Exception {
- ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
-
- service.stop();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
assertFalse(service.isRunning());
- assertFalse(service.doStartCalled);
- assertFalse(service.doStopCalled);
- assertEquals(ImmutableList.of(State.TERMINATED), listener.getStateHistory());
- }
-
- public void testManualServiceFailWhileStarting() throws Exception {
- ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
- service.start();
- service.notifyFailed(EXCEPTION);
- assertEquals(ImmutableList.of(State.STARTING, State.FAILED), listener.getStateHistory());
- }
-
- public void testManualServiceFailWhileRunning() throws Exception {
- ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
- service.start();
- service.notifyStarted();
- service.notifyFailed(EXCEPTION);
- assertEquals(ImmutableList.of(State.STARTING, State.RUNNING, State.FAILED),
- listener.getStateHistory());
- }
-
- public void testManualServiceFailWhileStopping() throws Exception {
- ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener listener = RecordingListener.record(service);
- service.start();
- service.notifyStarted();
- service.stop();
- service.notifyFailed(EXCEPTION);
- assertEquals(ImmutableList.of(State.STARTING, State.RUNNING, State.STOPPING, State.FAILED),
- listener.getStateHistory());
}
public void testManualServiceUnrequestedStop() {
@@ -285,12 +184,12 @@ public class AbstractServiceTest extends TestCase {
service.start();
service.notifyStarted();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
assertTrue(service.isRunning());
assertFalse(service.doStopCalled);
service.notifyStopped();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
assertFalse(service.isRunning());
assertFalse(service.doStopCalled);
}
@@ -316,23 +215,16 @@ public class AbstractServiceTest extends TestCase {
public void testThreadedServiceStartAndWaitStopAndWait() throws Throwable {
ThreadedService service = new ThreadedService();
- RecordingListener listener = RecordingListener.record(service);
+
service.start().get();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.awaitRunChecks();
- service.stopAndWait();
- assertEquals(State.TERMINATED, service.state());
+ service.stop().get();
+ assertEquals(Service.State.TERMINATED, service.state());
throwIfSet(thrownByExecutionThread);
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.STOPPING,
- State.TERMINATED),
- listener.getStateHistory());
}
public void testThreadedServiceStartStopIdempotence() throws Throwable {
@@ -340,13 +232,13 @@ public class AbstractServiceTest extends TestCase {
service.start();
service.start().get();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.awaitRunChecks();
service.stop();
service.stop().get();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
throwIfSet(thrownByExecutionThread);
}
@@ -357,13 +249,13 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.awaitRunChecks();
service.stop().get();
service.stop();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
executionThread.join();
@@ -376,31 +268,17 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start().get();
- assertEquals(State.RUNNING, service.state());
+ assertEquals(Service.State.RUNNING, service.state());
service.awaitRunChecks();
service.stop().get();
service.stop().get();
- assertEquals(State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, service.state());
throwIfSet(thrownByExecutionThread);
}
- public void testManualServiceFailureIdempotence() {
- ManualSwitchedService service = new ManualSwitchedService();
- RecordingListener.record(service);
- service.start();
- service.notifyFailed(new Exception("1"));
- service.notifyFailed(new Exception("2"));
- try {
- service.startAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- assertEquals("1", e.getCause().getMessage());
- }
- }
-
private class ThreadedService extends AbstractService {
final CountDownLatch hasConfirmedIsRunning = new CountDownLatch(1);
@@ -461,249 +339,53 @@ public class AbstractServiceTest extends TestCase {
public void testStopUnstartedService() throws Exception {
NoOpService service = new NoOpService();
- RecordingListener listener = RecordingListener.record(service);
-
- Future<State> stopResult = service.stop();
- assertEquals(State.TERMINATED, service.state());
- assertEquals(State.TERMINATED, stopResult.get());
+ Future<Service.State> stopResult = service.stop();
+ assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, stopResult.get());
- Future<State> startResult = service.start();
- assertEquals(State.TERMINATED, service.state());
- assertEquals(State.TERMINATED, startResult.get());
- assertEquals(State.TERMINATED, Iterables.getOnlyElement(listener.getStateHistory()));
- }
-
- public void testFailingServiceStartAndWait() throws Exception {
- StartFailingService service = new StartFailingService();
- RecordingListener listener = RecordingListener.record(service);
-
- try {
- service.startAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, e.getCause());
- }
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.FAILED),
- listener.getStateHistory());
- }
-
- public void testFailingServiceStopAndWait_stopFailing() throws Exception {
- StopFailingService service = new StopFailingService();
- RecordingListener listener = RecordingListener.record(service);
-
- service.startAndWait();
- try {
- service.stopAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, e.getCause());
- }
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.STOPPING,
- State.FAILED),
- listener.getStateHistory());
- }
-
- public void testFailingServiceStopAndWait_runFailinging() throws Exception {
- RunFailingService service = new RunFailingService();
- RecordingListener listener = RecordingListener.record(service);
-
- service.startAndWait();
- try {
- service.stopAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, e.getCause().getCause());
- }
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.FAILED),
- listener.getStateHistory());
+ Future<Service.State> startResult = service.start();
+ assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(Service.State.TERMINATED, startResult.get());
}
public void testThrowingServiceStartAndWait() throws Exception {
StartThrowingService service = new StartThrowingService();
- RecordingListener listener = RecordingListener.record(service);
try {
service.startAndWait();
fail();
} catch (UncheckedExecutionException e) {
- assertEquals(service.exception, e.getCause());
+ assertEquals(EXCEPTION, e.getCause());
}
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.FAILED),
- listener.getStateHistory());
}
public void testThrowingServiceStopAndWait_stopThrowing() throws Exception {
StopThrowingService service = new StopThrowingService();
- RecordingListener listener = RecordingListener.record(service);
service.startAndWait();
try {
service.stopAndWait();
fail();
} catch (UncheckedExecutionException e) {
- assertEquals(service.exception, e.getCause());
+ assertEquals(EXCEPTION, e.getCause());
}
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.STOPPING,
- State.FAILED),
- listener.getStateHistory());
}
public void testThrowingServiceStopAndWait_runThrowing() throws Exception {
RunThrowingService service = new RunThrowingService();
- RecordingListener listener = RecordingListener.record(service);
-
- service.startAndWait();
- try {
- service.stopAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- assertEquals(service.exception, e.getCause().getCause());
- }
- assertEquals(
- ImmutableList.of(
- State.STARTING,
- State.RUNNING,
- State.FAILED),
- listener.getStateHistory());
- }
- public void testFailureCause_throwsIfNotFailed() {
- StopFailingService service = new StopFailingService();
- try {
- service.failureCause();
- fail();
- } catch (IllegalStateException e) {
- // expected
- }
service.startAndWait();
try {
- service.failureCause();
- fail();
- } catch (IllegalStateException e) {
- // expected
- }
- try {
service.stopAndWait();
fail();
} catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, service.failureCause());
- assertEquals(EXCEPTION, e.getCause());
- }
- }
-
- public void testAddListenerAfterFailureDoesntCauseDeadlock() throws InterruptedException {
- final StartFailingService service = new StartFailingService();
- service.start();
- assertEquals(State.FAILED, service.state());
- service.addListener(new RecordingListener(service), MoreExecutors.sameThreadExecutor());
- Thread thread = new Thread() {
- @Override public void run() {
- // Internally start() grabs a lock, this could be any such method on AbstractService.
- service.start();
- }
- };
- thread.start();
- thread.join(100);
- assertFalse(thread + " is deadlocked", thread.isAlive());
- }
-
- public void testListenerDoesntDeadlockOnStartAndWaitFromRunning() throws Exception {
- final NoOpThreadedService service = new NoOpThreadedService();
- service.addListener(new Listener() {
- @Override public void starting() { }
- @Override public void running() {
- service.startAndWait();
- }
- @Override public void stopping(State from) { }
- @Override public void terminated(State from) { }
- @Override public void failed(State from, Throwable failure) { }
- }, MoreExecutors.sameThreadExecutor());
- service.start().get(10, TimeUnit.MILLISECONDS);
- service.stop();
- }
-
- public void testListenerDoesntDeadlockOnStopAndWaitFromTerminated() throws Exception {
- final NoOpThreadedService service = new NoOpThreadedService();
- service.addListener(new Listener() {
- @Override public void starting() { }
- @Override public void running() { }
- @Override public void stopping(State from) { }
- @Override public void terminated(State from) {
- service.stopAndWait();
- }
- @Override public void failed(State from, Throwable failure) { }
- }, MoreExecutors.sameThreadExecutor());
- service.startAndWait();
-
- Thread thread = new Thread() {
- @Override public void run() {
- service.stopAndWait();
- }
- };
- thread.start();
- thread.join(100);
- assertFalse(thread + " is deadlocked", thread.isAlive());
- }
-
- private static class NoOpThreadedService extends AbstractExecutionThreadService {
- @Override protected void run() throws Exception {}
- }
-
- private static class StartFailingService extends AbstractService {
- @Override protected void doStart() {
- notifyFailed(EXCEPTION);
- }
-
- @Override protected void doStop() {
- fail();
- }
- }
-
- private static class RunFailingService extends AbstractService {
- @Override protected void doStart() {
- notifyStarted();
- notifyFailed(EXCEPTION);
- }
-
- @Override protected void doStop() {
- fail();
- }
- }
-
- private static class StopFailingService extends AbstractService {
- @Override protected void doStart() {
- notifyStarted();
- }
-
- @Override protected void doStop() {
- notifyFailed(EXCEPTION);
+ assertEquals(EXCEPTION, e.getCause().getCause());
}
}
private static class StartThrowingService extends AbstractService {
-
- final RuntimeException exception = new RuntimeException("deliberate");
-
@Override protected void doStart() {
- throw exception;
+ notifyFailed(EXCEPTION);
}
@Override protected void doStop() {
@@ -712,12 +394,9 @@ public class AbstractServiceTest extends TestCase {
}
private static class RunThrowingService extends AbstractService {
-
- final RuntimeException exception = new RuntimeException("deliberate");
-
@Override protected void doStart() {
notifyStarted();
- throw exception;
+ notifyFailed(EXCEPTION);
}
@Override protected void doStop() {
@@ -726,143 +405,14 @@ public class AbstractServiceTest extends TestCase {
}
private static class StopThrowingService extends AbstractService {
-
- final RuntimeException exception = new RuntimeException("deliberate");
-
@Override protected void doStart() {
notifyStarted();
}
@Override protected void doStop() {
- throw exception;
- }
- }
-
- private static class RecordingListener implements Listener {
- static RecordingListener record(Service service) {
- RecordingListener listener = new RecordingListener(service);
- service.addListener(listener, MoreExecutors.sameThreadExecutor());
- return listener;
- }
-
- final Service service;
-
- RecordingListener(Service service) {
- this.service = service;
- }
-
- @GuardedBy("this")
- final List<State> stateHistory = Lists.newArrayList();
- final CountDownLatch completionLatch = new CountDownLatch(1);
-
- ImmutableList<State> getStateHistory() throws Exception {
- completionLatch.await();
- synchronized (this) {
- return ImmutableList.copyOf(stateHistory);
- }
- }
-
- @Override public synchronized void starting() {
- assertTrue(stateHistory.isEmpty());
- assertNotSame(State.NEW, service.state());
- stateHistory.add(State.STARTING);
- }
-
- @Override public synchronized void running() {
- assertEquals(State.STARTING, Iterables.getOnlyElement(stateHistory));
- stateHistory.add(State.RUNNING);
- assertTrue(service.start().isDone());
- assertEquals(State.RUNNING, service.startAndWait());
- assertNotSame(State.STARTING, service.state());
- }
-
- @Override public synchronized void stopping(State from) {
- assertEquals(from, Iterables.getLast(stateHistory));
- stateHistory.add(State.STOPPING);
- if (from == State.STARTING) {
- assertTrue(service.start().isDone());
- assertEquals(State.STOPPING, service.startAndWait());
- }
- assertNotSame(from, service.state());
- }
-
- @Override public synchronized void terminated(State from) {
- assertEquals(from, Iterables.getLast(stateHistory, State.NEW));
- stateHistory.add(State.TERMINATED);
- assertEquals(State.TERMINATED, service.state());
- assertTrue(service.start().isDone());
- if (from == State.NEW) {
- assertEquals(State.TERMINATED, service.startAndWait());
- }
- assertTrue(service.stop().isDone());
- assertEquals(State.TERMINATED, service.stopAndWait());
- completionLatch.countDown();
- }
-
- @Override public synchronized void failed(State from, Throwable failure) {
- assertEquals(from, Iterables.getLast(stateHistory));
- stateHistory.add(State.FAILED);
- assertEquals(State.FAILED, service.state());
- if (from == State.STARTING) {
- try {
- service.startAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- assertEquals(failure, e.getCause());
- }
- }
- try {
- service.stopAndWait();
- fail();
- } catch (UncheckedExecutionException e) {
- if (from == State.STOPPING) {
- assertEquals(failure, e.getCause());
- } else {
- assertEquals(failure, e.getCause().getCause());
- }
- }
- completionLatch.countDown();
+ notifyFailed(EXCEPTION);
}
}
- public void testNotifyStartedWhenNotStarting() {
- AbstractService service = new DefaultService();
- try {
- service.notifyStarted();
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- public void testNotifyStoppedWhenNotRunning() {
- AbstractService service = new DefaultService();
- try {
- service.notifyStopped();
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- public void testNotifyFailedWhenNotStarted() {
- AbstractService service = new DefaultService();
- try {
- service.notifyFailed(new Exception());
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- public void testNotifyFailedWhenTerminated() {
- NoOpService service = new NoOpService();
- service.startAndWait();
- service.stopAndWait();
- try {
- service.notifyFailed(new Exception());
- fail();
- } catch (IllegalStateException expected) {}
- }
-
- private static class DefaultService extends AbstractService {
- @Override protected void doStart() {}
- @Override protected void doStop() {}
- }
-
private static final Exception EXCEPTION = new Exception();
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java
index 7ad3a4a..f3aa63f 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java
@@ -14,7 +14,6 @@
package com.google.common.util.concurrent;
import junit.framework.*;
-
import java.util.Arrays;
/**
diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java
index 8746e33..8bffaa1 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java
@@ -1,23 +1,7 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.util.concurrent;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.testing.NullPointerTester;
@@ -35,17 +19,15 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* Tests for {@link AtomicLongMap}.
*
- * @author mike nonemacher
+ * @author schmoe@google.com (mike nonemacher)
*/
-@GwtCompatible(emulated = true)
public class AtomicLongMapTest extends TestCase {
private static final int ITERATIONS = 100;
private static final int MAX_ADDEND = 100;
private Random random = new Random(301);
- @GwtIncompatible("NullPointerTester")
- public void testNulls() {
+ public void testNulls() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicConstructors(AtomicLongMap.class);
tester.testAllPublicStaticMethods(AtomicLongMap.class);
@@ -554,7 +536,6 @@ public class AtomicLongMapTest extends TestCase {
assertFalse(map.replace("a", 1L, 0L));
}
- @GwtIncompatible("threads")
public void testModify_basher() throws InterruptedException {
int nTasks = 3000;
int nThreads = 100;
diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java
index 5a19625..66f2b13 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java
@@ -82,7 +82,7 @@ public class AtomicsTest extends TestCase {
}
}
- public void testNullPointers() {
+ public void testNullPointers() throws Exception {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicConstructors(Atomics.class); // there aren't any
tester.testAllPublicStaticMethods(Atomics.class);
diff --git a/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java b/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java
deleted file mode 100644
index b39601f..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.base.Joiner;
-import com.google.common.util.concurrent.CycleDetectingLockFactory.OrderedLockGraphNodesCreator;
-import com.google.common.util.concurrent.CycleDetectingLockFactory.Policies;
-import com.google.common.util.concurrent.CycleDetectingLockFactory.Policy;
-import com.google.common.util.concurrent.CycleDetectingLockFactory.PotentialDeadlockException;
-
-import junit.framework.TestCase;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Unittests for {@link CycleDetectingLockFactory}.
- *
- * @author Darick Tong
- */
-public class CycleDetectingLockFactoryTest extends TestCase {
-
- private ReentrantLock lockA;
- private ReentrantLock lockB;
- private ReentrantLock lockC;
- private ReentrantReadWriteLock.ReadLock readLockA;
- private ReentrantReadWriteLock.ReadLock readLockB;
- private ReentrantReadWriteLock.ReadLock readLockC;
- private ReentrantReadWriteLock.WriteLock writeLockA;
- private ReentrantReadWriteLock.WriteLock writeLockB;
- private ReentrantReadWriteLock.WriteLock writeLockC;
- private ReentrantLock lock1;
- private ReentrantLock lock2;
- private ReentrantLock lock3;
- private ReentrantLock lock01;
- private ReentrantLock lock02;
- private ReentrantLock lock03;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- CycleDetectingLockFactory factory =
- CycleDetectingLockFactory.newInstance(Policies.THROW);
- lockA = factory.newReentrantLock("LockA");
- lockB = factory.newReentrantLock("LockB");
- lockC = factory.newReentrantLock("LockC");
- ReentrantReadWriteLock readWriteLockA =
- factory.newReentrantReadWriteLock("ReadWriteA");
- ReentrantReadWriteLock readWriteLockB =
- factory.newReentrantReadWriteLock("ReadWriteB");
- ReentrantReadWriteLock readWriteLockC =
- factory.newReentrantReadWriteLock("ReadWriteC");
- readLockA = readWriteLockA.readLock();
- readLockB = readWriteLockB.readLock();
- readLockC = readWriteLockC.readLock();
- writeLockA = readWriteLockA.writeLock();
- writeLockB = readWriteLockB.writeLock();
- writeLockC = readWriteLockC.writeLock();
-
- CycleDetectingLockFactory.WithExplicitOrdering<MyOrder> factory2 =
- newInstanceWithExplicitOrdering(MyOrder.class, Policies.THROW);
- lock1 = factory2.newReentrantLock(MyOrder.FIRST);
- lock2 = factory2.newReentrantLock(MyOrder.SECOND);
- lock3 = factory2.newReentrantLock(MyOrder.THIRD);
-
- CycleDetectingLockFactory.WithExplicitOrdering<OtherOrder> factory3 =
- newInstanceWithExplicitOrdering(OtherOrder.class, Policies.THROW);
- lock01 = factory3.newReentrantLock(OtherOrder.FIRST);
- lock02 = factory3.newReentrantLock(OtherOrder.SECOND);
- lock03 = factory3.newReentrantLock(OtherOrder.THIRD);
- }
-
- // In the unittest, create each ordered factory with its own set of lock
- // graph nodes (as opposed to using the static per-Enum map) to avoid
- // conflicts across different test runs.
- private <E extends Enum<E>> CycleDetectingLockFactory.WithExplicitOrdering<E>
- newInstanceWithExplicitOrdering(Class<E> enumClass, Policy policy) {
- OrderedLockGraphNodesCreator nodeCreator =
- new OrderedLockGraphNodesCreator();
- return new CycleDetectingLockFactory.WithExplicitOrdering<E>(
- policy, nodeCreator.createNodesFor(enumClass));
- }
-
- public void testDeadlock_twoLocks() {
- // Establish an acquisition order of lockA -> lockB.
- lockA.lock();
- lockB.lock();
- lockA.unlock();
- lockB.unlock();
-
- // The opposite order should fail (Policies.THROW).
- PotentialDeadlockException firstException = null;
- lockB.lock();
- try {
- lockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "LockB -> LockA", "LockA -> LockB");
- firstException = expected;
- }
-
- // Second time should also fail, with a cached causal chain.
- try {
- lockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "LockB -> LockA", "LockA -> LockB");
- // The causal chain should be cached.
- assertSame(firstException.getCause(), expected.getCause());
- }
-
- // lockA should work after lockB is released.
- lockB.unlock();
- lockA.lock();
- }
-
- // Tests transitive deadlock detection.
- public void testDeadlock_threeLocks() {
- // Establish an ordering from lockA -> lockB.
- lockA.lock();
- lockB.lock();
- lockB.unlock();
- lockA.unlock();
-
- // Establish an ordering from lockB -> lockC.
- lockB.lock();
- lockC.lock();
- lockB.unlock();
-
- // lockC -> lockA should fail.
- try {
- lockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected, "LockC -> LockA", "LockB -> LockC", "LockA -> LockB");
- }
- }
-
- public void testReentrancy_noDeadlock() {
- lockA.lock();
- lockB.lock();
- lockA.lock(); // Should not assert on lockB -> reentrant(lockA)
- }
-
- public void testExplicitOrdering_noViolations() {
- lock1.lock();
- lock3.lock();
- lock3.unlock();
- lock2.lock();
- lock3.lock();
- }
-
- public void testExplicitOrdering_violations() {
- lock3.lock();
- try {
- lock2.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "MyOrder.THIRD -> MyOrder.SECOND");
- }
-
- try {
- lock1.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "MyOrder.THIRD -> MyOrder.FIRST");
- }
-
- lock3.unlock();
- lock2.lock();
-
- try {
- lock1.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "MyOrder.SECOND -> MyOrder.FIRST");
- }
- }
-
- public void testDifferentOrderings_noViolations() {
- lock3.lock(); // MyOrder, ordinal() == 3
- lock01.lock(); // OtherOrder, ordinal() == 1
- }
-
- public void testExplicitOrderings_generalCycleDetection() {
- lock3.lock(); // MyOrder, ordinal() == 3
- lock01.lock(); // OtherOrder, ordinal() == 1
-
- lock3.unlock();
- try {
- lock3.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected,
- "OtherOrder.FIRST -> MyOrder.THIRD",
- "MyOrder.THIRD -> OtherOrder.FIRST");
- }
-
- lockA.lock();
- lock01.unlock();
- lockB.lock();
- lockA.unlock();
-
- try {
- lock01.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected,
- "LockB -> OtherOrder.FIRST",
- "LockA -> LockB",
- "OtherOrder.FIRST -> LockA");
- }
- }
-
- public void testExplicitOrdering_cycleWithUnorderedLock() {
- Lock myLock = CycleDetectingLockFactory.newInstance(Policies.THROW)
- .newReentrantLock("MyLock");
- lock03.lock();
- myLock.lock();
- lock03.unlock();
-
- try {
- lock01.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected,
- "MyLock -> OtherOrder.FIRST",
- "OtherOrder.THIRD -> MyLock",
- "OtherOrder.FIRST -> OtherOrder.THIRD");
- }
- }
-
- public void testExplicitOrdering_reentrantAcquisition() {
- CycleDetectingLockFactory.WithExplicitOrdering<OtherOrder> factory =
- newInstanceWithExplicitOrdering(OtherOrder.class, Policies.THROW);
- Lock lockA = factory.newReentrantReadWriteLock(OtherOrder.FIRST).readLock();
- Lock lockB = factory.newReentrantLock(OtherOrder.SECOND);
-
- lockA.lock();
- lockA.lock();
- lockB.lock();
- lockB.lock();
- lockA.unlock();
- lockA.unlock();
- lockB.unlock();
- lockB.unlock();
- }
-
- public void testExplicitOrdering_acquiringMultipleLocksWithSameRank() {
- CycleDetectingLockFactory.WithExplicitOrdering<OtherOrder> factory =
- newInstanceWithExplicitOrdering(OtherOrder.class, Policies.THROW);
- Lock lockA = factory.newReentrantLock(OtherOrder.FIRST);
- Lock lockB = factory.newReentrantReadWriteLock(OtherOrder.FIRST).readLock();
-
- lockA.lock();
- try {
- lockB.lock();
- fail("Expected IllegalStateException");
- } catch (IllegalStateException expected) {
- }
-
- lockA.unlock();
- lockB.lock();
- }
-
- public void testReadLock_deadlock() {
- readLockA.lock(); // Establish an ordering from readLockA -> lockB.
- lockB.lock();
- lockB.unlock();
- readLockA.unlock();
-
- lockB.lock();
- try {
- readLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "LockB -> ReadWriteA", "ReadWriteA -> LockB");
- }
- }
-
- public void testReadLock_transitive() {
- readLockA.lock(); // Establish an ordering from readLockA -> lockB.
- lockB.lock();
- lockB.unlock();
- readLockA.unlock();
-
- // Establish an ordering from lockB -> readLockC.
- lockB.lock();
- readLockC.lock();
- lockB.unlock();
- readLockC.unlock();
-
- // readLockC -> readLockA
- readLockC.lock();
- try {
- readLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected,
- "ReadWriteC -> ReadWriteA",
- "LockB -> ReadWriteC",
- "ReadWriteA -> LockB");
- }
- }
-
- public void testWriteLock_threeLockDeadLock() {
- // Establish an ordering from writeLockA -> writeLockB.
- writeLockA.lock();
- writeLockB.lock();
- writeLockB.unlock();
- writeLockA.unlock();
-
- // Establish an ordering from writeLockB -> writeLockC.
- writeLockB.lock();
- writeLockC.lock();
- writeLockB.unlock();
-
- // writeLockC -> writeLockA should fail.
- try {
- writeLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected,
- "ReadWriteC -> ReadWriteA",
- "ReadWriteB -> ReadWriteC",
- "ReadWriteA -> ReadWriteB");
- }
- }
-
- public void testWriteToReadLockDowngrading() {
- writeLockA.lock(); // writeLockA downgrades to readLockA
- readLockA.lock();
- writeLockA.unlock();
-
- lockB.lock(); // readLockA -> lockB
- readLockA.unlock();
-
- // lockB -> writeLockA should fail
- try {
- writeLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected, "LockB -> ReadWriteA", "ReadWriteA -> LockB");
- }
- }
-
- public void testReadWriteLockDeadlock() {
- writeLockA.lock(); // Establish an ordering from writeLockA -> lockB
- lockB.lock();
- writeLockA.unlock();
- lockB.unlock();
-
- // lockB -> readLockA should fail.
- lockB.lock();
- try {
- readLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected, "LockB -> ReadWriteA", "ReadWriteA -> LockB");
- }
- }
-
- public void testReadWriteLockDeadlock_transitive() {
- readLockA.lock(); // Establish an ordering from readLockA -> lockB
- lockB.lock();
- readLockA.unlock();
- lockB.unlock();
-
- // Establish an ordering from lockB -> lockC
- lockB.lock();
- lockC.lock();
- lockB.unlock();
- lockC.unlock();
-
- // lockC -> writeLockA should fail.
- lockC.lock();
- try {
- writeLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected,
- "LockC -> ReadWriteA",
- "LockB -> LockC",
- "ReadWriteA -> LockB");
- }
- }
-
- public void testReadWriteLockDeadlock_treatedEquivalently() {
- readLockA.lock(); // readLockA -> writeLockB
- writeLockB.lock();
- readLockA.unlock();
- writeLockB.unlock();
-
- // readLockB -> writeLockA should fail.
- readLockB.lock();
- try {
- writeLockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(
- expected, "ReadWriteB -> ReadWriteA", "ReadWriteA -> ReadWriteB");
- }
- }
-
- public void testDifferentLockFactories() {
- CycleDetectingLockFactory otherFactory =
- CycleDetectingLockFactory.newInstance(Policies.WARN);
- ReentrantLock lockD = otherFactory.newReentrantLock("LockD");
-
- // lockA -> lockD
- lockA.lock();
- lockD.lock();
- lockA.unlock();
- lockD.unlock();
-
- // lockD -> lockA should fail even though lockD is from a different factory.
- lockD.lock();
- try {
- lockA.lock();
- fail("Expected PotentialDeadlockException");
- } catch (PotentialDeadlockException expected) {
- checkMessage(expected, "LockD -> LockA", "LockA -> LockD");
- }
- }
-
- public void testDifferentLockFactories_policyExecution() {
- CycleDetectingLockFactory otherFactory =
- CycleDetectingLockFactory.newInstance(Policies.WARN);
- ReentrantLock lockD = otherFactory.newReentrantLock("LockD");
-
- // lockD -> lockA
- lockD.lock();
- lockA.lock();
- lockA.unlock();
- lockD.unlock();
-
- // lockA -> lockD should warn but otherwise succeed because lockD was
- // created by a factory with the WARN policy.
- lockA.lock();
- lockD.lock();
- }
-
- public void testReentrantLock_tryLock() throws Exception {
- LockingThread thread = new LockingThread(lockA);
- thread.start();
-
- thread.waitUntilHoldingLock();
- assertFalse(lockA.tryLock());
-
- thread.releaseLockAndFinish();
- assertTrue(lockA.tryLock());
- }
-
- public void testReentrantWriteLock_tryLock() throws Exception {
- LockingThread thread = new LockingThread(writeLockA);
- thread.start();
-
- thread.waitUntilHoldingLock();
- assertFalse(writeLockA.tryLock());
- assertFalse(readLockA.tryLock());
-
- thread.releaseLockAndFinish();
- assertTrue(writeLockA.tryLock());
- assertTrue(readLockA.tryLock());
- }
-
- public void testReentrantReadLock_tryLock() throws Exception {
- LockingThread thread = new LockingThread(readLockA);
- thread.start();
-
- thread.waitUntilHoldingLock();
- assertFalse(writeLockA.tryLock());
- assertTrue(readLockA.tryLock());
- readLockA.unlock();
-
- thread.releaseLockAndFinish();
- assertTrue(writeLockA.tryLock());
- assertTrue(readLockA.tryLock());
- }
-
- private static class LockingThread extends Thread {
- final CountDownLatch locked = new CountDownLatch(1);
- final CountDownLatch finishLatch = new CountDownLatch(1);
- final Lock lock;
-
- LockingThread(Lock lock) {
- this.lock = lock;
- }
-
- @Override
- public void run() {
- lock.lock();
- try {
- locked.countDown();
- finishLatch.await(1, TimeUnit.MINUTES);
- } catch (InterruptedException e) {
- fail(e.toString());
- } finally {
- lock.unlock();
- }
- }
-
- void waitUntilHoldingLock() throws InterruptedException {
- locked.await(1, TimeUnit.MINUTES);
- }
-
- void releaseLockAndFinish() throws InterruptedException {
- finishLatch.countDown();
- this.join(10000);
- assertFalse(this.isAlive());
- }
- }
-
- public void testReentrantReadWriteLock_implDoesNotExposeShadowedLocks() {
- assertEquals(
- "Unexpected number of public methods in ReentrantReadWriteLock. " +
- "The correctness of CycleDetectingReentrantReadWriteLock depends on " +
- "the fact that the shadowed ReadLock and WriteLock are never used or " +
- "exposed by the superclass implementation. If the implementation has " +
- "changed, the code must be re-inspected to ensure that the " +
- "assumption is still valid.",
- 24, ReentrantReadWriteLock.class.getMethods().length);
- }
-
- private enum MyOrder {
- FIRST, SECOND, THIRD;
- }
-
- private enum OtherOrder {
- FIRST, SECOND, THIRD;
- }
-
- // Given a sequence of lock acquisition descriptions
- // (e.g. "LockA -> LockB", "LockB -> LockC", ...)
- // Checks that the exception.getMessage() matches a regex of the form:
- // "LockA -> LockB \b.*\b LockB -> LockC \b.*\b LockC -> LockA"
- private void checkMessage(
- IllegalStateException exception, String... expectedLockCycle) {
- String regex = Joiner.on("\\b.*\\b").join(expectedLockCycle);
- assertContainsRegex(regex, exception.getMessage());
- }
-
- // TODO(cpovirk): consider adding support for regex to Truth
- private static void assertContainsRegex(String expectedRegex, String actual) {
- Pattern pattern = Pattern.compile(expectedRegex);
- Matcher matcher = pattern.matcher(actual);
- if (!matcher.find()) {
- String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
- fail("expected to contain regex:<" + expectedRegex + "> but was:"
- + actualDesc);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java b/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java
index 92d9768..a4a2a8d 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java
@@ -27,7 +27,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* Unit tests for {@link ExecutionList}.
@@ -37,10 +36,10 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class ExecutionListTest extends TestCase {
- private final ExecutionList list = new ExecutionList();
+ protected ExecutionList list = new ExecutionList();
+ protected Executor exec = Executors.newCachedThreadPool();
public void testRunOnPopulatedList() throws Exception {
- Executor exec = Executors.newCachedThreadPool();
CountDownLatch countDownLatch = new CountDownLatch(3);
list.add(new MockRunnable(countDownLatch), exec);
list.add(new MockRunnable(countDownLatch), exec);
@@ -53,56 +52,13 @@ public class ExecutionListTest extends TestCase {
assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS));
}
- public void testExecute_idempotent() {
- final AtomicInteger runCalled = new AtomicInteger();
- list.add(new Runnable() {
- @Override public void run() {
- runCalled.getAndIncrement();
- }
- }, MoreExecutors.sameThreadExecutor());
- list.execute();
- assertEquals(1, runCalled.get());
- list.execute();
- assertEquals(1, runCalled.get());
- }
-
- public void testExecute_idempotentConcurrently() throws InterruptedException {
- final CountDownLatch okayToRun = new CountDownLatch(1);
- final AtomicInteger runCalled = new AtomicInteger();
- list.add(new Runnable() {
- @Override public void run() {
- try {
- okayToRun.await();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(e);
- }
- runCalled.getAndIncrement();
- }
- }, MoreExecutors.sameThreadExecutor());
- Runnable execute = new Runnable() {
- @Override public void run() {
- list.execute();
- }
- };
- Thread thread1 = new Thread(execute);
- Thread thread2 = new Thread(execute);
- thread1.start();
- thread2.start();
- assertEquals(0, runCalled.get());
- okayToRun.countDown();
- thread1.join();
- thread2.join();
- assertEquals(1, runCalled.get());
- }
-
public void testAddAfterRun() throws Exception {
// Run the previous test
testRunOnPopulatedList();
// If it passed, then verify an Add will be executed without calling run
CountDownLatch countDownLatch = new CountDownLatch(1);
- list.add(new MockRunnable(countDownLatch), Executors.newCachedThreadPool());
+ list.add(new MockRunnable(countDownLatch), exec);
assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS));
}
@@ -113,19 +69,24 @@ public class ExecutionListTest extends TestCase {
this.countDownLatch = countDownLatch;
}
- @Override public void run() {
+ @Override
+ public void run() {
countDownLatch.countDown();
}
}
public void testExceptionsCaught() {
+ ExecutionList list = new ExecutionList();
list.add(THROWING_RUNNABLE, sameThreadExecutor());
list.execute();
list.add(THROWING_RUNNABLE, sameThreadExecutor());
}
- public void testNulls() {
- new NullPointerTester().testAllPublicInstanceMethods(new ExecutionList());
+ public void testNulls() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Executor.class, sameThreadExecutor());
+ tester.setDefault(Runnable.class, DO_NOTHING);
+ tester.testAllPublicInstanceMethods(new ExecutionList());
}
private static final Runnable THROWING_RUNNABLE = new Runnable() {
@@ -134,6 +95,7 @@ public class ExecutionListTest extends TestCase {
}
};
private static final Runnable DO_NOTHING = new Runnable() {
- @Override public void run() {}
+ @Override public void run() {
+ }
};
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java
deleted file mode 100644
index c32eb3f..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for {@link ForwardingBlockingQueue}
- */
-public class ForwardingBlockingQueueTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingBlockingQueue.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java
index 1a642be..b78c287 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java
@@ -16,15 +16,99 @@
package com.google.common.util.concurrent;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import com.google.common.util.concurrent.ForwardingCheckedFuture.SimpleForwardingCheckedFuture;
+
import junit.framework.TestCase;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
/**
* Test for {@link ForwardingCheckedFuture}
*
- * @author Ben Yu
+ * @author Anthony Zana
*/
public class ForwardingCheckedFutureTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingCheckedFuture.class);
+ private static final String VALUE = "delegated";
+ private static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
+
+ @SuppressWarnings("unchecked")
+ private CheckedFuture<String, IOException> delegate =
+ createMock(CheckedFuture.class);
+
+ private TestDelegateFuture forwarded = new TestDelegateFuture();
+ private TestSimpleFuture simple = new TestSimpleFuture();
+
+ public void testCheckedGet() throws IOException {
+ expect(delegate.checkedGet()).andReturn(VALUE).times(2);
+ replay(delegate);
+ assertEquals(VALUE, forwarded.checkedGet());
+ assertEquals(VALUE, simple.checkedGet());
+ verify(delegate);
+ }
+
+ public void testTimedCheckedGet() throws TimeoutException, IOException {
+ expect(delegate.checkedGet(100, TIME_UNIT)).andReturn(VALUE).times(2);
+ replay(delegate);
+ assertEquals(VALUE, forwarded.checkedGet(100, TIME_UNIT));
+ assertEquals(VALUE, simple.checkedGet(100, TIME_UNIT));
+ verify(delegate);
+ }
+
+ public void testTimedCheckedGet_timeout()
+ throws IOException, TimeoutException {
+ expect(delegate.checkedGet(100, TIME_UNIT))
+ .andThrow(new TimeoutException()).times(2);
+ replay(delegate);
+ try {
+ forwarded.checkedGet(100, TIME_UNIT);
+ fail();
+ } catch (TimeoutException expected) {}
+ try {
+ simple.checkedGet(100, TIME_UNIT);
+ fail();
+ } catch (TimeoutException expected) {}
+ verify(delegate);
+ }
+
+ public void testCheckedGetException() throws IOException {
+ IOException expected = new IOException("expected");
+ expect(delegate.checkedGet()).andThrow(expected).times(2);
+ replay(delegate);
+ try {
+ delegate.checkedGet();
+ fail();
+ } catch (IOException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+ try {
+ simple.checkedGet();
+ fail();
+ } catch (IOException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+ verify(delegate);
+ }
+
+ private class TestDelegateFuture
+ extends ForwardingCheckedFuture<String, IOException> {
+ @Override
+ protected CheckedFuture<String, IOException> delegate() {
+ return delegate;
+ }
+ }
+
+ private class TestSimpleFuture
+ extends SimpleForwardingCheckedFuture<String, IOException> {
+ public TestSimpleFuture() {
+ super(delegate);
+ }
}
+
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java
deleted file mode 100644
index 15f1e0e..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for {@link ForwardingExecutorService}
- */
-public class ForwardingExecutorServiceTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingExecutorService.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java
deleted file mode 100644
index 4ce9ebf..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for {@link ForwardingFuture}
- */
-public class ForwardingFutureTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingFuture.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java
index 827f50e..4424e8d 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java
@@ -21,10 +21,48 @@ import junit.framework.TestCase;
/**
* Tests for {@link ForwardingListenableFuture}.
*
- * @author Ben Yu
+ * @author Shardul Deo
*/
public class ForwardingListenableFutureTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingListenableFuture.class);
+
+ private SettableFuture<String> delegate;
+ private ListenableFuture<String> forwardingFuture;
+
+ private ListenableFutureTester tester;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ delegate = SettableFuture.create();
+ forwardingFuture = new ForwardingListenableFuture<String>() {
+ @Override
+ protected ListenableFuture<String> delegate() {
+ return delegate;
+ }
+ };
+ tester = new ListenableFutureTester(forwardingFuture);
+ tester.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ tester.tearDown();
+ super.tearDown();
+ }
+
+ public void testCompletedFuture() throws Exception {
+ delegate.set("foo");
+ tester.testCompletedFuture("foo");
+ }
+
+ public void testCancelledFuture() throws Exception {
+ delegate.cancel(true); // parameter is ignored
+ tester.testCancelledFuture();
+ }
+
+ public void testFailedFuture() throws Exception {
+ delegate.setException(new Exception("failed"));
+ tester.testFailedFuture("failed");
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java
deleted file mode 100644
index d4ebd61..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for {@link ForwardingListeningExecutorService}
- */
-public class ForwardingListeningExecutorServiceTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingListeningExecutorService.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java
deleted file mode 100644
index edc48a9..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.base.Function;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ForwardingObject;
-import com.google.common.collect.Iterables;
-import com.google.common.testing.ForwardingWrapperTester;
-
-import org.easymock.EasyMock;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-/**
- * Tester for typical subclass of {@link ForwardingObject} by using EasyMock partial mocks.
- *
- * @author Ben Yu
- */
-final class ForwardingObjectTester {
-
- private static final Method DELEGATE_METHOD;
- static {
- try {
- DELEGATE_METHOD = ForwardingObject.class.getDeclaredMethod("delegate");
- DELEGATE_METHOD.setAccessible(true);
- } catch (SecurityException e) {
- throw new RuntimeException(e);
- } catch (NoSuchMethodException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
- * Ensures that all interface methods of {@code forwarderClass} are forwarded to the
- * {@link ForwardingObject#delegate}. {@code forwarderClass} is assumed to only implement one
- * interface.
- */
- static <T extends ForwardingObject> void testForwardingObject(final Class<T> forwarderClass) {
- @SuppressWarnings("unchecked") // super interface type of T
- Class<? super T> interfaceType = (Class<? super T>)
- Iterables.getOnlyElement(Arrays.asList(forwarderClass.getInterfaces()));
- new ForwardingWrapperTester().testForwarding(interfaceType, new Function<Object, T>() {
- @Override public T apply(Object delegate) {
- T mock = EasyMock.createMockBuilder(forwarderClass)
- .addMockedMethod(DELEGATE_METHOD)
- .createMock();
- try {
- DELEGATE_METHOD.invoke(mock);
- } catch (Exception e) {
- throw Throwables.propagate(e);
- }
- EasyMock.expectLastCall().andStubReturn(delegate);
- EasyMock.replay(mock);
- return mock;
- }
- });
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java
deleted file mode 100644
index eae45bc..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.collect.ForwardingObject;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link ForwardingObjectTester}.
- *
- * @author Ben Yu
- */
-public class ForwardingObjectTesterTest extends TestCase {
-
- public void testFailsToForward() {
- try {
- ForwardingObjectTester.testForwardingObject(FailToForward.class);
- } catch (AssertionError expected) {
- return;
- }
- fail("Should have thrown");
- }
-
- public void testSuccessfulForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardToDelegate.class);
- }
-
- private static abstract class FailToForward extends ForwardingObject implements Runnable {
- @Override public void run() {}
- }
-
- private static abstract class ForwardToDelegate extends ForwardingObject implements Runnable {
- @Override public void run() {
- delegate().run();
- }
- @Override protected abstract Runnable delegate();
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java
deleted file mode 100644
index e18b00e..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for {@link ForwardingService}
- */
-public class ForwardingServiceTest extends TestCase {
- public void testForwarding() {
- ForwardingObjectTester.testForwardingObject(ForwardingService.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java b/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java
index 44e759b..ea9a3da 100644
--- a/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java
@@ -23,12 +23,10 @@ import static com.google.common.util.concurrent.Futures.getUnchecked;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static com.google.common.util.concurrent.Futures.successfulAsList;
-import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.easymock.EasyMock.expect;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.base.Function;
import com.google.common.base.Functions;
@@ -37,7 +35,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
-import com.google.common.testing.ClassSanityTester;
+import com.google.common.testing.NullPointerTester;
import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture;
import junit.framework.AssertionFailedError;
@@ -56,12 +54,9 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
import javax.annotation.Nullable;
@@ -127,27 +122,6 @@ public class FuturesTest extends TestCase {
}
}
- public void testImmediateFailedFuture_cancellationException() throws Exception {
- CancellationException exception = new CancellationException();
- ListenableFuture<String> future =
- Futures.immediateFailedFuture(exception);
-
- try {
- future.get(0L, TimeUnit.MILLISECONDS);
- fail("This call was supposed to throw an ExecutionException");
- } catch (ExecutionException expected) {
- // This is good and expected
- assertSame(exception, expected.getCause());
- assertFalse(future.isCancelled());
- }
- }
-
- public void testImmediateCancelledFuture() throws Exception {
- ListenableFuture<String> future =
- Futures.immediateCancelledFuture();
- assertTrue(future.isCancelled());
- }
-
private static class MyException extends Exception {}
public void testImmediateCheckedFuture() throws Exception {
@@ -220,61 +194,6 @@ public class FuturesTest extends TestCase {
assertSame(barChild, bar);
}
- public void testTransform_ListenableFuture_cancelPropagatesToInput() throws Exception {
- SettableFuture<Foo> input = SettableFuture.create();
- AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
- @Override public ListenableFuture<Bar> apply(Foo unused) {
- fail("Unexpeted call to apply.");
- return null;
- }
- };
- assertTrue(Futures.transform(input, function).cancel(false));
- assertTrue(input.isCancelled());
- assertFalse(input.wasInterrupted());
- }
-
- public void testTransform_ListenableFuture_interruptPropagatesToInput()
- throws Exception {
- SettableFuture<Foo> input = SettableFuture.create();
- AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
- @Override public ListenableFuture<Bar> apply(Foo unused) {
- fail("Unexpeted call to apply.");
- return null;
- }
- };
- assertTrue(Futures.transform(input, function).cancel(true));
- assertTrue(input.isCancelled());
- assertTrue(input.wasInterrupted());
- }
-
- public void testTransform_ListenableFuture_cancelPropagatesToAsyncOutput()
- throws Exception {
- ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo());
- final SettableFuture<Bar> secondary = SettableFuture.create();
- AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
- @Override public ListenableFuture<Bar> apply(Foo unused) {
- return secondary;
- }
- };
- assertTrue(Futures.transform(immediate, function).cancel(false));
- assertTrue(secondary.isCancelled());
- assertFalse(secondary.wasInterrupted());
- }
-
- public void testTransform_ListenableFuture_interruptPropagatesToAsyncOutput()
- throws Exception {
- ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo());
- final SettableFuture<Bar> secondary = SettableFuture.create();
- AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
- @Override public ListenableFuture<Bar> apply(Foo unused) {
- return secondary;
- }
- };
- assertTrue(Futures.transform(immediate, function).cancel(true));
- assertTrue(secondary.isCancelled());
- assertTrue(secondary.wasInterrupted());
- }
-
/**
* {@link ListenableFuture} variant of
* {@link #testTransformValueRemainsMemoized_Future()}.
@@ -463,28 +382,6 @@ public class FuturesTest extends TestCase {
assertEquals(2, spy.getApplyCount());
}
- public void testLazyTransform_exception() throws Exception {
- final RuntimeException exception = new RuntimeException("deliberate");
- Function<Integer, String> function = new Function<Integer, String>() {
- @Override public String apply(Integer input) {
- throw exception;
- }
- };
- Future<String> transformed = Futures.lazyTransform(Futures.immediateFuture(1), function);
- try {
- transformed.get();
- fail();
- } catch (ExecutionException expected) {
- assertSame(exception, expected.getCause());
- }
- try {
- transformed.get(1, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertSame(exception, expected.getCause());
- }
- }
-
private static class FunctionSpy<I, O> implements Function<I, O> {
private int applyCount;
private final Function<I, O> delegate;
@@ -504,150 +401,6 @@ public class FuturesTest extends TestCase {
}
}
- @SuppressWarnings("unchecked")
- public void testWithFallback_inputDoesNotRaiseException() throws Exception {
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
- ListenableFuture<Integer> originalFuture = Futures.immediateFuture(7);
-
- mocksControl.replay();
- ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(originalFuture, fallback);
- assertEquals(7, faultToleranteFuture.get().intValue());
- mocksControl.verify();
- }
-
- @SuppressWarnings("unchecked")
- public void testWithFallback_inputRaisesException() throws Exception {
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
- RuntimeException raisedException = new RuntimeException();
- expect(fallback.create(raisedException)).andReturn(Futures.immediateFuture(20));
- ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
-
- mocksControl.replay();
- ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(failingFuture, fallback);
- assertEquals(20, faultToleranteFuture.get().intValue());
- mocksControl.verify();
- }
-
- public void testWithFallback_fallbackGeneratesRuntimeException() throws Exception {
- RuntimeException expectedException = new RuntimeException();
- runExpectedExceptionFallbackTest(expectedException, false);
- }
-
- public void testWithFallback_fallbackGeneratesCheckedException() throws Exception {
- Exception expectedException = new Exception() {};
- runExpectedExceptionFallbackTest(expectedException, false);
- }
-
- @SuppressWarnings("unchecked")
- public void testWithFallback_fallbackGeneratesError() throws Exception {
- Error error = new Error("deliberate");
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
- RuntimeException raisedException = new RuntimeException();
- expect(fallback.create(raisedException)).andThrow(error);
- ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
- mocksControl.replay();
- try {
- Futures.withFallback(failingFuture, fallback);
- fail("An Exception should have been thrown!");
- } catch (Error expected) {
- assertSame(error, expected);
- }
- mocksControl.verify();
- }
-
- public void testWithFallback_fallbackReturnsRuntimeException() throws Exception {
- RuntimeException expectedException = new RuntimeException();
- runExpectedExceptionFallbackTest(expectedException, true);
- }
-
- public void testWithFallback_fallbackReturnsCheckedException() throws Exception {
- Exception expectedException = new Exception() {};
- runExpectedExceptionFallbackTest(expectedException, true);
- }
-
- @SuppressWarnings("unchecked")
- private void runExpectedExceptionFallbackTest(
- Throwable expectedException, boolean wrapInFuture) throws Exception {
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
- RuntimeException raisedException = new RuntimeException();
- if (!wrapInFuture) {
- // Exception is thrown in the body of the "fallback" method.
- expect(fallback.create(raisedException)).andThrow(expectedException);
- } else {
- // Exception is wrapped in a future and returned.
- expect(fallback.create(raisedException)).andReturn(
- Futures.<Integer>immediateFailedFuture(expectedException));
- }
-
- ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
-
- mocksControl.replay();
- ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(failingFuture, fallback);
- try {
- faultToleranteFuture.get();
- fail("An Exception should have been thrown!");
- } catch (ExecutionException ee) {
- assertSame(expectedException, ee.getCause());
- }
- mocksControl.verify();
- }
-
- public void testWithFallback_fallbackNotReady() throws Exception {
- ListenableFuture<Integer> primary = immediateFailedFuture(new Exception());
- final SettableFuture<Integer> secondary = SettableFuture.create();
- FutureFallback<Integer> fallback = new FutureFallback<Integer>() {
- @Override
- public ListenableFuture<Integer> create(Throwable t) {
- return secondary;
- }
- };
- ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
- secondary.set(1);
- assertEquals(1, (int) derived.get());
- }
-
- @SuppressWarnings("unchecked")
- public void testWithFallback_resultInterruptedBeforeFallback() throws Exception {
- SettableFuture<Integer> primary = SettableFuture.create();
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
-
- mocksControl.replay();
- ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
- derived.cancel(true);
- assertTrue(primary.isCancelled());
- assertTrue(primary.wasInterrupted());
- mocksControl.verify();
- }
-
- @SuppressWarnings("unchecked")
- public void testWithFallback_resultCancelledBeforeFallback() throws Exception {
- SettableFuture<Integer> primary = SettableFuture.create();
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
-
- mocksControl.replay();
- ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
- derived.cancel(false);
- assertTrue(primary.isCancelled());
- assertFalse(primary.wasInterrupted());
- mocksControl.verify();
- }
-
- @SuppressWarnings("unchecked")
- public void testWithFallback_resultCancelledAfterFallback() throws Exception {
- SettableFuture<Integer> secondary = SettableFuture.create();
- FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
- RuntimeException raisedException = new RuntimeException();
- expect(fallback.create(raisedException)).andReturn(secondary);
- ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
-
- mocksControl.replay();
- ListenableFuture<Integer> derived = Futures.withFallback(failingFuture, fallback);
- derived.cancel(false);
- assertTrue(secondary.isCancelled());
- assertFalse(secondary.wasInterrupted());
- mocksControl.verify();
- }
-
public void testTransform_genericsWildcard_AsyncFunction() throws Exception {
ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
ListenableFuture<?> chainedFuture =
@@ -680,108 +433,74 @@ public class FuturesTest extends TestCase {
assertSame(barChild, bar);
}
- public void testTransform_asyncFunction_timeout()
- throws InterruptedException, ExecutionException {
- AsyncFunction<String, Integer> function = constantAsyncFunction(Futures.immediateFuture(1));
- ListenableFuture<Integer> future = Futures.transform(
- SettableFuture.<String>create(), function);
- try {
- future.get(1, TimeUnit.MILLISECONDS);
- fail();
- } catch (TimeoutException expected) {}
+ public void testTransform_delegatesBlockingGet_AsyncFunction() throws Exception {
+ performAsyncFunctionTransformedFutureDelgationTest(0, null);
}
- public void testTransform_asyncFunction_error() {
- final Error error = new Error("deliberate");
- AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() {
- @Override public ListenableFuture<Integer> apply(String input) {
- throw error;
- }
- };
- SettableFuture<String> inputFuture = SettableFuture.create();
- Futures.transform(inputFuture, function);
- try {
- inputFuture.set("value");
- } catch (Error expected) {
- assertSame(error, expected);
- return;
- }
- fail("should have thrown error");
- }
-
- public void testTransform_asyncFunction_cancelledWhileApplyingFunction()
- throws InterruptedException, ExecutionException {
- final CountDownLatch inFunction = new CountDownLatch(1);
- final CountDownLatch functionDone = new CountDownLatch(1);
- final SettableFuture<Integer> resultFuture = SettableFuture.create();
- AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() {
- @Override public ListenableFuture<Integer> apply(String input) throws Exception {
- inFunction.countDown();
- functionDone.await();
- return resultFuture;
- }
- };
- SettableFuture<String> inputFuture = SettableFuture.create();
- ListenableFuture<Integer> future = Futures.transform(
- inputFuture, function, Executors.newSingleThreadExecutor());
- inputFuture.set("value");
- inFunction.await();
- future.cancel(false);
- functionDone.countDown();
- try {
- future.get();
- fail();
- } catch (CancellationException expected) {}
- try {
- resultFuture.get();
- fail();
- } catch (CancellationException expected) {}
+ public void testTransform_delegatesTimedGet_AsyncFunction() throws Exception {
+ performAsyncFunctionTransformedFutureDelgationTest(25, TimeUnit.SECONDS);
}
- public void testDereference_genericsWildcard() throws Exception {
- ListenableFuture<?> inner = Futures.immediateFuture(null);
- ListenableFuture<ListenableFuture<?>> outer =
- Futures.<ListenableFuture<?>>immediateFuture(inner);
- ListenableFuture<?> dereferenced = Futures.dereference(outer);
- assertNull(dereferenced.get());
- }
+ private void performAsyncFunctionTransformedFutureDelgationTest(
+ long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ final Foo foo = new Foo();
+ MockRequiresGetCallFuture<Foo> fooFuture =
+ new MockRequiresGetCallFuture<Foo>(foo);
+
+ Bar bar = new Bar();
+ final MockRequiresGetCallFuture<Bar> barFuture =
+ new MockRequiresGetCallFuture<Bar>(bar);
+ AsyncFunction<Foo, Bar> function =
+ new AsyncFunction<Foo, Bar>() {
+ @Override public ListenableFuture<Bar> apply(Foo from) {
+ assertSame(foo, from);
+ return barFuture;
+ }
+ };
- public void testDereference_genericsHierarchy() throws Exception {
- FooChild fooChild = new FooChild();
- ListenableFuture<FooChild> inner = Futures.immediateFuture(fooChild);
- ListenableFuture<ListenableFuture<FooChild>> outer = Futures.immediateFuture(inner);
- ListenableFuture<Foo> dereferenced = Futures.<Foo>dereference(outer);
- assertSame(fooChild, dereferenced.get());
+ ListenableFuture<Bar> chainFuture = Futures.transform(fooFuture, function);
+ Bar theBar;
+ if (unit != null) {
+ theBar = chainFuture.get(timeout, unit);
+ } else {
+ theBar = chainFuture.get();
+ }
+ assertSame(bar, theBar);
+ assertTrue(fooFuture.getWasGetCalled());
+ assertTrue(barFuture.getWasGetCalled());
}
- public void testDereference_resultCancelsOuter() throws Exception {
- ListenableFuture<ListenableFuture<Foo>> outer = SettableFuture.create();
- ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
- dereferenced.cancel(true);
- assertTrue(outer.isCancelled());
- }
+ /**
+ * A mock listenable future that requires the caller invoke
+ * either form of get() before the future will make its value
+ * available or invoke listeners.
+ */
+ private static class MockRequiresGetCallFuture<T> extends AbstractFuture<T> {
- public void testDereference_resultCancelsInner() throws Exception {
- ListenableFuture<Foo> inner = SettableFuture.create();
- ListenableFuture<ListenableFuture<Foo>> outer = Futures.immediateFuture(inner);
- ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
- dereferenced.cancel(true);
- assertTrue(inner.isCancelled());
- }
+ private final T value;
+ private boolean getWasCalled;
- public void testDereference_outerCancelsResult() throws Exception {
- ListenableFuture<ListenableFuture<Foo>> outer = SettableFuture.create();
- ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
- outer.cancel(true);
- assertTrue(dereferenced.isCancelled());
- }
+ MockRequiresGetCallFuture(T value) {
+ this.value = value;
+ }
- public void testDereference_innerCancelsResult() throws Exception {
- ListenableFuture<Foo> inner = SettableFuture.create();
- ListenableFuture<ListenableFuture<Foo>> outer = Futures.immediateFuture(inner);
- ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
- inner.cancel(true);
- assertTrue(dereferenced.isCancelled());
+ @Override public T get() throws InterruptedException, ExecutionException {
+ set(value);
+ getWasCalled = true;
+ return super.get();
+ }
+
+ @Override public T get(long timeout, TimeUnit unit)
+ throws TimeoutException, ExecutionException, InterruptedException {
+ set(value);
+ getWasCalled = true;
+ return super.get(timeout, unit);
+ }
+
+ boolean getWasGetCalled() {
+ return getWasCalled;
+ }
}
/**
@@ -840,7 +559,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(DATA1, DATA2, DATA3).inOrder();
+ ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
}
public void testAllAsList_emptyList() throws Exception {
@@ -916,27 +635,6 @@ public class FuturesTest extends TestCase {
}
}
- public void testAllAsList_error() throws Exception {
- Error error = new Error("deliberate");
- SettableFuture<String> future1 = SettableFuture.create();
- ListenableFuture<String> future2 = Futures.immediateFuture("results");
- ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future1, future2));
-
- try {
- future1.setException(error);
- } catch (Error expected) {
- assertSame(error, expected);
- try {
- compound.get();
- } catch (ExecutionException ee) {
- assertSame(error, ee.getCause());
- return;
- }
- fail("Expected error not set in compound future.");
- }
- fail("Expected error not thrown");
- }
-
public void testAllAsList_cancelled() throws Exception {
SingleCallListener listener = new SingleCallListener();
SettableFuture<String> future1 = SettableFuture.create();
@@ -960,34 +658,22 @@ public class FuturesTest extends TestCase {
}
}
- public void testAllAsList_resultCancelled() throws Exception {
- SettableFuture<String> future1 = SettableFuture.create();
- SettableFuture<String> future2 = SettableFuture.create();
- @SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<String>> compound =
- Futures.allAsList(future1, future2);
-
- future2.set(DATA2);
- assertFalse(compound.isDone());
- assertTrue(compound.cancel(false));
- assertTrue(compound.isCancelled());
- assertTrue(future1.isCancelled());
- assertFalse(future1.wasInterrupted());
- }
+ public void testAllAsList_buggyInputFutures() throws Exception {
+ final Foo foo1 = new Foo();
+ MockRequiresGetCallFuture<Foo> foo1Future =
+ new MockRequiresGetCallFuture<Foo>(foo1);
+ final Foo foo2 = new Foo();
+ MockRequiresGetCallFuture<Foo> foo2Future =
+ new MockRequiresGetCallFuture<Foo>(foo2);
- public void testAllAsList_resultInterrupted() throws Exception {
- SettableFuture<String> future1 = SettableFuture.create();
- SettableFuture<String> future2 = SettableFuture.create();
@SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<String>> compound =
- Futures.allAsList(future1, future2);
+ ListenableFuture<List<Foo>> compound =
+ Futures.allAsList(foo1Future, foo2Future);
- future2.set(DATA2);
assertFalse(compound.isDone());
- assertTrue(compound.cancel(true));
- assertTrue(compound.isCancelled());
- assertTrue(future1.isCancelled());
- assertTrue(future1.wasInterrupted());
+ ASSERT.that(compound.get()).hasContentsAnyOrder(foo1, foo2);
+ assertTrue(foo1Future.getWasGetCalled());
+ assertTrue(foo2Future.getWasGetCalled());
}
/**
@@ -1021,10 +707,10 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(DATA1, DATA2, DATA3).inOrder();
+ ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
}
- private static String createCombinedResult(Integer i, Boolean b) {
+ private String createCombinedResult(Integer i, Boolean b) {
return "-" + i + "-" + b;
}
@@ -1441,7 +1127,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(DATA1, DATA2, DATA3).inOrder();
+ ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
}
public void testSuccessfulAsList_emptyList() throws Exception {
@@ -1484,7 +1170,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(null, DATA2).inOrder();
+ ASSERT.that(results).hasContentsInOrder(null, DATA2);
}
public void testSuccessfulAsList_totalFailure() throws Exception {
@@ -1505,7 +1191,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(null, null).inOrder();
+ ASSERT.that(results).hasContentsInOrder(null, null);
}
public void testSuccessfulAsList_cancelled() throws Exception {
@@ -1526,108 +1212,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(null, DATA2).inOrder();
- }
-
- public void testSuccessfulAsList_resultCancelled() throws Exception {
- SettableFuture<String> future1 = SettableFuture.create();
- SettableFuture<String> future2 = SettableFuture.create();
- @SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<String>> compound =
- Futures.successfulAsList(future1, future2);
-
- future2.set(DATA2);
- assertFalse(compound.isDone());
- assertTrue(compound.cancel(false));
- assertTrue(compound.isCancelled());
- assertTrue(future1.isCancelled());
- assertFalse(future1.wasInterrupted());
- }
-
- public void testSuccessfulAsList_resultCancelledRacingInputDone()
- throws Exception {
- /*
- * The IllegalStateException that we're testing for is caught by
- * ExecutionList and logged rather than allowed to propagate. We need to
- * turn that back into a failure.
- */
- Handler throwingHandler = new Handler() {
- @Override public void publish(@Nullable LogRecord record) {
- AssertionFailedError error = new AssertionFailedError();
- error.initCause(record.getThrown());
- throw error;
- }
-
- @Override public void flush() {}
-
- @Override public void close() {}
- };
-
- ExecutionList.log.addHandler(throwingHandler);
- try {
- doTestSuccessfulAsList_resultCancelledRacingInputDone();
- } finally {
- ExecutionList.log.removeHandler(throwingHandler);
- }
- }
-
- private static void doTestSuccessfulAsList_resultCancelledRacingInputDone()
- throws Exception {
- // Simple (combined.cancel -> input.cancel -> setOneValue):
- Futures.successfulAsList(ImmutableList.of(SettableFuture.create()))
- .cancel(true);
-
- /*
- * Complex (combined.cancel -> input.cancel -> other.set -> setOneValue),
- * to show that this isn't just about problems with the input future we just
- * cancelled:
- */
- final SettableFuture<String> future1 = SettableFuture.create();
- final SettableFuture<String> future2 = SettableFuture.create();
- @SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<String>> compound =
- Futures.successfulAsList(future1, future2);
-
- future1.addListener(new Runnable() {
- @Override public void run() {
- assertTrue(future1.isCancelled());
- /*
- * This test relies on behavior that's unspecified but currently
- * guaranteed by the implementation: Cancellation of inputs is
- * performed in the order they were provided to the constructor. Verify
- * that as a sanity check:
- */
- assertFalse(future2.isCancelled());
- // Now attempt to trigger the exception:
- future2.set(DATA2);
- }
- }, sameThreadExecutor());
- assertTrue(compound.cancel(false));
- assertTrue(compound.isCancelled());
- assertTrue(future1.isCancelled());
- assertFalse(future2.isCancelled());
-
- try {
- compound.get();
- fail("Expected exception not thrown");
- } catch (CancellationException e) {
- // Expected
- }
- }
-
- public void testSuccessfulAsList_resultInterrupted() throws Exception {
- SettableFuture<String> future1 = SettableFuture.create();
- SettableFuture<String> future2 = SettableFuture.create();
- @SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<String>> compound =
- Futures.successfulAsList(future1, future2);
-
- future2.set(DATA2);
- assertFalse(compound.isDone());
- assertTrue(compound.cancel(true));
- assertTrue(compound.isCancelled());
- assertTrue(future1.isCancelled());
- assertTrue(future1.wasInterrupted());
+ ASSERT.that(results).hasContentsInOrder(null, DATA2);
}
public void testSuccessfulAsList_mixed() throws Exception {
@@ -1652,7 +1237,25 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).has().allOf(null, null, DATA3).inOrder();
+ ASSERT.that(results).hasContentsInOrder(null, null, DATA3);
+ }
+
+ public void testSuccessfulAsList_buggyInputFutures() throws Exception {
+ final Foo foo1 = new Foo();
+ MockRequiresGetCallFuture<Foo> foo1Future =
+ new MockRequiresGetCallFuture<Foo>(foo1);
+ final Foo foo2 = new Foo();
+ MockRequiresGetCallFuture<Foo> foo2Future =
+ new MockRequiresGetCallFuture<Foo>(foo2);
+
+ @SuppressWarnings("unchecked") // array is never modified
+ ListenableFuture<List<Foo>> compound =
+ Futures.successfulAsList(foo1Future, foo2Future);
+
+ assertFalse(compound.isDone());
+ ASSERT.that(compound.get()).hasContentsAnyOrder(foo1, foo2);
+ assertTrue(foo1Future.getWasGetCalled());
+ assertTrue(foo2Future.getWasGetCalled());
}
private static class TestException extends Exception {
@@ -1882,8 +1485,20 @@ public class FuturesTest extends TestCase {
private static final Future<String> FAILED_FUTURE_OTHER_THROWABLE =
immediateFailedFuture(OTHER_THROWABLE);
private static final Error ERROR = new Error("mymessage");
- private static final Future<String> FAILED_FUTURE_ERROR =
- immediateFailedFuture(ERROR);
+ private static final Future<String> FAILED_FUTURE_ERROR;
+ /*
+ * We can't write "= immediateFailedFuture(ERROR)" because setException
+ * rethrows the error....
+ */
+ static {
+ SettableFuture<String> f = SettableFuture.create();
+ try {
+ f.setException(ERROR);
+ } catch (Error e) {
+ assertEquals(e, ERROR);
+ }
+ FAILED_FUTURE_ERROR = f;
+ }
private static final Future<String> RUNTIME_EXCEPTION_FUTURE =
new SimpleForwardingFuture<String>(FAILED_FUTURE_CHECKED_EXCEPTION) {
@Override public String get() {
@@ -1904,10 +1519,9 @@ public class FuturesTest extends TestCase {
}
public void testGetUntimed_interrupted() {
- SettableFuture<String> future = SettableFuture.create();
Thread.currentThread().interrupt();
try {
- get(future, TwoArgConstructorException.class);
+ get(immediateFuture("foo"), TwoArgConstructorException.class);
fail();
} catch (TwoArgConstructorException expected) {
assertTrue(expected.getCause() instanceof InterruptedException);
@@ -1976,24 +1590,6 @@ public class FuturesTest extends TestCase {
}
}
- public void testGetUntimed_badExceptionConstructor_wrapsOriginalChecked() throws Exception {
- try {
- get(FAILED_FUTURE_CHECKED_EXCEPTION, ExceptionWithBadConstructor.class);
- fail();
- } catch (IllegalArgumentException expected) {
- assertSame(CHECKED_EXCEPTION, expected.getCause());
- }
- }
-
- public void testGetUntimed_withGoodAndBadExceptionConstructor() throws Exception {
- try {
- get(FAILED_FUTURE_CHECKED_EXCEPTION, ExceptionWithGoodAndBadConstructor.class);
- fail();
- } catch (ExceptionWithGoodAndBadConstructor expected) {
- assertSame(CHECKED_EXCEPTION, expected.getCause());
- }
- }
-
// Boring timed-get tests:
public void testGetTimed_success()
@@ -2003,10 +1599,9 @@ public class FuturesTest extends TestCase {
}
public void testGetTimed_interrupted() {
- SettableFuture<String> future = SettableFuture.create();
Thread.currentThread().interrupt();
try {
- get(future, 0, SECONDS, TwoArgConstructorException.class);
+ get(immediateFuture("foo"), 0, SECONDS, TwoArgConstructorException.class);
fail();
} catch (TwoArgConstructorException expected) {
assertTrue(expected.getCause() instanceof InterruptedException);
@@ -2089,25 +1684,6 @@ public class FuturesTest extends TestCase {
}
}
- public void testGetTimed_badExceptionConstructor_wrapsOriginalChecked() throws Exception {
- try {
- get(FAILED_FUTURE_CHECKED_EXCEPTION, 1, TimeUnit.SECONDS, ExceptionWithBadConstructor.class);
- fail();
- } catch (IllegalArgumentException expected) {
- assertSame(CHECKED_EXCEPTION, expected.getCause());
- }
- }
-
- public void testGetTimed_withGoodAndBadExceptionConstructor() throws Exception {
- try {
- get(FAILED_FUTURE_CHECKED_EXCEPTION, 1, TimeUnit.SECONDS,
- ExceptionWithGoodAndBadConstructor.class);
- fail();
- } catch (ExceptionWithGoodAndBadConstructor expected) {
- assertSame(CHECKED_EXCEPTION, expected.getCause());
- }
- }
-
// Boring getUnchecked tests:
public void testGetUnchecked_success() {
@@ -2331,26 +1907,31 @@ public class FuturesTest extends TestCase {
}
}
- private static final class ExceptionWithGoodAndBadConstructor extends Exception {
- public ExceptionWithGoodAndBadConstructor(String message, Throwable cause) {
- throw new RuntimeException("bad constructor");
- }
- public ExceptionWithGoodAndBadConstructor(Throwable cause) {
- super(cause);
- }
- }
+ public void testNullArguments() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(ListenableFuture.class, Futures.immediateFuture(DATA1));
+ tester.setDefault(ListenableFuture[].class,
+ new ListenableFuture[] {Futures.immediateFuture(DATA1)});
+ tester.setDefault(Future.class, Futures.immediateFuture(DATA1));
+ tester.setDefault(Executor.class, MoreExecutors.sameThreadExecutor());
+ tester.setDefault(Callable.class, Callables.returning(null));
+ tester.setDefault(AsyncFunction.class, new AsyncFunction() {
+ @Override
+ public ListenableFuture apply(Object input) throws Exception {
+ return immediateFuture(DATA1);
+ }
+ });
- private static final class ExceptionWithBadConstructor extends Exception {
- public ExceptionWithBadConstructor(String message, Throwable cause) {
- throw new RuntimeException("bad constructor");
- }
- }
+ FutureCallback<Object> callback =
+ new FutureCallback<Object>() {
+ @Override
+ public void onSuccess(Object result) {}
+ @Override
+ public void onFailure(Throwable t) {}
+ };
+ tester.setDefault(FutureCallback.class, callback);
- public void testFutures_nullChecks() throws Exception {
- new ClassSanityTester()
- .forAllPublicStaticMethods(Futures.class)
- .thatReturn(Future.class)
- .testNulls();
+ tester.testAllPublicStaticMethods(Futures.class);
}
private static void failWithCause(Throwable cause, String message) {
diff --git a/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java b/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java
index 50d1be0..e610b20 100644
--- a/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java
+++ b/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java
@@ -16,7 +16,6 @@
package com.google.common.util.concurrent;
-import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static junit.framework.Assert.fail;
@@ -74,7 +73,6 @@ final class InterruptionUtil {
* Interrupts the current thread after sleeping for the specified delay.
*/
static void requestInterruptIn(final long time, final TimeUnit unit) {
- checkNotNull(unit);
final Thread interruptee = Thread.currentThread();
new Thread(new Runnable() {
@Override
diff --git a/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java b/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java
index 23fc1e8..80b9599 100644
--- a/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java
+++ b/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java
@@ -15,22 +15,11 @@
package com.google.common.util.concurrent;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
-
import junit.framework.*;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.security.CodeSource;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.Permissions;
-import java.security.Policy;
-import java.security.ProtectionDomain;
-import java.security.SecurityPermission;
import java.util.Arrays;
import java.util.Date;
import java.util.NoSuchElementException;
@@ -38,6 +27,15 @@ import java.util.PropertyPermission;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
/**
* Base class for JSR166 Junit TCK tests. Defines some constants,
diff --git a/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java b/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java
index ab072eb..298733f 100644
--- a/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java
@@ -23,7 +23,7 @@ import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor
import static java.util.concurrent.Executors.newCachedThreadPool;
import static java.util.concurrent.TimeUnit.SECONDS;
-import com.google.common.testing.ClassSanityTester;
+import com.google.common.testing.NullPointerTester;
import com.google.common.util.concurrent.FuturesTest.ExecutorSpy;
import com.google.common.util.concurrent.FuturesTest.SingleCallListener;
@@ -206,10 +206,9 @@ public class JdkFutureAdaptersTest extends TestCase {
assertTrue(lateListener.wasRun.await(1, SECONDS));
}
- public void testAdapters_nullChecks() throws Exception {
- new ClassSanityTester()
- .forAllPublicStaticMethods(JdkFutureAdapters.class)
- .thatReturn(Future.class)
- .testNulls();
+ public void testNullArguments() throws Exception {
+ NullPointerTester tester = new NullPointerTester();
+ tester.setDefault(Future.class, immediateFuture(DATA1));
+ tester.testAllPublicStaticMethods(JdkFutureAdapters.class);
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java b/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java
index cb10fc8..367b95a 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java
@@ -16,7 +16,6 @@
package com.google.common.util.concurrent;
-import static com.google.common.base.Preconditions.checkNotNull;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -29,8 +28,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import javax.annotation.Nullable;
-
/**
* Used to test listenable future implementations.
*
@@ -44,7 +41,7 @@ public class ListenableFutureTester {
public ListenableFutureTester(ListenableFuture<?> future) {
this.exec = Executors.newCachedThreadPool();
- this.future = checkNotNull(future);
+ this.future = future;
this.latch = new CountDownLatch(1);
}
@@ -64,7 +61,7 @@ public class ListenableFutureTester {
exec.shutdown();
}
- public void testCompletedFuture(@Nullable Object expectedValue)
+ public void testCompletedFuture(Object expectedValue)
throws InterruptedException, ExecutionException {
assertTrue(future.isDone());
assertFalse(future.isCancelled());
@@ -91,7 +88,7 @@ public class ListenableFutureTester {
} catch (CancellationException expected) {}
}
- public void testFailedFuture(@Nullable String message)
+ public void testFailedFuture(String message)
throws InterruptedException {
assertTrue(future.isDone());
assertFalse(future.isCancelled());
diff --git a/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java b/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java
index a6f8d2e..99a6be3 100644
--- a/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java
@@ -14,54 +14,26 @@
* limitations under the License.
*/
-/*
- * Portions of this file are modified versions of
- * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/AbstractExecutorServiceTest.java?revision=1.30
- * which contained the following notice:
- *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- * Other contributors include Andrew Wright, Jeffrey Hayes,
- * Pat Fisher, Mike Judd.
- */
-
package com.google.common.util.concurrent;
import static com.google.common.collect.Iterables.getOnlyElement;
-import static com.google.common.util.concurrent.MoreExecutors.invokeAnyImpl;
import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator;
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.testing.ClassSanityTester;
-import com.google.common.util.concurrent.MoreExecutors.Application;
-import org.mockito.InOrder;
-import org.mockito.Mockito;
+import junit.framework.TestCase;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -70,11 +42,7 @@ import java.util.concurrent.atomic.AtomicReference;
*
* @author Kyle Littlefield (klittle)
*/
-public class MoreExecutorsTest extends JSR166TestCase {
-
- private static final Runnable EMPTY_RUNNABLE = new Runnable() {
- @Override public void run() {}
- };
+public class MoreExecutorsTest extends TestCase {
public void testSameThreadExecutorServiceInThreadExecution()
throws Exception {
@@ -234,21 +202,6 @@ public class MoreExecutorsTest extends JSR166TestCase {
throwableFromOtherThread.get());
}
- public void testSameThreadExecutor_shutdownNow() {
- ExecutorService executor = MoreExecutors.sameThreadExecutor();
- assertEquals(ImmutableList.of(), executor.shutdownNow());
- assertTrue(executor.isShutdown());
- }
-
- public void testExecuteAfterShutdown() {
- ExecutorService executor = MoreExecutors.sameThreadExecutor();
- executor.shutdown();
- try {
- executor.execute(EMPTY_RUNNABLE);
- fail();
- } catch (RejectedExecutionException expected) {}
- }
-
public void testListeningDecorator() throws Exception {
ListeningExecutorService service =
listeningDecorator(MoreExecutors.sameThreadExecutor());
@@ -269,88 +222,6 @@ public class MoreExecutorsTest extends JSR166TestCase {
*/
}
- /**
- * invokeAny(null) throws NPE
- */
- public void testInvokeAnyImpl_nullTasks() throws Exception {
- ListeningExecutorService e = sameThreadExecutor();
- try {
- invokeAnyImpl(e, null, false, 0);
- shouldThrow();
- } catch (NullPointerException success) {
- } finally {
- joinPool(e);
- }
- }
-
- /**
- * invokeAny(empty collection) throws IAE
- */
- public void testInvokeAnyImpl_emptyTasks() throws Exception {
- ListeningExecutorService e = sameThreadExecutor();
- try {
- invokeAnyImpl(e, new ArrayList<Callable<String>>(), false, 0);
- shouldThrow();
- } catch (IllegalArgumentException success) {
- } finally {
- joinPool(e);
- }
- }
-
- /**
- * invokeAny(c) throws NPE if c has null elements
- */
- public void testInvokeAnyImpl_nullElement() throws Exception {
- ListeningExecutorService e = sameThreadExecutor();
- List<Callable<Integer>> l = new ArrayList<Callable<Integer>>();
- l.add(new Callable<Integer>() {
- @Override public Integer call() {
- throw new ArithmeticException("/ by zero");
- }
- });
- l.add(null);
- try {
- invokeAnyImpl(e, l, false, 0);
- shouldThrow();
- } catch (NullPointerException success) {
- } finally {
- joinPool(e);
- }
- }
-
- /**
- * invokeAny(c) throws ExecutionException if no task in c completes
- */
- public void testInvokeAnyImpl_noTaskCompletes() throws Exception {
- ListeningExecutorService e = sameThreadExecutor();
- List<Callable<String>> l = new ArrayList<Callable<String>>();
- l.add(new NPETask());
- try {
- invokeAnyImpl(e, l, false, 0);
- shouldThrow();
- } catch (ExecutionException success) {
- assertTrue(success.getCause() instanceof NullPointerException);
- } finally {
- joinPool(e);
- }
- }
-
- /**
- * invokeAny(c) returns result of some task in c if at least one completes
- */
- public void testInvokeAnyImpl() throws Exception {
- ListeningExecutorService e = sameThreadExecutor();
- try {
- List<Callable<String>> l = new ArrayList<Callable<String>>();
- l.add(new StringTask());
- l.add(new StringTask());
- String result = invokeAnyImpl(e, l, false, 0);
- assertSame(TEST_STRING, result);
- } finally {
- joinPool(e);
- }
- }
-
private static void assertListenerRunImmediately(ListenableFuture<?> future) {
CountingRunnable listener = new CountingRunnable();
future.addListener(listener, sameThreadExecutor());
@@ -365,109 +236,4 @@ public class MoreExecutorsTest extends JSR166TestCase {
count++;
}
}
-
- public void testAddDelayedShutdownHook_success() throws InterruptedException {
- TestApplication application = new TestApplication();
- ExecutorService service = mock(ExecutorService.class);
- application.addDelayedShutdownHook(service, 2, TimeUnit.SECONDS);
- verify(service, Mockito.never()).shutdown();
- application.shutdown();
- InOrder shutdownFirst = Mockito.inOrder(service);
- shutdownFirst.verify(service).shutdown();
- shutdownFirst.verify(service).awaitTermination(2, TimeUnit.SECONDS);
- }
-
- public void testAddDelayedShutdownHook_interrupted() throws InterruptedException {
- TestApplication application = new TestApplication();
- ExecutorService service = mock(ExecutorService.class);
- application.addDelayedShutdownHook(service, 2, TimeUnit.SECONDS);
- when(service.awaitTermination(2, TimeUnit.SECONDS)).thenThrow(new InterruptedException());
- application.shutdown();
- verify(service).shutdown();
- }
-
- public void testGetExitingExcutorService_executorSetToUseDaemonThreads() {
- TestApplication application = new TestApplication();
- ThreadPoolExecutor executor = new ThreadPoolExecutor(
- 1, 2, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
- assertNotNull(application.getExitingExecutorService(executor));
- assertTrue(executor.getThreadFactory().newThread(EMPTY_RUNNABLE).isDaemon());
- }
-
- public void testGetExitingExcutorService_executorDelegatesToOriginal() {
- TestApplication application = new TestApplication();
- ThreadPoolExecutor executor = mock(ThreadPoolExecutor.class);
- ThreadFactory threadFactory = mock(ThreadFactory.class);
- when(executor.getThreadFactory()).thenReturn(threadFactory);
- application.getExitingExecutorService(executor).execute(EMPTY_RUNNABLE);
- verify(executor).execute(EMPTY_RUNNABLE);
- }
-
- public void testGetExitingExcutorService_shutdownHookRegistered() throws InterruptedException {
- TestApplication application = new TestApplication();
- ThreadPoolExecutor executor = mock(ThreadPoolExecutor.class);
- ThreadFactory threadFactory = mock(ThreadFactory.class);
- when(executor.getThreadFactory()).thenReturn(threadFactory);
- application.getExitingExecutorService(executor);
- application.shutdown();
- verify(executor).shutdown();
- }
-
- public void testGetExitingScheduledExcutorService_executorSetToUseDaemonThreads() {
- TestApplication application = new TestApplication();
- ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
- assertNotNull(application.getExitingScheduledExecutorService(executor));
- assertTrue(executor.getThreadFactory().newThread(EMPTY_RUNNABLE).isDaemon());
- }
-
- public void testGetExitingScheduledExcutorService_executorDelegatesToOriginal() {
- TestApplication application = new TestApplication();
- ScheduledThreadPoolExecutor executor = mock(ScheduledThreadPoolExecutor.class);
- ThreadFactory threadFactory = mock(ThreadFactory.class);
- when(executor.getThreadFactory()).thenReturn(threadFactory);
- application.getExitingScheduledExecutorService(executor).execute(EMPTY_RUNNABLE);
- verify(executor).execute(EMPTY_RUNNABLE);
- }
-
- public void testGetScheduledExitingExcutorService_shutdownHookRegistered()
- throws InterruptedException {
- TestApplication application = new TestApplication();
- ScheduledThreadPoolExecutor executor = mock(ScheduledThreadPoolExecutor.class);
- ThreadFactory threadFactory = mock(ThreadFactory.class);
- when(executor.getThreadFactory()).thenReturn(threadFactory);
- application.getExitingScheduledExecutorService(executor);
- application.shutdown();
- verify(executor).shutdown();
- }
-
- public void testPlatformThreadFactory_default() {
- ThreadFactory factory = MoreExecutors.platformThreadFactory();
- assertNotNull(factory);
- // Executors#defaultThreadFactory() may return a new instance each time.
- assertEquals(factory.getClass(), Executors.defaultThreadFactory().getClass());
- }
-
- public void testExecutors_nullCheck() throws Exception {
- new ClassSanityTester()
- .forAllPublicStaticMethods(MoreExecutors.class)
- .thatReturn(Executor.class)
- .testNulls();
- }
-
- private static class TestApplication extends Application {
- private final List<Thread> hooks = Lists.newArrayList();
-
- @Override synchronized void addShutdownHook(Thread hook) {
- hooks.add(hook);
- }
-
- synchronized void shutdown() throws InterruptedException {
- for (Thread hook : hooks) {
- hook.start();
- }
- for (Thread hook : hooks) {
- hook.join();
- }
- }
- }
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java b/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java
deleted file mode 100644
index d4da81a..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.testing.AbstractPackageSanityTests;
-
-/**
- * Basic sanity tests for the entire package.
- *
- * @author Ben Yu
- */
-
-public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java
deleted file mode 100644
index 4768213..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.collect.Lists;
-import com.google.common.testing.NullPointerTester;
-import com.google.common.testing.NullPointerTester.Visibility;
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for RateLimiter.
- *
- * @author Dimitris Andreou
- */
-public class RateLimiterTest extends TestCase {
- /**
- * The ticker gathers events and presents them as strings.
- * R0.6 means a delay of 0.6 seconds caused by the (R)ateLimiter
- * U1.0 means the (U)ser caused the ticker to sleep for a second.
- */
- private final FakeTicker ticker = new FakeTicker();
-
- public void testSimple() {
- RateLimiter limiter = RateLimiter.create(ticker, 5.0);
- limiter.acquire(); // R0.00, since it's the first request
- limiter.acquire(); // R0.20
- limiter.acquire(); // R0.20
- assertEvents("R0.00", "R0.20", "R0.20");
- }
-
- public void testImmediateTryAcquire() {
- RateLimiter r = RateLimiter.create(1);
- assertTrue("Unable to acquire initial permit", r.tryAcquire());
- assertFalse("Capable of acquiring secondary permit", r.tryAcquire());
- }
-
- public void testSimpleRateUpdate() {
- RateLimiter limiter = RateLimiter.create(5.0, 5, TimeUnit.SECONDS);
- assertEquals(5.0, limiter.getRate());
- limiter.setRate(10.0);
- assertEquals(10.0, limiter.getRate());
-
- try {
- limiter.setRate(0.0);
- fail();
- } catch (IllegalArgumentException ok) {}
- try {
- limiter.setRate(-10.0);
- fail();
- } catch (IllegalArgumentException ok) {}
- }
-
- public void testSimpleWithWait() {
- RateLimiter limiter = RateLimiter.create(ticker, 5.0);
- limiter.acquire(); // R0.00
- ticker.sleepMillis(200); // U0.20, we are ready for the next request...
- limiter.acquire(); // R0.00, ...which is granted immediately
- limiter.acquire(); // R0.20
- assertEvents("R0.00", "U0.20", "R0.00", "R0.20");
- }
-
- public void testOneSecondBurst() {
- RateLimiter limiter = RateLimiter.create(ticker, 5.0);
- ticker.sleepMillis(1000); // max capacity reached
- ticker.sleepMillis(1000); // this makes no difference
- limiter.acquire(1); // R0.00, since it's the first request
-
- limiter.acquire(1); // R0.00, from capacity
- limiter.acquire(3); // R0.00, from capacity
- limiter.acquire(1); // R0.00, concluding a burst of 5 permits
-
- limiter.acquire(); // R0.20, capacity exhausted
- assertEvents("U1.00", "U1.00",
- "R0.00", "R0.00", "R0.00", "R0.00", // first request and burst
- "R0.20");
- }
-
- public void testWarmUp() {
- RateLimiter limiter = RateLimiter.create(ticker, 2.0, 4000, TimeUnit.MILLISECONDS);
- for (int i = 0; i < 8; i++) {
- limiter.acquire(); // #1
- }
- ticker.sleepMillis(500); // #2: to repay for the last acquire
- ticker.sleepMillis(4000); // #3: becomes cold again
- for (int i = 0; i < 8; i++) {
- limiter.acquire(); // // #4
- }
- ticker.sleepMillis(500); // #5: to repay for the last acquire
- ticker.sleepMillis(2000); // #6: didn't get cold! It would take another 2 seconds to go cold
- for (int i = 0; i < 8; i++) {
- limiter.acquire(); // #7
- }
- assertEvents(
- "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
- "U0.50", // #2
- "U4.00", // #3
- "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #4
- "U0.50", // #5
- "U2.00", // #6
- "R0.00, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50"); // #7
- }
-
- public void testWarmUpAndUpdate() {
- RateLimiter limiter = RateLimiter.create(ticker, 2.0, 4000, TimeUnit.MILLISECONDS);
- for (int i = 0; i < 8; i++) {
- limiter.acquire(); // // #1
- }
- ticker.sleepMillis(4500); // #2: back to cold state (warmup period + repay last acquire)
- for (int i = 0; i < 3; i++) { // only three steps, we're somewhere in the warmup period
- limiter.acquire(); // #3
- }
-
- limiter.setRate(4.0); // double the rate!
- limiter.acquire(); // #4, we repay the debt of the last acquire (imposed by the old rate)
- for (int i = 0; i < 4; i++) {
- limiter.acquire(); // #5
- }
- ticker.sleepMillis(4250); // #6, back to cold state (warmup period + repay last acquire)
- for (int i = 0; i < 11; i++) {
- limiter.acquire(); // #7, showing off the warmup starting from totally cold
- }
-
- // make sure the areas (times) remain the same, while permits are different
- assertEvents(
- "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
- "U4.50", // #2
- "R0.00, R1.38, R1.13", // #3, after that the rate changes
- "R0.88", // #4, this is what the throttling would be with the old rate
- "R0.34, R0.28, R0.25, R0.25", // #5
- "U4.25", // #6
- "R0.00, R0.72, R0.66, R0.59, R0.53, R0.47, R0.41", // #7
- "R0.34, R0.28, R0.25, R0.25"); // #7 (cont.), note, this matches #5
- }
-
- public void testBursty() {
- RateLimiter limiter = RateLimiter.createBursty(ticker, 1.0, 10);
- ticker.sleepMillis(10000); // reach full capacity
- limiter.acquire(11); // all these are served in a burst (10 + 1 by borrowing from the future)
- limiter.acquire(1); // out of capacity, we have to wait
- limiter.acquire(1); // and wait
- ticker.sleepMillis(3000); // fill up 3 permits
- limiter.acquire(5); // we had 3 ready, thus we borrow 2 permits
- limiter.acquire(1); // this acquire() will also repay for the previous acquire()
- assertEvents(
- "U10.00",
- "R0.00", // 10 permits grabbed
- "R1.00", "R1.00", // 1 and 1
- "U3.00", "R0.00", // 5 grabbed
- "R3.00" // 1 grabbed
- );
- }
-
- public void testBurstyAndUpdate() {
- RateLimiter rateLimiter = RateLimiter.create(ticker, 1.0);
- rateLimiter.acquire(1); // no wait
- rateLimiter.acquire(1); // R1.00, to repay previous
-
- rateLimiter.setRate(2.0); // update the rate!
-
- rateLimiter.acquire(1); // R1.00, to repay previous (the previous was under the old rate!)
- rateLimiter.acquire(2); // R0.50, to repay previous (now the rate takes effect)
- rateLimiter.acquire(4); // R1.00, to repay previous
- rateLimiter.acquire(1); // R2.00, to repay previous
- assertEvents("R0.00", "R1.00", "R1.00", "R0.50", "R1.00", "R2.00");
- }
-
- public void testTimeWrapping() {
- ticker.instant = Long.MAX_VALUE - TimeUnit.SECONDS.toNanos(1); // 1 second before max value
- RateLimiter limiter = RateLimiter.create(ticker, 1.0);
- for (int i = 0; i < 4; i++) {
- limiter.acquire();
- }
- // Without protection from overflow, the last wait value would have been huge,
- // because "now" would have wrapped into a value near MIN_VALUE, and the limiter would think
- // that the next request should be admitted far into the future
- assertEvents("R0.00", "R1.00", "R1.00", "R1.00");
- }
-
- public void testTryGate() {
- RateLimiter limiter = RateLimiter.create(ticker, 5.0);
- assertTrue(limiter.tryAcquire(0, TimeUnit.SECONDS));
- assertFalse(limiter.tryAcquire(0, TimeUnit.SECONDS));
- assertFalse(limiter.tryAcquire(0, TimeUnit.SECONDS));
- ticker.sleepMillis(100);
- assertFalse(limiter.tryAcquire(0, TimeUnit.SECONDS));
- }
-
- public void testSimpleWeights() {
- RateLimiter rateLimiter = RateLimiter.create(ticker, 1.0);
- rateLimiter.acquire(1); // no wait
- rateLimiter.acquire(1); // R1.00, to repay previous
- rateLimiter.acquire(2); // R1.00, to repay previous
- rateLimiter.acquire(4); // R2.00, to repay previous
- rateLimiter.acquire(8); // R4.00, to repay previous
- rateLimiter.acquire(1); // R8.00, to repay previous
- assertEvents("R0.00", "R1.00", "R1.00", "R2.00", "R4.00", "R8.00");
- }
-
- public void testInfinity_Bursty() {
- RateLimiter limiter = RateLimiter.create(ticker, Double.POSITIVE_INFINITY);
- limiter.acquire(Integer.MAX_VALUE / 4);
- limiter.acquire(Integer.MAX_VALUE / 2);
- limiter.acquire(Integer.MAX_VALUE);
- assertEvents("R0.00", "R0.00", "R0.00"); // no wait, infinite rate!
-
- limiter.setRate(1.0);
- limiter.acquire();
- limiter.acquire();
- limiter.acquire();
- assertEvents("R0.00", "R1.00", "R1.00"); // we repay the last request (but that had no cost)
- // and then we go to 1 second per request mode
-
- limiter.setRate(Double.POSITIVE_INFINITY);
- limiter.acquire();
- limiter.acquire();
- limiter.acquire();
- assertEvents("R1.00", "R0.00", "R0.00"); // we repay the last request (1sec), then back to +oo
- }
-
- public void testInfinity_WarmUp() {
- RateLimiter limiter = RateLimiter.create(
- ticker, Double.POSITIVE_INFINITY, 10, TimeUnit.SECONDS);
- limiter.acquire(Integer.MAX_VALUE / 4);
- limiter.acquire(Integer.MAX_VALUE / 2);
- limiter.acquire(Integer.MAX_VALUE);
- assertEvents("R0.00", "R0.00", "R0.00");
-
- limiter.setRate(1.0);
- limiter.acquire();
- limiter.acquire();
- limiter.acquire();
- assertEvents("R0.00", "R1.00", "R1.00");
-
- limiter.setRate(Double.POSITIVE_INFINITY);
- limiter.acquire();
- limiter.acquire();
- limiter.acquire();
- assertEvents("R1.00", "R0.00", "R0.00");
- }
-
- /**
- * Make sure that bursts can never go above 1-second-worth-of-work for the current
- * rate, even when we change the rate.
- */
- public void testWeNeverGetABurstMoreThanOneSec() {
- RateLimiter limiter = RateLimiter.create(ticker, 1.0);
- int[] rates = { 1000, 1, 10, 1000000, 10, 1};
- for (int rate : rates) {
- int oneSecWorthOfWork = rate;
- ticker.sleepMillis(rate * 1000);
- limiter.setRate(rate);
- long burst = measureTotalTimeMillis(limiter, oneSecWorthOfWork, new Random());
- // we allow one second worth of work to go in a burst (i.e. take less than a second)
- assertTrue(burst <= 1000);
- long afterBurst = measureTotalTimeMillis(limiter, oneSecWorthOfWork, new Random());
- // but work beyond that must take at least one second
- assertTrue(afterBurst >= 1000);
- }
- }
-
- /**
- * This neat test shows that no matter what weights we use in our requests, if we push X
- * amount of permits in a cool state, where X = rate * timeToCoolDown, and we have
- * specified a timeToWarmUp() period, it will cost as the prescribed amount of time. E.g.,
- * calling [acquire(5), acquire(1)] takes exactly the same time as
- * [acquire(2), acquire(3), acquire(1)].
- */
- public void testTimeToWarmUpIsHonouredEvenWithWeights() {
- Random random = new Random();
- int maxPermits = 10;
- double[] qpsToTest = { 4.0, 2.0, 1.0, 0.5, 0.1 };
- for (int trial = 0; trial < 100; trial++) {
- for (double qps : qpsToTest) {
- // Since we know that: maxPermits = 0.5 * warmup / stableInterval;
- // then if maxPermits == 10, we have:
- // warmupSeconds = 20 / qps
- long warmupMillis = (long) ((2 * maxPermits / qps) * 1000.0);
- RateLimiter rateLimiter = RateLimiter.create(
- ticker, qps, warmupMillis, TimeUnit.MILLISECONDS);
- assertEquals(warmupMillis, measureTotalTimeMillis(rateLimiter, maxPermits, random));
- }
- }
- }
-
- public void testNulls() {
- NullPointerTester tester = new NullPointerTester()
- .setDefault(RateLimiter.SleepingTicker.class, ticker);
- tester.testStaticMethods(RateLimiter.class, Visibility.PACKAGE);
- tester.testInstanceMethods(RateLimiter.create(ticker, 5.0), Visibility.PACKAGE);
- }
-
- private long measureTotalTimeMillis(RateLimiter rateLimiter, int permits, Random random) {
- long startTime = ticker.instant;
- while (permits > 0) {
- int nextPermitsToAcquire = Math.max(1, random.nextInt(permits));
- permits -= nextPermitsToAcquire;
- rateLimiter.acquire(nextPermitsToAcquire);
- }
- rateLimiter.acquire(1); // to repay for any pending debt
- return TimeUnit.NANOSECONDS.toMillis(ticker.instant - startTime);
- }
-
- private void assertEvents(String... events) {
- assertEquals(Arrays.asList(events).toString(), ticker.readEventsAndClear());
- }
-
- private static class FakeTicker extends RateLimiter.SleepingTicker {
- long instant = 0L;
- final List<String> events = Lists.newArrayList();
-
- @Override
- public long read() {
- return instant;
- }
-
- void sleepMillis(int millis) {
- sleepMicros("U", TimeUnit.MILLISECONDS.toMicros(millis));
- }
-
- void sleepMicros(String caption, long micros) {
- instant += TimeUnit.MICROSECONDS.toNanos(micros);
- events.add(caption + String.format("%3.2f", (micros / 1000000.0)));
- }
-
- @Override
- void sleepMicrosUninterruptibly(long micros) {
- sleepMicros("R", micros);
- }
-
- String readEventsAndClear() {
- try {
- return events.toString();
- } finally {
- events.clear();
- }
- }
-
- @Override
- public String toString() {
- return events.toString();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java
index 3651934..1db434a 100644
--- a/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java
@@ -183,7 +183,7 @@ public class SimpleTimeLimiterTest extends TestCase {
}
@SuppressWarnings("serial")
- public static class SampleException extends Exception {}
+ public static class SampleException extends Exception { }
public static class SampleImpl implements Sample {
boolean finished;
diff --git a/guava-tests/test/com/google/common/util/concurrent/StripedTest.java b/guava-tests/test/com/google/common/util/concurrent/StripedTest.java
deleted file mode 100644
index 0a4a655..0000000
--- a/guava-tests/test/com/google/common/util/concurrent/StripedTest.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import static com.google.common.collect.Iterables.concat;
-
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Sets;
-import com.google.common.testing.GcFinalization;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.Lock;
-
-/**
- * Tests for Striped.
- *
- * @author Dimitris Andreou
- */
-public class StripedTest extends TestCase {
- private static List<Striped<?>> strongImplementations() {
- return ImmutableList.of(
- Striped.readWriteLock(100),
- Striped.readWriteLock(256),
- Striped.lock(100),
- Striped.lock(256),
- Striped.semaphore(100, 1),
- Striped.semaphore(256, 1));
- }
-
- private static List<Striped<?>> weakImplementations() {
- return ImmutableList.of(
- Striped.lazyWeakReadWriteLock(50),
- Striped.lazyWeakReadWriteLock(64),
- Striped.lazyWeakLock(50),
- Striped.lazyWeakLock(64),
- Striped.lazyWeakSemaphore(50, 1),
- Striped.lazyWeakSemaphore(64, 1));
- }
-
- private static Iterable<Striped<?>> allImplementations() {
- return concat(strongImplementations(), weakImplementations());
- }
-
- public void testNull() throws Exception {
- for (Striped<?> striped : allImplementations()) {
- new NullPointerTester().testAllPublicInstanceMethods(striped);
- }
- }
-
- public void testSizes() {
- // not bothering testing all variations, since we know they share implementations
- assertTrue(Striped.lock(100).size() >= 100);
- assertTrue(Striped.lock(256).size() == 256);
- assertTrue(Striped.lazyWeakLock(100).size() >= 100);
- assertTrue(Striped.lazyWeakLock(256).size() == 256);
- }
-
- public void testWeakImplementations() {
- for (Striped<?> striped : weakImplementations()) {
- WeakReference<Object> weakRef = new WeakReference<Object>(striped.get(new Object()));
- GcFinalization.awaitClear(weakRef);
- }
- }
-
- public void testStrongImplementations() {
- for (Striped<?> striped : strongImplementations()) {
- WeakReference<Object> weakRef = new WeakReference<Object>(striped.get(new Object()));
- WeakReference<Object> garbage = new WeakReference<Object>(new Object());
- GcFinalization.awaitClear(garbage);
- assertNotNull(weakRef.get());
- }
- }
-
- public void testMaximalWeakStripedLock() {
- Striped<Lock> stripedLock = Striped.lazyWeakLock(Integer.MAX_VALUE);
- for (int i = 0; i < 10000; i++) {
- stripedLock.get(new Object()).lock();
- // nothing special (e.g. an exception) happens
- }
- }
-
- public void testBulkGetReturnsSorted() {
- for (Striped<?> striped : allImplementations()) {
- Map<Object, Integer> indexByLock = Maps.newHashMap();
- for (int i = 0; i < striped.size(); i++) {
- indexByLock.put(striped.getAt(i), i);
- }
-
- // ensure that bulkGet returns locks in monotonically increasing order
- for (int objectsNum = 1; objectsNum <= striped.size() * 2; objectsNum++) {
- Set<Object> objects = Sets.newHashSetWithExpectedSize(objectsNum);
- for (int i = 0; i < objectsNum; i++) {
- objects.add(new Object());
- }
-
- Iterable<?> locks = striped.bulkGet(objects);
- assertTrue(Ordering.natural().onResultOf(Functions.forMap(indexByLock)).isOrdered(locks));
-
- // check idempotency
- Iterable<?> locks2 = striped.bulkGet(objects);
- assertEquals(Lists.newArrayList(locks), Lists.newArrayList(locks2));
- }
- }
- }
-
- /**
- * Checks idempotency, and that we observe the promised number of stripes.
- */
- public void testBasicInvariants() {
- for (Striped<?> striped : allImplementations()) {
- assertBasicInvariants(striped);
- }
- }
-
- private static void assertBasicInvariants(Striped<?> striped) {
- Set<Object> observed = Sets.newIdentityHashSet(); // for the sake of weakly referenced locks.
- // this gets the stripes with #getAt(index)
- for (int i = 0; i < striped.size(); i++) {
- Object object = striped.getAt(i);
- assertNotNull(object);
- assertSame(object, striped.getAt(i)); // idempotent
- observed.add(object);
- }
- assertTrue("All stripes observed", observed.size() == striped.size());
-
- // this uses #get(key), makes sure an already observed stripe is returned
- for (int i = 0; i < striped.size() * 100; i++) {
- assertTrue(observed.contains(striped.get(new Object())));
- }
-
- try {
- striped.getAt(-1);
- fail();
- } catch (RuntimeException expected) {}
-
- try {
- striped.getAt(striped.size());
- fail();
- } catch (RuntimeException expected) {}
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java b/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java
index d26ba63..ec850d3 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java
@@ -16,7 +16,7 @@
package com.google.common.util.concurrent;
-import static org.truth0.Truth.ASSERT;
+import static org.junit.contrib.truth.Truth.ASSERT;
import com.google.common.testing.NullPointerTester;
@@ -93,20 +93,11 @@ public class ThreadFactoryBuilderTest extends TestCase {
assertTrue(thread.getName().matches("^pool-\\d+-thread-" + threadId + "$"));
}
- public void testNameFormatWithPercentS_custom() {
- String format = "super-duper-thread-%s";
- ThreadFactory factory = builder.setNameFormat(format).build();
- for (int i = 0; i < 11; i++) {
- assertEquals(String.format(format, i),
- factory.newThread(monitoredRunnable).getName());
- }
- }
-
- public void testNameFormatWithPercentD_custom() {
- String format = "super-duper-thread-%d";
- ThreadFactory factory = builder.setNameFormat(format).build();
- for (int i = 0; i < 11; i++) {
- assertEquals(String.format(format, i),
+ public void testNameFormat_custom() {
+ final String NAME_FORMAT = "super duper thread #%s";
+ ThreadFactory factory = builder.setNameFormat(NAME_FORMAT).build();
+ for (int i = 0; i < 10; i++) {
+ assertEquals(String.format(NAME_FORMAT, i),
factory.newThread(monitoredRunnable).getName());
}
}
@@ -206,7 +197,7 @@ public class ThreadFactoryBuilderTest extends TestCase {
assertTrue(completed);
}
- public void testNulls() {
+ public void testNulls() throws Exception {
NullPointerTester npTester = new NullPointerTester();
npTester.testAllPublicConstructors(ThreadFactoryBuilder.class);
npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class);
diff --git a/guava/pom.xml b/guava/pom.xml
index 32e6b76..14709e9 100644
--- a/guava/pom.xml
+++ b/guava/pom.xml
@@ -5,87 +5,82 @@
<parent>
<groupId>com.google.guava</groupId>
<artifactId>guava-parent</artifactId>
- <version>14.0.1</version>
+ <version>11.0.2</version>
</parent>
<artifactId>guava</artifactId>
<name>Guava: Google Core Libraries for Java</name>
- <packaging>bundle</packaging>
<description>
Guava is a suite of core and expanded libraries that include
utility classes, google's collections, io classes, and much
much more.
- Guava has two code dependencies - javax.annotation
- per the JSR-305 spec and javax.inject per the JSR-330 spec.
+ This project is a complete packaging of all the Guava libraries
+ into a single jar. Individual portions of Guava can be used
+ by downloading the appropriate module and its dependencies.
+
+ Guava (complete) has only one code dependency - javax.annotation,
+ per the JSR-305 spec.
</description>
<dependencies>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
- <scope>provided</scope>
</dependency>
<dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>guava-bootstrap</artifactId>
+ <version>${project.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
<plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.7</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <id>bundle-manifest</id>
- <phase>process-classes</phase>
- <goals>
- <goal>manifest</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <instructions>
- <Export-Package>!com.google.common.base.internal,com.google.common.*</Export-Package>
- <Import-Package>
- javax.annotation;resolution:=optional,
- javax.inject;resolution:=optional,
- sun.misc.*;resolution:=optional
- </Import-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
- <source>1.6</source>
- <target>1.6</target>
+ <source>1.5</source>
+ <target>1.5</target>
+ <!-- Prepend guava-bootstrap to avoid an API incompatibility between JDK5 and JDK6 -->
+ <compilerArgument>-Xbootclasspath/p:${project.build.directory}/dependency/guava-bootstrap-${project.version}.jar</compilerArgument>
</configuration>
</plugin>
<plugin>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.1.2</version>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.3</version>
<executions>
<execution>
- <id>attach-sources</id>
- <phase>post-integration-test</phase>
- <goals><goal>jar</goal></goals>
+ <id>prep-guava-bootstrap</id>
+ <phase>process-sources</phase>
+ <goals><goal>copy-dependencies</goal></goals>
+ <configuration>
+ <includeArtifactIds>guava-bootstrap</includeArtifactIds>
+ <excludeTransitive>true</excludeTransitive>
+ <includeScope>provided</includeScope>
+ </configuration>
</execution>
</executions>
</plugin>
<plugin>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.8</version>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.1.2</version>
<executions>
<execution>
- <id>attach-docs</id>
- <phase>post-integration-test</phase>
- <goals><goal>jar</goal></goals>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
</execution>
</executions>
</plugin>
@@ -96,13 +91,13 @@
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
- <artifactId>java16-sun</artifactId>
+ <artifactId>java15-sun</artifactId>
<version>1.0</version>
</signature>
</configuration>
<executions>
<execution>
- <id>check-java16-sun</id>
+ <id>check-java15</id>
<phase>test</phase>
<goals>
<goal>check</goal>
@@ -127,12 +122,12 @@
</configuration>
<executions>
<execution>
- <id>generate-javadoc-site-report</id>
+ <id>generate-javadoc</id>
<phase>site</phase>
<goals><goal>javadoc</goal></goals>
</execution>
<execution>
- <id>generate-jdiff-site-report</id>
+ <id>generate-jdiff</id>
<phase>site</phase>
<goals><goal>javadoc</goal></goals>
<configuration>
diff --git a/guava/src/com/google/common/annotations/Beta.java b/guava/src/com/google/common/annotations/Beta.java
index 5eefe9a..07009b0 100644
--- a/guava/src/com/google/common/annotations/Beta.java
+++ b/guava/src/com/google/common/annotations/Beta.java
@@ -26,15 +26,7 @@ import java.lang.annotation.Target;
* Signifies that a public API (public class, method or field) is subject to
* incompatible changes, or even removal, in a future release. An API bearing
* this annotation is exempt from any compatibility guarantees made by its
- * containing library. Note that the presence of this annotation implies nothing
- * about the quality or performance of the API in question, only the fact that
- * it is not "API-frozen."
- *
- * <p>It is generally safe for <i>applications</i> to depend on beta APIs, at
- * the cost of some extra work during upgrades. However it is generally
- * inadvisable for <i>libraries</i> (which get included on users' CLASSPATHs,
- * outside the library developers' control) to do so.
- *
+ * containing library.
*
* @author Kevin Bourrillion
*/
@@ -47,4 +39,5 @@ import java.lang.annotation.Target;
ElementType.TYPE})
@Documented
@GwtCompatible
+@Beta
public @interface Beta {}
diff --git a/guava/src/com/google/common/annotations/GwtIncompatible.java b/guava/src/com/google/common/annotations/GwtIncompatible.java
index a56d746..43ae705 100644
--- a/guava/src/com/google/common/annotations/GwtIncompatible.java
+++ b/guava/src/com/google/common/annotations/GwtIncompatible.java
@@ -36,12 +36,11 @@ import java.lang.annotation.Target;
* @author Charles Fry
*/
@Retention(RetentionPolicy.CLASS)
-@Target({
- ElementType.TYPE, ElementType.METHOD,
- ElementType.CONSTRUCTOR, ElementType.FIELD })
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD })
@Documented
@GwtCompatible
public @interface GwtIncompatible {
+
/**
* Describes why the annotated element is incompatible with GWT. Since this is
* generally due to a dependence on a type/method which GWT doesn't support,
@@ -49,4 +48,5 @@ public @interface GwtIncompatible {
* "Class.isInstance".
*/
String value();
+
}
diff --git a/guava/src/com/google/common/annotations/VisibleForTesting.java b/guava/src/com/google/common/annotations/VisibleForTesting.java
index 6f867db..e591719 100644
--- a/guava/src/com/google/common/annotations/VisibleForTesting.java
+++ b/guava/src/com/google/common/annotations/VisibleForTesting.java
@@ -17,8 +17,8 @@
package com.google.common.annotations;
/**
- * Annotates a program element that exists, or is more widely visible than
- * otherwise necessary, only for use in test code.
+ * An annotation that indicates that the visibility of a type or member has
+ * been relaxed to make the code testable.
*
* @author Johannes Henkel
*/
diff --git a/guava/src/com/google/common/base/Absent.java b/guava/src/com/google/common/base/Absent.java
deleted file mode 100644
index a182236..0000000
--- a/guava/src/com/google/common/base/Absent.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of an {@link Optional} not containing a reference.
- */
-@GwtCompatible
-final class Absent extends Optional<Object> {
- static final Absent INSTANCE = new Absent();
-
- private Absent() {}
-
- @Override public boolean isPresent() {
- return false;
- }
-
- @Override public Object get() {
- throw new IllegalStateException("Optional.get() cannot be called on an absent value");
- }
-
- @Override public Object or(Object defaultValue) {
- return checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
- }
-
- @SuppressWarnings("unchecked") // safe covariant cast
- @Override public Optional<Object> or(Optional<?> secondChoice) {
- return (Optional) checkNotNull(secondChoice);
- }
-
- @Override public Object or(Supplier<?> supplier) {
- return checkNotNull(supplier.get(),
- "use Optional.orNull() instead of a Supplier that returns null");
- }
-
- @Override @Nullable public Object orNull() {
- return null;
- }
-
- @Override public Set<Object> asSet() {
- return Collections.emptySet();
- }
-
- @Override public <V> Optional<V> transform(Function<Object, V> function) {
- checkNotNull(function);
- return Optional.absent();
- }
-
- @Override public boolean equals(@Nullable Object object) {
- return object == this;
- }
-
- @Override public int hashCode() {
- return 0x598df91c;
- }
-
- @Override public String toString() {
- return "Optional.absent()";
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
-
- private static final long serialVersionUID = 0;
-}
diff --git a/guava/src/com/google/common/base/Ascii.java b/guava/src/com/google/common/base/Ascii.java
index 3ccd0fe..a23a11f 100644
--- a/guava/src/com/google/common/base/Ascii.java
+++ b/guava/src/com/google/common/base/Ascii.java
@@ -16,6 +16,7 @@
package com.google.common.base;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
/**
@@ -213,7 +214,7 @@ public final class Ascii {
public static final byte DLE = 16;
/**
- * Device Control 1. Characters for the control
+ * Device Controls: Characters for the control
* of ancillary devices associated with data processing or
* telecommunication systems, more especially switching devices "on" or
* "off." (If a single "stop" control is required to interrupt or turn
@@ -224,7 +225,7 @@ public final class Ascii {
public static final byte DC1 = 17; // aka XON
/**
- * Transmission On: Although originally defined as DC1, this ASCII
+ * Transmission on/off: Although originally defined as DC1, this ASCII
* control character is now better known as the XON code used for software
* flow control in serial communications. The main use is restarting
* the transmission after the communication has been stopped by the XOFF
@@ -235,40 +236,28 @@ public final class Ascii {
public static final byte XON = 17; // aka DC1
/**
- * Device Control 2. Characters for the control
- * of ancillary devices associated with data processing or
- * telecommunication systems, more especially switching devices "on" or
- * "off." (If a single "stop" control is required to interrupt or turn
- * off ancillary devices, DC4 is the preferred assignment.)
+ * @see #DC1
*
* @since 8.0
*/
public static final byte DC2 = 18;
/**
- * Device Control 3. Characters for the control
- * of ancillary devices associated with data processing or
- * telecommunication systems, more especially switching devices "on" or
- * "off." (If a single "stop" control is required to interrupt or turn
- * off ancillary devices, DC4 is the preferred assignment.)
+ * @see #DC1
*
* @since 8.0
*/
public static final byte DC3 = 19; // aka XOFF
/**
- * Transmission off. See {@link #XON} for explanation.
+ * Transmission off. @see #XON
*
* @since 8.0
*/
public static final byte XOFF = 19; // aka DC3
/**
- * Device Control 4. Characters for the control
- * of ancillary devices associated with data processing or
- * telecommunication systems, more especially switching devices "on" or
- * "off." (If a single "stop" control is required to interrupt or turn
- * off ancillary devices, DC4 is the preferred assignment.)
+ * @see #DC1
*
* @since 8.0
*/
@@ -341,7 +330,7 @@ public final class Ascii {
public static final byte ESC = 27;
/**
- * File Separator: These four information separators may be
+ * File/Group/Record/Unit Separator: These information separators may be
* used within data in optional fashion, except that their hierarchical
* relationship shall be: FS is the most inclusive, then GS, then RS,
* and US is least inclusive. (The content and length of a File, Group,
@@ -352,33 +341,21 @@ public final class Ascii {
public static final byte FS = 28;
/**
- * Group Separator: These four information separators may be
- * used within data in optional fashion, except that their hierarchical
- * relationship shall be: FS is the most inclusive, then GS, then RS,
- * and US is least inclusive. (The content and length of a File, Group,
- * Record, or Unit are not specified.)
+ * @see #FS
*
* @since 8.0
*/
public static final byte GS = 29;
/**
- * Record Separator: These four information separators may be
- * used within data in optional fashion, except that their hierarchical
- * relationship shall be: FS is the most inclusive, then GS, then RS,
- * and US is least inclusive. (The content and length of a File, Group,
- * Record, or Unit are not specified.)
+ * @see #FS
*
* @since 8.0
*/
public static final byte RS = 30;
/**
- * Unit Separator: These four information separators may be
- * used within data in optional fashion, except that their hierarchical
- * relationship shall be: FS is the most inclusive, then GS, then RS,
- * and US is least inclusive. (The content and length of a File, Group,
- * Record, or Unit are not specified.)
+ * @see #FS
*
* @since 8.0
*/
@@ -412,16 +389,18 @@ public final class Ascii {
/**
* The minimum value of an ASCII character.
*
- * @since 9.0 (was type {@code int} before 12.0)
+ * @since 9.0
*/
- public static final char MIN = 0;
+ @Beta
+ public static final int MIN = 0;
/**
* The maximum value of an ASCII character.
*
- * @since 9.0 (was type {@code int} before 12.0)
+ * @since 9.0
*/
- public static final char MAX = 127;
+ @Beta
+ public static final int MAX = 127;
/**
* Returns a copy of the input string in which all {@linkplain #isUpperCase(char) uppercase ASCII
@@ -429,21 +408,10 @@ public final class Ascii {
* modification.
*/
public static String toLowerCase(String string) {
- return toLowerCase((CharSequence) string);
- }
-
- /**
- * Returns a copy of the input character sequence in which all {@linkplain #isUpperCase(char)
- * uppercase ASCII characters} have been converted to lowercase. All other characters are copied
- * without modification.
- *
- * @since 14.0
- */
- public static String toLowerCase(CharSequence chars) {
- int length = chars.length();
+ int length = string.length();
StringBuilder builder = new StringBuilder(length);
for (int i = 0; i < length; i++) {
- builder.append(toLowerCase(chars.charAt(i)));
+ builder.append(toLowerCase(string.charAt(i)));
}
return builder.toString();
}
@@ -455,28 +423,17 @@ public final class Ascii {
public static char toLowerCase(char c) {
return isUpperCase(c) ? (char) (c ^ 0x20) : c;
}
-
+
/**
* Returns a copy of the input string in which all {@linkplain #isLowerCase(char) lowercase ASCII
* characters} have been converted to uppercase. All other characters are copied without
* modification.
*/
public static String toUpperCase(String string) {
- return toUpperCase((CharSequence) string);
- }
-
- /**
- * Returns a copy of the input character sequence in which all {@linkplain #isLowerCase(char)
- * lowercase ASCII characters} have been converted to uppercase. All other characters are copied
- * without modification.
- *
- * @since 14.0
- */
- public static String toUpperCase(CharSequence chars) {
- int length = chars.length();
+ int length = string.length();
StringBuilder builder = new StringBuilder(length);
for (int i = 0; i < length; i++) {
- builder.append(toUpperCase(chars.charAt(i)));
+ builder.append(toUpperCase(string.charAt(i)));
}
return builder.toString();
}
diff --git a/guava/src/com/google/common/base/CaseFormat.java b/guava/src/com/google/common/base/CaseFormat.java
index b8b02c9..8ef7c5c 100644
--- a/guava/src/com/google/common/base/CaseFormat.java
+++ b/guava/src/com/google/common/base/CaseFormat.java
@@ -16,8 +16,6 @@
package com.google.common.base;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.GwtCompatible;
/**
@@ -31,74 +29,27 @@ public enum CaseFormat {
/**
* Hyphenated variable naming convention, e.g., "lower-hyphen".
*/
- LOWER_HYPHEN(CharMatcher.is('-'), "-") {
- @Override String normalizeWord(String word) {
- return Ascii.toLowerCase(word);
- }
- @Override String convert(CaseFormat format, String s) {
- if (format == LOWER_UNDERSCORE) {
- return s.replace('-', '_');
- }
- if (format == UPPER_UNDERSCORE) {
- return Ascii.toUpperCase(s.replace('-', '_'));
- }
- return super.convert(format, s);
- }
- },
+ LOWER_HYPHEN(CharMatcher.is('-'), "-"),
/**
* C++ variable naming convention, e.g., "lower_underscore".
*/
- LOWER_UNDERSCORE(CharMatcher.is('_'), "_") {
- @Override String normalizeWord(String word) {
- return Ascii.toLowerCase(word);
- }
- @Override String convert(CaseFormat format, String s) {
- if (format == LOWER_HYPHEN) {
- return s.replace('_', '-');
- }
- if (format == UPPER_UNDERSCORE) {
- return Ascii.toUpperCase(s);
- }
- return super.convert(format, s);
- }
- },
+ LOWER_UNDERSCORE(CharMatcher.is('_'), "_"),
/**
* Java variable naming convention, e.g., "lowerCamel".
*/
- LOWER_CAMEL(CharMatcher.inRange('A', 'Z'), "") {
- @Override String normalizeWord(String word) {
- return firstCharOnlyToUpper(word);
- }
- },
+ LOWER_CAMEL(CharMatcher.inRange('A', 'Z'), ""),
/**
* Java and C++ class naming convention, e.g., "UpperCamel".
*/
- UPPER_CAMEL(CharMatcher.inRange('A', 'Z'), "") {
- @Override String normalizeWord(String word) {
- return firstCharOnlyToUpper(word);
- }
- },
+ UPPER_CAMEL(CharMatcher.inRange('A', 'Z'), ""),
/**
* Java and C++ constant naming convention, e.g., "UPPER_UNDERSCORE".
*/
- UPPER_UNDERSCORE(CharMatcher.is('_'), "_") {
- @Override String normalizeWord(String word) {
- return Ascii.toUpperCase(word);
- }
- @Override String convert(CaseFormat format, String s) {
- if (format == LOWER_HYPHEN) {
- return Ascii.toLowerCase(s.replace('_', '-'));
- }
- if (format == LOWER_UNDERSCORE) {
- return Ascii.toLowerCase(s);
- }
- return super.convert(format, s);
- }
- };
+ UPPER_UNDERSCORE(CharMatcher.is('_'), "_");
private final CharMatcher wordBoundary;
private final String wordSeparator;
@@ -109,21 +60,51 @@ public enum CaseFormat {
}
/**
- * Converts the specified {@code String str} from this format to the specified {@code format}. A
- * "best effort" approach is taken; if {@code str} does not conform to the assumed format, then
- * the behavior of this method is undefined but we make a reasonable effort at converting anyway.
+ * Converts the specified {@code String s} from this format to the specified {@code format}. A
+ * "best effort" approach is taken; if {@code s} does not conform to the assumed format, then the
+ * behavior of this method is undefined but we make a reasonable effort at converting anyway.
*/
- public final String to(CaseFormat format, String str) {
- checkNotNull(format);
- checkNotNull(str);
- return (format == this) ? str : convert(format, str);
- }
+ public String to(CaseFormat format, String s) {
+ if (format == null) {
+ throw new NullPointerException();
+ }
+ if (s == null) {
+ throw new NullPointerException();
+ }
- /**
- * Enum values can override for performance reasons.
- */
- String convert(CaseFormat format, String s) {
- // deal with camel conversion
+ if (format == this) {
+ return s;
+ }
+
+ /* optimize cases where no camel conversion is required */
+ switch (this) {
+ case LOWER_HYPHEN:
+ switch (format) {
+ case LOWER_UNDERSCORE:
+ return s.replace('-', '_');
+ case UPPER_UNDERSCORE:
+ return Ascii.toUpperCase(s.replace('-', '_'));
+ }
+ break;
+ case LOWER_UNDERSCORE:
+ switch (format) {
+ case LOWER_HYPHEN:
+ return s.replace('_', '-');
+ case UPPER_UNDERSCORE:
+ return Ascii.toUpperCase(s);
+ }
+ break;
+ case UPPER_UNDERSCORE:
+ switch (format) {
+ case LOWER_HYPHEN:
+ return Ascii.toLowerCase(s.replace('_', '-'));
+ case LOWER_UNDERSCORE:
+ return Ascii.toLowerCase(s);
+ }
+ break;
+ }
+
+ // otherwise, deal with camel conversion
StringBuilder out = null;
int i = 0;
int j = -1;
@@ -138,23 +119,46 @@ public enum CaseFormat {
out.append(format.wordSeparator);
i = j + wordSeparator.length();
}
- return (i == 0)
- ? format.normalizeFirstWord(s)
- : out.append(format.normalizeWord(s.substring(i))).toString();
+ if (i == 0) {
+ return format.normalizeFirstWord(s);
+ }
+ out.append(format.normalizeWord(s.substring(i)));
+ return out.toString();
}
- abstract String normalizeWord(String word);
-
private String normalizeFirstWord(String word) {
- return (this == LOWER_CAMEL) ? Ascii.toLowerCase(word) : normalizeWord(word);
+ switch (this) {
+ case LOWER_CAMEL:
+ return Ascii.toLowerCase(word);
+ default:
+ return normalizeWord(word);
+ }
+ }
+
+ private String normalizeWord(String word) {
+ switch (this) {
+ case LOWER_HYPHEN:
+ return Ascii.toLowerCase(word);
+ case LOWER_UNDERSCORE:
+ return Ascii.toLowerCase(word);
+ case LOWER_CAMEL:
+ return firstCharOnlyToUpper(word);
+ case UPPER_CAMEL:
+ return firstCharOnlyToUpper(word);
+ case UPPER_UNDERSCORE:
+ return Ascii.toUpperCase(word);
+ }
+ throw new RuntimeException("unknown case: " + this);
}
private static String firstCharOnlyToUpper(String word) {
- return (word.isEmpty())
- ? word
- : new StringBuilder(word.length())
- .append(Ascii.toUpperCase(word.charAt(0)))
- .append(Ascii.toLowerCase(word.substring(1)))
- .toString();
+ int length = word.length();
+ if (length == 0) {
+ return word;
+ }
+ return new StringBuilder(length)
+ .append(Ascii.toUpperCase(word.charAt(0)))
+ .append(Ascii.toLowerCase(word.substring(1)))
+ .toString();
}
}
diff --git a/guava/src/com/google/common/base/CharMatcher.java b/guava/src/com/google/common/base/CharMatcher.java
index e79f7d4..1bea5c8 100644
--- a/guava/src/com/google/common/base/CharMatcher.java
+++ b/guava/src/com/google/common/base/CharMatcher.java
@@ -21,10 +21,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.BitSet;
+import java.util.List;
import javax.annotation.CheckReturnValue;
@@ -45,17 +45,38 @@ import javax.annotation.CheckReturnValue;
* String trimmed = {@link #WHITESPACE WHITESPACE}.{@link #trimFrom trimFrom}(userInput);
* if ({@link #ASCII ASCII}.{@link #matchesAllOf matchesAllOf}(s)) { ... }</pre>
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#CharMatcher">
- * {@code CharMatcher}</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@Beta // Possibly change from chars to code points; decide constants vs. methods
-@GwtCompatible(emulated = true)
+@GwtCompatible
public abstract class CharMatcher implements Predicate<Character> {
// Constants
+
+ // Excludes 2000-2000a, which is handled as a range
+ private static final String BREAKING_WHITESPACE_CHARS =
+ "\t\n\013\f\r \u0085\u1680\u2028\u2029\u205f\u3000";
+
+ // Excludes 2007, which is handled as a gap in a pair of ranges
+ private static final String NON_BREAKING_WHITESPACE_CHARS =
+ "\u00a0\u180e\u202f";
+
+ /**
+ * Determines whether a character is whitespace according to the latest Unicode standard, as
+ * illustrated
+ * <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bwhitespace%7D">here</a>.
+ * This is not the same definition used by other Java APIs. (See a
+ * <a href="http://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ">comparison of several
+ * definitions of "whitespace"</a>.)
+ *
+ * <p><b>Note:</b> as the Unicode definition evolves, we will modify this constant to keep it up
+ * to date.
+ */
+ public static final CharMatcher WHITESPACE =
+ anyOf(BREAKING_WHITESPACE_CHARS + NON_BREAKING_WHITESPACE_CHARS)
+ .or(inRange('\u2000', '\u200a'))
+ .precomputed();
+
/**
* Determines whether a character is a breaking whitespace (that is, a whitespace which can be
* interpreted as a break between words for formatting purposes). See {@link #WHITESPACE} for a
@@ -63,96 +84,40 @@ public abstract class CharMatcher implements Predicate<Character> {
*
* @since 2.0
*/
- public static final CharMatcher BREAKING_WHITESPACE = new CharMatcher() {
- @Override
- public boolean matches(char c) {
- switch (c) {
- case '\t':
- case '\n':
- case '\013':
- case '\f':
- case '\r':
- case ' ':
- case '\u0085':
- case '\u1680':
- case '\u2028':
- case '\u2029':
- case '\u205f':
- case '\u3000':
- return true;
- case '\u2007':
- return false;
- default:
- return c >= '\u2000' && c <= '\u200a';
- }
- }
-
- @Override
- public String toString() {
- return "CharMatcher.BREAKING_WHITESPACE";
- }
- };
+ public static final CharMatcher BREAKING_WHITESPACE =
+ anyOf(BREAKING_WHITESPACE_CHARS)
+ .or(inRange('\u2000', '\u2006'))
+ .or(inRange('\u2008', '\u200a'))
+ .precomputed();
/**
* Determines whether a character is ASCII, meaning that its code point is less than 128.
*/
- public static final CharMatcher ASCII = inRange('\0', '\u007f', "CharMatcher.ASCII");
-
- private static class RangesMatcher extends CharMatcher {
- private final char[] rangeStarts;
- private final char[] rangeEnds;
-
- RangesMatcher(String description, char[] rangeStarts, char[] rangeEnds) {
- super(description);
- this.rangeStarts = rangeStarts;
- this.rangeEnds = rangeEnds;
- checkArgument(rangeStarts.length == rangeEnds.length);
- for (int i = 0; i < rangeStarts.length; i++) {
- checkArgument(rangeStarts[i] <= rangeEnds[i]);
- if (i + 1 < rangeStarts.length) {
- checkArgument(rangeEnds[i] < rangeStarts[i + 1]);
- }
- }
- }
-
- @Override
- public boolean matches(char c) {
- int index = Arrays.binarySearch(rangeStarts, c);
- if (index >= 0) {
- return true;
- } else {
- index = ~index - 1;
- return index >= 0 && c <= rangeEnds[index];
- }
- }
- }
-
- // Must be in ascending order.
- private static final String ZEROES = "0\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66\u0be6"
- + "\u0c66\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810\u1946\u19d0\u1b50\u1bb0"
- + "\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10";
-
- private static final String NINES;
- static {
- StringBuilder builder = new StringBuilder(ZEROES.length());
- for (int i = 0; i < ZEROES.length(); i++) {
- builder.append((char) (ZEROES.charAt(i) + 9));
- }
- NINES = builder.toString();
- }
+ public static final CharMatcher ASCII = inRange('\0', '\u007f');
/**
* Determines whether a character is a digit according to
* <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D">Unicode</a>.
*/
- public static final CharMatcher DIGIT = new RangesMatcher(
- "CharMatcher.DIGIT", ZEROES.toCharArray(), NINES.toCharArray());
+ public static final CharMatcher DIGIT;
+
+ static {
+ CharMatcher digit = inRange('0', '9');
+ String zeroes =
+ "\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66\u0be6\u0c66"
+ + "\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810\u1946"
+ + "\u19d0\u1b50\u1bb0\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10";
+ for (char base : zeroes.toCharArray()) {
+ digit = digit.or(inRange(base, (char) (base + 9)));
+ }
+ DIGIT = digit.precomputed();
+ }
/**
* Determines whether a character is a digit according to {@link Character#isDigit(char) Java's
* definition}. If you only care to match ASCII digits, you can use {@code inRange('0', '9')}.
*/
- public static final CharMatcher JAVA_DIGIT = new CharMatcher("CharMatcher.JAVA_DIGIT") {
+ public static final CharMatcher JAVA_DIGIT = new CharMatcher() {
@Override public boolean matches(char c) {
return Character.isDigit(c);
}
@@ -163,7 +128,7 @@ public abstract class CharMatcher implements Predicate<Character> {
* definition}. If you only care to match letters of the Latin alphabet, you can use {@code
* inRange('a', 'z').or(inRange('A', 'Z'))}.
*/
- public static final CharMatcher JAVA_LETTER = new CharMatcher("CharMatcher.JAVA_LETTER") {
+ public static final CharMatcher JAVA_LETTER = new CharMatcher() {
@Override public boolean matches(char c) {
return Character.isLetter(c);
}
@@ -173,8 +138,7 @@ public abstract class CharMatcher implements Predicate<Character> {
* Determines whether a character is a letter or digit according to {@link
* Character#isLetterOrDigit(char) Java's definition}.
*/
- public static final CharMatcher JAVA_LETTER_OR_DIGIT =
- new CharMatcher("CharMatcher.JAVA_LETTER_OR_DIGIT") {
+ public static final CharMatcher JAVA_LETTER_OR_DIGIT = new CharMatcher() {
@Override public boolean matches(char c) {
return Character.isLetterOrDigit(c);
}
@@ -184,8 +148,7 @@ public abstract class CharMatcher implements Predicate<Character> {
* Determines whether a character is upper case according to {@link Character#isUpperCase(char)
* Java's definition}.
*/
- public static final CharMatcher JAVA_UPPER_CASE =
- new CharMatcher("CharMatcher.JAVA_UPPER_CASE") {
+ public static final CharMatcher JAVA_UPPER_CASE = new CharMatcher() {
@Override public boolean matches(char c) {
return Character.isUpperCase(c);
}
@@ -195,8 +158,7 @@ public abstract class CharMatcher implements Predicate<Character> {
* Determines whether a character is lower case according to {@link Character#isLowerCase(char)
* Java's definition}.
*/
- public static final CharMatcher JAVA_LOWER_CASE =
- new CharMatcher("CharMatcher.JAVA_LOWER_CASE") {
+ public static final CharMatcher JAVA_LOWER_CASE = new CharMatcher() {
@Override public boolean matches(char c) {
return Character.isLowerCase(c);
}
@@ -207,31 +169,26 @@ public abstract class CharMatcher implements Predicate<Character> {
* Character#isISOControl(char)}.
*/
public static final CharMatcher JAVA_ISO_CONTROL =
- inRange('\u0000', '\u001f')
- .or(inRange('\u007f', '\u009f'))
- .withToString("CharMatcher.JAVA_ISO_CONTROL");
+ inRange('\u0000', '\u001f').or(inRange('\u007f', '\u009f'));
/**
* Determines whether a character is invisible; that is, if its Unicode category is any of
* SPACE_SEPARATOR, LINE_SEPARATOR, PARAGRAPH_SEPARATOR, CONTROL, FORMAT, SURROGATE, and
* PRIVATE_USE according to ICU4J.
*/
- public static final CharMatcher INVISIBLE = new RangesMatcher("CharMatcher.INVISIBLE", (
- "\u0000\u007f\u00ad\u0600\u06dd\u070f\u1680\u180e\u2000\u2028\u205f\u206a\u3000\ud800\ufeff"
- + "\ufff9\ufffa").toCharArray(), (
- "\u0020\u00a0\u00ad\u0604\u06dd\u070f\u1680\u180e\u200f\u202f\u2064\u206f\u3000\uf8ff\ufeff"
- + "\ufff9\ufffb").toCharArray());
-
- private static String showCharacter(char c) {
- String hex = "0123456789ABCDEF";
- char[] tmp = {'\\', 'u', '\0', '\0', '\0', '\0'};
- for (int i = 0; i < 4; i++) {
- tmp[5 - i] = hex.charAt(c & 0xF);
- c >>= 4;
- }
- return String.copyValueOf(tmp);
-
- }
+ public static final CharMatcher INVISIBLE = inRange('\u0000', '\u0020')
+ .or(inRange('\u007f', '\u00a0'))
+ .or(is('\u00ad'))
+ .or(inRange('\u0600', '\u0603'))
+ .or(anyOf("\u06dd\u070f\u1680\u17b4\u17b5\u180e"))
+ .or(inRange('\u2000', '\u200f'))
+ .or(inRange('\u2028', '\u202f'))
+ .or(inRange('\u205f', '\u2064'))
+ .or(inRange('\u206a', '\u206f'))
+ .or(is('\u3000'))
+ .or(inRange('\ud800', '\uf8ff'))
+ .or(anyOf("\ufeff\ufff9\ufffa\ufffb"))
+ .precomputed();
/**
* Determines whether a character is single-width (not double-width). When in doubt, this matcher
@@ -241,13 +198,24 @@ public abstract class CharMatcher implements Predicate<Character> {
* <p><b>Note:</b> as the reference file evolves, we will modify this constant to keep it up to
* date.
*/
- public static final CharMatcher SINGLE_WIDTH = new RangesMatcher("CharMatcher.SINGLE_WIDTH",
- "\u0000\u05be\u05d0\u05f3\u0600\u0750\u0e00\u1e00\u2100\ufb50\ufe70\uff61".toCharArray(),
- "\u04f9\u05be\u05ea\u05f4\u06ff\u077f\u0e7f\u20af\u213a\ufdff\ufeff\uffdc".toCharArray());
+ public static final CharMatcher SINGLE_WIDTH = inRange('\u0000', '\u04f9')
+ .or(is('\u05be'))
+ .or(inRange('\u05d0', '\u05ea'))
+ .or(is('\u05f3'))
+ .or(is('\u05f4'))
+ .or(inRange('\u0600', '\u06ff'))
+ .or(inRange('\u0750', '\u077f'))
+ .or(inRange('\u0e00', '\u0e7f'))
+ .or(inRange('\u1e00', '\u20af'))
+ .or(inRange('\u2100', '\u213a'))
+ .or(inRange('\ufb50', '\ufdff'))
+ .or(inRange('\ufe70', '\ufeff'))
+ .or(inRange('\uff61', '\uffdc'))
+ .precomputed();
/** Matches any character. */
public static final CharMatcher ANY =
- new FastMatcher("CharMatcher.ANY") {
+ new CharMatcher() {
@Override public boolean matches(char c) {
return true;
}
@@ -319,11 +287,15 @@ public abstract class CharMatcher implements Predicate<Character> {
@Override public CharMatcher negate() {
return NONE;
}
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
};
/** Matches no characters. */
public static final CharMatcher NONE =
- new FastMatcher("CharMatcher.NONE") {
+ new CharMatcher() {
@Override public boolean matches(char c) {
return false;
}
@@ -374,16 +346,6 @@ public abstract class CharMatcher implements Predicate<Character> {
return sequence.toString();
}
- @Override
- public String trimLeadingFrom(CharSequence sequence) {
- return sequence.toString();
- }
-
- @Override
- public String trimTrailingFrom(CharSequence sequence) {
- return sequence.toString();
- }
-
@Override public int countIn(CharSequence sequence) {
checkNotNull(sequence);
return 0;
@@ -401,6 +363,12 @@ public abstract class CharMatcher implements Predicate<Character> {
@Override public CharMatcher negate() {
return ANY;
}
+
+ @Override void setBits(LookupTable table) {}
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
};
// Static factories
@@ -409,8 +377,7 @@ public abstract class CharMatcher implements Predicate<Character> {
* Returns a {@code char} matcher that matches only one specified character.
*/
public static CharMatcher is(final char match) {
- String description = "CharMatcher.is('" + showCharacter(match) + "')";
- return new FastMatcher(description) {
+ return new CharMatcher() {
@Override public boolean matches(char c) {
return c == match;
}
@@ -431,11 +398,13 @@ public abstract class CharMatcher implements Predicate<Character> {
return isNot(match);
}
- @GwtIncompatible("java.util.BitSet")
- @Override
- void setBits(BitSet table) {
+ @Override void setBits(LookupTable table) {
table.set(match);
}
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
};
}
@@ -445,8 +414,7 @@ public abstract class CharMatcher implements Predicate<Character> {
* <p>To negate another {@code CharMatcher}, use {@link #negate()}.
*/
public static CharMatcher isNot(final char match) {
- String description = "CharMatcher.isNot(" + Integer.toHexString(match) + ")";
- return new FastMatcher(description) {
+ return new CharMatcher() {
@Override public boolean matches(char c) {
return c != match;
}
@@ -459,13 +427,6 @@ public abstract class CharMatcher implements Predicate<Character> {
return other.matches(match) ? ANY : this;
}
- @GwtIncompatible("java.util.BitSet")
- @Override
- void setBits(BitSet table) {
- table.set(0, match);
- table.set(match + 1, Character.MAX_VALUE + 1);
- }
-
@Override public CharMatcher negate() {
return is(match);
}
@@ -483,26 +444,33 @@ public abstract class CharMatcher implements Predicate<Character> {
case 1:
return is(sequence.charAt(0));
case 2:
- return isEither(sequence.charAt(0), sequence.charAt(1));
- default:
- // continue below to handle the general case
+ final char match1 = sequence.charAt(0);
+ final char match2 = sequence.charAt(1);
+ return new CharMatcher() {
+ @Override public boolean matches(char c) {
+ return c == match1 || c == match2;
+ }
+
+ @Override void setBits(LookupTable table) {
+ table.set(match1);
+ table.set(match2);
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
}
- // TODO(user): is it potentially worth just going ahead and building a precomputed matcher?
+
final char[] chars = sequence.toString().toCharArray();
- Arrays.sort(chars);
- StringBuilder description = new StringBuilder("CharMatcher.anyOf(\"");
- for (char c : chars) {
- description.append(showCharacter(c));
- }
- description.append("\")");
- return new CharMatcher(description.toString()) {
+ Arrays.sort(chars); // not worth collapsing duplicates
+
+ return new CharMatcher() {
@Override public boolean matches(char c) {
return Arrays.binarySearch(chars, c) >= 0;
}
- @Override
- @GwtIncompatible("java.util.BitSet")
- void setBits(BitSet table) {
+ @Override void setBits(LookupTable table) {
for (char c : chars) {
table.set(c);
}
@@ -510,24 +478,6 @@ public abstract class CharMatcher implements Predicate<Character> {
};
}
- private static CharMatcher isEither(
- final char match1,
- final char match2) {
- String description = "CharMatcher.anyOf(\"" +
- showCharacter(match1) + showCharacter(match2) + "\")";
- return new FastMatcher(description) {
- @Override public boolean matches(char c) {
- return c == match1 || c == match2;
- }
-
- @GwtIncompatible("java.util.BitSet")
- @Override void setBits(BitSet table) {
- table.set(match1);
- table.set(match2);
- }
- };
- }
-
/**
* Returns a {@code char} matcher that matches any character not present in the given character
* sequence.
@@ -545,22 +495,23 @@ public abstract class CharMatcher implements Predicate<Character> {
*/
public static CharMatcher inRange(final char startInclusive, final char endInclusive) {
checkArgument(endInclusive >= startInclusive);
- String description = "CharMatcher.inRange('" +
- showCharacter(startInclusive) + "', '" +
- showCharacter(endInclusive) + "')";
- return inRange(startInclusive, endInclusive, description);
- }
-
- static CharMatcher inRange(final char startInclusive, final char endInclusive,
- String description) {
- return new FastMatcher(description) {
+ return new CharMatcher() {
@Override public boolean matches(char c) {
return startInclusive <= c && c <= endInclusive;
}
- @GwtIncompatible("java.util.BitSet")
- @Override void setBits(BitSet table) {
- table.set(startInclusive, endInclusive + 1);
+ @Override void setBits(LookupTable table) {
+ char c = startInclusive;
+ while (true) {
+ table.set(c);
+ if (c++ == endInclusive) {
+ break;
+ }
+ }
+ }
+
+ @Override public CharMatcher precomputed() {
+ return this;
}
};
}
@@ -574,8 +525,7 @@ public abstract class CharMatcher implements Predicate<Character> {
if (predicate instanceof CharMatcher) {
return (CharMatcher) predicate;
}
- String description = "CharMatcher.forPredicate(" + predicate + ")";
- return new CharMatcher(description) {
+ return new CharMatcher() {
@Override public boolean matches(char c) {
return predicate.apply(c);
}
@@ -586,25 +536,12 @@ public abstract class CharMatcher implements Predicate<Character> {
};
}
- // State
- final String description;
-
// Constructors
/**
- * Sets the {@code toString()} from the given description.
+ * Constructor for use by subclasses.
*/
- CharMatcher(String description) {
- this.description = description;
- }
-
- /**
- * Constructor for use by subclasses. When subclassing, you may want to override
- * {@code toString()} to provide a useful description.
- */
- protected CharMatcher() {
- description = super.toString();
- }
+ protected CharMatcher() {}
// Abstract methods
@@ -617,96 +554,57 @@ public abstract class CharMatcher implements Predicate<Character> {
* Returns a matcher that matches any character not matched by this matcher.
*/
public CharMatcher negate() {
- return new NegatedMatcher(this);
- }
-
- private static class NegatedMatcher extends CharMatcher {
- final CharMatcher original;
-
- NegatedMatcher(String toString, CharMatcher original) {
- super(toString);
- this.original = original;
- }
-
- NegatedMatcher(CharMatcher original) {
- this(original + ".negate()", original);
- }
-
- @Override public boolean matches(char c) {
- return !original.matches(c);
- }
-
- @Override public boolean matchesAllOf(CharSequence sequence) {
- return original.matchesNoneOf(sequence);
- }
-
- @Override public boolean matchesNoneOf(CharSequence sequence) {
- return original.matchesAllOf(sequence);
- }
+ final CharMatcher original = this;
+ return new CharMatcher() {
+ @Override public boolean matches(char c) {
+ return !original.matches(c);
+ }
- @Override public int countIn(CharSequence sequence) {
- return sequence.length() - original.countIn(sequence);
- }
+ @Override public boolean matchesAllOf(CharSequence sequence) {
+ return original.matchesNoneOf(sequence);
+ }
- @GwtIncompatible("java.util.BitSet")
- @Override
- void setBits(BitSet table) {
- BitSet tmp = new BitSet();
- original.setBits(tmp);
- tmp.flip(Character.MIN_VALUE, Character.MAX_VALUE + 1);
- table.or(tmp);
- }
+ @Override public boolean matchesNoneOf(CharSequence sequence) {
+ return original.matchesAllOf(sequence);
+ }
- @Override public CharMatcher negate() {
- return original;
- }
+ @Override public int countIn(CharSequence sequence) {
+ return sequence.length() - original.countIn(sequence);
+ }
- @Override
- CharMatcher withToString(String description) {
- return new NegatedMatcher(description, original);
- }
+ @Override public CharMatcher negate() {
+ return original;
+ }
+ };
}
/**
* Returns a matcher that matches any character matched by both this matcher and {@code other}.
*/
public CharMatcher and(CharMatcher other) {
- return new And(this, checkNotNull(other));
+ return new And(Arrays.asList(this, checkNotNull(other)));
}
private static class And extends CharMatcher {
- final CharMatcher first;
- final CharMatcher second;
+ List<CharMatcher> components;
- And(CharMatcher a, CharMatcher b) {
- this(a, b, "CharMatcher.and(" + a + ", " + b + ")");
+ And(List<CharMatcher> components) {
+ this.components = components; // Skip defensive copy (private)
}
- And(CharMatcher a, CharMatcher b, String description) {
- super(description);
- first = checkNotNull(a);
- second = checkNotNull(b);
- }
-
- @Override
- public boolean matches(char c) {
- return first.matches(c) && second.matches(c);
- }
-
- @GwtIncompatible("java.util.BitSet")
- @Override
- void setBits(BitSet table) {
- BitSet tmp1 = new BitSet();
- first.setBits(tmp1);
- BitSet tmp2 = new BitSet();
- second.setBits(tmp2);
- tmp1.and(tmp2);
- table.or(tmp1);
+ @Override public boolean matches(char c) {
+ for (CharMatcher matcher : components) {
+ if (!matcher.matches(c)) {
+ return false;
+ }
+ }
+ return true;
}
- @Override
- CharMatcher withToString(String description) {
- return new And(first, second, description);
+ @Override public CharMatcher and(CharMatcher other) {
+ List<CharMatcher> newComponents = new ArrayList<CharMatcher>(components);
+ newComponents.add(checkNotNull(other));
+ return new And(newComponents);
}
}
@@ -714,38 +612,35 @@ public abstract class CharMatcher implements Predicate<Character> {
* Returns a matcher that matches any character matched by either this matcher or {@code other}.
*/
public CharMatcher or(CharMatcher other) {
- return new Or(this, checkNotNull(other));
+ return new Or(Arrays.asList(this, checkNotNull(other)));
}
private static class Or extends CharMatcher {
- final CharMatcher first;
- final CharMatcher second;
-
- Or(CharMatcher a, CharMatcher b, String description) {
- super(description);
- first = checkNotNull(a);
- second = checkNotNull(b);
- }
+ List<CharMatcher> components;
- Or(CharMatcher a, CharMatcher b) {
- this(a, b, "CharMatcher.or(" + a + ", " + b + ")");
+ Or(List<CharMatcher> components) {
+ this.components = components; // Skip defensive copy (private)
}
- @GwtIncompatible("java.util.BitSet")
- @Override
- void setBits(BitSet table) {
- first.setBits(table);
- second.setBits(table);
+ @Override public boolean matches(char c) {
+ for (CharMatcher matcher : components) {
+ if (matcher.matches(c)) {
+ return true;
+ }
+ }
+ return false;
}
- @Override
- public boolean matches(char c) {
- return first.matches(c) || second.matches(c);
+ @Override public CharMatcher or(CharMatcher other) {
+ List<CharMatcher> newComponents = new ArrayList<CharMatcher>(components);
+ newComponents.add(checkNotNull(other));
+ return new Or(newComponents);
}
- @Override
- CharMatcher withToString(String description) {
- return new Or(first, second, description);
+ @Override void setBits(LookupTable table) {
+ for (CharMatcher matcher : components) {
+ matcher.setBits(table);
+ }
}
}
@@ -763,147 +658,67 @@ public abstract class CharMatcher implements Predicate<Character> {
}
/**
- * Subclasses should provide a new CharMatcher with the same characteristics as {@code this},
- * but with their {@code toString} method overridden with the new description.
+ * This is the actual implementation of {@link #precomputed}, but we bounce calls through a method
+ * on {@link Platform} so that we can have different behavior in GWT.
*
- * <p>This is unsupported by default.
- */
- CharMatcher withToString(String description) {
- throw new UnsupportedOperationException();
- }
-
- private static final int DISTINCT_CHARS = Character.MAX_VALUE - Character.MIN_VALUE + 1;
-
- /**
- * This is the actual implementation of {@link #precomputed}, but we bounce calls through a
- * method on {@link Platform} so that we can have different behavior in GWT.
+ * <p>The default precomputation is to cache the configuration of the original matcher in an
+ * eight-kilobyte bit array. In some situations this produces a matcher which is faster to query
+ * than the original.
*
- * <p>This implementation tries to be smart in a number of ways. It recognizes cases where
- * the negation is cheaper to precompute than the matcher itself; it tries to build small
- * hash tables for matchers that only match a few characters, and so on. In the worst-case
- * scenario, it constructs an eight-kilobyte bit array and queries that.
- * In many situations this produces a matcher which is faster to query than the original.
+ * <p>The default implementation creates a new bit array and passes it to {@link
+ * #setBits(LookupTable)}.
*/
- @GwtIncompatible("java.util.BitSet")
CharMatcher precomputedInternal() {
- final BitSet table = new BitSet();
+ final LookupTable table = new LookupTable();
setBits(table);
- int totalCharacters = table.cardinality();
- if (totalCharacters * 2 <= DISTINCT_CHARS) {
- return precomputedPositive(totalCharacters, table, description);
- } else {
- // TODO(user): is it worth it to worry about the last character of large matchers?
- table.flip(Character.MIN_VALUE, Character.MAX_VALUE + 1);
- int negatedCharacters = DISTINCT_CHARS - totalCharacters;
- return new NegatedFastMatcher(toString(),
- precomputedPositive(negatedCharacters, table, description + ".negate()"));
- }
- }
- /**
- * A matcher for which precomputation will not yield any significant benefit.
- */
- abstract static class FastMatcher extends CharMatcher {
- FastMatcher() {
- super();
- }
-
- FastMatcher(String description) {
- super(description);
- }
-
- @Override
- public final CharMatcher precomputed() {
- return this;
- }
-
- @Override
- public CharMatcher negate() {
- return new NegatedFastMatcher(this);
- }
- }
-
- static final class NegatedFastMatcher extends NegatedMatcher {
- NegatedFastMatcher(CharMatcher original) {
- super(original);
- }
-
- NegatedFastMatcher(String toString, CharMatcher original) {
- super(toString, original);
- }
+ return new CharMatcher() {
+ @Override public boolean matches(char c) {
+ return table.get(c);
+ }
- @Override
- public final CharMatcher precomputed() {
- return this;
- }
+ // TODO(kevinb): make methods like negate() smart?
- @Override
- CharMatcher withToString(String description) {
- return new NegatedFastMatcher(description, original);
- }
+ @Override public CharMatcher precomputed() {
+ return this;
+ }
+ };
}
/**
- * Helper method for {@link #precomputedInternal} that doesn't test if the negation is cheaper.
+ * For use by implementors; sets the bit corresponding to each character ('\0' to '{@literal
+ * \}uFFFF') that matches this matcher in the given bit array, leaving all other bits untouched.
+ *
+ * <p>The default implementation loops over every possible character value, invoking {@link
+ * #matches} for each one.
*/
- @GwtIncompatible("java.util.BitSet")
- private static CharMatcher precomputedPositive(
- int totalCharacters,
- BitSet table,
- String description) {
- switch (totalCharacters) {
- case 0:
- return NONE;
- case 1:
- return is((char) table.nextSetBit(0));
- case 2:
- char c1 = (char) table.nextSetBit(0);
- char c2 = (char) table.nextSetBit(c1 + 1);
- return isEither(c1, c2);
- default:
- return isSmall(totalCharacters, table.length())
- ? SmallCharMatcher.from(table, description)
- : new BitSetMatcher(table, description);
- }
- }
-
- private static boolean isSmall(int totalCharacters, int tableLength) {
- return totalCharacters <= SmallCharMatcher.MAX_SIZE
- && tableLength > (totalCharacters * Character.SIZE);
- }
-
- @GwtIncompatible("java.util.BitSet")
- private static class BitSetMatcher extends FastMatcher {
- private final BitSet table;
-
- private BitSetMatcher(BitSet table, String description) {
- super(description);
- if (table.length() + Long.SIZE < table.size()) {
- table = (BitSet) table.clone();
- // If only we could actually call BitSet.trimToSize() ourselves...
+ void setBits(LookupTable table) {
+ char c = Character.MIN_VALUE;
+ while (true) {
+ if (matches(c)) {
+ table.set(c);
+ }
+ if (c++ == Character.MAX_VALUE) {
+ break;
}
- this.table = table;
- }
-
- @Override public boolean matches(char c) {
- return table.get(c);
- }
-
- @Override
- void setBits(BitSet bitSet) {
- bitSet.or(table);
}
}
/**
- * Sets bits in {@code table} matched by this matcher.
+ * A bit array with one bit per {@code char} value, used by {@link CharMatcher#precomputed}.
+ *
+ * <p>TODO(kevinb): possibly share a common BitArray class with BloomFilter and others... a
+ * simpler java.util.BitSet.
*/
- @GwtIncompatible("java.util.BitSet")
- void setBits(BitSet table) {
- for (int c = Character.MAX_VALUE; c >= Character.MIN_VALUE; c--) {
- if (matches((char) c)) {
- table.set(c);
- }
+ private static final class LookupTable {
+ int[] data = new int[2048];
+
+ void set(char index) {
+ data[index >> 5] |= (1 << index);
+ }
+
+ boolean get(char index) {
+ return (data[index >> 5] & (1 << index)) != 0;
}
}
@@ -958,6 +773,8 @@ public abstract class CharMatcher implements Predicate<Character> {
return indexIn(sequence) == -1;
}
+ // TODO(kevinb): add matchesAnyOf()
+
/**
* Returns the index of the first matching character in a character sequence, or {@code -1} if no
* matching character is present.
@@ -1212,12 +1029,15 @@ public abstract class CharMatcher implements Predicate<Character> {
@CheckReturnValue
public String trimLeadingFrom(CharSequence sequence) {
int len = sequence.length();
- for (int first = 0; first < len; first++) {
+ int first;
+
+ for (first = 0; first < len; first++) {
if (!matches(sequence.charAt(first))) {
- return sequence.subSequence(first, len).toString();
+ break;
}
}
- return "";
+
+ return sequence.subSequence(first, len).toString();
}
/**
@@ -1231,12 +1051,15 @@ public abstract class CharMatcher implements Predicate<Character> {
@CheckReturnValue
public String trimTrailingFrom(CharSequence sequence) {
int len = sequence.length();
- for (int last = len - 1; last >= 0; last--) {
+ int last;
+
+ for (last = len - 1; last >= 0; last--) {
if (!matches(sequence.charAt(last))) {
- return sequence.subSequence(0, last + 1).toString();
+ break;
}
}
- return "";
+
+ return sequence.subSequence(0, last + 1).toString();
}
/**
@@ -1259,25 +1082,29 @@ public abstract class CharMatcher implements Predicate<Character> {
*/
@CheckReturnValue
public String collapseFrom(CharSequence sequence, char replacement) {
- // This implementation avoids unnecessary allocation.
- int len = sequence.length();
- for (int i = 0; i < len; i++) {
+ int first = indexIn(sequence);
+ if (first == -1) {
+ return sequence.toString();
+ }
+
+ // TODO(kevinb): see if this implementation can be made faster
+ StringBuilder builder = new StringBuilder(sequence.length())
+ .append(sequence.subSequence(0, first))
+ .append(replacement);
+ boolean in = true;
+ for (int i = first + 1; i < sequence.length(); i++) {
char c = sequence.charAt(i);
- if (matches(c)) {
- if (c == replacement
- && (i == len - 1 || !matches(sequence.charAt(i + 1)))) {
- // a no-op replacement
- i++;
- } else {
- StringBuilder builder = new StringBuilder(len)
- .append(sequence.subSequence(0, i))
- .append(replacement);
- return finishCollapseFrom(sequence, i + 1, len, replacement, builder, true);
+ if (apply(c)) {
+ if (!in) {
+ builder.append(replacement);
+ in = true;
}
+ } else {
+ builder.append(c);
+ in = false;
}
}
- // no replacement needed
- return sequence.toString();
+ return builder.toString();
}
/**
@@ -1287,35 +1114,22 @@ public abstract class CharMatcher implements Predicate<Character> {
*/
@CheckReturnValue
public String trimAndCollapseFrom(CharSequence sequence, char replacement) {
- // This implementation avoids unnecessary allocation.
- int len = sequence.length();
- int first;
- int last;
-
- for (first = 0; first < len && matches(sequence.charAt(first)); first++) {}
- for (last = len - 1; last > first && matches(sequence.charAt(last)); last--) {}
-
- return (first == 0 && last == len - 1)
- ? collapseFrom(sequence, replacement)
- : finishCollapseFrom(
- sequence, first, last + 1, replacement,
- new StringBuilder(last + 1 - first),
- false);
- }
-
- private String finishCollapseFrom(
- CharSequence sequence, int start, int end, char replacement,
- StringBuilder builder, boolean inMatchingGroup) {
- for (int i = start; i < end; i++) {
+ int first = negate().indexIn(sequence);
+ if (first == -1) {
+ return ""; // everything matches. nothing's left.
+ }
+ StringBuilder builder = new StringBuilder(sequence.length());
+ boolean inMatchingGroup = false;
+ for (int i = first; i < sequence.length(); i++) {
char c = sequence.charAt(i);
- if (matches(c)) {
- if (!inMatchingGroup) {
+ if (apply(c)) {
+ inMatchingGroup = true;
+ } else {
+ if (inMatchingGroup) {
builder.append(replacement);
- inMatchingGroup = true;
+ inMatchingGroup = false;
}
- } else {
builder.append(c);
- inMatchingGroup = false;
}
}
return builder.toString();
@@ -1324,67 +1138,11 @@ public abstract class CharMatcher implements Predicate<Character> {
// Predicate interface
/**
- * Equivalent to {@link #matches}; provided only to satisfy the {@link Predicate} interface. When
- * using a reference of type {@code CharMatcher}, invoke {@link #matches} directly instead.
+ * Returns {@code true} if this matcher matches the given character.
+ *
+ * @throws NullPointerException if {@code character} is null
*/
@Override public boolean apply(Character character) {
return matches(character);
}
-
- /**
- * Returns a string representation of this {@code CharMatcher}, such as
- * {@code CharMatcher.or(WHITESPACE, JAVA_DIGIT)}.
- */
- @Override
- public String toString() {
- return description;
- }
-
- /**
- * A special-case CharMatcher for Unicode whitespace characters that is extremely
- * efficient both in space required and in time to check for matches.
- *
- * Implementation details.
- * It turns out that all current (early 2012) Unicode characters are unique modulo 79:
- * so we can construct a lookup table of exactly 79 entries, and just check the character code
- * mod 79, and see if that character is in the table.
- *
- * There is a 1 at the beginning of the table so that the null character is not listed
- * as whitespace.
- *
- * Other things we tried that did not prove to be beneficial, mostly due to speed concerns:
- *
- * * Binary search into the sorted list of characters, i.e., what
- * CharMatcher.anyOf() does</li>
- * * Perfect hash function into a table of size 26 (using an offset table and a special
- * Jenkins hash function)</li>
- * * Perfect-ish hash function that required two lookups into a single table of size 26.</li>
- * * Using a power-of-2 sized hash table (size 64) with linear probing.</li>
- *
- * --Christopher Swenson, February 2012.
- */
- private static final String WHITESPACE_TABLE = "\u0001\u0000\u00a0\u0000\u0000\u0000\u0000\u0000"
- + "\u0000\u0009\n\u000b\u000c\r\u0000\u0000\u2028\u2029\u0000\u0000\u0000\u0000\u0000\u202f"
- + "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0020\u0000\u0000\u0000\u0000\u0000"
- + "\u0000\u0000\u0000\u0000\u0000\u3000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
- + "\u0000\u0000\u0085\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a"
- + "\u0000\u0000\u0000\u0000\u0000\u205f\u1680\u0000\u0000\u180e\u0000\u0000\u0000";
-
- /**
- * Determines whether a character is whitespace according to the latest Unicode standard, as
- * illustrated
- * <a href="http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bwhitespace%7D">here</a>.
- * This is not the same definition used by other Java APIs. (See a
- * <a href="http://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ">comparison of several
- * definitions of "whitespace"</a>.)
- *
- * <p><b>Note:</b> as the Unicode definition evolves, we will modify this constant to keep it up
- * to date.
- */
- public static final CharMatcher WHITESPACE = new FastMatcher("CharMatcher.WHITESPACE") {
-
- @Override public boolean matches(char c) {
- return WHITESPACE_TABLE.charAt(c % 79) == c;
- }
- };
}
diff --git a/guava/src/com/google/common/base/Charsets.java b/guava/src/com/google/common/base/Charsets.java
index 79c9128..407e798 100644
--- a/guava/src/com/google/common/base/Charsets.java
+++ b/guava/src/com/google/common/base/Charsets.java
@@ -16,38 +16,26 @@
package com.google.common.base;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
import java.nio.charset.Charset;
/**
* Contains constant definitions for the six standard {@link Charset} instances, which are
* guaranteed to be supported by all Java platform implementations.
*
- * <p>Assuming you're free to choose, note that <b>{@link #UTF_8} is widely preferred</b>.
- *
- * <p>See the Guava User Guide article on <a
- * href="http://code.google.com/p/guava-libraries/wiki/StringsExplained#Charsets">
- * {@code Charsets}</a>.
- *
* @author Mike Bostock
* @since 1.0
*/
-@GwtCompatible(emulated = true)
public final class Charsets {
private Charsets() {}
/**
* US-ASCII: seven-bit ASCII, the Basic Latin block of the Unicode character set (ISO646-US).
*/
- @GwtIncompatible("Non-UTF-8 Charset")
public static final Charset US_ASCII = Charset.forName("US-ASCII");
/**
* ISO-8859-1: ISO Latin Alphabet Number 1 (ISO-LATIN-1).
*/
- @GwtIncompatible("Non-UTF-8 Charset")
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
/**
@@ -58,20 +46,17 @@ public final class Charsets {
/**
* UTF-16BE: sixteen-bit UCS Transformation Format, big-endian byte order.
*/
- @GwtIncompatible("Non-UTF-8 Charset")
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
/**
* UTF-16LE: sixteen-bit UCS Transformation Format, little-endian byte order.
*/
- @GwtIncompatible("Non-UTF-8 Charset")
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
/**
* UTF-16: sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order
* mark.
*/
- @GwtIncompatible("Non-UTF-8 Charset")
public static final Charset UTF_16 = Charset.forName("UTF-16");
/*
diff --git a/guava/src/com/google/common/base/Defaults.java b/guava/src/com/google/common/base/Defaults.java
index 50717fc..f98cbbf 100644
--- a/guava/src/com/google/common/base/Defaults.java
+++ b/guava/src/com/google/common/base/Defaults.java
@@ -16,8 +16,6 @@
package com.google.common.base;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -26,7 +24,6 @@ import java.util.Map;
* This class provides default values for all Java types, as defined by the JLS.
*
* @author Ben Yu
- * @since 1.0
*/
public final class Defaults {
private Defaults() {}
@@ -57,6 +54,6 @@ public final class Defaults {
*/
@SuppressWarnings("unchecked")
public static <T> T defaultValue(Class<T> type) {
- return (T) DEFAULTS.get(checkNotNull(type));
+ return (T) DEFAULTS.get(type);
}
}
diff --git a/guava/src/com/google/common/base/Enums.java b/guava/src/com/google/common/base/Enums.java
index 6105410..f98e164 100644
--- a/guava/src/com/google/common/base/Enums.java
+++ b/guava/src/com/google/common/base/Enums.java
@@ -20,10 +20,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
-import java.lang.reflect.Field;
import javax.annotation.Nullable;
@@ -34,31 +32,13 @@ import javax.annotation.Nullable;
*
* @since 9.0
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
@Beta
public final class Enums {
private Enums() {}
/**
- * Returns the {@link Field} in which {@code enumValue} is defined.
- * For example, to get the {@code Description} annotation on the {@code GOLF}
- * constant of enum {@code Sport}, use
- * {@code Enums.getField(Sport.GOLF).getAnnotation(Description.class)}.
- *
- * @since 12.0
- */
- @GwtIncompatible("reflection")
- public static Field getField(Enum<?> enumValue) {
- Class<?> clazz = enumValue.getDeclaringClass();
- try {
- return clazz.getDeclaredField(enumValue.name());
- } catch (NoSuchFieldException impossible) {
- throw new AssertionError(impossible);
- }
- }
-
- /**
* Returns a {@link Function} that maps an {@link Enum} name to the associated
* {@code Enum} constant. The {@code Function} will return {@code null} if the
* {@code Enum} constant does not exist.
@@ -71,11 +51,11 @@ public final class Enums {
}
/**
- * A {@link Function} that maps an {@link Enum} name to the associated
+ * {@link Function} that maps an {@link Enum} name to the associated
* constant, or {@code null} if the constant does not exist.
*/
- private static final class ValueOfFunction<T extends Enum<T>>
- implements Function<String, T>, Serializable {
+ private static final class ValueOfFunction<T extends Enum<T>> implements
+ Function<String, T>, Serializable {
private final Class<T> enumClass;
@@ -107,22 +87,4 @@ public final class Enums {
private static final long serialVersionUID = 0;
}
-
- /**
- * Returns an optional enum constant for the given type, using {@link Enum#valueOf}. If the
- * constant does not exist, {@link Optional#absent} is returned. A common use case is for parsing
- * user input or falling back to a default enum constant. For example,
- * {@code Enums.getIfPresent(Country.class, countryInput).or(Country.DEFAULT);}
- *
- * @since 12.0
- */
- public static <T extends Enum<T>> Optional<T> getIfPresent(Class<T> enumClass, String value) {
- checkNotNull(enumClass);
- checkNotNull(value);
- try {
- return Optional.of(Enum.valueOf(enumClass, value));
- } catch (IllegalArgumentException iae) {
- return Optional.absent();
- }
- }
}
diff --git a/guava/src/com/google/common/base/Equivalence.java b/guava/src/com/google/common/base/Equivalence.java
index 339bec0..f6e89bd 100644
--- a/guava/src/com/google/common/base/Equivalence.java
+++ b/guava/src/com/google/common/base/Equivalence.java
@@ -27,8 +27,8 @@ import javax.annotation.Nullable;
/**
* A strategy for determining whether two instances are considered equivalent. Examples of
- * equivalences are the {@linkplain #identity() identity equivalence} and {@linkplain #equals equals
- * equivalence}.
+ * equivalences are the {@link Equivalences#identity() identity equivalence} and {@link
+ * Equivalences#equals equals equivalence}.
*
* @author Bob Lee
* @author Ben Yu
@@ -36,6 +36,7 @@ import javax.annotation.Nullable;
* @since 10.0 (<a href="http://code.google.com/p/guava-libraries/wiki/Compatibility"
* >mostly source-compatible</a> since 4.0)
*/
+@Beta
@GwtCompatible
public abstract class Equivalence<T> {
/**
@@ -122,7 +123,7 @@ public abstract class Equivalence<T> {
*
* <p>For example: <pre> {@code
*
- * Equivalence<Person> SAME_AGE = Equivalence.equals().onResultOf(GET_PERSON_AGE);
+ * Equivalence<Person> SAME_AGE = Equivalences.equals().onResultOf(GET_PERSON_AGE);
* }</pre>
*
* <p>{@code function} will never be invoked with a null value.
@@ -130,7 +131,7 @@ public abstract class Equivalence<T> {
* <p>Note that {@code function} must be consistent according to {@code this} equivalence
* relation. That is, invoking {@link Function#apply} multiple times for a given value must return
* equivalent results.
- * For example, {@code Equivalence.identity().onResultOf(Functions.toStringFunction())} is broken
+ * For example, {@code Equivalences.identity().onResultOf(Functions.toStringFunction())} is broken
* because it's not guaranteed that {@link Object#toString}) always returns the same string
* instance.
*
@@ -171,6 +172,7 @@ public abstract class Equivalence<T> {
*
* @since 10.0
*/
+ @Beta
public static final class Wrapper<T> implements Serializable {
private final Equivalence<? super T> equivalence;
@Nullable private final T reference;
@@ -251,7 +253,6 @@ public abstract class Equivalence<T> {
*
* @since 10.0
*/
- @Beta
public final Predicate<T> equivalentTo(@Nullable T target) {
return new EquivalentToPredicate<T>(this, target);
}
@@ -292,67 +293,4 @@ public abstract class Equivalence<T> {
private static final long serialVersionUID = 0;
}
-
- /**
- * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
- * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither
- * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns
- * {@code 0} if passed a null value.
- *
- * @since 13.0
- * @since 8.0 (in Equivalences with null-friendly behavior)
- * @since 4.0 (in Equivalences)
- */
- public static Equivalence<Object> equals() {
- return Equals.INSTANCE;
- }
-
- /**
- * Returns an equivalence that uses {@code ==} to compare values and {@link
- * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent}
- * returns {@code true} if {@code a == b}, including in the case that a and b are both null.
- *
- * @since 13.0
- * @since 4.0 (in Equivalences)
- */
- public static Equivalence<Object> identity() {
- return Identity.INSTANCE;
- }
-
- static final class Equals extends Equivalence<Object>
- implements Serializable {
-
- static final Equals INSTANCE = new Equals();
-
- @Override protected boolean doEquivalent(Object a, Object b) {
- return a.equals(b);
- }
- @Override public int doHash(Object o) {
- return o.hashCode();
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
- private static final long serialVersionUID = 1;
- }
-
- static final class Identity extends Equivalence<Object>
- implements Serializable {
-
- static final Identity INSTANCE = new Identity();
-
- @Override protected boolean doEquivalent(Object a, Object b) {
- return false;
- }
-
- @Override protected int doHash(Object o) {
- return System.identityHashCode(o);
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
- private static final long serialVersionUID = 1;
- }
}
diff --git a/guava/src/com/google/common/base/Equivalences.java b/guava/src/com/google/common/base/Equivalences.java
new file mode 100644
index 0000000..6c88dcf
--- /dev/null
+++ b/guava/src/com/google/common/base/Equivalences.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
+import java.io.Serializable;
+
+/**
+ * Contains static factory methods for creating {@code Equivalence} instances.
+ *
+ * <p>All methods return serializable instances.
+ *
+ * @author Bob Lee
+ * @author Kurt Alfred Kluever
+ * @author Gregory Kick
+ * @since 4.0
+ */
+@Beta
+@GwtCompatible
+public final class Equivalences {
+ private Equivalences() {}
+
+ /**
+ * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
+ * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither
+ * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns
+ * {@code 0} if passed a null value.
+ *
+ * @since 8.0 (present null-friendly behavior)
+ * @since 4.0 (otherwise)
+ */
+ public static Equivalence<Object> equals() {
+ return Equals.INSTANCE;
+ }
+
+ /**
+ * Returns an equivalence that uses {@code ==} to compare values and {@link
+ * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent}
+ * returns {@code true} if {@code a == b}, including in the case that a and b are both null.
+ */
+ public static Equivalence<Object> identity() {
+ return Identity.INSTANCE;
+ }
+
+ private static final class Equals extends Equivalence<Object>
+ implements Serializable {
+
+ static final Equals INSTANCE = new Equals();
+
+ @Override protected boolean doEquivalent(Object a, Object b) {
+ return a.equals(b);
+ }
+ @Override public int doHash(Object o) {
+ return o.hashCode();
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+ private static final long serialVersionUID = 1;
+ }
+
+ private static final class Identity extends Equivalence<Object>
+ implements Serializable {
+
+ static final Identity INSTANCE = new Identity();
+
+ @Override protected boolean doEquivalent(Object a, Object b) {
+ return false;
+ }
+
+ @Override protected int doHash(Object o) {
+ return System.identityHashCode(o);
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+ private static final long serialVersionUID = 1;
+ }
+}
diff --git a/guava/src/com/google/common/base/FinalizableReferenceQueue.java b/guava/src/com/google/common/base/FinalizableReferenceQueue.java
index 2ca3681..f300b33 100644
--- a/guava/src/com/google/common/base/FinalizableReferenceQueue.java
+++ b/guava/src/com/google/common/base/FinalizableReferenceQueue.java
@@ -16,12 +16,8 @@
package com.google.common.base;
-import com.google.common.annotations.VisibleForTesting;
-import java.io.Closeable;
-
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Method;
@@ -41,7 +37,7 @@ import java.util.logging.Logger;
* @author Bob Lee
* @since 2.0 (imported from Google Collections Library)
*/
-public class FinalizableReferenceQueue implements Closeable {
+public class FinalizableReferenceQueue {
/*
* The Finalizer thread keeps a phantom reference to this object. When the client (for example, a
* map built by MapMaker) no longer has a strong reference to this object, the garbage collector
@@ -95,8 +91,6 @@ public class FinalizableReferenceQueue implements Closeable {
*/
final ReferenceQueue<Object> queue;
- final PhantomReference<Object> frqRef;
-
/**
* Whether or not the background thread started successfully.
*/
@@ -108,28 +102,24 @@ public class FinalizableReferenceQueue implements Closeable {
@SuppressWarnings("unchecked")
public FinalizableReferenceQueue() {
// We could start the finalizer lazily, but I'd rather it blow up early.
- queue = new ReferenceQueue<Object>();
- frqRef = new PhantomReference<Object>(this, queue);
+ ReferenceQueue<Object> queue;
boolean threadStarted = false;
try {
- startFinalizer.invoke(null, FinalizableReference.class, queue, frqRef);
+ queue = (ReferenceQueue<Object>)
+ startFinalizer.invoke(null, FinalizableReference.class, this);
threadStarted = true;
} catch (IllegalAccessException impossible) {
throw new AssertionError(impossible); // startFinalizer() is public
} catch (Throwable t) {
logger.log(Level.INFO, "Failed to start reference finalizer thread."
+ " Reference cleanup will only occur when new references are created.", t);
+ queue = new ReferenceQueue<Object>();
}
+ this.queue = queue;
this.threadStarted = threadStarted;
}
- @Override
- public void close() {
- frqRef.enqueue();
- cleanUp();
- }
-
/**
* Repeatedly dequeues references from the queue and invokes {@link
* FinalizableReference#finalizeReferent()} on them until the queue is empty. This method is a
@@ -189,16 +179,8 @@ public class FinalizableReferenceQueue implements Closeable {
* we needn't create a separate loader.
*/
static class SystemLoader implements FinalizerLoader {
- // This is used by the ClassLoader-leak test in FinalizableReferenceQueueTest to disable
- // finding Finalizer on the system class path even if it is there.
- @VisibleForTesting
- static boolean disabled;
-
@Override
public Class<?> loadFinalizer() {
- if (disabled) {
- return null;
- }
ClassLoader systemLoader;
try {
systemLoader = ClassLoader.getSystemClassLoader();
@@ -272,10 +254,7 @@ public class FinalizableReferenceQueue implements Closeable {
/** Creates a class loader with the given base URL as its classpath. */
URLClassLoader newLoader(URL base) {
- // We use the bootstrap class loader as the parent because Finalizer by design uses
- // only standard Java classes. That also means that FinalizableReferenceQueueTest
- // doesn't pick up the wrong version of the Finalizer class.
- return new URLClassLoader(new URL[] {base}, null);
+ return new URLClassLoader(new URL[] {base});
}
}
@@ -299,11 +278,7 @@ public class FinalizableReferenceQueue implements Closeable {
*/
static Method getStartFinalizer(Class<?> finalizer) {
try {
- return finalizer.getMethod(
- "startFinalizer",
- Class.class,
- ReferenceQueue.class,
- PhantomReference.class);
+ return finalizer.getMethod("startFinalizer", Class.class, Object.class);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
diff --git a/guava/src/com/google/common/base/Function.java b/guava/src/com/google/common/base/Function.java
index f969b4a..6289fa4 100644
--- a/guava/src/com/google/common/base/Function.java
+++ b/guava/src/com/google/common/base/Function.java
@@ -23,12 +23,6 @@ import javax.annotation.Nullable;
/**
* Determines an output value based on an input value.
*
- * <p>The {@link Functions} class provides common functions and related utilites.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
- * Function}</a>.
- *
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
@@ -48,7 +42,7 @@ public interface Function<F, T> {
* @throws NullPointerException if {@code input} is null and this function does not accept null
* arguments
*/
- @Nullable T apply(@Nullable F input);
+ T apply(@Nullable F input);
/**
* Indicates whether another object is equal to this function.
diff --git a/guava/src/com/google/common/base/Functions.java b/guava/src/com/google/common/base/Functions.java
index 9336e02..cca629a 100644
--- a/guava/src/com/google/common/base/Functions.java
+++ b/guava/src/com/google/common/base/Functions.java
@@ -30,11 +30,7 @@ import javax.annotation.Nullable;
/**
* Static utility methods pertaining to {@code Function} instances.
*
- * <p>All methods return serializable functions as long as they're given serializable parameters.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
- * Function}</a>.
+ * <p>All methods returns serializable functions as long as they're given serializable parameters.
*
* @author Mike Bostock
* @author Jared Levy
@@ -84,8 +80,7 @@ public final class Functions {
INSTANCE;
@Override
- @Nullable
- public Object apply(@Nullable Object o) {
+ public Object apply(Object o) {
return o;
}
@@ -110,7 +105,7 @@ public final class Functions {
}
@Override
- public V apply(@Nullable K key) {
+ public V apply(K key) {
V result = map.get(key);
checkArgument(result != null || map.containsKey(key), "Key '%s' not present in map", key);
return result;
@@ -159,7 +154,7 @@ public final class Functions {
}
@Override
- public V apply(@Nullable K key) {
+ public V apply(K key) {
V result = map.get(key);
return (result != null || map.containsKey(key)) ? result : defaultValue;
}
@@ -206,7 +201,7 @@ public final class Functions {
}
@Override
- public C apply(@Nullable A a) {
+ public C apply(A a) {
return g.apply(f.apply(a));
}
@@ -248,7 +243,7 @@ public final class Functions {
}
@Override
- public Boolean apply(@Nullable T t) {
+ public Boolean apply(T t) {
return predicate.apply(t);
}
diff --git a/guava/src/com/google/common/base/Joiner.java b/guava/src/com/google/common/base/Joiner.java
index 8a2e9a2..048e477 100644
--- a/guava/src/com/google/common/base/Joiner.java
+++ b/guava/src/com/google/common/base/Joiner.java
@@ -56,9 +56,6 @@ import javax.annotation.Nullable;
* joiner.skipNulls(); // does nothing!
* return joiner.join("wrong", null, "wrong");}</pre>
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#Joiner">{@code Joiner}</a>.
- *
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
@@ -98,8 +95,7 @@ public class Joiner {
*/
@Beta
@Deprecated
- public
- final <A extends Appendable, I extends Object & Iterable<?> & Iterator<?>> A
+ public final <A extends Appendable, I extends Object & Iterable<?> & Iterator<?>> A
appendTo(A appendable, I parts) throws IOException {
return appendTo(appendable, (Iterator<?>) parts);
}
@@ -118,6 +114,7 @@ public class Joiner {
*
* @since 11.0
*/
+ @Beta
public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
checkNotNull(appendable);
if (parts.hasNext()) {
@@ -157,8 +154,7 @@ public class Joiner {
*/
@Beta
@Deprecated
- public
- final <I extends Object & Iterable<?> & Iterator<?>> StringBuilder
+ public final <I extends Object & Iterable<?> & Iterator<?>> StringBuilder
appendTo(StringBuilder builder, I parts) {
return appendTo(builder, (Iterator<?>) parts);
}
@@ -179,6 +175,7 @@ public class Joiner {
*
* @since 11.0
*/
+ @Beta
public final StringBuilder appendTo(StringBuilder builder, Iterator<?> parts) {
try {
appendTo((Appendable) builder, parts);
@@ -217,8 +214,7 @@ public class Joiner {
*/
@Beta
@Deprecated
- public
- final <I extends Object & Iterable<?> & Iterator<?>> String join(I parts) {
+ public final <I extends Object & Iterable<?> & Iterator<?>> String join(I parts) {
return join((Iterator<?>) parts);
}
@@ -236,6 +232,7 @@ public class Joiner {
*
* @since 11.0
*/
+ @Beta
public final String join(Iterator<?> parts) {
return appendTo(new StringBuilder(), parts).toString();
}
@@ -264,7 +261,7 @@ public class Joiner {
public Joiner useForNull(final String nullText) {
checkNotNull(nullText);
return new Joiner(this) {
- @Override CharSequence toString(@Nullable Object part) {
+ @Override CharSequence toString(Object part) {
return (part == null) ? nullText : Joiner.this.toString(part);
}
@@ -391,8 +388,7 @@ public class Joiner {
*/
@Beta
@Deprecated
- public
- <A extends Appendable,
+ public <A extends Appendable,
I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
A appendTo(A appendable, I entries) throws IOException {
Iterator<? extends Entry<?, ?>> iterator = entries;
@@ -448,8 +444,7 @@ public class Joiner {
*/
@Beta
@Deprecated
- public
- <I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
+ public <I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
StringBuilder appendTo(StringBuilder builder, I entries) throws IOException {
Iterator<? extends Entry<?, ?>> iterator = entries;
return appendTo(builder, iterator);
@@ -495,8 +490,7 @@ public class Joiner {
*/
@Beta
@Deprecated
- public
- <I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
+ public <I extends Object & Iterable<? extends Entry<?, ?>> & Iterator<? extends Entry<?, ?>>>
String join(I entries) throws IOException {
Iterator<? extends Entry<?, ?>> iterator = entries;
return join(iterator);
diff --git a/guava/src/com/google/common/base/Objects.java b/guava/src/com/google/common/base/Objects.java
index c65f84b..ffac9c4 100644
--- a/guava/src/com/google/common/base/Objects.java
+++ b/guava/src/com/google/common/base/Objects.java
@@ -27,10 +27,6 @@ import javax.annotation.Nullable;
/**
* Helper functions that can operate on any {@code Object}.
*
- * <p>See the Guava User Guide on <a
- * href="http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained">writing
- * {@code Object} methods with {@code Objects}</a>.
- *
* @author Laurence Gonsalves
* @since 2.0 (imported from Google Collections Library)
*/
@@ -98,14 +94,6 @@ public final class Objects {
* .add("x", 1)
* .add("y", "foo")
* .toString();
- * }}
- *
- * // Returns "ClassName{x=1}"
- * Objects.toStringHelper(this)
- * .omitNullValues()
- * .add("x", 1)
- * .add("y", null)
- * .toString();
* }}</pre>
*
* <p>Note that in GWT, class names are often obfuscated.
@@ -193,38 +181,25 @@ public final class Objects {
* @since 2.0
*/
public static final class ToStringHelper {
- private final String className;
- private ValueHolder holderHead = new ValueHolder();
- private ValueHolder holderTail = holderHead;
- private boolean omitNullValues = false;
+ private final StringBuilder builder;
+ private boolean needsSeparator = false;
/**
* Use {@link Objects#toStringHelper(Object)} to create an instance.
*/
private ToStringHelper(String className) {
- this.className = checkNotNull(className);
- }
-
- /**
- * Configures the {@link ToStringHelper} so {@link #toString()} will ignore
- * properties with null value. The order of calling this method, relative
- * to the {@code add()}/{@code addValue()} methods, is not significant.
- *
- * @since 12.0
- */
- public ToStringHelper omitNullValues() {
- omitNullValues = true;
- return this;
+ checkNotNull(className);
+ this.builder = new StringBuilder(32).append(className).append('{');
}
/**
* Adds a name/value pair to the formatted output in {@code name=value}
* format. If {@code value} is {@code null}, the string {@code "null"}
- * is used, unless {@link #omitNullValues()} is called, in which case this
- * name/value pair will not be added.
+ * is used.
*/
public ToStringHelper add(String name, @Nullable Object value) {
- return addHolder(name, value);
+ checkNameAndAppend(name).append(value);
+ return this;
}
/**
@@ -234,7 +209,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper add(String name, boolean value) {
- return addHolder(name, String.valueOf(value));
+ checkNameAndAppend(name).append(value);
+ return this;
}
/**
@@ -244,7 +220,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper add(String name, char value) {
- return addHolder(name, String.valueOf(value));
+ checkNameAndAppend(name).append(value);
+ return this;
}
/**
@@ -254,7 +231,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper add(String name, double value) {
- return addHolder(name, String.valueOf(value));
+ checkNameAndAppend(name).append(value);
+ return this;
}
/**
@@ -264,7 +242,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper add(String name, float value) {
- return addHolder(name, String.valueOf(value));
+ checkNameAndAppend(name).append(value);
+ return this;
}
/**
@@ -274,7 +253,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper add(String name, int value) {
- return addHolder(name, String.valueOf(value));
+ checkNameAndAppend(name).append(value);
+ return this;
}
/**
@@ -284,7 +264,13 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper add(String name, long value) {
- return addHolder(name, String.valueOf(value));
+ checkNameAndAppend(name).append(value);
+ return this;
+ }
+
+ private StringBuilder checkNameAndAppend(String name) {
+ checkNotNull(name);
+ return maybeAppendSeparator().append(name).append('=');
}
/**
@@ -294,7 +280,8 @@ public final class Objects {
* and give value a readable name.
*/
public ToStringHelper addValue(@Nullable Object value) {
- return addHolder(value);
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
@@ -306,7 +293,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper addValue(boolean value) {
- return addHolder(String.valueOf(value));
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
@@ -318,7 +306,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper addValue(char value) {
- return addHolder(String.valueOf(value));
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
@@ -330,7 +319,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper addValue(double value) {
- return addHolder(String.valueOf(value));
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
@@ -342,7 +332,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper addValue(float value) {
- return addHolder(String.valueOf(value));
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
@@ -354,7 +345,8 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper addValue(int value) {
- return addHolder(String.valueOf(value));
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
@@ -366,63 +358,31 @@ public final class Objects {
* @since 11.0 (source-compatible since 2.0)
*/
public ToStringHelper addValue(long value) {
- return addHolder(String.valueOf(value));
+ maybeAppendSeparator().append(value);
+ return this;
}
/**
* Returns a string in the format specified by {@link
* Objects#toStringHelper(Object)}.
- *
- * <p>After calling this method, you can keep adding more properties to later
- * call toString() again and get a more complete representation of the
- * same object; but properties cannot be removed, so this only allows
- * limited reuse of the helper instance. The helper allows duplication of
- * properties (multiple name/value pairs with the same name can be added).
*/
@Override public String toString() {
- // create a copy to keep it consistent in case value changes
- boolean omitNullValuesSnapshot = omitNullValues;
- String nextSeparator = "";
- StringBuilder builder = new StringBuilder(32).append(className)
- .append('{');
- for (ValueHolder valueHolder = holderHead.next; valueHolder != null;
- valueHolder = valueHolder.next) {
- if (!omitNullValuesSnapshot || valueHolder.value != null) {
- builder.append(nextSeparator);
- nextSeparator = ", ";
-
- if (valueHolder.name != null) {
- builder.append(valueHolder.name).append('=');
- }
- builder.append(valueHolder.value);
- }
+ try {
+ return builder.append('}').toString();
+ } finally {
+ // Slice off the closing brace in case there are additional calls to
+ // #add or #addValue.
+ builder.setLength(builder.length() - 1);
}
- return builder.append('}').toString();
}
- private ValueHolder addHolder() {
- ValueHolder valueHolder = new ValueHolder();
- holderTail = holderTail.next = valueHolder;
- return valueHolder;
- }
-
- private ToStringHelper addHolder(@Nullable Object value) {
- ValueHolder valueHolder = addHolder();
- valueHolder.value = value;
- return this;
- }
-
- private ToStringHelper addHolder(String name, @Nullable Object value) {
- ValueHolder valueHolder = addHolder();
- valueHolder.value = value;
- valueHolder.name = checkNotNull(name);
- return this;
- }
-
- private static final class ValueHolder {
- String name;
- Object value;
- ValueHolder next;
+ private StringBuilder maybeAppendSeparator() {
+ if (needsSeparator) {
+ return builder.append(", ");
+ } else {
+ needsSeparator = true;
+ return builder;
+ }
}
}
}
diff --git a/guava/src/com/google/common/base/Optional.java b/guava/src/com/google/common/base/Optional.java
index de3139c..035f96c 100644
--- a/guava/src/com/google/common/base/Optional.java
+++ b/guava/src/com/google/common/base/Optional.java
@@ -22,6 +22,7 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.io.Serializable;
+import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
@@ -58,10 +59,6 @@ import javax.annotation.Nullable;
* <p>This class is not intended as a direct analogue of any existing "option" or "maybe"
* construct from other programming environments, though it may bear some similarities.
*
- * <p>See the Guava User Guide article on <a
- * href="http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional">
- * using {@code Optional}</a>.
- *
* @param <T> the type of instance that can be contained. {@code Optional} is naturally
* covariant on this type, so it is safe to cast an {@code Optional<T>} to {@code
* Optional<S>} for any supertype {@code S} of {@code T}.
@@ -69,7 +66,8 @@ import javax.annotation.Nullable;
* @author Kevin Bourrillion
* @since 10.0
*/
-@GwtCompatible(serializable = true)
+@Beta
+@GwtCompatible
public abstract class Optional<T> implements Serializable {
/**
* Returns an {@code Optional} instance with no contained reference.
@@ -96,7 +94,7 @@ public abstract class Optional<T> implements Serializable {
: new Present<T>(nullableReference);
}
- Optional() {}
+ private Optional() {}
/**
* Returns {@code true} if this holder contains a (non-null) instance.
@@ -116,30 +114,6 @@ public abstract class Optional<T> implements Serializable {
* Returns the contained instance if it is present; {@code defaultValue} otherwise. If
* no default value should be required because the instance is known to be present, use
* {@link #get()} instead. For a default value of {@code null}, use {@link #orNull}.
- *
- * <p>Note about generics: The signature {@code public T or(T defaultValue)} is overly
- * restrictive. However, the ideal signature, {@code public <S super T> S or(S)}, is not legal
- * Java. As a result, some sensible operations involving subtypes are compile errors:
- * <pre> {@code
- *
- * Optional<Integer> optionalInt = getSomeOptionalInt();
- * Number value = optionalInt.or(0.5); // error
- *
- * FluentIterable<? extends Number> numbers = getSomeNumbers();
- * Optional<? extends Number> first = numbers.first();
- * Number value = first.or(0.5); // error}</pre>
- *
- * As a workaround, it is always safe to cast an {@code Optional<? extends T>} to {@code
- * Optional<T>}. Casting either of the above example {@code Optional} instances to {@code
- * Optional<Number>} (where {@code Number} is the desired output type) solves the problem:
- * <pre> {@code
- *
- * Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
- * Number value = optionalInt.or(0.5); // fine
- *
- * FluentIterable<? extends Number> numbers = getSomeNumbers();
- * Optional<Number> first = (Optional) numbers.first();
- * Number value = first.or(0.5); // fine}</pre>
*/
public abstract T or(T defaultValue);
@@ -151,83 +125,63 @@ public abstract class Optional<T> implements Serializable {
/**
* Returns the contained instance if it is present; {@code supplier.get()} otherwise. If the
- * supplier returns {@code null}, a {@link NullPointerException} is thrown.
+ * supplier returns {@code null}, a {@link NullPointerException} will be thrown.
*
* @throws NullPointerException if the supplier returns {@code null}
*/
- @Beta
public abstract T or(Supplier<? extends T> supplier);
/**
* Returns the contained instance if it is present; {@code null} otherwise. If the
* instance is known to be present, use {@link #get()} instead.
*/
- @Nullable
- public abstract T orNull();
+ @Nullable public abstract T orNull();
/**
- * Returns an immutable singleton {@link Set} whose only element is the contained instance
- * if it is present; an empty immutable {@link Set} otherwise.
+ * Returns an immutable singleton {@link Set} whose only element is the
+ * contained instance if it is present; an empty immutable {@link Set}
+ * otherwise.
*
* @since 11.0
*/
public abstract Set<T> asSet();
/**
- * If the instance is present, it is transformed with the given {@link Function}; otherwise,
- * {@link Optional#absent} is returned. If the function returns {@code null}, a
- * {@link NullPointerException} is thrown.
- *
- * @throws NullPointerException if the function returns {@code null}
- *
- * @since 12.0
- */
- public abstract <V> Optional<V> transform(Function<? super T, V> function);
-
- /**
* Returns {@code true} if {@code object} is an {@code Optional} instance, and either
* the contained references are {@linkplain Object#equals equal} to each other or both
* are absent. Note that {@code Optional} instances of differing parameterized types can
* be equal.
*/
- @Override
- public abstract boolean equals(@Nullable Object object);
+ @Override public abstract boolean equals(@Nullable Object object);
/**
* Returns a hash code for this instance.
*/
- @Override
- public abstract int hashCode();
+ @Override public abstract int hashCode();
/**
* Returns a string representation for this instance. The form of this string
* representation is unspecified.
*/
- @Override
- public abstract String toString();
+ @Override public abstract String toString();
/**
* Returns the value of each present instance from the supplied {@code optionals}, in order,
* skipping over occurrences of {@link Optional#absent}. Iterators are unmodifiable and are
* evaluated lazily.
*
- * @since 11.0 (generics widened in 13.0)
+ * @since 11.0
*/
- @Beta
- public static <T> Iterable<T> presentInstances(
- final Iterable<? extends Optional<? extends T>> optionals) {
+ public static <T> Iterable<T> presentInstances(final Iterable<Optional<T>> optionals) {
checkNotNull(optionals);
return new Iterable<T>() {
- @Override
- public Iterator<T> iterator() {
+ @Override public Iterator<T> iterator() {
return new AbstractIterator<T>() {
- private final Iterator<? extends Optional<? extends T>> iterator =
- checkNotNull(optionals.iterator());
+ private final Iterator<Optional<T>> iterator = checkNotNull(optionals.iterator());
- @Override
- protected T computeNext() {
+ @Override protected T computeNext() {
while (iterator.hasNext()) {
- Optional<? extends T> optional = iterator.next();
+ Optional<T> optional = iterator.next();
if (optional.isPresent()) {
return optional.get();
}
@@ -235,9 +189,118 @@ public abstract class Optional<T> implements Serializable {
return endOfData();
}
};
- }
+ };
};
}
private static final long serialVersionUID = 0;
+
+ private static final class Present<T> extends Optional<T> {
+ private final T reference;
+
+ Present(T reference) {
+ this.reference = reference;
+ }
+
+ @Override public boolean isPresent() {
+ return true;
+ }
+
+ @Override public T get() {
+ return reference;
+ }
+
+ @Override public T or(T defaultValue) {
+ checkNotNull(defaultValue, "use orNull() instead of or(null)");
+ return reference;
+ }
+
+ @Override public Optional<T> or(Optional<? extends T> secondChoice) {
+ checkNotNull(secondChoice);
+ return this;
+ }
+
+ @Override public T or(Supplier<? extends T> supplier) {
+ checkNotNull(supplier);
+ return reference;
+ }
+
+ @Override public T orNull() {
+ return reference;
+ }
+
+ @Override public Set<T> asSet() {
+ return Collections.singleton(reference);
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object instanceof Present) {
+ Present<?> other = (Present<?>) object;
+ return reference.equals(other.reference);
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return 0x598df91c + reference.hashCode();
+ }
+
+ @Override public String toString() {
+ return "Optional.of(" + reference + ")";
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ private static final class Absent extends Optional<Object> {
+ private static final Absent INSTANCE = new Absent();
+
+ @Override public boolean isPresent() {
+ return false;
+ }
+
+ @Override public Object get() {
+ throw new IllegalStateException("value is absent");
+ }
+
+ @Override public Object or(Object defaultValue) {
+ return checkNotNull(defaultValue, "use orNull() instead of or(null)");
+ }
+
+ @SuppressWarnings("unchecked") // safe covariant cast
+ @Override public Optional<Object> or(Optional<?> secondChoice) {
+ return (Optional) checkNotNull(secondChoice);
+ }
+
+ @Override public Object or(Supplier<?> supplier) {
+ return checkNotNull(supplier.get(),
+ "use orNull() instead of a Supplier that returns null");
+ }
+
+ @Override @Nullable public Object orNull() {
+ return null;
+ }
+
+ @Override public Set<Object> asSet() {
+ return Collections.emptySet();
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return object == this;
+ }
+
+ @Override public int hashCode() {
+ return 0x598df91c;
+ }
+
+ @Override public String toString() {
+ return "Optional.absent()";
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
}
diff --git a/guava/src/com/google/common/base/Preconditions.java b/guava/src/com/google/common/base/Preconditions.java
index 802a309..4c22f1e 100644
--- a/guava/src/com/google/common/base/Preconditions.java
+++ b/guava/src/com/google/common/base/Preconditions.java
@@ -53,10 +53,6 @@ import javax.annotation.Nullable;
* perhaps ever. Postcondition or other invariant failures should not throw
* these types of exceptions.
*
- * <p>See the Guava User Guide on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PreconditionsExplained">
- * using {@code Preconditions}</a>.
- *
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
diff --git a/guava/src/com/google/common/base/Predicate.java b/guava/src/com/google/common/base/Predicate.java
index 7345742..08d9f64 100644
--- a/guava/src/com/google/common/base/Predicate.java
+++ b/guava/src/com/google/common/base/Predicate.java
@@ -23,12 +23,6 @@ import javax.annotation.Nullable;
/**
* Determines a true or false value for a given input.
*
- * <p>The {@link Predicates} class provides common predicates and related utilities.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the use of {@code
- * Predicate}</a>.
- *
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
diff --git a/guava/src/com/google/common/base/Predicates.java b/guava/src/com/google/common/base/Predicates.java
index aa12750..5c77a28 100644
--- a/guava/src/com/google/common/base/Predicates.java
+++ b/guava/src/com/google/common/base/Predicates.java
@@ -37,10 +37,6 @@ import javax.annotation.Nullable;
* <p>All methods returns serializable predicates as long as they're given
* serializable parameters.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/FunctionalExplained">the
- * use of {@code Predicate}</a>.
- *
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
@@ -200,12 +196,12 @@ public final class Predicates {
public static Predicate<Object> instanceOf(Class<?> clazz) {
return new InstanceOfPredicate(clazz);
}
-
+
/**
* Returns a predicate that evaluates to {@code true} if the class being
* tested is assignable from the given class. The returned predicate
* does not allow null inputs.
- *
+ *
* @since 10.0
*/
@GwtIncompatible("Class.isAssignableFrom")
@@ -293,7 +289,7 @@ public final class Predicates {
return o != null;
}
};
-
+
@SuppressWarnings("unchecked") // these Object predicates work for any T
<T> Predicate<T> withNarrowedType() {
return (Predicate<T>) this;
@@ -308,7 +304,7 @@ public final class Predicates {
this.predicate = checkNotNull(predicate);
}
@Override
- public boolean apply(@Nullable T t) {
+ public boolean apply(T t) {
return !predicate.apply(t);
}
@Override public int hashCode() {
@@ -337,8 +333,7 @@ public final class Predicates {
this.components = components;
}
@Override
- public boolean apply(@Nullable T t) {
- // Avoid using the Iterator to avoid generating garbage (issue 820).
+ public boolean apply(T t) {
for (int i = 0; i < components.size(); i++) {
if (!components.get(i).apply(t)) {
return false;
@@ -347,7 +342,7 @@ public final class Predicates {
return true;
}
@Override public int hashCode() {
- // add a random number to avoid collisions with OrPredicate
+ // 0x12472c2c is a random number to help avoid collisions with OrPredicate
return components.hashCode() + 0x12472c2c;
}
@Override public boolean equals(@Nullable Object obj) {
@@ -371,8 +366,7 @@ public final class Predicates {
this.components = components;
}
@Override
- public boolean apply(@Nullable T t) {
- // Avoid using the Iterator to avoid generating garbage (issue 820).
+ public boolean apply(T t) {
for (int i = 0; i < components.size(); i++) {
if (components.get(i).apply(t)) {
return true;
@@ -381,7 +375,7 @@ public final class Predicates {
return false;
}
@Override public int hashCode() {
- // add a random number to avoid collisions with AndPredicate
+ // 0x053c91cf is a random number to help avoid collisions with AndPredicate
return components.hashCode() + 0x053c91cf;
}
@Override public boolean equals(@Nullable Object obj) {
@@ -453,7 +447,7 @@ public final class Predicates {
}
private static final long serialVersionUID = 0;
}
-
+
/** @see Predicates#assignableFrom(Class) */
@GwtIncompatible("Class.isAssignableFrom")
private static class AssignableFromPredicate
@@ -492,7 +486,7 @@ public final class Predicates {
}
@Override
- public boolean apply(@Nullable T t) {
+ public boolean apply(T t) {
try {
return target.contains(t);
} catch (NullPointerException e) {
@@ -532,7 +526,7 @@ public final class Predicates {
}
@Override
- public boolean apply(@Nullable A a) {
+ public boolean apply(A a) {
return p.apply(f.apply(a));
}
diff --git a/guava/src/com/google/common/base/Present.java b/guava/src/com/google/common/base/Present.java
deleted file mode 100644
index bcde922..0000000
--- a/guava/src/com/google/common/base/Present.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Collections;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of an {@link Optional} containing a reference.
- */
-@GwtCompatible
-final class Present<T> extends Optional<T> {
- private final T reference;
-
- Present(T reference) {
- this.reference = reference;
- }
-
- @Override public boolean isPresent() {
- return true;
- }
-
- @Override public T get() {
- return reference;
- }
-
- @Override public T or(T defaultValue) {
- checkNotNull(defaultValue, "use Optional.orNull() instead of Optional.or(null)");
- return reference;
- }
-
- @Override public Optional<T> or(Optional<? extends T> secondChoice) {
- checkNotNull(secondChoice);
- return this;
- }
-
- @Override public T or(Supplier<? extends T> supplier) {
- checkNotNull(supplier);
- return reference;
- }
-
- @Override public T orNull() {
- return reference;
- }
-
- @Override public Set<T> asSet() {
- return Collections.singleton(reference);
- }
-
- @Override public <V> Optional<V> transform(Function<? super T, V> function) {
- return new Present<V>(checkNotNull(function.apply(reference),
- "the Function passed to Optional.transform() must not return null."));
- }
-
- @Override public boolean equals(@Nullable Object object) {
- if (object instanceof Present) {
- Present<?> other = (Present<?>) object;
- return reference.equals(other.reference);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return 0x598df91c + reference.hashCode();
- }
-
- @Override public String toString() {
- return "Optional.of(" + reference + ")";
- }
-
- private static final long serialVersionUID = 0;
-}
diff --git a/guava/src/com/google/common/base/SmallCharMatcher.java b/guava/src/com/google/common/base/SmallCharMatcher.java
deleted file mode 100644
index 10234c5..0000000
--- a/guava/src/com/google/common/base/SmallCharMatcher.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.CharMatcher.FastMatcher;
-
-import java.util.BitSet;
-
-/**
- * An immutable version of CharMatcher for smallish sets of characters that uses a hash table
- * with linear probing to check for matches.
- *
- * @author Christopher Swenson
- */
-@GwtIncompatible("no precomputation is done in GWT")
-final class SmallCharMatcher extends FastMatcher {
- static final int MAX_SIZE = 1023;
- private final char[] table;
- private final boolean containsZero;
- private final long filter;
-
- private SmallCharMatcher(char[] table, long filter, boolean containsZero,
- String description) {
- super(description);
- this.table = table;
- this.filter = filter;
- this.containsZero = containsZero;
- }
-
- private static final int C1 = 0xcc9e2d51;
- private static final int C2 = 0x1b873593;
-
- /*
- * This method was rewritten in Java from an intermediate step of the Murmur hash function in
- * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp, which contained the
- * following header:
- *
- * MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author
- * hereby disclaims copyright to this source code.
- */
- static int smear(int hashCode) {
- return C2 * Integer.rotateLeft(hashCode * C1, 15);
- }
-
- private boolean checkFilter(int c) {
- return 1 == (1 & (filter >> c));
- }
-
- // This is all essentially copied from ImmutableSet, but we have to duplicate because
- // of dependencies.
-
- // Represents how tightly we can pack things, as a maximum.
- private static final double DESIRED_LOAD_FACTOR = 0.5;
-
- /**
- * Returns an array size suitable for the backing array of a hash table that
- * uses open addressing with linear probing in its implementation. The
- * returned size is the smallest power of two that can hold setSize elements
- * with the desired load factor.
- */
- @VisibleForTesting static int chooseTableSize(int setSize) {
- if (setSize == 1) {
- return 2;
- }
- // Correct the size for open addressing to match desired load factor.
- // Round up to the next highest power of 2.
- int tableSize = Integer.highestOneBit(setSize - 1) << 1;
- while (tableSize * DESIRED_LOAD_FACTOR < setSize) {
- tableSize <<= 1;
- }
- return tableSize;
- }
-
- @GwtIncompatible("java.util.BitSet")
- static CharMatcher from(BitSet chars, String description) {
- // Compute the filter.
- long filter = 0;
- int size = chars.cardinality();
- boolean containsZero = chars.get(0);
- // Compute the hash table.
- char[] table = new char[chooseTableSize(size)];
- int mask = table.length - 1;
- for (int c = chars.nextSetBit(0); c != -1; c = chars.nextSetBit(c + 1)) {
- // Compute the filter at the same time.
- filter |= 1L << c;
- int index = smear(c) & mask;
- while (true) {
- // Check for empty.
- if (table[index] == 0) {
- table[index] = (char) c;
- break;
- }
- // Linear probing.
- index = (index + 1) & mask;
- }
- }
- return new SmallCharMatcher(table, filter, containsZero, description);
- }
-
- @Override
- public boolean matches(char c) {
- if (c == 0) {
- return containsZero;
- }
- if (!checkFilter(c)) {
- return false;
- }
- int mask = table.length - 1;
- int startingIndex = smear(c) & mask;
- int index = startingIndex;
- do {
- // Check for empty.
- if (table[index] == 0) {
- return false;
- // Check for match.
- } else if (table[index] == c) {
- return true;
- } else {
- // Linear probing.
- index = (index + 1) & mask;
- }
- // Check to see if we wrapped around the whole table.
- } while (index != startingIndex);
- return false;
- }
-
- @GwtIncompatible("java.util.BitSet")
- @Override
- void setBits(BitSet table) {
- if (containsZero) {
- table.set(0);
- }
- for (char c : this.table) {
- if (c != 0) {
- table.set(c);
- }
- }
- }
-}
diff --git a/guava/src/com/google/common/base/Splitter.java b/guava/src/com/google/common/base/Splitter.java
index b9e820f..da7da95 100644
--- a/guava/src/com/google/common/base/Splitter.java
+++ b/guava/src/com/google/common/base/Splitter.java
@@ -33,63 +33,60 @@ import java.util.regex.Pattern;
import javax.annotation.CheckReturnValue;
/**
- * Extracts non-overlapping substrings from an input string, typically by
- * recognizing appearances of a <i>separator</i> sequence. This separator can be
- * specified as a single {@linkplain #on(char) character}, fixed {@linkplain
- * #on(String) string}, {@linkplain #onPattern regular expression} or {@link
- * #on(CharMatcher) CharMatcher} instance. Or, instead of using a separator at
- * all, a splitter can extract adjacent substrings of a given {@linkplain
- * #fixedLength fixed length}.
+ * An object that divides strings (or other instances of {@code CharSequence})
+ * into substrings, by recognizing a <i>separator</i> (a.k.a. "delimiter")
+ * which can be expressed as a single character, literal string, regular
+ * expression, {@code CharMatcher}, or by using a fixed substring length. This
+ * class provides the complementary functionality to {@link Joiner}.
*
- * <p>For example, this expression: <pre> {@code
+ * <p>Here is the most basic example of {@code Splitter} usage: <pre> {@code
*
- * Splitter.on(',').split("foo,bar,qux")}</pre>
+ * Splitter.on(',').split("foo,bar")}</pre>
*
- * ... produces an {@code Iterable} containing {@code "foo"}, {@code "bar"} and
- * {@code "qux"}, in that order.
+ * This invocation returns an {@code Iterable<String>} containing {@code "foo"}
+ * and {@code "bar"}, in that order.
*
- * <p>By default, {@code Splitter}'s behavior is simplistic and unassuming. The
- * following expression: <pre> {@code
+ * <p>By default {@code Splitter}'s behavior is very simplistic: <pre> {@code
*
- * Splitter.on(',').split(" foo,,, bar ,")}</pre>
+ * Splitter.on(',').split("foo,,bar, quux")}</pre>
*
- * ... yields the substrings {@code [" foo", "", "", " bar ", ""]}. If this
- * is not the desired behavior, use configuration methods to obtain a <i>new</i>
- * splitter instance with modified behavior: <pre> {@code
+ * This returns an iterable containing {@code ["foo", "", "bar", " quux"]}.
+ * Notice that the splitter does not assume that you want empty strings removed,
+ * or that you wish to trim whitespace. If you want features like these, simply
+ * ask for them: <pre> {@code
*
* private static final Splitter MY_SPLITTER = Splitter.on(',')
* .trimResults()
* .omitEmptyStrings();}</pre>
*
- * Now {@code MY_SPLITTER.split("foo,,, bar ,")} returns just {@code ["foo",
- * "bar"]}. Note that the order in which these configuration methods are called
- * is never significant.
+ * Now {@code MY_SPLITTER.split("foo, ,bar, quux,")} returns an iterable
+ * containing just {@code ["foo", "bar", "quux"]}. Note that the order in which
+ * the configuration methods are called is never significant; for instance,
+ * trimming is always applied first before checking for an empty result,
+ * regardless of the order in which the {@link #trimResults()} and
+ * {@link #omitEmptyStrings()} methods were invoked.
*
- * <p><b>Warning:</b> Splitter instances are immutable. Invoking a configuration
- * method has no effect on the receiving instance; you must store and use the
- * new splitter instance it returns instead. <pre> {@code
+ * <p><b>Warning: splitter instances are always immutable</b>; a configuration
+ * method such as {@code omitEmptyStrings} has no effect on the instance it
+ * is invoked on! You must store and use the new splitter instance returned by
+ * the method. This makes splitters thread-safe, and safe to store as {@code
+ * static final} constants (as illustrated above). <pre> {@code
*
- * // Do NOT do this
+ * // Bad! Do not do this!
* Splitter splitter = Splitter.on('/');
* splitter.trimResults(); // does nothing!
* return splitter.split("wrong / wrong / wrong");}</pre>
*
- * <p>For separator-based splitters that do not use {@code omitEmptyStrings}, an
- * input string containing {@code n} occurrences of the separator naturally
- * yields an iterable of size {@code n + 1}. So if the separator does not occur
- * anywhere in the input, a single substring is returned containing the entire
- * input. Consequently, all splitters split the empty string to {@code [""]}
- * (note: even fixed-length splitters).
+ * The separator recognized by the splitter does not have to be a single
+ * literal character as in the examples above. See the methods {@link
+ * #on(String)}, {@link #on(Pattern)} and {@link #on(CharMatcher)} for examples
+ * of other ways to specify separators.
*
- * <p>Splitter instances are thread-safe immutable, and are therefore safe to
- * store as {@code static final} constants.
- *
- * <p>The {@link Joiner} class provides the inverse operation to splitting, but
- * note that a round-trip between the two should be assumed to be lossy.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/StringsExplained#Splitter">
- * {@code Splitter}</a>.
+ * <p><b>Note:</b> this class does not mimic any of the quirky behaviors of
+ * similar JDK methods; for instance, it does not silently discard trailing
+ * separators, as does {@link String#split(String)}, nor does it have a default
+ * behavior of using five particular whitespace characters as separators, like
+ * {@link java.util.StringTokenizer}.
*
* @author Julien Silland
* @author Jesse Wilson
@@ -159,8 +156,8 @@ public final class Splitter {
/**
* Returns a splitter that uses the given fixed string as a separator. For
- * example, {@code Splitter.on(", ").split("foo, bar,baz")} returns an
- * iterable containing {@code ["foo", "bar,baz"]}.
+ * example, {@code Splitter.on(", ").split("foo, bar, baz,qux")} returns an
+ * iterable containing {@code ["foo", "bar", "baz,qux"]}.
*
* @param separator the literal, nonempty string to recognize as a separator
* @return a splitter, with default settings, that recognizes that separator
@@ -258,18 +255,9 @@ public final class Splitter {
* iterable containing {@code ["ab", "cd", "e"]}. The last piece can be
* smaller than {@code length} but will never be empty.
*
- * <p><b>Exception:</b> for consistency with separator-based splitters, {@code
- * split("")} does not yield an empty iterable, but an iterable containing
- * {@code ""}. This is the only case in which {@code
- * Iterables.size(split(input))} does not equal {@code
- * IntMath.divide(input.length(), length, CEILING)}. To avoid this behavior,
- * use {@code omitEmptyStrings}.
- *
- * @param length the desired length of pieces after splitting, a positive
- * integer
+ * @param length the desired length of pieces after splitting
* @return a splitter, with default settings, that can split into fixed sized
* pieces
- * @throws IllegalArgumentException if {@code length} is zero or negative
*/
public static Splitter fixedLength(final int length) {
checkArgument(length > 0, "The length may not be less than 1");
@@ -386,12 +374,6 @@ public final class Splitter {
@Override public Iterator<String> iterator() {
return spliterator(sequence);
}
- @Override public String toString() {
- return Joiner.on(", ")
- .appendTo(new StringBuilder().append('['), this)
- .append(']')
- .toString();
- }
};
}
@@ -413,18 +395,6 @@ public final class Splitter {
/**
* Returns a {@code MapSplitter} which splits entries based on this splitter,
- * and splits entries into keys and values using the specified separator.
- *
- * @since 14.0
- */
- @CheckReturnValue
- @Beta
- public MapSplitter withKeyValueSeparator(char separator) {
- return withKeyValueSeparator(on(separator));
- }
-
- /**
- * Returns a {@code MapSplitter} which splits entries based on this splitter,
* and splits entries into keys and values using the specified key-value
* splitter.
*
@@ -493,7 +463,8 @@ public final class Splitter {
Iterator<String> iterator(Splitter splitter, CharSequence toSplit);
}
- private abstract static class SplittingIterator extends AbstractIterator<String> {
+ private abstract static class SplittingIterator
+ extends AbstractIterator<String> {
final CharSequence toSplit;
final CharMatcher trimmer;
final boolean omitEmptyStrings;
@@ -522,15 +493,8 @@ public final class Splitter {
}
@Override protected String computeNext() {
- /*
- * The returned string will be from the end of the last match to the
- * beginning of the next one. nextStart is the start position of the
- * returned substring, while offset is the place to start looking for a
- * separator.
- */
- int nextStart = offset;
while (offset != -1) {
- int start = nextStart;
+ int start = offset;
int end;
int separatorPosition = separatorStart(offset);
@@ -541,20 +505,6 @@ public final class Splitter {
end = separatorPosition;
offset = separatorEnd(separatorPosition);
}
- if (offset == nextStart) {
- /*
- * This occurs when some pattern has an empty match, even if it
- * doesn't match the empty string -- for example, if it requires
- * lookahead or the like. The offset must be increased to look for
- * separators beyond this point, without changing the start position
- * of the next returned substring -- so nextStart stays the same.
- */
- offset++;
- if (offset >= toSplit.length()) {
- offset = -1;
- }
- continue;
- }
while (start < end && trimmer.matches(toSplit.charAt(start))) {
start++;
@@ -564,8 +514,6 @@ public final class Splitter {
}
if (omitEmptyStrings && start == end) {
- // Don't include the (unused) separator in next split string.
- nextStart = offset;
continue;
}
diff --git a/guava/src/com/google/common/base/Stopwatch.java b/guava/src/com/google/common/base/Stopwatch.java
index bcd898a..ec9cc9c 100644
--- a/guava/src/com/google/common/base/Stopwatch.java
+++ b/guava/src/com/google/common/base/Stopwatch.java
@@ -50,7 +50,7 @@ import java.util.concurrent.TimeUnit;
* doSomething();
* stopwatch.{@link #stop stop}(); // optional
*
- * long millis = stopwatch.elapsed(MILLISECONDS);
+ * long millis = stopwatch.{@link #elapsedMillis elapsedMillis}();
*
* log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
* </pre>
@@ -69,7 +69,7 @@ import java.util.concurrent.TimeUnit;
* @since 10.0
*/
@Beta
-@GwtCompatible(emulated = true)
+@GwtCompatible(emulated=true)
public final class Stopwatch {
private final Ticker ticker;
private boolean isRunning;
@@ -89,7 +89,7 @@ public final class Stopwatch {
* source.
*/
public Stopwatch(Ticker ticker) {
- this.ticker = checkNotNull(ticker, "ticker");
+ this.ticker = checkNotNull(ticker);
}
/**
@@ -108,8 +108,7 @@ public final class Stopwatch {
* @throws IllegalStateException if the stopwatch is already running.
*/
public Stopwatch start() {
- checkState(!isRunning,
- "This stopwatch is already running; it cannot be started more than once.");
+ checkState(!isRunning);
isRunning = true;
startTick = ticker.read();
return this;
@@ -124,8 +123,7 @@ public final class Stopwatch {
*/
public Stopwatch stop() {
long tick = ticker.read();
- checkState(isRunning,
- "This stopwatch is already stopped; it cannot be stopped more than once.");
+ checkState(isRunning);
isRunning = false;
elapsedNanos += tick - startTick;
return this;
@@ -154,44 +152,23 @@ public final class Stopwatch {
* <p>Note that the overhead of measurement can be more than a microsecond, so
* it is generally not useful to specify {@link TimeUnit#NANOSECONDS}
* precision here.
- *
- * @since 14.0 (since 10.0 as {@code elapsedTime()})
- */
- public long elapsed(TimeUnit desiredUnit) {
- return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
- }
-
- /**
- * Returns the current elapsed time shown on this stopwatch, expressed
- * in the desired time unit, with any fraction rounded down.
- *
- * <p>Note that the overhead of measurement can be more than a microsecond, so
- * it is generally not useful to specify {@link TimeUnit#NANOSECONDS}
- * precision here.
- *
- * @deprecated Use {@link Stopwatch#elapsed(TimeUnit)} instead. This method is
- * scheduled to be removed in Guava release 16.0.
*/
- @Deprecated
public long elapsedTime(TimeUnit desiredUnit) {
- return elapsed(desiredUnit);
+ return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
}
/**
* Returns the current elapsed time shown on this stopwatch, expressed
* in milliseconds, with any fraction rounded down. This is identical to
- * {@code elapsed(TimeUnit.MILLISECONDS)}.
- *
- * @deprecated Use {@code stopwatch.elapsed(MILLISECONDS)} instead. This
- * method is scheduled to be removed in Guava release 16.0.
+ * {@code elapsedTime(TimeUnit.MILLISECONDS}.
*/
- @Deprecated
public long elapsedMillis() {
- return elapsed(MILLISECONDS);
+ return elapsedTime(MILLISECONDS);
}
/**
- * Returns a string representation of the current elapsed time.
+ * Returns a string representation of the current elapsed time; equivalent to
+ * {@code toString(4)} (four significant figures).
*/
@GwtIncompatible("String.format()")
@Override public String toString() {
@@ -201,13 +178,9 @@ public final class Stopwatch {
/**
* Returns a string representation of the current elapsed time, choosing an
* appropriate unit and using the specified number of significant figures.
- * For example, at the instant when {@code elapsed(NANOSECONDS)} would
+ * For example, at the instant when {@code elapsedTime(NANOSECONDS)} would
* return {1234567}, {@code toString(4)} returns {@code "1.235 ms"}.
- *
- * @deprecated Use {@link #toString()} instead. This method is scheduled
- * to be removed in Guava release 15.0.
*/
- @Deprecated
@GwtIncompatible("String.format()")
public String toString(int significantDigits) {
long nanos = elapsedNanos();
diff --git a/guava/src/com/google/common/base/Strings.java b/guava/src/com/google/common/base/Strings.java
index 45007fd..7697452 100644
--- a/guava/src/com/google/common/base/Strings.java
+++ b/guava/src/com/google/common/base/Strings.java
@@ -19,6 +19,7 @@ package com.google.common.base;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
@@ -185,6 +186,7 @@ public final class Strings {
*
* @since 11.0
*/
+ @Beta
public static String commonPrefix(CharSequence a, CharSequence b) {
checkNotNull(a);
checkNotNull(b);
@@ -208,6 +210,7 @@ public final class Strings {
*
* @since 11.0
*/
+ @Beta
public static String commonSuffix(CharSequence a, CharSequence b) {
checkNotNull(a);
checkNotNull(b);
diff --git a/guava/src/com/google/common/base/Suppliers.java b/guava/src/com/google/common/base/Suppliers.java
index 468ce8b..5f418c0 100644
--- a/guava/src/com/google/common/base/Suppliers.java
+++ b/guava/src/com/google/common/base/Suppliers.java
@@ -62,27 +62,10 @@ public final class Suppliers {
this.function = function;
this.supplier = supplier;
}
-
- @Override public T get() {
+ @Override
+ public T get() {
return function.apply(supplier.get());
}
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof SupplierComposition) {
- SupplierComposition<?, ?> that = (SupplierComposition<?, ?>) obj;
- return function.equals(that.function) && supplier.equals(that.supplier);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return Objects.hashCode(function, supplier);
- }
-
- @Override public String toString() {
- return "Suppliers.compose(" + function + ", " + supplier + ")";
- }
-
private static final long serialVersionUID = 0;
}
@@ -117,7 +100,8 @@ public final class Suppliers {
this.delegate = delegate;
}
- @Override public T get() {
+ @Override
+ public T get() {
// A 2-field variant of Double Checked Locking.
if (!initialized) {
synchronized (this) {
@@ -132,10 +116,6 @@ public final class Suppliers {
return value;
}
- @Override public String toString() {
- return "Suppliers.memoize(" + delegate + ")";
- }
-
private static final long serialVersionUID = 0;
}
@@ -177,7 +157,8 @@ public final class Suppliers {
Preconditions.checkArgument(duration > 0);
}
- @Override public T get() {
+ @Override
+ public T get() {
// Another variant of Double Checked Locking.
//
// We use two volatile reads. We could reduce this to one by
@@ -202,13 +183,6 @@ public final class Suppliers {
return value;
}
- @Override public String toString() {
- // This is a little strange if the unit the user provided was not NANOS,
- // but we don't want to store the unit just for toString
- return "Suppliers.memoizeWithExpiration(" + delegate + ", " +
- durationNanos + ", NANOS)";
- }
-
private static final long serialVersionUID = 0;
}
@@ -226,27 +200,10 @@ public final class Suppliers {
SupplierOfInstance(@Nullable T instance) {
this.instance = instance;
}
-
- @Override public T get() {
+ @Override
+ public T get() {
return instance;
}
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof SupplierOfInstance) {
- SupplierOfInstance<?> that = (SupplierOfInstance<?>) obj;
- return Objects.equal(instance, that.instance);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return Objects.hashCode(instance);
- }
-
- @Override public String toString() {
- return "Suppliers.ofInstance(" + instance + ")";
- }
-
private static final long serialVersionUID = 0;
}
@@ -265,17 +222,12 @@ public final class Suppliers {
ThreadSafeSupplier(Supplier<T> delegate) {
this.delegate = delegate;
}
-
- @Override public T get() {
+ @Override
+ public T get() {
synchronized (delegate) {
return delegate.get();
}
}
-
- @Override public String toString() {
- return "Suppliers.synchronizedSupplier(" + delegate + ")";
- }
-
private static final long serialVersionUID = 0;
}
@@ -286,8 +238,7 @@ public final class Suppliers {
* @since 8.0
*/
@Beta
- //SupplierFunction works for any T.
- @SuppressWarnings({"unchecked", "rawtypes"})
+ @SuppressWarnings("unchecked") // SupplierFunction works for any T.
public static <T> Function<Supplier<T>, T> supplierFunction() {
return (Function) SupplierFunction.INSTANCE;
}
@@ -295,12 +246,9 @@ public final class Suppliers {
private enum SupplierFunction implements Function<Supplier<?>, Object> {
INSTANCE;
- @Override public Object apply(Supplier<?> input) {
+ @Override
+ public Object apply(Supplier<?> input) {
return input.get();
}
-
- @Override public String toString() {
- return "Suppliers.supplierFunction()";
- }
}
}
diff --git a/guava/src/com/google/common/base/Throwables.java b/guava/src/com/google/common/base/Throwables.java
index 5e4d6ec..793c5f9 100644
--- a/guava/src/com/google/common/base/Throwables.java
+++ b/guava/src/com/google/common/base/Throwables.java
@@ -31,10 +31,6 @@ import javax.annotation.Nullable;
/**
* Static utility methods pertaining to instances of {@link Throwable}.
*
- * <p>See the Guava User Guide entry on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ThrowablesExplained">
- * Throwables</a>.
- *
* @author Kevin Bourrillion
* @author Ben Yu
* @since 1.0
diff --git a/guava/src/com/google/common/base/Ticker.java b/guava/src/com/google/common/base/Ticker.java
index 6c34aef..e074cf1 100644
--- a/guava/src/com/google/common/base/Ticker.java
+++ b/guava/src/com/google/common/base/Ticker.java
@@ -20,11 +20,8 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
/**
- * A time source; returns a time value representing the number of nanoseconds elapsed since some
- * fixed but arbitrary point in time. Note that most users should use {@link Stopwatch} instead of
- * interacting with this class directly.
- *
- * <p><b>Warning:</b> this interface can only be used to measure elapsed time, not wall time.
+ * A time source; returns a time value representing the number of nanoseconds
+ * elapsed since some fixed but arbitrary point in time.
*
* @author Kevin Bourrillion
* @since 10.0
diff --git a/guava/src/com/google/common/base/internal/Finalizer.java b/guava/src/com/google/common/base/internal/Finalizer.java
index ebef272..6be4eec 100644
--- a/guava/src/com/google/common/base/internal/Finalizer.java
+++ b/guava/src/com/google/common/base/internal/Finalizer.java
@@ -46,7 +46,7 @@ import java.util.logging.Logger;
* class loader from getting garbage collected, and this class can detect when
* the main class loader has been garbage collected and stop itself.
*/
-public class Finalizer implements Runnable {
+public class Finalizer extends Thread {
private static final Logger logger
= Logger.getLogger(Finalizer.class.getName());
@@ -59,16 +59,13 @@ public class Finalizer implements Runnable {
* Starts the Finalizer thread. FinalizableReferenceQueue calls this method
* reflectively.
*
- * @param finalizableReferenceClass FinalizableReference.class.
- * @param queue a reference queue that the thread will poll.
- * @param frqReference a phantom reference to the FinalizableReferenceQueue, which will be
- * queued either when the FinalizableReferenceQueue is no longer referenced anywhere, or when
- * its close() method is called.
+ * @param finalizableReferenceClass FinalizableReference.class
+ * @param frq reference to instance of FinalizableReferenceQueue that started
+ * this thread
+ * @return ReferenceQueue which Finalizer will poll
*/
- public static void startFinalizer(
- Class<?> finalizableReferenceClass,
- ReferenceQueue<Object> queue,
- PhantomReference<Object> frqReference) {
+ public static ReferenceQueue<Object> startFinalizer(
+ Class<?> finalizableReferenceClass, Object frq) {
/*
* We use FinalizableReference.class for two things:
*
@@ -82,42 +79,40 @@ public class Finalizer implements Runnable {
"Expected " + FINALIZABLE_REFERENCE + ".");
}
- Finalizer finalizer = new Finalizer(finalizableReferenceClass, queue, frqReference);
- Thread thread = new Thread(finalizer);
- thread.setName(Finalizer.class.getName());
- thread.setDaemon(true);
-
- try {
- if (inheritableThreadLocals != null) {
- inheritableThreadLocals.set(thread, null);
- }
- } catch (Throwable t) {
- logger.log(Level.INFO, "Failed to clear thread local values inherited"
- + " by reference finalizer thread.", t);
- }
-
- thread.start();
+ Finalizer finalizer = new Finalizer(finalizableReferenceClass, frq);
+ finalizer.start();
+ return finalizer.queue;
}
private final WeakReference<Class<?>> finalizableReferenceClassReference;
private final PhantomReference<Object> frqReference;
- private final ReferenceQueue<Object> queue;
+ private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
private static final Field inheritableThreadLocals
= getInheritableThreadLocalsField();
/** Constructs a new finalizer thread. */
- private Finalizer(
- Class<?> finalizableReferenceClass,
- ReferenceQueue<Object> queue,
- PhantomReference<Object> frqReference) {
- this.queue = queue;
+ private Finalizer(Class<?> finalizableReferenceClass, Object frq) {
+ super(Finalizer.class.getName());
this.finalizableReferenceClassReference
= new WeakReference<Class<?>>(finalizableReferenceClass);
// Keep track of the FRQ that started us so we know when to stop.
- this.frqReference = frqReference;
+ this.frqReference = new PhantomReference<Object>(frq, queue);
+
+ setDaemon(true);
+
+ try {
+ if (inheritableThreadLocals != null) {
+ inheritableThreadLocals.set(this, null);
+ }
+ } catch (Throwable t) {
+ logger.log(Level.INFO, "Failed to clear thread local values inherited"
+ + " by reference finalizer thread.", t);
+ }
+
+ // TODO(fry): Priority?
}
/**
@@ -208,5 +203,5 @@ public class Finalizer implements Runnable {
/** Indicates that it's time to shut down the Finalizer. */
@SuppressWarnings("serial") // Never serialized or thrown out of this class.
- private static class ShutDown extends Exception {}
+ private static class ShutDown extends Exception { }
}
diff --git a/guava/src/com/google/common/base/package-info.java b/guava/src/com/google/common/base/package-info.java
index c18bd58..66e7177 100644
--- a/guava/src/com/google/common/base/package-info.java
+++ b/guava/src/com/google/common/base/package-info.java
@@ -41,7 +41,8 @@
* {@link com.google.common.base.Functions}
* <li>{@link com.google.common.base.Predicate},
* {@link com.google.common.base.Predicates}
- * <li>{@link com.google.common.base.Equivalence}
+ * <li>{@link com.google.common.base.Equivalence},
+ * {@link com.google.common.base.Equivalences}
* <li>{@link com.google.common.base.Supplier},
* {@link com.google.common.base.Suppliers}
* </ul>
diff --git a/guava/src/com/google/common/cache/AbstractCache.java b/guava/src/com/google/common/cache/AbstractCache.java
index a8af810..8ce941d 100644
--- a/guava/src/com/google/common/cache/AbstractCache.java
+++ b/guava/src/com/google/common/cache/AbstractCache.java
@@ -20,21 +20,22 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicLong;
/**
* This class provides a skeletal implementation of the {@code Cache} interface to minimize the
* effort required to implement this interface.
*
* <p>To implement a cache, the programmer needs only to extend this class and provide an
- * implementation for the {@link #put} and {@link #getIfPresent} methods. {@link #getAllPresent} is
- * implemented in terms of {@link #getIfPresent}; {@link #putAll} is implemented in terms of
- * {@link #put}, {@link #invalidateAll(Iterable)} is implemented in terms of {@link #invalidate}.
- * The method {@link #cleanUp} is a no-op. All other methods throw an
+ * implementation for the {@link #getIfPresent} method. {@link #getAllPresent} is implemented in
+ * terms of {@code getIfPresent}; {@link #invalidateAll(Iterable)} is implemented in terms of
+ * {@link #invalidate}. The method {@link #cleanUp} is a no-op. All other methods throw an
* {@link UnsupportedOperationException}.
*
* @author Charles Fry
@@ -56,22 +57,14 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
}
/**
- * This implementation of {@code getAllPresent} lacks any insight into the internal cache data
- * structure, and is thus forced to return the query keys instead of the cached keys. This is only
- * possible with an unsafe cast which requires {@code keys} to actually be of type {@code K}.
- *
- * {@inheritDoc}
- *
* @since 11.0
*/
@Override
- public ImmutableMap<K, V> getAllPresent(Iterable<?> keys) {
+ public ImmutableMap<K, V> getAllPresent(Iterable<? extends K> keys) {
Map<K, V> result = Maps.newLinkedHashMap();
- for (Object key : keys) {
+ for (K key : keys) {
if (!result.containsKey(key)) {
- @SuppressWarnings("unchecked")
- K castKey = (K) key;
- result.put(castKey, getIfPresent(key));
+ result.put(key, getIfPresent(key));
}
}
return ImmutableMap.copyOf(result);
@@ -85,16 +78,6 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
throw new UnsupportedOperationException();
}
- /**
- * @since 12.0
- */
- @Override
- public void putAll(Map<? extends K, ? extends V> m) {
- for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
- put(entry.getKey(), entry.getValue());
- }
- }
-
@Override
public void cleanUp() {}
@@ -133,6 +116,22 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
throw new UnsupportedOperationException();
}
+ @Deprecated
+ @Override
+ public V getUnchecked(K key) {
+ try {
+ return get(key);
+ } catch (ExecutionException e) {
+ throw new UncheckedExecutionException(e.getCause());
+ }
+ }
+
+ @Deprecated
+ @Override
+ public V apply(K key) {
+ return getUnchecked(key);
+ }
+
/**
* Accumulates statistics during the operation of a {@link Cache} for presentation by {@link
* Cache#stats}. This is solely intended for consumption by {@code Cache} implementors.
@@ -165,7 +164,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
/**
* Records the successful load of a new entry. This should be called when a cache request
* causes an entry to be loaded, and the loading completes successfully. In contrast to
- * {@link #recordMisses}, this method should only be called by the loading thread.
+ * {@link #recordConcurrentMiss}, this method should only be called by the loading thread.
*
* @param loadTime the number of nanoseconds the cache spent computing or retrieving the new
* value
@@ -175,7 +174,7 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
/**
* Records the failed load of a new entry. This should be called when a cache request causes
* an entry to be loaded, but an exception is thrown while loading the entry. In contrast to
- * {@link #recordMisses}, this method should only be called by the loading thread.
+ * {@link #recordConcurrentMiss}, this method should only be called by the loading thread.
*
* @param loadTime the number of nanoseconds the cache spent computing or retrieving the new
* value prior to an exception being thrown
@@ -202,25 +201,20 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
* @since 10.0
*/
@Beta
- public static final class SimpleStatsCounter implements StatsCounter {
- private final LongAddable hitCount = LongAddables.create();
- private final LongAddable missCount = LongAddables.create();
- private final LongAddable loadSuccessCount = LongAddables.create();
- private final LongAddable loadExceptionCount = LongAddables.create();
- private final LongAddable totalLoadTime = LongAddables.create();
- private final LongAddable evictionCount = LongAddables.create();
-
- /**
- * Constructs an instance with all counts initialized to zero.
- */
- public SimpleStatsCounter() {}
+ public static class SimpleStatsCounter implements StatsCounter {
+ private final AtomicLong hitCount = new AtomicLong();
+ private final AtomicLong missCount = new AtomicLong();
+ private final AtomicLong loadSuccessCount = new AtomicLong();
+ private final AtomicLong loadExceptionCount = new AtomicLong();
+ private final AtomicLong totalLoadTime = new AtomicLong();
+ private final AtomicLong evictionCount = new AtomicLong();
/**
* @since 11.0
*/
@Override
public void recordHits(int count) {
- hitCount.add(count);
+ hitCount.addAndGet(count);
}
/**
@@ -228,35 +222,35 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
*/
@Override
public void recordMisses(int count) {
- missCount.add(count);
+ missCount.addAndGet(count);
}
@Override
public void recordLoadSuccess(long loadTime) {
- loadSuccessCount.increment();
- totalLoadTime.add(loadTime);
+ loadSuccessCount.incrementAndGet();
+ totalLoadTime.addAndGet(loadTime);
}
@Override
public void recordLoadException(long loadTime) {
- loadExceptionCount.increment();
- totalLoadTime.add(loadTime);
+ loadExceptionCount.incrementAndGet();
+ totalLoadTime.addAndGet(loadTime);
}
@Override
public void recordEviction() {
- evictionCount.increment();
+ evictionCount.incrementAndGet();
}
@Override
public CacheStats snapshot() {
return new CacheStats(
- hitCount.sum(),
- missCount.sum(),
- loadSuccessCount.sum(),
- loadExceptionCount.sum(),
- totalLoadTime.sum(),
- evictionCount.sum());
+ hitCount.get(),
+ missCount.get(),
+ loadSuccessCount.get(),
+ loadExceptionCount.get(),
+ totalLoadTime.get(),
+ evictionCount.get());
}
/**
@@ -264,12 +258,12 @@ public abstract class AbstractCache<K, V> implements Cache<K, V> {
*/
public void incrementBy(StatsCounter other) {
CacheStats otherStats = other.snapshot();
- hitCount.add(otherStats.hitCount());
- missCount.add(otherStats.missCount());
- loadSuccessCount.add(otherStats.loadSuccessCount());
- loadExceptionCount.add(otherStats.loadExceptionCount());
- totalLoadTime.add(otherStats.totalLoadTime());
- evictionCount.add(otherStats.evictionCount());
+ hitCount.addAndGet(otherStats.hitCount());
+ missCount.addAndGet(otherStats.missCount());
+ loadSuccessCount.addAndGet(otherStats.loadSuccessCount());
+ loadExceptionCount.addAndGet(otherStats.loadExceptionCount());
+ totalLoadTime.addAndGet(otherStats.totalLoadTime());
+ evictionCount.addAndGet(otherStats.evictionCount());
}
}
}
diff --git a/guava/src/com/google/common/cache/AbstractLoadingCache.java b/guava/src/com/google/common/cache/AbstractLoadingCache.java
index 6a12c40..22ef81b 100644
--- a/guava/src/com/google/common/cache/AbstractLoadingCache.java
+++ b/guava/src/com/google/common/cache/AbstractLoadingCache.java
@@ -30,11 +30,10 @@ import java.util.concurrent.ExecutionException;
* effort required to implement this interface.
*
* <p>To implement a cache, the programmer needs only to extend this class and provide an
- * implementation for the {@link #get(Object)} and {@link #getIfPresent} methods.
- * {@link #getUnchecked}, {@link #get(Object, Callable)}, and {@link #getAll} are implemented in
- * terms of {@code get}; {@link #getAllPresent} is implemented in terms of {@code getIfPresent};
- * {@link #putAll} is implemented in terms of {@link #put}, {@link #invalidateAll(Iterable)} is
- * implemented in terms of {@link #invalidate}. The method {@link #cleanUp} is a no-op. All other
+ * implementation for the {@link #get} and {@link #getIfPresent} methods. {@link #getUnchecked},
+ * {@link #get(K, Callable)}, and {@link #getAll} are implemented in terms of {@code get};
+ * {@link #getAllPresent} is implemented in terms of {@code get}; {@link #invalidateAll(Iterable)}
+ * is implemented in terms of {@link #invalidate}. The method {@link #cleanUp} is a no-op. All other
* methods throw an {@link UnsupportedOperationException}.
*
* @author Charles Fry
diff --git a/guava/src/com/google/common/cache/Cache.java b/guava/src/com/google/common/cache/Cache.java
index cfe5764..f243adc 100644
--- a/guava/src/com/google/common/cache/Cache.java
+++ b/guava/src/com/google/common/cache/Cache.java
@@ -18,11 +18,11 @@ package com.google.common.cache;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.UncheckedExecutionException;
-import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
@@ -31,23 +31,24 @@ import javax.annotation.Nullable;
/**
* A semi-persistent mapping from keys to values. Cache entries are manually added using
- * {@link #get(Object, Callable)} or {@link #put(Object, Object)}, and are stored in the cache until
- * either evicted or manually invalidated.
+ * {@link #get(K, Callable)} or {@link #put(K, V)}, and are stored in the cache until either
+ * evicted or manually invalidated.
+ *
+ * <p><b>Note:</b> in release 12.0, all methods moved from {@code Cache} to {@link LoadingCache}
+ * will be deleted from {@code Cache}. As part of this transition {@code Cache} will no longer
+ * extend {@link Function}.
*
* <p>Implementations of this interface are expected to be thread-safe, and can be safely accessed
* by multiple concurrent threads.
*
- * <p>Note that while this class is still annotated as {@link Beta}, the API is frozen from a
- * consumer's standpoint. In other words existing methods are all considered {@code non-Beta} and
- * won't be changed without going through an 18 month deprecation cycle; however new methods may be
- * added at any time.
+ * <p>All methods other than {@link #getIfPresent} are optional.
*
* @author Charles Fry
* @since 10.0
*/
@Beta
@GwtCompatible
-public interface Cache<K, V> {
+public interface Cache<K, V> extends Function<K, V> {
/**
* Returns the value associated with {@code key} in this cache, or {@code null} if there is no
@@ -56,7 +57,7 @@ public interface Cache<K, V> {
* @since 11.0
*/
@Nullable
- V getIfPresent(Object key);
+ V getIfPresent(K key);
/**
* Returns the value associated with {@code key} in this cache, obtaining that value from
@@ -82,7 +83,7 @@ public interface Cache<K, V> {
*
* @since 11.0
*/
- ImmutableMap<K, V> getAllPresent(Iterable<?> keys);
+ ImmutableMap<K, V> getAllPresent(Iterable<? extends K> keys);
/**
* Associates {@code value} with {@code key} in this cache. If the cache previously contained a
@@ -96,16 +97,6 @@ public interface Cache<K, V> {
void put(K key, V value);
/**
- * Copies all of the mappings from the specified map to the cache. The effect of this call is
- * equivalent to that of calling {@code put(k, v)} on this map once for each mapping from key
- * {@code k} to value {@code v} in the specified map. The behavior of this operation is undefined
- * if the specified map is modified while the operation is in progress.
- *
- * @since 12.0
- */
- void putAll(Map<? extends K,? extends V> m);
-
- /**
* Discards any cached value for key {@code key}.
*/
void invalidate(Object key);
@@ -144,4 +135,55 @@ public interface Cache<K, V> {
* performed -- if any -- is implementation-dependent.
*/
void cleanUp();
+
+ /**
+ * Returns the value associated with {@code key} in this cache, first loading that value if
+ * necessary. No observable state associated with this cache is modified until loading completes.
+ *
+ * @throws ExecutionException if a checked exception was thrown while loading the value
+ * @throws UncheckedExecutionException if an unchecked exception was thrown while loading the
+ * value
+ * @throws ExecutionError if an error was thrown while loading the value
+ * @deprecated This method has been split out into the {@link LoadingCache} interface, and will be
+ * removed from {@code Cache} in Guava release 12.0. Note that
+ * {@link CacheBuilder#build(CacheLoader)} now returns a {@code LoadingCache}, so this deprecation
+ * (migration) can be dealt with by simply changing the type of references to the results of
+ * {@link CacheBuilder#build(CacheLoader)}.
+ */
+ @Deprecated V get(K key) throws ExecutionException;
+
+ /**
+ * Returns the value associated with {@code key} in this cache, first loading that value if
+ * necessary. No observable state associated with this cache is modified until computation
+ * completes. Unlike {@link #get}, this method does not throw a checked exception, and thus should
+ * only be used in situations where checked exceptions are not thrown by the cache loader.
+ *
+ * <p><b>Warning:</b> this method silently converts checked exceptions to unchecked exceptions,
+ * and should not be used with cache loaders which throw checked exceptions.
+ *
+ * @throws UncheckedExecutionException if an exception was thrown while loading the value,
+ * regardless of whether the exception was checked or unchecked
+ * @throws ExecutionError if an error was thrown while loading the value
+ * @deprecated This method has been split out into the {@link LoadingCache} interface, and will be
+ * removed from {@code Cache} in Guava release 12.0. Note that
+ * {@link CacheBuilder#build(CacheLoader)} now returns a {@code LoadingCache}, so this deprecation
+ * (migration) can be dealt with by simply changing the type of references to the results of
+ * {@link CacheBuilder#build(CacheLoader)}.
+ */
+ @Deprecated V getUnchecked(K key);
+
+ /**
+ * Discouraged. Provided to satisfy the {@code Function} interface; use {@link #get} or
+ * {@link #getUnchecked} instead.
+ *
+ * @throws UncheckedExecutionException if an exception was thrown while loading the value,
+ * regardless of whether the exception was checked or unchecked
+ * @throws ExecutionError if an error was thrown while loading the value
+ * @deprecated This method has been split out into the {@link LoadingCache} interface, and will be
+ * removed from {@code Cache} in Guava release 12.0. Note that
+ * {@link CacheBuilder#build(CacheLoader)} now returns a {@code LoadingCache}, so this deprecation
+ * (migration) can be dealt with by simply changing the type of references to the results of
+ * {@link CacheBuilder#build(CacheLoader)}.
+ */
+ @Deprecated V apply(K key);
}
diff --git a/guava/src/com/google/common/cache/CacheBuilder.java b/guava/src/com/google/common/cache/CacheBuilder.java
index 105ff73..8eef200 100644
--- a/guava/src/com/google/common/cache/CacheBuilder.java
+++ b/guava/src/com/google/common/cache/CacheBuilder.java
@@ -26,6 +26,7 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Ascii;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
@@ -56,12 +57,8 @@ import javax.annotation.CheckReturnValue;
* <li>values automatically wrapped in {@linkplain WeakReference weak} or
* {@linkplain SoftReference soft} references
* <li>notification of evicted (or otherwise removed) entries
- * <li>accumulation of cache access statistics
* </ul>
*
- * These features are all optional; caches can be created using all or none of them. By default
- * cache instances created by {@code CacheBuilder} will not perform any type of eviction.
- *
* <p>Usage example: <pre> {@code
*
* LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
@@ -75,19 +72,8 @@ import javax.annotation.CheckReturnValue;
* }
* });}</pre>
*
- * Or equivalently, <pre> {@code
- *
- * // In real life this would come from a command-line flag or config file
- * String spec = "maximumSize=10000,expireAfterWrite=10m";
*
- * LoadingCache<Key, Graph> graphs = CacheBuilder.from(spec)
- * .removalListener(MY_LISTENER)
- * .build(
- * new CacheLoader<Key, Graph>() {
- * public Graph load(Key key) throws AnyException {
- * return createExpensiveGraph(key);
- * }
- * });}</pre>
+ * These features are all optional.
*
* <p>The returned cache is implemented as a hash table with similar performance characteristics to
* {@link ConcurrentHashMap}. It implements all optional operations of the {@link LoadingCache} and
@@ -139,16 +125,13 @@ import javax.annotation.CheckReturnValue;
* retain all the configuration properties of the original cache. Note that the serialized form does
* <i>not</i> include cache contents, but only configuration.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CachesExplained">caching</a> for a higher-level
- * explanation.
- *
* @param <K> the base key type for all caches created by this builder
* @param <V> the base value type for all caches created by this builder
* @author Charles Fry
* @author Kevin Bourrillion
* @since 10.0
*/
+@Beta
@GwtCompatible(emulated = true)
public final class CacheBuilder<K, V> {
private static final int DEFAULT_INITIAL_CAPACITY = 16;
@@ -180,10 +163,10 @@ public final class CacheBuilder<K, V> {
});
static final CacheStats EMPTY_STATS = new CacheStats(0, 0, 0, 0, 0, 0);
- static final Supplier<StatsCounter> CACHE_STATS_COUNTER =
- new Supplier<StatsCounter>() {
+ static final Supplier<SimpleStatsCounter> CACHE_STATS_COUNTER =
+ new Supplier<SimpleStatsCounter>() {
@Override
- public StatsCounter get() {
+ public SimpleStatsCounter get() {
return new SimpleStatsCounter();
}
};
@@ -236,7 +219,7 @@ public final class CacheBuilder<K, V> {
RemovalListener<? super K, ? super V> removalListener;
Ticker ticker;
- Supplier<? extends StatsCounter> statsCounterSupplier = NULL_STATS_COUNTER;
+ Supplier<? extends StatsCounter> statsCounterSupplier = CACHE_STATS_COUNTER;
// TODO(fry): make constructor private and update tests to use newBuilder
CacheBuilder() {}
@@ -250,34 +233,8 @@ public final class CacheBuilder<K, V> {
}
/**
- * Constructs a new {@code CacheBuilder} instance with the settings specified in {@code spec}.
- *
- * @since 12.0
- */
- @Beta
- @GwtIncompatible("To be supported")
- public static CacheBuilder<Object, Object> from(CacheBuilderSpec spec) {
- return spec.toCacheBuilder()
- .lenientParsing();
- }
-
- /**
- * Constructs a new {@code CacheBuilder} instance with the settings specified in {@code spec}.
- * This is especially useful for command-line configuration of a {@code CacheBuilder}.
- *
- * @param spec a String in the format specified by {@link CacheBuilderSpec}
- * @since 12.0
- */
- @Beta
- @GwtIncompatible("To be supported")
- public static CacheBuilder<Object, Object> from(String spec) {
- return from(CacheBuilderSpec.parse(spec));
- }
-
- /**
* Enables lenient parsing. Useful for tests and spec parsing.
*/
- @GwtIncompatible("To be supported")
CacheBuilder<K, V> lenientParsing() {
strictParsing = false;
return this;
@@ -286,10 +243,9 @@ public final class CacheBuilder<K, V> {
/**
* Sets a custom {@code Equivalence} strategy for comparing keys.
*
- * <p>By default, the cache uses {@link Equivalence#identity} to determine key equality when
- * {@link #weakKeys} is specified, and {@link Equivalence#equals()} otherwise.
+ * <p>By default, the cache uses {@link Equivalences#identity} to determine key equality when
+ * {@link #weakKeys} is specified, and {@link Equivalences#equals()} otherwise.
*/
- @GwtIncompatible("To be supported")
CacheBuilder<K, V> keyEquivalence(Equivalence<Object> equivalence) {
checkState(keyEquivalence == null, "key equivalence was already set to %s", keyEquivalence);
keyEquivalence = checkNotNull(equivalence);
@@ -303,11 +259,10 @@ public final class CacheBuilder<K, V> {
/**
* Sets a custom {@code Equivalence} strategy for comparing values.
*
- * <p>By default, the cache uses {@link Equivalence#identity} to determine value equality when
- * {@link #weakValues} or {@link #softValues} is specified, and {@link Equivalence#equals()}
+ * <p>By default, the cache uses {@link Equivalences#identity} to determine value equality when
+ * {@link #weakValues} or {@link #softValues} is specified, and {@link Equivalences#equals()}
* otherwise.
*/
- @GwtIncompatible("To be supported")
CacheBuilder<K, V> valueEquivalence(Equivalence<Object> equivalence) {
checkState(valueEquivalence == null,
"value equivalence was already set to %s", valueEquivalence);
@@ -350,23 +305,11 @@ public final class CacheBuilder<K, V> {
* higher value than you need can waste space and time, and a significantly lower value can lead
* to thread contention. But overestimates and underestimates within an order of magnitude do not
* usually have much noticeable impact. A value of one permits only one thread to modify the cache
- * at a time, but since read operations and cache loading computations can proceed concurrently,
- * this still yields higher concurrency than full synchronization.
- *
- * <p> Defaults to 4. <b>Note:</b>The default may change in the future. If you care about this
- * value, you should always choose it explicitly.
- *
- * <p>The current implementation uses the concurrency level to create a fixed number of hashtable
- * segments, each governed by its own write lock. The segment lock is taken once for each explicit
- * write, and twice for each cache loading computation (once prior to loading the new value,
- * and once after loading completes). Much internal cache management is performed at the segment
- * granularity. For example, access queues and write queues are kept per segment when they are
- * required by the selected eviction algorithm. As such, when writing unit tests it is not
- * uncommon to specify {@code concurrencyLevel(1)} in order to achieve more deterministic eviction
- * behavior.
+ * at a time, but since read operations can proceed concurrently, this still yields higher
+ * concurrency than full synchronization. Defaults to 4.
*
- * <p>Note that future implementations may abandon segment locking in favor of more advanced
- * concurrency controls.
+ * <p><b>Note:</b>The default may change in the future. If you care about this value, you should
+ * always choose it explicitly.
*
* @throws IllegalArgumentException if {@code concurrencyLevel} is nonpositive
* @throws IllegalStateException if a concurrency level was already set
@@ -392,11 +335,9 @@ public final class CacheBuilder<K, V> {
* <p>When {@code size} is zero, elements will be evicted immediately after being loaded into the
* cache. This can be useful in testing, or to disable caching temporarily without a code change.
*
- * <p>This feature cannot be used in conjunction with {@link #maximumWeight}.
- *
* @param size the maximum size of the cache
* @throws IllegalArgumentException if {@code size} is negative
- * @throws IllegalStateException if a maximum size or weight was already set
+ * @throws IllegalStateException if a maximum size was already set
*/
public CacheBuilder<K, V> maximumSize(long size) {
checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s",
@@ -423,17 +364,11 @@ public final class CacheBuilder<K, V> {
* cache. This can be useful in testing, or to disable caching temporarily without a code
* change.
*
- * <p>Note that weight is only used to determine whether the cache is over capacity; it has no
- * effect on selecting which entry should be evicted next.
- *
- * <p>This feature cannot be used in conjunction with {@link #maximumSize}.
- *
- * @param weight the maximum total weight of entries the cache may contain
- * @throws IllegalArgumentException if {@code weight} is negative
- * @throws IllegalStateException if a maximum weight or size was already set
+ * @param weight the maximum weight the cache may contain
+ * @throws IllegalArgumentException if {@code size} is negative
+ * @throws IllegalStateException if a maximum size was already set
* @since 11.0
*/
- @GwtIncompatible("To be supported")
public CacheBuilder<K, V> maximumWeight(long weight) {
checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s",
this.maximumWeight);
@@ -472,7 +407,6 @@ public final class CacheBuilder<K, V> {
* @throws IllegalStateException if a maximum size was already set
* @since 11.0
*/
- @GwtIncompatible("To be supported")
public <K1 extends K, V1 extends V> CacheBuilder<K1, V1> weigher(
Weigher<? super K1, ? super V1> weigher) {
checkState(this.weigher == null);
@@ -502,6 +436,15 @@ public final class CacheBuilder<K, V> {
}
/**
+ * Specifies that each key (not value) stored in the cache should be strongly referenced.
+ *
+ * @throws IllegalStateException if the key strength was already set
+ */
+ CacheBuilder<K, V> strongKeys() {
+ return setKeyStrength(Strength.STRONG);
+ }
+
+ /**
* Specifies that each key (not value) stored in the cache should be wrapped in a {@link
* WeakReference} (by default, strong references are used).
*
@@ -530,6 +473,15 @@ public final class CacheBuilder<K, V> {
}
/**
+ * Specifies that each value (not key) stored in the cache should be strongly referenced.
+ *
+ * @throws IllegalStateException if the value strength was already set
+ */
+ CacheBuilder<K, V> strongValues() {
+ return setValueStrength(Strength.STRONG);
+ }
+
+ /**
* Specifies that each value (not key) stored in the cache should be wrapped in a
* {@link WeakReference} (by default, strong references are used).
*
@@ -657,9 +609,8 @@ public final class CacheBuilder<K, V> {
* {@link CacheLoader#reload}.
*
* <p>As the default implementation of {@link CacheLoader#reload} is synchronous, it is
- * recommended that users of this method override {@link CacheLoader#reload} with an asynchronous
- * implementation; otherwise refreshes will be performed during unrelated cache read and write
- * operations.
+ * recommended that users of this method override {@link CacheLoader#reload} with an asynchrnous
+ * implementation; otherwise refreshes will block other cache operations.
*
* <p>Currently automatic refreshes are performed when the first stale request for an entry
* occurs. The request triggering refresh will make a blocking call to {@link CacheLoader#reload}
@@ -675,8 +626,7 @@ public final class CacheBuilder<K, V> {
* @throws IllegalStateException if the refresh interval was already set
* @since 11.0
*/
- @Beta
- @GwtIncompatible("To be supported (synchronously).")
+ @GwtIncompatible("To be supported")
public CacheBuilder<K, V> refreshAfterWrite(long duration, TimeUnit unit) {
checkNotNull(unit);
checkState(refreshNanos == UNSET_INT, "refresh was already set to %s ns", refreshNanos);
@@ -698,6 +648,7 @@ public final class CacheBuilder<K, V> {
*
* @throws IllegalStateException if a ticker was already set
*/
+ @GwtIncompatible("To be supported")
public CacheBuilder<K, V> ticker(Ticker ticker) {
checkState(this.ticker == null);
this.ticker = checkNotNull(ticker);
@@ -712,27 +663,34 @@ public final class CacheBuilder<K, V> {
}
/**
- * Specifies a listener instance that caches should notify each time an entry is removed for any
- * {@linkplain RemovalCause reason}. Each cache created by this builder will invoke this listener
- * as part of the routine maintenance described in the class documentation above.
- *
- * <p><b>Warning:</b> after invoking this method, do not continue to use <i>this</i> cache
- * builder reference; instead use the reference this method <i>returns</i>. At runtime, these
- * point to the same instance, but only the returned reference has the correct generic type
- * information so as to ensure type safety. For best results, use the standard method-chaining
- * idiom illustrated in the class documentation above, configuring a builder and building your
- * cache in a single statement. Failure to heed this advice can result in a {@link
- * ClassCastException} being thrown by a cache operation at some <i>undefined</i> point in the
- * future.
- *
- * <p><b>Warning:</b> any exception thrown by {@code listener} will <i>not</i> be propagated to
- * the {@code Cache} user, only logged via a {@link Logger}.
- *
- * @return the cache builder reference that should be used instead of {@code this} for any
- * remaining configuration and cache building
+ * Specifies a listener instance, which all caches built using this {@code CacheBuilder} will
+ * notify each time an entry is removed from the cache by any means.
+ *
+ * <p>Each cache built by this {@code CacheBuilder} after this method is called invokes the
+ * supplied listener after removing an element for any reason (see removal causes in {@link
+ * RemovalCause}). It will invoke the listener as part of the routine maintenance described
+ * in the class javadoc.
+ *
+ * <p><b>Note:</b> <i>all exceptions thrown by {@code listener} will be logged (using
+ * {@link java.util.logging.Logger})and then swallowed</i>.
+ *
+ * <p><b>Important note:</b> Instead of returning <em>this</em> as a {@code CacheBuilder}
+ * instance, this method returns {@code CacheBuilder<K1, V1>}. From this point on, either the
+ * original reference or the returned reference may be used to complete configuration and build
+ * the cache, but only the "generic" one is type-safe. That is, it will properly prevent you from
+ * building caches whose key or value types are incompatible with the types accepted by the
+ * listener already provided; the {@code CacheBuilder} type cannot do this. For best results,
+ * simply use the standard method-chaining idiom, as illustrated in the documentation at top,
+ * configuring a {@code CacheBuilder} and building your {@link Cache} all in a single statement.
+ *
+ * <p><b>Warning:</b> if you ignore the above advice, and use this {@code CacheBuilder} to build
+ * a cache whose key or value type is incompatible with the listener, you will likely experience
+ * a {@link ClassCastException} at some <i>undefined</i> point in the future.
+ *
* @throws IllegalStateException if a removal listener was already set
*/
@CheckReturnValue
+ @GwtIncompatible("To be supported")
public <K1 extends K, V1 extends V> CacheBuilder<K1, V1> removalListener(
RemovalListener<? super K1, ? super V1> listener) {
checkState(this.removalListener == null);
@@ -751,15 +709,11 @@ public final class CacheBuilder<K, V> {
}
/**
- * Enable the accumulation of {@link CacheStats} during the operation of the cache. Without this
- * {@link Cache#stats} will return zero for all statistics. Note that recording stats requires
- * bookkeeping to be performed with each operation, and thus imposes a performance penalty on
- * cache operation.
- *
- * @since 12.0 (previously, stats collection was automatic)
+ * Disable the accumulation of {@link CacheStats} during the operation of the cache.
*/
- public CacheBuilder<K, V> recordStats() {
- statsCounterSupplier = CACHE_STATS_COUNTER;
+ CacheBuilder<K, V> disableStats() {
+ checkState(statsCounterSupplier == CACHE_STATS_COUNTER);
+ statsCounterSupplier = NULL_STATS_COUNTER;
return this;
}
@@ -834,11 +788,12 @@ public final class CacheBuilder<K, V> {
if (concurrencyLevel != UNSET_INT) {
s.add("concurrencyLevel", concurrencyLevel);
}
- if (maximumSize != UNSET_INT) {
- s.add("maximumSize", maximumSize);
- }
if (maximumWeight != UNSET_INT) {
- s.add("maximumWeight", maximumWeight);
+ if (weigher == null) {
+ s.add("maximumSize", maximumWeight);
+ } else {
+ s.add("maximumWeight", maximumWeight);
+ }
}
if (expireAfterWriteNanos != UNSET_INT) {
s.add("expireAfterWrite", expireAfterWriteNanos + "ns");
diff --git a/guava/src/com/google/common/cache/CacheBuilderSpec.java b/guava/src/com/google/common/cache/CacheBuilderSpec.java
deleted file mode 100644
index 1e03335..0000000
--- a/guava/src/com/google/common/cache/CacheBuilderSpec.java
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.cache.LocalCache.Strength;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-/**
- * A specification of a {@link CacheBuilder} configuration.
- *
- * <p>{@code CacheBuilderSpec} supports parsing configuration off of a string, which
- * makes it especially useful for command-line configuration of a {@code CacheBuilder}.
- *
- * <p>The string syntax is a series of comma-separated keys or key-value pairs,
- * each corresponding to a {@code CacheBuilder} method.
- * <ul>
- * <li>{@code concurrencyLevel=[integer]}: sets {@link CacheBuilder#concurrencyLevel}.
- * <li>{@code initialCapacity=[integer]}: sets {@link CacheBuilder#initialCapacity}.
- * <li>{@code maximumSize=[long]}: sets {@link CacheBuilder#maximumSize}.
- * <li>{@code maximumWeight=[long]}: sets {@link CacheBuilder#maximumWeight}.
- * <li>{@code expireAfterAccess=[duration]}: sets {@link CacheBuilder#expireAfterAccess}.
- * <li>{@code expireAfterWrite=[duration]}: sets {@link CacheBuilder#expireAfterWrite}.
- * <li>{@code refreshAfterWrite=[duration]}: sets {@link CacheBuilder#refreshAfterWrite}.
- * <li>{@code weakKeys}: sets {@link CacheBuilder#weakKeys}.
- * <li>{@code softValues}: sets {@link CacheBuilder#softValues}.
- * <li>{@code weakValues}: sets {@link CacheBuilder#weakValues}.
- * </ul>
- *
- * The set of supported keys will grow as {@code CacheBuilder} evolves, but existing keys
- * will never be removed.
- *
- * <p>Durations are represented by an integer, followed by one of "d", "h", "m",
- * or "s", representing days, hours, minutes, or seconds respectively. (There
- * is currently no syntax to request expiration in milliseconds, microseconds,
- * or nanoseconds.)
- *
- * <p>Whitespace before and after commas and equal signs is ignored. Keys may
- * not be repeated; it is also illegal to use the following pairs of keys in
- * a single value:
- * <ul>
- * <li>{@code maximumSize} and {@code maximumWeight}
- * <li>{@code softValues} and {@code weakValues}
- * </ul>
- *
- * <p>{@code CacheBuilderSpec} does not support configuring {@code CacheBuilder} methods
- * with non-value parameters. These must be configured in code.
- *
- * <p>A new {@code CacheBuilder} can be instantiated from a {@code CacheBuilderSpec} using
- * {@link CacheBuilder#from(CacheBuilderSpec)} or {@link CacheBuilder#from(String)}.
- *
- * @author Adam Winer
- * @since 12.0
- */
-@Beta
-public final class CacheBuilderSpec {
- /** Parses a single value. */
- private interface ValueParser {
- void parse(CacheBuilderSpec spec, String key, @Nullable String value);
- }
-
- /** Splits each key-value pair. */
- private static final Splitter KEYS_SPLITTER = Splitter.on(',').trimResults();
-
- /** Splits the key from the value. */
- private static final Splitter KEY_VALUE_SPLITTER = Splitter.on('=').trimResults();
-
- /** Map of names to ValueParser. */
- private static final ImmutableMap<String, ValueParser> VALUE_PARSERS =
- ImmutableMap.<String, ValueParser>builder()
- .put("initialCapacity", new InitialCapacityParser())
- .put("maximumSize", new MaximumSizeParser())
- .put("maximumWeight", new MaximumWeightParser())
- .put("concurrencyLevel", new ConcurrencyLevelParser())
- .put("weakKeys", new KeyStrengthParser(Strength.WEAK))
- .put("softValues", new ValueStrengthParser(Strength.SOFT))
- .put("weakValues", new ValueStrengthParser(Strength.WEAK))
- .put("expireAfterAccess", new AccessDurationParser())
- .put("expireAfterWrite", new WriteDurationParser())
- .put("refreshAfterWrite", new RefreshDurationParser())
- .put("refreshInterval", new RefreshDurationParser())
- .build();
-
- @VisibleForTesting Integer initialCapacity;
- @VisibleForTesting Long maximumSize;
- @VisibleForTesting Long maximumWeight;
- @VisibleForTesting Integer concurrencyLevel;
- @VisibleForTesting Strength keyStrength;
- @VisibleForTesting Strength valueStrength;
- @VisibleForTesting long writeExpirationDuration;
- @VisibleForTesting TimeUnit writeExpirationTimeUnit;
- @VisibleForTesting long accessExpirationDuration;
- @VisibleForTesting TimeUnit accessExpirationTimeUnit;
- @VisibleForTesting long refreshDuration;
- @VisibleForTesting TimeUnit refreshTimeUnit;
- /** Specification; used for toParseableString(). */
- private final String specification;
-
- private CacheBuilderSpec(String specification) {
- this.specification = specification;
- }
-
- /**
- * Creates a CacheBuilderSpec from a string.
- *
- * @param cacheBuilderSpecification the string form
- */
- public static CacheBuilderSpec parse(String cacheBuilderSpecification) {
- CacheBuilderSpec spec = new CacheBuilderSpec(cacheBuilderSpecification);
- if (!cacheBuilderSpecification.isEmpty()) {
- for (String keyValuePair : KEYS_SPLITTER.split(cacheBuilderSpecification)) {
- List<String> keyAndValue = ImmutableList.copyOf(KEY_VALUE_SPLITTER.split(keyValuePair));
- checkArgument(!keyAndValue.isEmpty(), "blank key-value pair");
- checkArgument(keyAndValue.size() <= 2,
- "key-value pair %s with more than one equals sign", keyValuePair);
-
- // Find the ValueParser for the current key.
- String key = keyAndValue.get(0);
- ValueParser valueParser = VALUE_PARSERS.get(key);
- checkArgument(valueParser != null, "unknown key %s", key);
-
- String value = keyAndValue.size() == 1 ? null : keyAndValue.get(1);
- valueParser.parse(spec, key, value);
- }
- }
-
- return spec;
- }
-
- /**
- * Returns a CacheBuilderSpec that will prevent caching.
- */
- public static CacheBuilderSpec disableCaching() {
- // Maximum size of zero is one way to block caching
- return CacheBuilderSpec.parse("maximumSize=0");
- }
-
- /**
- * Returns a CacheBuilder configured according to this instance's specification.
- */
- CacheBuilder<Object, Object> toCacheBuilder() {
- CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
- if (initialCapacity != null) {
- builder.initialCapacity(initialCapacity);
- }
- if (maximumSize != null) {
- builder.maximumSize(maximumSize);
- }
- if (maximumWeight != null) {
- builder.maximumWeight(maximumWeight);
- }
- if (concurrencyLevel != null) {
- builder.concurrencyLevel(concurrencyLevel);
- }
- if (keyStrength != null) {
- switch (keyStrength) {
- case WEAK:
- builder.weakKeys();
- break;
- default:
- throw new AssertionError();
- }
- }
- if (valueStrength != null) {
- switch (valueStrength) {
- case SOFT:
- builder.softValues();
- break;
- case WEAK:
- builder.weakValues();
- break;
- default:
- throw new AssertionError();
- }
- }
- if (writeExpirationTimeUnit != null) {
- builder.expireAfterWrite(writeExpirationDuration, writeExpirationTimeUnit);
- }
- if (accessExpirationTimeUnit != null) {
- builder.expireAfterAccess(accessExpirationDuration, accessExpirationTimeUnit);
- }
- if (refreshTimeUnit != null) {
- builder.refreshAfterWrite(refreshDuration, refreshTimeUnit);
- }
-
- return builder;
- }
-
- /**
- * Returns a string that can be used to parse an equivalent
- * {@code CacheBuilderSpec}. The order and form of this representation is
- * not guaranteed, except that reparsing its output will produce
- * a {@code CacheBuilderSpec} equal to this instance.
- */
- public String toParsableString() {
- return specification;
- }
-
- /**
- * Returns a string representation for this CacheBuilderSpec instance.
- * The form of this representation is not guaranteed.
- */
- @Override
- public String toString() {
- return Objects.toStringHelper(this).addValue(toParsableString()).toString();
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(
- initialCapacity,
- maximumSize,
- maximumWeight,
- concurrencyLevel,
- keyStrength,
- valueStrength,
- durationInNanos(writeExpirationDuration, writeExpirationTimeUnit),
- durationInNanos(accessExpirationDuration, accessExpirationTimeUnit),
- durationInNanos(refreshDuration, refreshTimeUnit));
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof CacheBuilderSpec)) {
- return false;
- }
- CacheBuilderSpec that = (CacheBuilderSpec) obj;
- return Objects.equal(initialCapacity, that.initialCapacity)
- && Objects.equal(maximumSize, that.maximumSize)
- && Objects.equal(maximumWeight, that.maximumWeight)
- && Objects.equal(concurrencyLevel, that.concurrencyLevel)
- && Objects.equal(keyStrength, that.keyStrength)
- && Objects.equal(valueStrength, that.valueStrength)
- && Objects.equal(durationInNanos(writeExpirationDuration, writeExpirationTimeUnit),
- durationInNanos(that.writeExpirationDuration, that.writeExpirationTimeUnit))
- && Objects.equal(durationInNanos(accessExpirationDuration, accessExpirationTimeUnit),
- durationInNanos(that.accessExpirationDuration, that.accessExpirationTimeUnit))
- && Objects.equal(durationInNanos(refreshDuration, refreshTimeUnit),
- durationInNanos(that.refreshDuration, that.refreshTimeUnit));
- }
-
- /**
- * Converts an expiration duration/unit pair into a single Long for hashing and equality.
- * Uses nanos to match CacheBuilder implementation.
- */
- @Nullable private static Long durationInNanos(long duration, @Nullable TimeUnit unit) {
- return (unit == null) ? null : unit.toNanos(duration);
- }
-
- /** Base class for parsing integers. */
- abstract static class IntegerParser implements ValueParser {
- protected abstract void parseInteger(CacheBuilderSpec spec, int value);
-
- @Override
- public void parse(CacheBuilderSpec spec, String key, String value) {
- checkArgument(value != null && !value.isEmpty(), "value of key %s omitted", key);
- try {
- parseInteger(spec, Integer.parseInt(value));
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(
- String.format("key %s value set to %s, must be integer", key, value), e);
- }
- }
- }
-
- /** Base class for parsing integers. */
- abstract static class LongParser implements ValueParser {
- protected abstract void parseLong(CacheBuilderSpec spec, long value);
-
- @Override
- public void parse(CacheBuilderSpec spec, String key, String value) {
- checkArgument(value != null && !value.isEmpty(), "value of key %s omitted", key);
- try {
- parseLong(spec, Long.parseLong(value));
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(
- String.format("key %s value set to %s, must be integer", key, value), e);
- }
- }
- }
-
- /** Parse initialCapacity */
- static class InitialCapacityParser extends IntegerParser {
- @Override
- protected void parseInteger(CacheBuilderSpec spec, int value) {
- checkArgument(spec.initialCapacity == null,
- "initial capacity was already set to ", spec.initialCapacity);
- spec.initialCapacity = value;
- }
- }
-
- /** Parse maximumSize */
- static class MaximumSizeParser extends LongParser {
- @Override
- protected void parseLong(CacheBuilderSpec spec, long value) {
- checkArgument(spec.maximumSize == null,
- "maximum size was already set to ", spec.maximumSize);
- checkArgument(spec.maximumWeight == null,
- "maximum weight was already set to ", spec.maximumWeight);
- spec.maximumSize = value;
- }
- }
-
- /** Parse maximumWeight */
- static class MaximumWeightParser extends LongParser {
- @Override
- protected void parseLong(CacheBuilderSpec spec, long value) {
- checkArgument(spec.maximumWeight == null,
- "maximum weight was already set to ", spec.maximumWeight);
- checkArgument(spec.maximumSize == null,
- "maximum size was already set to ", spec.maximumSize);
- spec.maximumWeight = value;
- }
- }
-
- /** Parse concurrencyLevel */
- static class ConcurrencyLevelParser extends IntegerParser {
- @Override
- protected void parseInteger(CacheBuilderSpec spec, int value) {
- checkArgument(spec.concurrencyLevel == null,
- "concurrency level was already set to ", spec.concurrencyLevel);
- spec.concurrencyLevel = value;
- }
- }
-
- /** Parse weakKeys */
- static class KeyStrengthParser implements ValueParser {
- private final Strength strength;
-
- public KeyStrengthParser(Strength strength) {
- this.strength = strength;
- }
-
- @Override
- public void parse(CacheBuilderSpec spec, String key, @Nullable String value) {
- checkArgument(value == null, "key %s does not take values", key);
- checkArgument(spec.keyStrength == null, "%s was already set to %s", key, spec.keyStrength);
- spec.keyStrength = strength;
- }
- }
-
- /** Parse weakValues and softValues */
- static class ValueStrengthParser implements ValueParser {
- private final Strength strength;
-
- public ValueStrengthParser(Strength strength) {
- this.strength = strength;
- }
-
- @Override
- public void parse(CacheBuilderSpec spec, String key, @Nullable String value) {
- checkArgument(value == null, "key %s does not take values", key);
- checkArgument(spec.valueStrength == null,
- "%s was already set to %s", key, spec.valueStrength);
-
- spec.valueStrength = strength;
- }
- }
-
- /** Base class for parsing times with durations */
- abstract static class DurationParser implements ValueParser {
- protected abstract void parseDuration(
- CacheBuilderSpec spec,
- long duration,
- TimeUnit unit);
-
- @Override
- public void parse(CacheBuilderSpec spec, String key, String value) {
- checkArgument(value != null && !value.isEmpty(), "value of key %s omitted", key);
- try {
- char lastChar = value.charAt(value.length() - 1);
- TimeUnit timeUnit;
- switch (lastChar) {
- case 'd':
- timeUnit = TimeUnit.DAYS;
- break;
- case 'h':
- timeUnit = TimeUnit.HOURS;
- break;
- case 'm':
- timeUnit = TimeUnit.MINUTES;
- break;
- case 's':
- timeUnit = TimeUnit.SECONDS;
- break;
- default:
- throw new IllegalArgumentException(
- String.format("key %s invalid format. was %s, must end with one of [dDhHmMsS]",
- key, value));
- }
-
- long duration = Long.parseLong(value.substring(0, value.length() - 1));
- parseDuration(spec, duration, timeUnit);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(
- String.format("key %s value set to %s, must be integer", key, value));
- }
- }
- }
-
- /** Parse expireAfterAccess */
- static class AccessDurationParser extends DurationParser {
- @Override protected void parseDuration(CacheBuilderSpec spec, long duration, TimeUnit unit) {
- checkArgument(spec.accessExpirationTimeUnit == null, "expireAfterAccess already set");
- spec.accessExpirationDuration = duration;
- spec.accessExpirationTimeUnit = unit;
- }
- }
-
- /** Parse expireAfterWrite */
- static class WriteDurationParser extends DurationParser {
- @Override protected void parseDuration(CacheBuilderSpec spec, long duration, TimeUnit unit) {
- checkArgument(spec.writeExpirationTimeUnit == null, "expireAfterWrite already set");
- spec.writeExpirationDuration = duration;
- spec.writeExpirationTimeUnit = unit;
- }
- }
-
- /** Parse refreshAfterWrite */
- static class RefreshDurationParser extends DurationParser {
- @Override protected void parseDuration(CacheBuilderSpec spec, long duration, TimeUnit unit) {
- checkArgument(spec.refreshTimeUnit == null, "refreshAfterWrite already set");
- spec.refreshDuration = duration;
- spec.refreshTimeUnit = unit;
- }
- }
-}
diff --git a/guava/src/com/google/common/cache/CacheLoader.java b/guava/src/com/google/common/cache/CacheLoader.java
index 2f014a3..21811e8 100644
--- a/guava/src/com/google/common/cache/CacheLoader.java
+++ b/guava/src/com/google/common/cache/CacheLoader.java
@@ -30,23 +30,15 @@ import java.io.Serializable;
import java.util.Map;
/**
- * Computes or retrieves values, based on a key, for use in populating a {@link LoadingCache}.
+ * Computes or retrieves values, based on a key, for use in populating a {@code Cache}.
*
* <p>Most implementations will only need to implement {@link #load}. Other methods may be
* overridden as desired.
*
- * <p>Usage example: <pre> {@code
- *
- * CacheLoader<Key, Graph> loader = new CacheLoader<Key, Graph>() {
- * public Graph load(Key key) throws AnyException {
- * return createExpensiveGraph(key);
- * }
- * };
- * LoadingCache<Key, Graph> cache = CacheBuilder.newBuilder().build(loader);}</pre>
- *
* @author Charles Fry
* @since 10.0
*/
+@Beta
@GwtCompatible(emulated = true)
public abstract class CacheLoader<K, V> {
/**
@@ -59,17 +51,13 @@ public abstract class CacheLoader<K, V> {
*
* @param key the non-null key whose value should be loaded
* @return the value associated with {@code key}; <b>must not be null</b>
- * @throws Exception if unable to load the result
- * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is
- * treated like any other {@code Exception} in all respects except that, when it is caught,
- * the thread's interrupt status is set
*/
public abstract V load(K key) throws Exception;
/**
* Computes or retrieves a replacement value corresponding to an already-cached {@code key}. This
* method is called when an existing cache entry is refreshed by
- * {@link CacheBuilder#refreshAfterWrite}, or through a call to {@link LoadingCache#refresh}.
+ * {@link CacheBuilder#refreshAfterWrite}, or through a call to {@link Cache#refresh}.
*
* <p>This implementation synchronously delegates to {@link #load}. It is recommended that it be
* overridden with an asynchronous implementation when using
@@ -81,22 +69,16 @@ public abstract class CacheLoader<K, V> {
* @param oldValue the non-null old value corresponding to {@code key}
* @return the future new value associated with {@code key};
* <b>must not be null, must not return null</b>
- * @throws Exception if unable to reload the result
- * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is
- * treated like any other {@code Exception} in all respects except that, when it is caught,
- * the thread's interrupt status is set
* @since 11.0
*/
@GwtIncompatible("Futures")
public ListenableFuture<V> reload(K key, V oldValue) throws Exception {
- checkNotNull(key);
- checkNotNull(oldValue);
return Futures.immediateFuture(load(key));
}
/**
* Computes or retrieves the values corresponding to {@code keys}. This method is called by
- * {@link LoadingCache#getAll}.
+ * {@link Cache#getAll}.
*
* <p>If the returned map doesn't contain all requested {@code keys} then the entries it does
* contain will be cached, but {@code getAll} will throw an exception. If the returned map
@@ -104,33 +86,22 @@ public abstract class CacheLoader<K, V> {
* but only the entries for {@code keys} will be returned from {@code getAll}.
*
* <p>This method should be overriden when bulk retrieval is significantly more efficient than
- * many individual lookups. Note that {@link LoadingCache#getAll} will defer to individual calls
- * to {@link LoadingCache#get} if this method is not overriden.
+ * many individual lookups. Note that {@link Cache#getAll} will defer to individual calls to
+ * {@link Cache#get} if this method is not overriden.
*
* @param keys the unique, non-null keys whose values should be loaded
* @return a map from each key in {@code keys} to the value associated with that key;
* <b>may not contain null values</b>
- * @throws Exception if unable to load the result
- * @throws InterruptedException if this method is interrupted. {@code InterruptedException} is
- * treated like any other {@code Exception} in all respects except that, when it is caught,
- * the thread's interrupt status is set
* @since 11.0
*/
public Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception {
- // This will be caught by getAll(), causing it to fall back to multiple calls to
- // LoadingCache.get
+ // This will be caught by getAll(), causing it to fall back to multiple calls to Cache.get
throw new UnsupportedLoadingOperationException();
}
/**
- * Returns a cache loader based on an <i>existing</i> function instance. Note that there's no need
- * to create a <i>new</i> function just to pass it in here; just subclass {@code CacheLoader} and
- * implement {@link #load load} instead.
- *
- * @param function the function to be used for loading values; must never return {@code null}
- * @return a cache loader that loads values by passing each key to {@code function}
+ * Returns a {@code CacheLoader} which creates values by applying a {@code Function} to the key.
*/
- @Beta
public static <K, V> CacheLoader<K, V> from(Function<K, V> function) {
return new FunctionToCacheLoader<K, V>(function);
}
@@ -145,22 +116,16 @@ public abstract class CacheLoader<K, V> {
@Override
public V load(K key) {
- return computingFunction.apply(checkNotNull(key));
+ return computingFunction.apply(key);
}
private static final long serialVersionUID = 0;
}
/**
- * Returns a cache loader based on an <i>existing</i> supplier instance. Note that there's no need
- * to create a <i>new</i> supplier just to pass it in here; just subclass {@code CacheLoader} and
- * implement {@link #load load} instead.
- *
- * @param supplier the supplier to be used for loading values; must never return {@code null}
- * @return a cache loader that loads values by calling {@link Supplier#get}, irrespective of the
- * key
+ * Returns a {@code CacheLoader} which obtains values from a {@code Supplier} (independent of the
+ * key).
*/
- @Beta
public static <V> CacheLoader<Object, V> from(Supplier<V> supplier) {
return new SupplierToCacheLoader<V>(supplier);
}
@@ -175,7 +140,6 @@ public abstract class CacheLoader<K, V> {
@Override
public V load(Object key) {
- checkNotNull(key);
return computingSupplier.get();
}
diff --git a/guava/src/com/google/common/cache/CacheStats.java b/guava/src/com/google/common/cache/CacheStats.java
index d8c9eb7..04d442c 100644
--- a/guava/src/com/google/common/cache/CacheStats.java
+++ b/guava/src/com/google/common/cache/CacheStats.java
@@ -22,8 +22,6 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
-import java.util.concurrent.Callable;
-
import javax.annotation.Nullable;
/**
@@ -46,14 +44,9 @@ import javax.annotation.Nullable;
* </ul>
* <li>When an entry is evicted from the cache, {@code evictionCount} is incremented.
* <li>No stats are modified when a cache entry is invalidated or manually removed.
- * <li>No stats are modified on a query to {@link Cache#getIfPresent}.
* <li>No stats are modified by operations invoked on the {@linkplain Cache#asMap asMap} view of
* the cache.
* </ul>
- *
- * <p>A lookup is specifically defined as an invocation of one of the methods
- * {@link LoadingCache#get(Object)}, {@link LoadingCache#getUnchecked(Object)},
- * {@link Cache#get(Object, Callable)}, or {@link LoadingCache#getAll(Iterable)}.
*
* @author Charles Fry
* @since 10.0
diff --git a/guava/src/com/google/common/cache/ForwardingCache.java b/guava/src/com/google/common/cache/ForwardingCache.java
index 44fe683..4404593 100644
--- a/guava/src/com/google/common/cache/ForwardingCache.java
+++ b/guava/src/com/google/common/cache/ForwardingCache.java
@@ -21,7 +21,6 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ForwardingObject;
import com.google.common.collect.ImmutableMap;
-import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
@@ -50,7 +49,7 @@ public abstract class ForwardingCache<K, V> extends ForwardingObject implements
*/
@Override
@Nullable
- public V getIfPresent(Object key) {
+ public V getIfPresent(K key) {
return delegate().getIfPresent(key);
}
@@ -66,7 +65,7 @@ public abstract class ForwardingCache<K, V> extends ForwardingObject implements
* @since 11.0
*/
@Override
- public ImmutableMap<K, V> getAllPresent(Iterable<?> keys) {
+ public ImmutableMap<K, V> getAllPresent(Iterable<? extends K> keys) {
return delegate().getAllPresent(keys);
}
@@ -78,14 +77,6 @@ public abstract class ForwardingCache<K, V> extends ForwardingObject implements
delegate().put(key, value);
}
- /**
- * @since 12.0
- */
- @Override
- public void putAll(Map<? extends K,? extends V> m) {
- delegate().putAll(m);
- }
-
@Override
public void invalidate(Object key) {
delegate().invalidate(key);
@@ -124,6 +115,24 @@ public abstract class ForwardingCache<K, V> extends ForwardingObject implements
delegate().cleanUp();
}
+ @Deprecated
+ @Override
+ public V get(K key) throws ExecutionException {
+ return delegate().get(key);
+ }
+
+ @Deprecated
+ @Override
+ public V getUnchecked(K key) {
+ return delegate().getUnchecked(key);
+ }
+
+ @Deprecated
+ @Override
+ public V apply(K key) {
+ return delegate().apply(key);
+ }
+
/**
* A simplified version of {@link ForwardingCache} where subclasses can pass in an already
* constructed {@link Cache} as the delegete.
diff --git a/guava/src/com/google/common/cache/LoadingCache.java b/guava/src/com/google/common/cache/LoadingCache.java
index 05b1312..471c31a 100644
--- a/guava/src/com/google/common/cache/LoadingCache.java
+++ b/guava/src/com/google/common/cache/LoadingCache.java
@@ -33,14 +33,11 @@ import java.util.concurrent.ExecutionException;
* <p>Implementations of this interface are expected to be thread-safe, and can be safely accessed
* by multiple concurrent threads.
*
+ * <p>All methods other than {@link #get} and {@link #getUnchecked} are optional.
+ *
* <p>When evaluated as a {@link Function}, a cache yields the same result as invoking
* {@link #getUnchecked}.
*
- * <p>Note that while this class is still annotated as {@link Beta}, the API is frozen from a
- * consumer's standpoint. In other words existing methods are all considered {@code non-Beta} and
- * won't be changed without going through an 18 month deprecation cycle; however new methods may be
- * added at any time.
- *
* @author Charles Fry
* @since 11.0
*/
@@ -141,8 +138,6 @@ public interface LoadingCache<K, V> extends Cache<K, V>, Function<K, V> {
*
* <p>Caches loaded by a {@link CacheLoader} will call {@link CacheLoader#reload} if the
* cache currently contains a value for {@code key}, and {@link CacheLoader#load} otherwise.
- * Loading is asynchronous only if {@link CacheLoader#reload} was overridden with an
- * asynchronous implementation.
*
* <p>Returns without doing anything if another thread is currently loading the value for
* {@code key}. If the cache loader associated with this cache performs refresh asynchronously
diff --git a/guava/src/com/google/common/cache/LocalCache.java b/guava/src/com/google/common/cache/LocalCache.java
index d7c5bd7..4973429 100644
--- a/guava/src/com/google/common/cache/LocalCache.java
+++ b/guava/src/com/google/common/cache/LocalCache.java
@@ -23,10 +23,9 @@ import static com.google.common.cache.CacheBuilder.UNSET_INT;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Stopwatch;
import com.google.common.base.Ticker;
import com.google.common.cache.AbstractCache.SimpleStatsCounter;
@@ -35,7 +34,7 @@ import com.google.common.cache.CacheBuilder.NullListener;
import com.google.common.cache.CacheBuilder.OneWeigher;
import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.CacheLoader.UnsupportedLoadingOperationException;
-import com.google.common.collect.AbstractSequentialIterator;
+import com.google.common.collect.AbstractLinkedIterator;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
@@ -48,7 +47,6 @@ import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
-import com.google.common.util.concurrent.Uninterruptibles;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -57,6 +55,7 @@ import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
+import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractQueue;
import java.util.AbstractSet;
@@ -90,7 +89,6 @@ import javax.annotation.concurrent.GuardedBy;
* @author Bob Lee ({@code com.google.common.collect.MapMaker})
* @author Doug Lea ({@code ConcurrentHashMap})
*/
-@GwtCompatible(emulated = true)
class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
/*
@@ -232,8 +230,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
/**
* Creates a new, empty map with the specified strategy, initial capacity and concurrency level.
*/
- LocalCache(
- CacheBuilder<? super K, ? super V> builder, @Nullable CacheLoader<? super K, V> loader) {
+ LocalCache(CacheBuilder<? super K, ? super V> builder, CacheLoader<? super K, V> loader) {
concurrencyLevel = Math.min(builder.getConcurrencyLevel(), MAX_SEGMENTS);
keyStrength = builder.getKeyStrength();
@@ -263,15 +260,13 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
initialCapacity = Math.min(initialCapacity, (int) maxWeight);
}
- // Find the lowest power-of-two segmentCount that exceeds concurrencyLevel, unless
- // maximumSize/Weight is specified in which case ensure that each segment gets at least 10
- // entries. The special casing for size-based eviction is only necessary because that eviction
- // happens per segment instead of globally, so too many segments compared to the maximum size
- // will result in random eviction behavior.
+ // Find power-of-two sizes best matching arguments. Constraints:
+ // (segmentCount <= maxWeight)
+ // && (concurrencyLevel > maxWeight || segmentCount > concurrencyLevel)
int segmentShift = 0;
int segmentCount = 1;
while (segmentCount < concurrencyLevel
- && (!evictsBySize() || segmentCount * 20 <= maxWeight)) {
+ && (!evictsBySize() || customWeigher() || segmentCount * 2 <= maxWeight)) {
++segmentShift;
segmentCount <<= 1;
}
@@ -386,7 +381,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
Equivalence<Object> defaultEquivalence() {
- return Equivalence.equals();
+ return Equivalences.equals();
}
},
@@ -402,7 +397,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
Equivalence<Object> defaultEquivalence() {
- return Equivalence.identity();
+ return Equivalences.identity();
}
},
@@ -418,7 +413,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
Equivalence<Object> defaultEquivalence() {
- return Equivalence.identity();
+ return Equivalences.identity();
}
};
@@ -652,11 +647,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
/**
* Creates a copy of this reference for the given entry.
- *
- * <p>{@code value} may be null only for a loading reference.
*/
- ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, @Nullable V value, ReferenceEntry<K, V> entry);
+ ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry);
/**
* Notifify pending loads that a new value was set. This is only relevant to loading
@@ -701,8 +693,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
@Override
- public ValueReference<Object, Object> copyFor(ReferenceQueue<Object> queue,
- @Nullable Object value, ReferenceEntry<Object, Object> entry) {
+ public ValueReference<Object, Object> copyFor(
+ ReferenceQueue<Object> queue, ReferenceEntry<Object, Object> entry) {
return this;
}
@@ -1664,8 +1656,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return new WeakValueReference<K, V>(queue, value, entry);
+ ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new WeakValueReference<K, V>(queue, get(), entry);
}
@Override
@@ -1710,9 +1702,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
public void notifyNewValue(V newValue) {}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return new SoftValueReference<K, V>(queue, value, entry);
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new SoftValueReference<K, V>(queue, get(), entry);
}
@Override
@@ -1757,8 +1748,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return this;
}
@@ -1800,8 +1790,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return new WeightedWeakValueReference<K, V>(queue, value, entry, weight);
+ ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new WeightedWeakValueReference<K, V>(queue, get(), entry, weight);
}
}
@@ -1822,9 +1812,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return weight;
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return new WeightedSoftValueReference<K, V>(queue, value, entry, weight);
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new WeightedSoftValueReference<K, V>(queue, get(), entry, weight);
}
}
@@ -1892,10 +1881,10 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@VisibleForTesting
ValueReference<K, V> newValueReference(ReferenceEntry<K, V> entry, V value, int weight) {
int hash = entry.getHash();
- return valueStrength.referenceValue(segmentFor(hash), entry, checkNotNull(value), weight);
+ return valueStrength.referenceValue(segmentFor(hash), entry, value, weight);
}
- int hash(@Nullable Object key) {
+ int hash(Object key) {
int h = keyEquivalence.hash(key);
return rehash(h);
}
@@ -1964,13 +1953,12 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
* Returns true if the entry has expired.
*/
boolean isExpired(ReferenceEntry<K, V> entry, long now) {
- checkNotNull(entry);
if (expiresAfterAccess()
- && (now - entry.getAccessTime() >= expireAfterAccessNanos)) {
+ && (now - entry.getAccessTime() > expireAfterAccessNanos)) {
return true;
}
if (expiresAfterWrite()
- && (now - entry.getWriteTime() >= expireAfterWriteNanos)) {
+ && (now - entry.getWriteTime() > expireAfterWriteNanos)) {
return true;
}
return false;
@@ -2150,7 +2138,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
StatsCounter statsCounter) {
this.map = map;
this.maxSegmentWeight = maxSegmentWeight;
- this.statsCounter = checkNotNull(statsCounter);
+ this.statsCounter = statsCounter;
initTable(newEntryArray(initialCapacity));
keyReferenceQueue = map.usesKeyReferences()
@@ -2187,29 +2175,14 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@GuardedBy("Segment.this")
ReferenceEntry<K, V> newEntry(K key, int hash, @Nullable ReferenceEntry<K, V> next) {
- return map.entryFactory.newEntry(this, checkNotNull(key), hash, next);
+ return map.entryFactory.newEntry(this, key, hash, next);
}
- /**
- * Copies {@code original} into a new entry chained to {@code newNext}. Returns the new entry,
- * or {@code null} if {@code original} was already garbage collected.
- */
@GuardedBy("Segment.this")
ReferenceEntry<K, V> copyEntry(ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) {
- if (original.getKey() == null) {
- // key collected
- return null;
- }
-
ValueReference<K, V> valueReference = original.getValueReference();
- V value = valueReference.get();
- if ((value == null) && valueReference.isActive()) {
- // value collected
- return null;
- }
-
ReferenceEntry<K, V> newEntry = map.entryFactory.copyEntry(this, original, newNext);
- newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, value, newEntry));
+ newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, newEntry));
return newEntry;
}
@@ -2232,8 +2205,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
// loading
V get(K key, int hash, CacheLoader<? super K, V> loader) throws ExecutionException {
- checkNotNull(key);
- checkNotNull(loader);
try {
if (count != 0) { // read-volatile
// don't call getLiveEntry, which would ignore loading values
@@ -2424,9 +2395,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
V scheduleRefresh(ReferenceEntry<K, V> entry, K key, int hash, V oldValue, long now,
CacheLoader<? super K, V> loader) {
- if (map.refreshes() && (now - entry.getWriteTime() > map.refreshNanos)
- && !entry.getValueReference().isLoading()) {
- V newValue = refresh(key, hash, loader, true);
+ if (map.refreshes() && (now - entry.getWriteTime() > map.refreshNanos)) {
+ V newValue = refresh(key, hash, loader);
if (newValue != null) {
return newValue;
}
@@ -2441,9 +2411,9 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
* refresh.
*/
@Nullable
- V refresh(K key, int hash, CacheLoader<? super K, V> loader, boolean checkTime) {
+ V refresh(K key, int hash, CacheLoader<? super K, V> loader) {
final LoadingValueReference<K, V> loadingValueReference =
- insertLoadingValueReference(key, hash, checkTime);
+ insertLoadingValueReference(key, hash);
if (loadingValueReference == null) {
return null;
}
@@ -2451,7 +2421,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
ListenableFuture<V> result = loadAsync(key, hash, loadingValueReference, loader);
if (result.isDone()) {
try {
- return Uninterruptibles.getUninterruptibly(result);
+ return result.get();
} catch (Throwable t) {
// don't let refresh exceptions propagate; error was already logged
}
@@ -2464,8 +2434,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
* is already loading.
*/
@Nullable
- LoadingValueReference<K, V> insertLoadingValueReference(final K key, final int hash,
- boolean checkTime) {
+ LoadingValueReference<K, V> insertLoadingValueReference(final K key, final int hash) {
ReferenceEntry<K, V> e = null;
lock();
try {
@@ -2484,11 +2453,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
// We found an existing entry.
ValueReference<K, V> valueReference = e.getValueReference();
- if (valueReference.isLoading()
- || (checkTime && (now - e.getWriteTime() < map.refreshNanos))) {
+ if (valueReference.isLoading()) {
// refresh is a no-op if loading is pending
- // if checkTime, we want to check *after* acquiring the lock if refresh still needs
- // to be scheduled
return null;
}
@@ -3008,14 +2974,14 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
// Clone nodes leading up to the tail.
for (ReferenceEntry<K, V> e = head; e != tail; e = e.getNext()) {
- int newIndex = e.getHash() & newMask;
- ReferenceEntry<K, V> newNext = newTable.get(newIndex);
- ReferenceEntry<K, V> newFirst = copyEntry(e, newNext);
- if (newFirst != null) {
- newTable.set(newIndex, newFirst);
- } else {
+ if (isCollected(e)) {
removeCollectedEntry(e);
newCount--;
+ } else {
+ int newIndex = e.getHash() & newMask;
+ ReferenceEntry<K, V> newNext = newTable.get(newIndex);
+ ReferenceEntry<K, V> newFirst = copyEntry(e, newNext);
+ newTable.set(newIndex, newFirst);
}
}
}
@@ -3177,11 +3143,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
preWriteCleanup(now);
int newCount = this.count + 1;
- if (newCount > this.threshold) { // ensure capacity
- expand();
- newCount = this.count + 1;
- }
-
AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table;
int index = hash & (table.length() - 1);
ReferenceEntry<K, V> first = table.get(index);
@@ -3192,10 +3153,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
&& map.keyEquivalence.equivalent(key, entryKey)) {
ValueReference<K, V> valueReference = e.getValueReference();
V entryValue = valueReference.get();
- // replace the old LoadingValueReference if it's live, otherwise
- // perform a putIfAbsent
- if (oldValueReference == valueReference
- || (entryValue == null && valueReference != UNSET)) {
+ if (entryValue == null || oldValueReference == valueReference) {
++modCount;
if (oldValueReference.isActive()) {
RemovalCause cause =
@@ -3328,12 +3286,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
int newCount = count;
ReferenceEntry<K, V> newFirst = entry.getNext();
for (ReferenceEntry<K, V> e = first; e != entry; e = e.getNext()) {
- ReferenceEntry<K, V> next = copyEntry(e, newFirst);
- if (next != null) {
- newFirst = next;
- } else {
+ if (isCollected(e)) {
removeCollectedEntry(e);
newCount--;
+ } else {
+ newFirst = copyEntry(e, newFirst);
}
}
this.count = newCount;
@@ -3470,6 +3427,18 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
/**
+ * Returns true if the entry has been partially collected, meaning that either the key is null,
+ * or the value is active but null.
+ */
+ boolean isCollected(ReferenceEntry<K, V> entry) {
+ if (entry.getKey() == null) {
+ return true;
+ }
+ ValueReference<K, V> valueReference = entry.getValueReference();
+ return (valueReference.get() == null) && valueReference.isActive();
+ }
+
+ /**
* Performs routine cleanup following a read. Normally cleanup happens during writes. If cleanup
* is not observed after a sufficient number of reads, try cleaning up from the read thread.
*/
@@ -3604,15 +3573,12 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return newValue != null ? newValue : Futures.<V>immediateFuture(null);
}
} catch (Throwable t) {
- if (t instanceof InterruptedException) {
- Thread.currentThread().interrupt();
- }
return setException(t) ? futureValue : fullyFailedFuture(t);
}
}
public long elapsedNanos() {
- return stopwatch.elapsed(NANOSECONDS);
+ return stopwatch.elapsedTime(NANOSECONDS);
}
@Override
@@ -3635,8 +3601,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, @Nullable V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return this;
}
}
@@ -3770,7 +3735,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
public Iterator<ReferenceEntry<K, V>> iterator() {
- return new AbstractSequentialIterator<ReferenceEntry<K, V>>(peek()) {
+ return new AbstractLinkedIterator<ReferenceEntry<K, V>>(peek()) {
@Override
protected ReferenceEntry<K, V> computeNext(ReferenceEntry<K, V> previous) {
ReferenceEntry<K, V> next = previous.getNextInWriteQueue();
@@ -3907,7 +3872,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Override
public Iterator<ReferenceEntry<K, V>> iterator() {
- return new AbstractSequentialIterator<ReferenceEntry<K, V>>(peek()) {
+ return new AbstractLinkedIterator<ReferenceEntry<K, V>>(peek()) {
@Override
protected ReferenceEntry<K, V> computeNext(ReferenceEntry<K, V> previous) {
ReferenceEntry<K, V> next = previous.getNextInAccessQueue();
@@ -4004,20 +3969,17 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return get(key, defaultLoader);
}
- ImmutableMap<K, V> getAllPresent(Iterable<?> keys) {
+ ImmutableMap<K, V> getAllPresent(Iterable<? extends K> keys) {
int hits = 0;
int misses = 0;
Map<K, V> result = Maps.newLinkedHashMap();
- for (Object key : keys) {
+ for (K key : keys) {
V value = get(key);
if (value == null) {
misses++;
} else {
- // TODO(fry): store entry key instead of query key
- @SuppressWarnings("unchecked")
- K castKey = (K) key;
- result.put(castKey, value);
+ result.put(key, value);
hits++;
}
}
@@ -4026,7 +3988,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return ImmutableMap.copyOf(result);
}
- ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
+ ImmutableMap<K, V> getAll(Iterable<? extends K> keys)
+ throws ExecutionException {
int hits = 0;
int misses = 0;
@@ -4078,8 +4041,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
@Nullable
Map<K, V> loadAll(Set<? extends K> keys, CacheLoader<? super K, V> loader)
throws ExecutionException {
- checkNotNull(loader);
- checkNotNull(keys);
Stopwatch stopwatch = new Stopwatch().start();
Map<K, V> result;
boolean success = false;
@@ -4091,9 +4052,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
} catch (UnsupportedLoadingOperationException e) {
success = true;
throw e;
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new ExecutionException(e);
} catch (RuntimeException e) {
throw new UncheckedExecutionException(e);
} catch (Exception e) {
@@ -4102,12 +4060,12 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
throw new ExecutionError(e);
} finally {
if (!success) {
- globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS));
+ globalStatsCounter.recordLoadException(stopwatch.elapsedTime(NANOSECONDS));
}
}
if (result == null) {
- globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS));
+ globalStatsCounter.recordLoadException(stopwatch.elapsedTime(NANOSECONDS));
throw new InvalidCacheLoadException(loader + " returned null map from loadAll");
}
@@ -4126,12 +4084,12 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
if (nullsPresent) {
- globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS));
+ globalStatsCounter.recordLoadException(stopwatch.elapsedTime(NANOSECONDS));
throw new InvalidCacheLoadException(loader + " returned null keys or values from loadAll");
}
// TODO(fry): record count of loaded entries
- globalStatsCounter.recordLoadSuccess(stopwatch.elapsed(NANOSECONDS));
+ globalStatsCounter.recordLoadSuccess(stopwatch.elapsedTime(NANOSECONDS));
return result;
}
@@ -4148,9 +4106,21 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return segmentFor(hash).getEntry(key, hash);
}
+ /**
+ * Returns the live internal entry for the specified key.
+ */
+ ReferenceEntry<K, V> getLiveEntry(@Nullable Object key) {
+ // does not impact recency ordering
+ if (key == null) {
+ return null;
+ }
+ int hash = hash(key);
+ return segmentFor(hash).getLiveEntry(key, hash, ticker.read());
+ }
+
void refresh(K key) {
int hash = hash(checkNotNull(key));
- segmentFor(hash).refresh(key, hash, defaultLoader, false);
+ segmentFor(hash).refresh(key, hash, defaultLoader);
}
@Override
@@ -4284,7 +4254,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
public Set<K> keySet() {
// does not impact recency ordering
Set<K> ks = keySet;
- return (ks != null) ? ks : (keySet = new KeySet(this));
+ return (ks != null) ? ks : (keySet = new KeySet());
}
Collection<V> values;
@@ -4293,22 +4263,21 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
public Collection<V> values() {
// does not impact recency ordering
Collection<V> vs = values;
- return (vs != null) ? vs : (values = new Values(this));
+ return (vs != null) ? vs : (values = new Values());
}
Set<Entry<K, V>> entrySet;
@Override
- @GwtIncompatible("Not supported.")
public Set<Entry<K, V>> entrySet() {
// does not impact recency ordering
Set<Entry<K, V>> es = entrySet;
- return (es != null) ? es : (entrySet = new EntrySet(this));
+ return (es != null) ? es : (entrySet = new EntrySet());
}
// Iterator Support
- abstract class HashIterator<T> implements Iterator<T> {
+ abstract class HashIterator {
int nextSegmentIndex;
int nextTableIndex;
@@ -4324,9 +4293,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
advance();
}
- @Override
- public abstract T next();
-
final void advance() {
nextExternal = null;
@@ -4399,7 +4365,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- @Override
public boolean hasNext() {
return nextExternal != null;
}
@@ -4413,7 +4378,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
return lastReturned;
}
- @Override
public void remove() {
checkState(lastReturned != null);
LocalCache.this.remove(lastReturned.getKey());
@@ -4421,7 +4385,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- final class KeyIterator extends HashIterator<K> {
+ final class KeyIterator extends HashIterator implements Iterator<K> {
@Override
public K next() {
@@ -4429,7 +4393,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- final class ValueIterator extends HashIterator<V> {
+ final class ValueIterator extends HashIterator implements Iterator<V> {
@Override
public V next() {
@@ -4489,7 +4453,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- final class EntryIterator extends HashIterator<Entry<K, V>> {
+ final class EntryIterator extends HashIterator implements Iterator<Entry<K, V>> {
@Override
public Entry<K, V> next() {
@@ -4497,73 +4461,68 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
}
- abstract class AbstractCacheSet<T> extends AbstractSet<T> {
- final ConcurrentMap<?, ?> map;
+ final class KeySet extends AbstractSet<K> {
- AbstractCacheSet(ConcurrentMap<?, ?> map) {
- this.map = map;
+ @Override
+ public Iterator<K> iterator() {
+ return new KeyIterator();
}
@Override
public int size() {
- return map.size();
+ return LocalCache.this.size();
}
@Override
public boolean isEmpty() {
- return map.isEmpty();
+ return LocalCache.this.isEmpty();
}
@Override
- public void clear() {
- map.clear();
+ public boolean contains(Object o) {
+ return LocalCache.this.containsKey(o);
}
- }
- final class KeySet extends AbstractCacheSet<K> {
-
- KeySet(ConcurrentMap<?, ?> map) {
- super(map);
+ @Override
+ public boolean remove(Object o) {
+ return LocalCache.this.remove(o) != null;
}
@Override
- public Iterator<K> iterator() {
- return new KeyIterator();
+ public void clear() {
+ LocalCache.this.clear();
}
+ }
+
+ final class Values extends AbstractCollection<V> {
@Override
- public boolean contains(Object o) {
- return map.containsKey(o);
+ public Iterator<V> iterator() {
+ return new ValueIterator();
}
@Override
- public boolean remove(Object o) {
- return map.remove(o) != null;
+ public int size() {
+ return LocalCache.this.size();
}
- }
-
- final class Values extends AbstractCacheSet<V> {
- Values(ConcurrentMap<?, ?> map) {
- super(map);
+ @Override
+ public boolean isEmpty() {
+ return LocalCache.this.isEmpty();
}
@Override
- public Iterator<V> iterator() {
- return new ValueIterator();
+ public boolean contains(Object o) {
+ return LocalCache.this.containsValue(o);
}
@Override
- public boolean contains(Object o) {
- return map.containsValue(o);
+ public void clear() {
+ LocalCache.this.clear();
}
}
- final class EntrySet extends AbstractCacheSet<Entry<K, V>> {
-
- EntrySet(ConcurrentMap<?, ?> map) {
- super(map);
- }
+ final class EntrySet extends AbstractSet<Entry<K, V>> {
@Override
public Iterator<Entry<K, V>> iterator() {
@@ -4594,6 +4553,21 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
Object key = e.getKey();
return key != null && LocalCache.this.remove(key, e.getValue());
}
+
+ @Override
+ public int size() {
+ return LocalCache.this.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return LocalCache.this.isEmpty();
+ }
+
+ @Override
+ public void clear() {
+ LocalCache.this.clear();
+ }
}
// Serialization Support
@@ -4663,15 +4637,15 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
this.loader = loader;
}
- CacheBuilder<K, V> recreateCacheBuilder() {
- CacheBuilder<K, V> builder = CacheBuilder.newBuilder()
+ CacheBuilder<Object, Object> recreateCacheBuilder() {
+ CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder()
.setKeyStrength(keyStrength)
.setValueStrength(valueStrength)
.keyEquivalence(keyEquivalence)
.valueEquivalence(valueEquivalence)
- .concurrencyLevel(concurrencyLevel)
- .removalListener(removalListener);
+ .concurrencyLevel(concurrencyLevel);
builder.strictParsing = false;
+ builder.removalListener(removalListener);
if (expireAfterWriteNanos > 0) {
builder.expireAfterWrite(expireAfterWriteNanos, TimeUnit.NANOSECONDS);
}
@@ -4696,7 +4670,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
- CacheBuilder<K, V> builder = recreateCacheBuilder();
+ CacheBuilder<Object, Object> builder = recreateCacheBuilder();
this.delegate = builder.build();
}
@@ -4730,7 +4704,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
- CacheBuilder<K, V> builder = recreateCacheBuilder();
+ CacheBuilder<Object, Object> builder = recreateCacheBuilder();
this.autoDelegate = builder.build(loader);
}
@@ -4768,18 +4742,19 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
final LocalCache<K, V> localCache;
LocalManualCache(CacheBuilder<? super K, ? super V> builder) {
- this(new LocalCache<K, V>(builder, null));
+ this(builder, null);
}
- private LocalManualCache(LocalCache<K, V> localCache) {
- this.localCache = localCache;
+ protected LocalManualCache(CacheBuilder<? super K, ? super V> builder,
+ CacheLoader<? super K, V> loader) {
+ this.localCache = new LocalCache<K, V>(builder, loader);
}
// Cache methods
@Override
@Nullable
- public V getIfPresent(Object key) {
+ public V getIfPresent(K key) {
return localCache.getIfPresent(key);
}
@@ -4795,7 +4770,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
@Override
- public ImmutableMap<K, V> getAllPresent(Iterable<?> keys) {
+ public ImmutableMap<K, V> getAllPresent(Iterable<? extends K> keys) {
return localCache.getAllPresent(keys);
}
@@ -4805,11 +4780,6 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
}
@Override
- public void putAll(Map<? extends K, ? extends V> m) {
- localCache.putAll(m);
- }
-
- @Override
public void invalidate(Object key) {
checkNotNull(key);
localCache.remove(key);
@@ -4850,6 +4820,27 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
localCache.cleanUp();
}
+ /*
+ * These methods have been moved to LoadingCache, but they temporarily
+ * remain in Cache in Guava.
+ */
+
+ public V get(K key) throws ExecutionException {
+ return localCache.getOrLoad(key);
+ }
+
+ public V getUnchecked(K key) {
+ try {
+ return get(key);
+ } catch (ExecutionException e) {
+ throw new UncheckedExecutionException(e.getCause());
+ }
+ }
+
+ public final V apply(K key) {
+ return getUnchecked(key);
+ }
+
// Serialization Support
private static final long serialVersionUID = 1;
@@ -4864,24 +4855,10 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
LocalLoadingCache(CacheBuilder<? super K, ? super V> builder,
CacheLoader<? super K, V> loader) {
- super(new LocalCache<K, V>(builder, checkNotNull(loader)));
+ super(builder, checkNotNull(loader));
}
- // LoadingCache methods
-
- @Override
- public V get(K key) throws ExecutionException {
- return localCache.getOrLoad(key);
- }
-
- @Override
- public V getUnchecked(K key) {
- try {
- return get(key);
- } catch (ExecutionException e) {
- throw new UncheckedExecutionException(e.getCause());
- }
- }
+ // Cache methods
@Override
public ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
@@ -4893,16 +4870,10 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>
localCache.refresh(key);
}
- @Override
- public final V apply(K key) {
- return getUnchecked(key);
- }
-
// Serialization Support
private static final long serialVersionUID = 1;
- @Override
Object writeReplace() {
return new LoadingSerializationProxy<K, V>(localCache);
}
diff --git a/guava/src/com/google/common/cache/LongAddable.java b/guava/src/com/google/common/cache/LongAddable.java
deleted file mode 100644
index 48ddbfc..0000000
--- a/guava/src/com/google/common/cache/LongAddable.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * Abstract interface for objects that can concurrently add longs.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-interface LongAddable {
- void increment();
-
- void add(long x);
-
- long sum();
-}
diff --git a/guava/src/com/google/common/cache/LongAddables.java b/guava/src/com/google/common/cache/LongAddables.java
deleted file mode 100644
index a110c6c..0000000
--- a/guava/src/com/google/common/cache/LongAddables.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.cache;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Supplier;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Source of {@link LongAddable} objects that deals with GWT, Unsafe, and all
- * that.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-final class LongAddables {
- private static final Supplier<LongAddable> SUPPLIER;
-
- static {
- Supplier<LongAddable> supplier;
- try {
- new LongAdder();
- supplier = new Supplier<LongAddable>() {
- @Override
- public LongAddable get() {
- return new LongAdder();
- }
- };
- } catch (Throwable t) { // we really want to catch *everything*
- supplier = new Supplier<LongAddable>() {
- @Override
- public LongAddable get() {
- return new PureJavaLongAddable();
- }
- };
- }
- SUPPLIER = supplier;
- }
-
- public static LongAddable create() {
- return SUPPLIER.get();
- }
-
- private static final class PureJavaLongAddable extends AtomicLong implements LongAddable {
- @Override
- public void increment() {
- getAndIncrement();
- }
-
- @Override
- public void add(long x) {
- getAndAdd(x);
- }
-
- @Override
- public long sum() {
- return get();
- }
- }
-}
diff --git a/guava/src/com/google/common/cache/LongAdder.java b/guava/src/com/google/common/cache/LongAdder.java
deleted file mode 100644
index 5af81e1..0000000
--- a/guava/src/com/google/common/cache/LongAdder.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/*
- * Source:
- * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8
- */
-
-package com.google.common.cache;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.concurrent.atomic.AtomicLong;
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * One or more variables that together maintain an initially zero
- * {@code long} sum. When updates (method {@link #add}) are contended
- * across threads, the set of variables may grow dynamically to reduce
- * contention. Method {@link #sum} (or, equivalently, {@link
- * #longValue}) returns the current total combined across the
- * variables maintaining the sum.
- *
- * <p> This class is usually preferable to {@link AtomicLong} when
- * multiple threads update a common sum that is used for purposes such
- * as collecting statistics, not for fine-grained synchronization
- * control. Under low update contention, the two classes have similar
- * characteristics. But under high contention, expected throughput of
- * this class is significantly higher, at the expense of higher space
- * consumption.
- *
- * <p>This class extends {@link Number}, but does <em>not</em> define
- * methods such as {@code hashCode} and {@code compareTo} because
- * instances are expected to be mutated, and so are not useful as
- * collection keys.
- *
- * <p><em>jsr166e note: This class is targeted to be placed in
- * java.util.concurrent.atomic<em>
- *
- * @since 1.8
- * @author Doug Lea
- */
-@GwtCompatible(emulated = true)
-final class LongAdder extends Striped64 implements Serializable, LongAddable {
- private static final long serialVersionUID = 7249069246863182397L;
-
- /**
- * Version of plus for use in retryUpdate
- */
- final long fn(long v, long x) { return v + x; }
-
- /**
- * Creates a new adder with initial sum of zero.
- */
- public LongAdder() {
- }
-
- /**
- * Adds the given value.
- *
- * @param x the value to add
- */
- public void add(long x) {
- Cell[] as; long b, v; HashCode hc; Cell a; int n;
- if ((as = cells) != null || !casBase(b = base, b + x)) {
- boolean uncontended = true;
- int h = (hc = threadHashCode.get()).code;
- if (as == null || (n = as.length) < 1 ||
- (a = as[(n - 1) & h]) == null ||
- !(uncontended = a.cas(v = a.value, v + x)))
- retryUpdate(x, hc, uncontended);
- }
- }
-
- /**
- * Equivalent to {@code add(1)}.
- */
- public void increment() {
- add(1L);
- }
-
- /**
- * Equivalent to {@code add(-1)}.
- */
- public void decrement() {
- add(-1L);
- }
-
- /**
- * Returns the current sum. The returned value is <em>NOT</em> an
- * atomic snapshot: Invocation in the absence of concurrent
- * updates returns an accurate result, but concurrent updates that
- * occur while the sum is being calculated might not be
- * incorporated.
- *
- * @return the sum
- */
- public long sum() {
- long sum = base;
- Cell[] as = cells;
- if (as != null) {
- int n = as.length;
- for (int i = 0; i < n; ++i) {
- Cell a = as[i];
- if (a != null)
- sum += a.value;
- }
- }
- return sum;
- }
-
- /**
- * Resets variables maintaining the sum to zero. This method may
- * be a useful alternative to creating a new adder, but is only
- * effective if there are no concurrent updates. Because this
- * method is intrinsically racy, it should only be used when it is
- * known that no threads are concurrently updating.
- */
- public void reset() {
- internalReset(0L);
- }
-
- /**
- * Equivalent in effect to {@link #sum} followed by {@link
- * #reset}. This method may apply for example during quiescent
- * points between multithreaded computations. If there are
- * updates concurrent with this method, the returned value is
- * <em>not</em> guaranteed to be the final value occurring before
- * the reset.
- *
- * @return the sum
- */
- public long sumThenReset() {
- long sum = base;
- Cell[] as = cells;
- base = 0L;
- if (as != null) {
- int n = as.length;
- for (int i = 0; i < n; ++i) {
- Cell a = as[i];
- if (a != null) {
- sum += a.value;
- a.value = 0L;
- }
- }
- }
- return sum;
- }
-
- /**
- * Returns the String representation of the {@link #sum}.
- * @return the String representation of the {@link #sum}
- */
- public String toString() {
- return Long.toString(sum());
- }
-
- /**
- * Equivalent to {@link #sum}.
- *
- * @return the sum
- */
- public long longValue() {
- return sum();
- }
-
- /**
- * Returns the {@link #sum} as an {@code int} after a narrowing
- * primitive conversion.
- */
- public int intValue() {
- return (int)sum();
- }
-
- /**
- * Returns the {@link #sum} as a {@code float}
- * after a widening primitive conversion.
- */
- public float floatValue() {
- return (float)sum();
- }
-
- /**
- * Returns the {@link #sum} as a {@code double} after a widening
- * primitive conversion.
- */
- public double doubleValue() {
- return (double)sum();
- }
-
- private void writeObject(ObjectOutputStream s)
- throws java.io.IOException {
- s.defaultWriteObject();
- s.writeLong(sum());
- }
-
- private void readObject(ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- s.defaultReadObject();
- busy = 0;
- cells = null;
- base = s.readLong();
- }
-
-}
diff --git a/guava/src/com/google/common/cache/RemovalCause.java b/guava/src/com/google/common/cache/RemovalCause.java
index 0be9b5b..6574b0e 100644
--- a/guava/src/com/google/common/cache/RemovalCause.java
+++ b/guava/src/com/google/common/cache/RemovalCause.java
@@ -17,7 +17,6 @@
package com.google.common.cache;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
import java.util.Iterator;
import java.util.Map;
@@ -30,7 +29,6 @@ import java.util.concurrent.ConcurrentMap;
* @since 10.0
*/
@Beta
-@GwtCompatible
public enum RemovalCause {
/**
* The entry was manually removed by the user. This can result from the user invoking
diff --git a/guava/src/com/google/common/cache/RemovalListener.java b/guava/src/com/google/common/cache/RemovalListener.java
index 270a7c4..e9b6c2c 100644
--- a/guava/src/com/google/common/cache/RemovalListener.java
+++ b/guava/src/com/google/common/cache/RemovalListener.java
@@ -17,7 +17,6 @@
package com.google.common.cache;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
/**
* An object that can receive a notification when an entry is removed from a cache. The removal
@@ -37,7 +36,6 @@ import com.google.common.annotations.GwtCompatible;
* @since 10.0
*/
@Beta
-@GwtCompatible
public interface RemovalListener<K, V> {
/**
* Notifies the listener that a removal occurred at some point in the past.
diff --git a/guava/src/com/google/common/cache/RemovalListeners.java b/guava/src/com/google/common/cache/RemovalListeners.java
index dbb9efc..18292fd 100644
--- a/guava/src/com/google/common/cache/RemovalListeners.java
+++ b/guava/src/com/google/common/cache/RemovalListeners.java
@@ -16,8 +16,6 @@
package com.google.common.cache;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
import java.util.concurrent.Executor;
@@ -43,8 +41,6 @@ public final class RemovalListeners {
*/
public static <K, V> RemovalListener<K, V> asynchronous(
final RemovalListener<K, V> listener, final Executor executor) {
- checkNotNull(listener);
- checkNotNull(executor);
return new RemovalListener<K, V>() {
@Override
public void onRemoval(final RemovalNotification<K, V> notification) {
diff --git a/guava/src/com/google/common/cache/RemovalNotification.java b/guava/src/com/google/common/cache/RemovalNotification.java
index 2565dba..8e0066e 100644
--- a/guava/src/com/google/common/cache/RemovalNotification.java
+++ b/guava/src/com/google/common/cache/RemovalNotification.java
@@ -19,7 +19,6 @@ package com.google.common.cache;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
import java.util.Map.Entry;
@@ -38,7 +37,6 @@ import javax.annotation.Nullable;
* @since 10.0
*/
@Beta
-@GwtCompatible
public final class RemovalNotification<K, V> implements Entry<K, V> {
@Nullable private final K key;
@Nullable private final V value;
diff --git a/guava/src/com/google/common/cache/Striped64.java b/guava/src/com/google/common/cache/Striped64.java
deleted file mode 100644
index e045453..0000000
--- a/guava/src/com/google/common/cache/Striped64.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/*
- * Source:
- * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.7
- */
-
-package com.google.common.cache;
-
-import java.util.Random;
-
-/**
- * A package-local class holding common representation and mechanics
- * for classes supporting dynamic striping on 64bit values. The class
- * extends Number so that concrete subclasses must publicly do so.
- */
-abstract class Striped64 extends Number {
- /*
- * This class maintains a lazily-initialized table of atomically
- * updated variables, plus an extra "base" field. The table size
- * is a power of two. Indexing uses masked per-thread hash codes.
- * Nearly all declarations in this class are package-private,
- * accessed directly by subclasses.
- *
- * Table entries are of class Cell; a variant of AtomicLong padded
- * to reduce cache contention on most processors. Padding is
- * overkill for most Atomics because they are usually irregularly
- * scattered in memory and thus don't interfere much with each
- * other. But Atomic objects residing in arrays will tend to be
- * placed adjacent to each other, and so will most often share
- * cache lines (with a huge negative performance impact) without
- * this precaution.
- *
- * In part because Cells are relatively large, we avoid creating
- * them until they are needed. When there is no contention, all
- * updates are made to the base field. Upon first contention (a
- * failed CAS on base update), the table is initialized to size 2.
- * The table size is doubled upon further contention until
- * reaching the nearest power of two greater than or equal to the
- * number of CPUS. Table slots remain empty (null) until they are
- * needed.
- *
- * A single spinlock ("busy") is used for initializing and
- * resizing the table, as well as populating slots with new Cells.
- * There is no need for a blocking lock: When the lock is not
- * available, threads try other slots (or the base). During these
- * retries, there is increased contention and reduced locality,
- * which is still better than alternatives.
- *
- * Per-thread hash codes are initialized to random values.
- * Contention and/or table collisions are indicated by failed
- * CASes when performing an update operation (see method
- * retryUpdate). Upon a collision, if the table size is less than
- * the capacity, it is doubled in size unless some other thread
- * holds the lock. If a hashed slot is empty, and lock is
- * available, a new Cell is created. Otherwise, if the slot
- * exists, a CAS is tried. Retries proceed by "double hashing",
- * using a secondary hash (Marsaglia XorShift) to try to find a
- * free slot.
- *
- * The table size is capped because, when there are more threads
- * than CPUs, supposing that each thread were bound to a CPU,
- * there would exist a perfect hash function mapping threads to
- * slots that eliminates collisions. When we reach capacity, we
- * search for this mapping by randomly varying the hash codes of
- * colliding threads. Because search is random, and collisions
- * only become known via CAS failures, convergence can be slow,
- * and because threads are typically not bound to CPUS forever,
- * may not occur at all. However, despite these limitations,
- * observed contention rates are typically low in these cases.
- *
- * It is possible for a Cell to become unused when threads that
- * once hashed to it terminate, as well as in the case where
- * doubling the table causes no thread to hash to it under
- * expanded mask. We do not try to detect or remove such cells,
- * under the assumption that for long-running instances, observed
- * contention levels will recur, so the cells will eventually be
- * needed again; and for short-lived ones, it does not matter.
- */
-
- /**
- * Padded variant of AtomicLong supporting only raw accesses plus CAS.
- * The value field is placed between pads, hoping that the JVM doesn't
- * reorder them.
- *
- * JVM intrinsics note: It would be possible to use a release-only
- * form of CAS here, if it were provided.
- */
- static final class Cell {
- volatile long p0, p1, p2, p3, p4, p5, p6;
- volatile long value;
- volatile long q0, q1, q2, q3, q4, q5, q6;
- Cell(long x) { value = x; }
-
- final boolean cas(long cmp, long val) {
- return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
- }
-
- // Unsafe mechanics
- private static final sun.misc.Unsafe UNSAFE;
- private static final long valueOffset;
- static {
- try {
- UNSAFE = getUnsafe();
- Class<?> ak = Cell.class;
- valueOffset = UNSAFE.objectFieldOffset
- (ak.getDeclaredField("value"));
- } catch (Exception e) {
- throw new Error(e);
- }
- }
-
- }
-
- /**
- * Holder for the thread-local hash code. The code is initially
- * random, but may be set to a different value upon collisions.
- */
- static final class HashCode {
- static final Random rng = new Random();
- int code;
- HashCode() {
- int h = rng.nextInt(); // Avoid zero to allow xorShift rehash
- code = (h == 0) ? 1 : h;
- }
- }
-
- /**
- * The corresponding ThreadLocal class
- */
- static final class ThreadHashCode extends ThreadLocal<HashCode> {
- public HashCode initialValue() { return new HashCode(); }
- }
-
- /**
- * Static per-thread hash codes. Shared across all instances to
- * reduce ThreadLocal pollution and because adjustments due to
- * collisions in one table are likely to be appropriate for
- * others.
- */
- static final ThreadHashCode threadHashCode = new ThreadHashCode();
-
- /** Number of CPUS, to place bound on table size */
- static final int NCPU = Runtime.getRuntime().availableProcessors();
-
- /**
- * Table of cells. When non-null, size is a power of 2.
- */
- transient volatile Cell[] cells;
-
- /**
- * Base value, used mainly when there is no contention, but also as
- * a fallback during table initialization races. Updated via CAS.
- */
- transient volatile long base;
-
- /**
- * Spinlock (locked via CAS) used when resizing and/or creating Cells.
- */
- transient volatile int busy;
-
- /**
- * Package-private default constructor
- */
- Striped64() {
- }
-
- /**
- * CASes the base field.
- */
- final boolean casBase(long cmp, long val) {
- return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val);
- }
-
- /**
- * CASes the busy field from 0 to 1 to acquire lock.
- */
- final boolean casBusy() {
- return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1);
- }
-
- /**
- * Computes the function of current and new value. Subclasses
- * should open-code this update function for most uses, but the
- * virtualized form is needed within retryUpdate.
- *
- * @param currentValue the current value (of either base or a cell)
- * @param newValue the argument from a user update call
- * @return result of the update function
- */
- abstract long fn(long currentValue, long newValue);
-
- /**
- * Handles cases of updates involving initialization, resizing,
- * creating new Cells, and/or contention. See above for
- * explanation. This method suffers the usual non-modularity
- * problems of optimistic retry code, relying on rechecked sets of
- * reads.
- *
- * @param x the value
- * @param hc the hash code holder
- * @param wasUncontended false if CAS failed before call
- */
- final void retryUpdate(long x, HashCode hc, boolean wasUncontended) {
- int h = hc.code;
- boolean collide = false; // True if last slot nonempty
- for (;;) {
- Cell[] as; Cell a; int n; long v;
- if ((as = cells) != null && (n = as.length) > 0) {
- if ((a = as[(n - 1) & h]) == null) {
- if (busy == 0) { // Try to attach new Cell
- Cell r = new Cell(x); // Optimistically create
- if (busy == 0 && casBusy()) {
- boolean created = false;
- try { // Recheck under lock
- Cell[] rs; int m, j;
- if ((rs = cells) != null &&
- (m = rs.length) > 0 &&
- rs[j = (m - 1) & h] == null) {
- rs[j] = r;
- created = true;
- }
- } finally {
- busy = 0;
- }
- if (created)
- break;
- continue; // Slot is now non-empty
- }
- }
- collide = false;
- }
- else if (!wasUncontended) // CAS already known to fail
- wasUncontended = true; // Continue after rehash
- else if (a.cas(v = a.value, fn(v, x)))
- break;
- else if (n >= NCPU || cells != as)
- collide = false; // At max size or stale
- else if (!collide)
- collide = true;
- else if (busy == 0 && casBusy()) {
- try {
- if (cells == as) { // Expand table unless stale
- Cell[] rs = new Cell[n << 1];
- for (int i = 0; i < n; ++i)
- rs[i] = as[i];
- cells = rs;
- }
- } finally {
- busy = 0;
- }
- collide = false;
- continue; // Retry with expanded table
- }
- h ^= h << 13; // Rehash
- h ^= h >>> 17;
- h ^= h << 5;
- }
- else if (busy == 0 && cells == as && casBusy()) {
- boolean init = false;
- try { // Initialize table
- if (cells == as) {
- Cell[] rs = new Cell[2];
- rs[h & 1] = new Cell(x);
- cells = rs;
- init = true;
- }
- } finally {
- busy = 0;
- }
- if (init)
- break;
- }
- else if (casBase(v = base, fn(v, x)))
- break; // Fall back on using base
- }
- hc.code = h; // Record index for next time
- }
-
- /**
- * Sets base and all cells to the given value.
- */
- final void internalReset(long initialValue) {
- Cell[] as = cells;
- base = initialValue;
- if (as != null) {
- int n = as.length;
- for (int i = 0; i < n; ++i) {
- Cell a = as[i];
- if (a != null)
- a.value = initialValue;
- }
- }
- }
-
- // Unsafe mechanics
- private static final sun.misc.Unsafe UNSAFE;
- private static final long baseOffset;
- private static final long busyOffset;
- static {
- try {
- UNSAFE = getUnsafe();
- Class<?> sk = Striped64.class;
- baseOffset = UNSAFE.objectFieldOffset
- (sk.getDeclaredField("base"));
- busyOffset = UNSAFE.objectFieldOffset
- (sk.getDeclaredField("busy"));
- } catch (Exception e) {
- throw new Error(e);
- }
- }
-
- /**
- * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
- * Replace with a simple call to Unsafe.getUnsafe when integrating
- * into a jdk.
- *
- * @return a sun.misc.Unsafe
- */
- private static sun.misc.Unsafe getUnsafe() {
- try {
- return sun.misc.Unsafe.getUnsafe();
- } catch (SecurityException tryReflectionInstead) {}
- try {
- return java.security.AccessController.doPrivileged
- (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
- public sun.misc.Unsafe run() throws Exception {
- Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
- for (java.lang.reflect.Field f : k.getDeclaredFields()) {
- f.setAccessible(true);
- Object x = f.get(null);
- if (k.isInstance(x))
- return k.cast(x);
- }
- throw new NoSuchFieldError("the Unsafe");
- }});
- } catch (java.security.PrivilegedActionException e) {
- throw new RuntimeException("Could not initialize intrinsics",
- e.getCause());
- }
- }
-
-}
diff --git a/guava/src/com/google/common/cache/Weigher.java b/guava/src/com/google/common/cache/Weigher.java
index 5720cb8..bbb0a33 100644
--- a/guava/src/com/google/common/cache/Weigher.java
+++ b/guava/src/com/google/common/cache/Weigher.java
@@ -1,30 +1,30 @@
/*
* Copyright (C) 2011 The Guava Authors
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations
- * under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.google.common.cache;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
/**
* Calculates the weights of cache entries.
*
- * @author Charles Fry
+ * @author fry@google.com (Charles Fry)
* @since 11.0
*/
@Beta
-@GwtCompatible
public interface Weigher<K, V> {
/**
@@ -34,4 +34,5 @@ public interface Weigher<K, V> {
* @return the weight of the entry; must be non-negative
*/
int weigh(K key, V value);
+
}
diff --git a/guava/src/com/google/common/cache/package-info.java b/guava/src/com/google/common/cache/package-info.java
index ea0297b..1c5391c 100644
--- a/guava/src/com/google/common/cache/package-info.java
+++ b/guava/src/com/google/common/cache/package-info.java
@@ -22,9 +22,6 @@
* {@link com.google.common.cache.CacheBuilder}, with cache entries being loaded by
* {@link com.google.common.cache.CacheLoader}. Statistics about cache performance are exposed using
* {@link com.google.common.cache.CacheStats}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CachesExplained">caches</a>.
*
* <p>This package is a part of the open-source
* <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
@@ -35,4 +32,3 @@
package com.google.common.cache;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/guava/src/com/google/common/collect/AbstractBiMap.java b/guava/src/com/google/common/collect/AbstractBiMap.java
index 44ab8c7..2a94f88 100644
--- a/guava/src/com/google/common/collect/AbstractBiMap.java
+++ b/guava/src/com/google/common/collect/AbstractBiMap.java
@@ -49,7 +49,7 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
implements BiMap<K, V>, Serializable {
private transient Map<K, V> delegate;
- transient AbstractBiMap<V, K> inverse;
+ private transient AbstractBiMap<V, K> inverse;
/** Package-private constructor for creating a map-backed bimap. */
AbstractBiMap(Map<K, V> forward, Map<V, K> backward) {
@@ -67,20 +67,6 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
}
/**
- * Returns its input, or throws an exception if this is not a valid key.
- */
- K checkKey(@Nullable K key) {
- return key;
- }
-
- /**
- * Returns its input, or throws an exception if this is not a valid value.
- */
- V checkValue(@Nullable V value) {
- return value;
- }
-
- /**
* Specifies the delegate maps going in each direction. Called by the
* constructor and by subclasses during deserialization.
*/
@@ -100,24 +86,22 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
// Query Operations (optimizations)
- @Override public boolean containsValue(@Nullable Object value) {
+ @Override public boolean containsValue(Object value) {
return inverse.containsKey(value);
}
// Modification Operations
- @Override public V put(@Nullable K key, @Nullable V value) {
+ @Override public V put(K key, V value) {
return putInBothMaps(key, value, false);
}
@Override
- public V forcePut(@Nullable K key, @Nullable V value) {
+ public V forcePut(K key, V value) {
return putInBothMaps(key, value, true);
}
private V putInBothMaps(@Nullable K key, @Nullable V value, boolean force) {
- checkKey(key);
- checkValue(value);
boolean containedKey = containsKey(key);
if (containedKey && Objects.equal(value, get(key))) {
return value;
@@ -140,7 +124,7 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
inverse.delegate.put(newValue, key);
}
- @Override public V remove(@Nullable Object key) {
+ @Override public V remove(Object key) {
return containsKey(key) ? removeFromBothMaps(key) : null;
}
@@ -207,7 +191,27 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
}
@Override public Iterator<K> iterator() {
- return Maps.keyIterator(entrySet().iterator());
+ final Iterator<Entry<K, V>> iterator = delegate.entrySet().iterator();
+ return new Iterator<K>() {
+ Entry<K, V> entry;
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ @Override
+ public K next() {
+ entry = iterator.next();
+ return entry.getKey();
+ }
+ @Override
+ public void remove() {
+ checkState(entry != null);
+ V value = entry.getValue();
+ iterator.remove();
+ removeFromInverseMap(value);
+ }
+ };
}
}
@@ -230,7 +234,23 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
}
@Override public Iterator<V> iterator() {
- return Maps.valueIterator(entrySet().iterator());
+ final Iterator<V> iterator = delegate.values().iterator();
+ return new Iterator<V>() {
+ V valueToRemove;
+
+ @Override public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override public V next() {
+ return valueToRemove = iterator.next();
+ }
+
+ @Override public void remove() {
+ iterator.remove();
+ removeFromInverseMap(valueToRemove);
+ }
+ };
}
@Override public Object[] toArray() {
@@ -363,16 +383,6 @@ abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V>
* instances have inverse() methods that return the other.
*/
- @Override
- K checkKey(K key) {
- return inverse.checkValue(key);
- }
-
- @Override
- V checkValue(V value) {
- return inverse.checkKey(value);
- }
-
/**
* @serialData the forward bimap
*/
diff --git a/guava/src/com/google/common/collect/AbstractSequentialIterator.java b/guava/src/com/google/common/collect/AbstractLinkedIterator.java
index c6567f5..e796b9b 100644
--- a/guava/src/com/google/common/collect/AbstractSequentialIterator.java
+++ b/guava/src/com/google/common/collect/AbstractLinkedIterator.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.NoSuchElementException;
@@ -30,18 +31,18 @@ import javax.annotation.Nullable;
*
* <p>Example: <pre> {@code
*
- * Iterator<Integer> powersOfTwo =
- * new AbstractSequentialIterator<Integer>(1) {
- * protected Integer computeNext(Integer previous) {
- * return (previous == 1 << 30) ? null : previous * 2;
- * }
- * };}</pre>
+ * Iterator<Integer> powersOfTwo = new AbstractLinkedIterator<Integer>(1) {
+ * protected Integer computeNext(Integer previous) {
+ * return (previous == 1 << 30) ? null : previous * 2;
+ * }
+ * };}</pre>
*
* @author Chris Povirk
- * @since 12.0 (in Guava as {@code AbstractLinkedIterator} since 8.0)
+ * @since 8.0
*/
+@Beta
@GwtCompatible
-public abstract class AbstractSequentialIterator<T>
+public abstract class AbstractLinkedIterator<T>
extends UnmodifiableIterator<T> {
private T nextOrNull;
@@ -49,7 +50,7 @@ public abstract class AbstractSequentialIterator<T>
* Creates a new iterator with the given first element, or, if {@code
* firstOrNull} is null, creates a new empty iterator.
*/
- protected AbstractSequentialIterator(@Nullable T firstOrNull) {
+ protected AbstractLinkedIterator(@Nullable T firstOrNull) {
this.nextOrNull = firstOrNull;
}
diff --git a/guava/src/com/google/common/collect/AbstractListMultimap.java b/guava/src/com/google/common/collect/AbstractListMultimap.java
index 3759c93..ad24011 100644
--- a/guava/src/com/google/common/collect/AbstractListMultimap.java
+++ b/guava/src/com/google/common/collect/AbstractListMultimap.java
@@ -26,7 +26,7 @@ import javax.annotation.Nullable;
/**
* Basic implementation of the {@link ListMultimap} interface. It's a wrapper
- * around {@link AbstractMapBasedMultimap} that converts the returned collections into
+ * around {@link AbstractMultimap} that converts the returned collections into
* {@code Lists}. The {@link #createCollection} method must return a {@code
* List}.
*
@@ -35,7 +35,7 @@ import javax.annotation.Nullable;
*/
@GwtCompatible
abstract class AbstractListMultimap<K, V>
- extends AbstractMapBasedMultimap<K, V> implements ListMultimap<K, V> {
+ extends AbstractMultimap<K, V> implements ListMultimap<K, V> {
/**
* Creates a new multimap that uses the provided map.
*
@@ -48,11 +48,6 @@ abstract class AbstractListMultimap<K, V>
@Override abstract List<V> createCollection();
- @Override
- List<V> createUnmodifiableEmptyCollection() {
- return ImmutableList.of();
- }
-
// Following Javadoc copied from ListMultimap.
/**
diff --git a/guava/src/com/google/common/collect/AbstractMapBasedMultimap.java b/guava/src/com/google/common/collect/AbstractMapBasedMultimap.java
deleted file mode 100644
index 0a1edf3..0000000
--- a/guava/src/com/google/common/collect/AbstractMapBasedMultimap.java
+++ /dev/null
@@ -1,1567 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.RandomAccess;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * Basic implementation of the {@link Multimap} interface. This class represents
- * a multimap as a map that associates each key with a collection of values. All
- * methods of {@link Multimap} are supported, including those specified as
- * optional in the interface.
- *
- * <p>To implement a multimap, a subclass must define the method {@link
- * #createCollection()}, which creates an empty collection of values for a key.
- *
- * <p>The multimap constructor takes a map that has a single entry for each
- * distinct key. When you insert a key-value pair with a key that isn't already
- * in the multimap, {@code AbstractMapBasedMultimap} calls {@link #createCollection()}
- * to create the collection of values for that key. The subclass should not call
- * {@link #createCollection()} directly, and a new instance should be created
- * every time the method is called.
- *
- * <p>For example, the subclass could pass a {@link java.util.TreeMap} during
- * construction, and {@link #createCollection()} could return a {@link
- * java.util.TreeSet}, in which case the multimap's iterators would propagate
- * through the keys and values in sorted order.
- *
- * <p>Keys and values may be null, as long as the underlying collection classes
- * support null elements.
- *
- * <p>The collections created by {@link #createCollection()} may or may not
- * allow duplicates. If the collection, such as a {@link Set}, does not support
- * duplicates, an added key-value pair will replace an existing pair with the
- * same key and value, if such a pair is present. With collections like {@link
- * List} that allow duplicates, the collection will keep the existing key-value
- * pairs while adding a new pair.
- *
- * <p>This class is not threadsafe when any concurrent operations update the
- * multimap, even if the underlying map and {@link #createCollection()} method
- * return threadsafe classes. Concurrent read operations will work correctly. To
- * allow concurrent update operations, wrap your multimap with a call to {@link
- * Multimaps#synchronizedMultimap}.
- *
- * <p>For serialization to work, the subclass must specify explicit
- * {@code readObject} and {@code writeObject} methods.
- *
- * @author Jared Levy
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-abstract class AbstractMapBasedMultimap<K, V> extends AbstractMultimap<K, V>
- implements Serializable {
- /*
- * Here's an outline of the overall design.
- *
- * The map variable contains the collection of values associated with each
- * key. When a key-value pair is added to a multimap that didn't previously
- * contain any values for that key, a new collection generated by
- * createCollection is added to the map. That same collection instance
- * remains in the map as long as the multimap has any values for the key. If
- * all values for the key are removed, the key and collection are removed
- * from the map.
- *
- * The get method returns a WrappedCollection, which decorates the collection
- * in the map (if the key is present) or an empty collection (if the key is
- * not present). When the collection delegate in the WrappedCollection is
- * empty, the multimap may contain subsequently added values for that key. To
- * handle that situation, the WrappedCollection checks whether map contains
- * an entry for the provided key, and if so replaces the delegate.
- */
-
- private transient Map<K, Collection<V>> map;
- private transient int totalSize;
-
- /**
- * Creates a new multimap that uses the provided map.
- *
- * @param map place to store the mapping from each key to its corresponding
- * values
- * @throws IllegalArgumentException if {@code map} is not empty
- */
- protected AbstractMapBasedMultimap(Map<K, Collection<V>> map) {
- checkArgument(map.isEmpty());
- this.map = map;
- }
-
- /** Used during deserialization only. */
- final void setMap(Map<K, Collection<V>> map) {
- this.map = map;
- totalSize = 0;
- for (Collection<V> values : map.values()) {
- checkArgument(!values.isEmpty());
- totalSize += values.size();
- }
- }
-
- /**
- * Creates an unmodifiable, empty collection of values.
- *
- * <p>This is used in {@link #removeAll} on an empty key.
- */
- Collection<V> createUnmodifiableEmptyCollection() {
- return unmodifiableCollectionSubclass(createCollection());
- }
-
- /**
- * Creates the collection of values for a single key.
- *
- * <p>Collections with weak, soft, or phantom references are not supported.
- * Each call to {@code createCollection} should create a new instance.
- *
- * <p>The returned collection class determines whether duplicate key-value
- * pairs are allowed.
- *
- * @return an empty collection of values
- */
- abstract Collection<V> createCollection();
-
- /**
- * Creates the collection of values for an explicitly provided key. By
- * default, it simply calls {@link #createCollection()}, which is the correct
- * behavior for most implementations. The {@link LinkedHashMultimap} class
- * overrides it.
- *
- * @param key key to associate with values in the collection
- * @return an empty collection of values
- */
- Collection<V> createCollection(@Nullable K key) {
- return createCollection();
- }
-
- Map<K, Collection<V>> backingMap() {
- return map;
- }
-
- // Query Operations
-
- @Override
- public int size() {
- return totalSize;
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return map.containsKey(key);
- }
-
- // Modification Operations
-
- @Override
- public boolean put(@Nullable K key, @Nullable V value) {
- Collection<V> collection = map.get(key);
- if (collection == null) {
- collection = createCollection(key);
- if (collection.add(value)) {
- totalSize++;
- map.put(key, collection);
- return true;
- } else {
- throw new AssertionError("New Collection violated the Collection spec");
- }
- } else if (collection.add(value)) {
- totalSize++;
- return true;
- } else {
- return false;
- }
- }
-
- private Collection<V> getOrCreateCollection(@Nullable K key) {
- Collection<V> collection = map.get(key);
- if (collection == null) {
- collection = createCollection(key);
- map.put(key, collection);
- }
- return collection;
- }
-
- // Bulk Operations
-
- /**
- * {@inheritDoc}
- *
- * <p>The returned collection is immutable.
- */
- @Override
- public Collection<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
- Iterator<? extends V> iterator = values.iterator();
- if (!iterator.hasNext()) {
- return removeAll(key);
- }
-
- // TODO(user): investigate atomic failure?
- Collection<V> collection = getOrCreateCollection(key);
- Collection<V> oldValues = createCollection();
- oldValues.addAll(collection);
-
- totalSize -= collection.size();
- collection.clear();
-
- while (iterator.hasNext()) {
- if (collection.add(iterator.next())) {
- totalSize++;
- }
- }
-
- return unmodifiableCollectionSubclass(oldValues);
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The returned collection is immutable.
- */
- @Override
- public Collection<V> removeAll(@Nullable Object key) {
- Collection<V> collection = map.remove(key);
-
- if (collection == null) {
- return createUnmodifiableEmptyCollection();
- }
-
- Collection<V> output = createCollection();
- output.addAll(collection);
- totalSize -= collection.size();
- collection.clear();
-
- return unmodifiableCollectionSubclass(output);
- }
-
- Collection<V> unmodifiableCollectionSubclass(Collection<V> collection) {
- // We don't deal with NavigableSet here yet for GWT reasons -- instead,
- // non-GWT TreeMultimap explicitly overrides this and uses NavigableSet.
- if (collection instanceof SortedSet) {
- return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
- } else if (collection instanceof Set) {
- return Collections.unmodifiableSet((Set<V>) collection);
- } else if (collection instanceof List) {
- return Collections.unmodifiableList((List<V>) collection);
- } else {
- return Collections.unmodifiableCollection(collection);
- }
- }
-
- @Override
- public void clear() {
- // Clear each collection, to make previously returned collections empty.
- for (Collection<V> collection : map.values()) {
- collection.clear();
- }
- map.clear();
- totalSize = 0;
- }
-
- // Views
-
- /**
- * {@inheritDoc}
- *
- * <p>The returned collection is not serializable.
- */
- @Override
- public Collection<V> get(@Nullable K key) {
- Collection<V> collection = map.get(key);
- if (collection == null) {
- collection = createCollection(key);
- }
- return wrapCollection(key, collection);
- }
-
- /**
- * Generates a decorated collection that remains consistent with the values in
- * the multimap for the provided key. Changes to the multimap may alter the
- * returned collection, and vice versa.
- */
- Collection<V> wrapCollection(@Nullable K key, Collection<V> collection) {
- // We don't deal with NavigableSet here yet for GWT reasons -- instead,
- // non-GWT TreeMultimap explicitly overrides this and uses NavigableSet.
- if (collection instanceof SortedSet) {
- return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
- } else if (collection instanceof Set) {
- return new WrappedSet(key, (Set<V>) collection);
- } else if (collection instanceof List) {
- return wrapList(key, (List<V>) collection, null);
- } else {
- return new WrappedCollection(key, collection, null);
- }
- }
-
- private List<V> wrapList(
- @Nullable K key, List<V> list, @Nullable WrappedCollection ancestor) {
- return (list instanceof RandomAccess)
- ? new RandomAccessWrappedList(key, list, ancestor)
- : new WrappedList(key, list, ancestor);
- }
-
- /**
- * Collection decorator that stays in sync with the multimap values for a key.
- * There are two kinds of wrapped collections: full and subcollections. Both
- * have a delegate pointing to the underlying collection class.
- *
- * <p>Full collections, identified by a null ancestor field, contain all
- * multimap values for a given key. Its delegate is a value in {@link
- * AbstractMapBasedMultimap#map} whenever the delegate is non-empty. The {@code
- * refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} methods ensure
- * that the {@code WrappedCollection} and map remain consistent.
- *
- * <p>A subcollection, such as a sublist, contains some of the values for a
- * given key. Its ancestor field points to the full wrapped collection with
- * all values for the key. The subcollection {@code refreshIfEmpty}, {@code
- * removeIfEmpty}, and {@code addToMap} methods call the corresponding methods
- * of the full wrapped collection.
- */
- private class WrappedCollection extends AbstractCollection<V> {
- final K key;
- Collection<V> delegate;
- final WrappedCollection ancestor;
- final Collection<V> ancestorDelegate;
-
- WrappedCollection(@Nullable K key, Collection<V> delegate,
- @Nullable WrappedCollection ancestor) {
- this.key = key;
- this.delegate = delegate;
- this.ancestor = ancestor;
- this.ancestorDelegate
- = (ancestor == null) ? null : ancestor.getDelegate();
- }
-
- /**
- * If the delegate collection is empty, but the multimap has values for the
- * key, replace the delegate with the new collection for the key.
- *
- * <p>For a subcollection, refresh its ancestor and validate that the
- * ancestor delegate hasn't changed.
- */
- void refreshIfEmpty() {
- if (ancestor != null) {
- ancestor.refreshIfEmpty();
- if (ancestor.getDelegate() != ancestorDelegate) {
- throw new ConcurrentModificationException();
- }
- } else if (delegate.isEmpty()) {
- Collection<V> newDelegate = map.get(key);
- if (newDelegate != null) {
- delegate = newDelegate;
- }
- }
- }
-
- /**
- * If collection is empty, remove it from {@code AbstractMapBasedMultimap.this.map}.
- * For subcollections, check whether the ancestor collection is empty.
- */
- void removeIfEmpty() {
- if (ancestor != null) {
- ancestor.removeIfEmpty();
- } else if (delegate.isEmpty()) {
- map.remove(key);
- }
- }
-
- K getKey() {
- return key;
- }
-
- /**
- * Add the delegate to the map. Other {@code WrappedCollection} methods
- * should call this method after adding elements to a previously empty
- * collection.
- *
- * <p>Subcollection add the ancestor's delegate instead.
- */
- void addToMap() {
- if (ancestor != null) {
- ancestor.addToMap();
- } else {
- map.put(key, delegate);
- }
- }
-
- @Override public int size() {
- refreshIfEmpty();
- return delegate.size();
- }
-
- @Override public boolean equals(@Nullable Object object) {
- if (object == this) {
- return true;
- }
- refreshIfEmpty();
- return delegate.equals(object);
- }
-
- @Override public int hashCode() {
- refreshIfEmpty();
- return delegate.hashCode();
- }
-
- @Override public String toString() {
- refreshIfEmpty();
- return delegate.toString();
- }
-
- Collection<V> getDelegate() {
- return delegate;
- }
-
- @Override public Iterator<V> iterator() {
- refreshIfEmpty();
- return new WrappedIterator();
- }
-
- /** Collection iterator for {@code WrappedCollection}. */
- class WrappedIterator implements Iterator<V> {
- final Iterator<V> delegateIterator;
- final Collection<V> originalDelegate = delegate;
-
- WrappedIterator() {
- delegateIterator = iteratorOrListIterator(delegate);
- }
-
- WrappedIterator(Iterator<V> delegateIterator) {
- this.delegateIterator = delegateIterator;
- }
-
- /**
- * If the delegate changed since the iterator was created, the iterator is
- * no longer valid.
- */
- void validateIterator() {
- refreshIfEmpty();
- if (delegate != originalDelegate) {
- throw new ConcurrentModificationException();
- }
- }
-
- @Override
- public boolean hasNext() {
- validateIterator();
- return delegateIterator.hasNext();
- }
-
- @Override
- public V next() {
- validateIterator();
- return delegateIterator.next();
- }
-
- @Override
- public void remove() {
- delegateIterator.remove();
- totalSize--;
- removeIfEmpty();
- }
-
- Iterator<V> getDelegateIterator() {
- validateIterator();
- return delegateIterator;
- }
- }
-
- @Override public boolean add(V value) {
- refreshIfEmpty();
- boolean wasEmpty = delegate.isEmpty();
- boolean changed = delegate.add(value);
- if (changed) {
- totalSize++;
- if (wasEmpty) {
- addToMap();
- }
- }
- return changed;
- }
-
- WrappedCollection getAncestor() {
- return ancestor;
- }
-
- // The following methods are provided for better performance.
-
- @Override public boolean addAll(Collection<? extends V> collection) {
- if (collection.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = delegate.addAll(collection);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- if (oldSize == 0) {
- addToMap();
- }
- }
- return changed;
- }
-
- @Override public boolean contains(Object o) {
- refreshIfEmpty();
- return delegate.contains(o);
- }
-
- @Override public boolean containsAll(Collection<?> c) {
- refreshIfEmpty();
- return delegate.containsAll(c);
- }
-
- @Override public void clear() {
- int oldSize = size(); // calls refreshIfEmpty
- if (oldSize == 0) {
- return;
- }
- delegate.clear();
- totalSize -= oldSize;
- removeIfEmpty(); // maybe shouldn't be removed if this is a sublist
- }
-
- @Override public boolean remove(Object o) {
- refreshIfEmpty();
- boolean changed = delegate.remove(o);
- if (changed) {
- totalSize--;
- removeIfEmpty();
- }
- return changed;
- }
-
- @Override public boolean removeAll(Collection<?> c) {
- if (c.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = delegate.removeAll(c);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- removeIfEmpty();
- }
- return changed;
- }
-
- @Override public boolean retainAll(Collection<?> c) {
- checkNotNull(c);
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = delegate.retainAll(c);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- removeIfEmpty();
- }
- return changed;
- }
- }
-
- private Iterator<V> iteratorOrListIterator(Collection<V> collection) {
- return (collection instanceof List)
- ? ((List<V>) collection).listIterator()
- : collection.iterator();
- }
-
- /** Set decorator that stays in sync with the multimap values for a key. */
- private class WrappedSet extends WrappedCollection implements Set<V> {
- WrappedSet(@Nullable K key, Set<V> delegate) {
- super(key, delegate, null);
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- if (c.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
-
- // Guava issue 1013: AbstractSet and most JDK set implementations are
- // susceptible to quadratic removeAll performance on lists;
- // use a slightly smarter implementation here
- boolean changed = Sets.removeAllImpl((Set<V>) delegate, c);
- if (changed) {
- int newSize = delegate.size();
- totalSize += (newSize - oldSize);
- removeIfEmpty();
- }
- return changed;
- }
- }
-
- /**
- * SortedSet decorator that stays in sync with the multimap values for a key.
- */
- private class WrappedSortedSet extends WrappedCollection
- implements SortedSet<V> {
- WrappedSortedSet(@Nullable K key, SortedSet<V> delegate,
- @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
-
- SortedSet<V> getSortedSetDelegate() {
- return (SortedSet<V>) getDelegate();
- }
-
- @Override
- public Comparator<? super V> comparator() {
- return getSortedSetDelegate().comparator();
- }
-
- @Override
- public V first() {
- refreshIfEmpty();
- return getSortedSetDelegate().first();
- }
-
- @Override
- public V last() {
- refreshIfEmpty();
- return getSortedSetDelegate().last();
- }
-
- @Override
- public SortedSet<V> headSet(V toElement) {
- refreshIfEmpty();
- return new WrappedSortedSet(
- getKey(), getSortedSetDelegate().headSet(toElement),
- (getAncestor() == null) ? this : getAncestor());
- }
-
- @Override
- public SortedSet<V> subSet(V fromElement, V toElement) {
- refreshIfEmpty();
- return new WrappedSortedSet(
- getKey(), getSortedSetDelegate().subSet(fromElement, toElement),
- (getAncestor() == null) ? this : getAncestor());
- }
-
- @Override
- public SortedSet<V> tailSet(V fromElement) {
- refreshIfEmpty();
- return new WrappedSortedSet(
- getKey(), getSortedSetDelegate().tailSet(fromElement),
- (getAncestor() == null) ? this : getAncestor());
- }
- }
-
- @GwtIncompatible("NavigableSet")
- class WrappedNavigableSet extends WrappedSortedSet implements NavigableSet<V> {
- WrappedNavigableSet(
- @Nullable K key, NavigableSet<V> delegate, @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
-
- @Override
- NavigableSet<V> getSortedSetDelegate() {
- return (NavigableSet<V>) super.getSortedSetDelegate();
- }
-
- @Override
- public V lower(V v) {
- return getSortedSetDelegate().lower(v);
- }
-
- @Override
- public V floor(V v) {
- return getSortedSetDelegate().floor(v);
- }
-
- @Override
- public V ceiling(V v) {
- return getSortedSetDelegate().ceiling(v);
- }
-
- @Override
- public V higher(V v) {
- return getSortedSetDelegate().higher(v);
- }
-
- @Override
- public V pollFirst() {
- return Iterators.pollNext(iterator());
- }
-
- @Override
- public V pollLast() {
- return Iterators.pollNext(descendingIterator());
- }
-
- private NavigableSet<V> wrap(NavigableSet<V> wrapped) {
- return new WrappedNavigableSet(key, wrapped,
- (getAncestor() == null) ? this : getAncestor());
- }
-
- @Override
- public NavigableSet<V> descendingSet() {
- return wrap(getSortedSetDelegate().descendingSet());
- }
-
- @Override
- public Iterator<V> descendingIterator() {
- return new WrappedIterator(getSortedSetDelegate().descendingIterator());
- }
-
- @Override
- public NavigableSet<V> subSet(
- V fromElement, boolean fromInclusive, V toElement, boolean toInclusive) {
- return wrap(
- getSortedSetDelegate().subSet(fromElement, fromInclusive, toElement, toInclusive));
- }
-
- @Override
- public NavigableSet<V> headSet(V toElement, boolean inclusive) {
- return wrap(getSortedSetDelegate().headSet(toElement, inclusive));
- }
-
- @Override
- public NavigableSet<V> tailSet(V fromElement, boolean inclusive) {
- return wrap(getSortedSetDelegate().tailSet(fromElement, inclusive));
- }
- }
-
- /** List decorator that stays in sync with the multimap values for a key. */
- private class WrappedList extends WrappedCollection implements List<V> {
- WrappedList(@Nullable K key, List<V> delegate,
- @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
-
- List<V> getListDelegate() {
- return (List<V>) getDelegate();
- }
-
- @Override
- public boolean addAll(int index, Collection<? extends V> c) {
- if (c.isEmpty()) {
- return false;
- }
- int oldSize = size(); // calls refreshIfEmpty
- boolean changed = getListDelegate().addAll(index, c);
- if (changed) {
- int newSize = getDelegate().size();
- totalSize += (newSize - oldSize);
- if (oldSize == 0) {
- addToMap();
- }
- }
- return changed;
- }
-
- @Override
- public V get(int index) {
- refreshIfEmpty();
- return getListDelegate().get(index);
- }
-
- @Override
- public V set(int index, V element) {
- refreshIfEmpty();
- return getListDelegate().set(index, element);
- }
-
- @Override
- public void add(int index, V element) {
- refreshIfEmpty();
- boolean wasEmpty = getDelegate().isEmpty();
- getListDelegate().add(index, element);
- totalSize++;
- if (wasEmpty) {
- addToMap();
- }
- }
-
- @Override
- public V remove(int index) {
- refreshIfEmpty();
- V value = getListDelegate().remove(index);
- totalSize--;
- removeIfEmpty();
- return value;
- }
-
- @Override
- public int indexOf(Object o) {
- refreshIfEmpty();
- return getListDelegate().indexOf(o);
- }
-
- @Override
- public int lastIndexOf(Object o) {
- refreshIfEmpty();
- return getListDelegate().lastIndexOf(o);
- }
-
- @Override
- public ListIterator<V> listIterator() {
- refreshIfEmpty();
- return new WrappedListIterator();
- }
-
- @Override
- public ListIterator<V> listIterator(int index) {
- refreshIfEmpty();
- return new WrappedListIterator(index);
- }
-
- @Override
- public List<V> subList(int fromIndex, int toIndex) {
- refreshIfEmpty();
- return wrapList(getKey(),
- getListDelegate().subList(fromIndex, toIndex),
- (getAncestor() == null) ? this : getAncestor());
- }
-
- /** ListIterator decorator. */
- private class WrappedListIterator extends WrappedIterator
- implements ListIterator<V> {
- WrappedListIterator() {}
-
- public WrappedListIterator(int index) {
- super(getListDelegate().listIterator(index));
- }
-
- private ListIterator<V> getDelegateListIterator() {
- return (ListIterator<V>) getDelegateIterator();
- }
-
- @Override
- public boolean hasPrevious() {
- return getDelegateListIterator().hasPrevious();
- }
-
- @Override
- public V previous() {
- return getDelegateListIterator().previous();
- }
-
- @Override
- public int nextIndex() {
- return getDelegateListIterator().nextIndex();
- }
-
- @Override
- public int previousIndex() {
- return getDelegateListIterator().previousIndex();
- }
-
- @Override
- public void set(V value) {
- getDelegateListIterator().set(value);
- }
-
- @Override
- public void add(V value) {
- boolean wasEmpty = isEmpty();
- getDelegateListIterator().add(value);
- totalSize++;
- if (wasEmpty) {
- addToMap();
- }
- }
- }
- }
-
- /**
- * List decorator that stays in sync with the multimap values for a key and
- * supports rapid random access.
- */
- private class RandomAccessWrappedList extends WrappedList
- implements RandomAccess {
- RandomAccessWrappedList(@Nullable K key, List<V> delegate,
- @Nullable WrappedCollection ancestor) {
- super(key, delegate, ancestor);
- }
- }
-
- @Override
- Set<K> createKeySet() {
- // TreeMultimap uses NavigableKeySet explicitly, but we don't handle that here for GWT
- // compatibility reasons
- return (map instanceof SortedMap)
- ? new SortedKeySet((SortedMap<K, Collection<V>>) map) : new KeySet(map);
- }
-
- private class KeySet extends Maps.KeySet<K, Collection<V>> {
-
- /**
- * This is usually the same as map, except when someone requests a
- * subcollection of a {@link SortedKeySet}.
- */
- final Map<K, Collection<V>> subMap;
-
- KeySet(final Map<K, Collection<V>> subMap) {
- this.subMap = subMap;
- }
-
- @Override
- Map<K, Collection<V>> map() {
- return subMap;
- }
-
- @Override public Iterator<K> iterator() {
- final Iterator<Map.Entry<K, Collection<V>>> entryIterator
- = subMap.entrySet().iterator();
- return new Iterator<K>() {
- Map.Entry<K, Collection<V>> entry;
-
- @Override
- public boolean hasNext() {
- return entryIterator.hasNext();
- }
- @Override
- public K next() {
- entry = entryIterator.next();
- return entry.getKey();
- }
- @Override
- public void remove() {
- Iterators.checkRemove(entry != null);
- Collection<V> collection = entry.getValue();
- entryIterator.remove();
- totalSize -= collection.size();
- collection.clear();
- }
- };
- }
-
- // The following methods are included for better performance.
-
- @Override public boolean remove(Object key) {
- int count = 0;
- Collection<V> collection = subMap.remove(key);
- if (collection != null) {
- count = collection.size();
- collection.clear();
- totalSize -= count;
- }
- return count > 0;
- }
-
- @Override
- public void clear() {
- Iterators.clear(iterator());
- }
-
- @Override public boolean containsAll(Collection<?> c) {
- return subMap.keySet().containsAll(c);
- }
-
- @Override public boolean equals(@Nullable Object object) {
- return this == object || this.subMap.keySet().equals(object);
- }
-
- @Override public int hashCode() {
- return subMap.keySet().hashCode();
- }
- }
-
- private class SortedKeySet extends KeySet implements SortedSet<K> {
-
- SortedKeySet(SortedMap<K, Collection<V>> subMap) {
- super(subMap);
- }
-
- SortedMap<K, Collection<V>> sortedMap() {
- return (SortedMap<K, Collection<V>>) subMap;
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return sortedMap().comparator();
- }
-
- @Override
- public K first() {
- return sortedMap().firstKey();
- }
-
- @Override
- public SortedSet<K> headSet(K toElement) {
- return new SortedKeySet(sortedMap().headMap(toElement));
- }
-
- @Override
- public K last() {
- return sortedMap().lastKey();
- }
-
- @Override
- public SortedSet<K> subSet(K fromElement, K toElement) {
- return new SortedKeySet(sortedMap().subMap(fromElement, toElement));
- }
-
- @Override
- public SortedSet<K> tailSet(K fromElement) {
- return new SortedKeySet(sortedMap().tailMap(fromElement));
- }
- }
-
- @GwtIncompatible("NavigableSet")
- class NavigableKeySet extends SortedKeySet implements NavigableSet<K> {
- NavigableKeySet(NavigableMap<K, Collection<V>> subMap) {
- super(subMap);
- }
-
- @Override
- NavigableMap<K, Collection<V>> sortedMap() {
- return (NavigableMap<K, Collection<V>>) super.sortedMap();
- }
-
- @Override
- public K lower(K k) {
- return sortedMap().lowerKey(k);
- }
-
- @Override
- public K floor(K k) {
- return sortedMap().floorKey(k);
- }
-
- @Override
- public K ceiling(K k) {
- return sortedMap().ceilingKey(k);
- }
-
- @Override
- public K higher(K k) {
- return sortedMap().higherKey(k);
- }
-
- @Override
- public K pollFirst() {
- return Iterators.pollNext(iterator());
- }
-
- @Override
- public K pollLast() {
- return Iterators.pollNext(descendingIterator());
- }
-
- @Override
- public NavigableSet<K> descendingSet() {
- return new NavigableKeySet(sortedMap().descendingMap());
- }
-
- @Override
- public Iterator<K> descendingIterator() {
- return descendingSet().iterator();
- }
-
- @Override
- public NavigableSet<K> headSet(K toElement) {
- return headSet(toElement, false);
- }
-
- @Override
- public NavigableSet<K> headSet(K toElement, boolean inclusive) {
- return new NavigableKeySet(sortedMap().headMap(toElement, inclusive));
- }
-
- @Override
- public NavigableSet<K> subSet(K fromElement, K toElement) {
- return subSet(fromElement, true, toElement, false);
- }
-
- @Override
- public NavigableSet<K> subSet(
- K fromElement, boolean fromInclusive, K toElement, boolean toInclusive) {
- return new NavigableKeySet(
- sortedMap().subMap(fromElement, fromInclusive, toElement, toInclusive));
- }
-
- @Override
- public NavigableSet<K> tailSet(K fromElement) {
- return tailSet(fromElement, true);
- }
-
- @Override
- public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
- return new NavigableKeySet(sortedMap().tailMap(fromElement, inclusive));
- }
- }
-
- /**
- * Removes all values for the provided key. Unlike {@link #removeAll}, it
- * returns the number of removed mappings.
- */
- private int removeValuesForKey(Object key) {
- Collection<V> collection = Maps.safeRemove(map, key);
-
- int count = 0;
- if (collection != null) {
- count = collection.size();
- collection.clear();
- totalSize -= count;
- }
- return count;
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>The iterator generated by the returned collection traverses the values
- * for one key, followed by the values of a second key, and so on.
- */
- @Override public Collection<V> values() {
- return super.values();
- }
-
- /*
- * TODO(kevinb): should we copy this javadoc to each concrete class, so that
- * classes like LinkedHashMultimap that need to say something different are
- * still able to {@inheritDoc} all the way from Multimap?
- */
-
- /**
- * {@inheritDoc}
- *
- * <p>The iterator generated by the returned collection traverses the values
- * for one key, followed by the values of a second key, and so on.
- *
- * <p>Each entry is an immutable snapshot of a key-value mapping in the
- * multimap, taken at the time the entry is returned by a method call to the
- * collection or its iterator.
- */
- @Override
- public Collection<Map.Entry<K, V>> entries() {
- return super.entries();
- }
-
- /**
- * Returns an iterator across all key-value map entries, used by {@code
- * entries().iterator()} and {@code values().iterator()}. The default
- * behavior, which traverses the values for one key, the values for a second
- * key, and so on, suffices for most {@code AbstractMapBasedMultimap} implementations.
- *
- * @return an iterator across map entries
- */
- @Override
- Iterator<Map.Entry<K, V>> entryIterator() {
- return new EntryIterator();
- }
-
- /** Iterator across all key-value pairs. */
- private class EntryIterator implements Iterator<Map.Entry<K, V>> {
- final Iterator<Map.Entry<K, Collection<V>>> keyIterator;
- K key;
- Collection<V> collection;
- Iterator<V> valueIterator;
-
- EntryIterator() {
- keyIterator = map.entrySet().iterator();
- if (keyIterator.hasNext()) {
- findValueIteratorAndKey();
- } else {
- valueIterator = Iterators.emptyModifiableIterator();
- }
- }
-
- void findValueIteratorAndKey() {
- Map.Entry<K, Collection<V>> entry = keyIterator.next();
- key = entry.getKey();
- collection = entry.getValue();
- valueIterator = collection.iterator();
- }
-
- @Override
- public boolean hasNext() {
- return keyIterator.hasNext() || valueIterator.hasNext();
- }
-
- @Override
- public Map.Entry<K, V> next() {
- if (!valueIterator.hasNext()) {
- findValueIteratorAndKey();
- }
- return Maps.immutableEntry(key, valueIterator.next());
- }
-
- @Override
- public void remove() {
- valueIterator.remove();
- if (collection.isEmpty()) {
- keyIterator.remove();
- }
- totalSize--;
- }
- }
-
- @Override
- Map<K, Collection<V>> createAsMap() {
- // TreeMultimap uses NavigableAsMap explicitly, but we don't handle that here for GWT
- // compatibility reasons
- return (map instanceof SortedMap)
- ? new SortedAsMap((SortedMap<K, Collection<V>>) map) : new AsMap(map);
- }
-
- private class AsMap extends AbstractMap<K, Collection<V>> {
- /**
- * Usually the same as map, but smaller for the headMap(), tailMap(), or
- * subMap() of a SortedAsMap.
- */
- final transient Map<K, Collection<V>> submap;
-
- AsMap(Map<K, Collection<V>> submap) {
- this.submap = submap;
- }
-
- transient Set<Map.Entry<K, Collection<V>>> entrySet;
-
- @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
- Set<Map.Entry<K, Collection<V>>> result = entrySet;
- return (result == null) ? entrySet = new AsMapEntries() : result;
- }
-
- // The following methods are included for performance.
-
- @Override public boolean containsKey(Object key) {
- return Maps.safeContainsKey(submap, key);
- }
-
- @Override public Collection<V> get(Object key) {
- Collection<V> collection = Maps.safeGet(submap, key);
- if (collection == null) {
- return null;
- }
- @SuppressWarnings("unchecked")
- K k = (K) key;
- return wrapCollection(k, collection);
- }
-
- @Override public Set<K> keySet() {
- return AbstractMapBasedMultimap.this.keySet();
- }
-
- @Override
- public int size() {
- return submap.size();
- }
-
- @Override public Collection<V> remove(Object key) {
- Collection<V> collection = submap.remove(key);
- if (collection == null) {
- return null;
- }
-
- Collection<V> output = createCollection();
- output.addAll(collection);
- totalSize -= collection.size();
- collection.clear();
- return output;
- }
-
- @Override public boolean equals(@Nullable Object object) {
- return this == object || submap.equals(object);
- }
-
- @Override public int hashCode() {
- return submap.hashCode();
- }
-
- @Override public String toString() {
- return submap.toString();
- }
-
- @Override
- public void clear() {
- if (submap == map) {
- AbstractMapBasedMultimap.this.clear();
- } else {
-
- Iterators.clear(new AsMapIterator());
- }
- }
-
- Entry<K, Collection<V>> wrapEntry(Entry<K, Collection<V>> entry) {
- K key = entry.getKey();
- return Maps.immutableEntry(key, wrapCollection(key, entry.getValue()));
- }
-
- class AsMapEntries extends Maps.EntrySet<K, Collection<V>> {
- @Override
- Map<K, Collection<V>> map() {
- return AsMap.this;
- }
-
- @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
- return new AsMapIterator();
- }
-
- // The following methods are included for performance.
-
- @Override public boolean contains(Object o) {
- return Collections2.safeContains(submap.entrySet(), o);
- }
-
- @Override public boolean remove(Object o) {
- if (!contains(o)) {
- return false;
- }
- Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
- removeValuesForKey(entry.getKey());
- return true;
- }
- }
-
- /** Iterator across all keys and value collections. */
- class AsMapIterator implements Iterator<Map.Entry<K, Collection<V>>> {
- final Iterator<Map.Entry<K, Collection<V>>> delegateIterator
- = submap.entrySet().iterator();
- Collection<V> collection;
-
- @Override
- public boolean hasNext() {
- return delegateIterator.hasNext();
- }
-
- @Override
- public Map.Entry<K, Collection<V>> next() {
- Map.Entry<K, Collection<V>> entry = delegateIterator.next();
- collection = entry.getValue();
- return wrapEntry(entry);
- }
-
- @Override
- public void remove() {
- delegateIterator.remove();
- totalSize -= collection.size();
- collection.clear();
- }
- }
- }
-
- private class SortedAsMap extends AsMap
- implements SortedMap<K, Collection<V>> {
- SortedAsMap(SortedMap<K, Collection<V>> submap) {
- super(submap);
- }
-
- SortedMap<K, Collection<V>> sortedMap() {
- return (SortedMap<K, Collection<V>>) submap;
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return sortedMap().comparator();
- }
-
- @Override
- public K firstKey() {
- return sortedMap().firstKey();
- }
-
- @Override
- public K lastKey() {
- return sortedMap().lastKey();
- }
-
- @Override
- public SortedMap<K, Collection<V>> headMap(K toKey) {
- return new SortedAsMap(sortedMap().headMap(toKey));
- }
-
- @Override
- public SortedMap<K, Collection<V>> subMap(K fromKey, K toKey) {
- return new SortedAsMap(sortedMap().subMap(fromKey, toKey));
- }
-
- @Override
- public SortedMap<K, Collection<V>> tailMap(K fromKey) {
- return new SortedAsMap(sortedMap().tailMap(fromKey));
- }
-
- SortedSet<K> sortedKeySet;
-
- // returns a SortedSet, even though returning a Set would be sufficient to
- // satisfy the SortedMap.keySet() interface
- @Override public SortedSet<K> keySet() {
- SortedSet<K> result = sortedKeySet;
- return (result == null) ? sortedKeySet = createKeySet() : result;
- }
-
- SortedSet<K> createKeySet() {
- return new SortedKeySet(sortedMap());
- }
- }
-
- @GwtIncompatible("NavigableAsMap")
- class NavigableAsMap extends SortedAsMap implements NavigableMap<K, Collection<V>> {
-
- NavigableAsMap(NavigableMap<K, Collection<V>> submap) {
- super(submap);
- }
-
- @Override
- NavigableMap<K, Collection<V>> sortedMap() {
- return (NavigableMap<K, Collection<V>>) super.sortedMap();
- }
-
- @Override
- public Entry<K, Collection<V>> lowerEntry(K key) {
- Entry<K, Collection<V>> entry = sortedMap().lowerEntry(key);
- return (entry == null) ? null : wrapEntry(entry);
- }
-
- @Override
- public K lowerKey(K key) {
- return sortedMap().lowerKey(key);
- }
-
- @Override
- public Entry<K, Collection<V>> floorEntry(K key) {
- Entry<K, Collection<V>> entry = sortedMap().floorEntry(key);
- return (entry == null) ? null : wrapEntry(entry);
- }
-
- @Override
- public K floorKey(K key) {
- return sortedMap().floorKey(key);
- }
-
- @Override
- public Entry<K, Collection<V>> ceilingEntry(K key) {
- Entry<K, Collection<V>> entry = sortedMap().ceilingEntry(key);
- return (entry == null) ? null : wrapEntry(entry);
- }
-
- @Override
- public K ceilingKey(K key) {
- return sortedMap().ceilingKey(key);
- }
-
- @Override
- public Entry<K, Collection<V>> higherEntry(K key) {
- Entry<K, Collection<V>> entry = sortedMap().higherEntry(key);
- return (entry == null) ? null : wrapEntry(entry);
- }
-
- @Override
- public K higherKey(K key) {
- return sortedMap().higherKey(key);
- }
-
- @Override
- public Entry<K, Collection<V>> firstEntry() {
- Entry<K, Collection<V>> entry = sortedMap().firstEntry();
- return (entry == null) ? null : wrapEntry(entry);
- }
-
- @Override
- public Entry<K, Collection<V>> lastEntry() {
- Entry<K, Collection<V>> entry = sortedMap().lastEntry();
- return (entry == null) ? null : wrapEntry(entry);
- }
-
- @Override
- public Entry<K, Collection<V>> pollFirstEntry() {
- return pollAsMapEntry(entrySet().iterator());
- }
-
- @Override
- public Entry<K, Collection<V>> pollLastEntry() {
- return pollAsMapEntry(descendingMap().entrySet().iterator());
- }
-
- Map.Entry<K, Collection<V>> pollAsMapEntry(Iterator<Entry<K, Collection<V>>> entryIterator) {
- if (!entryIterator.hasNext()) {
- return null;
- }
- Entry<K, Collection<V>> entry = entryIterator.next();
- Collection<V> output = createCollection();
- output.addAll(entry.getValue());
- entryIterator.remove();
- return Maps.immutableEntry(entry.getKey(), unmodifiableCollectionSubclass(output));
- }
-
- @Override
- public NavigableMap<K, Collection<V>> descendingMap() {
- return new NavigableAsMap(sortedMap().descendingMap());
- }
-
- @Override
- public NavigableSet<K> keySet() {
- return (NavigableSet<K>) super.keySet();
- }
-
- @Override
- NavigableSet<K> createKeySet() {
- return new NavigableKeySet(sortedMap());
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return keySet();
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return descendingMap().navigableKeySet();
- }
-
- @Override
- public NavigableMap<K, Collection<V>> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override
- public NavigableMap<K, Collection<V>> subMap(
- K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return new NavigableAsMap(sortedMap().subMap(fromKey, fromInclusive, toKey, toInclusive));
- }
-
- @Override
- public NavigableMap<K, Collection<V>> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override
- public NavigableMap<K, Collection<V>> headMap(K toKey, boolean inclusive) {
- return new NavigableAsMap(sortedMap().headMap(toKey, false));
- }
-
- @Override
- public NavigableMap<K, Collection<V>> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override
- public NavigableMap<K, Collection<V>> tailMap(K fromKey, boolean inclusive) {
- return new NavigableAsMap(sortedMap().tailMap(fromKey, inclusive));
- }
- }
-
- private static final long serialVersionUID = 2447537837011683357L;
-}
diff --git a/guava/src/com/google/common/collect/AbstractMapBasedMultiset.java b/guava/src/com/google/common/collect/AbstractMapBasedMultiset.java
index 6f14380..362386c 100644
--- a/guava/src/com/google/common/collect/AbstractMapBasedMultiset.java
+++ b/guava/src/com/google/common/collect/AbstractMapBasedMultiset.java
@@ -28,6 +28,7 @@ import com.google.common.primitives.Ints;
import java.io.InvalidObjectException;
import java.io.ObjectStreamException;
import java.io.Serializable;
+import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Map;
@@ -37,7 +38,7 @@ import javax.annotation.Nullable;
/**
* Basic implementation of {@code Multiset<E>} backed by an instance of {@code
- * Map<E, Count>}.
+ * Map<E, AtomicInteger>}.
*
* <p>For serialization to work, the subclass must specify explicit {@code
* readObject} and {@code writeObject} methods.
@@ -63,6 +64,10 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
this.size = super.size();
}
+ Map<E, Count> backingMap() {
+ return backingMap;
+ }
+
/** Used during deserialization only. The backing map must be empty. */
void setBackingMap(Map<E, Count> backingMap) {
this.backingMap = backingMap;
@@ -119,7 +124,8 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
@Override
public void remove() {
- Iterators.checkRemove(toRemove != null);
+ checkState(toRemove != null,
+ "no calls to next() since the last call to remove()");
size -= toRemove.getValue().getAndSet(0);
backingEntries.remove();
toRemove = null;
@@ -153,7 +159,7 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
/*
* Not subclassing AbstractMultiset$MultisetIterator because next() needs to
- * retrieve the Map.Entry<E, Count> entry, which can then be used for
+ * retrieve the Map.Entry<E, AtomicInteger> entry, which can then be used for
* a more efficient remove() call.
*/
private class MapBasedMultisetIterator implements Iterator<E> {
@@ -199,8 +205,14 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
}
@Override public int count(@Nullable Object element) {
- Count frequency = Maps.safeGet(backingMap, element);
- return (frequency == null) ? 0 : frequency.get();
+ try {
+ Count frequency = backingMap.get(element);
+ return (frequency == null) ? 0 : frequency.get();
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
}
// Optional Operations - Modification Operations
@@ -261,7 +273,7 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
}
// Roughly a 33% performance improvement over AbstractMultiset.setCount().
- @Override public int setCount(@Nullable E element, int count) {
+ @Override public int setCount(E element, int count) {
checkNonnegative(count, "count");
Count existingCounter;
@@ -290,6 +302,98 @@ abstract class AbstractMapBasedMultiset<E> extends AbstractMultiset<E>
return i.getAndSet(count);
}
+ private int removeAllOccurrences(@Nullable Object element,
+ Map<E, Count> map) {
+ Count frequency = map.remove(element);
+ if (frequency == null) {
+ return 0;
+ }
+ int numberRemoved = frequency.getAndSet(0);
+ size -= numberRemoved;
+ return numberRemoved;
+ }
+
+ // Views
+
+ @Override Set<E> createElementSet() {
+ return new MapBasedElementSet(backingMap);
+ }
+
+ // TODO(user): once TreeMultiset is replaced with a SortedMultiset
+ // implementation, replace this with a subclass of Multisets.ElementSet.
+ class MapBasedElementSet extends ForwardingSet<E> {
+
+ // This mapping is the usually the same as 'backingMap', but can be a
+ // submap in some implementations.
+ private final Map<E, Count> map;
+ private final Set<E> delegate;
+
+ MapBasedElementSet(Map<E, Count> map) {
+ this.map = map;
+ delegate = map.keySet();
+ }
+
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+
+ @Override public Iterator<E> iterator() {
+ final Iterator<Map.Entry<E, Count>> entries
+ = map.entrySet().iterator();
+ return new Iterator<E>() {
+ Map.Entry<E, Count> toRemove;
+
+ @Override
+ public boolean hasNext() {
+ return entries.hasNext();
+ }
+
+ @Override
+ public E next() {
+ toRemove = entries.next();
+ return toRemove.getKey();
+ }
+
+ @Override
+ public void remove() {
+ checkState(toRemove != null,
+ "no calls to next() since the last call to remove()");
+ size -= toRemove.getValue().getAndSet(0);
+ entries.remove();
+ toRemove = null;
+ }
+ };
+ }
+
+ @Override public boolean remove(Object element) {
+ return removeAllOccurrences(element, map) != 0;
+ }
+
+ @Override public boolean removeAll(Collection<?> elementsToRemove) {
+ return Iterators.removeAll(iterator(), elementsToRemove);
+ }
+
+ @Override public boolean retainAll(Collection<?> elementsToRetain) {
+ return Iterators.retainAll(iterator(), elementsToRetain);
+ }
+
+ @Override public void clear() {
+ if (map == backingMap) {
+ AbstractMapBasedMultiset.this.clear();
+ } else {
+ Iterator<E> i = iterator();
+ while (i.hasNext()) {
+ i.next();
+ i.remove();
+ }
+ }
+ }
+
+ public Map<E, Count> getMap() {
+ return map;
+ }
+ }
+
// Don't allow default serialization.
@GwtIncompatible("java.io.ObjectStreamException")
@SuppressWarnings("unused") // actually used during deserialization
diff --git a/guava/src/com/google/common/collect/AbstractMultimap.java b/guava/src/com/google/common/collect/AbstractMultimap.java
index 13fdd00..38f69ec 100644
--- a/guava/src/com/google/common/collect/AbstractMultimap.java
+++ b/guava/src/com/google/common/collect/AbstractMultimap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Guava Authors
+ * Copyright (C) 2007 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,33 +16,170 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
import com.google.common.annotations.GwtCompatible;
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.RandomAccess;
import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
import javax.annotation.Nullable;
/**
- * A skeleton {@code Multimap} implementation, not necessarily in terms of a {@code Map}.
- *
+ * Basic implementation of the {@link Multimap} interface. This class represents
+ * a multimap as a map that associates each key with a collection of values. All
+ * methods of {@link Multimap} are supported, including those specified as
+ * optional in the interface.
+ *
+ * <p>To implement a multimap, a subclass must define the method {@link
+ * #createCollection()}, which creates an empty collection of values for a key.
+ *
+ * <p>The multimap constructor takes a map that has a single entry for each
+ * distinct key. When you insert a key-value pair with a key that isn't already
+ * in the multimap, {@code AbstractMultimap} calls {@link #createCollection()}
+ * to create the collection of values for that key. The subclass should not call
+ * {@link #createCollection()} directly, and a new instance should be created
+ * every time the method is called.
+ *
+ * <p>For example, the subclass could pass a {@link java.util.TreeMap} during
+ * construction, and {@link #createCollection()} could return a {@link
+ * java.util.TreeSet}, in which case the multimap's iterators would propagate
+ * through the keys and values in sorted order.
+ *
+ * <p>Keys and values may be null, as long as the underlying collection classes
+ * support null elements.
+ *
+ * <p>The collections created by {@link #createCollection()} may or may not
+ * allow duplicates. If the collection, such as a {@link Set}, does not support
+ * duplicates, an added key-value pair will replace an existing pair with the
+ * same key and value, if such a pair is present. With collections like {@link
+ * List} that allow duplicates, the collection will keep the existing key-value
+ * pairs while adding a new pair.
+ *
+ * <p>This class is not threadsafe when any concurrent operations update the
+ * multimap, even if the underlying map and {@link #createCollection()} method
+ * return threadsafe classes. Concurrent read operations will work correctly. To
+ * allow concurrent update operations, wrap your multimap with a call to {@link
+ * Multimaps#synchronizedMultimap}.
+ *
+ * <p>For serialization to work, the subclass must specify explicit
+ * {@code readObject} and {@code writeObject} methods.
+ *
+ * @author Jared Levy
* @author Louis Wasserman
*/
@GwtCompatible
-abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
+abstract class AbstractMultimap<K, V> implements Multimap<K, V>, Serializable {
+ /*
+ * Here's an outline of the overall design.
+ *
+ * The map variable contains the collection of values associated with each
+ * key. When a key-value pair is added to a multimap that didn't previously
+ * contain any values for that key, a new collection generated by
+ * createCollection is added to the map. That same collection instance
+ * remains in the map as long as the multimap has any values for the key. If
+ * all values for the key are removed, the key and collection are removed
+ * from the map.
+ *
+ * The get method returns a WrappedCollection, which decorates the collection
+ * in the map (if the key is present) or an empty collection (if the key is
+ * not present). When the collection delegate in the WrappedCollection is
+ * empty, the multimap may contain subsequently added values for that key. To
+ * handle that situation, the WrappedCollection checks whether map contains
+ * an entry for the provided key, and if so replaces the delegate.
+ */
+
+ private transient Map<K, Collection<V>> map;
+ private transient int totalSize;
+
+ /**
+ * Creates a new multimap that uses the provided map.
+ *
+ * @param map place to store the mapping from each key to its corresponding
+ * values
+ * @throws IllegalArgumentException if {@code map} is not empty
+ */
+ protected AbstractMultimap(Map<K, Collection<V>> map) {
+ checkArgument(map.isEmpty());
+ this.map = map;
+ }
+
+ /** Used during deserialization only. */
+ final void setMap(Map<K, Collection<V>> map) {
+ this.map = map;
+ totalSize = 0;
+ for (Collection<V> values : map.values()) {
+ checkArgument(!values.isEmpty());
+ totalSize += values.size();
+ }
+ }
+
+ /**
+ * Creates the collection of values for a single key.
+ *
+ * <p>Collections with weak, soft, or phantom references are not supported.
+ * Each call to {@code createCollection} should create a new instance.
+ *
+ * <p>The returned collection class determines whether duplicate key-value
+ * pairs are allowed.
+ *
+ * @return an empty collection of values
+ */
+ abstract Collection<V> createCollection();
+
+ /**
+ * Creates the collection of values for an explicitly provided key. By
+ * default, it simply calls {@link #createCollection()}, which is the correct
+ * behavior for most implementations. The {@link LinkedHashMultimap} class
+ * overrides it.
+ *
+ * @param key key to associate with values in the collection
+ * @return an empty collection of values
+ */
+ Collection<V> createCollection(@Nullable K key) {
+ return createCollection();
+ }
+
+ Map<K, Collection<V>> backingMap() {
+ return map;
+ }
+
+ // Query Operations
+
+ @Override
+ public int size() {
+ return totalSize;
+ }
+
@Override
public boolean isEmpty() {
- return size() == 0;
+ return totalSize == 0;
+ }
+
+ @Override
+ public boolean containsKey(@Nullable Object key) {
+ return map.containsKey(key);
}
@Override
public boolean containsValue(@Nullable Object value) {
- for (Collection<V> collection : asMap().values()) {
+ for (Collection<V> collection : map.values()) {
if (collection.contains(value)) {
return true;
}
@@ -53,25 +190,72 @@ abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
@Override
public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
- Collection<V> collection = asMap().get(key);
+ Collection<V> collection = map.get(key);
return collection != null && collection.contains(value);
}
-
+
+ // Modification Operations
+
@Override
- public boolean remove(@Nullable Object key, @Nullable Object value) {
- Collection<V> collection = asMap().get(key);
- return collection != null && collection.remove(value);
+ public boolean put(@Nullable K key, @Nullable V value) {
+ Collection<V> collection = getOrCreateCollection(key);
+
+ if (collection.add(value)) {
+ totalSize++;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private Collection<V> getOrCreateCollection(@Nullable K key) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ collection = createCollection(key);
+ map.put(key, collection);
+ }
+ return collection;
}
@Override
- public boolean put(@Nullable K key, @Nullable V value) {
- return get(key).add(value);
+ public boolean remove(@Nullable Object key, @Nullable Object value) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ return false;
+ }
+
+ boolean changed = collection.remove(value);
+ if (changed) {
+ totalSize--;
+ if (collection.isEmpty()) {
+ map.remove(key);
+ }
+ }
+ return changed;
}
+ // Bulk Operations
+
@Override
public boolean putAll(@Nullable K key, Iterable<? extends V> values) {
- checkNotNull(values);
- return values.iterator().hasNext() && Iterables.addAll(get(key), values);
+ if (!values.iterator().hasNext()) {
+ return false;
+ }
+ Collection<V> collection = getOrCreateCollection(key);
+ int oldSize = collection.size();
+
+ boolean changed = false;
+ if (values instanceof Collection) {
+ Collection<? extends V> c = Collections2.cast(values);
+ changed = collection.addAll(c);
+ } else {
+ for (V value : values) {
+ changed |= collection.add(value);
+ }
+ }
+
+ totalSize += (collection.size() - oldSize);
+ return changed;
}
@Override
@@ -83,50 +267,597 @@ abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
return changed;
}
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned collection is immutable.
+ */
@Override
- public Collection<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
- checkNotNull(values);
- Collection<V> result = removeAll(key);
- putAll(key, values);
- return result;
+ public Collection<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
+ Iterator<? extends V> iterator = values.iterator();
+ if (!iterator.hasNext()) {
+ return removeAll(key);
+ }
+
+ Collection<V> collection = getOrCreateCollection(key);
+ Collection<V> oldValues = createCollection();
+ oldValues.addAll(collection);
+
+ totalSize -= collection.size();
+ collection.clear();
+
+ while (iterator.hasNext()) {
+ if (collection.add(iterator.next())) {
+ totalSize++;
+ }
+ }
+
+ return unmodifiableCollectionSubclass(oldValues);
}
-
- private transient Collection<Entry<K, V>> entries;
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned collection is immutable.
+ */
@Override
- public Collection<Entry<K, V>> entries() {
- Collection<Entry<K, V>> result = entries;
- return (result == null) ? entries = createEntries() : result;
+ public Collection<V> removeAll(@Nullable Object key) {
+ Collection<V> collection = map.remove(key);
+ Collection<V> output = createCollection();
+
+ if (collection != null) {
+ output.addAll(collection);
+ totalSize -= collection.size();
+ collection.clear();
+ }
+
+ return unmodifiableCollectionSubclass(output);
}
-
- Collection<Entry<K, V>> createEntries() {
- if (this instanceof SetMultimap) {
- return new Multimaps.EntrySet<K, V>() {
- @Override
- Multimap<K, V> multimap() {
- return AbstractMultimap.this;
+
+ private Collection<V> unmodifiableCollectionSubclass(
+ Collection<V> collection) {
+ if (collection instanceof SortedSet) {
+ return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
+ } else if (collection instanceof Set) {
+ return Collections.unmodifiableSet((Set<V>) collection);
+ } else if (collection instanceof List) {
+ return Collections.unmodifiableList((List<V>) collection);
+ } else {
+ return Collections.unmodifiableCollection(collection);
+ }
+ }
+
+ @Override
+ public void clear() {
+ // Clear each collection, to make previously returned collections empty.
+ for (Collection<V> collection : map.values()) {
+ collection.clear();
+ }
+ map.clear();
+ totalSize = 0;
+ }
+
+ // Views
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The returned collection is not serializable.
+ */
+ @Override
+ public Collection<V> get(@Nullable K key) {
+ Collection<V> collection = map.get(key);
+ if (collection == null) {
+ collection = createCollection(key);
+ }
+ return wrapCollection(key, collection);
+ }
+
+ /**
+ * Generates a decorated collection that remains consistent with the values in
+ * the multimap for the provided key. Changes to the multimap may alter the
+ * returned collection, and vice versa.
+ */
+ private Collection<V> wrapCollection(
+ @Nullable K key, Collection<V> collection) {
+ if (collection instanceof SortedSet) {
+ return new WrappedSortedSet(key, (SortedSet<V>) collection, null);
+ } else if (collection instanceof Set) {
+ return new WrappedSet(key, (Set<V>) collection);
+ } else if (collection instanceof List) {
+ return wrapList(key, (List<V>) collection, null);
+ } else {
+ return new WrappedCollection(key, collection, null);
+ }
+ }
+
+ private List<V> wrapList(
+ @Nullable K key, List<V> list, @Nullable WrappedCollection ancestor) {
+ return (list instanceof RandomAccess)
+ ? new RandomAccessWrappedList(key, list, ancestor)
+ : new WrappedList(key, list, ancestor);
+ }
+
+ /**
+ * Collection decorator that stays in sync with the multimap values for a key.
+ * There are two kinds of wrapped collections: full and subcollections. Both
+ * have a delegate pointing to the underlying collection class.
+ *
+ * <p>Full collections, identified by a null ancestor field, contain all
+ * multimap values for a given key. Its delegate is a value in {@link
+ * AbstractMultimap#map} whenever the delegate is non-empty. The {@code
+ * refreshIfEmpty}, {@code removeIfEmpty}, and {@code addToMap} methods ensure
+ * that the {@code WrappedCollection} and map remain consistent.
+ *
+ * <p>A subcollection, such as a sublist, contains some of the values for a
+ * given key. Its ancestor field points to the full wrapped collection with
+ * all values for the key. The subcollection {@code refreshIfEmpty}, {@code
+ * removeIfEmpty}, and {@code addToMap} methods call the corresponding methods
+ * of the full wrapped collection.
+ */
+ private class WrappedCollection extends AbstractCollection<V> {
+ final K key;
+ Collection<V> delegate;
+ final WrappedCollection ancestor;
+ final Collection<V> ancestorDelegate;
+
+ WrappedCollection(@Nullable K key, Collection<V> delegate,
+ @Nullable WrappedCollection ancestor) {
+ this.key = key;
+ this.delegate = delegate;
+ this.ancestor = ancestor;
+ this.ancestorDelegate
+ = (ancestor == null) ? null : ancestor.getDelegate();
+ }
+
+ /**
+ * If the delegate collection is empty, but the multimap has values for the
+ * key, replace the delegate with the new collection for the key.
+ *
+ * <p>For a subcollection, refresh its ancestor and validate that the
+ * ancestor delegate hasn't changed.
+ */
+ void refreshIfEmpty() {
+ if (ancestor != null) {
+ ancestor.refreshIfEmpty();
+ if (ancestor.getDelegate() != ancestorDelegate) {
+ throw new ConcurrentModificationException();
}
+ } else if (delegate.isEmpty()) {
+ Collection<V> newDelegate = map.get(key);
+ if (newDelegate != null) {
+ delegate = newDelegate;
+ }
+ }
+ }
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return entryIterator();
+ /**
+ * If collection is empty, remove it from {@code AbstractMultimap.this.map}.
+ * For subcollections, check whether the ancestor collection is empty.
+ */
+ void removeIfEmpty() {
+ if (ancestor != null) {
+ ancestor.removeIfEmpty();
+ } else if (delegate.isEmpty()) {
+ map.remove(key);
+ }
+ }
+
+ K getKey() {
+ return key;
+ }
+
+ /**
+ * Add the delegate to the map. Other {@code WrappedCollection} methods
+ * should call this method after adding elements to a previously empty
+ * collection.
+ *
+ * <p>Subcollection add the ancestor's delegate instead.
+ */
+ void addToMap() {
+ if (ancestor != null) {
+ ancestor.addToMap();
+ } else {
+ map.put(key, delegate);
+ }
+ }
+
+ @Override public int size() {
+ refreshIfEmpty();
+ return delegate.size();
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object == this) {
+ return true;
+ }
+ refreshIfEmpty();
+ return delegate.equals(object);
+ }
+
+ @Override public int hashCode() {
+ refreshIfEmpty();
+ return delegate.hashCode();
+ }
+
+ @Override public String toString() {
+ refreshIfEmpty();
+ return delegate.toString();
+ }
+
+ Collection<V> getDelegate() {
+ return delegate;
+ }
+
+ @Override public Iterator<V> iterator() {
+ refreshIfEmpty();
+ return new WrappedIterator();
+ }
+
+ /** Collection iterator for {@code WrappedCollection}. */
+ class WrappedIterator implements Iterator<V> {
+ final Iterator<V> delegateIterator;
+ final Collection<V> originalDelegate = delegate;
+
+ WrappedIterator() {
+ delegateIterator = iteratorOrListIterator(delegate);
+ }
+
+ WrappedIterator(Iterator<V> delegateIterator) {
+ this.delegateIterator = delegateIterator;
+ }
+
+ /**
+ * If the delegate changed since the iterator was created, the iterator is
+ * no longer valid.
+ */
+ void validateIterator() {
+ refreshIfEmpty();
+ if (delegate != originalDelegate) {
+ throw new ConcurrentModificationException();
}
- };
+ }
+
+ @Override
+ public boolean hasNext() {
+ validateIterator();
+ return delegateIterator.hasNext();
+ }
+
+ @Override
+ public V next() {
+ validateIterator();
+ return delegateIterator.next();
+ }
+
+ @Override
+ public void remove() {
+ delegateIterator.remove();
+ totalSize--;
+ removeIfEmpty();
+ }
+
+ Iterator<V> getDelegateIterator() {
+ validateIterator();
+ return delegateIterator;
+ }
}
- return new Multimaps.Entries<K, V>() {
+
+ @Override public boolean add(V value) {
+ refreshIfEmpty();
+ boolean wasEmpty = delegate.isEmpty();
+ boolean changed = delegate.add(value);
+ if (changed) {
+ totalSize++;
+ if (wasEmpty) {
+ addToMap();
+ }
+ }
+ return changed;
+ }
+
+ WrappedCollection getAncestor() {
+ return ancestor;
+ }
+
+ // The following methods are provided for better performance.
+
+ @Override public boolean addAll(Collection<? extends V> collection) {
+ if (collection.isEmpty()) {
+ return false;
+ }
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = delegate.addAll(collection);
+ if (changed) {
+ int newSize = delegate.size();
+ totalSize += (newSize - oldSize);
+ if (oldSize == 0) {
+ addToMap();
+ }
+ }
+ return changed;
+ }
+
+ @Override public boolean contains(Object o) {
+ refreshIfEmpty();
+ return delegate.contains(o);
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ refreshIfEmpty();
+ return delegate.containsAll(c);
+ }
+
+ @Override public void clear() {
+ int oldSize = size(); // calls refreshIfEmpty
+ if (oldSize == 0) {
+ return;
+ }
+ delegate.clear();
+ totalSize -= oldSize;
+ removeIfEmpty(); // maybe shouldn't be removed if this is a sublist
+ }
+
+ @Override public boolean remove(Object o) {
+ refreshIfEmpty();
+ boolean changed = delegate.remove(o);
+ if (changed) {
+ totalSize--;
+ removeIfEmpty();
+ }
+ return changed;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ if (c.isEmpty()) {
+ return false;
+ }
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = delegate.removeAll(c);
+ if (changed) {
+ int newSize = delegate.size();
+ totalSize += (newSize - oldSize);
+ removeIfEmpty();
+ }
+ return changed;
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ checkNotNull(c);
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = delegate.retainAll(c);
+ if (changed) {
+ int newSize = delegate.size();
+ totalSize += (newSize - oldSize);
+ removeIfEmpty();
+ }
+ return changed;
+ }
+ }
+
+ private Iterator<V> iteratorOrListIterator(Collection<V> collection) {
+ return (collection instanceof List)
+ ? ((List<V>) collection).listIterator()
+ : collection.iterator();
+ }
+
+ /** Set decorator that stays in sync with the multimap values for a key. */
+ private class WrappedSet extends WrappedCollection implements Set<V> {
+ WrappedSet(@Nullable K key, Set<V> delegate) {
+ super(key, delegate, null);
+ }
+ }
+
+ /**
+ * SortedSet decorator that stays in sync with the multimap values for a key.
+ */
+ private class WrappedSortedSet extends WrappedCollection
+ implements SortedSet<V> {
+ WrappedSortedSet(@Nullable K key, SortedSet<V> delegate,
+ @Nullable WrappedCollection ancestor) {
+ super(key, delegate, ancestor);
+ }
+
+ SortedSet<V> getSortedSetDelegate() {
+ return (SortedSet<V>) getDelegate();
+ }
+
+ @Override
+ public Comparator<? super V> comparator() {
+ return getSortedSetDelegate().comparator();
+ }
+
+ @Override
+ public V first() {
+ refreshIfEmpty();
+ return getSortedSetDelegate().first();
+ }
+
+ @Override
+ public V last() {
+ refreshIfEmpty();
+ return getSortedSetDelegate().last();
+ }
+
+ @Override
+ public SortedSet<V> headSet(V toElement) {
+ refreshIfEmpty();
+ return new WrappedSortedSet(
+ getKey(), getSortedSetDelegate().headSet(toElement),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+
+ @Override
+ public SortedSet<V> subSet(V fromElement, V toElement) {
+ refreshIfEmpty();
+ return new WrappedSortedSet(
+ getKey(), getSortedSetDelegate().subSet(fromElement, toElement),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+
+ @Override
+ public SortedSet<V> tailSet(V fromElement) {
+ refreshIfEmpty();
+ return new WrappedSortedSet(
+ getKey(), getSortedSetDelegate().tailSet(fromElement),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+ }
+
+ /** List decorator that stays in sync with the multimap values for a key. */
+ private class WrappedList extends WrappedCollection implements List<V> {
+ WrappedList(@Nullable K key, List<V> delegate,
+ @Nullable WrappedCollection ancestor) {
+ super(key, delegate, ancestor);
+ }
+
+ List<V> getListDelegate() {
+ return (List<V>) getDelegate();
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends V> c) {
+ if (c.isEmpty()) {
+ return false;
+ }
+ int oldSize = size(); // calls refreshIfEmpty
+ boolean changed = getListDelegate().addAll(index, c);
+ if (changed) {
+ int newSize = getDelegate().size();
+ totalSize += (newSize - oldSize);
+ if (oldSize == 0) {
+ addToMap();
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ public V get(int index) {
+ refreshIfEmpty();
+ return getListDelegate().get(index);
+ }
+
+ @Override
+ public V set(int index, V element) {
+ refreshIfEmpty();
+ return getListDelegate().set(index, element);
+ }
+
+ @Override
+ public void add(int index, V element) {
+ refreshIfEmpty();
+ boolean wasEmpty = getDelegate().isEmpty();
+ getListDelegate().add(index, element);
+ totalSize++;
+ if (wasEmpty) {
+ addToMap();
+ }
+ }
+
+ @Override
+ public V remove(int index) {
+ refreshIfEmpty();
+ V value = getListDelegate().remove(index);
+ totalSize--;
+ removeIfEmpty();
+ return value;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ refreshIfEmpty();
+ return getListDelegate().indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ refreshIfEmpty();
+ return getListDelegate().lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator<V> listIterator() {
+ refreshIfEmpty();
+ return new WrappedListIterator();
+ }
+
+ @Override
+ public ListIterator<V> listIterator(int index) {
+ refreshIfEmpty();
+ return new WrappedListIterator(index);
+ }
+
+ @Override
+ public List<V> subList(int fromIndex, int toIndex) {
+ refreshIfEmpty();
+ return wrapList(getKey(),
+ getListDelegate().subList(fromIndex, toIndex),
+ (getAncestor() == null) ? this : getAncestor());
+ }
+
+ /** ListIterator decorator. */
+ private class WrappedListIterator extends WrappedIterator
+ implements ListIterator<V> {
+ WrappedListIterator() {}
+
+ public WrappedListIterator(int index) {
+ super(getListDelegate().listIterator(index));
+ }
+
+ private ListIterator<V> getDelegateListIterator() {
+ return (ListIterator<V>) getDelegateIterator();
+ }
+
@Override
- Multimap<K, V> multimap() {
- return AbstractMultimap.this;
+ public boolean hasPrevious() {
+ return getDelegateListIterator().hasPrevious();
}
@Override
- public Iterator<Entry<K, V>> iterator() {
- return entryIterator();
+ public V previous() {
+ return getDelegateListIterator().previous();
}
- };
+
+ @Override
+ public int nextIndex() {
+ return getDelegateListIterator().nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return getDelegateListIterator().previousIndex();
+ }
+
+ @Override
+ public void set(V value) {
+ getDelegateListIterator().set(value);
+ }
+
+ @Override
+ public void add(V value) {
+ boolean wasEmpty = isEmpty();
+ getDelegateListIterator().add(value);
+ totalSize++;
+ if (wasEmpty) {
+ addToMap();
+ }
+ }
+ }
+ }
+
+ /**
+ * List decorator that stays in sync with the multimap values for a key and
+ * supports rapid random access.
+ */
+ private class RandomAccessWrappedList extends WrappedList
+ implements RandomAccess {
+ RandomAccessWrappedList(@Nullable K key, List<V> delegate,
+ @Nullable WrappedCollection ancestor) {
+ super(key, delegate, ancestor);
+ }
}
-
- abstract Iterator<Entry<K, V>> entryIterator();
private transient Set<K> keySet;
@@ -136,48 +867,484 @@ abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
return (result == null) ? keySet = createKeySet() : result;
}
- Set<K> createKeySet() {
- return new Maps.KeySet<K, Collection<V>>() {
- @Override
- Map<K, Collection<V>> map() {
- return asMap();
+ private Set<K> createKeySet() {
+ return (map instanceof SortedMap)
+ ? new SortedKeySet((SortedMap<K, Collection<V>>) map) : new KeySet(map);
+ }
+
+ private class KeySet extends Maps.KeySet<K, Collection<V>> {
+
+ /**
+ * This is usually the same as map, except when someone requests a
+ * subcollection of a {@link SortedKeySet}.
+ */
+ final Map<K, Collection<V>> subMap;
+
+ KeySet(final Map<K, Collection<V>> subMap) {
+ this.subMap = subMap;
+ }
+
+ @Override
+ Map<K, Collection<V>> map() {
+ return subMap;
+ }
+
+ @Override public Iterator<K> iterator() {
+ return new Iterator<K>() {
+ final Iterator<Map.Entry<K, Collection<V>>> entryIterator
+ = subMap.entrySet().iterator();
+ Map.Entry<K, Collection<V>> entry;
+
+ @Override
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ @Override
+ public K next() {
+ entry = entryIterator.next();
+ return entry.getKey();
+ }
+ @Override
+ public void remove() {
+ checkState(entry != null);
+ Collection<V> collection = entry.getValue();
+ entryIterator.remove();
+ totalSize -= collection.size();
+ collection.clear();
+ }
+ };
+ }
+
+ // The following methods are included for better performance.
+
+ @Override public boolean remove(Object key) {
+ int count = 0;
+ Collection<V> collection = subMap.remove(key);
+ if (collection != null) {
+ count = collection.size();
+ collection.clear();
+ totalSize -= count;
}
- };
+ return count > 0;
+ }
+
+ @Override
+ public void clear() {
+ Iterators.clear(iterator());
+ }
+
+ @Override public boolean containsAll(Collection<?> c) {
+ return subMap.keySet().containsAll(c);
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return this == object || this.subMap.keySet().equals(object);
+ }
+
+ @Override public int hashCode() {
+ return subMap.keySet().hashCode();
+ }
+ }
+
+ private class SortedKeySet extends KeySet implements SortedSet<K> {
+
+ SortedKeySet(SortedMap<K, Collection<V>> subMap) {
+ super(subMap);
+ }
+
+ SortedMap<K, Collection<V>> sortedMap() {
+ return (SortedMap<K, Collection<V>>) subMap;
+ }
+
+ @Override
+ public Comparator<? super K> comparator() {
+ return sortedMap().comparator();
+ }
+
+ @Override
+ public K first() {
+ return sortedMap().firstKey();
+ }
+
+ @Override
+ public SortedSet<K> headSet(K toElement) {
+ return new SortedKeySet(sortedMap().headMap(toElement));
+ }
+
+ @Override
+ public K last() {
+ return sortedMap().lastKey();
+ }
+
+ @Override
+ public SortedSet<K> subSet(K fromElement, K toElement) {
+ return new SortedKeySet(sortedMap().subMap(fromElement, toElement));
+ }
+
+ @Override
+ public SortedSet<K> tailSet(K fromElement) {
+ return new SortedKeySet(sortedMap().tailMap(fromElement));
+ }
}
-
- private transient Multiset<K> keys;
-
+
+ private transient Multiset<K> multiset;
+
@Override
public Multiset<K> keys() {
- Multiset<K> result = keys;
- return (result == null) ? keys = createKeys() : result;
+ Multiset<K> result = multiset;
+ if (result == null) {
+ return multiset = new Multimaps.Keys<K, V>() {
+ @Override Multimap<K, V> multimap() {
+ return AbstractMultimap.this;
+ }
+ };
+ }
+ return result;
}
-
- Multiset<K> createKeys() {
- return new Multimaps.Keys<K, V>(this);
+
+ /**
+ * Removes all values for the provided key. Unlike {@link #removeAll}, it
+ * returns the number of removed mappings.
+ */
+ private int removeValuesForKey(Object key) {
+ Collection<V> collection;
+ try {
+ collection = map.remove(key);
+ } catch (NullPointerException e) {
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ }
+
+ int count = 0;
+ if (collection != null) {
+ count = collection.size();
+ collection.clear();
+ totalSize -= count;
+ }
+ return count;
}
-
- private transient Collection<V> values;
-
+
+ private transient Collection<V> valuesCollection;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The iterator generated by the returned collection traverses the values
+ * for one key, followed by the values of a second key, and so on.
+ */
+ @Override public Collection<V> values() {
+ Collection<V> result = valuesCollection;
+ if (result == null) {
+ return valuesCollection = new Multimaps.Values<K, V>() {
+ @Override Multimap<K, V> multimap() {
+ return AbstractMultimap.this;
+ }
+ };
+ }
+ return result;
+ }
+
+ private transient Collection<Map.Entry<K, V>> entries;
+
+ /*
+ * TODO(kevinb): should we copy this javadoc to each concrete class, so that
+ * classes like LinkedHashMultimap that need to say something different are
+ * still able to {@inheritDoc} all the way from Multimap?
+ */
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The iterator generated by the returned collection traverses the values
+ * for one key, followed by the values of a second key, and so on.
+ *
+ * <p>Each entry is an immutable snapshot of a key-value mapping in the
+ * multimap, taken at the time the entry is returned by a method call to the
+ * collection or its iterator.
+ */
@Override
- public Collection<V> values() {
- Collection<V> result = values;
- return (result == null) ? values = createValues() : result;
+ public Collection<Map.Entry<K, V>> entries() {
+ Collection<Map.Entry<K, V>> result = entries;
+ return (result == null) ? entries = createEntries() : result;
}
-
- Collection<V> createValues() {
- return new Multimaps.Values<K, V>(this);
+
+ Collection<Map.Entry<K, V>> createEntries() {
+ if (this instanceof SetMultimap) {
+ return new Multimaps.EntrySet<K, V>() {
+ @Override Multimap<K, V> multimap() {
+ return AbstractMultimap.this;
+ }
+
+ @Override public Iterator<Entry<K, V>> iterator() {
+ return createEntryIterator();
+ }
+ };
+ }
+ return new Multimaps.Entries<K, V>() {
+ @Override Multimap<K, V> multimap() {
+ return AbstractMultimap.this;
+ }
+
+ @Override public Iterator<Entry<K, V>> iterator() {
+ return createEntryIterator();
+ }
+ };
}
-
+
+ /**
+ * Returns an iterator across all key-value map entries, used by {@code
+ * entries().iterator()} and {@code values().iterator()}. The default
+ * behavior, which traverses the values for one key, the values for a second
+ * key, and so on, suffices for most {@code AbstractMultimap} implementations.
+ *
+ * @return an iterator across map entries
+ */
+ Iterator<Map.Entry<K, V>> createEntryIterator() {
+ return new EntryIterator();
+ }
+
+ /** Iterator across all key-value pairs. */
+ private class EntryIterator implements Iterator<Map.Entry<K, V>> {
+ final Iterator<Map.Entry<K, Collection<V>>> keyIterator;
+ K key;
+ Collection<V> collection;
+ Iterator<V> valueIterator;
+
+ EntryIterator() {
+ keyIterator = map.entrySet().iterator();
+ if (keyIterator.hasNext()) {
+ findValueIteratorAndKey();
+ } else {
+ valueIterator = Iterators.emptyModifiableIterator();
+ }
+ }
+
+ void findValueIteratorAndKey() {
+ Map.Entry<K, Collection<V>> entry = keyIterator.next();
+ key = entry.getKey();
+ collection = entry.getValue();
+ valueIterator = collection.iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return keyIterator.hasNext() || valueIterator.hasNext();
+ }
+
+ @Override
+ public Map.Entry<K, V> next() {
+ if (!valueIterator.hasNext()) {
+ findValueIteratorAndKey();
+ }
+ return Maps.immutableEntry(key, valueIterator.next());
+ }
+
+ @Override
+ public void remove() {
+ valueIterator.remove();
+ if (collection.isEmpty()) {
+ keyIterator.remove();
+ }
+ totalSize--;
+ }
+ }
+
private transient Map<K, Collection<V>> asMap;
-
+
@Override
public Map<K, Collection<V>> asMap() {
Map<K, Collection<V>> result = asMap;
return (result == null) ? asMap = createAsMap() : result;
}
-
- abstract Map<K, Collection<V>> createAsMap();
+
+ private Map<K, Collection<V>> createAsMap() {
+ return (map instanceof SortedMap)
+ ? new SortedAsMap((SortedMap<K, Collection<V>>) map) : new AsMap(map);
+ }
+
+ private class AsMap extends AbstractMap<K, Collection<V>> {
+ /**
+ * Usually the same as map, but smaller for the headMap(), tailMap(), or
+ * subMap() of a SortedAsMap.
+ */
+ final transient Map<K, Collection<V>> submap;
+
+ AsMap(Map<K, Collection<V>> submap) {
+ this.submap = submap;
+ }
+
+ transient Set<Map.Entry<K, Collection<V>>> entrySet;
+
+ @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
+ Set<Map.Entry<K, Collection<V>>> result = entrySet;
+ return (result == null) ? entrySet = new AsMapEntries() : result;
+ }
+
+ // The following methods are included for performance.
+
+ @Override public boolean containsKey(Object key) {
+ return Maps.safeContainsKey(submap, key);
+ }
+
+ @Override public Collection<V> get(Object key) {
+ Collection<V> collection = Maps.safeGet(submap, key);
+ if (collection == null) {
+ return null;
+ }
+ @SuppressWarnings("unchecked")
+ K k = (K) key;
+ return wrapCollection(k, collection);
+ }
+
+ @Override public Set<K> keySet() {
+ return AbstractMultimap.this.keySet();
+ }
+
+ @Override
+ public int size() {
+ return submap.size();
+ }
+
+ @Override public Collection<V> remove(Object key) {
+ Collection<V> collection = submap.remove(key);
+ if (collection == null) {
+ return null;
+ }
+
+ Collection<V> output = createCollection();
+ output.addAll(collection);
+ totalSize -= collection.size();
+ collection.clear();
+ return output;
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return this == object || submap.equals(object);
+ }
+
+ @Override public int hashCode() {
+ return submap.hashCode();
+ }
+
+ @Override public String toString() {
+ return submap.toString();
+ }
+
+ @Override
+ public void clear() {
+ if (submap == map) {
+ AbstractMultimap.this.clear();
+ } else {
+
+ Iterators.clear(new AsMapIterator());
+ }
+ }
+
+ class AsMapEntries extends Maps.EntrySet<K, Collection<V>> {
+ @Override
+ Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
+ return new AsMapIterator();
+ }
+
+ // The following methods are included for performance.
+
+ @Override public boolean contains(Object o) {
+ return Collections2.safeContains(submap.entrySet(), o);
+ }
+
+ @Override public boolean remove(Object o) {
+ if (!contains(o)) {
+ return false;
+ }
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+ removeValuesForKey(entry.getKey());
+ return true;
+ }
+ }
+
+ /** Iterator across all keys and value collections. */
+ class AsMapIterator implements Iterator<Map.Entry<K, Collection<V>>> {
+ final Iterator<Map.Entry<K, Collection<V>>> delegateIterator
+ = submap.entrySet().iterator();
+ Collection<V> collection;
+
+ @Override
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+
+ @Override
+ public Map.Entry<K, Collection<V>> next() {
+ Map.Entry<K, Collection<V>> entry = delegateIterator.next();
+ K key = entry.getKey();
+ collection = entry.getValue();
+ return Maps.immutableEntry(key, wrapCollection(key, collection));
+ }
+
+ @Override
+ public void remove() {
+ delegateIterator.remove();
+ totalSize -= collection.size();
+ collection.clear();
+ }
+ }
+ }
+
+ private class SortedAsMap extends AsMap
+ implements SortedMap<K, Collection<V>> {
+ SortedAsMap(SortedMap<K, Collection<V>> submap) {
+ super(submap);
+ }
+
+ SortedMap<K, Collection<V>> sortedMap() {
+ return (SortedMap<K, Collection<V>>) submap;
+ }
+
+ @Override
+ public Comparator<? super K> comparator() {
+ return sortedMap().comparator();
+ }
+
+ @Override
+ public K firstKey() {
+ return sortedMap().firstKey();
+ }
+
+ @Override
+ public K lastKey() {
+ return sortedMap().lastKey();
+ }
+
+ @Override
+ public SortedMap<K, Collection<V>> headMap(K toKey) {
+ return new SortedAsMap(sortedMap().headMap(toKey));
+ }
+
+ @Override
+ public SortedMap<K, Collection<V>> subMap(K fromKey, K toKey) {
+ return new SortedAsMap(sortedMap().subMap(fromKey, toKey));
+ }
+
+ @Override
+ public SortedMap<K, Collection<V>> tailMap(K fromKey) {
+ return new SortedAsMap(sortedMap().tailMap(fromKey));
+ }
+
+ SortedSet<K> sortedKeySet;
+
+ // returns a SortedSet, even though returning a Set would be sufficient to
+ // satisfy the SortedMap.keySet() interface
+ @Override public SortedSet<K> keySet() {
+ SortedSet<K> result = sortedKeySet;
+ return (result == null)
+ ? sortedKeySet = new SortedKeySet(sortedMap()) : result;
+ }
+ }
// Comparison and hashing
@@ -187,7 +1354,7 @@ abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
}
if (object instanceof Multimap) {
Multimap<?, ?> that = (Multimap<?, ?>) object;
- return this.asMap().equals(that.asMap());
+ return this.map.equals(that.asMap());
}
return false;
}
@@ -201,7 +1368,7 @@ abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
* @see Map#hashCode
*/
@Override public int hashCode() {
- return asMap().hashCode();
+ return map.hashCode();
}
/**
@@ -212,6 +1379,9 @@ abstract class AbstractMultimap<K, V> implements Multimap<K, V> {
*/
@Override
public String toString() {
- return asMap().toString();
+ return map.toString();
}
+
+ private static final long serialVersionUID = 2447537837011683357L;
}
+
diff --git a/guava/src/com/google/common/collect/AbstractMultiset.java b/guava/src/com/google/common/collect/AbstractMultiset.java
index 20ea93f..c0d2c4a 100644
--- a/guava/src/com/google/common/collect/AbstractMultiset.java
+++ b/guava/src/com/google/common/collect/AbstractMultiset.java
@@ -65,7 +65,7 @@ abstract class AbstractMultiset<E> extends AbstractCollection<E>
}
@Override
- public int count(@Nullable Object element) {
+ public int count(Object element) {
for (Entry<E> entry : entrySet()) {
if (Objects.equal(entry.getElement(), element)) {
return entry.getCount();
@@ -82,26 +82,26 @@ abstract class AbstractMultiset<E> extends AbstractCollection<E>
}
@Override
- public int add(@Nullable E element, int occurrences) {
+ public int add(E element, int occurrences) {
throw new UnsupportedOperationException();
}
- @Override public boolean remove(@Nullable Object element) {
+ @Override public boolean remove(Object element) {
return remove(element, 1) > 0;
}
@Override
- public int remove(@Nullable Object element, int occurrences) {
+ public int remove(Object element, int occurrences) {
throw new UnsupportedOperationException();
}
@Override
- public int setCount(@Nullable E element, int count) {
+ public int setCount(E element, int count) {
return setCountImpl(this, element, count);
}
@Override
- public boolean setCount(@Nullable E element, int oldCount, int newCount) {
+ public boolean setCount(E element, int oldCount, int newCount) {
return setCountImpl(this, element, oldCount, newCount);
}
@@ -109,7 +109,7 @@ abstract class AbstractMultiset<E> extends AbstractCollection<E>
/**
* {@inheritDoc}
- *
+ *
* <p>This implementation is highly efficient when {@code elementsToAdd}
* is itself a {@link Multiset}.
*/
@@ -158,11 +158,11 @@ abstract class AbstractMultiset<E> extends AbstractCollection<E>
}
abstract Iterator<Entry<E>> entryIterator();
-
+
abstract int distinctElements();
private transient Set<Entry<E>> entrySet;
-
+
@Override public Set<Entry<E>> entrySet() {
Set<Entry<E>> result = entrySet;
return (result == null) ? entrySet = createEntrySet() : result;
diff --git a/guava/src/com/google/common/collect/AbstractNavigableMap.java b/guava/src/com/google/common/collect/AbstractNavigableMap.java
deleted file mode 100644
index f6defe6..0000000
--- a/guava/src/com/google/common/collect/AbstractNavigableMap.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.AbstractMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.SortedMap;
-
-import javax.annotation.Nullable;
-
-/**
- * Skeletal implementation of {@link NavigableMap}.
- *
- * @author Louis Wasserman
- */
-abstract class AbstractNavigableMap<K, V> extends AbstractMap<K, V> implements NavigableMap<K, V> {
-
- @Override
- @Nullable
- public abstract V get(@Nullable Object key);
-
- @Override
- @Nullable
- public Entry<K, V> firstEntry() {
- return Iterators.getNext(entryIterator(), null);
- }
-
- @Override
- @Nullable
- public Entry<K, V> lastEntry() {
- return Iterators.getNext(descendingEntryIterator(), null);
- }
-
- @Override
- @Nullable
- public Entry<K, V> pollFirstEntry() {
- return Iterators.pollNext(entryIterator());
- }
-
- @Override
- @Nullable
- public Entry<K, V> pollLastEntry() {
- return Iterators.pollNext(descendingEntryIterator());
- }
-
- @Override
- public K firstKey() {
- Entry<K, V> entry = firstEntry();
- if (entry == null) {
- throw new NoSuchElementException();
- } else {
- return entry.getKey();
- }
- }
-
- @Override
- public K lastKey() {
- Entry<K, V> entry = lastEntry();
- if (entry == null) {
- throw new NoSuchElementException();
- } else {
- return entry.getKey();
- }
- }
-
- @Override
- @Nullable
- public Entry<K, V> lowerEntry(K key) {
- return headMap(key, false).lastEntry();
- }
-
- @Override
- @Nullable
- public Entry<K, V> floorEntry(K key) {
- return headMap(key, true).lastEntry();
- }
-
- @Override
- @Nullable
- public Entry<K, V> ceilingEntry(K key) {
- return tailMap(key, true).firstEntry();
- }
-
- @Override
- @Nullable
- public Entry<K, V> higherEntry(K key) {
- return tailMap(key, false).firstEntry();
- }
-
- @Override
- public K lowerKey(K key) {
- return Maps.keyOrNull(lowerEntry(key));
- }
-
- @Override
- public K floorKey(K key) {
- return Maps.keyOrNull(floorEntry(key));
- }
-
- @Override
- public K ceilingKey(K key) {
- return Maps.keyOrNull(ceilingEntry(key));
- }
-
- @Override
- public K higherKey(K key) {
- return Maps.keyOrNull(higherEntry(key));
- }
-
- abstract Iterator<Entry<K, V>> entryIterator();
-
- abstract Iterator<Entry<K, V>> descendingEntryIterator();
-
- @Override
- public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override
- public SortedMap<K, V> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override
- public SortedMap<K, V> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return new Maps.NavigableKeySet<K, V>(this);
- }
-
- @Override
- public Set<K> keySet() {
- return navigableKeySet();
- }
-
- @Override
- public abstract int size();
-
- @Override
- public Set<Entry<K, V>> entrySet() {
- return new Maps.EntrySet<K, V>() {
- @Override
- Map<K, V> map() {
- return AbstractNavigableMap.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return entryIterator();
- }
- };
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return descendingMap().navigableKeySet();
- }
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- return new DescendingMap();
- }
-
- private final class DescendingMap extends Maps.DescendingMap<K, V> {
- @Override
- NavigableMap<K, V> forward() {
- return AbstractNavigableMap.this;
- }
-
- @Override
- Iterator<Entry<K, V>> entryIterator() {
- return descendingEntryIterator();
- }
- }
-
-}
diff --git a/guava/src/com/google/common/collect/AbstractRangeSet.java b/guava/src/com/google/common/collect/AbstractRangeSet.java
deleted file mode 100644
index e02f5da..0000000
--- a/guava/src/com/google/common/collect/AbstractRangeSet.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import javax.annotation.Nullable;
-
-/**
- * A skeletal implementation of {@code RangeSet}.
- *
- * @author Louis Wasserman
- */
-abstract class AbstractRangeSet<C extends Comparable> implements RangeSet<C> {
- AbstractRangeSet() {}
-
- @Override
- public boolean contains(C value) {
- return rangeContaining(value) != null;
- }
-
- @Override
- public Range<C> rangeContaining(C value) {
- checkNotNull(value);
- for (Range<C> range : asRanges()) {
- if (range.contains(value)) {
- return range;
- }
- }
- return null;
- }
-
- @Override
- public boolean isEmpty() {
- return asRanges().isEmpty();
- }
-
- @Override
- public void add(Range<C> range) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(Range<C> range) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- remove(Range.<C>all());
- }
-
- @Override
- public boolean enclosesAll(RangeSet<C> other) {
- for (Range<C> range : other.asRanges()) {
- if (!encloses(range)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public void addAll(RangeSet<C> other) {
- for (Range<C> range : other.asRanges()) {
- add(range);
- }
- }
-
- @Override
- public void removeAll(RangeSet<C> other) {
- for (Range<C> range : other.asRanges()) {
- remove(range);
- }
- }
-
- @Override
- public boolean encloses(Range<C> otherRange) {
- for (Range<C> range : asRanges()) {
- if (range.encloses(otherRange)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof RangeSet) {
- RangeSet<?> other = (RangeSet<?>) obj;
- return this.asRanges().equals(other.asRanges());
- }
- return false;
- }
-
- @Override
- public final int hashCode() {
- return asRanges().hashCode();
- }
-
- @Override
- public final String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append('{');
- for (Range<C> range : asRanges()) {
- builder.append(range);
- }
- builder.append('}');
- return builder.toString();
- }
-}
diff --git a/guava/src/com/google/common/collect/AbstractSetMultimap.java b/guava/src/com/google/common/collect/AbstractSetMultimap.java
index e43d8b1..fe68470 100644
--- a/guava/src/com/google/common/collect/AbstractSetMultimap.java
+++ b/guava/src/com/google/common/collect/AbstractSetMultimap.java
@@ -26,14 +26,14 @@ import javax.annotation.Nullable;
/**
* Basic implementation of the {@link SetMultimap} interface. It's a wrapper
- * around {@link AbstractMapBasedMultimap} that converts the returned collections into
+ * around {@link AbstractMultimap} that converts the returned collections into
* {@code Sets}. The {@link #createCollection} method must return a {@code Set}.
*
* @author Jared Levy
*/
@GwtCompatible
abstract class AbstractSetMultimap<K, V>
- extends AbstractMapBasedMultimap<K, V> implements SetMultimap<K, V> {
+ extends AbstractMultimap<K, V> implements SetMultimap<K, V> {
/**
* Creates a new multimap that uses the provided map.
*
@@ -46,10 +46,6 @@ abstract class AbstractSetMultimap<K, V>
@Override abstract Set<V> createCollection();
- @Override Set<V> createUnmodifiableEmptyCollection() {
- return ImmutableSet.of();
- }
-
// Following Javadoc copied from SetMultimap.
/**
@@ -117,7 +113,7 @@ abstract class AbstractSetMultimap<K, V>
* @return {@code true} if the method increased the size of the multimap, or
* {@code false} if the multimap already contained the key-value pair
*/
- @Override public boolean put(@Nullable K key, @Nullable V value) {
+ @Override public boolean put(K key, V value) {
return super.put(key, value);
}
diff --git a/guava/src/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java b/guava/src/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java
deleted file mode 100644
index c561b87..0000000
--- a/guava/src/com/google/common/collect/AbstractSortedKeySortedSetMultimap.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Collection;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
-/**
- * Basic implementation of a {@link SortedSetMultimap} with a sorted key set.
- *
- * This superclass allows {@code TreeMultimap} to override methods to return
- * navigable set and map types in non-GWT only, while GWT code will inherit the
- * SortedMap/SortedSet overrides.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-abstract class AbstractSortedKeySortedSetMultimap<K, V> extends AbstractSortedSetMultimap<K, V> {
-
- AbstractSortedKeySortedSetMultimap(SortedMap<K, Collection<V>> map) {
- super(map);
- }
-
- @Override
- public SortedMap<K, Collection<V>> asMap() {
- return (SortedMap<K, Collection<V>>) super.asMap();
- }
-
- @Override
- SortedMap<K, Collection<V>> backingMap() {
- return (SortedMap<K, Collection<V>>) super.backingMap();
- }
-
- @Override
- public SortedSet<K> keySet() {
- return (SortedSet<K>) super.keySet();
- }
-
-}
diff --git a/guava/src/com/google/common/collect/AbstractSortedMultiset.java b/guava/src/com/google/common/collect/AbstractSortedMultiset.java
index 7c277f8..b1a1d54 100644
--- a/guava/src/com/google/common/collect/AbstractSortedMultiset.java
+++ b/guava/src/com/google/common/collect/AbstractSortedMultiset.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -20,9 +20,7 @@ import com.google.common.annotations.GwtCompatible;
import java.util.Comparator;
import java.util.Iterator;
-import java.util.NavigableSet;
-
-import javax.annotation.Nullable;
+import java.util.SortedSet;
/**
* This class provides a skeletal implementation of the {@link SortedMultiset} interface.
@@ -33,28 +31,33 @@ import javax.annotation.Nullable;
*
* @author Louis Wasserman
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
abstract class AbstractSortedMultiset<E> extends AbstractMultiset<E> implements SortedMultiset<E> {
- @GwtTransient final Comparator<? super E> comparator;
+ final Comparator<? super E> comparator;
// needed for serialization
@SuppressWarnings("unchecked")
AbstractSortedMultiset() {
this((Comparator) Ordering.natural());
}
-
+
AbstractSortedMultiset(Comparator<? super E> comparator) {
this.comparator = checkNotNull(comparator);
}
@Override
- public NavigableSet<E> elementSet() {
- return (NavigableSet<E>) super.elementSet();
+ public SortedSet<E> elementSet() {
+ return (SortedSet<E>) super.elementSet();
}
@Override
- NavigableSet<E> createElementSet() {
- return new SortedMultisets.NavigableElementSet<E>(this);
+ SortedSet<E> createElementSet() {
+ return new SortedMultisets.ElementSet<E>() {
+ @Override
+ SortedMultiset<E> multiset() {
+ return AbstractSortedMultiset.this;
+ }
+ };
}
@Override
@@ -99,11 +102,8 @@ abstract class AbstractSortedMultiset<E> extends AbstractMultiset<E> implements
}
@Override
- public SortedMultiset<E> subMultiset(@Nullable E fromElement, BoundType fromBoundType,
- @Nullable E toElement, BoundType toBoundType) {
- // These are checked elsewhere, but NullPointerTester wants them checked eagerly.
- checkNotNull(fromBoundType);
- checkNotNull(toBoundType);
+ public SortedMultiset<E> subMultiset(E fromElement, BoundType fromBoundType, E toElement,
+ BoundType toBoundType) {
return tailMultiset(fromElement, fromBoundType).headMultiset(toElement, toBoundType);
}
@@ -122,7 +122,7 @@ abstract class AbstractSortedMultiset<E> extends AbstractMultiset<E> implements
}
SortedMultiset<E> createDescendingMultiset() {
- return new DescendingMultiset<E>() {
+ return new SortedMultisets.DescendingMultiset<E>() {
@Override
SortedMultiset<E> forwardMultiset() {
return AbstractSortedMultiset.this;
diff --git a/guava/src/com/google/common/collect/AbstractSortedSetMultimap.java b/guava/src/com/google/common/collect/AbstractSortedSetMultimap.java
index ac74155..2be5f4b 100644
--- a/guava/src/com/google/common/collect/AbstractSortedSetMultimap.java
+++ b/guava/src/com/google/common/collect/AbstractSortedSetMultimap.java
@@ -19,8 +19,6 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;
@@ -28,7 +26,7 @@ import javax.annotation.Nullable;
/**
* Basic implementation of the {@link SortedSetMultimap} interface. It's a
- * wrapper around {@link AbstractMapBasedMultimap} that converts the returned
+ * wrapper around {@link AbstractMultimap} that converts the returned
* collections into sorted sets. The {@link #createCollection} method
* must return a {@code SortedSet}.
*
@@ -47,18 +45,7 @@ abstract class AbstractSortedSetMultimap<K, V>
super(map);
}
- @Override
- abstract SortedSet<V> createCollection();
-
- @Override
- SortedSet<V> createUnmodifiableEmptyCollection() {
- Comparator<? super V> comparator = valueComparator();
- if (comparator == null) {
- return Collections.unmodifiableSortedSet(createCollection());
- } else {
- return ImmutableSortedSet.emptySet(valueComparator());
- }
- }
+ @Override abstract SortedSet<V> createCollection();
// Following Javadoc copied from Multimap and SortedSetMultimap.
@@ -101,7 +88,7 @@ abstract class AbstractSortedSetMultimap<K, V>
* <p>Any duplicates in {@code values} will be stored in the multimap once.
*/
@Override public SortedSet<V> replaceValues(
- @Nullable K key, Iterable<? extends V> values) {
+ K key, Iterable<? extends V> values) {
return (SortedSet<V>) super.replaceValues(key, values);
}
diff --git a/guava/src/com/google/common/collect/AllEqualOrdering.java b/guava/src/com/google/common/collect/AllEqualOrdering.java
deleted file mode 100644
index c30164b..0000000
--- a/guava/src/com/google/common/collect/AllEqualOrdering.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.io.Serializable;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-/**
- * An ordering that treats all references as equals, even nulls.
- *
- * @author Emily Soldal
- */
-@GwtCompatible(serializable = true)
-final class AllEqualOrdering extends Ordering<Object> implements Serializable {
- static final AllEqualOrdering INSTANCE = new AllEqualOrdering();
-
- @Override
- public int compare(@Nullable Object left, @Nullable Object right) {
- return 0;
- }
-
- @Override
- public <E> List<E> sortedCopy(Iterable<E> iterable) {
- return Lists.newArrayList(iterable);
- }
-
- @Override
- public <E> ImmutableList<E> immutableSortedCopy(Iterable<E> iterable) {
- return ImmutableList.copyOf(iterable);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <S> Ordering<S> reverse() {
- return (Ordering<S>) this;
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
-
- @Override
- public String toString() {
- return "Ordering.allEqual()";
- }
-
- private static final long serialVersionUID = 0;
-}
diff --git a/guava/src/com/google/common/collect/ArrayListMultimap.java b/guava/src/com/google/common/collect/ArrayListMultimap.java
index 759c073..43d42c3 100644
--- a/guava/src/com/google/common/collect/ArrayListMultimap.java
+++ b/guava/src/com/google/common/collect/ArrayListMultimap.java
@@ -55,10 +55,6 @@ import java.util.Map;
* multimap. Concurrent read operations will work correctly. To allow concurrent
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedListMultimap}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
*
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -66,7 +62,7 @@ import java.util.Map;
@GwtCompatible(serializable = true, emulated = true)
public final class ArrayListMultimap<K, V> extends AbstractListMultimap<K, V> {
// Default from ArrayList
- private static final int DEFAULT_VALUES_PER_KEY = 3;
+ private static final int DEFAULT_VALUES_PER_KEY = 10;
@VisibleForTesting transient int expectedValuesPerKey;
diff --git a/guava/src/com/google/common/collect/ArrayTable.java b/guava/src/com/google/common/collect/ArrayTable.java
index 554265c..28eb5b8 100644
--- a/guava/src/com/google/common/collect/ArrayTable.java
+++ b/guava/src/com/google/common/collect/ArrayTable.java
@@ -17,23 +17,21 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.AbstractCollection;
+import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Nullable;
@@ -76,15 +74,10 @@ import javax.annotation.Nullable;
* implementations, synchronization is unnecessary between a thread that writes
* to one cell and a thread that reads from another.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table">
- * {@code Table}</a>.
- *
* @author Jared Levy
* @since 10.0
*/
@Beta
-@GwtCompatible(emulated = true)
public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
/**
@@ -162,23 +155,22 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
* columnKeys is empty but rowKeys isn't, the table is empty but
* containsRow() can return true and rowKeySet() isn't empty.
*/
- rowKeyToIndex = index(rowList);
- columnKeyToIndex = index(columnList);
+ ImmutableMap.Builder<R, Integer> rowBuilder = ImmutableMap.builder();
+ for (int i = 0; i < rowList.size(); i++) {
+ rowBuilder.put(rowList.get(i), i);
+ }
+ rowKeyToIndex = rowBuilder.build();
+
+ ImmutableMap.Builder<C, Integer> columnBuilder = ImmutableMap.builder();
+ for (int i = 0; i < columnList.size(); i++) {
+ columnBuilder.put(columnList.get(i), i);
+ }
+ columnKeyToIndex = columnBuilder.build();
@SuppressWarnings("unchecked")
V[][] tmpArray
= (V[][]) new Object[rowList.size()][columnList.size()];
array = tmpArray;
- // Necessary because in GWT the arrays are initialized with "undefined" instead of null.
- eraseAll();
- }
-
- private static <E> ImmutableMap<E, Integer> index(List<E> list) {
- ImmutableMap.Builder<E, Integer> columnBuilder = ImmutableMap.builder();
- for (int i = 0; i < list.size(); i++) {
- columnBuilder.put(list.get(i), i);
- }
- return columnBuilder.build();
}
private ArrayTable(Table<R, C, V> table) {
@@ -194,116 +186,11 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
@SuppressWarnings("unchecked")
V[][] copy = (V[][]) new Object[rowList.size()][columnList.size()];
array = copy;
- // Necessary because in GWT the arrays are initialized with "undefined" instead of null.
- eraseAll();
for (int i = 0; i < rowList.size(); i++) {
System.arraycopy(table.array[i], 0, copy[i], 0, table.array[i].length);
}
}
- private abstract static class ArrayMap<K, V> extends Maps.ImprovedAbstractMap<K, V> {
- private final ImmutableMap<K, Integer> keyIndex;
-
- private ArrayMap(ImmutableMap<K, Integer> keyIndex) {
- this.keyIndex = keyIndex;
- }
-
- @Override
- public Set<K> keySet() {
- return keyIndex.keySet();
- }
-
- K getKey(int index) {
- return keyIndex.keySet().asList().get(index);
- }
-
- abstract String getKeyRole();
-
- @Nullable abstract V getValue(int index);
-
- @Nullable abstract V setValue(int index, V newValue);
-
- @Override
- public int size() {
- return keyIndex.size();
- }
-
- @Override
- public boolean isEmpty() {
- return keyIndex.isEmpty();
- }
-
- @Override
- protected Set<Entry<K, V>> createEntrySet() {
- return new Maps.EntrySet<K, V>() {
- @Override
- Map<K, V> map() {
- return ArrayMap.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return new AbstractIndexedListIterator<Entry<K, V>>(size()) {
- @Override
- protected Entry<K, V> get(final int index) {
- return new AbstractMapEntry<K, V>() {
- @Override
- public K getKey() {
- return ArrayMap.this.getKey(index);
- }
-
- @Override
- public V getValue() {
- return ArrayMap.this.getValue(index);
- }
-
- @Override
- public V setValue(V value) {
- return ArrayMap.this.setValue(index, value);
- }
- };
- }
- };
- }
- };
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return keyIndex.containsKey(key);
- }
-
- @Override
- public V get(@Nullable Object key) {
- Integer index = keyIndex.get(key);
- if (index == null) {
- return null;
- } else {
- return getValue(index);
- }
- }
-
- @Override
- public V put(K key, V value) {
- Integer index = keyIndex.get(key);
- if (index == null) {
- throw new IllegalArgumentException(
- getKeyRole() + " " + key + " not in " + keyIndex.keySet());
- }
- return setValue(index, value);
- }
-
- @Override
- public V remove(Object key) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException();
- }
- }
-
/**
* Returns, as an immutable list, the row keys provided when the table was
* constructed, including those that are mapped to null values only.
@@ -335,9 +222,6 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
* allowed column keys
*/
public V at(int rowIndex, int columnIndex) {
- // In GWT array access never throws IndexOutOfBoundsException.
- checkElementIndex(rowIndex, rowList.size());
- checkElementIndex(columnIndex, columnList.size());
return array[rowIndex][columnIndex];
}
@@ -357,9 +241,6 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
* allowed column keys
*/
public V set(int rowIndex, int columnIndex, @Nullable V value) {
- // In GWT array access never throws IndexOutOfBoundsException.
- checkElementIndex(rowIndex, rowList.size());
- checkElementIndex(columnIndex, columnList.size());
V oldValue = array[rowIndex][columnIndex];
array[rowIndex][columnIndex] = value;
return oldValue;
@@ -375,7 +256,6 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
*
* @param valueClass class of values stored in the returned array
*/
- @GwtIncompatible("reflection")
public V[][] toArray(Class<V> valueClass) {
// Can change to use varargs in JDK 1.6 if we want
@SuppressWarnings("unchecked") // TODO: safe?
@@ -451,8 +331,12 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
Integer rowIndex = rowKeyToIndex.get(rowKey);
Integer columnIndex = columnKeyToIndex.get(columnKey);
+ return getIndexed(rowIndex, columnIndex);
+ }
+
+ private V getIndexed(Integer rowIndex, Integer columnIndex) {
return (rowIndex == null || columnIndex == null)
- ? null : at(rowIndex, columnIndex);
+ ? null : array[rowIndex][columnIndex];
}
/**
@@ -602,7 +486,7 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
}
@Override
public V getValue() {
- return at(rowIndex, columnIndex);
+ return array[rowIndex][columnIndex];
}
};
}
@@ -620,7 +504,7 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
Integer columnIndex = columnKeyToIndex.get(cell.getColumnKey());
return rowIndex != null
&& columnIndex != null
- && Objects.equal(at(rowIndex, columnIndex), cell.getValue());
+ && Objects.equal(array[rowIndex][columnIndex], cell.getValue());
}
return false;
}
@@ -646,27 +530,68 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
? ImmutableMap.<R, V>of() : new Column(columnIndex);
}
- private class Column extends ArrayMap<R, V> {
+ private class Column extends AbstractMap<R, V> {
final int columnIndex;
Column(int columnIndex) {
- super(rowKeyToIndex);
this.columnIndex = columnIndex;
}
- @Override
- String getKeyRole() {
- return "Row";
+ ColumnEntrySet entrySet;
+
+ @Override public Set<Entry<R, V>> entrySet() {
+ ColumnEntrySet set = entrySet;
+ return (set == null) ? entrySet = new ColumnEntrySet(columnIndex) : set;
+ }
+
+ @Override public V get(Object rowKey) {
+ Integer rowIndex = rowKeyToIndex.get(rowKey);
+ return getIndexed(rowIndex, columnIndex);
+ }
+
+ @Override public boolean containsKey(Object rowKey) {
+ return rowKeyToIndex.containsKey(rowKey);
+ }
+
+ @Override public V put(R rowKey, V value) {
+ checkNotNull(rowKey);
+ Integer rowIndex = rowKeyToIndex.get(rowKey);
+ checkArgument(rowIndex != null, "Row %s not in %s", rowKey, rowList);
+ return set(rowIndex, columnIndex, value);
+ }
+
+ @Override public Set<R> keySet() {
+ return rowKeySet();
+ }
+ }
+
+ private class ColumnEntrySet extends AbstractSet<Entry<R, V>> {
+ final int columnIndex;
+
+ ColumnEntrySet(int columnIndex) {
+ this.columnIndex = columnIndex;
}
- @Override
- V getValue(int index) {
- return at(index, columnIndex);
+ @Override public Iterator<Entry<R, V>> iterator() {
+ return new AbstractIndexedListIterator<Entry<R, V>>(size()) {
+ @Override protected Entry<R, V> get(final int rowIndex) {
+ return new AbstractMapEntry<R, V>() {
+ @Override public R getKey() {
+ return rowList.get(rowIndex);
+ }
+ @Override public V getValue() {
+ return array[rowIndex][columnIndex];
+ }
+ @Override public V setValue(V value) {
+ return ArrayTable.this.set(rowIndex, columnIndex, value);
+ }
+ };
+ }
+ };
}
- @Override
- V setValue(int index, V newValue) {
- return set(index, columnIndex, newValue);
+ @Override public int size() {
+ return rowList.size();
}
}
@@ -689,32 +614,47 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
return (map == null) ? columnMap = new ColumnMap() : map;
}
- private class ColumnMap extends ArrayMap<C, Map<R, V>> {
- private ColumnMap() {
- super(columnKeyToIndex);
+ private class ColumnMap extends AbstractMap<C, Map<R, V>> {
+ transient ColumnMapEntrySet entrySet;
+
+ @Override public Set<Entry<C, Map<R, V>>> entrySet() {
+ ColumnMapEntrySet set = entrySet;
+ return (set == null) ? entrySet = new ColumnMapEntrySet() : set;
}
- @Override
- String getKeyRole() {
- return "Column";
+ @Override public Map<R, V> get(Object columnKey) {
+ Integer columnIndex = columnKeyToIndex.get(columnKey);
+ return (columnIndex == null) ? null : new Column(columnIndex);
}
- @Override
- Map<R, V> getValue(int index) {
- return new Column(index);
+ @Override public boolean containsKey(Object columnKey) {
+ return containsColumn(columnKey);
}
- @Override
- Map<R, V> setValue(int index, Map<R, V> newValue) {
- throw new UnsupportedOperationException();
+ @Override public Set<C> keySet() {
+ return columnKeySet();
}
- @Override
- public Map<R, V> put(C key, Map<R, V> value) {
+ @Override public Map<R, V> remove(Object columnKey) {
throw new UnsupportedOperationException();
}
}
+ private class ColumnMapEntrySet extends AbstractSet<Entry<C, Map<R, V>>> {
+ @Override public Iterator<Entry<C, Map<R, V>>> iterator() {
+ return new AbstractIndexedListIterator<Entry<C, Map<R, V>>>(size()) {
+ @Override protected Entry<C, Map<R, V>> get(int index) {
+ return Maps.<C, Map<R, V>>immutableEntry(columnList.get(index),
+ new Column(index));
+ }
+ };
+ }
+
+ @Override public int size() {
+ return columnList.size();
+ }
+ }
+
/**
* Returns a view of all mappings that have the given row key. If the
* row key isn't in {@link #rowKeySet()}, an empty immutable map is
@@ -735,27 +675,69 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
return (rowIndex == null) ? ImmutableMap.<C, V>of() : new Row(rowIndex);
}
- private class Row extends ArrayMap<C, V> {
+ private class Row extends AbstractMap<C, V> {
final int rowIndex;
Row(int rowIndex) {
- super(columnKeyToIndex);
this.rowIndex = rowIndex;
}
- @Override
- String getKeyRole() {
- return "Column";
+ RowEntrySet entrySet;
+
+ @Override public Set<Entry<C, V>> entrySet() {
+ RowEntrySet set = entrySet;
+ return (set == null) ? entrySet = new RowEntrySet(rowIndex) : set;
+ }
+
+ @Override public V get(Object columnKey) {
+ Integer columnIndex = columnKeyToIndex.get(columnKey);
+ return getIndexed(rowIndex, columnIndex);
+ }
+
+ @Override public boolean containsKey(Object columnKey) {
+ return containsColumn(columnKey);
+ }
+
+ @Override public V put(C columnKey, V value) {
+ checkNotNull(columnKey);
+ Integer columnIndex = columnKeyToIndex.get(columnKey);
+ checkArgument(columnIndex != null,
+ "Column %s not in %s", columnKey, columnList);
+ return set(rowIndex, columnIndex, value);
}
- @Override
- V getValue(int index) {
- return at(rowIndex, index);
+ @Override public Set<C> keySet() {
+ return columnKeySet();
}
+ }
+
+ private class RowEntrySet extends AbstractSet<Entry<C, V>> {
+ final int rowIndex;
- @Override
- V setValue(int index, V newValue) {
- return set(rowIndex, index, newValue);
+ RowEntrySet(int rowIndex) {
+ this.rowIndex = rowIndex;
+ }
+
+ @Override public Iterator<Entry<C, V>> iterator() {
+ return new AbstractIndexedListIterator<Entry<C, V>>(size()) {
+ @Override protected Entry<C, V> get(final int columnIndex) {
+ return new AbstractMapEntry<C, V>() {
+ @Override public C getKey() {
+ return columnList.get(columnIndex);
+ }
+ @Override public V getValue() {
+ return array[rowIndex][columnIndex];
+ }
+ @Override public V setValue(V value) {
+ return ArrayTable.this.set(rowIndex, columnIndex, value);
+ }
+ };
+ }
+ };
+ }
+
+ @Override public int size() {
+ return columnList.size();
}
}
@@ -778,32 +760,47 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
return (map == null) ? rowMap = new RowMap() : map;
}
- private class RowMap extends ArrayMap<R, Map<C, V>> {
- private RowMap() {
- super(rowKeyToIndex);
+ private class RowMap extends AbstractMap<R, Map<C, V>> {
+ transient RowMapEntrySet entrySet;
+
+ @Override public Set<Entry<R, Map<C, V>>> entrySet() {
+ RowMapEntrySet set = entrySet;
+ return (set == null) ? entrySet = new RowMapEntrySet() : set;
}
- @Override
- String getKeyRole() {
- return "Row";
+ @Override public Map<C, V> get(Object rowKey) {
+ Integer rowIndex = rowKeyToIndex.get(rowKey);
+ return (rowIndex == null) ? null : new Row(rowIndex);
}
- @Override
- Map<C, V> getValue(int index) {
- return new Row(index);
+ @Override public boolean containsKey(Object rowKey) {
+ return containsRow(rowKey);
}
- @Override
- Map<C, V> setValue(int index, Map<C, V> newValue) {
- throw new UnsupportedOperationException();
+ @Override public Set<R> keySet() {
+ return rowKeySet();
}
- @Override
- public Map<C, V> put(R key, Map<C, V> value) {
+ @Override public Map<C, V> remove(Object rowKey) {
throw new UnsupportedOperationException();
}
}
+ private class RowMapEntrySet extends AbstractSet<Entry<R, Map<C, V>>> {
+ @Override public Iterator<Entry<R, Map<C, V>>> iterator() {
+ return new AbstractIndexedListIterator<Entry<R, Map<C, V>>>(size()) {
+ @Override protected Entry<R, Map<C, V>> get(int index) {
+ return Maps.<R, Map<C, V>>immutableEntry(rowList.get(index),
+ new Row(index));
+ }
+ };
+ }
+
+ @Override public int size() {
+ return rowList.size();
+ }
+ }
+
private transient Collection<V> values;
/**
@@ -823,10 +820,11 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
private class Values extends AbstractCollection<V> {
@Override public Iterator<V> iterator() {
- return new TransformedIterator<Cell<R, C, V>, V>(cellSet().iterator()) {
- @Override
- V transform(Cell<R, C, V> cell) {
- return cell.getValue();
+ return new AbstractIndexedListIterator<V>(size()) {
+ @Override protected V get(int index) {
+ int rowIndex = index / columnList.size();
+ int columnIndex = index % columnList.size();
+ return array[rowIndex][columnIndex];
}
};
}
@@ -834,6 +832,10 @@ public final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable {
@Override public int size() {
return ArrayTable.this.size();
}
+
+ @Override public boolean contains(Object value) {
+ return containsValue(value);
+ }
}
private static final long serialVersionUID = 0;
diff --git a/guava-gwt/src/com/google/common/collect/ForwardingImmutableList_CustomFieldSerializer.java b/guava/src/com/google/common/collect/AsynchronousComputationException.java
index b6767a2..e64e17b 100644
--- a/guava-gwt/src/com/google/common/collect/ForwardingImmutableList_CustomFieldSerializer.java
+++ b/guava/src/com/google/common/collect/AsynchronousComputationException.java
@@ -17,9 +17,21 @@
package com.google.common.collect;
/**
- * Even though {@link ForwardingImmutableList} cannot be instantiated, we still
- * need a custom field serializer. TODO(cpovirk): why?
+ * Wraps an exception that occurred during a computation in a different thread.
*
- * @author Hayward Chan
+ * @author Bob Lee
+ * @since 2.0 (imported from Google Collections Library)
+ * @deprecated this class is unused by com.google.common.collect. <b>This class
+ * is scheduled for deletion in November 2012.</b>
*/
-public final class ForwardingImmutableList_CustomFieldSerializer {}
+@Deprecated
+public
+class AsynchronousComputationException extends ComputationException {
+ /**
+ * Creates a new instance with the given cause.
+ */
+ public AsynchronousComputationException(Throwable cause) {
+ super(cause);
+ }
+ private static final long serialVersionUID = 0;
+}
diff --git a/guava/src/com/google/common/collect/BiMap.java b/guava/src/com/google/common/collect/BiMap.java
index a6203e0..34d6677 100644
--- a/guava/src/com/google/common/collect/BiMap.java
+++ b/guava/src/com/google/common/collect/BiMap.java
@@ -28,10 +28,6 @@ import javax.annotation.Nullable;
* its values as well as that of its keys. This constraint enables bimaps to
* support an "inverse view", which is another bimap containing the same entries
* as this bimap but with reversed keys and values.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap">
- * {@code BiMap}</a>.
*
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
diff --git a/guava/src/com/google/common/collect/BoundType.java b/guava/src/com/google/common/collect/BoundType.java
index 7b8f34b..3632b32 100644
--- a/guava/src/com/google/common/collect/BoundType.java
+++ b/guava/src/com/google/common/collect/BoundType.java
@@ -14,6 +14,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
/**
@@ -23,26 +24,18 @@ import com.google.common.annotations.GwtCompatible;
*
* @since 10.0
*/
+@Beta
@GwtCompatible
public enum BoundType {
/**
* The endpoint value <i>is not</i> considered part of the set ("exclusive").
*/
- OPEN {
- @Override
- BoundType flip() {
- return CLOSED;
- }
- },
+ OPEN,
+
/**
* The endpoint value <i>is</i> considered part of the set ("inclusive").
*/
- CLOSED {
- @Override
- BoundType flip() {
- return OPEN;
- }
- };
+ CLOSED;
/**
* Returns the bound type corresponding to a boolean value for inclusivity.
@@ -50,6 +43,4 @@ public enum BoundType {
static BoundType forBoolean(boolean inclusive) {
return inclusive ? CLOSED : OPEN;
}
-
- abstract BoundType flip();
}
diff --git a/guava/src/com/google/common/collect/BstAggregate.java b/guava/src/com/google/common/collect/BstAggregate.java
new file mode 100644
index 0000000..84d150f
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstAggregate.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * An integer-valued function on binary search tree nodes that adds between nodes.
+ *
+ * <p>The value of individual entries must fit into an {@code int}, but the value of an entire
+ * tree can require a {@code long}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+interface BstAggregate<N extends BstNode<?, N>> {
+ /**
+ * The total value on an entire subtree. Must be equal to the sum of the {@link #entryValue
+ * entryValue} of this node and all its descendants.
+ */
+ long treeValue(@Nullable N tree);
+
+ /**
+ * The value on a single entry, ignoring its descendants.
+ */
+ int entryValue(N entry);
+}
diff --git a/guava/src/com/google/common/collect/BstBalancePolicy.java b/guava/src/com/google/common/collect/BstBalancePolicy.java
new file mode 100644
index 0000000..d1e93d0
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstBalancePolicy.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * A local balancing policy for modified nodes in binary search trees.
+ *
+ * @author Louis Wasserman
+ * @param <N> The type of the nodes in the trees that this {@code BstRebalancePolicy} can
+ * rebalance.
+ */
+@GwtCompatible
+interface BstBalancePolicy<N extends BstNode<?, N>> {
+ /**
+ * Constructs a locally balanced tree around the key and value data in {@code source}, and the
+ * subtrees {@code left} and {@code right}. It is guaranteed that the resulting tree will have
+ * the same inorder traversal order as the subtree {@code left}, then the entry {@code source},
+ * then the subtree {@code right}.
+ */
+ N balance(BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right);
+
+ /**
+ * Constructs a locally balanced tree around the subtrees {@code left} and {@code right}. It is
+ * guaranteed that the resulting tree will have the same inorder traversal order as the subtree
+ * {@code left}, then the subtree {@code right}.
+ */
+ @Nullable
+ N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right);
+}
diff --git a/guava/src/com/google/common/collect/BstCountBasedBalancePolicies.java b/guava/src/com/google/common/collect/BstCountBasedBalancePolicies.java
new file mode 100644
index 0000000..5b98b91
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstCountBasedBalancePolicies.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.BstOperations.extractMax;
+import static com.google.common.collect.BstOperations.extractMin;
+import static com.google.common.collect.BstOperations.insertMax;
+import static com.google.common.collect.BstOperations.insertMin;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * A tree-size-based set of balancing policies, based on <a
+ * href="http://www.swiss.ai.mit.edu/~adams/BB/"> Stephen Adams, "Efficient sets: a balancing
+ * act."</a>.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+final class BstCountBasedBalancePolicies {
+ private BstCountBasedBalancePolicies() {}
+
+ private static final int SINGLE_ROTATE_RATIO = 4;
+ private static final int SECOND_ROTATE_RATIO = 2;
+
+ /**
+ * Returns a balance policy that does no balancing or the bare minimum (for {@code combine}).
+ */
+ public static <N extends BstNode<?, N>> BstBalancePolicy<N> noRebalancePolicy(
+ final BstAggregate<N> countAggregate) {
+ checkNotNull(countAggregate);
+ return new BstBalancePolicy<N>() {
+ @Override
+ public N balance(
+ BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right) {
+ return checkNotNull(nodeFactory).createNode(source, left, right);
+ }
+
+ @Nullable
+ @Override
+ public N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right) {
+ if (left == null) {
+ return right;
+ } else if (right == null) {
+ return left;
+ } else if (countAggregate.treeValue(left) > countAggregate.treeValue(right)) {
+ return nodeFactory.createNode(
+ left, left.childOrNull(LEFT), combine(nodeFactory, left.childOrNull(RIGHT), right));
+ } else {
+ return nodeFactory.createNode(right, combine(nodeFactory, left, right.childOrNull(LEFT)),
+ right.childOrNull(RIGHT));
+ }
+ }
+ };
+ }
+
+ /**
+ * Returns a balance policy that expects the sizes of each side to be at most one node (added or
+ * removed) away from being balanced. {@code balance} takes {@code O(1)} time, and {@code
+ * combine} takes {@code O(log n)} time.
+ */
+ public static <K, N extends BstNode<K, N>> BstBalancePolicy<N> singleRebalancePolicy(
+ final BstAggregate<N> countAggregate) {
+ checkNotNull(countAggregate);
+ return new BstBalancePolicy<N>() {
+ @Override
+ public N balance(
+ BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right) {
+ long countL = countAggregate.treeValue(left);
+ long countR = countAggregate.treeValue(right);
+ if (countL + countR > 1) {
+ if (countR >= SINGLE_ROTATE_RATIO * countL) {
+ return rotateL(nodeFactory, source, left, right);
+ } else if (countL >= SINGLE_ROTATE_RATIO * countR) {
+ return rotateR(nodeFactory, source, left, right);
+ }
+ }
+ return nodeFactory.createNode(source, left, right);
+ }
+
+ private N rotateL(BstNodeFactory<N> nodeFactory, N source, @Nullable N left, N right) {
+ checkNotNull(right);
+ N rl = right.childOrNull(LEFT);
+ N rr = right.childOrNull(RIGHT);
+ if (countAggregate.treeValue(rl) >= SECOND_ROTATE_RATIO * countAggregate.treeValue(rr)) {
+ right = singleR(nodeFactory, right, rl, rr);
+ }
+ return singleL(nodeFactory, source, left, right);
+ }
+
+ private N rotateR(BstNodeFactory<N> nodeFactory, N source, N left, @Nullable N right) {
+ checkNotNull(left);
+ N lr = left.childOrNull(RIGHT);
+ N ll = left.childOrNull(LEFT);
+ if (countAggregate.treeValue(lr) >= SECOND_ROTATE_RATIO * countAggregate.treeValue(ll)) {
+ left = singleL(nodeFactory, left, ll, lr);
+ }
+ return singleR(nodeFactory, source, left, right);
+ }
+
+ private N singleL(BstNodeFactory<N> nodeFactory, N source, @Nullable N left, N right) {
+ checkNotNull(right);
+ return nodeFactory.createNode(right,
+ nodeFactory.createNode(source, left, right.childOrNull(LEFT)),
+ right.childOrNull(RIGHT));
+ }
+
+ private N singleR(BstNodeFactory<N> nodeFactory, N source, N left, @Nullable N right) {
+ checkNotNull(left);
+ return nodeFactory.createNode(left, left.childOrNull(LEFT),
+ nodeFactory.createNode(source, left.childOrNull(RIGHT), right));
+ }
+
+ @Nullable
+ @Override
+ public N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right) {
+ if (left == null) {
+ return right;
+ } else if (right == null) {
+ return left;
+ }
+ N newRootSource;
+ if (countAggregate.treeValue(left) > countAggregate.treeValue(right)) {
+ BstMutationResult<K, N> extractLeftMax = extractMax(left, nodeFactory, this);
+ newRootSource = extractLeftMax.getOriginalTarget();
+ left = extractLeftMax.getChangedRoot();
+ } else {
+ BstMutationResult<K, N> extractRightMin = extractMin(right, nodeFactory, this);
+ newRootSource = extractRightMin.getOriginalTarget();
+ right = extractRightMin.getChangedRoot();
+ }
+ return nodeFactory.createNode(newRootSource, left, right);
+ }
+ };
+ }
+
+ /**
+ * Returns a balance policy that makes no assumptions on the relative balance of the two sides
+ * and performs a full rebalancing as necessary. Both {@code balance} and {@code combine} take
+ * {@code O(log n)} time.
+ */
+ public static <K, N extends BstNode<K, N>> BstBalancePolicy<N> fullRebalancePolicy(
+ final BstAggregate<N> countAggregate) {
+ checkNotNull(countAggregate);
+ final BstBalancePolicy<N> singleBalancePolicy =
+ BstCountBasedBalancePolicies.<K, N>singleRebalancePolicy(countAggregate);
+ return new BstBalancePolicy<N>() {
+ @Override
+ public N balance(
+ BstNodeFactory<N> nodeFactory, N source, @Nullable N left, @Nullable N right) {
+ if (left == null) {
+ return insertMin(right, source, nodeFactory, singleBalancePolicy);
+ } else if (right == null) {
+ return insertMax(left, source, nodeFactory, singleBalancePolicy);
+ }
+ long countL = countAggregate.treeValue(left);
+ long countR = countAggregate.treeValue(right);
+ if (SINGLE_ROTATE_RATIO * countL <= countR) {
+ N resultLeft = balance(nodeFactory, source, left, right.childOrNull(LEFT));
+ return singleBalancePolicy.balance(
+ nodeFactory, right, resultLeft, right.childOrNull(RIGHT));
+ } else if (SINGLE_ROTATE_RATIO * countR <= countL) {
+ N resultRight = balance(nodeFactory, source, left.childOrNull(RIGHT), right);
+ return singleBalancePolicy.balance(
+ nodeFactory, left, left.childOrNull(LEFT), resultRight);
+ } else {
+ return nodeFactory.createNode(source, left, right);
+ }
+ }
+
+ @Nullable
+ @Override
+ public N combine(BstNodeFactory<N> nodeFactory, @Nullable N left, @Nullable N right) {
+ if (left == null) {
+ return right;
+ } else if (right == null) {
+ return left;
+ }
+ long countL = countAggregate.treeValue(left);
+ long countR = countAggregate.treeValue(right);
+ if (SINGLE_ROTATE_RATIO * countL <= countR) {
+ N resultLeft = combine(nodeFactory, left, right.childOrNull(LEFT));
+ return singleBalancePolicy.balance(
+ nodeFactory, right, resultLeft, right.childOrNull(RIGHT));
+ } else if (SINGLE_ROTATE_RATIO * countR <= countL) {
+ N resultRight = combine(nodeFactory, left.childOrNull(RIGHT), right);
+ return singleBalancePolicy.balance(
+ nodeFactory, left, left.childOrNull(LEFT), resultRight);
+ } else {
+ return singleBalancePolicy.combine(nodeFactory, left, right);
+ }
+ }
+ };
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstInOrderPath.java b/guava/src/com/google/common/collect/BstInOrderPath.java
new file mode 100644
index 0000000..de14c39
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstInOrderPath.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Optional;
+
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nullable;
+
+/**
+ * A {@code BstPath} supporting inorder traversal operations.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+final class BstInOrderPath<N extends BstNode<?, N>> extends BstPath<N, BstInOrderPath<N>> {
+ /**
+ * The factory to use to construct {@code BstInOrderPath} values.
+ */
+ public static <N extends BstNode<?, N>> BstPathFactory<N, BstInOrderPath<N>> inOrderFactory() {
+ return new BstPathFactory<N, BstInOrderPath<N>>() {
+ @Override
+ public BstInOrderPath<N> extension(BstInOrderPath<N> path, BstSide side) {
+ return BstInOrderPath.extension(path, side);
+ }
+
+ @Override
+ public BstInOrderPath<N> initialPath(N root) {
+ return new BstInOrderPath<N>(root, null, null);
+ }
+ };
+ }
+
+ private static <N extends BstNode<?, N>> BstInOrderPath<N> extension(
+ BstInOrderPath<N> path, BstSide side) {
+ checkNotNull(path);
+ N tip = path.getTip();
+ return new BstInOrderPath<N>(tip.getChild(side), side, path);
+ }
+
+ private final BstSide sideExtension;
+ private transient Optional<BstInOrderPath<N>> prevInOrder;
+ private transient Optional<BstInOrderPath<N>> nextInOrder;
+
+ private BstInOrderPath(
+ N tip, @Nullable BstSide sideExtension, @Nullable BstInOrderPath<N> tail) {
+ super(tip, tail);
+ this.sideExtension = sideExtension;
+ assert (sideExtension == null) == (tail == null);
+ }
+
+ private Optional<BstInOrderPath<N>> computeNextInOrder(BstSide side) {
+ if (getTip().hasChild(side)) {
+ BstInOrderPath<N> path = extension(this, side);
+ BstSide otherSide = side.other();
+ while (path.getTip().hasChild(otherSide)) {
+ path = extension(path, otherSide);
+ }
+ return Optional.of(path);
+ } else {
+ BstInOrderPath<N> current = this;
+ while (current.sideExtension == side) {
+ current = current.getPrefix();
+ }
+ current = current.prefixOrNull();
+ return Optional.fromNullable(current);
+ }
+ }
+
+ private Optional<BstInOrderPath<N>> nextInOrder(BstSide side) {
+ Optional<BstInOrderPath<N>> result;
+ switch (side) {
+ case LEFT:
+ result = prevInOrder;
+ return (result == null) ? prevInOrder = computeNextInOrder(side) : result;
+ case RIGHT:
+ result = nextInOrder;
+ return (result == null) ? nextInOrder = computeNextInOrder(side) : result;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Returns {@code true} if there is a next path in an in-order traversal in the given direction.
+ */
+ public boolean hasNext(BstSide side) {
+ return nextInOrder(side).isPresent();
+ }
+
+ /**
+ * Returns the next path in an in-order traversal in the given direction.
+ *
+ * @throws NoSuchElementException if this would be the last path in an in-order traversal
+ */
+ public BstInOrderPath<N> next(BstSide side) {
+ if (!hasNext(side)) {
+ throw new NoSuchElementException();
+ }
+ return nextInOrder(side).get();
+ }
+
+ /**
+ * Returns the direction this path went in relative to its tail path, or {@code null} if this
+ * path has no tail.
+ */
+ public BstSide getSideOfExtension() {
+ return sideExtension;
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstModificationResult.java b/guava/src/com/google/common/collect/BstModificationResult.java
new file mode 100644
index 0000000..2c7c036
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstModificationResult.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * The result of a {@code BstModifier}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+final class BstModificationResult<N extends BstNode<?, N>> {
+ enum ModificationType {
+ IDENTITY, REBUILDING_CHANGE, REBALANCING_CHANGE;
+ }
+
+ static <N extends BstNode<?, N>> BstModificationResult<N> identity(@Nullable N target) {
+ return new BstModificationResult<N>(target, target, ModificationType.IDENTITY);
+ }
+
+ static <N extends BstNode<?, N>> BstModificationResult<N> rebuildingChange(
+ @Nullable N originalTarget, @Nullable N changedTarget) {
+ return new BstModificationResult<N>(
+ originalTarget, changedTarget, ModificationType.REBUILDING_CHANGE);
+ }
+
+ static <N extends BstNode<?, N>> BstModificationResult<N> rebalancingChange(
+ @Nullable N originalTarget, @Nullable N changedTarget) {
+ return new BstModificationResult<N>(
+ originalTarget, changedTarget, ModificationType.REBALANCING_CHANGE);
+ }
+
+ @Nullable private final N originalTarget;
+ @Nullable private final N changedTarget;
+ private final ModificationType type;
+
+ private BstModificationResult(
+ @Nullable N originalTarget, @Nullable N changedTarget, ModificationType type) {
+ this.originalTarget = originalTarget;
+ this.changedTarget = changedTarget;
+ this.type = checkNotNull(type);
+ }
+
+ @Nullable
+ N getOriginalTarget() {
+ return originalTarget;
+ }
+
+ @Nullable
+ N getChangedTarget() {
+ return changedTarget;
+ }
+
+ ModificationType getType() {
+ return type;
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstModifier.java b/guava/src/com/google/common/collect/BstModifier.java
new file mode 100644
index 0000000..d972800
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstModifier.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * A specification for a local change to an entry in a binary search tree.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+interface BstModifier<K, N extends BstNode<K, N>> {
+
+ /**
+ * Given a target key and the original entry (if any) with the specified key, returns the entry
+ * with key {@code key} after this mutation has been performed. The result must either be {@code
+ * null} or must have a key that compares as equal to {@code key}. A deletion operation, for
+ * example, would always return {@code null}, or an insertion operation would always return a
+ * non-null {@code insertedEntry}.
+ *
+ * <p>If this method returns a non-null entry of type {@code N}, any children it has will be
+ * ignored.
+ *
+ * <p>This method may return {@code originalEntry} itself to indicate that no change is made.
+ *
+ * @param key The key being targeted for modification.
+ * @param originalEntry The original entry in the binary search tree with the specified key, if
+ * any. No guarantees are made about the children of this entry when treated as a node; in
+ * particular, they are not necessarily the children of the corresponding node in the
+ * binary search tree.
+ * @return the entry (if any) with the specified key after this modification is performed
+ */
+ BstModificationResult<N> modify(K key, @Nullable N originalEntry);
+}
diff --git a/guava/src/com/google/common/collect/BstMutationResult.java b/guava/src/com/google/common/collect/BstMutationResult.java
new file mode 100644
index 0000000..68309a8
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstMutationResult.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.BstModificationResult.ModificationType.IDENTITY;
+import static com.google.common.collect.BstModificationResult.ModificationType.REBUILDING_CHANGE;
+import static com.google.common.collect.BstModificationResult.ModificationType.REBALANCING_CHANGE;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.BstModificationResult.ModificationType;
+
+import javax.annotation.Nullable;
+
+/**
+ * The result of a mutation operation performed at a single location in a binary search tree.
+ *
+ * @author Louis Wasserman
+ * @param <K> The key type of the nodes in the modified binary search tree.
+ * @param <N> The type of the nodes in the modified binary search tree.
+ */
+@GwtCompatible
+final class BstMutationResult<K, N extends BstNode<K, N>> {
+ /**
+ * Creates a {@code BstMutationResult}.
+ *
+ * @param targetKey The key targeted for modification. If {@code originalTarget} or {@code
+ * changedTarget} are non-null, their keys must compare as equal to {@code targetKey}.
+ * @param originalRoot The root of the subtree that was modified.
+ * @param changedRoot The root of the subtree, after the modification and any rebalancing.
+ * @param modificationResult The result of the local modification to an entry.
+ */
+ public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> mutationResult(
+ @Nullable K targetKey, @Nullable N originalRoot, @Nullable N changedRoot,
+ BstModificationResult<N> modificationResult) {
+ return new BstMutationResult<K, N>(targetKey, originalRoot, changedRoot, modificationResult);
+ }
+
+ private final K targetKey;
+
+ @Nullable
+ private N originalRoot;
+
+ @Nullable
+ private N changedRoot;
+
+ private final BstModificationResult<N> modificationResult;
+
+ private BstMutationResult(@Nullable K targetKey, @Nullable N originalRoot,
+ @Nullable N changedRoot, BstModificationResult<N> modificationResult) {
+ this.targetKey = targetKey;
+ this.originalRoot = originalRoot;
+ this.changedRoot = changedRoot;
+ this.modificationResult = checkNotNull(modificationResult);
+ }
+
+ /**
+ * Returns the key which was the target of this modification.
+ */
+ public K getTargetKey() {
+ return targetKey;
+ }
+
+ /**
+ * Returns the root of the subtree that was modified.
+ */
+ @Nullable
+ public N getOriginalRoot() {
+ return originalRoot;
+ }
+
+ /**
+ * Returns the root of the subtree, after the modification and any rebalancing was performed.
+ */
+ @Nullable
+ public N getChangedRoot() {
+ return changedRoot;
+ }
+
+ /**
+ * Returns the entry in the original subtree with key {@code targetKey}, if any. This should not
+ * be treated as a subtree, but only as an entry, and no guarantees are made about its children
+ * when viewed as a subtree.
+ */
+ @Nullable
+ public N getOriginalTarget() {
+ return modificationResult.getOriginalTarget();
+ }
+
+ /**
+ * Returns the result of the modification to {@link #getOriginalTarget()}. This should not be
+ * treated as a subtree, but only as an entry, and no guarantees are made about its children when
+ * viewed as a subtree.
+ */
+ @Nullable
+ public N getChangedTarget() {
+ return modificationResult.getChangedTarget();
+ }
+
+ ModificationType modificationType() {
+ return modificationResult.getType();
+ }
+
+ /**
+ * If this mutation was to an immediate child subtree of the specified root on the specified
+ * side, returns the {@code BstMutationResult} of applying the mutation to the appropriate child
+ * of the specified root and rebalancing using the specified mutation rule.
+ */
+ public BstMutationResult<K, N> lift(N liftOriginalRoot, BstSide side,
+ BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) {
+ assert liftOriginalRoot != null & side != null & nodeFactory != null & balancePolicy != null;
+ switch (modificationType()) {
+ case IDENTITY:
+ this.originalRoot = this.changedRoot = liftOriginalRoot;
+ return this;
+ case REBUILDING_CHANGE:
+ case REBALANCING_CHANGE:
+ this.originalRoot = liftOriginalRoot;
+ N resultLeft = liftOriginalRoot.childOrNull(LEFT);
+ N resultRight = liftOriginalRoot.childOrNull(RIGHT);
+ switch (side) {
+ case LEFT:
+ resultLeft = changedRoot;
+ break;
+ case RIGHT:
+ resultRight = changedRoot;
+ break;
+ default:
+ throw new AssertionError();
+ }
+ if (modificationType() == REBUILDING_CHANGE) {
+ this.changedRoot = nodeFactory.createNode(liftOriginalRoot, resultLeft, resultRight);
+ } else {
+ this.changedRoot =
+ balancePolicy.balance(nodeFactory, liftOriginalRoot, resultLeft, resultRight);
+ }
+ return this;
+ default:
+ throw new AssertionError();
+ }
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstMutationRule.java b/guava/src/com/google/common/collect/BstMutationRule.java
new file mode 100644
index 0000000..7f90f8c
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstMutationRule.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * A rule for a local mutation to a binary search tree, that changes at most one entry. In addition
+ * to specifying how it modifies a particular entry via a {@code BstModifier}, it specifies a
+ * {@link BstBalancePolicy} for rebalancing the tree after the modification is performed and a
+ * {@link BstNodeFactory} for constructing newly rebalanced nodes.
+ *
+ * @author Louis Wasserman
+ * @param <K> The key type of the nodes in binary search trees that this rule can modify.
+ * @param <N> The type of the nodes in binary search trees that this rule can modify.
+ */
+@GwtCompatible
+final class BstMutationRule<K, N extends BstNode<K, N>> {
+ /**
+ * Constructs a {@code BstMutationRule} with the specified modifier, balance policy, and node
+ * factory.
+ */
+ public static <K, N extends BstNode<K, N>> BstMutationRule<K, N> createRule(
+ BstModifier<K, N> modifier, BstBalancePolicy<N> balancePolicy,
+ BstNodeFactory<N> nodeFactory) {
+ return new BstMutationRule<K, N>(modifier, balancePolicy, nodeFactory);
+ }
+
+ private final BstModifier<K, N> modifier;
+ private final BstBalancePolicy<N> balancePolicy;
+ private final BstNodeFactory<N> nodeFactory;
+
+ private BstMutationRule(BstModifier<K, N> modifier, BstBalancePolicy<N> balancePolicy,
+ BstNodeFactory<N> nodeFactory) {
+ this.balancePolicy = checkNotNull(balancePolicy);
+ this.nodeFactory = checkNotNull(nodeFactory);
+ this.modifier = checkNotNull(modifier);
+ }
+
+ /**
+ * Returns the {@link BstModifier} that specifies the change to a targeted entry in a binary
+ * search tree.
+ */
+ public BstModifier<K, N> getModifier() {
+ return modifier;
+ }
+
+ /**
+ * Returns the policy used to rebalance nodes in the tree after this modification has been
+ * performed.
+ */
+ public BstBalancePolicy<N> getBalancePolicy() {
+ return balancePolicy;
+ }
+
+ /**
+ * Returns the node factory used to create new nodes in the tree after this modification has been
+ * performed.
+ */
+ public BstNodeFactory<N> getNodeFactory() {
+ return nodeFactory;
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstNode.java b/guava/src/com/google/common/collect/BstNode.java
new file mode 100644
index 0000000..818f85a
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstNode.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Comparator;
+
+import javax.annotation.Nullable;
+
+/**
+ * A reusable abstraction for a node in a binary search tree. Null keys are allowed.
+ *
+ * <p>The node is considered to be immutable. Any subclass with mutable fields must create a new
+ * {@code BstNode} object upon any mutation, as the {@code Bst} classes assume that two nodes
+ * {@code a} and {@code b} represent exactly the same tree if and only if {@code a == b}.
+ *
+ * <p>A {@code BstNode} can be considered to be an <i>entry</i>, containing a key and possibly some
+ * value data, or it can be considered to be a <i>subtree</i>, representative of it and all its
+ * descendants.
+ *
+ * @author Louis Wasserman
+ * @param <K> The key type associated with this tree.
+ * @param <N> The type of the nodes in this tree.
+ */
+@GwtCompatible
+class BstNode<K, N extends BstNode<K, N>> {
+ /**
+ * The key on which this binary search tree is ordered. All descendants of the left subtree of
+ * this node must have keys strictly less than {@code this.key}.
+ */
+ private final K key;
+
+ /**
+ * The left child of this node. A null value indicates that this node has no left child.
+ */
+ @Nullable
+ private final N left;
+
+ /**
+ * The right child of this node. A null value indicates that this node has no right child.
+ */
+ @Nullable
+ private final N right;
+
+ BstNode(@Nullable K key, @Nullable N left, @Nullable N right) {
+ this.key = key;
+ this.left = left;
+ this.right = right;
+ }
+
+ /**
+ * Returns the ordered key associated with this node.
+ */
+ @Nullable
+ public final K getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the child on the specified side, or {@code null} if there is no such child.
+ */
+ @Nullable
+ public final N childOrNull(BstSide side) {
+ switch (side) {
+ case LEFT:
+ return left;
+ case RIGHT:
+ return right;
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Returns {@code true} if this node has a child on the specified side.
+ */
+ public final boolean hasChild(BstSide side) {
+ return childOrNull(side) != null;
+ }
+
+ /**
+ * Returns this node's child on the specified side.
+ *
+ * @throws IllegalStateException if this node has no such child
+ */
+ public final N getChild(BstSide side) {
+ N child = childOrNull(side);
+ checkState(child != null);
+ return child;
+ }
+
+ /**
+ * Returns {@code true} if the traditional binary search tree ordering invariant holds with
+ * respect to the specified {@code comparator}.
+ */
+ protected final boolean orderingInvariantHolds(Comparator<? super K> comparator) {
+ checkNotNull(comparator);
+ boolean result = true;
+ if (hasChild(LEFT)) {
+ result &= comparator.compare(getChild(LEFT).getKey(), key) < 0;
+ }
+ if (hasChild(RIGHT)) {
+ result &= comparator.compare(getChild(RIGHT).getKey(), key) > 0;
+ }
+ return result;
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstNodeFactory.java b/guava/src/com/google/common/collect/BstNodeFactory.java
new file mode 100644
index 0000000..8e1476c
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstNodeFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * A factory for copying nodes in binary search trees with different children.
+ *
+ * <p>Typically, nodes will carry more information than the fields in the {@link BstNode} class,
+ * often some kind of value or some aggregate data for the subtree. This factory is responsible for
+ * copying this additional data between nodes.
+ *
+ * @author Louis Wasserman
+ * @param <N> The type of the tree nodes constructed with this {@code BstNodeFactory}.
+ */
+@GwtCompatible
+abstract class BstNodeFactory<N extends BstNode<?, N>> {
+ /**
+ * Returns a new {@code N} with the key and value data from {@code source}, with left child
+ * {@code left}, and right child {@code right}. If {@code left} or {@code right} is null, the
+ * returned node will not have a child on the corresponding side.
+ */
+ public abstract N createNode(N source, @Nullable N left, @Nullable N right);
+
+ /**
+ * Returns a new {@code N} with the key and value data from {@code source} that is a leaf.
+ */
+ public final N createLeaf(N source) {
+ return createNode(source, null, null);
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstOperations.java b/guava/src/com/google/common/collect/BstOperations.java
new file mode 100644
index 0000000..1f933d4
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstOperations.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Comparator;
+
+import javax.annotation.Nullable;
+
+/**
+ * Tools to perform single-key queries and mutations in binary search trees.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+final class BstOperations {
+ private BstOperations() {}
+
+ /**
+ * Returns the node with key {@code key} in {@code tree}, if any.
+ */
+ @Nullable
+ public static <K, N extends BstNode<K, N>> N seek(
+ Comparator<? super K> comparator, @Nullable N tree, @Nullable K key) {
+ checkNotNull(comparator);
+ if (tree == null) {
+ return null;
+ }
+ int cmp = comparator.compare(key, tree.getKey());
+ if (cmp == 0) {
+ return tree;
+ } else {
+ BstSide side = (cmp < 0) ? LEFT : RIGHT;
+ return seek(comparator, tree.childOrNull(side), key);
+ }
+ }
+
+ /**
+ * Returns the result of performing the mutation specified by {@code mutationRule} in {@code
+ * tree} at the location with key {@code key}.
+ *
+ * <ul>
+ * <li>If the returned {@link BstModificationResult} has type {@code IDENTITY}, the exact
+ * original tree is returned.
+ * <li>If the returned {@code BstModificationResult} has type {@code REBUILDING_CHANGE},
+ * the tree will be rebuilt with the node factory of the mutation rule, but not rebalanced.
+ * <li>If the returned {@code BstModificationResult} has type {@code REBALANCING_CHANGE},
+ * the tree will be rebalanced using the balance policy of the mutation rule.
+ * </ul>
+ */
+ public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> mutate(
+ Comparator<? super K> comparator, BstMutationRule<K, N> mutationRule, @Nullable N tree,
+ @Nullable K key) {
+ checkNotNull(comparator);
+ checkNotNull(mutationRule);
+
+ if (tree != null) {
+ int cmp = comparator.compare(key, tree.getKey());
+ if (cmp != 0) {
+ BstSide side = (cmp < 0) ? LEFT : RIGHT;
+ BstMutationResult<K, N> mutation =
+ mutate(comparator, mutationRule, tree.childOrNull(side), key);
+ return mutation.lift(
+ tree, side, mutationRule.getNodeFactory(), mutationRule.getBalancePolicy());
+ }
+ }
+ return modify(tree, key, mutationRule);
+ }
+
+ /**
+ * Perform the local mutation at the tip of the specified path.
+ */
+ public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> mutate(
+ BstInOrderPath<N> path, BstMutationRule<K, N> mutationRule) {
+ checkNotNull(path);
+ checkNotNull(mutationRule);
+ BstBalancePolicy<N> balancePolicy = mutationRule.getBalancePolicy();
+ BstNodeFactory<N> nodeFactory = mutationRule.getNodeFactory();
+ BstModifier<K, N> modifier = mutationRule.getModifier();
+
+ N target = path.getTip();
+ K key = target.getKey();
+ BstMutationResult<K, N> result = modify(target, key, mutationRule);
+ while (path.hasPrefix()) {
+ BstInOrderPath<N> prefix = path.getPrefix();
+ result = result.lift(prefix.getTip(), path.getSideOfExtension(), nodeFactory, balancePolicy);
+ path = prefix;
+ }
+ return result;
+ }
+
+ /**
+ * Perform the local mutation right here, at the specified node.
+ */
+ private static <K, N extends BstNode<K, N>> BstMutationResult<K, N> modify(
+ @Nullable N tree, K key, BstMutationRule<K, N> mutationRule) {
+ BstBalancePolicy<N> rebalancePolicy = mutationRule.getBalancePolicy();
+ BstNodeFactory<N> nodeFactory = mutationRule.getNodeFactory();
+ BstModifier<K, N> modifier = mutationRule.getModifier();
+
+ N originalRoot = tree;
+ N changedRoot;
+ N originalTarget = (tree == null) ? null : nodeFactory.createLeaf(tree);
+ BstModificationResult<N> modResult = modifier.modify(key, originalTarget);
+ N originalLeft = null;
+ N originalRight = null;
+ if (tree != null) {
+ originalLeft = tree.childOrNull(LEFT);
+ originalRight = tree.childOrNull(RIGHT);
+ }
+ switch (modResult.getType()) {
+ case IDENTITY:
+ changedRoot = tree;
+ break;
+ case REBUILDING_CHANGE:
+ if (modResult.getChangedTarget() != null) {
+ changedRoot =
+ nodeFactory.createNode(modResult.getChangedTarget(), originalLeft, originalRight);
+ } else if (tree == null) {
+ changedRoot = null;
+ } else {
+ throw new AssertionError(
+ "Modification result is a REBUILDING_CHANGE, but rebalancing required");
+ }
+ break;
+ case REBALANCING_CHANGE:
+ if (modResult.getChangedTarget() != null) {
+ changedRoot = rebalancePolicy.balance(
+ nodeFactory, modResult.getChangedTarget(), originalLeft, originalRight);
+ } else if (tree != null) {
+ changedRoot = rebalancePolicy.combine(nodeFactory, originalLeft, originalRight);
+ } else {
+ changedRoot = null;
+ }
+ break;
+ default:
+ throw new AssertionError();
+ }
+ return BstMutationResult.mutationResult(key, originalRoot, changedRoot, modResult);
+ }
+
+ /**
+ * Returns the result of removing the minimum element from the specified subtree.
+ */
+ public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> extractMin(
+ N root, BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) {
+ checkNotNull(root);
+ checkNotNull(nodeFactory);
+ checkNotNull(balancePolicy);
+ if (root.hasChild(LEFT)) {
+ BstMutationResult<K, N> subResult =
+ extractMin(root.getChild(LEFT), nodeFactory, balancePolicy);
+ return subResult.lift(root, LEFT, nodeFactory, balancePolicy);
+ }
+ return BstMutationResult.mutationResult(
+ root.getKey(), root, root.childOrNull(RIGHT),
+ BstModificationResult.rebalancingChange(root, null));
+ }
+
+ /**
+ * Returns the result of removing the maximum element from the specified subtree.
+ */
+ public static <K, N extends BstNode<K, N>> BstMutationResult<K, N> extractMax(
+ N root, BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) {
+ checkNotNull(root);
+ checkNotNull(nodeFactory);
+ checkNotNull(balancePolicy);
+ if (root.hasChild(RIGHT)) {
+ BstMutationResult<K, N> subResult =
+ extractMax(root.getChild(RIGHT), nodeFactory, balancePolicy);
+ return subResult.lift(root, RIGHT, nodeFactory, balancePolicy);
+ }
+ return BstMutationResult.mutationResult(root.getKey(), root, root.childOrNull(LEFT),
+ BstModificationResult.rebalancingChange(root, null));
+ }
+
+ /**
+ * Inserts the specified entry into the tree as the minimum entry. Assumes that {@code
+ * entry.getKey()} is less than the key of all nodes in the subtree {@code root}.
+ */
+ public static <N extends BstNode<?, N>> N insertMin(@Nullable N root, N entry,
+ BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) {
+ checkNotNull(entry);
+ checkNotNull(nodeFactory);
+ checkNotNull(balancePolicy);
+ if (root == null) {
+ return nodeFactory.createLeaf(entry);
+ } else {
+ return balancePolicy.balance(nodeFactory, root,
+ insertMin(root.childOrNull(LEFT), entry, nodeFactory, balancePolicy),
+ root.childOrNull(RIGHT));
+ }
+ }
+
+ /**
+ * Inserts the specified entry into the tree as the maximum entry. Assumes that {@code
+ * entry.getKey()} is greater than the key of all nodes in the subtree {@code root}.
+ */
+ public static <N extends BstNode<?, N>> N insertMax(@Nullable N root, N entry,
+ BstNodeFactory<N> nodeFactory, BstBalancePolicy<N> balancePolicy) {
+ checkNotNull(entry);
+ checkNotNull(nodeFactory);
+ checkNotNull(balancePolicy);
+ if (root == null) {
+ return nodeFactory.createLeaf(entry);
+ } else {
+ return balancePolicy.balance(nodeFactory, root, root.childOrNull(LEFT),
+ insertMax(root.childOrNull(RIGHT), entry, nodeFactory, balancePolicy));
+ }
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstPath.java b/guava/src/com/google/common/collect/BstPath.java
new file mode 100644
index 0000000..dd564c7
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstPath.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * A path to a node in a binary search tree, originating at the root.
+ *
+ * @author Louis Wasserman
+ * @param <N> The type of nodes in this binary search tree.
+ * @param <P> This path type, and the path type of all suffix paths.
+ */
+@GwtCompatible
+abstract class BstPath<N extends BstNode<?, N>, P extends BstPath<N, P>> {
+ private final N tip;
+ @Nullable
+ private final P prefix;
+
+ BstPath(N tip, @Nullable P prefix) {
+ this.tip = checkNotNull(tip);
+ this.prefix = prefix;
+ }
+
+ /**
+ * Return the end of this {@code BstPath}, the deepest node in the path.
+ */
+ public final N getTip() {
+ return tip;
+ }
+
+ /**
+ * Returns {@code true} if this path has a prefix.
+ */
+ public final boolean hasPrefix() {
+ return prefix != null;
+ }
+
+ /**
+ * Returns the prefix of this path, which reaches to the parent of the end of this path. Returns
+ * {@code null} if this path has no prefix.
+ */
+ @Nullable
+ public final P prefixOrNull() {
+ return prefix;
+ }
+
+ /**
+ * Returns the prefix of this path, which reaches to the parent of the end of this path.
+ *
+ * @throws IllegalStateException if this path has no prefix.
+ */
+ public final P getPrefix() {
+ checkState(hasPrefix());
+ return prefix;
+ }
+}
diff --git a/guava/src/com/google/common/collect/BstPathFactory.java b/guava/src/com/google/common/collect/BstPathFactory.java
new file mode 100644
index 0000000..92086ae
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstPathFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * A factory for extending paths in a binary search tree.
+ *
+ * @author Louis Wasserman
+ * @param <N> The type of binary search tree nodes used in the paths generated by this {@code
+ * BstPathFactory}.
+ * @param <P> The type of paths constructed by this {@code BstPathFactory}.
+ */
+@GwtCompatible
+interface BstPathFactory<N extends BstNode<?, N>, P extends BstPath<N, P>> {
+ /**
+ * Returns this path extended by one node to the specified {@code side}.
+ */
+ P extension(P path, BstSide side);
+
+ /**
+ * Returns the trivial path that starts at {@code root} and goes no further.
+ */
+ P initialPath(N root);
+}
diff --git a/guava/src/com/google/common/collect/BstRangeOps.java b/guava/src/com/google/common/collect/BstRangeOps.java
new file mode 100644
index 0000000..10d5931
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstRangeOps.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
+
+import com.google.common.annotations.GwtCompatible;
+
+import javax.annotation.Nullable;
+
+/**
+ * A utility class with operations on binary search trees that operate on some interval.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+final class BstRangeOps {
+ /**
+ * Returns the total value of the specified aggregation function on the specified tree restricted
+ * to the specified range. Assumes that the tree satisfies the binary search ordering property
+ * relative to {@code range.comparator()}.
+ */
+ public static <K, N extends BstNode<K, N>> long totalInRange(
+ BstAggregate<? super N> aggregate, GeneralRange<K> range, @Nullable N root) {
+ checkNotNull(aggregate);
+ checkNotNull(range);
+ if (root == null || range.isEmpty()) {
+ return 0;
+ }
+ long total = aggregate.treeValue(root);
+ if (range.hasLowerBound()) {
+ total -= totalBeyondRangeToSide(aggregate, range, LEFT, root);
+ }
+ if (range.hasUpperBound()) {
+ total -= totalBeyondRangeToSide(aggregate, range, RIGHT, root);
+ }
+ return total;
+ }
+
+ // Returns total value strictly to the specified side of the specified range.
+ private static <K, N extends BstNode<K, N>> long totalBeyondRangeToSide(
+ BstAggregate<? super N> aggregate, GeneralRange<K> range, BstSide side, @Nullable N root) {
+ long accum = 0;
+ while (root != null) {
+ if (beyond(range, root.getKey(), side)) {
+ accum += aggregate.entryValue(root);
+ accum += aggregate.treeValue(root.childOrNull(side));
+ root = root.childOrNull(side.other());
+ } else {
+ root = root.childOrNull(side);
+ }
+ }
+ return accum;
+ }
+
+ /**
+ * Returns a balanced tree containing all nodes from the specified tree that were <i>not</i> in
+ * the specified range, using the specified balance policy. Assumes that the tree satisfies the
+ * binary search ordering property relative to {@code range.comparator()}.
+ */
+ @Nullable
+ public static <K, N extends BstNode<K, N>> N minusRange(GeneralRange<K> range,
+ BstBalancePolicy<N> balancePolicy, BstNodeFactory<N> nodeFactory, @Nullable N root) {
+ checkNotNull(range);
+ checkNotNull(balancePolicy);
+ checkNotNull(nodeFactory);
+ N higher = range.hasUpperBound()
+ ? subTreeBeyondRangeToSide(range, balancePolicy, nodeFactory, RIGHT, root)
+ : null;
+ N lower = range.hasLowerBound()
+ ? subTreeBeyondRangeToSide(range, balancePolicy, nodeFactory, LEFT, root)
+ : null;
+ return balancePolicy.combine(nodeFactory, lower, higher);
+ }
+
+ /*
+ * Returns a balanced tree containing all nodes in the specified tree that are strictly to the
+ * specified side of the specified range.
+ */
+ @Nullable
+ private static <K, N extends BstNode<K, N>> N subTreeBeyondRangeToSide(GeneralRange<K> range,
+ BstBalancePolicy<N> balancePolicy, BstNodeFactory<N> nodeFactory, BstSide side,
+ @Nullable N root) {
+ if (root == null) {
+ return null;
+ }
+ if (beyond(range, root.getKey(), side)) {
+ N left = root.childOrNull(LEFT);
+ N right = root.childOrNull(RIGHT);
+ switch (side) {
+ case LEFT:
+ right = subTreeBeyondRangeToSide(range, balancePolicy, nodeFactory, LEFT, right);
+ break;
+ case RIGHT:
+ left = subTreeBeyondRangeToSide(range, balancePolicy, nodeFactory, RIGHT, left);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ return balancePolicy.balance(nodeFactory, root, left, right);
+ } else {
+ return subTreeBeyondRangeToSide(
+ range, balancePolicy, nodeFactory, side, root.childOrNull(side));
+ }
+ }
+
+ /**
+ * Returns the furthest path to the specified side in the specified tree that falls into the
+ * specified range.
+ */
+ @Nullable
+ public static <K, N extends BstNode<K, N>, P extends BstPath<N, P>> P furthestPath(
+ GeneralRange<K> range, BstSide side, BstPathFactory<N, P> pathFactory, @Nullable N root) {
+ checkNotNull(range);
+ checkNotNull(pathFactory);
+ checkNotNull(side);
+ if (root == null) {
+ return null;
+ }
+ P path = pathFactory.initialPath(root);
+ return furthestPath(range, side, pathFactory, path);
+ }
+
+ private static <K, N extends BstNode<K, N>, P extends BstPath<N, P>> P furthestPath(
+ GeneralRange<K> range, BstSide side, BstPathFactory<N, P> pathFactory, P currentPath) {
+ N tip = currentPath.getTip();
+ K tipKey = tip.getKey();
+ if (beyond(range, tipKey, side)) {
+ if (tip.hasChild(side.other())) {
+ currentPath = pathFactory.extension(currentPath, side.other());
+ return furthestPath(range, side, pathFactory, currentPath);
+ } else {
+ return null;
+ }
+ } else if (tip.hasChild(side)) {
+ P alphaPath = pathFactory.extension(currentPath, side);
+ alphaPath = furthestPath(range, side, pathFactory, alphaPath);
+ if (alphaPath != null) {
+ return alphaPath;
+ }
+ }
+ return beyond(range, tipKey, side.other()) ? null : currentPath;
+ }
+
+ /**
+ * Returns {@code true} if {@code key} is beyond the specified side of the specified range.
+ */
+ public static <K> boolean beyond(GeneralRange<K> range, @Nullable K key, BstSide side) {
+ checkNotNull(range);
+ switch (side) {
+ case LEFT:
+ return range.tooLow(key);
+ case RIGHT:
+ return range.tooHigh(key);
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ private BstRangeOps() {}
+}
diff --git a/guava/src/com/google/common/collect/BstSide.java b/guava/src/com/google/common/collect/BstSide.java
new file mode 100644
index 0000000..5dec1bc
--- /dev/null
+++ b/guava/src/com/google/common/collect/BstSide.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * A side of a binary search tree node, used to index its children.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+enum BstSide {
+ LEFT {
+ @Override
+ public BstSide other() {
+ return RIGHT;
+ }
+ },
+ RIGHT {
+ @Override
+ public BstSide other() {
+ return LEFT;
+ }
+ };
+
+ abstract BstSide other();
+}
diff --git a/guava/src/com/google/common/collect/CartesianList.java b/guava/src/com/google/common/collect/CartesianList.java
deleted file mode 100644
index 62f9227..0000000
--- a/guava/src/com/google/common/collect/CartesianList.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkElementIndex;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.math.IntMath;
-
-import java.util.AbstractList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of {@link Lists#cartesianProduct(List)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-final class CartesianList<E> extends AbstractList<List<E>> {
-
- private transient final ImmutableList<List<E>> axes;
- private transient final int[] axesSizeProduct;
-
- static <E> List<List<E>> create(List<? extends List<? extends E>> lists) {
- ImmutableList.Builder<List<E>> axesBuilder =
- new ImmutableList.Builder<List<E>>(lists.size());
- for (List<? extends E> list : lists) {
- List<E> copy = ImmutableList.copyOf(list);
- if (copy.isEmpty()) {
- return ImmutableList.of();
- }
- axesBuilder.add(copy);
- }
- return new CartesianList<E>(axesBuilder.build());
- }
-
- CartesianList(ImmutableList<List<E>> axes) {
- this.axes = axes;
- int[] axesSizeProduct = new int[axes.size() + 1];
- axesSizeProduct[axes.size()] = 1;
- try {
- for (int i = axes.size() - 1; i >= 0; i--) {
- axesSizeProduct[i] =
- IntMath.checkedMultiply(axesSizeProduct[i + 1], axes.get(i).size());
- }
- } catch (ArithmeticException e) {
- throw new IllegalArgumentException(
- "Cartesian product too large; must have size at most Integer.MAX_VALUE");
- }
- this.axesSizeProduct = axesSizeProduct;
- }
-
- private int getAxisIndexForProductIndex(int index, int axis) {
- return (index / axesSizeProduct[axis + 1]) % axes.get(axis).size();
- }
-
- @Override
- public ImmutableList<E> get(final int index) {
- checkElementIndex(index, size());
- return new ImmutableList<E>() {
-
- @Override
- public int size() {
- return axes.size();
- }
-
- @Override
- public E get(int axis) {
- checkElementIndex(axis, size());
- int axisIndex = getAxisIndexForProductIndex(index, axis);
- return axes.get(axis).get(axisIndex);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- };
- }
-
- @Override
- public int size() {
- return axesSizeProduct[0];
- }
-
- @Override
- public boolean contains(@Nullable Object o) {
- if (!(o instanceof List)) {
- return false;
- }
- List<?> list = (List<?>) o;
- if (list.size() != axes.size()) {
- return false;
- }
- ListIterator<?> itr = list.listIterator();
- while (itr.hasNext()) {
- int index = itr.nextIndex();
- if (!axes.get(index).contains(itr.next())) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public int indexOf(Object o) {
- if (!(o instanceof List)) {
- return -1;
- }
- List<?> l = (List<?>) o;
- if (l.size() != axes.size()) {
- return -1;
- }
- Iterator<?> lIterator = l.iterator();
- int i = 0;
- for (List<E> axis : axes) {
- Object lElement = lIterator.next();
- int axisIndex = axis.indexOf(lElement);
- if (axisIndex == -1) {
- return -1;
- }
- i = (i * axis.size()) + axisIndex;
- }
- return i;
- }
-
- @Override
- public int lastIndexOf(Object o) {
- if (!(o instanceof List)) {
- return -1;
- }
- List<?> l = (List<?>) o;
- if (l.size() != axes.size()) {
- return -1;
- }
- Iterator<?> lIterator = l.iterator();
- int i = 0;
- for (List<E> axis : axes) {
- Object lElement = lIterator.next();
- int axisIndex = axis.lastIndexOf(lElement);
- if (axisIndex == -1) {
- return -1;
- }
- i = (i * axis.size()) + axisIndex;
- }
- return i;
- }
-}
diff --git a/guava/src/com/google/common/collect/ClassToInstanceMap.java b/guava/src/com/google/common/collect/ClassToInstanceMap.java
index b3f535c..6b6fb5b 100644
--- a/guava/src/com/google/common/collect/ClassToInstanceMap.java
+++ b/guava/src/com/google/common/collect/ClassToInstanceMap.java
@@ -31,13 +31,6 @@ import javax.annotation.Nullable;
* <p>Like any other {@code Map<Class, Object>}, this map may contain entries
* for primitive types, and a primitive type and its corresponding wrapper type
* may map to different values.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#ClassToInstanceMap">
- * {@code ClassToInstanceMap}</a>.
- *
- * <p>To map a generic type to an instance of that type, use {@link
- * com.google.common.reflect.TypeToInstanceMap} instead.
*
* @param <B> the common supertype that all entries must share; often this is
* simply {@link Object}
diff --git a/guava/src/com/google/common/collect/Collections2.java b/guava/src/com/google/common/collect/Collections2.java
index 7805e0b..603fa8b 100644
--- a/guava/src/com/google/common/collect/Collections2.java
+++ b/guava/src/com/google/common/collect/Collections2.java
@@ -18,27 +18,21 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.math.LongMath.binomial;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-import com.google.common.math.IntMath;
import com.google.common.primitives.Ints;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
-import javax.annotation.Nullable;
-
/**
* Provides static methods for working with {@code Collection} instances.
*
@@ -95,33 +89,13 @@ public final class Collections2 {
/**
* Delegates to {@link Collection#contains}. Returns {@code false} if the
- * {@code contains} method throws a {@code ClassCastException} or
- * {@code NullPointerException}.
+ * {@code contains} method throws a {@code ClassCastException}.
*/
static boolean safeContains(Collection<?> collection, Object object) {
- checkNotNull(collection);
try {
return collection.contains(object);
} catch (ClassCastException e) {
return false;
- } catch (NullPointerException e) {
- return false;
- }
- }
-
- /**
- * Delegates to {@link Collection#remove}. Returns {@code false} if the
- * {@code remove} method throws a {@code ClassCastException} or
- * {@code NullPointerException}.
- */
- static boolean safeRemove(Collection<?> collection, Object object) {
- checkNotNull(collection);
- try {
- return collection.remove(object);
- } catch (ClassCastException e) {
- return false;
- } catch (NullPointerException e) {
- return false;
}
}
@@ -163,9 +137,6 @@ public final class Collections2 {
@Override
public boolean contains(Object element) {
try {
- // TODO(user): consider doing the predicate after unfiltered.contains,
- // which would reduce the risk of CCE here
-
// unsafe cast can result in a CCE from predicate.apply(), which we
// will catch
@SuppressWarnings("unchecked")
@@ -207,9 +178,6 @@ public final class Collections2 {
@Override
public boolean remove(Object element) {
try {
- // TODO(user): consider doing the predicate after unfiltered.contains,
- // which would reduce the risk of CCE here
-
// unsafe cast can result in a CCE from predicate.apply(), which we
// will catch
@SuppressWarnings("unchecked")
@@ -373,357 +341,8 @@ public final class Collections2 {
return (Collection<T>) iterable;
}
- static final Joiner STANDARD_JOINER = Joiner.on(", ").useForNull("null");
-
- /**
- * Returns a {@link Collection} of all the permutations of the specified
- * {@link Iterable}.
- *
- * <p><i>Notes:</i> This is an implementation of the algorithm for
- * Lexicographical Permutations Generation, described in Knuth's "The Art of
- * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The
- * iteration order follows the lexicographical order. This means that
- * the first permutation will be in ascending order, and the last will be in
- * descending order.
- *
- * <p>Duplicate elements are considered equal. For example, the list [1, 1]
- * will have only one permutation, instead of two. This is why the elements
- * have to implement {@link Comparable}.
- *
- * <p>An empty iterable has only one permutation, which is an empty list.
- *
- * <p>This method is equivalent to
- * {@code Collections2.orderedPermutations(list, Ordering.natural())}.
- *
- * @param elements the original iterable whose elements have to be permuted.
- * @return an immutable {@link Collection} containing all the different
- * permutations of the original iterable.
- * @throws NullPointerException if the specified iterable is null or has any
- * null elements.
- * @since 12.0
- */
- @Beta public static <E extends Comparable<? super E>>
- Collection<List<E>> orderedPermutations(Iterable<E> elements) {
- return orderedPermutations(elements, Ordering.natural());
- }
-
- /**
- * Returns a {@link Collection} of all the permutations of the specified
- * {@link Iterable} using the specified {@link Comparator} for establishing
- * the lexicographical ordering.
- *
- * <p>Examples: <pre> {@code
- *
- * for (List<String> perm : orderedPermutations(asList("b", "c", "a"))) {
- * println(perm);
- * }
- * // -> ["a", "b", "c"]
- * // -> ["a", "c", "b"]
- * // -> ["b", "a", "c"]
- * // -> ["b", "c", "a"]
- * // -> ["c", "a", "b"]
- * // -> ["c", "b", "a"]
- *
- * for (List<Integer> perm : orderedPermutations(asList(1, 2, 2, 1))) {
- * println(perm);
- * }
- * // -> [1, 1, 2, 2]
- * // -> [1, 2, 1, 2]
- * // -> [1, 2, 2, 1]
- * // -> [2, 1, 1, 2]
- * // -> [2, 1, 2, 1]
- * // -> [2, 2, 1, 1]}</pre>
- *
- * <p><i>Notes:</i> This is an implementation of the algorithm for
- * Lexicographical Permutations Generation, described in Knuth's "The Art of
- * Computer Programming", Volume 4, Chapter 7, Section 7.2.1.2. The
- * iteration order follows the lexicographical order. This means that
- * the first permutation will be in ascending order, and the last will be in
- * descending order.
- *
- * <p>Elements that compare equal are considered equal and no new permutations
- * are created by swapping them.
- *
- * <p>An empty iterable has only one permutation, which is an empty list.
- *
- * @param elements the original iterable whose elements have to be permuted.
- * @param comparator a comparator for the iterable's elements.
- * @return an immutable {@link Collection} containing all the different
- * permutations of the original iterable.
- * @throws NullPointerException If the specified iterable is null, has any
- * null elements, or if the specified comparator is null.
- * @since 12.0
- */
- @Beta public static <E> Collection<List<E>> orderedPermutations(
- Iterable<E> elements, Comparator<? super E> comparator) {
- return new OrderedPermutationCollection<E>(elements, comparator);
- }
-
- private static final class OrderedPermutationCollection<E>
- extends AbstractCollection<List<E>> {
- final ImmutableList<E> inputList;
- final Comparator<? super E> comparator;
- final int size;
-
- OrderedPermutationCollection(Iterable<E> input,
- Comparator<? super E> comparator) {
- this.inputList = Ordering.from(comparator).immutableSortedCopy(input);
- this.comparator = comparator;
- this.size = calculateSize(inputList, comparator);
- }
-
- /**
- * The number of permutations with repeated elements is calculated as
- * follows:
- * <ul>
- * <li>For an empty list, it is 1 (base case).</li>
- * <li>When r numbers are added to a list of n-r elements, the number of
- * permutations is increased by a factor of (n choose r).</li>
- * </ul>
- */
- private static <E> int calculateSize(
- List<E> sortedInputList, Comparator<? super E> comparator) {
- long permutations = 1;
- int n = 1;
- int r = 1;
- while (n < sortedInputList.size()) {
- int comparison = comparator.compare(
- sortedInputList.get(n - 1), sortedInputList.get(n));
- if (comparison < 0) {
- // We move to the next non-repeated element.
- permutations *= binomial(n, r);
- r = 0;
- if (!isPositiveInt(permutations)) {
- return Integer.MAX_VALUE;
- }
- }
- n++;
- r++;
- }
- permutations *= binomial(n, r);
- if (!isPositiveInt(permutations)) {
- return Integer.MAX_VALUE;
- }
- return (int) permutations;
- }
-
- @Override public int size() {
- return size;
- }
-
- @Override public boolean isEmpty() {
- return false;
- }
-
- @Override public Iterator<List<E>> iterator() {
- return new OrderedPermutationIterator<E>(inputList, comparator);
- }
-
- @Override public boolean contains(@Nullable Object obj) {
- if (obj instanceof List) {
- List<?> list = (List<?>) obj;
- return isPermutation(inputList, list);
- }
- return false;
- }
-
- @Override public String toString() {
- return "orderedPermutationCollection(" + inputList + ")";
- }
- }
-
- private static final class OrderedPermutationIterator<E>
- extends AbstractIterator<List<E>> {
-
- List<E> nextPermutation;
- final Comparator<? super E> comparator;
-
- OrderedPermutationIterator(List<E> list,
- Comparator<? super E> comparator) {
- this.nextPermutation = Lists.newArrayList(list);
- this.comparator = comparator;
- }
-
- @Override protected List<E> computeNext() {
- if (nextPermutation == null) {
- return endOfData();
- }
- ImmutableList<E> next = ImmutableList.copyOf(nextPermutation);
- calculateNextPermutation();
- return next;
- }
-
- void calculateNextPermutation() {
- int j = findNextJ();
- if (j == -1) {
- nextPermutation = null;
- return;
- }
-
- int l = findNextL(j);
- Collections.swap(nextPermutation, j, l);
- int n = nextPermutation.size();
- Collections.reverse(nextPermutation.subList(j + 1, n));
- }
-
- int findNextJ() {
- for (int k = nextPermutation.size() - 2; k >= 0; k--) {
- if (comparator.compare(nextPermutation.get(k),
- nextPermutation.get(k + 1)) < 0) {
- return k;
- }
- }
- return -1;
- }
-
- int findNextL(int j) {
- E ak = nextPermutation.get(j);
- for (int l = nextPermutation.size() - 1; l > j; l--) {
- if (comparator.compare(ak, nextPermutation.get(l)) < 0) {
- return l;
- }
- }
- throw new AssertionError("this statement should be unreachable");
- }
- }
-
- /**
- * Returns a {@link Collection} of all the permutations of the specified
- * {@link Collection}.
- *
- * <p><i>Notes:</i> This is an implementation of the Plain Changes algorithm
- * for permutations generation, described in Knuth's "The Art of Computer
- * Programming", Volume 4, Chapter 7, Section 7.2.1.2.
- *
- * <p>If the input list contains equal elements, some of the generated
- * permutations will be equal.
- *
- * <p>An empty collection has only one permutation, which is an empty list.
- *
- * @param elements the original collection whose elements have to be permuted.
- * @return an immutable {@link Collection} containing all the different
- * permutations of the original collection.
- * @throws NullPointerException if the specified collection is null or has any
- * null elements.
- * @since 12.0
- */
- @Beta public static <E> Collection<List<E>> permutations(
- Collection<E> elements) {
- return new PermutationCollection<E>(ImmutableList.copyOf(elements));
- }
-
- private static final class PermutationCollection<E>
- extends AbstractCollection<List<E>> {
- final ImmutableList<E> inputList;
-
- PermutationCollection(ImmutableList<E> input) {
- this.inputList = input;
- }
-
- @Override public int size() {
- return IntMath.factorial(inputList.size());
- }
-
- @Override public boolean isEmpty() {
- return false;
- }
-
- @Override public Iterator<List<E>> iterator() {
- return new PermutationIterator<E>(inputList);
- }
-
- @Override public boolean contains(@Nullable Object obj) {
- if (obj instanceof List) {
- List<?> list = (List<?>) obj;
- return isPermutation(inputList, list);
- }
- return false;
- }
-
- @Override public String toString() {
- return "permutations(" + inputList + ")";
- }
- }
-
- private static class PermutationIterator<E>
- extends AbstractIterator<List<E>> {
- final List<E> list;
- final int[] c;
- final int[] o;
- int j;
-
- PermutationIterator(List<E> list) {
- this.list = new ArrayList<E>(list);
- int n = list.size();
- c = new int[n];
- o = new int[n];
- for (int i = 0; i < n; i++) {
- c[i] = 0;
- o[i] = 1;
- }
- j = Integer.MAX_VALUE;
- }
-
- @Override protected List<E> computeNext() {
- if (j <= 0) {
- return endOfData();
- }
- ImmutableList<E> next = ImmutableList.copyOf(list);
- calculateNextPermutation();
- return next;
- }
+ static final Joiner STANDARD_JOINER = Joiner.on(", ");
- void calculateNextPermutation() {
- j = list.size() - 1;
- int s = 0;
-
- // Handle the special case of an empty list. Skip the calculation of the
- // next permutation.
- if (j == -1) {
- return;
- }
-
- while (true) {
- int q = c[j] + o[j];
- if (q < 0) {
- switchDirection();
- continue;
- }
- if (q == j + 1) {
- if (j == 0) {
- break;
- }
- s++;
- switchDirection();
- continue;
- }
-
- Collections.swap(list, j - c[j] + s, j - q + s);
- c[j] = q;
- break;
- }
- }
-
- void switchDirection() {
- o[j] = -o[j];
- j--;
- }
- }
-
- /**
- * Returns {@code true} if the second list is a permutation of the first.
- */
- private static boolean isPermutation(List<?> first,
- List<?> second) {
- if (first.size() != second.size()) {
- return false;
- }
- Multiset<?> firstSet = HashMultiset.create(first);
- Multiset<?> secondSet = HashMultiset.create(second);
- return firstSet.equals(secondSet);
- }
-
- private static boolean isPositiveInt(long n) {
- return n >= 0 && n <= Integer.MAX_VALUE;
- }
+ // TODO(user): Maybe move the mathematical methods to a separate
+ // package-permission class.
}
diff --git a/guava/src/com/google/common/collect/ComparatorOrdering.java b/guava/src/com/google/common/collect/ComparatorOrdering.java
index 5eb7612..77fe58d 100644
--- a/guava/src/com/google/common/collect/ComparatorOrdering.java
+++ b/guava/src/com/google/common/collect/ComparatorOrdering.java
@@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import java.io.Serializable;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -53,17 +52,6 @@ final class ComparatorOrdering<T> extends Ordering<T> implements Serializable {
return list;
}
- // Override just to remove a level of indirection from inner loops
- @Override public <E extends T> ImmutableList<E> immutableSortedCopy(Iterable<E> iterable) {
- @SuppressWarnings("unchecked") // we'll only ever have E's in here
- E[] elements = (E[]) Iterables.toArray(iterable);
- for (E e : elements) {
- checkNotNull(e);
- }
- Arrays.sort(elements, comparator);
- return ImmutableList.asImmutableList(elements);
- }
-
@Override public boolean equals(@Nullable Object object) {
if (object == this) {
return true;
diff --git a/guava/src/com/google/common/collect/ComparisonChain.java b/guava/src/com/google/common/collect/ComparisonChain.java
index 2ed8cc4..cc90357 100644
--- a/guava/src/com/google/common/collect/ComparisonChain.java
+++ b/guava/src/com/google/common/collect/ComparisonChain.java
@@ -44,10 +44,6 @@ import javax.annotation.Nullable;
*
* <p>Once any comparison returns a nonzero value, remaining comparisons are
* "short-circuited".
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained#compare/compareTo">
- * {@code ComparisonChain}</a>.
*
* @author Mark Davis
* @author Kevin Bourrillion
@@ -87,10 +83,7 @@ public abstract class ComparisonChain {
@Override public ComparisonChain compare(double left, double right) {
return classify(Double.compare(left, right));
}
- @Override public ComparisonChain compareTrueFirst(boolean left, boolean right) {
- return classify(Booleans.compare(right, left)); // reversed
- }
- @Override public ComparisonChain compareFalseFirst(boolean left, boolean right) {
+ @Override public ComparisonChain compare(boolean left, boolean right) {
return classify(Booleans.compare(left, right));
}
ComparisonChain classify(int result) {
@@ -131,10 +124,7 @@ public abstract class ComparisonChain {
@Override public ComparisonChain compare(double left, double right) {
return this;
}
- @Override public ComparisonChain compareTrueFirst(boolean left, boolean right) {
- return this;
- }
- @Override public ComparisonChain compareFalseFirst(boolean left, boolean right) {
+ @Override public ComparisonChain compare(boolean left, boolean right) {
return this;
}
@Override public int result() {
@@ -186,35 +176,11 @@ public abstract class ComparisonChain {
public abstract ComparisonChain compare(double left, double right);
/**
- * Compares two {@code boolean} values, considering {@code true} to be less
- * than {@code false}, <i>if</i> the result of this comparison chain has not
+ * Compares two {@code boolean} values as specified by {@link
+ * Booleans#compare}, <i>if</i> the result of this comparison chain has not
* already been determined.
- *
- * @since 12.0
*/
- public abstract ComparisonChain compareTrueFirst(boolean left, boolean right);
-
- /**
- * Compares two {@code boolean} values, considering {@code false} to be less
- * than {@code true}, <i>if</i> the result of this comparison chain has not
- * already been determined.
- *
- * @since 12.0 (present as {@code compare} since 2.0)
- */
- public abstract ComparisonChain compareFalseFirst(boolean left, boolean right);
-
- /**
- * Old name of {@link #compareFalseFirst}.
- *
- * @deprecated Use {@link #compareFalseFirst}; or, if the parameters passed
- * are being either negated or reversed, undo the negation or reversal and
- * use {@link #compareTrueFirst}. <b>This method is scheduled for deletion
- * in September 2013.</b>
- */
- @Deprecated
- public final ComparisonChain compare(boolean left, boolean right) {
- return compareFalseFirst(left, right);
- }
+ public abstract ComparisonChain compare(boolean left, boolean right);
/**
* Ends this comparison chain and returns its result: a value having the
diff --git a/guava/src/com/google/common/collect/CompoundOrdering.java b/guava/src/com/google/common/collect/CompoundOrdering.java
index 26ebf54..f669a62 100644
--- a/guava/src/com/google/common/collect/CompoundOrdering.java
+++ b/guava/src/com/google/common/collect/CompoundOrdering.java
@@ -20,6 +20,7 @@ import com.google.common.annotations.GwtCompatible;
import java.io.Serializable;
import java.util.Comparator;
+import java.util.List;
/** An ordering that tries several comparators in order. */
@GwtCompatible(serializable = true)
@@ -36,11 +37,15 @@ final class CompoundOrdering<T> extends Ordering<T> implements Serializable {
this.comparators = ImmutableList.copyOf(comparators);
}
+ CompoundOrdering(List<? extends Comparator<? super T>> comparators,
+ Comparator<? super T> lastComparator) {
+ this.comparators = new ImmutableList.Builder<Comparator<? super T>>()
+ .addAll(comparators).add(lastComparator).build();
+ }
+
@Override public int compare(T left, T right) {
- // Avoid using the Iterator to avoid generating garbage (issue 979).
- int size = comparators.size();
- for (int i = 0; i < size; i++) {
- int result = comparators.get(i).compare(left, right);
+ for (Comparator<? super T> comparator : comparators) {
+ int result = comparator.compare(left, right);
if (result != 0) {
return result;
}
diff --git a/guava/src/com/google/common/collect/ComputationException.java b/guava/src/com/google/common/collect/ComputationException.java
index ac80d6a..5401aff 100644
--- a/guava/src/com/google/common/collect/ComputationException.java
+++ b/guava/src/com/google/common/collect/ComputationException.java
@@ -18,8 +18,6 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import javax.annotation.Nullable;
-
/**
* Wraps an exception that occurred during a computation.
*
@@ -31,7 +29,7 @@ public class ComputationException extends RuntimeException {
/**
* Creates a new instance with the given cause.
*/
- public ComputationException(@Nullable Throwable cause) {
+ public ComputationException(Throwable cause) {
super(cause);
}
private static final long serialVersionUID = 0;
diff --git a/guava/src/com/google/common/collect/ComputingConcurrentHashMap.java b/guava/src/com/google/common/collect/ComputingConcurrentHashMap.java
index eb7363a..1e37edc 100644
--- a/guava/src/com/google/common/collect/ComputingConcurrentHashMap.java
+++ b/guava/src/com/google/common/collect/ComputingConcurrentHashMap.java
@@ -223,8 +223,7 @@ class ComputingConcurrentHashMap<K, V> extends MapMakerInternalMap<K, V> {
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return this;
}
@@ -263,8 +262,7 @@ class ComputingConcurrentHashMap<K, V> extends MapMakerInternalMap<K, V> {
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return this;
}
@@ -305,8 +303,7 @@ class ComputingConcurrentHashMap<K, V> extends MapMakerInternalMap<K, V> {
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, @Nullable V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return this;
}
diff --git a/guava/src/com/google/common/collect/ConcurrentHashMultiset.java b/guava/src/com/google/common/collect/ConcurrentHashMultiset.java
index 1a1331b..46b8d6e 100644
--- a/guava/src/com/google/common/collect/ConcurrentHashMultiset.java
+++ b/guava/src/com/google/common/collect/ConcurrentHashMultiset.java
@@ -17,7 +17,6 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Multisets.checkNonnegative;
@@ -31,7 +30,6 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -46,10 +44,6 @@ import javax.annotation.Nullable;
* A multiset that supports concurrent modifications and that provides atomic versions of most
* {@code Multiset} operations (exceptions where noted). Null elements are not supported.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
- *
* @author Cliff L. Biffle
* @author mike nonemacher
* @since 2.0 (imported from Google Collections Library)
@@ -118,7 +112,7 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
* <p>Finally, soft/weak values can be used but are not very useful: the values are created
* internally and not exposed externally, so no one else will have a strong reference to the
* values. Weak keys on the other hand can be useful in some scenarios.
- *
+ *
* @since 7.0
*/
@Beta
@@ -151,11 +145,26 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
* @return the nonnegative number of occurrences of the element
*/
@Override public int count(@Nullable Object element) {
- AtomicInteger existingCounter = Maps.safeGet(countMap, element);
+ AtomicInteger existingCounter = safeGet(element);
return (existingCounter == null) ? 0 : existingCounter.get();
}
/**
+ * Depending on the type of the underlying map, map.get may throw NullPointerException or
+ * ClassCastException, if the object is null or of the wrong type. We usually just want to treat
+ * those cases as if the element isn't in the map, by catching the exceptions and returning null.
+ */
+ private AtomicInteger safeGet(Object element) {
+ try {
+ return countMap.get(element);
+ } catch (NullPointerException e) {
+ return null;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+
+ /**
* {@inheritDoc}
*
* <p>If the data in the multiset is modified by any other threads during this method,
@@ -209,14 +218,13 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
* the resulting amount would exceed {@link Integer#MAX_VALUE}
*/
@Override public int add(E element, int occurrences) {
- checkNotNull(element);
if (occurrences == 0) {
return count(element);
}
checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
while (true) {
- AtomicInteger existingCounter = Maps.safeGet(countMap, element);
+ AtomicInteger existingCounter = safeGet(element);
if (existingCounter == null) {
existingCounter = countMap.putIfAbsent(element, new AtomicInteger(occurrences));
if (existingCounter == null) {
@@ -264,22 +272,13 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
* @return the count of the element before the operation; possibly zero
* @throws IllegalArgumentException if {@code occurrences} is negative
*/
- /*
- * TODO(cpovirk): remove and removeExactly currently accept null inputs only
- * if occurrences == 0. This satisfies both NullPointerTester and
- * CollectionRemoveTester.testRemove_nullAllowed, but it's not clear that it's
- * a good policy, especially because, in order for the test to pass, the
- * parameter must be misleadingly annotated as @Nullable. I suspect that
- * we'll want to remove @Nullable, add an eager checkNotNull, and loosen up
- * testRemove_nullAllowed.
- */
@Override public int remove(@Nullable Object element, int occurrences) {
if (occurrences == 0) {
return count(element);
}
checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
- AtomicInteger existingCounter = Maps.safeGet(countMap, element);
+ AtomicInteger existingCounter = safeGet(element);
if (existingCounter == null) {
return 0;
}
@@ -318,7 +317,7 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
}
checkArgument(occurrences > 0, "Invalid occurrences: %s", occurrences);
- AtomicInteger existingCounter = Maps.safeGet(countMap, element);
+ AtomicInteger existingCounter = safeGet(element);
if (existingCounter == null) {
return false;
}
@@ -347,10 +346,9 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
* @throws IllegalArgumentException if {@code count} is negative
*/
@Override public int setCount(E element, int count) {
- checkNotNull(element);
checkNonnegative(count, "count");
while (true) {
- AtomicInteger existingCounter = Maps.safeGet(countMap, element);
+ AtomicInteger existingCounter = safeGet(element);
if (existingCounter == null) {
if (count == 0) {
return 0;
@@ -402,11 +400,10 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
* @throws IllegalArgumentException if {@code expectedOldCount} or {@code newCount} is negative
*/
@Override public boolean setCount(E element, int expectedOldCount, int newCount) {
- checkNotNull(element);
checkNonnegative(expectedOldCount, "oldCount");
checkNonnegative(newCount, "newCount");
- AtomicInteger existingCounter = Maps.safeGet(countMap, element);
+ AtomicInteger existingCounter = safeGet(element);
if (existingCounter == null) {
if (expectedOldCount != 0) {
return false;
@@ -451,23 +448,14 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
@Override protected Set<E> delegate() {
return delegate;
}
-
- @Override
- public boolean contains(@Nullable Object object) {
- return object != null && Collections2.safeContains(delegate, object);
- }
-
- @Override
- public boolean containsAll(Collection<?> collection) {
- return standardContainsAll(collection);
- }
-
@Override public boolean remove(Object object) {
- return object != null && Collections2.safeRemove(delegate, object);
- }
-
- @Override public boolean removeAll(Collection<?> c) {
- return standardRemoveAll(c);
+ try {
+ return delegate.remove(object);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
}
};
}
@@ -559,6 +547,21 @@ public final class ConcurrentHashMultiset<E> extends AbstractMultiset<E> impleme
Iterators.addAll(list, iterator());
return list;
}
+
+ @Override public boolean remove(Object object) {
+ if (object instanceof Multiset.Entry) {
+ Multiset.Entry<?> entry = (Multiset.Entry<?>) object;
+ Object element = entry.getElement();
+ int entryCount = entry.getCount();
+ if (entryCount != 0) {
+ // Safe as long as we never add a new entry, which we won't.
+ @SuppressWarnings("unchecked")
+ Multiset<Object> multiset = (Multiset) multiset();
+ return multiset.setCount(element, entryCount, 0);
+ }
+ }
+ return false;
+ }
}
/**
diff --git a/guava/src/com/google/common/collect/ContiguousSet.java b/guava/src/com/google/common/collect/ContiguousSet.java
index dc9aa83..439f675 100644
--- a/guava/src/com/google/common/collect/ContiguousSet.java
+++ b/guava/src/com/google/common/collect/ContiguousSet.java
@@ -19,63 +19,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import java.util.Collections;
import java.util.NoSuchElementException;
-import java.util.Set;
/**
* A sorted set of contiguous values in a given {@link DiscreteDomain}.
*
- * <p><b>Warning:</b> Be extremely careful what you do with conceptually large instances (such as
- * {@code ContiguousSet.create(Range.greaterThan(0), DiscreteDomains.integers()}). Certain
- * operations on such a set can be performed efficiently, but others (such as {@link Set#hashCode}
- * or {@link Collections#frequency}) can cause major performance problems.
- *
* @author Gregory Kick
* @since 10.0
*/
@Beta
-@GwtCompatible(emulated = true)
-@SuppressWarnings("rawtypes") // allow ungenerified Comparable types
+@GwtCompatible
+@SuppressWarnings("unchecked") // allow ungenerified Comparable types
public abstract class ContiguousSet<C extends Comparable> extends ImmutableSortedSet<C> {
- /**
- * Returns a {@code ContiguousSet} containing the same values in the given domain
- * {@linkplain Range#contains contained} by the range.
- *
- * @throws IllegalArgumentException if neither range nor the domain has a lower bound, or if
- * neither has an upper bound
- *
- * @since 13.0
- */
- public static <C extends Comparable> ContiguousSet<C> create(
- Range<C> range, DiscreteDomain<C> domain) {
- checkNotNull(range);
- checkNotNull(domain);
- Range<C> effectiveRange = range;
- try {
- if (!range.hasLowerBound()) {
- effectiveRange = effectiveRange.intersection(Range.atLeast(domain.minValue()));
- }
- if (!range.hasUpperBound()) {
- effectiveRange = effectiveRange.intersection(Range.atMost(domain.maxValue()));
- }
- } catch (NoSuchElementException e) {
- throw new IllegalArgumentException(e);
- }
-
- // Per class spec, we are allowed to throw CCE if necessary
- boolean empty = effectiveRange.isEmpty()
- || Range.compareOrThrow(
- range.lowerBound.leastValueAbove(domain),
- range.upperBound.greatestValueBelow(domain)) > 0;
-
- return empty
- ? new EmptyContiguousSet<C>(domain)
- : new RegularContiguousSet<C>(effectiveRange, domain);
- }
-
final DiscreteDomain<C> domain;
ContiguousSet(DiscreteDomain<C> domain) {
@@ -84,14 +40,10 @@ public abstract class ContiguousSet<C extends Comparable> extends ImmutableSorte
}
@Override public ContiguousSet<C> headSet(C toElement) {
- return headSetImpl(checkNotNull(toElement), false);
+ return headSet(checkNotNull(toElement), false);
}
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override public ContiguousSet<C> headSet(C toElement, boolean inclusive) {
+ @Override ContiguousSet<C> headSet(C toElement, boolean inclusive) {
return headSetImpl(checkNotNull(toElement), inclusive);
}
@@ -99,14 +51,10 @@ public abstract class ContiguousSet<C extends Comparable> extends ImmutableSorte
checkNotNull(fromElement);
checkNotNull(toElement);
checkArgument(comparator().compare(fromElement, toElement) <= 0);
- return subSetImpl(fromElement, true, toElement, false);
+ return subSet(fromElement, true, toElement, false);
}
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override public ContiguousSet<C> subSet(C fromElement, boolean fromInclusive, C toElement,
+ @Override ContiguousSet<C> subSet(C fromElement, boolean fromInclusive, C toElement,
boolean toInclusive) {
checkNotNull(fromElement);
checkNotNull(toElement);
@@ -115,14 +63,10 @@ public abstract class ContiguousSet<C extends Comparable> extends ImmutableSorte
}
@Override public ContiguousSet<C> tailSet(C fromElement) {
- return tailSetImpl(checkNotNull(fromElement), true);
+ return tailSet(checkNotNull(fromElement), true);
}
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override public ContiguousSet<C> tailSet(C fromElement, boolean inclusive) {
+ @Override ContiguousSet<C> tailSet(C fromElement, boolean inclusive){
return tailSetImpl(checkNotNull(fromElement), inclusive);
}
diff --git a/guava/src/com/google/common/collect/Count.java b/guava/src/com/google/common/collect/Count.java
index 768e298..a095119 100644
--- a/guava/src/com/google/common/collect/Count.java
+++ b/guava/src/com/google/common/collect/Count.java
@@ -29,6 +29,10 @@ import javax.annotation.Nullable;
final class Count implements Serializable {
private int value;
+ Count() {
+ this(0);
+ }
+
Count(int value) {
this.value = value;
}
diff --git a/guava/src/com/google/common/collect/Cut.java b/guava/src/com/google/common/collect/Cut.java
index 44e3450..204ea0c 100644
--- a/guava/src/com/google/common/collect/Cut.java
+++ b/guava/src/com/google/common/collect/Cut.java
@@ -161,9 +161,6 @@ abstract class Cut<C extends Comparable> implements Comparable<Cut<C>>, Serializ
@Override public int compareTo(Cut<Comparable<?>> o) {
return (o == this) ? 0 : -1;
}
- @Override public String toString() {
- return "-\u221e";
- }
private Object readResolve() {
return INSTANCE;
}
@@ -222,9 +219,6 @@ abstract class Cut<C extends Comparable> implements Comparable<Cut<C>>, Serializ
@Override public int compareTo(Cut<Comparable<?>> o) {
return (o == this) ? 0 : 1;
}
- @Override public String toString() {
- return "+\u221e";
- }
private Object readResolve() {
return INSTANCE;
}
@@ -286,9 +280,6 @@ abstract class Cut<C extends Comparable> implements Comparable<Cut<C>>, Serializ
@Override public int hashCode() {
return endpoint.hashCode();
}
- @Override public String toString() {
- return "\\" + endpoint + "/";
- }
private static final long serialVersionUID = 0;
}
@@ -351,9 +342,6 @@ abstract class Cut<C extends Comparable> implements Comparable<Cut<C>>, Serializ
@Override public int hashCode() {
return ~endpoint.hashCode();
}
- @Override public String toString() {
- return "/" + endpoint + "\\";
- }
private static final long serialVersionUID = 0;
}
}
diff --git a/guava/src/com/google/common/collect/DescendingImmutableSortedMultiset.java b/guava/src/com/google/common/collect/DescendingImmutableSortedMultiset.java
index d2d0088..f5630dd 100644
--- a/guava/src/com/google/common/collect/DescendingImmutableSortedMultiset.java
+++ b/guava/src/com/google/common/collect/DescendingImmutableSortedMultiset.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -18,14 +18,14 @@ import javax.annotation.Nullable;
/**
* A descending wrapper around an {@code ImmutableSortedMultiset}
- *
+ *
* @author Louis Wasserman
*/
-@SuppressWarnings("serial") // uses writeReplace, not default serialization
final class DescendingImmutableSortedMultiset<E> extends ImmutableSortedMultiset<E> {
private final transient ImmutableSortedMultiset<E> forward;
DescendingImmutableSortedMultiset(ImmutableSortedMultiset<E> forward) {
+ super(forward.reverseComparator());
this.forward = forward;
}
@@ -50,29 +50,18 @@ final class DescendingImmutableSortedMultiset<E> extends ImmutableSortedMultiset
}
@Override
- public ImmutableSortedSet<E> elementSet() {
- return forward.elementSet().descendingSet();
+ ImmutableSortedSet<E> createElementSet() {
+ return forward.createDescendingElementSet();
}
@Override
- ImmutableSet<Entry<E>> createEntrySet() {
- final ImmutableSet<Entry<E>> forwardEntrySet = forward.entrySet();
- return new EntrySet() {
- @Override
- public int size() {
- return forwardEntrySet.size();
- }
-
- @Override
- public UnmodifiableIterator<Entry<E>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<E>> createAsList() {
- return forwardEntrySet.asList().reverse();
- }
- };
+ ImmutableSortedSet<E> createDescendingElementSet() {
+ return forward.elementSet();
+ }
+
+ @Override
+ UnmodifiableIterator<Entry<E>> descendingEntryIterator() {
+ return forward.entryIterator();
}
@Override
@@ -91,6 +80,16 @@ final class DescendingImmutableSortedMultiset<E> extends ImmutableSortedMultiset
}
@Override
+ UnmodifiableIterator<Entry<E>> entryIterator() {
+ return forward.descendingEntryIterator();
+ }
+
+ @Override
+ int distinctElements() {
+ return forward.distinctElements();
+ }
+
+ @Override
boolean isPartialView() {
return forward.isPartialView();
}
diff --git a/guava/src/com/google/common/collect/DescendingImmutableSortedSet.java b/guava/src/com/google/common/collect/DescendingImmutableSortedSet.java
deleted file mode 100644
index 340d8b9..0000000
--- a/guava/src/com/google/common/collect/DescendingImmutableSortedSet.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtIncompatible;
-
-import javax.annotation.Nullable;
-
-/**
- * Skeletal implementation of {@link ImmutableSortedSet#descendingSet()}.
- *
- * @author Louis Wasserman
- */
-class DescendingImmutableSortedSet<E> extends ImmutableSortedSet<E> {
- private final ImmutableSortedSet<E> forward;
-
- DescendingImmutableSortedSet(ImmutableSortedSet<E> forward) {
- super(Ordering.from(forward.comparator()).reverse());
- this.forward = forward;
- }
-
- @Override
- public int size() {
- return forward.size();
- }
-
- @Override
- public UnmodifiableIterator<E> iterator() {
- return forward.descendingIterator();
- }
-
- @Override
- ImmutableSortedSet<E> headSetImpl(E toElement, boolean inclusive) {
- return forward.tailSet(toElement, inclusive).descendingSet();
- }
-
- @Override
- ImmutableSortedSet<E> subSetImpl(
- E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
- return forward.subSet(toElement, toInclusive, fromElement, fromInclusive).descendingSet();
- }
-
- @Override
- ImmutableSortedSet<E> tailSetImpl(E fromElement, boolean inclusive) {
- return forward.headSet(fromElement, inclusive).descendingSet();
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- public ImmutableSortedSet<E> descendingSet() {
- return forward;
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- public UnmodifiableIterator<E> descendingIterator() {
- return forward.iterator();
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- ImmutableSortedSet<E> createDescendingSet() {
- throw new AssertionError("should never be called");
- }
-
- @Override
- public E lower(E element) {
- return forward.higher(element);
- }
-
- @Override
- public E floor(E element) {
- return forward.ceiling(element);
- }
-
- @Override
- public E ceiling(E element) {
- return forward.floor(element);
- }
-
- @Override
- public E higher(E element) {
- return forward.lower(element);
- }
-
- @Override
- int indexOf(@Nullable Object target) {
- int index = forward.indexOf(target);
- if (index == -1) {
- return index;
- } else {
- return size() - 1 - index;
- }
- }
-
- @Override
- boolean isPartialView() {
- return forward.isPartialView();
- }
-}
diff --git a/guava/src/com/google/common/collect/DescendingMultiset.java b/guava/src/com/google/common/collect/DescendingMultiset.java
deleted file mode 100644
index d83f782..0000000
--- a/guava/src/com/google/common/collect/DescendingMultiset.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.NavigableSet;
-import java.util.Set;
-
-/**
- * A skeleton implementation of a descending multiset. Only needs
- * {@code forwardMultiset()} and {@code entryIterator()}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-abstract class DescendingMultiset<E> extends ForwardingMultiset<E>
- implements SortedMultiset<E> {
- abstract SortedMultiset<E> forwardMultiset();
-
- private transient Comparator<? super E> comparator;
-
- @Override public Comparator<? super E> comparator() {
- Comparator<? super E> result = comparator;
- if (result == null) {
- return comparator =
- Ordering.from(forwardMultiset().comparator()).<E>reverse();
- }
- return result;
- }
-
- private transient NavigableSet<E> elementSet;
-
- @Override public NavigableSet<E> elementSet() {
- NavigableSet<E> result = elementSet;
- if (result == null) {
- return elementSet = new SortedMultisets.NavigableElementSet<E>(this);
- }
- return result;
- }
-
- @Override public Entry<E> pollFirstEntry() {
- return forwardMultiset().pollLastEntry();
- }
-
- @Override public Entry<E> pollLastEntry() {
- return forwardMultiset().pollFirstEntry();
- }
-
- @Override public SortedMultiset<E> headMultiset(E toElement,
- BoundType boundType) {
- return forwardMultiset().tailMultiset(toElement, boundType)
- .descendingMultiset();
- }
-
- @Override public SortedMultiset<E> subMultiset(E fromElement,
- BoundType fromBoundType, E toElement, BoundType toBoundType) {
- return forwardMultiset().subMultiset(toElement, toBoundType, fromElement,
- fromBoundType).descendingMultiset();
- }
-
- @Override public SortedMultiset<E> tailMultiset(E fromElement,
- BoundType boundType) {
- return forwardMultiset().headMultiset(fromElement, boundType)
- .descendingMultiset();
- }
-
- @Override protected Multiset<E> delegate() {
- return forwardMultiset();
- }
-
- @Override public SortedMultiset<E> descendingMultiset() {
- return forwardMultiset();
- }
-
- @Override public Entry<E> firstEntry() {
- return forwardMultiset().lastEntry();
- }
-
- @Override public Entry<E> lastEntry() {
- return forwardMultiset().firstEntry();
- }
-
- abstract Iterator<Entry<E>> entryIterator();
-
- private transient Set<Entry<E>> entrySet;
-
- @Override public Set<Entry<E>> entrySet() {
- Set<Entry<E>> result = entrySet;
- return (result == null) ? entrySet = createEntrySet() : result;
- }
-
- Set<Entry<E>> createEntrySet() {
- return new Multisets.EntrySet<E>() {
- @Override Multiset<E> multiset() {
- return DescendingMultiset.this;
- }
-
- @Override public Iterator<Entry<E>> iterator() {
- return entryIterator();
- }
-
- @Override public int size() {
- return forwardMultiset().entrySet().size();
- }
- };
- }
-
- @Override public Iterator<E> iterator() {
- return Multisets.iteratorImpl(this);
- }
-
- @Override public Object[] toArray() {
- return standardToArray();
- }
-
- @Override public <T> T[] toArray(T[] array) {
- return standardToArray(array);
- }
-
- @Override public String toString() {
- return entrySet().toString();
- }
-} \ No newline at end of file
diff --git a/guava/src/com/google/common/collect/DiscreteDomain.java b/guava/src/com/google/common/collect/DiscreteDomain.java
index f2a2f9a..893bbbb 100644
--- a/guava/src/com/google/common/collect/DiscreteDomain.java
+++ b/guava/src/com/google/common/collect/DiscreteDomain.java
@@ -19,13 +19,11 @@ package com.google.common.collect;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import java.io.Serializable;
-import java.math.BigInteger;
import java.util.NoSuchElementException;
/**
* A descriptor for a <i>discrete</i> {@code Comparable} domain such as all
- * {@link Integer} instances. A discrete domain is one that supports the three basic
+ * {@link Integer}s. A discrete domain is one that supports the three basic
* operations: {@link #next}, {@link #previous} and {@link #distance}, according
* to their specifications. The methods {@link #minValue} and {@link #maxValue}
* should also be overridden for bounded types.
@@ -34,159 +32,13 @@ import java.util.NoSuchElementException;
* type; it cannot represent partial domains such as "prime integers" or
* "strings of length 5."
*
- * <p>See the Guava User Guide section on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/RangesExplained#Discrete_Domains">
- * {@code DiscreteDomain}</a>.
- *
* @author Kevin Bourrillion
* @since 10.0
+ * @see DiscreteDomains
*/
@GwtCompatible
@Beta
public abstract class DiscreteDomain<C extends Comparable> {
-
- /**
- * Returns the discrete domain for values of type {@code Integer}.
- *
- * @since 14.0 (since 10.0 as {@code DiscreteDomains.integers()})
- */
- public static DiscreteDomain<Integer> integers() {
- return IntegerDomain.INSTANCE;
- }
-
- private static final class IntegerDomain extends DiscreteDomain<Integer>
- implements Serializable {
- private static final IntegerDomain INSTANCE = new IntegerDomain();
-
- @Override public Integer next(Integer value) {
- int i = value;
- return (i == Integer.MAX_VALUE) ? null : i + 1;
- }
-
- @Override public Integer previous(Integer value) {
- int i = value;
- return (i == Integer.MIN_VALUE) ? null : i - 1;
- }
-
- @Override public long distance(Integer start, Integer end) {
- return (long) end - start;
- }
-
- @Override public Integer minValue() {
- return Integer.MIN_VALUE;
- }
-
- @Override public Integer maxValue() {
- return Integer.MAX_VALUE;
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
-
- @Override
- public String toString() {
- return "DiscreteDomains.integers()";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns the discrete domain for values of type {@code Long}.
- *
- * @since 14.0 (since 10.0 as {@code DiscreteDomains.longs()})
- */
- public static DiscreteDomain<Long> longs() {
- return LongDomain.INSTANCE;
- }
-
- private static final class LongDomain extends DiscreteDomain<Long>
- implements Serializable {
- private static final LongDomain INSTANCE = new LongDomain();
-
- @Override public Long next(Long value) {
- long l = value;
- return (l == Long.MAX_VALUE) ? null : l + 1;
- }
-
- @Override public Long previous(Long value) {
- long l = value;
- return (l == Long.MIN_VALUE) ? null : l - 1;
- }
-
- @Override public long distance(Long start, Long end) {
- long result = end - start;
- if (end > start && result < 0) { // overflow
- return Long.MAX_VALUE;
- }
- if (end < start && result > 0) { // underflow
- return Long.MIN_VALUE;
- }
- return result;
- }
-
- @Override public Long minValue() {
- return Long.MIN_VALUE;
- }
-
- @Override public Long maxValue() {
- return Long.MAX_VALUE;
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
-
- @Override
- public String toString() {
- return "DiscreteDomains.longs()";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns the discrete domain for values of type {@code BigInteger}.
- */
- // TODO(kevinb): make sure it's tested, and make it public
- static DiscreteDomain<BigInteger> bigIntegers() {
- return BigIntegerDomain.INSTANCE;
- }
-
- private static final class BigIntegerDomain extends DiscreteDomain<BigInteger>
- implements Serializable {
- private static final BigIntegerDomain INSTANCE = new BigIntegerDomain();
-
- private static final BigInteger MIN_LONG =
- BigInteger.valueOf(Long.MIN_VALUE);
- private static final BigInteger MAX_LONG =
- BigInteger.valueOf(Long.MAX_VALUE);
-
- @Override public BigInteger next(BigInteger value) {
- return value.add(BigInteger.ONE);
- }
-
- @Override public BigInteger previous(BigInteger value) {
- return value.subtract(BigInteger.ONE);
- }
-
- @Override public long distance(BigInteger start, BigInteger end) {
- return end.subtract(start).max(MIN_LONG).min(MAX_LONG).longValue();
- }
-
- private Object readResolve() {
- return INSTANCE;
- }
-
- @Override
- public String toString() {
- return "DiscreteDomains.bigIntegers()";
- }
-
- private static final long serialVersionUID = 0;
- }
-
/** Constructor for use by subclasses. */
protected DiscreteDomain() {}
@@ -224,7 +76,7 @@ public abstract class DiscreteDomain<C extends Comparable> {
* type.
*
* @return the distance as described above, or {@link Long#MIN_VALUE} or
- * {@link Long#MAX_VALUE} if the distance is too small or too large,
+ * {@link Long#MIN_VALUE} if the distance is too small or too large,
* respectively.
*/
public abstract long distance(C start, C end);
@@ -258,5 +110,4 @@ public abstract class DiscreteDomain<C extends Comparable> {
public C maxValue() {
throw new NoSuchElementException();
}
-
}
diff --git a/guava/src/com/google/common/collect/DiscreteDomains.java b/guava/src/com/google/common/collect/DiscreteDomains.java
index dac4628..8cb2ae7 100644
--- a/guava/src/com/google/common/collect/DiscreteDomains.java
+++ b/guava/src/com/google/common/collect/DiscreteDomains.java
@@ -16,22 +16,20 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
+import java.io.Serializable;
+import java.math.BigInteger;
+
/**
* Factories for common {@link DiscreteDomain} instances.
*
- * <p>See the Guava User Guide section on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/RangesExplained#Discrete_Domains">
- * {@code DiscreteDomain}</a>.
- *
* @author Gregory Kick
* @since 10.0
- * @deprecated Merged into {@link DiscreteDomain}. This class is scheduled for deletion in release
- * 15.0.
*/
@GwtCompatible
-@Deprecated
+@Beta
public final class DiscreteDomains {
private DiscreteDomains() {}
@@ -39,13 +37,122 @@ public final class DiscreteDomains {
* Returns the discrete domain for values of type {@code Integer}.
*/
public static DiscreteDomain<Integer> integers() {
- return DiscreteDomain.integers();
+ return IntegerDomain.INSTANCE;
+ }
+
+ private static final class IntegerDomain extends DiscreteDomain<Integer>
+ implements Serializable {
+ private static final IntegerDomain INSTANCE = new IntegerDomain();
+
+ @Override public Integer next(Integer value) {
+ int i = value;
+ return (i == Integer.MAX_VALUE) ? null : i + 1;
+ }
+
+ @Override public Integer previous(Integer value) {
+ int i = value;
+ return (i == Integer.MIN_VALUE) ? null : i - 1;
+ }
+
+ @Override public long distance(Integer start, Integer end) {
+ return (long) end - start;
+ }
+
+ @Override public Integer minValue() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override public Integer maxValue() {
+ return Integer.MAX_VALUE;
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+
+ private static final long serialVersionUID = 0;
}
/**
* Returns the discrete domain for values of type {@code Long}.
*/
public static DiscreteDomain<Long> longs() {
- return DiscreteDomain.longs();
+ return LongDomain.INSTANCE;
+ }
+
+ private static final class LongDomain extends DiscreteDomain<Long>
+ implements Serializable {
+ private static final LongDomain INSTANCE = new LongDomain();
+
+ @Override public Long next(Long value) {
+ long l = value;
+ return (l == Long.MAX_VALUE) ? null : l + 1;
+ }
+
+ @Override public Long previous(Long value) {
+ long l = value;
+ return (l == Long.MIN_VALUE) ? null : l - 1;
+ }
+
+ @Override public long distance(Long start, Long end) {
+ long result = end - start;
+ if (end > start && result < 0) { // overflow
+ return Long.MAX_VALUE;
+ }
+ if (end < start && result > 0) { // underflow
+ return Long.MIN_VALUE;
+ }
+ return result;
+ }
+
+ @Override public Long minValue() {
+ return Long.MIN_VALUE;
+ }
+
+ @Override public Long maxValue() {
+ return Long.MAX_VALUE;
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
+ * Returns the discrete domain for values of type {@code BigInteger}.
+ */
+ // TODO(kevinb): make sure it's tested, and make it public
+ static DiscreteDomain<BigInteger> bigIntegers() {
+ return BigIntegerDomain.INSTANCE;
+ }
+
+ private static final class BigIntegerDomain extends DiscreteDomain<BigInteger>
+ implements Serializable {
+ private static final BigIntegerDomain INSTANCE = new BigIntegerDomain();
+
+ private static final BigInteger MIN_LONG =
+ BigInteger.valueOf(Long.MIN_VALUE);
+ private static final BigInteger MAX_LONG =
+ BigInteger.valueOf(Long.MAX_VALUE);
+
+ @Override public BigInteger next(BigInteger value) {
+ return value.add(BigInteger.ONE);
+ }
+
+ @Override public BigInteger previous(BigInteger value) {
+ return value.subtract(BigInteger.ONE);
+ }
+
+ @Override public long distance(BigInteger start, BigInteger end) {
+ return start.subtract(end).max(MIN_LONG).min(MAX_LONG).longValue();
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+
+ private static final long serialVersionUID = 0;
}
}
diff --git a/guava/src/com/google/common/collect/EmptyContiguousSet.java b/guava/src/com/google/common/collect/EmptyContiguousSet.java
index 4546349..2bec7bd 100644
--- a/guava/src/com/google/common/collect/EmptyContiguousSet.java
+++ b/guava/src/com/google/common/collect/EmptyContiguousSet.java
@@ -71,8 +71,8 @@ final class EmptyContiguousSet<C extends Comparable> extends ContiguousSet<C> {
return this;
}
- @GwtIncompatible("not used by GWT emulation")
- @Override int indexOf(Object target) {
+ //Abstract method doesn't exist in GWT emulation
+ /* @Override */ int indexOf(Object target) {
return -1;
}
@@ -80,11 +80,6 @@ final class EmptyContiguousSet<C extends Comparable> extends ContiguousSet<C> {
return Iterators.emptyIterator();
}
- @GwtIncompatible("NavigableSet")
- @Override public UnmodifiableIterator<C> descendingIterator() {
- return Iterators.emptyIterator();
- }
-
@Override boolean isPartialView() {
return false;
}
@@ -133,9 +128,4 @@ final class EmptyContiguousSet<C extends Comparable> extends ContiguousSet<C> {
Object writeReplace() {
return new SerializedForm<C>(domain);
}
-
- @GwtIncompatible("NavigableSet")
- ImmutableSortedSet<C> createDescendingSet() {
- return new EmptyImmutableSortedSet<C>(Ordering.natural().reverse());
- }
}
diff --git a/guava/src/com/google/common/collect/EmptyImmutableBiMap.java b/guava/src/com/google/common/collect/EmptyImmutableBiMap.java
deleted file mode 100644
index 5b862b3..0000000
--- a/guava/src/com/google/common/collect/EmptyImmutableBiMap.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import javax.annotation.Nullable;
-
-/**
- * Bimap with no mappings.
- *
- * @author Jared Levy
- */
-@GwtCompatible(emulated = true)
-@SuppressWarnings("serial") // uses writeReplace(), not default serialization
-final class EmptyImmutableBiMap extends ImmutableBiMap<Object, Object> {
- static final EmptyImmutableBiMap INSTANCE = new EmptyImmutableBiMap();
-
- private EmptyImmutableBiMap() {}
-
- @Override public ImmutableBiMap<Object, Object> inverse() {
- return this;
- }
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public boolean isEmpty() {
- return true;
- }
-
- @Override
- public Object get(@Nullable Object key) {
- return null;
- }
-
- @Override
- public ImmutableSet<Entry<Object, Object>> entrySet() {
- return ImmutableSet.of();
- }
-
- @Override
- ImmutableSet<Entry<Object, Object>> createEntrySet() {
- throw new AssertionError("should never be called");
- }
-
- @Override
- public ImmutableSet<Object> keySet() {
- return ImmutableSet.of();
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
-
- Object readResolve() {
- return INSTANCE; // preserve singleton property
- }
-}
diff --git a/guava/src/com/google/common/collect/EmptyImmutableList.java b/guava/src/com/google/common/collect/EmptyImmutableList.java
index b854d2b..ec685dd 100644
--- a/guava/src/com/google/common/collect/EmptyImmutableList.java
+++ b/guava/src/com/google/common/collect/EmptyImmutableList.java
@@ -24,17 +24,45 @@ import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
import java.util.List;
+import java.util.NoSuchElementException;
import javax.annotation.Nullable;
/**
* An empty immutable list.
- *
+ *
* @author Kevin Bourrillion
*/
@GwtCompatible(serializable = true, emulated = true)
final class EmptyImmutableList extends ImmutableList<Object> {
static final EmptyImmutableList INSTANCE = new EmptyImmutableList();
+ static final UnmodifiableListIterator<Object> ITERATOR =
+ new UnmodifiableListIterator<Object>() {
+
+ @Override public boolean hasNext() {
+ return false;
+ }
+
+ @Override public boolean hasPrevious() {
+ return false;
+ }
+
+ @Override public Object next() {
+ throw new NoSuchElementException();
+ }
+
+ @Override public int nextIndex() {
+ return 0;
+ }
+
+ @Override public Object previous() {
+ throw new NoSuchElementException();
+ }
+
+ @Override public int previousIndex() {
+ return -1;
+ }
+ };
private EmptyImmutableList() {}
@@ -51,20 +79,18 @@ final class EmptyImmutableList extends ImmutableList<Object> {
return false;
}
- @Override public boolean contains(@Nullable Object target) {
+ @Override public boolean contains(Object target) {
return false;
}
- @Override public boolean containsAll(Collection<?> targets) {
- return targets.isEmpty();
- }
-
@Override public UnmodifiableIterator<Object> iterator() {
- return listIterator();
+ return Iterators.emptyIterator();
}
+ private static final Object[] EMPTY_ARRAY = new Object[0];
+
@Override public Object[] toArray() {
- return ObjectArrays.EMPTY_ARRAY;
+ return EMPTY_ARRAY;
}
@Override public <T> T[] toArray(T[] a) {
@@ -98,13 +124,17 @@ final class EmptyImmutableList extends ImmutableList<Object> {
return this;
}
- @Override public UnmodifiableListIterator<Object> listIterator() {
- return Iterators.EMPTY_LIST_ITERATOR;
+ @Override public UnmodifiableListIterator<Object> listIterator(){
+ return ITERATOR;
}
@Override public UnmodifiableListIterator<Object> listIterator(int start) {
checkPositionIndex(start, 0);
- return Iterators.EMPTY_LIST_ITERATOR;
+ return ITERATOR;
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ return targets.isEmpty();
}
@Override public boolean equals(@Nullable Object object) {
diff --git a/guava/src/com/google/common/collect/EmptyImmutableMap.java b/guava/src/com/google/common/collect/EmptyImmutableMap.java
new file mode 100644
index 0000000..8d58021
--- /dev/null
+++ b/guava/src/com/google/common/collect/EmptyImmutableMap.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+/**
+ * An empty immutable map.
+ *
+ * @author Jesse Wilson
+ * @author Kevin Bourrillion
+ */
+@GwtCompatible(serializable = true, emulated = true)
+final class EmptyImmutableMap extends ImmutableMap<Object, Object> {
+ static final EmptyImmutableMap INSTANCE = new EmptyImmutableMap();
+
+ private EmptyImmutableMap() {}
+
+ @Override public Object get(@Nullable Object key) {
+ return null;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override public boolean isEmpty() {
+ return true;
+ }
+
+ @Override public boolean containsKey(@Nullable Object key) {
+ return false;
+ }
+
+ @Override public boolean containsValue(@Nullable Object value) {
+ return false;
+ }
+
+ @Override public ImmutableSet<Entry<Object, Object>> entrySet() {
+ return ImmutableSet.of();
+ }
+
+ @Override public ImmutableSet<Object> keySet() {
+ return ImmutableSet.of();
+ }
+
+ @Override public ImmutableCollection<Object> values() {
+ return ImmutableCollection.EMPTY_IMMUTABLE_COLLECTION;
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object instanceof Map) {
+ Map<?, ?> that = (Map<?, ?>) object;
+ return that.isEmpty();
+ }
+ return false;
+ }
+
+ @Override boolean isPartialView() {
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public String toString() {
+ return "{}";
+ }
+
+ Object readResolve() {
+ return INSTANCE; // preserve singleton property
+ }
+
+ private static final long serialVersionUID = 0;
+}
diff --git a/guava/src/com/google/common/collect/EmptyImmutableMultiset.java b/guava/src/com/google/common/collect/EmptyImmutableMultiset.java
index 1931342..2a72a2b 100644
--- a/guava/src/com/google/common/collect/EmptyImmutableMultiset.java
+++ b/guava/src/com/google/common/collect/EmptyImmutableMultiset.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2008 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,13 +18,11 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import java.util.Collection;
-
import javax.annotation.Nullable;
/**
* An empty immutable multiset.
- *
+ *
* @author Jared Levy
* @author Louis Wasserman
*/
@@ -38,51 +36,22 @@ final class EmptyImmutableMultiset extends ImmutableMultiset<Object> {
}
@Override
- public boolean contains(@Nullable Object object) {
- return false;
- }
-
- @Override
- public boolean containsAll(Collection<?> targets) {
- return targets.isEmpty();
- }
-
- @Override
- public UnmodifiableIterator<Object> iterator() {
- return Iterators.emptyIterator();
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (object instanceof Multiset) {
- Multiset<?> other = (Multiset<?>) object;
- return other.isEmpty();
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return 0;
- }
-
- @Override
public ImmutableSet<Object> elementSet() {
return ImmutableSet.of();
}
@Override
- public ImmutableSet<Entry<Object>> entrySet() {
- return ImmutableSet.of();
+ public int size() {
+ return 0;
}
@Override
- ImmutableSet<Entry<Object>> createEntrySet() {
- throw new AssertionError("should never be called");
+ UnmodifiableIterator<Entry<Object>> entryIterator() {
+ return Iterators.emptyIterator();
}
@Override
- public int size() {
+ int distinctElements() {
return 0;
}
@@ -92,22 +61,8 @@ final class EmptyImmutableMultiset extends ImmutableMultiset<Object> {
}
@Override
- public Object[] toArray() {
- return ObjectArrays.EMPTY_ARRAY;
- }
-
- @Override
- public <T> T[] toArray(T[] other) {
- return asList().toArray(other);
- }
-
- @Override
- public ImmutableList<Object> asList() {
- return ImmutableList.of();
- }
-
- Object readResolve() {
- return INSTANCE; // preserve singleton property
+ ImmutableSet<Entry<Object>> createEntrySet() {
+ return ImmutableSet.of();
}
private static final long serialVersionUID = 0;
diff --git a/guava/src/com/google/common/collect/EmptyImmutableSet.java b/guava/src/com/google/common/collect/EmptyImmutableSet.java
index e70b051..8722bdf 100644
--- a/guava/src/com/google/common/collect/EmptyImmutableSet.java
+++ b/guava/src/com/google/common/collect/EmptyImmutableSet.java
@@ -25,7 +25,7 @@ import javax.annotation.Nullable;
/**
* An empty immutable set.
- *
+ *
* @author Kevin Bourrillion
*/
@GwtCompatible(serializable = true, emulated = true)
@@ -43,14 +43,10 @@ final class EmptyImmutableSet extends ImmutableSet<Object> {
return true;
}
- @Override public boolean contains(@Nullable Object target) {
+ @Override public boolean contains(Object target) {
return false;
}
- @Override public boolean containsAll(Collection<?> targets) {
- return targets.isEmpty();
- }
-
@Override public UnmodifiableIterator<Object> iterator() {
return Iterators.emptyIterator();
}
@@ -59,17 +55,21 @@ final class EmptyImmutableSet extends ImmutableSet<Object> {
return false;
}
+ private static final Object[] EMPTY_ARRAY = new Object[0];
+
@Override public Object[] toArray() {
- return ObjectArrays.EMPTY_ARRAY;
+ return EMPTY_ARRAY;
}
@Override public <T> T[] toArray(T[] a) {
- return asList().toArray(a);
+ if (a.length > 0) {
+ a[0] = null;
+ }
+ return a;
}
- @Override
- public ImmutableList<Object> asList() {
- return ImmutableList.of();
+ @Override public boolean containsAll(Collection<?> targets) {
+ return targets.isEmpty();
}
@Override public boolean equals(@Nullable Object object) {
diff --git a/guava/src/com/google/common/collect/EmptyImmutableSortedMap.java b/guava/src/com/google/common/collect/EmptyImmutableSortedMap.java
deleted file mode 100644
index 0a1e854..0000000
--- a/guava/src/com/google/common/collect/EmptyImmutableSortedMap.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Comparator;
-
-import javax.annotation.Nullable;
-
-/**
- * An empty immutable sorted map.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-@SuppressWarnings("serial") // uses writeReplace, not default serialization
-final class EmptyImmutableSortedMap<K, V> extends ImmutableSortedMap<K, V> {
- private final transient ImmutableSortedSet<K> keySet;
-
- EmptyImmutableSortedMap(Comparator<? super K> comparator) {
- this.keySet = ImmutableSortedSet.emptySet(comparator);
- }
-
- EmptyImmutableSortedMap(
- Comparator<? super K> comparator, ImmutableSortedMap<K, V> descendingMap) {
- super(descendingMap);
- this.keySet = ImmutableSortedSet.emptySet(comparator);
- }
-
- @Override
- public V get(@Nullable Object key) {
- return null;
- }
-
- @Override
- public ImmutableSortedSet<K> keySet() {
- return keySet;
- }
-
- @Override
- public int size() {
- return 0;
- }
-
- @Override
- public boolean isEmpty() {
- return true;
- }
-
- @Override
- public ImmutableCollection<V> values() {
- return ImmutableList.of();
- }
-
- @Override
- public String toString() {
- return "{}";
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
-
- @Override
- public ImmutableSet<Entry<K, V>> entrySet() {
- return ImmutableSet.of();
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- throw new AssertionError("should never be called");
- }
-
- @Override
- public ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive) {
- checkNotNull(toKey);
- return this;
- }
-
- @Override
- public ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) {
- checkNotNull(fromKey);
- return this;
- }
-
- @Override
- ImmutableSortedMap<K, V> createDescendingMap() {
- return new EmptyImmutableSortedMap<K, V>(Ordering.from(comparator()).reverse(), this);
- }
-}
diff --git a/guava/src/com/google/common/collect/EmptyImmutableSortedMultiset.java b/guava/src/com/google/common/collect/EmptyImmutableSortedMultiset.java
index a7ddf28..623050c 100644
--- a/guava/src/com/google/common/collect/EmptyImmutableSortedMultiset.java
+++ b/guava/src/com/google/common/collect/EmptyImmutableSortedMultiset.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -16,7 +16,6 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Collection;
import java.util.Comparator;
import javax.annotation.Nullable;
@@ -26,12 +25,9 @@ import javax.annotation.Nullable;
*
* @author Louis Wasserman
*/
-@SuppressWarnings("serial") // Uses writeReplace, not default serialization
final class EmptyImmutableSortedMultiset<E> extends ImmutableSortedMultiset<E> {
- private final ImmutableSortedSet<E> elementSet;
-
EmptyImmutableSortedMultiset(Comparator<? super E> comparator) {
- this.elementSet = ImmutableSortedSet.emptySet(comparator);
+ super(comparator);
}
@Override
@@ -50,33 +46,28 @@ final class EmptyImmutableSortedMultiset<E> extends ImmutableSortedMultiset<E> {
}
@Override
- public boolean contains(@Nullable Object object) {
- return false;
- }
-
- @Override
- public boolean containsAll(Collection<?> targets) {
- return targets.isEmpty();
+ public int size() {
+ return 0;
}
@Override
- public int size() {
- return 0;
+ ImmutableSortedSet<E> createElementSet() {
+ return ImmutableSortedSet.emptySet(comparator());
}
@Override
- public ImmutableSortedSet<E> elementSet() {
- return elementSet;
+ ImmutableSortedSet<E> createDescendingElementSet() {
+ return ImmutableSortedSet.emptySet(reverseComparator());
}
@Override
- public ImmutableSet<Entry<E>> entrySet() {
- return ImmutableSet.of();
+ UnmodifiableIterator<Entry<E>> descendingEntryIterator() {
+ return Iterators.emptyIterator();
}
@Override
- ImmutableSet<Entry<E>> createEntrySet() {
- throw new AssertionError("should never be called");
+ UnmodifiableIterator<Entry<E>> entryIterator() {
+ return Iterators.emptyIterator();
}
@Override
@@ -94,46 +85,12 @@ final class EmptyImmutableSortedMultiset<E> extends ImmutableSortedMultiset<E> {
}
@Override
- public UnmodifiableIterator<E> iterator() {
- return Iterators.emptyIterator();
- }
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (object instanceof Multiset) {
- Multiset<?> other = (Multiset<?>) object;
- return other.isEmpty();
- }
- return false;
- }
-
- @Override
- public int hashCode() {
+ int distinctElements() {
return 0;
}
@Override
- public String toString() {
- return "[]";
- }
-
- @Override
boolean isPartialView() {
return false;
}
-
- @Override
- public Object[] toArray() {
- return ObjectArrays.EMPTY_ARRAY;
- }
-
- @Override
- public <T> T[] toArray(T[] other) {
- return asList().toArray(other);
- }
-
- @Override
- public ImmutableList<E> asList() {
- return ImmutableList.of();
- }
}
diff --git a/guava/src/com/google/common/collect/EmptyImmutableSortedSet.java b/guava/src/com/google/common/collect/EmptyImmutableSortedSet.java
index 9f5d522..e406163 100644
--- a/guava/src/com/google/common/collect/EmptyImmutableSortedSet.java
+++ b/guava/src/com/google/common/collect/EmptyImmutableSortedSet.java
@@ -17,7 +17,6 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.util.Collection;
import java.util.Comparator;
@@ -47,37 +46,33 @@ class EmptyImmutableSortedSet<E> extends ImmutableSortedSet<E> {
return true;
}
- @Override public boolean contains(@Nullable Object target) {
+ @Override public boolean contains(Object target) {
return false;
}
- @Override public boolean containsAll(Collection<?> targets) {
- return targets.isEmpty();
- }
-
@Override public UnmodifiableIterator<E> iterator() {
return Iterators.emptyIterator();
}
- @GwtIncompatible("NavigableSet")
- @Override public UnmodifiableIterator<E> descendingIterator() {
- return Iterators.emptyIterator();
- }
-
@Override boolean isPartialView() {
return false;
}
- @Override public ImmutableList<E> asList() {
- return ImmutableList.of();
- }
+ private static final Object[] EMPTY_ARRAY = new Object[0];
@Override public Object[] toArray() {
- return ObjectArrays.EMPTY_ARRAY;
+ return EMPTY_ARRAY;
}
@Override public <T> T[] toArray(T[] a) {
- return asList().toArray(a);
+ if (a.length > 0) {
+ a[0] = null;
+ }
+ return a;
+ }
+
+ @Override public boolean containsAll(Collection<?> targets) {
+ return targets.isEmpty();
}
@Override public boolean equals(@Nullable Object object) {
@@ -125,9 +120,4 @@ class EmptyImmutableSortedSet<E> extends ImmutableSortedSet<E> {
@Override int indexOf(@Nullable Object target) {
return -1;
}
-
- @Override
- ImmutableSortedSet<E> createDescendingSet() {
- return new EmptyImmutableSortedSet<E>(Ordering.from(comparator).reverse());
- }
}
diff --git a/guava/src/com/google/common/collect/EmptyImmutableTable.java b/guava/src/com/google/common/collect/EmptyImmutableTable.java
index 65b8042..61949ca 100644
--- a/guava/src/com/google/common/collect/EmptyImmutableTable.java
+++ b/guava/src/com/google/common/collect/EmptyImmutableTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import javax.annotation.concurrent.Immutable;
/**
* An empty implementation of {@link ImmutableTable}.
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
@GwtCompatible
@Immutable
@@ -53,7 +53,7 @@ final class EmptyImmutableTable extends ImmutableTable<Object, Object, Object> {
@Override public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
- } else if (obj instanceof Table) {
+ } else if (obj instanceof Table<?, ?, ?>) {
Table<?, ?, ?> that = (Table<?, ?, ?>) obj;
return that.isEmpty();
} else {
diff --git a/guava/src/com/google/common/collect/EnumBiMap.java b/guava/src/com/google/common/collect/EnumBiMap.java
index 05d84ed..9a94ddd 100644
--- a/guava/src/com/google/common/collect/EnumBiMap.java
+++ b/guava/src/com/google/common/collect/EnumBiMap.java
@@ -17,7 +17,6 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -32,10 +31,6 @@ import java.util.Map;
* A {@code BiMap} backed by two {@code EnumMap} instances. Null keys and values
* are not permitted. An {@code EnumBiMap} and its inverse are both
* serializable.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap">
- * {@code BiMap}</a>.
*
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
@@ -111,16 +106,6 @@ public final class EnumBiMap<K extends Enum<K>, V extends Enum<V>>
return valueType;
}
- @Override
- K checkKey(K key) {
- return checkNotNull(key);
- }
-
- @Override
- V checkValue(V value) {
- return checkNotNull(value);
- }
-
/**
* @serialData the key class, value class, number of entries, first key, first
* value, second key, second value, and so on.
diff --git a/guava/src/com/google/common/collect/EnumHashBiMap.java b/guava/src/com/google/common/collect/EnumHashBiMap.java
index c43daf0..8f32515 100644
--- a/guava/src/com/google/common/collect/EnumHashBiMap.java
+++ b/guava/src/com/google/common/collect/EnumHashBiMap.java
@@ -16,8 +16,6 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -35,10 +33,6 @@ import javax.annotation.Nullable;
* a {@code HashMap} instance for values-to-keys. Null keys are not permitted,
* but null values are. An {@code EnumHashBiMap} and its inverse are both
* serializable.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap">
- * {@code BiMap}</a>.
*
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
@@ -83,12 +77,7 @@ public final class EnumHashBiMap<K extends Enum<K>, V>
this.keyType = keyType;
}
- // Overriding these 3 methods to show that values may be null (but not keys)
-
- @Override
- K checkKey(K key) {
- return checkNotNull(key);
- }
+ // Overriding these two methods to show that values may be null (but not keys)
@Override public V put(K key, @Nullable V value) {
return super.put(key, value);
diff --git a/guava/src/com/google/common/collect/EnumMultiset.java b/guava/src/com/google/common/collect/EnumMultiset.java
index 2bb121c..560bf7c 100644
--- a/guava/src/com/google/common/collect/EnumMultiset.java
+++ b/guava/src/com/google/common/collect/EnumMultiset.java
@@ -27,10 +27,6 @@ import java.util.Iterator;
/**
* Multiset implementation backed by an {@link EnumMap}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
*
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -58,19 +54,6 @@ public final class EnumMultiset<E extends Enum<E>> extends AbstractMapBasedMulti
Iterables.addAll(multiset, elements);
return multiset;
}
-
- /**
- * Returns a new {@code EnumMultiset} instance containing the given elements. Unlike
- * {@link EnumMultiset#create(Iterable)}, this method does not produce an exception on an empty
- * iterable.
- *
- * @since 14.0
- */
- public static <E extends Enum<E>> EnumMultiset<E> create(Iterable<E> elements, Class<E> type) {
- EnumMultiset<E> result = create(type);
- Iterables.addAll(result, elements);
- return result;
- }
private transient Class<E> type;
diff --git a/guava/src/com/google/common/collect/FilteredEntryMultimap.java b/guava/src/com/google/common/collect/FilteredEntryMultimap.java
deleted file mode 100644
index 9120893..0000000
--- a/guava/src/com/google/common/collect/FilteredEntryMultimap.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Predicates.compose;
-import static com.google.common.base.Predicates.in;
-import static com.google.common.base.Predicates.not;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of {@link Multimaps#filterEntries(Multimap, Predicate)}.
- *
- * @author Jared Levy
- * @author Louis Wasserman
- */
-@GwtCompatible
-class FilteredEntryMultimap<K, V> extends FilteredMultimap<K, V> {
- final Predicate<? super Entry<K, V>> predicate;
-
- FilteredEntryMultimap(Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
- super(unfiltered);
- this.predicate = checkNotNull(predicate);
- }
-
- @Override
- Predicate<? super Entry<K, V>> entryPredicate() {
- return predicate;
- }
-
- @Override
- public int size() {
- return entries().size();
- }
-
- private boolean satisfies(K key, V value) {
- return predicate.apply(Maps.immutableEntry(key, value));
- }
-
-
- final class ValuePredicate implements Predicate<V> {
- private final K key;
-
- ValuePredicate(K key) {
- this.key = key;
- }
-
- @Override
- public boolean apply(@Nullable V value) {
- return satisfies(key, value);
- }
- }
-
- static <E> Collection<E> filterCollection(
- Collection<E> collection, Predicate<? super E> predicate) {
- if (collection instanceof Set) {
- return Sets.filter((Set<E>) collection, predicate);
- } else {
- return Collections2.filter(collection, predicate);
- }
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return asMap().get(key) != null;
- }
-
- @Override
- public Collection<V> removeAll(@Nullable Object key) {
- return Objects.firstNonNull(asMap().remove(key), unmodifiableEmptyCollection());
- }
-
- Collection<V> unmodifiableEmptyCollection() {
- // These return false, rather than throwing a UOE, on remove calls.
- return (unfiltered instanceof SetMultimap)
- ? Collections.<V>emptySet()
- : Collections.<V>emptyList();
- }
-
- @Override
- public void clear() {
- entries().clear();
- }
-
- @Override
- public Collection<V> get(final K key) {
- return filterCollection(unfiltered.get(key), new ValuePredicate(key));
- }
-
- @Override
- Collection<Entry<K, V>> createEntries() {
- return filterCollection(unfiltered.entries(), predicate);
- }
-
- @Override
- Iterator<Entry<K, V>> entryIterator() {
- throw new AssertionError("should never be called");
- }
-
- @Override
- Map<K, Collection<V>> createAsMap() {
- return new AsMap();
- }
-
- @Override
- public Set<K> keySet() {
- return asMap().keySet();
- }
-
- boolean removeIf(Predicate<? super Entry<K, Collection<V>>> predicate) {
- Iterator<Entry<K, Collection<V>>> entryIterator = unfiltered.asMap().entrySet().iterator();
- boolean changed = false;
- while (entryIterator.hasNext()) {
- Entry<K, Collection<V>> entry = entryIterator.next();
- K key = entry.getKey();
- Collection<V> collection = filterCollection(entry.getValue(), new ValuePredicate(key));
- if (!collection.isEmpty() && predicate.apply(Maps.immutableEntry(key, collection))) {
- if (collection.size() == entry.getValue().size()) {
- entryIterator.remove();
- } else {
- collection.clear();
- }
- changed = true;
- }
- }
- return changed;
- }
-
- class AsMap extends AbstractMap<K, Collection<V>> {
- @Override
- public boolean containsKey(@Nullable Object key) {
- return get(key) != null;
- }
-
- @Override
- public void clear() {
- FilteredEntryMultimap.this.clear();
- }
-
- @Override
- public Collection<V> get(@Nullable Object key) {
- Collection<V> result = unfiltered.asMap().get(key);
- if (result == null) {
- return null;
- }
- @SuppressWarnings("unchecked") // key is equal to a K, if not a K itself
- K k = (K) key;
- result = filterCollection(result, new ValuePredicate(k));
- return result.isEmpty() ? null : result;
- }
-
- @Override
- public Collection<V> remove(@Nullable Object key) {
- Collection<V> collection = unfiltered.asMap().get(key);
- if (collection == null) {
- return null;
- }
- @SuppressWarnings("unchecked") // it's definitely equal to a K
- K k = (K) key;
- List<V> result = Lists.newArrayList();
- Iterator<V> itr = collection.iterator();
- while (itr.hasNext()) {
- V v = itr.next();
- if (satisfies(k, v)) {
- itr.remove();
- result.add(v);
- }
- }
- if (result.isEmpty()) {
- return null;
- } else if (unfiltered instanceof SetMultimap) {
- return Collections.unmodifiableSet(Sets.newLinkedHashSet(result));
- } else {
- return Collections.unmodifiableList(result);
- }
- }
-
- private Set<K> keySet;
-
- @Override
- public Set<K> keySet() {
- Set<K> result = keySet;
- if (result == null) {
- return keySet = new Maps.KeySet<K, Collection<V>>() {
- @Override
- Map<K, Collection<V>> map() {
- return AsMap.this;
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeIf(compose(in(c), Maps.<K>keyFunction()));
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(compose(not(in(c)), Maps.<K>keyFunction()));
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- return AsMap.this.remove(o) != null;
- }
- };
- }
- return result;
- }
-
- @Override
- public Set<Entry<K, Collection<V>>> entrySet() {
- return new Maps.EntrySet<K, Collection<V>>() {
- @Override
- Map<K, Collection<V>> map() {
- return AsMap.this;
- }
-
- @Override
- public Iterator<Entry<K, Collection<V>>> iterator() {
- return new AbstractIterator<Entry<K, Collection<V>>>() {
- final Iterator<Entry<K, Collection<V>>> backingIterator
- = unfiltered.asMap().entrySet().iterator();
-
- @Override
- protected Entry<K, Collection<V>> computeNext() {
- while (backingIterator.hasNext()) {
- Entry<K, Collection<V>> entry = backingIterator.next();
- K key = entry.getKey();
- Collection<V> collection
- = filterCollection(entry.getValue(), new ValuePredicate(key));
- if (!collection.isEmpty()) {
- return Maps.immutableEntry(key, collection);
- }
- }
- return endOfData();
- }
- };
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeIf(in(c));
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(not(in(c)));
- }
-
- @Override
- public int size() {
- return Iterators.size(iterator());
- }
- };
- }
-
- @Override
- public Collection<Collection<V>> values() {
- return new Maps.Values<K, Collection<V>>() {
- @Override
- Map<K, Collection<V>> map() {
- return AsMap.this;
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- if (o instanceof Collection) {
- Collection<?> c = (Collection<?>) o;
- Iterator<Entry<K, Collection<V>>> entryIterator
- = unfiltered.asMap().entrySet().iterator();
- while (entryIterator.hasNext()) {
- Entry<K, Collection<V>> entry = entryIterator.next();
- K key = entry.getKey();
- Collection<V> collection
- = filterCollection(entry.getValue(), new ValuePredicate(key));
- if (!collection.isEmpty() && c.equals(collection)) {
- if (collection.size() == entry.getValue().size()) {
- entryIterator.remove();
- } else {
- collection.clear();
- }
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeIf(compose(in(c), Maps.<Collection<V>>valueFunction()));
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(compose(not(in(c)), Maps.<Collection<V>>valueFunction()));
- }
- };
- }
- }
-
- @Override
- Multiset<K> createKeys() {
- return new Keys();
- }
-
- class Keys extends Multimaps.Keys<K, V> {
- Keys() {
- super(FilteredEntryMultimap.this);
- }
-
- @Override
- public int remove(@Nullable Object key, int occurrences) {
- Multisets.checkNonnegative(occurrences, "occurrences");
- if (occurrences == 0) {
- return count(key);
- }
- Collection<V> collection = unfiltered.asMap().get(key);
- if (collection == null) {
- return 0;
- }
- @SuppressWarnings("unchecked") // key is equal to a K, if not a K itself
- K k = (K) key;
- int oldCount = 0;
- Iterator<V> itr = collection.iterator();
- while (itr.hasNext()) {
- V v = itr.next();
- if (satisfies(k, v)) {
- oldCount++;
- if (oldCount <= occurrences) {
- itr.remove();
- }
- }
- }
- return oldCount;
- }
-
- @Override
- public Set<Multiset.Entry<K>> entrySet() {
- return new Multisets.EntrySet<K>() {
-
- @Override
- Multiset<K> multiset() {
- return Keys.this;
- }
-
- @Override
- public Iterator<Multiset.Entry<K>> iterator() {
- return Keys.this.entryIterator();
- }
-
- @Override
- public int size() {
- return FilteredEntryMultimap.this.keySet().size();
- }
-
- private boolean removeIf(final Predicate<? super Multiset.Entry<K>> predicate) {
- return FilteredEntryMultimap.this.removeIf(new Predicate<Map.Entry<K, Collection<V>>>() {
- @Override
- public boolean apply(Map.Entry<K, Collection<V>> entry) {
- return predicate.apply(
- Multisets.immutableEntry(entry.getKey(), entry.getValue().size()));
- }
- });
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeIf(in(c));
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(not(in(c)));
- }
- };
- }
- }
-}
diff --git a/guava/src/com/google/common/collect/FilteredKeyMultimap.java b/guava/src/com/google/common/collect/FilteredKeyMultimap.java
deleted file mode 100644
index 0a07333..0000000
--- a/guava/src/com/google/common/collect/FilteredKeyMultimap.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndex;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of {@link Multimaps#filterKeys(Multimap, Predicate)}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-class FilteredKeyMultimap<K, V> extends FilteredMultimap<K, V> {
- final Predicate<? super K> keyPredicate;
-
- FilteredKeyMultimap(Multimap<K, V> unfiltered, Predicate<? super K> keyPredicate) {
- super(unfiltered);
- this.keyPredicate = checkNotNull(keyPredicate);
- }
-
- @Override
- Predicate<? super Entry<K, V>> entryPredicate() {
- return Predicates.compose(keyPredicate, Maps.<K>keyFunction());
- }
-
- @Override
- public int size() {
- int size = 0;
- for (Collection<V> collection : asMap().values()) {
- size += collection.size();
- }
- return size;
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- if (unfiltered.containsKey(key)) {
- @SuppressWarnings("unchecked") // k is equal to a K, if not one itself
- K k = (K) key;
- return keyPredicate.apply(k);
- }
- return false;
- }
-
- @Override
- public Collection<V> removeAll(Object key) {
- return containsKey(key) ? unfiltered.removeAll(key) : unmodifiableEmptyCollection();
- }
-
- Collection<V> unmodifiableEmptyCollection() {
- if (unfiltered instanceof SetMultimap) {
- return ImmutableSet.of();
- } else {
- return ImmutableList.of();
- }
- }
-
- @Override
- public void clear() {
- keySet().clear();
- }
-
- @Override
- Set<K> createKeySet() {
- return Sets.filter(unfiltered.keySet(), keyPredicate);
- }
-
- @Override
- public Collection<V> get(K key) {
- if (keyPredicate.apply(key)) {
- return unfiltered.get(key);
- } else if (unfiltered instanceof SetMultimap) {
- return new AddRejectingSet<K, V>(key);
- } else {
- return new AddRejectingList<K, V>(key);
- }
- }
-
- static class AddRejectingSet<K, V> extends ForwardingSet<V> {
- final K key;
-
- AddRejectingSet(K key) {
- this.key = key;
- }
-
- @Override
- public boolean add(V element) {
- throw new IllegalArgumentException("Key does not satisfy predicate: " + key);
- }
-
- @Override
- public boolean addAll(Collection<? extends V> collection) {
- checkNotNull(collection);
- throw new IllegalArgumentException("Key does not satisfy predicate: " + key);
- }
-
- @Override
- protected Set<V> delegate() {
- return Collections.emptySet();
- }
- }
-
- static class AddRejectingList<K, V> extends ForwardingList<V> {
- final K key;
-
- AddRejectingList(K key) {
- this.key = key;
- }
-
- @Override
- public boolean add(V v) {
- add(0, v);
- return true;
- }
-
- @Override
- public boolean addAll(Collection<? extends V> collection) {
- addAll(0, collection);
- return true;
- }
-
- @Override
- public void add(int index, V element) {
- checkPositionIndex(index, 0);
- throw new IllegalArgumentException("Key does not satisfy predicate: " + key);
- }
-
- @Override
- public boolean addAll(int index, Collection<? extends V> elements) {
- checkNotNull(elements);
- checkPositionIndex(index, 0);
- throw new IllegalArgumentException("Key does not satisfy predicate: " + key);
- }
-
- @Override
- protected List<V> delegate() {
- return Collections.emptyList();
- }
- }
-
- @Override
- Iterator<Entry<K, V>> entryIterator() {
- return Iterators.filter(
- unfiltered.entries().iterator(), Predicates.compose(keyPredicate, Maps.<K>keyFunction()));
- }
-
- @Override
- Collection<Entry<K, V>> createEntries() {
- return new Multimaps.Entries<K, V>() {
- @Override
- Multimap<K, V> multimap() {
- return FilteredKeyMultimap.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return entryIterator();
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public boolean remove(@Nullable Object o) {
- if (o instanceof Entry) {
- Entry<?, ?> entry = (Entry<?, ?>) o;
- if (unfiltered.containsEntry(entry.getKey(), entry.getValue())
- && keyPredicate.apply((K) entry.getKey())) {
- return unfiltered.remove(entry.getKey(), entry.getValue());
- }
- }
- return false;
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- Predicate<Entry<K, ?>> combinedPredicate = Predicates.and(
- Predicates.compose(keyPredicate, Maps.<K>keyFunction()), Predicates.in(c));
- return Iterators.removeIf(unfiltered.entries().iterator(), combinedPredicate);
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- Predicate<Entry<K, ?>> combinedPredicate = Predicates.and(
- Predicates.compose(keyPredicate, Maps.<K>keyFunction()),
- Predicates.not(Predicates.in(c)));
- return Iterators.removeIf(unfiltered.entries().iterator(), combinedPredicate);
- }
- };
- }
-
- @Override
- Map<K, Collection<V>> createAsMap() {
- return Maps.filterKeys(unfiltered.asMap(), keyPredicate);
- }
-
- @Override
- Multiset<K> createKeys() {
- return Multisets.filter(unfiltered.keys(), keyPredicate);
- }
-}
diff --git a/guava/src/com/google/common/collect/FilteredMultimap.java b/guava/src/com/google/common/collect/FilteredMultimap.java
deleted file mode 100644
index d7d2b3b..0000000
--- a/guava/src/com/google/common/collect/FilteredMultimap.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Predicate;
-
-import java.util.Map.Entry;
-
-/**
- * A superclass of all filtered multimap types.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-abstract class FilteredMultimap<K, V> extends AbstractMultimap<K, V> {
- final Multimap<K, V> unfiltered;
-
- FilteredMultimap(Multimap<K, V> unfiltered) {
- this.unfiltered = checkNotNull(unfiltered);
- }
-
- abstract Predicate<? super Entry<K, V>> entryPredicate();
-}
diff --git a/guava/src/com/google/common/collect/FluentIterable.java b/guava/src/com/google/common/collect/FluentIterable.java
deleted file mode 100644
index 2469180..0000000
--- a/guava/src/com/google/common/collect/FluentIterable.java
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.SortedSet;
-
-import javax.annotation.Nullable;
-
-/**
- * {@code FluentIterable} provides a rich interface for manipulating {@code Iterable} instances in a
- * chained fashion. A {@code FluentIterable} can be created from an {@code Iterable}, or from a set
- * of elements. The following types of methods are provided on {@code FluentIterable}:
- * <ul>
- * <li>chained methods which return a new {@code FluentIterable} based in some way on the contents
- * of the current one (for example {@link #transform})
- * <li>conversion methods which copy the {@code FluentIterable}'s contents into a new collection or
- * array (for example {@link #toList})
- * <li>element extraction methods which facilitate the retrieval of certain elements (for example
- * {@link #last})
- * <li>query methods which answer questions about the {@code FluentIterable}'s contents (for example
- * {@link #anyMatch})
- * </ul>
- *
- * <p>Here is an example that merges the lists returned by two separate database calls, transforms
- * it by invoking {@code toString()} on each element, and returns the first 10 elements as an
- * {@code ImmutableList}: <pre> {@code
- *
- * FluentIterable
- * .from(database.getClientList())
- * .filter(activeInLastMonth())
- * .transform(Functions.toStringFunction())
- * .limit(10)
- * .toList();}</pre>
- *
- * Anything which can be done using {@code FluentIterable} could be done in a different fashion
- * (often with {@link Iterables}), however the use of {@code FluentIterable} makes many sets of
- * operations significantly more concise.
- *
- * @author Marcin Mikosik
- * @since 12.0
- */
-@GwtCompatible(emulated = true)
-public abstract class FluentIterable<E> implements Iterable<E> {
- // We store 'iterable' and use it instead of 'this' to allow Iterables to perform instanceof
- // checks on the _original_ iterable when FluentIterable.from is used.
- private final Iterable<E> iterable;
-
- /** Constructor for use by subclasses. */
- protected FluentIterable() {
- this.iterable = this;
- }
-
- FluentIterable(Iterable<E> iterable) {
- this.iterable = checkNotNull(iterable);
- }
-
- /**
- * Returns a fluent iterable that wraps {@code iterable}, or {@code iterable} itself if it
- * is already a {@code FluentIterable}.
- */
- public static <E> FluentIterable<E> from(final Iterable<E> iterable) {
- return (iterable instanceof FluentIterable) ? (FluentIterable<E>) iterable
- : new FluentIterable<E>(iterable) {
- @Override
- public Iterator<E> iterator() {
- return iterable.iterator();
- }
- };
- }
-
- /**
- * Construct a fluent iterable from another fluent iterable. This is obviously never necessary,
- * but is intended to help call out cases where one migration from {@code Iterable} to
- * {@code FluentIterable} has obviated the need to explicitly convert to a {@code FluentIterable}.
- *
- * @deprecated instances of {@code FluentIterable} don't need to be converted to
- * {@code FluentIterable}
- */
- @Deprecated
- public static <E> FluentIterable<E> from(FluentIterable<E> iterable) {
- return checkNotNull(iterable);
- }
-
- /**
- * Returns a string representation of this fluent iterable, with the format
- * {@code [e1, e2, ..., en]}.
- */
- @Override
- public String toString() {
- return Iterables.toString(iterable);
- }
-
- /**
- * Returns the number of elements in this fluent iterable.
- */
- public final int size() {
- return Iterables.size(iterable);
- }
-
- /**
- * Returns {@code true} if this fluent iterable contains any object for which
- * {@code equals(element)} is true.
- */
- public final boolean contains(@Nullable Object element) {
- return Iterables.contains(iterable, element);
- }
-
- /**
- * Returns a fluent iterable whose {@code Iterator} cycles indefinitely over the elements of
- * this fluent iterable.
- *
- * <p>That iterator supports {@code remove()} if {@code iterable.iterator()} does. After
- * {@code remove()} is called, subsequent cycles omit the removed element, which is no longer in
- * this fluent iterable. The iterator's {@code hasNext()} method returns {@code true} until
- * this fluent iterable is empty.
- *
- * <p><b>Warning:</b> Typical uses of the resulting iterator may produce an infinite loop. You
- * should use an explicit {@code break} or be certain that you will eventually remove all the
- * elements.
- */
- public final FluentIterable<E> cycle() {
- return from(Iterables.cycle(iterable));
- }
-
- /**
- * Returns the elements from this fluent iterable that satisfy a predicate. The
- * resulting fluent iterable's iterator does not support {@code remove()}.
- */
- public final FluentIterable<E> filter(Predicate<? super E> predicate) {
- return from(Iterables.filter(iterable, predicate));
- }
-
- /**
- * Returns the elements from this fluent iterable that are instances of class {@code type}.
- *
- * @param type the type of elements desired
- */
- @GwtIncompatible("Class.isInstance")
- public final <T> FluentIterable<T> filter(Class<T> type) {
- return from(Iterables.filter(iterable, type));
- }
-
- /**
- * Returns {@code true} if any element in this fluent iterable satisfies the predicate.
- */
- public final boolean anyMatch(Predicate<? super E> predicate) {
- return Iterables.any(iterable, predicate);
- }
-
- /**
- * Returns {@code true} if every element in this fluent iterable satisfies the predicate.
- * If this fluent iterable is empty, {@code true} is returned.
- */
- public final boolean allMatch(Predicate<? super E> predicate) {
- return Iterables.all(iterable, predicate);
- }
-
- /**
- * Returns an {@link Optional} containing the first element in this fluent iterable that
- * satisfies the given predicate, if such an element exists.
- *
- * <p><b>Warning:</b> avoid using a {@code predicate} that matches {@code null}. If {@code null}
- * is matched in this fluent iterable, a {@link NullPointerException} will be thrown.
- */
- public final Optional<E> firstMatch(Predicate<? super E> predicate) {
- return Iterables.tryFind(iterable, predicate);
- }
-
- /**
- * Returns a fluent iterable that applies {@code function} to each element of this
- * fluent iterable.
- *
- * <p>The returned fluent iterable's iterator supports {@code remove()} if this iterable's
- * iterator does. After a successful {@code remove()} call, this fluent iterable no longer
- * contains the corresponding element.
- */
- public final <T> FluentIterable<T> transform(Function<? super E, T> function) {
- return from(Iterables.transform(iterable, function));
- }
-
- /**
- * Applies {@code function} to each element of this fluent iterable and returns
- * a fluent iterable with the concatenated combination of results. {@code function}
- * returns an Iterable of results.
- *
- * <p>The returned fluent iterable's iterator supports {@code remove()} if this
- * function-returned iterables' iterator does. After a successful {@code remove()} call,
- * the returned fluent iterable no longer contains the corresponding element.
- *
- * @since 13.0 (required {@code Function<E, Iterable<T>>} until 14.0)
- */
- public <T> FluentIterable<T> transformAndConcat(
- Function<? super E, ? extends Iterable<? extends T>> function) {
- return from(Iterables.concat(transform(function)));
- }
-
- /**
- * Returns an {@link Optional} containing the first element in this fluent iterable.
- * If the iterable is empty, {@code Optional.absent()} is returned.
- *
- * @throws NullPointerException if the first element is null; if this is a possibility, use
- * {@code iterator().next()} or {@link Iterables#getFirst} instead.
- */
- public final Optional<E> first() {
- Iterator<E> iterator = iterable.iterator();
- return iterator.hasNext()
- ? Optional.of(iterator.next())
- : Optional.<E>absent();
- }
-
- /**
- * Returns an {@link Optional} containing the last element in this fluent iterable.
- * If the iterable is empty, {@code Optional.absent()} is returned.
- *
- * @throws NullPointerException if the last element is null; if this is a possibility, use
- * {@link Iterables#getLast} instead.
- */
- public final Optional<E> last() {
- // Iterables#getLast was inlined here so we don't have to throw/catch a NSEE
-
- // TODO(kevinb): Support a concurrently modified collection?
- if (iterable instanceof List) {
- List<E> list = (List<E>) iterable;
- if (list.isEmpty()) {
- return Optional.absent();
- }
- return Optional.of(list.get(list.size() - 1));
- }
- Iterator<E> iterator = iterable.iterator();
- if (!iterator.hasNext()) {
- return Optional.absent();
- }
-
- /*
- * TODO(kevinb): consider whether this "optimization" is worthwhile. Users
- * with SortedSets tend to know they are SortedSets and probably would not
- * call this method.
- */
- if (iterable instanceof SortedSet) {
- SortedSet<E> sortedSet = (SortedSet<E>) iterable;
- return Optional.of(sortedSet.last());
- }
-
- while (true) {
- E current = iterator.next();
- if (!iterator.hasNext()) {
- return Optional.of(current);
- }
- }
- }
-
- /**
- * Returns a view of this fluent iterable that skips its first {@code numberToSkip}
- * elements. If this fluent iterable contains fewer than {@code numberToSkip} elements,
- * the returned fluent iterable skips all of its elements.
- *
- * <p>Modifications to this fluent iterable before a call to {@code iterator()} are
- * reflected in the returned fluent iterable. That is, the its iterator skips the first
- * {@code numberToSkip} elements that exist when the iterator is created, not when {@code skip()}
- * is called.
- *
- * <p>The returned fluent iterable's iterator supports {@code remove()} if the
- * {@code Iterator} of this fluent iterable supports it. Note that it is <i>not</i>
- * possible to delete the last skipped element by immediately calling {@code remove()} on the
- * returned fluent iterable's iterator, as the {@code Iterator} contract states that a call
- * to {@code * remove()} before a call to {@code next()} will throw an
- * {@link IllegalStateException}.
- */
- public final FluentIterable<E> skip(int numberToSkip) {
- return from(Iterables.skip(iterable, numberToSkip));
- }
-
- /**
- * Creates a fluent iterable with the first {@code size} elements of this
- * fluent iterable. If this fluent iterable does not contain that many elements,
- * the returned fluent iterable will have the same behavior as this fluent iterable.
- * The returned fluent iterable's iterator supports {@code remove()} if this
- * fluent iterable's iterator does.
- *
- * @param size the maximum number of elements in the returned fluent iterable
- * @throws IllegalArgumentException if {@code size} is negative
- */
- public final FluentIterable<E> limit(int size) {
- return from(Iterables.limit(iterable, size));
- }
-
- /**
- * Determines whether this fluent iterable is empty.
- */
- public final boolean isEmpty() {
- return !iterable.iterator().hasNext();
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this fluent iterable in
- * proper sequence.
- *
- * @since 14.0 (since 12.0 as {@code toImmutableList()}).
- */
- public final ImmutableList<E> toList() {
- return ImmutableList.copyOf(iterable);
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this {@code
- * FluentIterable} in the order specified by {@code comparator}. To produce an {@code
- * ImmutableList} sorted by its natural ordering, use {@code toSortedList(Ordering.natural())}.
- *
- * @param comparator the function by which to sort list elements
- * @throws NullPointerException if any element is null
- * @since 14.0 (since 13.0 as {@code toSortedImmutableList()}).
- */
- @Beta
- public final ImmutableList<E> toSortedList(Comparator<? super E> comparator) {
- return Ordering.from(comparator).immutableSortedCopy(iterable);
- }
-
- /**
- * Returns an {@code ImmutableSet} containing all of the elements from this fluent iterable with
- * duplicates removed.
- *
- * @since 14.0 (since 12.0 as {@code toImmutableSet()}).
- */
- public final ImmutableSet<E> toSet() {
- return ImmutableSet.copyOf(iterable);
- }
-
- /**
- * Returns an {@code ImmutableSortedSet} containing all of the elements from this {@code
- * FluentIterable} in the order specified by {@code comparator}, with duplicates (determined by
- * {@code comparator.compare(x, y) == 0}) removed. To produce an {@code ImmutableSortedSet} sorted
- * by its natural ordering, use {@code toSortedSet(Ordering.natural())}.
- *
- * @param comparator the function by which to sort set elements
- * @throws NullPointerException if any element is null
- * @since 14.0 (since 12.0 as {@code toImmutableSortedSet()}).
- */
- public final ImmutableSortedSet<E> toSortedSet(Comparator<? super E> comparator) {
- return ImmutableSortedSet.copyOf(comparator, iterable);
- }
-
- /**
- * Returns an immutable map for which the elements of this {@code FluentIterable} are the keys in
- * the same order, mapped to values by the given function. If this iterable contains duplicate
- * elements, the returned map will contain each distinct element once in the order it first
- * appears.
- *
- * @throws NullPointerException if any element of this iterable is {@code null}, or if {@code
- * valueFunction} produces {@code null} for any key
- * @since 14.0
- */
- public final <V> ImmutableMap<E, V> toMap(Function<? super E, V> valueFunction) {
- return Maps.toMap(iterable, valueFunction);
- }
-
- /**
- * Creates an index {@code ImmutableListMultimap} that contains the results of applying a
- * specified function to each item in this {@code FluentIterable} of values. Each element of this
- * iterable will be stored as a value in the resulting multimap, yielding a multimap with the same
- * size as this iterable. The key used to store that value in the multimap will be the result of
- * calling the function on that value. The resulting multimap is created as an immutable snapshot.
- * In the returned multimap, keys appear in the order they are first encountered, and the values
- * corresponding to each key appear in the same order as they are encountered.
- *
- * @param keyFunction the function used to produce the key for each value
- * @throws NullPointerException if any of the following cases is true:
- * <ul>
- * <li>{@code keyFunction} is null
- * <li>An element in this fluent iterable is null
- * <li>{@code keyFunction} returns {@code null} for any element of this iterable
- * </ul>
- * @since 14.0
- */
- public final <K> ImmutableListMultimap<K, E> index(Function<? super E, K> keyFunction) {
- return Multimaps.index(iterable, keyFunction);
- }
-
- /**
- * Returns an immutable map for which the {@link java.util.Map#values} are the elements of this
- * {@code FluentIterable} in the given order, and each key is the product of invoking a supplied
- * function on its corresponding value.
- *
- * @param keyFunction the function used to produce the key for each value
- * @throws IllegalArgumentException if {@code keyFunction} produces the same key for more than one
- * value in this fluent iterable
- * @throws NullPointerException if any element of this fluent iterable is null, or if
- * {@code keyFunction} produces {@code null} for any value
- * @since 14.0
- */
- public final <K> ImmutableMap<K, E> uniqueIndex(Function<? super E, K> keyFunction) {
- return Maps.uniqueIndex(iterable, keyFunction);
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this
- * fluent iterable in proper sequence.
- *
- * @deprecated Use {@link #toList()} instead. This method is scheduled for removal in Guava 15.0.
- */
- @Deprecated
- public final ImmutableList<E> toImmutableList() {
- return toList();
- }
-
- /**
- * Returns an {@code ImmutableList} containing all of the elements from this
- * {@code FluentIterable} in the order specified by {@code comparator}. To produce an
- * {@code ImmutableList} sorted by its natural ordering, use
- * {@code toSortedImmutableList(Ordering.natural())}.
- *
- * @param comparator the function by which to sort list elements
- * @throws NullPointerException if any element is null
- * @since 13.0
- * @deprecated Use {@link #toSortedList(Comparator)} instead. This method is scheduled for removal
- * in Guava 15.0.
- */
- @Deprecated
- public final ImmutableList<E> toSortedImmutableList(Comparator<? super E> comparator) {
- return toSortedList(comparator);
- }
-
- /**
- * Returns an {@code ImmutableSet} containing all of the elements from this
- * fluent iterable with duplicates removed.
- *
- * @deprecated Use {@link #toSet()} instead. This method is scheduled for removal in Guava 15.0.
- */
- @Deprecated
- public final ImmutableSet<E> toImmutableSet() {
- return toSet();
- }
-
- /**
- * Returns an {@code ImmutableSortedSet} containing all of the elements from this
- * {@code FluentIterable} in the order specified by {@code comparator}, with duplicates
- * (determined by {@code comparator.compare(x, y) == 0}) removed. To produce an
- * {@code ImmutableSortedSet} sorted by its natural ordering, use
- * {@code toImmutableSortedSet(Ordering.natural())}.
- *
- * @param comparator the function by which to sort set elements
- * @throws NullPointerException if any element is null
- * @deprecated Use {@link #toSortedSet(Comparator)} instead. This method is scheduled for removal
- * in Guava 15.0.
- */
- @Deprecated
- public final ImmutableSortedSet<E> toImmutableSortedSet(Comparator<? super E> comparator) {
- return toSortedSet(comparator);
- }
-
- /**
- * Returns an array containing all of the elements from this fluent iterable in iteration order.
- *
- * @param type the type of the elements
- * @return a newly-allocated array into which all the elements of this fluent iterable have
- * been copied
- */
- @GwtIncompatible("Array.newArray(Class, int)")
- public final E[] toArray(Class<E> type) {
- return Iterables.toArray(iterable, type);
- }
-
- /**
- * Copies all the elements from this fluent iterable to {@code collection}. This is equivalent to
- * calling {@code Iterables.addAll(collection, this)}.
- *
- * @param collection the collection to copy elements to
- * @return {@code collection}, for convenience
- * @since 14.0
- */
- public final <C extends Collection<? super E>> C copyInto(C collection) {
- checkNotNull(collection);
- if (iterable instanceof Collection) {
- collection.addAll(Collections2.cast(iterable));
- } else {
- for (E item : iterable) {
- collection.add(item);
- }
- }
- return collection;
- }
-
- /**
- * Returns the element at the specified position in this fluent iterable.
- *
- * @param position position of the element to return
- * @return the element at the specified position in this fluent iterable
- * @throws IndexOutOfBoundsException if {@code position} is negative or greater than or equal to
- * the size of this fluent iterable
- */
- public final E get(int position) {
- return Iterables.get(iterable, position);
- }
-
- /**
- * Function that transforms {@code Iterable<E>} into a fluent iterable.
- */
- private static class FromIterableFunction<E>
- implements Function<Iterable<E>, FluentIterable<E>> {
- @Override
- public FluentIterable<E> apply(Iterable<E> fromObject) {
- return FluentIterable.from(fromObject);
- }
- }
-}
diff --git a/guava/src/com/google/common/collect/ForwardingBlockingDeque.java b/guava/src/com/google/common/collect/ForwardingBlockingDeque.java
deleted file mode 100644
index a6fb43d..0000000
--- a/guava/src/com/google/common/collect/ForwardingBlockingDeque.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Collection;
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A {@link BlockingDeque} which forwards all its method calls to another {@code BlockingDeque}.
- * Subclasses should override one or more methods to modify the behavior of the backing deque as
- * desired per the <a href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
- *
- * <p><b>Warning:</b> The methods of {@code ForwardingBlockingDeque} forward
- * <b>indiscriminately</b> to the methods of the delegate. For example, overriding {@link #add}
- * alone <b>will not</b> change the behaviour of {@link #offer} which can lead to unexpected
- * behaviour. In this case, you should override {@code offer} as well, either providing your own
- * implementation, or delegating to the provided {@code standardOffer} method.
- *
- * <p>
- * The {@code standard} methods are not guaranteed to be thread-safe, even when all of the methods
- * that they depend on are thread-safe.
- *
- * @author Emily Soldal
- * @since 14.0
- */
-public abstract class ForwardingBlockingDeque<E>
- extends ForwardingDeque<E> implements BlockingDeque<E> {
-
- /** Constructor for use by subclasses. */
- protected ForwardingBlockingDeque() {}
-
- @Override protected abstract BlockingDeque<E> delegate();
-
- @Override
- public int remainingCapacity() {
- return delegate().remainingCapacity();
- }
-
- @Override
- public void putFirst(E e) throws InterruptedException {
- delegate().putFirst(e);
- }
-
- @Override
- public void putLast(E e) throws InterruptedException {
- delegate().putLast(e);
- }
-
- @Override
- public boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException {
- return delegate().offerFirst(e, timeout, unit);
- }
-
- @Override
- public boolean offerLast(E e, long timeout, TimeUnit unit) throws InterruptedException {
- return delegate().offerLast(e, timeout, unit);
- }
-
- @Override
- public E takeFirst() throws InterruptedException {
- return delegate().takeFirst();
- }
-
- @Override
- public E takeLast() throws InterruptedException {
- return delegate().takeLast();
- }
-
- @Override
- public E pollFirst(long timeout, TimeUnit unit) throws InterruptedException {
- return delegate().pollFirst(timeout, unit);
- }
-
- @Override
- public E pollLast(long timeout, TimeUnit unit) throws InterruptedException {
- return delegate().pollLast(timeout, unit);
- }
-
- @Override
- public void put(E e) throws InterruptedException {
- delegate().put(e);
- }
-
- @Override
- public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
- return delegate().offer(e, timeout, unit);
- }
-
- @Override
- public E take() throws InterruptedException {
- return delegate().take();
- }
-
- @Override
- public E poll(long timeout, TimeUnit unit) throws InterruptedException {
- return delegate().poll(timeout, unit);
- }
-
- @Override
- public int drainTo(Collection<? super E> c) {
- return delegate().drainTo(c);
- }
-
- @Override
- public int drainTo(Collection<? super E> c, int maxElements) {
- return delegate().drainTo(c, maxElements);
- }
-}
diff --git a/guava/src/com/google/common/collect/ForwardingCollection.java b/guava/src/com/google/common/collect/ForwardingCollection.java
index 79d7860..a6a46f0 100644
--- a/guava/src/com/google/common/collect/ForwardingCollection.java
+++ b/guava/src/com/google/common/collect/ForwardingCollection.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
@@ -126,7 +127,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardContains(@Nullable Object object) {
+ @Beta protected boolean standardContains(@Nullable Object object) {
return Iterators.contains(iterator(), object);
}
@@ -137,7 +138,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardContainsAll(Collection<?> collection) {
+ @Beta protected boolean standardContainsAll(Collection<?> collection) {
for (Object o : collection) {
if (!contains(o)) {
return false;
@@ -153,7 +154,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardAddAll(Collection<? extends E> collection) {
+ @Beta protected boolean standardAddAll(Collection<? extends E> collection) {
return Iterators.addAll(this, collection.iterator());
}
@@ -165,7 +166,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardRemove(@Nullable Object object) {
+ @Beta protected boolean standardRemove(@Nullable Object object) {
Iterator<E> iterator = iterator();
while (iterator.hasNext()) {
if (Objects.equal(iterator.next(), object)) {
@@ -184,7 +185,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardRemoveAll(Collection<?> collection) {
+ @Beta protected boolean standardRemoveAll(Collection<?> collection) {
return Iterators.removeAll(iterator(), collection);
}
@@ -196,7 +197,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardRetainAll(Collection<?> collection) {
+ @Beta protected boolean standardRetainAll(Collection<?> collection) {
return Iterators.retainAll(iterator(), collection);
}
@@ -208,8 +209,12 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected void standardClear() {
- Iterators.clear(iterator());
+ @Beta protected void standardClear() {
+ Iterator<E> iterator = iterator();
+ while (iterator.hasNext()) {
+ iterator.next();
+ iterator.remove();
+ }
}
/**
@@ -220,7 +225,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardIsEmpty() {
+ @Beta protected boolean standardIsEmpty() {
return !iterator().hasNext();
}
@@ -231,7 +236,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected String standardToString() {
+ @Beta protected String standardToString() {
return Collections2.toStringImpl(this);
}
@@ -242,7 +247,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected Object[] standardToArray() {
+ @Beta protected Object[] standardToArray() {
Object[] newArray = new Object[size()];
return toArray(newArray);
}
@@ -254,7 +259,7 @@ public abstract class ForwardingCollection<E> extends ForwardingObject
*
* @since 7.0
*/
- protected <T> T[] standardToArray(T[] array) {
+ @Beta protected <T> T[] standardToArray(T[] array) {
return ObjectArrays.toArrayImpl(this, array);
}
}
diff --git a/guava/src/com/google/common/collect/ForwardingDeque.java b/guava/src/com/google/common/collect/ForwardingDeque.java
deleted file mode 100644
index 070f622..0000000
--- a/guava/src/com/google/common/collect/ForwardingDeque.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.Deque;
-import java.util.Iterator;
-
-/**
- * A deque which forwards all its method calls to another deque. Subclasses
- * should override one or more methods to modify the behavior of the backing
- * deque as desired per the <a
- * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
- *
- * <p><b>Warning:</b> The methods of {@code ForwardingDeque} forward
- * <b>indiscriminately</b> to the methods of the delegate. For example,
- * overriding {@link #add} alone <b>will not</b> change the behavior of {@link
- * #offer} which can lead to unexpected behavior. In this case, you should
- * override {@code offer} as well.
- *
- * @author Kurt Alfred Kluever
- * @since 12.0
- */
-public abstract class ForwardingDeque<E> extends ForwardingQueue<E>
- implements Deque<E> {
-
- /** Constructor for use by subclasses. */
- protected ForwardingDeque() {}
-
- @Override protected abstract Deque<E> delegate();
-
- @Override
- public void addFirst(E e) {
- delegate().addFirst(e);
- }
-
- @Override
- public void addLast(E e) {
- delegate().addLast(e);
- }
-
- @Override
- public Iterator<E> descendingIterator() {
- return delegate().descendingIterator();
- }
-
- @Override
- public E getFirst() {
- return delegate().getFirst();
- }
-
- @Override
- public E getLast() {
- return delegate().getLast();
- }
-
- @Override
- public boolean offerFirst(E e) {
- return delegate().offerFirst(e);
- }
-
- @Override
- public boolean offerLast(E e) {
- return delegate().offerLast(e);
- }
-
- @Override
- public E peekFirst() {
- return delegate().peekFirst();
- }
-
- @Override
- public E peekLast() {
- return delegate().peekLast();
- }
-
- @Override
- public E pollFirst() {
- return delegate().pollFirst();
- }
-
- @Override
- public E pollLast() {
- return delegate().pollLast();
- }
-
- @Override
- public E pop() {
- return delegate().pop();
- }
-
- @Override
- public void push(E e) {
- delegate().push(e);
- }
-
- @Override
- public E removeFirst() {
- return delegate().removeFirst();
- }
-
- @Override
- public E removeLast() {
- return delegate().removeLast();
- }
-
- @Override
- public boolean removeFirstOccurrence(Object o) {
- return delegate().removeFirstOccurrence(o);
- }
-
- @Override
- public boolean removeLastOccurrence(Object o) {
- return delegate().removeLastOccurrence(o);
- }
-}
diff --git a/guava/src/com/google/common/collect/ForwardingImmutableCollection.java b/guava/src/com/google/common/collect/ForwardingImmutableCollection.java
deleted file mode 100644
index 90489a4..0000000
--- a/guava/src/com/google/common/collect/ForwardingImmutableCollection.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * Dummy class that makes the GWT serialization policy happy. It isn't used
- * on the server-side.
- *
- * @author Hayward Chan
- */
-@GwtCompatible(emulated = true)
-class ForwardingImmutableCollection {
- private ForwardingImmutableCollection() {}
-}
diff --git a/guava/src/com/google/common/collect/ForwardingImmutableList.java b/guava/src/com/google/common/collect/ForwardingImmutableList.java
deleted file mode 100644
index 2b9092e..0000000
--- a/guava/src/com/google/common/collect/ForwardingImmutableList.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * Unused stub class, unreferenced under Java and manually emulated under GWT.
- *
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-abstract class ForwardingImmutableList<E> {
- private ForwardingImmutableList() {}
-}
diff --git a/guava/src/com/google/common/collect/ForwardingImmutableSet.java b/guava/src/com/google/common/collect/ForwardingImmutableSet.java
deleted file mode 100644
index c7d7bf6..0000000
--- a/guava/src/com/google/common/collect/ForwardingImmutableSet.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * Unused stub class, unreferenced under Java and manually emulated under GWT.
- *
- * @author Chris Povirk
- */
-@GwtCompatible(emulated = true)
-abstract class ForwardingImmutableSet<E> {
- private ForwardingImmutableSet() {}
-}
diff --git a/guava/src/com/google/common/collect/ForwardingList.java b/guava/src/com/google/common/collect/ForwardingList.java
index 9f3cf1c..e59e662 100644
--- a/guava/src/com/google/common/collect/ForwardingList.java
+++ b/guava/src/com/google/common/collect/ForwardingList.java
@@ -127,7 +127,7 @@ public abstract class ForwardingList<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected boolean standardAdd(E element){
+ @Beta protected boolean standardAdd(E element){
add(size(), element);
return true;
}
@@ -140,7 +140,7 @@ public abstract class ForwardingList<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected boolean standardAddAll(
+ @Beta protected boolean standardAddAll(
int index, Iterable<? extends E> elements) {
return Lists.addAllImpl(this, index, elements);
}
@@ -152,7 +152,7 @@ public abstract class ForwardingList<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected int standardIndexOf(@Nullable Object element) {
+ @Beta protected int standardIndexOf(@Nullable Object element) {
return Lists.indexOfImpl(this, element);
}
@@ -164,7 +164,7 @@ public abstract class ForwardingList<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected int standardLastIndexOf(@Nullable Object element) {
+ @Beta protected int standardLastIndexOf(@Nullable Object element) {
return Lists.lastIndexOfImpl(this, element);
}
@@ -175,7 +175,7 @@ public abstract class ForwardingList<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected Iterator<E> standardIterator() {
+ @Beta protected Iterator<E> standardIterator() {
return listIterator();
}
@@ -187,15 +187,14 @@ public abstract class ForwardingList<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected ListIterator<E> standardListIterator() {
+ @Beta protected ListIterator<E> standardListIterator(){
return listIterator(0);
}
/**
* A sensible default implementation of {@link #listIterator(int)}, in terms
- * of {@link #size}, {@link #get(int)}, {@link #set(int, Object)}, {@link
- * #add(int, Object)}, and {@link #remove(int)}. If you override any of these
- * methods, you may wish to override {@link #listIterator(int)} to forward to
+ * of {@link #size} and {@link #get(int)}. If you override either of these
+ * methods you may wish to override {@link #listIterator(int)} to forward to
* this implementation.
*
* @since 7.0
diff --git a/guava/src/com/google/common/collect/ForwardingMap.java b/guava/src/com/google/common/collect/ForwardingMap.java
index be22230..9b3a489 100644
--- a/guava/src/com/google/common/collect/ForwardingMap.java
+++ b/guava/src/com/google/common/collect/ForwardingMap.java
@@ -86,17 +86,17 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
}
@Override
- public boolean containsKey(@Nullable Object key) {
+ public boolean containsKey(Object key) {
return delegate().containsKey(key);
}
@Override
- public boolean containsValue(@Nullable Object value) {
+ public boolean containsValue(Object value) {
return delegate().containsValue(value);
}
@Override
- public V get(@Nullable Object key) {
+ public V get(Object key) {
return delegate().get(key);
}
@@ -141,7 +141,7 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected void standardPutAll(Map<? extends K, ? extends V> map) {
+ @Beta protected void standardPutAll(Map<? extends K, ? extends V> map) {
Maps.putAllImpl(this, map);
}
@@ -177,8 +177,12 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected void standardClear() {
- Iterators.clear(entrySet().iterator());
+ @Beta protected void standardClear() {
+ Iterator<Entry<K, V>> entryIterator = entrySet().iterator();
+ while (entryIterator.hasNext()) {
+ entryIterator.next();
+ entryIterator.remove();
+ }
}
/**
@@ -194,7 +198,6 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*/
@Beta
protected class StandardKeySet extends Maps.KeySet<K, V> {
- /** Constructor for use by subclasses. */
public StandardKeySet() {}
@Override
@@ -227,7 +230,6 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*/
@Beta
protected class StandardValues extends Maps.Values<K, V> {
- /** Constructor for use by subclasses. */
public StandardValues() {}
@Override
@@ -244,7 +246,7 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardContainsValue(@Nullable Object value) {
+ @Beta protected boolean standardContainsValue(@Nullable Object value) {
return Maps.containsValueImpl(this, value);
}
@@ -260,7 +262,6 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*/
@Beta
protected abstract class StandardEntrySet extends Maps.EntrySet<K, V> {
- /** Constructor for use by subclasses. */
public StandardEntrySet() {}
@Override
@@ -276,7 +277,7 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardIsEmpty() {
+ @Beta protected boolean standardIsEmpty() {
return !entrySet().iterator().hasNext();
}
@@ -287,7 +288,7 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected boolean standardEquals(@Nullable Object object) {
+ @Beta protected boolean standardEquals(@Nullable Object object) {
return Maps.equalsImpl(this, object);
}
@@ -298,7 +299,7 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected int standardHashCode() {
+ @Beta protected int standardHashCode() {
return Sets.hashCodeImpl(entrySet());
}
@@ -309,7 +310,7 @@ public abstract class ForwardingMap<K, V> extends ForwardingObject
*
* @since 7.0
*/
- protected String standardToString() {
+ @Beta protected String standardToString() {
return Maps.toStringImpl(this);
}
}
diff --git a/guava/src/com/google/common/collect/ForwardingMapEntry.java b/guava/src/com/google/common/collect/ForwardingMapEntry.java
index 4d63757..ff201a5 100644
--- a/guava/src/com/google/common/collect/ForwardingMapEntry.java
+++ b/guava/src/com/google/common/collect/ForwardingMapEntry.java
@@ -92,7 +92,7 @@ public abstract class ForwardingMapEntry<K, V>
*
* @since 7.0
*/
- protected boolean standardEquals(@Nullable Object object) {
+ @Beta protected boolean standardEquals(@Nullable Object object) {
if (object instanceof Entry) {
Entry<?, ?> that = (Entry<?, ?>) object;
return Objects.equal(this.getKey(), that.getKey())
@@ -108,7 +108,7 @@ public abstract class ForwardingMapEntry<K, V>
*
* @since 7.0
*/
- protected int standardHashCode() {
+ @Beta protected int standardHashCode() {
K k = getKey();
V v = getValue();
return ((k == null) ? 0 : k.hashCode()) ^ ((v == null) ? 0 : v.hashCode());
diff --git a/guava/src/com/google/common/collect/ForwardingMultiset.java b/guava/src/com/google/common/collect/ForwardingMultiset.java
index 9834751..4e1ceed 100644
--- a/guava/src/com/google/common/collect/ForwardingMultiset.java
+++ b/guava/src/com/google/common/collect/ForwardingMultiset.java
@@ -107,7 +107,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- @Override protected boolean standardContains(@Nullable Object object) {
+ @Override @Beta protected boolean standardContains(@Nullable Object object) {
return count(object) > 0;
}
@@ -118,8 +118,12 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- @Override protected void standardClear() {
- Iterators.clear(entrySet().iterator());
+ @Override @Beta protected void standardClear() {
+ Iterator<Entry<E>> entryIterator = entrySet().iterator();
+ while (entryIterator.hasNext()) {
+ entryIterator.next();
+ entryIterator.remove();
+ }
}
/**
@@ -145,7 +149,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected boolean standardAdd(E element) {
+ @Beta protected boolean standardAdd(E element) {
add(element, 1);
return true;
}
@@ -171,7 +175,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- @Override protected boolean standardRemove(Object element) {
+ @Beta @Override protected boolean standardRemove(Object element) {
return remove(element, 1) > 0;
}
@@ -183,7 +187,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- @Override protected boolean standardRemoveAll(
+ @Beta @Override protected boolean standardRemoveAll(
Collection<?> elementsToRemove) {
return Multisets.removeAllImpl(this, elementsToRemove);
}
@@ -196,7 +200,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- @Override protected boolean standardRetainAll(
+ @Beta @Override protected boolean standardRetainAll(
Collection<?> elementsToRetain) {
return Multisets.retainAllImpl(this, elementsToRetain);
}
@@ -210,7 +214,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected int standardSetCount(E element, int count) {
+ @Beta protected int standardSetCount(E element, int count) {
return Multisets.setCountImpl(this, element, count);
}
@@ -222,7 +226,8 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected boolean standardSetCount(E element, int oldCount, int newCount) {
+ @Beta protected boolean standardSetCount(
+ E element, int oldCount, int newCount) {
return Multisets.setCountImpl(this, element, oldCount, newCount);
}
@@ -241,7 +246,6 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*/
@Beta
protected class StandardElementSet extends Multisets.ElementSet<E> {
- /** Constructor for use by subclasses. */
public StandardElementSet() {}
@Override
@@ -257,7 +261,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected Iterator<E> standardIterator() {
+ @Beta protected Iterator<E> standardIterator() {
return Multisets.iteratorImpl(this);
}
@@ -268,7 +272,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected int standardSize() {
+ @Beta protected int standardSize() {
return Multisets.sizeImpl(this);
}
@@ -280,7 +284,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected boolean standardEquals(@Nullable Object object) {
+ @Beta protected boolean standardEquals(@Nullable Object object) {
return Multisets.equalsImpl(this, object);
}
@@ -291,7 +295,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected int standardHashCode() {
+ @Beta protected int standardHashCode() {
return entrySet().hashCode();
}
@@ -302,7 +306,7 @@ public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- @Override protected String standardToString() {
+ @Beta @Override protected String standardToString() {
return entrySet().toString();
}
}
diff --git a/guava/src/com/google/common/collect/ForwardingNavigableMap.java b/guava/src/com/google/common/collect/ForwardingNavigableMap.java
deleted file mode 100644
index 8f371ff..0000000
--- a/guava/src/com/google/common/collect/ForwardingNavigableMap.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.Maps.keyOrNull;
-
-import com.google.common.annotations.Beta;
-
-import java.util.Iterator;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.NoSuchElementException;
-import java.util.SortedMap;
-
-/**
- * A navigable map which forwards all its method calls to another navigable map. Subclasses should
- * override one or more methods to modify the behavior of the backing map as desired per the <a
- * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
- *
- * <p><i>Warning:</i> The methods of {@code ForwardingNavigableMap} forward <i>indiscriminately</i>
- * to the methods of the delegate. For example, overriding {@link #put} alone <i>will not</i>
- * change the behavior of {@link #putAll}, which can lead to unexpected behavior. In this case, you
- * should override {@code putAll} as well, either providing your own implementation, or delegating
- * to the provided {@code standardPutAll} method.
- *
- * <p>Each of the {@code standard} methods uses the map's comparator (or the natural ordering of
- * the elements, if there is no comparator) to test element equality. As a result, if the comparator
- * is not consistent with equals, some of the standard implementations may violate the {@code Map}
- * contract.
- *
- * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
- * thread-safe, even when all of the methods that they depend on are thread-safe.
- *
- * @author Louis Wasserman
- * @since 12.0
- */
-public abstract class ForwardingNavigableMap<K, V>
- extends ForwardingSortedMap<K, V> implements NavigableMap<K, V> {
-
- /** Constructor for use by subclasses. */
- protected ForwardingNavigableMap() {}
-
- @Override
- protected abstract NavigableMap<K, V> delegate();
-
- @Override
- public Entry<K, V> lowerEntry(K key) {
- return delegate().lowerEntry(key);
- }
-
- /**
- * A sensible definition of {@link #lowerEntry} in terms of the {@code lastEntry()} of
- * {@link #headMap(Object, boolean)}. If you override {@code headMap}, you may wish to override
- * {@code lowerEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardLowerEntry(K key) {
- return headMap(key, false).lastEntry();
- }
-
- @Override
- public K lowerKey(K key) {
- return delegate().lowerKey(key);
- }
-
- /**
- * A sensible definition of {@link #lowerKey} in terms of {@code lowerEntry}. If you override
- * {@link #lowerEntry}, you may wish to override {@code lowerKey} to forward to this
- * implementation.
- */
- protected K standardLowerKey(K key) {
- return keyOrNull(lowerEntry(key));
- }
-
- @Override
- public Entry<K, V> floorEntry(K key) {
- return delegate().floorEntry(key);
- }
-
- /**
- * A sensible definition of {@link #floorEntry} in terms of the {@code lastEntry()} of
- * {@link #headMap(Object, boolean)}. If you override {@code headMap}, you may wish to override
- * {@code floorEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardFloorEntry(K key) {
- return headMap(key, true).lastEntry();
- }
-
- @Override
- public K floorKey(K key) {
- return delegate().floorKey(key);
- }
-
- /**
- * A sensible definition of {@link #floorKey} in terms of {@code floorEntry}. If you override
- * {@code floorEntry}, you may wish to override {@code floorKey} to forward to this
- * implementation.
- */
- protected K standardFloorKey(K key) {
- return keyOrNull(floorEntry(key));
- }
-
- @Override
- public Entry<K, V> ceilingEntry(K key) {
- return delegate().ceilingEntry(key);
- }
-
- /**
- * A sensible definition of {@link #ceilingEntry} in terms of the {@code firstEntry()} of
- * {@link #tailMap(Object, boolean)}. If you override {@code tailMap}, you may wish to override
- * {@code ceilingEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardCeilingEntry(K key) {
- return tailMap(key, true).firstEntry();
- }
-
- @Override
- public K ceilingKey(K key) {
- return delegate().ceilingKey(key);
- }
-
- /**
- * A sensible definition of {@link #ceilingKey} in terms of {@code ceilingEntry}. If you override
- * {@code ceilingEntry}, you may wish to override {@code ceilingKey} to forward to this
- * implementation.
- */
- protected K standardCeilingKey(K key) {
- return keyOrNull(ceilingEntry(key));
- }
-
- @Override
- public Entry<K, V> higherEntry(K key) {
- return delegate().higherEntry(key);
- }
-
- /**
- * A sensible definition of {@link #higherEntry} in terms of the {@code firstEntry()} of
- * {@link #tailMap(Object, boolean)}. If you override {@code tailMap}, you may wish to override
- * {@code higherEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardHigherEntry(K key) {
- return tailMap(key, false).firstEntry();
- }
-
- @Override
- public K higherKey(K key) {
- return delegate().higherKey(key);
- }
-
- /**
- * A sensible definition of {@link #higherKey} in terms of {@code higherEntry}. If you override
- * {@code higherEntry}, you may wish to override {@code higherKey} to forward to this
- * implementation.
- */
- protected K standardHigherKey(K key) {
- return keyOrNull(higherEntry(key));
- }
-
- @Override
- public Entry<K, V> firstEntry() {
- return delegate().firstEntry();
- }
-
- /**
- * A sensible definition of {@link #firstEntry} in terms of the {@code iterator()} of
- * {@link #entrySet}. If you override {@code entrySet}, you may wish to override
- * {@code firstEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardFirstEntry() {
- return Iterables.getFirst(entrySet(), null);
- }
-
- /**
- * A sensible definition of {@link #firstKey} in terms of {@code firstEntry}. If you override
- * {@code firstEntry}, you may wish to override {@code firstKey} to forward to this
- * implementation.
- */
- protected K standardFirstKey() {
- Entry<K, V> entry = firstEntry();
- if (entry == null) {
- throw new NoSuchElementException();
- } else {
- return entry.getKey();
- }
- }
-
- @Override
- public Entry<K, V> lastEntry() {
- return delegate().lastEntry();
- }
-
- /**
- * A sensible definition of {@link #lastEntry} in terms of the {@code iterator()} of the
- * {@link #entrySet} of {@link #descendingMap}. If you override {@code descendingMap}, you may
- * wish to override {@code lastEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardLastEntry() {
- return Iterables.getFirst(descendingMap().entrySet(), null);
- }
-
- /**
- * A sensible definition of {@link #lastKey} in terms of {@code lastEntry}. If you override
- * {@code lastEntry}, you may wish to override {@code lastKey} to forward to this implementation.
- */
- protected K standardLastKey() {
- Entry<K, V> entry = lastEntry();
- if (entry == null) {
- throw new NoSuchElementException();
- } else {
- return entry.getKey();
- }
- }
-
- @Override
- public Entry<K, V> pollFirstEntry() {
- return delegate().pollFirstEntry();
- }
-
- /**
- * A sensible definition of {@link #pollFirstEntry} in terms of the {@code iterator} of
- * {@code entrySet}. If you override {@code entrySet}, you may wish to override
- * {@code pollFirstEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardPollFirstEntry() {
- return Iterators.pollNext(entrySet().iterator());
- }
-
- @Override
- public Entry<K, V> pollLastEntry() {
- return delegate().pollLastEntry();
- }
-
- /**
- * A sensible definition of {@link #pollFirstEntry} in terms of the {@code iterator} of the
- * {@code entrySet} of {@code descendingMap}. If you override {@code descendingMap}, you may wish
- * to override {@code pollFirstEntry} to forward to this implementation.
- */
- protected Entry<K, V> standardPollLastEntry() {
- return Iterators.pollNext(descendingMap().entrySet().iterator());
- }
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- return delegate().descendingMap();
- }
-
- /**
- * A sensible implementation of {@link NavigableMap#descendingMap} in terms of the methods of
- * this {@code NavigableMap}. In many cases, you may wish to override
- * {@link ForwardingNavigableMap#descendingMap} to forward to this implementation or a subclass
- * thereof.
- *
- * <p>In particular, this map iterates over entries with repeated calls to
- * {@link NavigableMap#lowerEntry}. If a more efficient means of iteration is available, you may
- * wish to override the {@code entryIterator()} method of this class.
- *
- * @since 12.0
- */
- @Beta
- protected class StandardDescendingMap extends Maps.DescendingMap<K, V> {
- /** Constructor for use by subclasses. */
- public StandardDescendingMap() {}
-
- @Override
- NavigableMap<K, V> forward() {
- return ForwardingNavigableMap.this;
- }
-
- @Override
- protected Iterator<Entry<K, V>> entryIterator() {
- return new Iterator<Entry<K, V>>() {
- private Entry<K, V> toRemove = null;
- private Entry<K, V> nextOrNull = forward().lastEntry();
-
- @Override
- public boolean hasNext() {
- return nextOrNull != null;
- }
-
- @Override
- public java.util.Map.Entry<K, V> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- try {
- return nextOrNull;
- } finally {
- toRemove = nextOrNull;
- nextOrNull = forward().lowerEntry(nextOrNull.getKey());
- }
- }
-
- @Override
- public void remove() {
- Iterators.checkRemove(toRemove != null);
- forward().remove(toRemove.getKey());
- toRemove = null;
- }
- };
- }
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return delegate().navigableKeySet();
- }
-
- /**
- * A sensible implementation of {@link NavigableMap#navigableKeySet} in terms of the methods of
- * this {@code NavigableMap}. In many cases, you may wish to override
- * {@link ForwardingNavigableMap#navigableKeySet} to forward to this implementation or a subclass
- * thereof.
- *
- * @since 12.0
- */
- @Beta
- protected class StandardNavigableKeySet extends Maps.NavigableKeySet<K, V> {
- /** Constructor for use by subclasses. */
- public StandardNavigableKeySet() {
- super(ForwardingNavigableMap.this);
- }
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return delegate().descendingKeySet();
- }
-
- /**
- * A sensible definition of {@link #descendingKeySet} as the {@code navigableKeySet} of
- * {@link #descendingMap}. (The {@link StandardDescendingMap} implementation implements
- * {@code navigableKeySet} on its own, so as not to cause an infinite loop.) If you override
- * {@code descendingMap}, you may wish to override {@code descendingKeySet} to forward to this
- * implementation.
- */
- @Beta
- protected NavigableSet<K> standardDescendingKeySet() {
- return descendingMap().navigableKeySet();
- }
-
- /**
- * A sensible definition of {@link #subMap(Object, Object)} in terms of
- * {@link #subMap(Object, boolean, Object, boolean)}. If you override
- * {@code subMap(K, boolean, K, boolean)}, you may wish to override {@code subMap} to forward to
- * this implementation.
- */
- @Override
- protected SortedMap<K, V> standardSubMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override
- public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive);
- }
-
- @Override
- public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- return delegate().headMap(toKey, inclusive);
- }
-
- @Override
- public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- return delegate().tailMap(fromKey, inclusive);
- }
-
- /**
- * A sensible definition of {@link #headMap(Object)} in terms of
- * {@link #headMap(Object, boolean)}. If you override {@code headMap(K, boolean)}, you may wish
- * to override {@code headMap} to forward to this implementation.
- */
- protected SortedMap<K, V> standardHeadMap(K toKey) {
- return headMap(toKey, false);
- }
-
- /**
- * A sensible definition of {@link #tailMap(Object)} in terms of
- * {@link #tailMap(Object, boolean)}. If you override {@code tailMap(K, boolean)}, you may wish
- * to override {@code tailMap} to forward to this implementation.
- */
- protected SortedMap<K, V> standardTailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-}
diff --git a/guava/src/com/google/common/collect/ForwardingNavigableSet.java b/guava/src/com/google/common/collect/ForwardingNavigableSet.java
deleted file mode 100644
index dff5ea0..0000000
--- a/guava/src/com/google/common/collect/ForwardingNavigableSet.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.Beta;
-
-import java.util.Iterator;
-import java.util.NavigableSet;
-import java.util.SortedSet;
-
-/**
- * A navigable set which forwards all its method calls to another navigable set. Subclasses should
- * override one or more methods to modify the behavior of the backing set as desired per the <a
- * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
- *
- * <p><i>Warning:</i> The methods of {@code ForwardingNavigableSet} forward <i>indiscriminately</i>
- * to the methods of the delegate. For example, overriding {@link #add} alone <i>will not</i>
- * change the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you
- * should override {@code addAll} as well, either providing your own implementation, or delegating
- * to the provided {@code standardAddAll} method.
- *
- * <p>Each of the {@code standard} methods uses the set's comparator (or the natural ordering of
- * the elements, if there is no comparator) to test element equality. As a result, if the
- * comparator is not consistent with equals, some of the standard implementations may violate the
- * {@code Set} contract.
- *
- * <p>The {@code standard} methods and the collection views they return are not guaranteed to be
- * thread-safe, even when all of the methods that they depend on are thread-safe.
- *
- * @author Louis Wasserman
- * @since 12.0
- */
-public abstract class ForwardingNavigableSet<E>
- extends ForwardingSortedSet<E> implements NavigableSet<E> {
-
- /** Constructor for use by subclasses. */
- protected ForwardingNavigableSet() {}
-
- @Override
- protected abstract NavigableSet<E> delegate();
-
- @Override
- public E lower(E e) {
- return delegate().lower(e);
- }
-
- /**
- * A sensible definition of {@link #lower} in terms of the {@code descendingIterator} method of
- * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
- * wish to override {@link #lower} to forward to this implementation.
- */
- protected E standardLower(E e) {
- return Iterators.getNext(headSet(e, false).descendingIterator(), null);
- }
-
- @Override
- public E floor(E e) {
- return delegate().floor(e);
- }
-
- /**
- * A sensible definition of {@link #floor} in terms of the {@code descendingIterator} method of
- * {@link #headSet(Object, boolean)}. If you override {@link #headSet(Object, boolean)}, you may
- * wish to override {@link #floor} to forward to this implementation.
- */
- protected E standardFloor(E e) {
- return Iterators.getNext(headSet(e, true).descendingIterator(), null);
- }
-
- @Override
- public E ceiling(E e) {
- return delegate().ceiling(e);
- }
-
- /**
- * A sensible definition of {@link #ceiling} in terms of the {@code iterator} method of
- * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may
- * wish to override {@link #ceiling} to forward to this implementation.
- */
- protected E standardCeiling(E e) {
- return Iterators.getNext(tailSet(e, true).iterator(), null);
- }
-
- @Override
- public E higher(E e) {
- return delegate().higher(e);
- }
-
- /**
- * A sensible definition of {@link #higher} in terms of the {@code iterator} method of
- * {@link #tailSet(Object, boolean)}. If you override {@link #tailSet(Object, boolean)}, you may
- * wish to override {@link #higher} to forward to this implementation.
- */
- protected E standardHigher(E e) {
- return Iterators.getNext(tailSet(e, false).iterator(), null);
- }
-
- @Override
- public E pollFirst() {
- return delegate().pollFirst();
- }
-
- /**
- * A sensible definition of {@link #pollFirst} in terms of the {@code iterator} method. If you
- * override {@link #iterator} you may wish to override {@link #pollFirst} to forward to this
- * implementation.
- */
- protected E standardPollFirst() {
- return Iterators.pollNext(iterator());
- }
-
- @Override
- public E pollLast() {
- return delegate().pollLast();
- }
-
- /**
- * A sensible definition of {@link #pollLast} in terms of the {@code descendingIterator} method.
- * If you override {@link #descendingIterator} you may wish to override {@link #pollLast} to
- * forward to this implementation.
- */
- protected E standardPollLast() {
- return Iterators.pollNext(descendingIterator());
- }
-
- protected E standardFirst() {
- return iterator().next();
- }
-
- protected E standardLast() {
- return descendingIterator().next();
- }
-
- @Override
- public NavigableSet<E> descendingSet() {
- return delegate().descendingSet();
- }
-
- /**
- * A sensible implementation of {@link NavigableSet#descendingSet} in terms of the other methods
- * of {@link NavigableSet}, notably including {@link NavigableSet#descendingIterator}.
- *
- * <p>In many cases, you may wish to override {@link ForwardingNavigableSet#descendingSet} to
- * forward to this implementation or a subclass thereof.
- *
- * @since 12.0
- */
- @Beta
- protected class StandardDescendingSet extends Sets.DescendingSet<E> {
- /** Constructor for use by subclasses. */
- public StandardDescendingSet() {
- super(ForwardingNavigableSet.this);
- }
- }
-
- @Override
- public Iterator<E> descendingIterator() {
- return delegate().descendingIterator();
- }
-
- @Override
- public NavigableSet<E> subSet(
- E fromElement,
- boolean fromInclusive,
- E toElement,
- boolean toInclusive) {
- return delegate().subSet(fromElement, fromInclusive, toElement, toInclusive);
- }
-
- /**
- * A sensible definition of {@link #subSet(Object, boolean, Object, boolean)} in terms of the
- * {@code headSet} and {@code tailSet} methods. In many cases, you may wish to override
- * {@link #subSet(Object, boolean, Object, boolean)} to forward to this implementation.
- */
- @Beta
- protected NavigableSet<E> standardSubSet(
- E fromElement,
- boolean fromInclusive,
- E toElement,
- boolean toInclusive) {
- return tailSet(fromElement, fromInclusive).headSet(toElement, toInclusive);
- }
-
- /**
- * A sensible definition of {@link #subSet(Object, Object)} in terms of the
- * {@link #subSet(Object, boolean, Object, boolean)} method. If you override
- * {@link #subSet(Object, boolean, Object, boolean)}, you may wish to override
- * {@link #subSet(Object, Object)} to forward to this implementation.
- */
- @Override
- protected SortedSet<E> standardSubSet(E fromElement, E toElement) {
- return subSet(fromElement, true, toElement, false);
- }
-
- @Override
- public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- return delegate().headSet(toElement, inclusive);
- }
-
- /**
- * A sensible definition of {@link #headSet(Object)} in terms of the
- * {@link #headSet(Object, boolean)} method. If you override
- * {@link #headSet(Object, boolean)}, you may wish to override
- * {@link #headSet(Object)} to forward to this implementation.
- */
- protected SortedSet<E> standardHeadSet(E toElement) {
- return headSet(toElement, false);
- }
-
- @Override
- public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- return delegate().tailSet(fromElement, inclusive);
- }
-
- /**
- * A sensible definition of {@link #tailSet(Object)} in terms of the
- * {@link #tailSet(Object, boolean)} method. If you override
- * {@link #tailSet(Object, boolean)}, you may wish to override
- * {@link #tailSet(Object)} to forward to this implementation.
- */
- protected SortedSet<E> standardTailSet(E fromElement) {
- return tailSet(fromElement, true);
- }
-}
diff --git a/guava/src/com/google/common/collect/ForwardingQueue.java b/guava/src/com/google/common/collect/ForwardingQueue.java
index 569880a..3d30aaf 100644
--- a/guava/src/com/google/common/collect/ForwardingQueue.java
+++ b/guava/src/com/google/common/collect/ForwardingQueue.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.NoSuchElementException;
@@ -82,7 +83,7 @@ public abstract class ForwardingQueue<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected boolean standardOffer(E e) {
+ @Beta protected boolean standardOffer(E e) {
try {
return add(e);
} catch (IllegalStateException caught) {
@@ -97,7 +98,7 @@ public abstract class ForwardingQueue<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected E standardPeek() {
+ @Beta protected E standardPeek() {
try {
return element();
} catch (NoSuchElementException caught) {
@@ -112,7 +113,7 @@ public abstract class ForwardingQueue<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected E standardPoll() {
+ @Beta protected E standardPoll() {
try {
return remove();
} catch (NoSuchElementException caught) {
diff --git a/guava/src/com/google/common/collect/ForwardingSet.java b/guava/src/com/google/common/collect/ForwardingSet.java
index e1a4485..4c3dccd 100644
--- a/guava/src/com/google/common/collect/ForwardingSet.java
+++ b/guava/src/com/google/common/collect/ForwardingSet.java
@@ -16,11 +16,9 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import java.util.Collection;
import java.util.Set;
import javax.annotation.Nullable;
@@ -64,26 +62,13 @@ public abstract class ForwardingSet<E> extends ForwardingCollection<E>
}
/**
- * A sensible definition of {@link #removeAll} in terms of {@link #iterator}
- * and {@link #remove}. If you override {@code iterator} or {@code remove},
- * you may wish to override {@link #removeAll} to forward to this
- * implementation.
- *
- * @since 7.0 (this version overrides the {@code ForwardingCollection} version as of 12.0)
- */
- @Override
- protected boolean standardRemoveAll(Collection<?> collection) {
- return Sets.removeAllImpl(this, checkNotNull(collection)); // for GWT
- }
-
- /**
* A sensible definition of {@link #equals} in terms of {@link #size} and
* {@link #containsAll}. If you override either of those methods, you may wish
* to override {@link #equals} to forward to this implementation.
*
* @since 7.0
*/
- protected boolean standardEquals(@Nullable Object object) {
+ @Beta protected boolean standardEquals(@Nullable Object object) {
return Sets.equalsImpl(this, object);
}
@@ -94,7 +79,7 @@ public abstract class ForwardingSet<E> extends ForwardingCollection<E>
*
* @since 7.0
*/
- protected int standardHashCode() {
+ @Beta protected int standardHashCode() {
return Sets.hashCodeImpl(this);
}
}
diff --git a/guava/src/com/google/common/collect/ForwardingTable.java b/guava/src/com/google/common/collect/ForwardingTable.java
index 92cc876..2c59705 100644
--- a/guava/src/com/google/common/collect/ForwardingTable.java
+++ b/guava/src/com/google/common/collect/ForwardingTable.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
@@ -31,6 +32,7 @@ import java.util.Set;
* @author Gregory Kick
* @since 7.0
*/
+@Beta
@GwtCompatible
public abstract class ForwardingTable<R, C, V> extends ForwardingObject
implements Table<R, C, V> {
diff --git a/guava/src/com/google/common/collect/GeneralRange.java b/guava/src/com/google/common/collect/GeneralRange.java
index cb3b2c8..5a3980f 100644
--- a/guava/src/com/google/common/collect/GeneralRange.java
+++ b/guava/src/com/google/common/collect/GeneralRange.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -19,21 +19,21 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Objects;
-
import java.io.Serializable;
import java.util.Comparator;
import javax.annotation.Nullable;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Objects;
+
/**
* A generalized interval on any ordering, for internal use. Supports {@code null}. Unlike
* {@link Range}, this allows the use of an arbitrary comparator. This is designed for use in the
* implementation of subcollections of sorted collection types.
- *
+ *
* <p>Whenever possible, use {@code Range} instead, which is better supported.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(serializable = true)
@@ -138,26 +138,26 @@ final class GeneralRange<T> implements Serializable {
}
boolean isEmpty() {
- return (hasUpperBound() && tooLow(getUpperEndpoint()))
- || (hasLowerBound() && tooHigh(getLowerEndpoint()));
+ return (hasUpperBound() && tooLow(upperEndpoint))
+ || (hasLowerBound() && tooHigh(lowerEndpoint));
}
boolean tooLow(@Nullable T t) {
if (!hasLowerBound()) {
return false;
}
- T lbound = getLowerEndpoint();
+ T lbound = lowerEndpoint;
int cmp = comparator.compare(t, lbound);
- return cmp < 0 | (cmp == 0 & getLowerBoundType() == OPEN);
+ return cmp < 0 | (cmp == 0 & lowerBoundType == OPEN);
}
boolean tooHigh(@Nullable T t) {
if (!hasUpperBound()) {
return false;
}
- T ubound = getUpperEndpoint();
+ T ubound = upperEndpoint;
int cmp = comparator.compare(t, ubound);
- return cmp > 0 | (cmp == 0 & getUpperBoundType() == OPEN);
+ return cmp > 0 | (cmp == 0 & upperBoundType == OPEN);
}
boolean contains(@Nullable T t) {
@@ -173,33 +173,33 @@ final class GeneralRange<T> implements Serializable {
boolean hasLowBound = this.hasLowerBound;
@Nullable
- T lowEnd = getLowerEndpoint();
- BoundType lowType = getLowerBoundType();
+ T lowEnd = lowerEndpoint;
+ BoundType lowType = lowerBoundType;
if (!hasLowerBound()) {
hasLowBound = other.hasLowerBound;
- lowEnd = other.getLowerEndpoint();
- lowType = other.getLowerBoundType();
+ lowEnd = other.lowerEndpoint;
+ lowType = other.lowerBoundType;
} else if (other.hasLowerBound()) {
- int cmp = comparator.compare(getLowerEndpoint(), other.getLowerEndpoint());
- if (cmp < 0 || (cmp == 0 && other.getLowerBoundType() == OPEN)) {
- lowEnd = other.getLowerEndpoint();
- lowType = other.getLowerBoundType();
+ int cmp = comparator.compare(lowerEndpoint, other.lowerEndpoint);
+ if (cmp < 0 || (cmp == 0 && other.lowerBoundType == OPEN)) {
+ lowEnd = other.lowerEndpoint;
+ lowType = other.lowerBoundType;
}
}
boolean hasUpBound = this.hasUpperBound;
@Nullable
- T upEnd = getUpperEndpoint();
- BoundType upType = getUpperBoundType();
+ T upEnd = upperEndpoint;
+ BoundType upType = upperBoundType;
if (!hasUpperBound()) {
hasUpBound = other.hasUpperBound;
- upEnd = other.getUpperEndpoint();
- upType = other.getUpperBoundType();
+ upEnd = other.upperEndpoint;
+ upType = other.upperBoundType;
} else if (other.hasUpperBound()) {
- int cmp = comparator.compare(getUpperEndpoint(), other.getUpperEndpoint());
- if (cmp > 0 || (cmp == 0 && other.getUpperBoundType() == OPEN)) {
- upEnd = other.getUpperEndpoint();
- upType = other.getUpperBoundType();
+ int cmp = comparator.compare(upperEndpoint, other.upperEndpoint);
+ if (cmp > 0 || (cmp == 0 && other.upperBoundType == OPEN)) {
+ upEnd = other.upperEndpoint;
+ upType = other.upperBoundType;
}
}
@@ -221,18 +221,18 @@ final class GeneralRange<T> implements Serializable {
if (obj instanceof GeneralRange) {
GeneralRange<?> r = (GeneralRange<?>) obj;
return comparator.equals(r.comparator) && hasLowerBound == r.hasLowerBound
- && hasUpperBound == r.hasUpperBound && getLowerBoundType().equals(r.getLowerBoundType())
- && getUpperBoundType().equals(r.getUpperBoundType())
- && Objects.equal(getLowerEndpoint(), r.getLowerEndpoint())
- && Objects.equal(getUpperEndpoint(), r.getUpperEndpoint());
+ && hasUpperBound == r.hasUpperBound && lowerBoundType.equals(r.lowerBoundType)
+ && upperBoundType.equals(r.upperBoundType)
+ && Objects.equal(lowerEndpoint, r.lowerEndpoint)
+ && Objects.equal(upperEndpoint, r.upperEndpoint);
}
return false;
}
@Override
public int hashCode() {
- return Objects.hashCode(comparator, getLowerEndpoint(), getLowerBoundType(), getUpperEndpoint(),
- getUpperBoundType());
+ return Objects.hashCode(comparator, lowerEndpoint, lowerBoundType, upperEndpoint,
+ upperBoundType);
}
private transient GeneralRange<T> reverse;
@@ -240,12 +240,12 @@ final class GeneralRange<T> implements Serializable {
/**
* Returns the same range relative to the reversed comparator.
*/
- GeneralRange<T> reverse() {
+ public GeneralRange<T> reverse() {
GeneralRange<T> result = reverse;
if (result == null) {
- result = new GeneralRange<T>(
- Ordering.from(comparator).reverse(), hasUpperBound, getUpperEndpoint(),
- getUpperBoundType(), hasLowerBound, getLowerEndpoint(), getLowerBoundType());
+ result =
+ new GeneralRange<T>(Ordering.from(comparator).reverse(), hasUpperBound, upperEndpoint,
+ upperBoundType, hasLowerBound, lowerEndpoint, lowerBoundType);
result.reverse = this;
return this.reverse = result;
}
@@ -254,30 +254,35 @@ final class GeneralRange<T> implements Serializable {
@Override
public String toString() {
- return new StringBuilder()
- .append(comparator)
- .append(":")
- .append(lowerBoundType == CLOSED ? '[' : '(')
- .append(hasLowerBound ? lowerEndpoint : "-\u221e")
- .append(',')
- .append(hasUpperBound ? upperEndpoint : "\u221e")
- .append(upperBoundType == CLOSED ? ']' : ')')
- .toString();
- }
-
- T getLowerEndpoint() {
- return lowerEndpoint;
- }
-
- BoundType getLowerBoundType() {
- return lowerBoundType;
- }
-
- T getUpperEndpoint() {
- return upperEndpoint;
- }
-
- BoundType getUpperBoundType() {
- return upperBoundType;
+ StringBuilder builder = new StringBuilder();
+ builder.append(comparator).append(":");
+ switch (lowerBoundType) {
+ case CLOSED:
+ builder.append('[');
+ break;
+ case OPEN:
+ builder.append('(');
+ break;
+ }
+ if (hasLowerBound()) {
+ builder.append(lowerEndpoint);
+ } else {
+ builder.append("-\u221e");
+ }
+ builder.append(',');
+ if (hasUpperBound()) {
+ builder.append(upperEndpoint);
+ } else {
+ builder.append("\u221e");
+ }
+ switch (upperBoundType) {
+ case CLOSED:
+ builder.append(']');
+ break;
+ case OPEN:
+ builder.append(')');
+ break;
+ }
+ return builder.toString();
}
}
diff --git a/guava/src/com/google/common/collect/GenericMapMaker.java b/guava/src/com/google/common/collect/GenericMapMaker.java
index 0b0a290..8c5bbeb 100644
--- a/guava/src/com/google/common/collect/GenericMapMaker.java
+++ b/guava/src/com/google/common/collect/GenericMapMaker.java
@@ -62,6 +62,12 @@ public abstract class GenericMapMaker<K0, V0> {
abstract GenericMapMaker<K0, V0> keyEquivalence(Equivalence<Object> equivalence);
/**
+ * See {@link MapMaker#valueEquivalence}.
+ */
+ @GwtIncompatible("To be supported")
+ abstract GenericMapMaker<K0, V0> valueEquivalence(Equivalence<Object> equivalence);
+
+ /**
* See {@link MapMaker#initialCapacity}.
*/
public abstract GenericMapMaker<K0, V0> initialCapacity(int initialCapacity);
@@ -72,6 +78,11 @@ public abstract class GenericMapMaker<K0, V0> {
abstract GenericMapMaker<K0, V0> maximumSize(int maximumSize);
/**
+ * See {@link MapMaker#strongKeys}.
+ */
+ abstract GenericMapMaker<K0, V0> strongKeys();
+
+ /**
* See {@link MapMaker#concurrencyLevel}.
*/
public abstract GenericMapMaker<K0, V0> concurrencyLevel(int concurrencyLevel);
@@ -83,6 +94,18 @@ public abstract class GenericMapMaker<K0, V0> {
public abstract GenericMapMaker<K0, V0> weakKeys();
/**
+ * See {@link MapMaker#strongValues}.
+ */
+ abstract GenericMapMaker<K0, V0> strongValues();
+
+ /**
+ * See {@link MapMaker#softKeys}.
+ */
+ @Deprecated
+ @GwtIncompatible("java.lang.ref.SoftReference")
+ public abstract GenericMapMaker<K0, V0> softKeys();
+
+ /**
* See {@link MapMaker#weakValues}.
*/
@GwtIncompatible("java.lang.ref.WeakReference")
@@ -95,6 +118,13 @@ public abstract class GenericMapMaker<K0, V0> {
public abstract GenericMapMaker<K0, V0> softValues();
/**
+ * See {@link MapMaker#expiration}.
+ */
+ @Deprecated
+ public
+ abstract GenericMapMaker<K0, V0> expiration(long duration, TimeUnit unit);
+
+ /**
* See {@link MapMaker#expireAfterWrite}.
*/
abstract GenericMapMaker<K0, V0> expireAfterWrite(long duration, TimeUnit unit);
diff --git a/guava/src/com/google/common/collect/HashBasedTable.java b/guava/src/com/google/common/collect/HashBasedTable.java
index 4944174..8c92ec1 100644
--- a/guava/src/com/google/common/collect/HashBasedTable.java
+++ b/guava/src/com/google/common/collect/HashBasedTable.java
@@ -18,6 +18,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Supplier;
@@ -44,15 +45,12 @@ import javax.annotation.Nullable;
* <p>Note that this implementation is not synchronized. If multiple threads
* access this table concurrently and one of the threads modifies the table, it
* must be synchronized externally.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table">
- * {@code Table}</a>.
*
* @author Jared Levy
* @since 7.0
*/
@GwtCompatible(serializable = true)
+@Beta
public class HashBasedTable<R, C, V> extends StandardTable<R, C, V> {
private static class Factory<C, V>
implements Supplier<Map<C, V>>, Serializable {
diff --git a/guava/src/com/google/common/collect/HashBiMap.java b/guava/src/com/google/common/collect/HashBiMap.java
index 0620f45..26d11e1 100644
--- a/guava/src/com/google/common/collect/HashBiMap.java
+++ b/guava/src/com/google/common/collect/HashBiMap.java
@@ -1,657 +1,97 @@
/*
* Copyright (C) 2007 The Guava Authors
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Objects;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.ConcurrentModificationException;
-import java.util.Iterator;
+import java.util.HashMap;
import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
import javax.annotation.Nullable;
/**
- * A {@link BiMap} backed by two hash tables. This implementation allows null keys and values. A
- * {@code HashBiMap} and its inverse are both serializable.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap"> {@code BiMap}
- * </a>.
+ * A {@link BiMap} backed by two {@link HashMap} instances. This implementation
+ * allows null keys and values. A {@code HashBiMap} and its inverse are both
+ * serializable.
*
- * @author Louis Wasserman
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(emulated = true)
-public final class HashBiMap<K, V> extends AbstractMap<K, V> implements BiMap<K, V>, Serializable {
+public final class HashBiMap<K, V> extends AbstractBiMap<K, V> {
/**
- * Returns a new, empty {@code HashBiMap} with the default initial capacity (16).
+ * Returns a new, empty {@code HashBiMap} with the default initial capacity
+ * (16).
*/
public static <K, V> HashBiMap<K, V> create() {
- return create(16);
+ return new HashBiMap<K, V>();
}
/**
* Constructs a new, empty bimap with the specified expected size.
*
* @param expectedSize the expected number of entries
- * @throws IllegalArgumentException if the specified expected size is negative
+ * @throws IllegalArgumentException if the specified expected size is
+ * negative
*/
public static <K, V> HashBiMap<K, V> create(int expectedSize) {
return new HashBiMap<K, V>(expectedSize);
}
/**
- * Constructs a new bimap containing initial values from {@code map}. The bimap is created with an
- * initial capacity sufficient to hold the mappings in the specified map.
+ * Constructs a new bimap containing initial values from {@code map}. The
+ * bimap is created with an initial capacity sufficient to hold the mappings
+ * in the specified map.
*/
- public static <K, V> HashBiMap<K, V> create(Map<? extends K, ? extends V> map) {
+ public static <K, V> HashBiMap<K, V> create(
+ Map<? extends K, ? extends V> map) {
HashBiMap<K, V> bimap = create(map.size());
bimap.putAll(map);
return bimap;
}
- private static final class BiEntry<K, V> {
- final K key;
- final int keyHash;
-
- final V value;
- final int valueHash;
-
- @Nullable
- BiEntry<K, V> nextInKToVBucket;
-
- @Nullable
- BiEntry<K, V> nextInVToKBucket;
-
- BiEntry(K key, int keyHash, V value, int valueHash) {
- this.key = key;
- this.keyHash = keyHash;
- this.value = value;
- this.valueHash = valueHash;
- }
+ private HashBiMap() {
+ super(new HashMap<K, V>(), new HashMap<V, K>());
}
- private static final double LOAD_FACTOR = 1.0;
-
- private transient BiEntry<K, V>[] hashTableKToV;
- private transient BiEntry<K, V>[] hashTableVToK;
- private transient int size;
- private transient int mask;
- private transient int modCount;
-
private HashBiMap(int expectedSize) {
- init(expectedSize);
- }
-
- private void init(int expectedSize) {
- checkArgument(expectedSize >= 0, "expectedSize must be >= 0 but was %s", expectedSize);
- int tableSize = Hashing.closedTableSize(expectedSize, LOAD_FACTOR);
- this.hashTableKToV = createTable(tableSize);
- this.hashTableVToK = createTable(tableSize);
- this.mask = tableSize - 1;
- this.modCount = 0;
- this.size = 0;
- }
-
- /**
- * Finds and removes {@code entry} from the bucket linked lists in both the
- * key-to-value direction and the value-to-key direction.
- */
- private void delete(BiEntry<K, V> entry) {
- int keyBucket = entry.keyHash & mask;
- BiEntry<K, V> prevBucketEntry = null;
- for (BiEntry<K, V> bucketEntry = hashTableKToV[keyBucket]; true;
- bucketEntry = bucketEntry.nextInKToVBucket) {
- if (bucketEntry == entry) {
- if (prevBucketEntry == null) {
- hashTableKToV[keyBucket] = entry.nextInKToVBucket;
- } else {
- prevBucketEntry.nextInKToVBucket = entry.nextInKToVBucket;
- }
- break;
- }
- prevBucketEntry = bucketEntry;
- }
-
- int valueBucket = entry.valueHash & mask;
- prevBucketEntry = null;
- for (BiEntry<K, V> bucketEntry = hashTableVToK[valueBucket];;
- bucketEntry = bucketEntry.nextInVToKBucket) {
- if (bucketEntry == entry) {
- if (prevBucketEntry == null) {
- hashTableVToK[valueBucket] = entry.nextInVToKBucket;
- } else {
- prevBucketEntry.nextInVToKBucket = entry.nextInVToKBucket;
- }
- break;
- }
- prevBucketEntry = bucketEntry;
- }
-
- size--;
- modCount++;
- }
-
- private void insert(BiEntry<K, V> entry) {
- int keyBucket = entry.keyHash & mask;
- entry.nextInKToVBucket = hashTableKToV[keyBucket];
- hashTableKToV[keyBucket] = entry;
-
- int valueBucket = entry.valueHash & mask;
- entry.nextInVToKBucket = hashTableVToK[valueBucket];
- hashTableVToK[valueBucket] = entry;
-
- size++;
- modCount++;
- }
-
- private static int hash(@Nullable Object o) {
- return Hashing.smear((o == null) ? 0 : o.hashCode());
+ super(
+ Maps.<K, V>newHashMapWithExpectedSize(expectedSize),
+ Maps.<V, K>newHashMapWithExpectedSize(expectedSize));
}
- private BiEntry<K, V> seekByKey(@Nullable Object key, int keyHash) {
- for (BiEntry<K, V> entry = hashTableKToV[keyHash & mask]; entry != null;
- entry = entry.nextInKToVBucket) {
- if (keyHash == entry.keyHash && Objects.equal(key, entry.key)) {
- return entry;
- }
- }
- return null;
- }
-
- private BiEntry<K, V> seekByValue(@Nullable Object value, int valueHash) {
- for (BiEntry<K, V> entry = hashTableVToK[valueHash & mask]; entry != null;
- entry = entry.nextInVToKBucket) {
- if (valueHash == entry.valueHash && Objects.equal(value, entry.value)) {
- return entry;
- }
- }
- return null;
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return seekByKey(key, hash(key)) != null;
- }
-
- @Override
- public boolean containsValue(@Nullable Object value) {
- return seekByValue(value, hash(value)) != null;
- }
+ // Override these two methods to show that keys and values may be null
- @Nullable
- @Override
- public V get(@Nullable Object key) {
- BiEntry<K, V> entry = seekByKey(key, hash(key));
- return (entry == null) ? null : entry.value;
+ @Override public V put(@Nullable K key, @Nullable V value) {
+ return super.put(key, value);
}
- @Override
- public V put(@Nullable K key, @Nullable V value) {
- return put(key, value, false);
- }
-
- @Override
- public V forcePut(@Nullable K key, @Nullable V value) {
- return put(key, value, true);
- }
-
- private V put(@Nullable K key, @Nullable V value, boolean force) {
- int keyHash = hash(key);
- int valueHash = hash(value);
-
- BiEntry<K, V> oldEntryForKey = seekByKey(key, keyHash);
- if (oldEntryForKey != null && valueHash == oldEntryForKey.valueHash
- && Objects.equal(value, oldEntryForKey.value)) {
- return value;
- }
-
- BiEntry<K, V> oldEntryForValue = seekByValue(value, valueHash);
- if (oldEntryForValue != null) {
- if (force) {
- delete(oldEntryForValue);
- } else {
- throw new IllegalArgumentException("value already present: " + value);
- }
- }
-
- if (oldEntryForKey != null) {
- delete(oldEntryForKey);
- }
- BiEntry<K, V> newEntry = new BiEntry<K, V>(key, keyHash, value, valueHash);
- insert(newEntry);
- rehashIfNecessary();
- return (oldEntryForKey == null) ? null : oldEntryForKey.value;
- }
-
- @Nullable
- private K putInverse(@Nullable V value, @Nullable K key, boolean force) {
- int valueHash = hash(value);
- int keyHash = hash(key);
-
- BiEntry<K, V> oldEntryForValue = seekByValue(value, valueHash);
- if (oldEntryForValue != null && keyHash == oldEntryForValue.keyHash
- && Objects.equal(key, oldEntryForValue.key)) {
- return key;
- }
-
- BiEntry<K, V> oldEntryForKey = seekByKey(key, keyHash);
- if (oldEntryForKey != null) {
- if (force) {
- delete(oldEntryForKey);
- } else {
- throw new IllegalArgumentException("value already present: " + key);
- }
- }
-
- if (oldEntryForValue != null) {
- delete(oldEntryForValue);
- }
- BiEntry<K, V> newEntry = new BiEntry<K, V>(key, keyHash, value, valueHash);
- insert(newEntry);
- rehashIfNecessary();
- return (oldEntryForValue == null) ? null : oldEntryForValue.key;
- }
-
- private void rehashIfNecessary() {
- BiEntry<K, V>[] oldKToV = hashTableKToV;
- if (Hashing.needsResizing(size, oldKToV.length, LOAD_FACTOR)) {
- int newTableSize = oldKToV.length * 2;
-
- this.hashTableKToV = createTable(newTableSize);
- this.hashTableVToK = createTable(newTableSize);
- this.mask = newTableSize - 1;
- this.size = 0;
-
- for (int bucket = 0; bucket < oldKToV.length; bucket++) {
- BiEntry<K, V> entry = oldKToV[bucket];
- while (entry != null) {
- BiEntry<K, V> nextEntry = entry.nextInKToVBucket;
- insert(entry);
- entry = nextEntry;
- }
- }
- this.modCount++;
- }
- }
-
- @SuppressWarnings("unchecked")
- private BiEntry<K, V>[] createTable(int length) {
- return new BiEntry[length];
- }
-
- @Override
- public V remove(@Nullable Object key) {
- BiEntry<K, V> entry = seekByKey(key, hash(key));
- if (entry == null) {
- return null;
- } else {
- delete(entry);
- return entry.value;
- }
- }
-
- @Override
- public void clear() {
- size = 0;
- Arrays.fill(hashTableKToV, null);
- Arrays.fill(hashTableVToK, null);
- modCount++;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- abstract class Itr<T> implements Iterator<T> {
- int nextBucket = 0;
- BiEntry<K, V> next = null;
- BiEntry<K, V> toRemove = null;
- int expectedModCount = modCount;
-
- private void checkForConcurrentModification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
-
- @Override
- public boolean hasNext() {
- checkForConcurrentModification();
- if (next != null) {
- return true;
- }
- while (nextBucket < hashTableKToV.length) {
- if (hashTableKToV[nextBucket] != null) {
- next = hashTableKToV[nextBucket++];
- return true;
- }
- nextBucket++;
- }
- return false;
- }
-
- @Override
- public T next() {
- checkForConcurrentModification();
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
-
- BiEntry<K, V> entry = next;
- next = entry.nextInKToVBucket;
- toRemove = entry;
- return output(entry);
- }
-
- @Override
- public void remove() {
- checkForConcurrentModification();
- checkState(toRemove != null, "Only one remove() call allowed per call to next");
- delete(toRemove);
- expectedModCount = modCount;
- toRemove = null;
- }
-
- abstract T output(BiEntry<K, V> entry);
- }
-
- @Override
- public Set<K> keySet() {
- return new KeySet();
- }
-
- private final class KeySet extends Maps.KeySet<K, V> {
- @Override
- Map<K, V> map() {
- return HashBiMap.this;
- }
-
- @Override
- public Iterator<K> iterator() {
- return new Itr<K>() {
- @Override
- K output(BiEntry<K, V> entry) {
- return entry.key;
- }
- };
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- BiEntry<K, V> entry = seekByKey(o, hash(o));
- if (entry == null) {
- return false;
- } else {
- delete(entry);
- return true;
- }
- }
- }
-
- @Override
- public Set<V> values() {
- return inverse().keySet();
- }
-
- @Override
- public Set<Entry<K, V>> entrySet() {
- return new EntrySet();
- }
-
- private final class EntrySet extends Maps.EntrySet<K, V> {
- @Override
- Map<K, V> map() {
- return HashBiMap.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return new Itr<Entry<K, V>>() {
- @Override
- Entry<K, V> output(BiEntry<K, V> entry) {
- return new MapEntry(entry);
- }
-
- class MapEntry extends AbstractMapEntry<K, V> {
- BiEntry<K, V> delegate;
-
- MapEntry(BiEntry<K, V> entry) {
- this.delegate = entry;
- }
-
- @Override public K getKey() {
- return delegate.key;
- }
-
- @Override public V getValue() {
- return delegate.value;
- }
-
- @Override public V setValue(V value) {
- V oldValue = delegate.value;
- int valueHash = hash(value);
- if (valueHash == delegate.valueHash && Objects.equal(value, oldValue)) {
- return value;
- }
- checkArgument(
- seekByValue(value, valueHash) == null, "value already present: %s", value);
- delete(delegate);
- BiEntry<K, V> newEntry =
- new BiEntry<K, V>(delegate.key, delegate.keyHash, value, valueHash);
- insert(newEntry);
- expectedModCount = modCount;
- if (toRemove == delegate) {
- toRemove = newEntry;
- }
- delegate = newEntry;
- return oldValue;
- }
- }
- };
- }
- }
-
- private transient BiMap<V, K> inverse;
-
- @Override
- public BiMap<V, K> inverse() {
- return (inverse == null) ? inverse = new Inverse() : inverse;
- }
-
- private final class Inverse extends AbstractMap<V, K> implements BiMap<V, K>, Serializable {
- BiMap<K, V> forward() {
- return HashBiMap.this;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public void clear() {
- forward().clear();
- }
-
- @Override
- public boolean containsKey(@Nullable Object value) {
- return forward().containsValue(value);
- }
-
- @Override
- public K get(@Nullable Object value) {
- BiEntry<K, V> entry = seekByValue(value, hash(value));
- return (entry == null) ? null : entry.key;
- }
-
- @Override
- public K put(@Nullable V value, @Nullable K key) {
- return putInverse(value, key, false);
- }
-
- @Override
- public K forcePut(@Nullable V value, @Nullable K key) {
- return putInverse(value, key, true);
- }
-
- @Override
- public K remove(@Nullable Object value) {
- BiEntry<K, V> entry = seekByValue(value, hash(value));
- if (entry == null) {
- return null;
- } else {
- delete(entry);
- return entry.key;
- }
- }
-
- @Override
- public BiMap<K, V> inverse() {
- return forward();
- }
-
- @Override
- public Set<V> keySet() {
- return new InverseKeySet();
- }
-
- private final class InverseKeySet extends Maps.KeySet<V, K> {
- @Override
- Map<V, K> map() {
- return Inverse.this;
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- BiEntry<K, V> entry = seekByValue(o, hash(o));
- if (entry == null) {
- return false;
- } else {
- delete(entry);
- return true;
- }
- }
-
- @Override
- public Iterator<V> iterator() {
- return new Itr<V>() {
- @Override V output(BiEntry<K, V> entry) {
- return entry.value;
- }
- };
- }
- }
-
- @Override
- public Set<K> values() {
- return forward().keySet();
- }
-
- @Override
- public Set<Entry<V, K>> entrySet() {
- return new Maps.EntrySet<V, K>() {
-
- @Override
- Map<V, K> map() {
- return Inverse.this;
- }
-
- @Override
- public Iterator<Entry<V, K>> iterator() {
- return new Itr<Entry<V, K>>() {
- @Override
- Entry<V, K> output(BiEntry<K, V> entry) {
- return new InverseEntry(entry);
- }
-
- class InverseEntry extends AbstractMapEntry<V, K> {
- BiEntry<K, V> delegate;
-
- InverseEntry(BiEntry<K, V> entry) {
- this.delegate = entry;
- }
-
- @Override
- public V getKey() {
- return delegate.value;
- }
-
- @Override
- public K getValue() {
- return delegate.key;
- }
-
- @Override
- public K setValue(K key) {
- K oldKey = delegate.key;
- int keyHash = hash(key);
- if (keyHash == delegate.keyHash && Objects.equal(key, oldKey)) {
- return key;
- }
- checkArgument(seekByKey(key, keyHash) == null, "value already present: %s", key);
- delete(delegate);
- BiEntry<K, V> newEntry =
- new BiEntry<K, V>(key, keyHash, delegate.value, delegate.valueHash);
- insert(newEntry);
- expectedModCount = modCount;
- // This is safe because entries can only get bumped up to earlier in the iteration,
- // so they can't get revisited.
- return oldKey;
- }
- }
- };
- }
- };
- }
-
- Object writeReplace() {
- return new InverseSerializedForm<K, V>(HashBiMap.this);
- }
- }
-
- private static final class InverseSerializedForm<K, V> implements Serializable {
- private final HashBiMap<K, V> bimap;
-
- InverseSerializedForm(HashBiMap<K, V> bimap) {
- this.bimap = bimap;
- }
-
- Object readResolve() {
- return bimap.inverse();
- }
+ @Override public V forcePut(@Nullable K key, @Nullable V value) {
+ return super.forcePut(key, value);
}
/**
- * @serialData the number of entries, first key, first value, second key, second value, and so on.
+ * @serialData the number of entries, first key, first value, second key,
+ * second value, and so on.
*/
@GwtIncompatible("java.io.ObjectOutputStream")
private void writeObject(ObjectOutputStream stream) throws IOException {
@@ -660,10 +100,12 @@ public final class HashBiMap<K, V> extends AbstractMap<K, V> implements BiMap<K,
}
@GwtIncompatible("java.io.ObjectInputStream")
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
stream.defaultReadObject();
int size = Serialization.readCount(stream);
- init(size);
+ setDelegates(Maps.<K, V>newHashMapWithExpectedSize(size),
+ Maps.<V, K>newHashMapWithExpectedSize(size));
Serialization.populateMap(this, stream, size);
}
diff --git a/guava/src/com/google/common/collect/HashMultimap.java b/guava/src/com/google/common/collect/HashMultimap.java
index bab2a05..d347ff1 100644
--- a/guava/src/com/google/common/collect/HashMultimap.java
+++ b/guava/src/com/google/common/collect/HashMultimap.java
@@ -48,7 +48,7 @@ import java.util.Set;
*/
@GwtCompatible(serializable = true, emulated = true)
public final class HashMultimap<K, V> extends AbstractSetMultimap<K, V> {
- private static final int DEFAULT_VALUES_PER_KEY = 2;
+ private static final int DEFAULT_VALUES_PER_KEY = 8;
@VisibleForTesting
transient int expectedValuesPerKey = DEFAULT_VALUES_PER_KEY;
diff --git a/guava/src/com/google/common/collect/Hashing.java b/guava/src/com/google/common/collect/Hashing.java
index b13eb7c..9c5f6bc 100644
--- a/guava/src/com/google/common/collect/Hashing.java
+++ b/guava/src/com/google/common/collect/Hashing.java
@@ -17,50 +17,27 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.primitives.Ints;
/**
* Static methods for implementing hash-based collections.
*
* @author Kevin Bourrillion
* @author Jesse Wilson
- * @author Austin Appleby
*/
@GwtCompatible
final class Hashing {
private Hashing() {}
- private static final int C1 = 0xcc9e2d51;
- private static final int C2 = 0x1b873593;
-
/*
- * This method was rewritten in Java from an intermediate step of the Murmur hash function in
- * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp, which contained the
- * following header:
- *
- * MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author
- * hereby disclaims copyright to this source code.
+ * This method was written by Doug Lea with assistance from members of JCP
+ * JSR-166 Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ *
+ * As of 2010/06/11, this method is identical to the (package private) hash
+ * method in OpenJDK 7's java.util.HashMap class.
*/
static int smear(int hashCode) {
- return C2 * Integer.rotateLeft(hashCode * C1, 15);
- }
-
- static int MAX_TABLE_SIZE = Ints.MAX_POWER_OF_TWO;
-
- static int closedTableSize(int expectedEntries, double loadFactor) {
- // Get the recommended table size.
- // Round down to the nearest power of 2.
- expectedEntries = Math.max(expectedEntries, 2);
- int tableSize = Integer.highestOneBit(expectedEntries);
- // Check to make sure that we will not exceed the maximum load factor.
- if ((double) expectedEntries / tableSize > loadFactor) {
- tableSize <<= 1;
- return (tableSize > 0) ? tableSize : MAX_TABLE_SIZE;
- }
- return tableSize;
- }
-
- static boolean needsResizing(int size, int tableSize, double loadFactor) {
- return size > loadFactor * tableSize && tableSize < MAX_TABLE_SIZE;
+ hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12);
+ return hashCode ^ (hashCode >>> 7) ^ (hashCode >>> 4);
}
}
diff --git a/guava/src/com/google/common/collect/ImmutableAsList.java b/guava/src/com/google/common/collect/ImmutableAsList.java
index 249abee..9eb87de 100644
--- a/guava/src/com/google/common/collect/ImmutableAsList.java
+++ b/guava/src/com/google/common/collect/ImmutableAsList.java
@@ -17,49 +17,36 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
/**
- * List returned by {@link ImmutableCollection#asList} that delegates {@code contains} checks
- * to the backing collection.
+ * List returned by {@link ImmutableCollection#asList} when the collection isn't
+ * an {@link ImmutableList} or an {@link ImmutableSortedSet}.
*
* @author Jared Levy
- * @author Louis Wasserman
*/
@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial")
-abstract class ImmutableAsList<E> extends ImmutableList<E> {
- abstract ImmutableCollection<E> delegateCollection();
+final class ImmutableAsList<E> extends RegularImmutableList<E> {
+ private final transient ImmutableCollection<E> collection;
- @Override public boolean contains(Object target) {
- // The collection's contains() is at least as fast as ImmutableList's
- // and is often faster.
- return delegateCollection().contains(target);
- }
-
- @Override
- public int size() {
- return delegateCollection().size();
+ ImmutableAsList(Object[] array, ImmutableCollection<E> collection) {
+ super(array, 0, array.length);
+ this.collection = collection;
}
- @Override
- public boolean isEmpty() {
- return delegateCollection().isEmpty();
- }
-
- @Override
- boolean isPartialView() {
- return delegateCollection().isPartialView();
+ @Override public boolean contains(Object target) {
+ // The collection's contains() is at least as fast as RegularImmutableList's
+ // and is often faster.
+ return collection.contains(target);
}
/**
* Serialized form that leads to the same performance as the original list.
*/
- @GwtIncompatible("serialization")
static class SerializedForm implements Serializable {
final ImmutableCollection<?> collection;
SerializedForm(ImmutableCollection<?> collection) {
@@ -71,14 +58,12 @@ abstract class ImmutableAsList<E> extends ImmutableList<E> {
private static final long serialVersionUID = 0;
}
- @GwtIncompatible("serialization")
private void readObject(ObjectInputStream stream)
throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
- @GwtIncompatible("serialization")
@Override Object writeReplace() {
- return new SerializedForm(delegateCollection());
+ return new SerializedForm(collection);
}
}
diff --git a/guava/src/com/google/common/collect/ImmutableBiMap.java b/guava/src/com/google/common/collect/ImmutableBiMap.java
index d7968b2..9d8e144 100644
--- a/guava/src/com/google/common/collect/ImmutableBiMap.java
+++ b/guava/src/com/google/common/collect/ImmutableBiMap.java
@@ -16,13 +16,12 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.GwtCompatible;
-import java.util.Collection;
import java.util.Map;
+import javax.annotation.Nullable;
+
/**
* An immutable {@link BiMap} with reliable user-specified iteration order. Does
* not permit null keys or values. An {@code ImmutableBiMap} and its inverse
@@ -44,22 +43,23 @@ import java.util.Map;
public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
implements BiMap<K, V> {
+ private static final ImmutableBiMap<Object, Object> EMPTY_IMMUTABLE_BIMAP
+ = new EmptyBiMap();
+
/**
* Returns the empty bimap.
*/
// Casting to any type is safe because the set will never hold any elements.
@SuppressWarnings("unchecked")
public static <K, V> ImmutableBiMap<K, V> of() {
- return (ImmutableBiMap<K, V>) EmptyImmutableBiMap.INSTANCE;
+ return (ImmutableBiMap<K, V>) EMPTY_IMMUTABLE_BIMAP;
}
/**
* Returns an immutable bimap containing a single entry.
*/
public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1) {
- checkNotNull(k1, "null key in entry: null=%s", v1);
- checkNotNull(v1, "null value in entry: %s=null", k1);
- return new SingletonImmutableBiMap<K, V>(k1, v1);
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1));
}
/**
@@ -68,10 +68,7 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
* @throws IllegalArgumentException if duplicate keys or values are added
*/
public static <K, V> ImmutableBiMap<K, V> of(K k1, V v1, K k2, V v2) {
- return new Builder<K, V>()
- .put(k1, v1)
- .put(k2, v2)
- .build();
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(k1, v1, k2, v2));
}
/**
@@ -81,11 +78,8 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
*/
public static <K, V> ImmutableBiMap<K, V> of(
K k1, V v1, K k2, V v2, K k3, V v3) {
- return new Builder<K, V>()
- .put(k1, v1)
- .put(k2, v2)
- .put(k3, v3)
- .build();
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
+ k1, v1, k2, v2, k3, v3));
}
/**
@@ -95,12 +89,8 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
*/
public static <K, V> ImmutableBiMap<K, V> of(
K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
- return new Builder<K, V>()
- .put(k1, v1)
- .put(k2, v2)
- .put(k3, v3)
- .put(k4, v4)
- .build();
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
+ k1, v1, k2, v2, k3, v3, k4, v4));
}
/**
@@ -110,13 +100,8 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
*/
public static <K, V> ImmutableBiMap<K, V> of(
K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
- return new Builder<K, V>()
- .put(k1, v1)
- .put(k2, v2)
- .put(k3, v3)
- .put(k4, v4)
- .put(k5, v5)
- .build();
+ return new RegularImmutableBiMap<K, V>(ImmutableMap.of(
+ k1, v1, k2, v2, k3, v3, k4, v4, k5, v5));
}
// looking for of() with > 5 entries? Use the builder instead.
@@ -184,7 +169,11 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
* @throws IllegalArgumentException if duplicate keys or values were added
*/
@Override public ImmutableBiMap<K, V> build() {
- return fromEntries(entries);
+ ImmutableMap<K, V> map = super.build();
+ if (map.isEmpty()) {
+ return of();
+ }
+ return new RegularImmutableBiMap<K, V>(map);
}
}
@@ -213,25 +202,18 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
}
}
- return fromEntries(ImmutableList.copyOf(map.entrySet()));
- }
-
- static <K, V> ImmutableBiMap<K, V> fromEntries(
- Collection<? extends Entry<? extends K, ? extends V>> entries) {
- switch (entries.size()) {
- case 0:
- return of();
- case 1: {
- Entry<? extends K, ? extends V> entry = Iterables.getOnlyElement(entries);
- return new SingletonImmutableBiMap<K, V>(entry.getKey(), entry.getValue());
- }
- default:
- return new RegularImmutableBiMap<K, V>(entries);
+ if (map.isEmpty()) {
+ return of();
}
+
+ ImmutableMap<K, V> immutableMap = ImmutableMap.copyOf(map);
+ return new RegularImmutableBiMap<K, V>(immutableMap);
}
ImmutableBiMap() {}
+ abstract ImmutableMap<K, V> delegate();
+
/**
* {@inheritDoc}
*
@@ -241,6 +223,26 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
@Override
public abstract ImmutableBiMap<V, K> inverse();
+ @Override public boolean containsKey(@Nullable Object key) {
+ return delegate().containsKey(key);
+ }
+
+ @Override public boolean containsValue(@Nullable Object value) {
+ return inverse().containsKey(value);
+ }
+
+ @Override public ImmutableSet<Entry<K, V>> entrySet() {
+ return delegate().entrySet();
+ }
+
+ @Override public V get(@Nullable Object key) {
+ return delegate().get(key);
+ }
+
+ @Override public ImmutableSet<K> keySet() {
+ return delegate().keySet();
+ }
+
/**
* Returns an immutable set of the values in this map. The values are in the
* same order as the parameters used to build this map.
@@ -253,14 +255,50 @@ public abstract class ImmutableBiMap<K, V> extends ImmutableMap<K, V>
* Guaranteed to throw an exception and leave the bimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public V forcePut(K key, V value) {
throw new UnsupportedOperationException();
}
+ @Override public boolean isEmpty() {
+ return delegate().isEmpty();
+ }
+
+ @Override
+ public int size() {
+ return delegate().size();
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return object == this || delegate().equals(object);
+ }
+
+ @Override public int hashCode() {
+ return delegate().hashCode();
+ }
+
+ @Override public String toString() {
+ return delegate().toString();
+ }
+
+ /** Bimap with no mappings. */
+ @SuppressWarnings("serial") // uses writeReplace(), not default serialization
+ static class EmptyBiMap extends ImmutableBiMap<Object, Object> {
+ @Override ImmutableMap<Object, Object> delegate() {
+ return ImmutableMap.of();
+ }
+ @Override public ImmutableBiMap<Object, Object> inverse() {
+ return this;
+ }
+ @Override boolean isPartialView() {
+ return false;
+ }
+ Object readResolve() {
+ return EMPTY_IMMUTABLE_BIMAP; // preserve singleton property
+ }
+ }
+
/**
* Serialized type for all ImmutableBiMap instances. It captures the logical
* contents and they are reconstructed using public factory methods. This
diff --git a/guava/src/com/google/common/collect/ImmutableClassToInstanceMap.java b/guava/src/com/google/common/collect/ImmutableClassToInstanceMap.java
index 50f93c3..1c596e2 100644
--- a/guava/src/com/google/common/collect/ImmutableClassToInstanceMap.java
+++ b/guava/src/com/google/common/collect/ImmutableClassToInstanceMap.java
@@ -16,14 +16,10 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.primitives.Primitives;
import java.util.Map;
-import javax.annotation.Nullable;
-
/**
* A class-to-instance map backed by an {@link ImmutableMap}. See also {@link
* MutableClassToInstanceMap}.
@@ -142,18 +138,15 @@ public final class ImmutableClassToInstanceMap<B> extends
@Override
@SuppressWarnings("unchecked") // value could not get in if not a T
- @Nullable
public <T extends B> T getInstance(Class<T> type) {
- return (T) delegate.get(checkNotNull(type));
+ return (T) delegate.get(type);
}
/**
* Guaranteed to throw an exception and leave the map unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public <T extends B> T putInstance(Class<T> type, T value) {
throw new UnsupportedOperationException();
diff --git a/guava/src/com/google/common/collect/ImmutableCollection.java b/guava/src/com/google/common/collect/ImmutableCollection.java
index 2aeca97..5fca2aa 100644
--- a/guava/src/com/google/common/collect/ImmutableCollection.java
+++ b/guava/src/com/google/common/collect/ImmutableCollection.java
@@ -17,7 +17,6 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.VisibleForTesting;
import java.io.Serializable;
import java.util.Collection;
@@ -86,9 +85,7 @@ public abstract class ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean add(E e) {
throw new UnsupportedOperationException();
@@ -98,9 +95,7 @@ public abstract class ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean remove(Object object) {
throw new UnsupportedOperationException();
@@ -110,9 +105,7 @@ public abstract class ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean addAll(Collection<? extends E> newElements) {
throw new UnsupportedOperationException();
@@ -122,9 +115,7 @@ public abstract class ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean removeAll(Collection<?> oldElements) {
throw new UnsupportedOperationException();
@@ -134,9 +125,7 @@ public abstract class ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean retainAll(Collection<?> elementsToKeep) {
throw new UnsupportedOperationException();
@@ -146,9 +135,7 @@ public abstract class ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final void clear() {
throw new UnsupportedOperationException();
@@ -177,7 +164,7 @@ public abstract class ImmutableCollection<E>
case 1:
return ImmutableList.of(iterator().next());
default:
- return new RegularImmutableAsList<E>(this, toArray());
+ return new ImmutableAsList<E>(toArray(), this);
}
}
@@ -199,7 +186,7 @@ public abstract class ImmutableCollection<E>
}
@Override public UnmodifiableIterator<Object> iterator() {
- return Iterators.EMPTY_LIST_ITERATOR;
+ return Iterators.EMPTY_ITERATOR;
}
private static final Object[] EMPTY_ARRAY = new Object[0];
@@ -285,24 +272,6 @@ public abstract class ImmutableCollection<E>
* @since 10.0
*/
public abstract static class Builder<E> {
- static final int DEFAULT_INITIAL_CAPACITY = 4;
-
- @VisibleForTesting
- static int expandedCapacity(int oldCapacity, int minCapacity) {
- if (minCapacity < 0) {
- throw new AssertionError("cannot store more than MAX_VALUE elements");
- }
- // careful of overflow!
- int newCapacity = oldCapacity + (oldCapacity >> 1) + 1;
- if (newCapacity < minCapacity) {
- newCapacity = Integer.highestOneBit(minCapacity - 1) << 1;
- }
- if (newCapacity < 0) {
- newCapacity = Integer.MAX_VALUE;
- // guaranteed to be >= newCapacity
- }
- return newCapacity;
- }
Builder() {
}
diff --git a/guava/src/com/google/common/collect/ImmutableEnumMap.java b/guava/src/com/google/common/collect/ImmutableEnumMap.java
deleted file mode 100644
index 6738685..0000000
--- a/guava/src/com/google/common/collect/ImmutableEnumMap.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.io.Serializable;
-import java.util.EnumMap;
-import java.util.Iterator;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of {@link ImmutableMap} backed by a non-empty {@link
- * java.util.EnumMap}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(serializable = true, emulated = true)
-@SuppressWarnings("serial") // we're overriding default serialization
-final class ImmutableEnumMap<K extends Enum<K>, V> extends ImmutableMap<K, V> {
- static <K extends Enum<K>, V> ImmutableMap<K, V> asImmutable(EnumMap<K, V> map) {
- switch (map.size()) {
- case 0:
- return ImmutableMap.of();
- case 1: {
- Entry<K, V> entry = Iterables.getOnlyElement(map.entrySet());
- return ImmutableMap.of(entry.getKey(), entry.getValue());
- }
- default:
- return new ImmutableEnumMap<K, V>(map);
- }
- }
-
- private transient final EnumMap<K, V> delegate;
-
- private ImmutableEnumMap(EnumMap<K, V> delegate) {
- this.delegate = delegate;
- checkArgument(!delegate.isEmpty());
- }
-
- @Override
- ImmutableSet<K> createKeySet() {
- return new ImmutableSet<K>() {
-
- @Override
- public boolean contains(Object object) {
- return delegate.containsKey(object);
- }
-
- @Override
- public int size() {
- return ImmutableEnumMap.this.size();
- }
-
- @Override
- public UnmodifiableIterator<K> iterator() {
- return Iterators.unmodifiableIterator(delegate.keySet().iterator());
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- };
- }
-
- @Override
- public int size() {
- return delegate.size();
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return delegate.containsKey(key);
- }
-
- @Override
- public V get(Object key) {
- return delegate.get(key);
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- return new ImmutableMapEntrySet<K, V>() {
-
- @Override
- ImmutableMap<K, V> map() {
- return ImmutableEnumMap.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return new UnmodifiableIterator<Entry<K, V>>() {
- private final Iterator<Entry<K, V>> backingIterator = delegate.entrySet().iterator();
-
- @Override
- public boolean hasNext() {
- return backingIterator.hasNext();
- }
-
- @Override
- public Entry<K, V> next() {
- Entry<K, V> entry = backingIterator.next();
- return Maps.immutableEntry(entry.getKey(), entry.getValue());
- }
- };
- }
- };
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
-
- // All callers of the constructor are restricted to <K extends Enum<K>>.
- @Override Object writeReplace() {
- return new EnumSerializedForm<K, V>(delegate);
- }
-
- /*
- * This class is used to serialize ImmutableEnumSet instances.
- */
- private static class EnumSerializedForm<K extends Enum<K>, V>
- implements Serializable {
- final EnumMap<K, V> delegate;
- EnumSerializedForm(EnumMap<K, V> delegate) {
- this.delegate = delegate;
- }
- Object readResolve() {
- return new ImmutableEnumMap<K, V>(delegate);
- }
- private static final long serialVersionUID = 0;
- }
-}
diff --git a/guava/src/com/google/common/collect/ImmutableEnumSet.java b/guava/src/com/google/common/collect/ImmutableEnumSet.java
index d187b5c..ac6dd0e 100644
--- a/guava/src/com/google/common/collect/ImmutableEnumSet.java
+++ b/guava/src/com/google/common/collect/ImmutableEnumSet.java
@@ -31,17 +31,6 @@ import java.util.EnumSet;
@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial") // we're overriding default serialization
final class ImmutableEnumSet<E extends Enum<E>> extends ImmutableSet<E> {
- static <E extends Enum<E>> ImmutableSet<E> asImmutable(EnumSet<E> set) {
- switch (set.size()) {
- case 0:
- return ImmutableSet.of();
- case 1:
- return ImmutableSet.of(Iterables.getOnlyElement(set));
- default:
- return new ImmutableEnumSet<E>(set);
- }
- }
-
/*
* Notes on EnumSet and <E extends Enum<E>>:
*
@@ -52,7 +41,7 @@ final class ImmutableEnumSet<E extends Enum<E>> extends ImmutableSet<E> {
*/
private final transient EnumSet<E> delegate;
- private ImmutableEnumSet(EnumSet<E> delegate) {
+ ImmutableEnumSet(EnumSet<E> delegate) {
this.delegate = delegate;
}
diff --git a/guava/src/com/google/common/collect/ImmutableList.java b/guava/src/com/google/common/collect/ImmutableList.java
index a01f4bc..cd8235a 100644
--- a/guava/src/com/google/common/collect/ImmutableList.java
+++ b/guava/src/com/google/common/collect/ImmutableList.java
@@ -16,17 +16,15 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndex;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static com.google.common.collect.ObjectArrays.checkElementNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Preconditions;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -50,10 +48,6 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this type are
* guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @see ImmutableMap
* @see ImmutableSet
* @author Kevin Bourrillion
@@ -259,19 +253,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* @throws NullPointerException if any of {@code elements} is null
*/
public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
- // We special-case for 0 or 1 elements, but going further is madness.
- if (!elements.hasNext()) {
- return of();
- }
- E first = elements.next();
- if (!elements.hasNext()) {
- return of(first);
- } else {
- return new ImmutableList.Builder<E>()
- .add(first)
- .addAll(elements)
- .build();
- }
+ return copyFromCollection(Lists.newArrayList(elements));
}
/**
@@ -291,12 +273,9 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
}
}
- /**
- * Views the array as an immutable list. The array must have only non-null {@code E} elements.
- *
- * <p>The array must be internally created.
- */
- static <E> ImmutableList<E> asImmutableList(Object[] elements) {
+ private static <E> ImmutableList<E> copyFromCollection(
+ Collection<? extends E> collection) {
+ Object[] elements = collection.toArray();
switch (elements.length) {
case 0:
return of();
@@ -305,23 +284,29 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
return list;
default:
+ // safe to use the array without copying it
+ // as specified by Collection.toArray().
return construct(elements);
}
}
-
- private static <E> ImmutableList<E> copyFromCollection(
- Collection<? extends E> collection) {
- return asImmutableList(collection.toArray());
- }
-
+
/** {@code elements} has to be internally created array. */
private static <E> ImmutableList<E> construct(Object... elements) {
for (int i = 0; i < elements.length; i++) {
- ObjectArrays.checkElementNotNull(elements[i], i);
+ checkElementNotNull(elements[i], i);
}
return new RegularImmutableList<E>(elements);
}
+ // We do this instead of Preconditions.checkNotNull to save boxing and array
+ // creation cost.
+ private static Object checkElementNotNull(Object element, int index) {
+ if (element == null) {
+ throw new NullPointerException("at index " + index);
+ }
+ return element;
+ }
+
ImmutableList() {}
// This declaration is needed to make List.iterator() and
@@ -334,29 +319,15 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
return listIterator(0);
}
- @Override public UnmodifiableListIterator<E> listIterator(int index) {
- return new AbstractIndexedListIterator<E>(size(), index) {
- @Override
- protected E get(int index) {
- return ImmutableList.this.get(index);
- }
- };
- }
+ @Override public abstract UnmodifiableListIterator<E> listIterator(int index);
- @Override
- public int indexOf(@Nullable Object object) {
- return (object == null) ? -1 : Lists.indexOfImpl(this, object);
- }
+ // Mark these two methods with @Nullable
@Override
- public int lastIndexOf(@Nullable Object object) {
- return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object);
- }
+ public abstract int indexOf(@Nullable Object object);
@Override
- public boolean contains(@Nullable Object object) {
- return indexOf(object) >= 0;
- }
+ public abstract int lastIndexOf(@Nullable Object object);
// constrain the return type to ImmutableList<E>
@@ -367,67 +338,13 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* returned.)
*/
@Override
- public ImmutableList<E> subList(int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size());
- int length = toIndex - fromIndex;
- switch (length) {
- case 0:
- return of();
- case 1:
- return of(get(fromIndex));
- default:
- return subListUnchecked(fromIndex, toIndex);
- }
- }
-
- /**
- * Called by the default implementation of {@link #subList} when {@code
- * toIndex - fromIndex > 1}, after index validation has already been
- * performed.
- */
- ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
- return new SubList(fromIndex, toIndex - fromIndex);
- }
-
- class SubList extends ImmutableList<E> {
- transient final int offset;
- transient final int length;
-
- SubList(int offset, int length) {
- this.offset = offset;
- this.length = length;
- }
-
- @Override
- public int size() {
- return length;
- }
-
- @Override
- public E get(int index) {
- checkElementIndex(index, length);
- return ImmutableList.this.get(index + offset);
- }
-
- @Override
- public ImmutableList<E> subList(int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, length);
- return ImmutableList.this.subList(fromIndex + offset, toIndex + offset);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- }
+ public abstract ImmutableList<E> subList(int fromIndex, int toIndex);
/**
* Guaranteed to throw an exception and leave the list unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean addAll(int index, Collection<? extends E> newElements) {
throw new UnsupportedOperationException();
@@ -437,9 +354,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the list unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final E set(int index, E element) {
throw new UnsupportedOperationException();
@@ -449,9 +364,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the list unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final void add(int index, E element) {
throw new UnsupportedOperationException();
@@ -461,9 +374,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the list unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final E remove(int index) {
throw new UnsupportedOperationException();
@@ -491,8 +402,8 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
}
private static class ReverseImmutableList<E> extends ImmutableList<E> {
- private final transient ImmutableList<E> forwardList;
- private final transient int size;
+ private transient final ImmutableList<E> forwardList;
+ private transient final int size;
ReverseImmutableList(ImmutableList<E> backingList) {
this.forwardList = backingList;
@@ -530,18 +441,18 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
}
@Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size);
+ Preconditions.checkPositionIndexes(fromIndex, toIndex, size);
return forwardList.subList(
reversePosition(toIndex), reversePosition(fromIndex)).reverse();
}
@Override public E get(int index) {
- checkElementIndex(index, size);
+ Preconditions.checkElementIndex(index, size);
return forwardList.get(reverseIndex(index));
}
@Override public UnmodifiableListIterator<E> listIterator(int index) {
- checkPositionIndex(index, size);
+ Preconditions.checkPositionIndex(index, size);
final UnmodifiableListIterator<E> forward =
forwardList.listIterator(reversePosition(index));
return new UnmodifiableListIterator<E>() {
@@ -583,7 +494,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
return forwardList.isPartialView();
}
}
-
+
@Override public boolean equals(Object obj) {
return Lists.equalsImpl(this, obj);
}
@@ -641,34 +552,13 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* @since 2.0 (imported from Google Collections Library)
*/
public static final class Builder<E> extends ImmutableCollection.Builder<E> {
- private Object[] contents;
- private int size;
+ private final ArrayList<E> contents = Lists.newArrayList();
/**
* Creates a new builder. The returned builder is equivalent to the builder
* generated by {@link ImmutableList#builder}.
*/
- public Builder() {
- this(DEFAULT_INITIAL_CAPACITY);
- }
-
- // TODO(user): consider exposing this
- Builder(int capacity) {
- this.contents = new Object[capacity];
- this.size = 0;
- }
-
- /**
- * Expand the absolute capacity of the builder so it can accept at least
- * the specified number of elements without being resized.
- */
- Builder<E> ensureCapacity(int minCapacity) {
- if (contents.length < minCapacity) {
- this.contents = ObjectArrays.arraysCopyOf(
- this.contents, expandedCapacity(contents.length, minCapacity));
- }
- return this;
- }
+ public Builder() {}
/**
* Adds {@code element} to the {@code ImmutableList}.
@@ -678,9 +568,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* @throws NullPointerException if {@code element} is null
*/
@Override public Builder<E> add(E element) {
- checkNotNull(element);
- ensureCapacity(size + 1);
- contents[size++] = element;
+ contents.add(checkNotNull(element));
return this;
}
@@ -695,7 +583,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
@Override public Builder<E> addAll(Iterable<? extends E> elements) {
if (elements instanceof Collection) {
Collection<?> collection = (Collection<?>) elements;
- ensureCapacity(size + collection.size());
+ contents.ensureCapacity(contents.size() + collection.size());
}
super.addAll(elements);
return this;
@@ -710,12 +598,8 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* null element
*/
@Override public Builder<E> add(E... elements) {
- for (int i = 0; i < elements.length; i++) {
- checkElementNotNull(elements[i], i);
- }
- ensureCapacity(size + elements.length);
- System.arraycopy(elements, 0, contents, size, elements.length);
- size += elements.length;
+ contents.ensureCapacity(contents.size() + elements.length);
+ super.add(elements);
return this;
}
@@ -737,21 +621,7 @@ public abstract class ImmutableList<E> extends ImmutableCollection<E>
* the {@code Builder}.
*/
@Override public ImmutableList<E> build() {
- switch (size) {
- case 0:
- return of();
- case 1:
- @SuppressWarnings("unchecked") // guaranteed to be an E
- E singleElement = (E) contents[0];
- return of(singleElement);
- default:
- if (size == contents.length) {
- // no need to copy; any further add operations on the builder will copy the buffer
- return new RegularImmutableList<E>(contents);
- } else {
- return new RegularImmutableList<E>(ObjectArrays.arraysCopyOf(contents, size));
- }
- }
+ return copyOf(contents);
}
}
}
diff --git a/guava/src/com/google/common/collect/ImmutableListMultimap.java b/guava/src/com/google/common/collect/ImmutableListMultimap.java
index 865fa6f..3071075 100644
--- a/guava/src/com/google/common/collect/ImmutableListMultimap.java
+++ b/guava/src/com/google/common/collect/ImmutableListMultimap.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -45,10 +46,6 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this class
* are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
@@ -200,7 +197,7 @@ public class ImmutableListMultimap<K, V>
*
* @since 8.0
*/
- @Override
+ @Beta @Override
public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
super.orderKeysBy(keyComparator);
return this;
@@ -211,7 +208,7 @@ public class ImmutableListMultimap<K, V>
*
* @since 8.0
*/
- @Override
+ @Beta @Override
public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
super.orderValuesBy(valueComparator);
return this;
@@ -291,14 +288,13 @@ public class ImmutableListMultimap<K, V>
/**
* {@inheritDoc}
*
- * <p>Because an inverse of a list multimap can contain multiple pairs with
- * the same key and value, this method returns an {@code
- * ImmutableListMultimap} rather than the {@code ImmutableMultimap} specified
- * in the {@code ImmutableMultimap} class.
+ * <p>Because an inverse of a list multimap can contain multiple pairs with the same key and
+ * value, this method returns an {@code ImmutableListMultimap} rather than the
+ * {@code ImmutableMultimap} specified in the {@code ImmutableMultimap} class.
*
- * @since 11.0
+ * @since 11
*/
- @Override
+ @Beta
public ImmutableListMultimap<V, K> inverse() {
ImmutableListMultimap<V, K> result = inverse;
return (result == null) ? (inverse = invert()) : result;
@@ -318,9 +314,8 @@ public class ImmutableListMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableList<V> removeAll(Object key) {
+ @Override public ImmutableList<V> removeAll(Object key) {
throw new UnsupportedOperationException();
}
@@ -328,9 +323,8 @@ public class ImmutableListMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableList<V> replaceValues(
+ @Override public ImmutableList<V> replaceValues(
K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
}
diff --git a/guava/src/com/google/common/collect/ImmutableMap.java b/guava/src/com/google/common/collect/ImmutableMap.java
index c1d7933..0a2ef77 100644
--- a/guava/src/com/google/common/collect/ImmutableMap.java
+++ b/guava/src/com/google/common/collect/ImmutableMap.java
@@ -19,15 +19,12 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.EnumMap;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -50,10 +47,6 @@ import javax.annotation.Nullable;
* having your element type cache its own hash codes, and by making use of the
* cached values to short-circuit a slow {@code equals} algorithm.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jesse Wilson
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
@@ -66,8 +59,10 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* {@link Collections#emptyMap}, and is preferable mainly for consistency
* and maintainability of your code.
*/
+ // Casting to any type is safe because the set will never hold any elements.
+ @SuppressWarnings("unchecked")
public static <K, V> ImmutableMap<K, V> of() {
- return ImmutableBiMap.of();
+ return (ImmutableMap<K, V>) EmptyImmutableMap.INSTANCE;
}
/**
@@ -77,7 +72,8 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* maintainability of your code.
*/
public static <K, V> ImmutableMap<K, V> of(K k1, V v1) {
- return ImmutableBiMap.of(k1, v1);
+ return new SingletonImmutableMap<K, V>(
+ checkNotNull(k1), checkNotNull(v1));
}
/**
@@ -140,9 +136,9 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* throw {@link UnsupportedOperationException}.
*/
static <K, V> Entry<K, V> entryOf(K key, V value) {
- checkNotNull(key, "null key in entry: null=%s", value);
- checkNotNull(value, "null value in entry: %s=null", key);
- return Maps.immutableEntry(key, value);
+ return Maps.immutableEntry(
+ checkNotNull(key, "null key"),
+ checkNotNull(value, "null value"));
}
/**
@@ -193,7 +189,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
K key = entry.getKey();
V value = entry.getValue();
- if (entry instanceof ImmutableEntry) {
+ if (entry instanceof ImmutableEntry<?, ?>) {
checkNotNull(key);
checkNotNull(value);
@SuppressWarnings("unchecked") // all supported methods are covariant
@@ -242,7 +238,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
case 0:
return of();
case 1:
- return new SingletonImmutableBiMap<K, V>(getOnlyElement(entries));
+ return new SingletonImmutableMap<K, V>(getOnlyElement(entries));
default:
Entry<?, ?>[] entryArray
= entries.toArray(new Entry<?, ?>[entries.size()]);
@@ -274,16 +270,6 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
if (!kvMap.isPartialView()) {
return kvMap;
}
- } else if (map instanceof EnumMap) {
- EnumMap<?, ?> enumMap = (EnumMap<?, ?>) map;
- for (Map.Entry<?, ?> entry : enumMap.entrySet()) {
- checkNotNull(entry.getKey());
- checkNotNull(entry.getValue());
- }
- @SuppressWarnings("unchecked")
- // immutable collections are safe for covariant casts
- ImmutableMap<K, V> result = ImmutableEnumMap.asImmutable(new EnumMap(enumMap));
- return result;
}
@SuppressWarnings("unchecked") // we won't write to this array
@@ -292,7 +278,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
case 0:
return of();
case 1:
- return new SingletonImmutableBiMap<K, V>(entryOf(
+ return new SingletonImmutableMap<K, V>(entryOf(
entries[0].getKey(), entries[0].getValue()));
default:
for (int i = 0; i < entries.length; i++) {
@@ -310,9 +296,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* Guaranteed to throw an exception and leave the map unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final V put(K k, V v) {
throw new UnsupportedOperationException();
@@ -322,9 +306,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* Guaranteed to throw an exception and leave the map unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final V remove(Object o) {
throw new UnsupportedOperationException();
@@ -334,9 +316,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* Guaranteed to throw an exception and leave the map unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final void putAll(Map<? extends K, ? extends V> map) {
throw new UnsupportedOperationException();
@@ -346,9 +326,7 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
* Guaranteed to throw an exception and leave the map unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final void clear() {
throw new UnsupportedOperationException();
@@ -364,132 +342,44 @@ public abstract class ImmutableMap<K, V> implements Map<K, V>, Serializable {
return get(key) != null;
}
+ // Overriding to mark it Nullable
@Override
- public boolean containsValue(@Nullable Object value) {
- return value != null && Maps.containsValueImpl(this, value);
- }
+ public abstract boolean containsValue(@Nullable Object value);
// Overriding to mark it Nullable
@Override
public abstract V get(@Nullable Object key);
- private transient ImmutableSet<Entry<K, V>> entrySet;
-
/**
* Returns an immutable set of the mappings in this map. The entries are in
* the same order as the parameters used to build this map.
*/
@Override
- public ImmutableSet<Entry<K, V>> entrySet() {
- ImmutableSet<Entry<K, V>> result = entrySet;
- return (result == null) ? entrySet = createEntrySet() : result;
- }
-
- abstract ImmutableSet<Entry<K, V>> createEntrySet();
-
- private transient ImmutableSet<K> keySet;
+ public abstract ImmutableSet<Entry<K, V>> entrySet();
/**
* Returns an immutable set of the keys in this map. These keys are in
* the same order as the parameters used to build this map.
*/
@Override
- public ImmutableSet<K> keySet() {
- ImmutableSet<K> result = keySet;
- return (result == null) ? keySet = createKeySet() : result;
- }
-
- ImmutableSet<K> createKeySet() {
- return new ImmutableMapKeySet<K, V>(this);
- }
-
- private transient ImmutableCollection<V> values;
+ public abstract ImmutableSet<K> keySet();
/**
* Returns an immutable collection of the values in this map. The values are
* in the same order as the parameters used to build this map.
*/
@Override
- public ImmutableCollection<V> values() {
- ImmutableCollection<V> result = values;
- return (result == null) ? values = new ImmutableMapValues<K, V>(this) : result;
- }
-
- // cached so that this.multimapView().inverse() only computes inverse once
- private transient ImmutableSetMultimap<K, V> multimapView;
-
- /**
- * Returns a multimap view of the map.
- *
- * @since 14.0
- */
- @Beta
- public ImmutableSetMultimap<K, V> asMultimap() {
- ImmutableSetMultimap<K, V> result = multimapView;
- return (result == null) ? (multimapView = createMultimapView()) : result;
- }
-
- private ImmutableSetMultimap<K, V> createMultimapView() {
- ImmutableMap<K, ImmutableSet<V>> map = viewMapValuesAsSingletonSets();
- return new ImmutableSetMultimap<K, V>(map, map.size(), null);
- }
-
- private ImmutableMap<K, ImmutableSet<V>> viewMapValuesAsSingletonSets() {
- class MapViewOfValuesAsSingletonSets extends ImmutableMap<K, ImmutableSet<V>> {
- @Override public int size() {
- return ImmutableMap.this.size();
- }
-
- @Override public boolean containsKey(@Nullable Object key) {
- return ImmutableMap.this.containsKey(key);
- }
-
- @Override public ImmutableSet<V> get(@Nullable Object key) {
- V outerValue = ImmutableMap.this.get(key);
- return (outerValue == null) ? null : ImmutableSet.of(outerValue);
- }
-
- @Override boolean isPartialView() {
- return false;
- }
-
- @Override ImmutableSet<Entry<K, ImmutableSet<V>>> createEntrySet() {
- return new ImmutableMapEntrySet<K, ImmutableSet<V>>() {
- @Override ImmutableMap<K, ImmutableSet<V>> map() {
- return MapViewOfValuesAsSingletonSets.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, ImmutableSet<V>>> iterator() {
- final Iterator<Entry<K,V>> backingIterator = ImmutableMap.this
- .entrySet().iterator();
- return new UnmodifiableIterator<Entry<K, ImmutableSet<V>>>() {
- @Override public boolean hasNext() {
- return backingIterator.hasNext();
- }
-
- @Override public Entry<K, ImmutableSet<V>> next() {
- final Entry<K, V> backingEntry = backingIterator.next();
- return new AbstractMapEntry<K, ImmutableSet<V>>() {
- @Override public K getKey() {
- return backingEntry.getKey();
- }
-
- @Override public ImmutableSet<V> getValue() {
- return ImmutableSet.of(backingEntry.getValue());
- }
- };
- }
- };
- }
- };
- }
- }
- return new MapViewOfValuesAsSingletonSets();
- }
+ public abstract ImmutableCollection<V> values();
@Override public boolean equals(@Nullable Object object) {
- return Maps.equalsImpl(this, object);
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Map) {
+ Map<?, ?> that = (Map<?, ?>) object;
+ return this.entrySet().equals(that.entrySet());
+ }
+ return false;
}
abstract boolean isPartialView();
diff --git a/guava/src/com/google/common/collect/ImmutableMapEntrySet.java b/guava/src/com/google/common/collect/ImmutableMapEntrySet.java
deleted file mode 100644
index a6aa6e0..0000000
--- a/guava/src/com/google/common/collect/ImmutableMapEntrySet.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.Map.Entry;
-
-import javax.annotation.Nullable;
-
-/**
- * {@code entrySet()} implementation for {@link ImmutableMap}.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-abstract class ImmutableMapEntrySet<K, V> extends ImmutableSet<Entry<K, V>> {
- ImmutableMapEntrySet() {}
-
- abstract ImmutableMap<K, V> map();
-
- @Override
- public int size() {
- return map().size();
- }
-
- @Override
- public boolean contains(@Nullable Object object) {
- if (object instanceof Entry) {
- Entry<?, ?> entry = (Entry<?, ?>) object;
- V value = map().get(entry.getKey());
- return value != null && value.equals(entry.getValue());
- }
- return false;
- }
-
- @Override
- boolean isPartialView() {
- return map().isPartialView();
- }
-
- @GwtIncompatible("serialization")
- @Override
- Object writeReplace() {
- return new EntrySetSerializedForm<K, V>(map());
- }
-
- @GwtIncompatible("serialization")
- private static class EntrySetSerializedForm<K, V> implements Serializable {
- final ImmutableMap<K, V> map;
- EntrySetSerializedForm(ImmutableMap<K, V> map) {
- this.map = map;
- }
- Object readResolve() {
- return map.entrySet();
- }
- private static final long serialVersionUID = 0;
- }
-}
diff --git a/guava/src/com/google/common/collect/ImmutableMapKeySet.java b/guava/src/com/google/common/collect/ImmutableMapKeySet.java
deleted file mode 100644
index fbb59d8..0000000
--- a/guava/src/com/google/common/collect/ImmutableMapKeySet.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.Map.Entry;
-
-import javax.annotation.Nullable;
-
-/**
- * {@code keySet()} implementation for {@link ImmutableMap}.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-final class ImmutableMapKeySet<K, V> extends ImmutableSet<K> {
- private final ImmutableMap<K, V> map;
-
- ImmutableMapKeySet(ImmutableMap<K, V> map) {
- this.map = map;
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public UnmodifiableIterator<K> iterator() {
- return asList().iterator();
- }
-
- @Override
- public boolean contains(@Nullable Object object) {
- return map.containsKey(object);
- }
-
- @Override
- ImmutableList<K> createAsList() {
- final ImmutableList<Entry<K, V>> entryList = map.entrySet().asList();
- return new ImmutableAsList<K>() {
-
- @Override
- public K get(int index) {
- return entryList.get(index).getKey();
- }
-
- @Override
- ImmutableCollection<K> delegateCollection() {
- return ImmutableMapKeySet.this;
- }
-
- };
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
-
- @GwtIncompatible("serialization")
- @Override Object writeReplace() {
- return new KeySetSerializedForm<K>(map);
- }
-
- @GwtIncompatible("serialization")
- private static class KeySetSerializedForm<K> implements Serializable {
- final ImmutableMap<K, ?> map;
- KeySetSerializedForm(ImmutableMap<K, ?> map) {
- this.map = map;
- }
- Object readResolve() {
- return map.keySet();
- }
- private static final long serialVersionUID = 0;
- }
-}
diff --git a/guava/src/com/google/common/collect/ImmutableMapValues.java b/guava/src/com/google/common/collect/ImmutableMapValues.java
deleted file mode 100644
index 6ec7464..0000000
--- a/guava/src/com/google/common/collect/ImmutableMapValues.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import java.io.Serializable;
-import java.util.Map.Entry;
-
-/**
- * {@code values()} implementation for {@link ImmutableMap}.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(emulated = true)
-final class ImmutableMapValues<K, V> extends ImmutableCollection<V> {
- private final ImmutableMap<K, V> map;
-
- ImmutableMapValues(ImmutableMap<K, V> map) {
- this.map = map;
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public UnmodifiableIterator<V> iterator() {
- return Maps.valueIterator(map.entrySet().iterator());
- }
-
- @Override
- public boolean contains(Object object) {
- return map.containsValue(object);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
-
- @Override
- ImmutableList<V> createAsList() {
- final ImmutableList<Entry<K, V>> entryList = map.entrySet().asList();
- return new ImmutableAsList<V>() {
- @Override
- public V get(int index) {
- return entryList.get(index).getValue();
- }
-
- @Override
- ImmutableCollection<V> delegateCollection() {
- return ImmutableMapValues.this;
- }
- };
- }
-
- @GwtIncompatible("serialization")
- @Override Object writeReplace() {
- return new SerializedForm<V>(map);
- }
-
- @GwtIncompatible("serialization")
- private static class SerializedForm<V> implements Serializable {
- final ImmutableMap<?, V> map;
- SerializedForm(ImmutableMap<?, V> map) {
- this.map = map;
- }
- Object readResolve() {
- return map.values();
- }
- private static final long serialVersionUID = 0;
- }
-}
diff --git a/guava/src/com/google/common/collect/ImmutableMultimap.java b/guava/src/com/google/common/collect/ImmutableMultimap.java
index e29dbc1..13e213e 100644
--- a/guava/src/com/google/common/collect/ImmutableMultimap.java
+++ b/guava/src/com/google/common/collect/ImmutableMultimap.java
@@ -18,9 +18,9 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
import java.io.Serializable;
import java.util.Arrays;
@@ -30,9 +30,8 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
+import java.util.TreeMap;
import javax.annotation.Nullable;
@@ -54,16 +53,13 @@ import javax.annotation.Nullable;
* <p>In addition to methods defined by {@link Multimap}, an {@link #inverse}
* method is also supported.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(emulated = true)
-public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
- implements Serializable {
+// TODO(user): If BiMultimap graduates from labs, this class should implement it.
+public abstract class ImmutableMultimap<K, V>
+ implements Multimap<K, V>, Serializable {
/** Returns an empty multimap. */
public static <K, V> ImmutableMultimap<K, V> of() {
@@ -123,7 +119,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* value orderings, allows duplicate values, and performs better than
* {@link LinkedListMultimap}.
*/
- private static class BuilderMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
+ private static class BuilderMultimap<K, V> extends AbstractMultimap<K, V> {
BuilderMultimap() {
super(new LinkedHashMap<K, Collection<V>>());
}
@@ -134,6 +130,23 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
}
/**
+ * Multimap for {@link ImmutableMultimap.Builder} that sorts key and allows
+ * duplicate values,
+ */
+ private static class SortedKeyBuilderMultimap<K, V>
+ extends AbstractMultimap<K, V> {
+ SortedKeyBuilderMultimap(
+ Comparator<? super K> keyComparator, Multimap<K, V> multimap) {
+ super(new TreeMap<K, Collection<V>>(keyComparator));
+ putAll(multimap);
+ }
+ @Override Collection<V> createCollection() {
+ return Lists.newArrayList();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
* A builder for creating immutable multimap instances, especially
* {@code public static final} multimaps ("constant multimaps"). Example:
* <pre> {@code
@@ -153,7 +166,6 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
public static class Builder<K, V> {
Multimap<K, V> builderMultimap = new BuilderMultimap<K, V>();
- Comparator<? super K> keyComparator;
Comparator<? super V> valueComparator;
/**
@@ -228,8 +240,10 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*
* @since 8.0
*/
+ @Beta
public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
- this.keyComparator = checkNotNull(keyComparator);
+ builderMultimap = new SortedKeyBuilderMultimap<K, V>(
+ checkNotNull(keyComparator), builderMultimap);
return this;
}
@@ -238,6 +252,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*
* @since 8.0
*/
+ @Beta
public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
this.valueComparator = checkNotNull(valueComparator);
return this;
@@ -253,23 +268,6 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
Collections.sort(list, valueComparator);
}
}
- if (keyComparator != null) {
- Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
- List<Map.Entry<K, Collection<V>>> entries = Lists.newArrayList(
- builderMultimap.asMap().entrySet());
- Collections.sort(
- entries,
- Ordering.from(keyComparator).onResultOf(new Function<Entry<K, Collection<V>>, K>() {
- @Override
- public K apply(Entry<K, Collection<V>> entry) {
- return entry.getKey();
- }
- }));
- for (Map.Entry<K, Collection<V>> entry : entries) {
- sortedCopy.putAll(entry.getKey(), entry.getValue());
- }
- builderMultimap = sortedCopy;
- }
return copyOf(builderMultimap);
}
}
@@ -327,9 +325,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public ImmutableCollection<V> removeAll(Object key) {
throw new UnsupportedOperationException();
@@ -339,9 +335,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public ImmutableCollection<V> replaceValues(K key,
Iterable<? extends V> values) {
@@ -352,9 +346,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public void clear() {
throw new UnsupportedOperationException();
@@ -374,17 +366,16 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* key-value mapping in the original, the result will have a mapping with
* key and value reversed.
*
- * @since 11.0
+ * @since 11
*/
+ @Beta
public abstract ImmutableMultimap<V, K> inverse();
/**
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean put(K key, V value) {
throw new UnsupportedOperationException();
@@ -394,9 +385,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean putAll(K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
@@ -406,9 +395,7 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
throw new UnsupportedOperationException();
@@ -418,30 +405,65 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
- boolean isPartialView() {
+ boolean isPartialView(){
return map.isPartialView();
}
// accessors
@Override
+ public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
+ Collection<V> values = map.get(key);
+ return values != null && values.contains(value);
+ }
+
+ @Override
public boolean containsKey(@Nullable Object key) {
return map.containsKey(key);
}
@Override
+ public boolean containsValue(@Nullable Object value) {
+ for (Collection<V> valueCollection : map.values()) {
+ if (valueCollection.contains(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ @Override
public int size() {
return size;
}
+ @Override public boolean equals(@Nullable Object object) {
+ if (object instanceof Multimap) {
+ Multimap<?, ?> that = (Multimap<?, ?>) object;
+ return this.map.equals(that.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return map.hashCode();
+ }
+
+ @Override public String toString() {
+ return map.toString();
+ }
+
// views
/**
@@ -463,11 +485,8 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
public ImmutableMap<K, Collection<V>> asMap() {
return (ImmutableMap) map;
}
-
- @Override
- Map<K, Collection<V>> createAsMap() {
- throw new AssertionError("should never be called");
- }
+
+ private transient ImmutableCollection<Entry<K, V>> entries;
/**
* Returns an immutable collection of all key-value pairs in the multimap. Its
@@ -476,12 +495,9 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
@Override
public ImmutableCollection<Entry<K, V>> entries() {
- return (ImmutableCollection<Entry<K, V>>) super.entries();
- }
-
- @Override
- ImmutableCollection<Entry<K, V>> createEntries() {
- return new EntryCollection<K, V>(this);
+ ImmutableCollection<Entry<K, V>> result = entries;
+ return (result == null)
+ ? (entries = new EntryCollection<K, V>(this)) : result;
}
private static class EntryCollection<K, V>
@@ -493,7 +509,30 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
}
@Override public UnmodifiableIterator<Entry<K, V>> iterator() {
- return multimap.entryIterator();
+ final Iterator<? extends Entry<K, ? extends ImmutableCollection<V>>>
+ mapIterator = this.multimap.map.entrySet().iterator();
+
+ return new UnmodifiableIterator<Entry<K, V>>() {
+ K key;
+ Iterator<V> valueIterator;
+
+ @Override
+ public boolean hasNext() {
+ return (key != null && valueIterator.hasNext())
+ || mapIterator.hasNext();
+ }
+
+ @Override
+ public Entry<K, V> next() {
+ if (key == null || !valueIterator.hasNext()) {
+ Entry<K, ? extends ImmutableCollection<V>> entry
+ = mapIterator.next();
+ key = entry.getKey();
+ valueIterator = entry.getValue().iterator();
+ }
+ return Maps.immutableEntry(key, valueIterator.next());
+ }
+ };
}
@Override boolean isPartialView() {
@@ -515,34 +554,8 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
private static final long serialVersionUID = 0;
}
-
- @Override
- UnmodifiableIterator<Entry<K, V>> entryIterator() {
- final Iterator<? extends Entry<K, ? extends ImmutableCollection<V>>>
- mapIterator = map.entrySet().iterator();
-
- return new UnmodifiableIterator<Entry<K, V>>() {
- K key;
- Iterator<V> valueIterator;
-
- @Override
- public boolean hasNext() {
- return (key != null && valueIterator.hasNext())
- || mapIterator.hasNext();
- }
- @Override
- public Entry<K, V> next() {
- if (key == null || !valueIterator.hasNext()) {
- Entry<K, ? extends ImmutableCollection<V>> entry
- = mapIterator.next();
- key = entry.getKey();
- valueIterator = entry.getValue().iterator();
- }
- return Maps.immutableEntry(key, valueIterator.next());
- }
- };
- }
+ private transient ImmutableMultiset<K> keys;
/**
* Returns a collection, which may contain duplicates, of all keys. The number
@@ -552,78 +565,21 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
@Override
public ImmutableMultiset<K> keys() {
- return (ImmutableMultiset<K>) super.keys();
+ ImmutableMultiset<K> result = keys;
+ return (result == null) ? (keys = createKeys()) : result;
}
- @Override
- ImmutableMultiset<K> createKeys() {
- return new Keys();
- }
-
- @SuppressWarnings("serial") // Uses writeReplace, not default serialization
- class Keys extends ImmutableMultiset<K> {
- @Override
- public boolean contains(@Nullable Object object) {
- return containsKey(object);
- }
-
- @Override
- public int count(@Nullable Object element) {
- Collection<V> values = map.get(element);
- return (values == null) ? 0 : values.size();
- }
-
- @Override
- public Set<K> elementSet() {
- return keySet();
- }
-
- @Override
- public int size() {
- return ImmutableMultimap.this.size();
- }
-
- @Override
- ImmutableSet<Entry<K>> createEntrySet() {
- return new KeysEntrySet();
- }
-
- private class KeysEntrySet extends ImmutableMultiset<K>.EntrySet {
- @Override
- public int size() {
- return keySet().size();
- }
-
- @Override
- public UnmodifiableIterator<Entry<K>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<K>> createAsList() {
- final ImmutableList<? extends Map.Entry<K, ? extends Collection<V>>> mapEntries =
- map.entrySet().asList();
- return new ImmutableAsList<Entry<K>>() {
- @Override
- public Entry<K> get(int index) {
- Map.Entry<K, ? extends Collection<V>> entry = mapEntries.get(index);
- return Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
- }
-
- @Override
- ImmutableCollection<Entry<K>> delegateCollection() {
- return KeysEntrySet.this;
- }
- };
- }
- }
-
- @Override
- boolean isPartialView() {
- return true;
+ private ImmutableMultiset<K> createKeys() {
+ ImmutableMultiset.Builder<K> builder = ImmutableMultiset.builder();
+ for (Entry<K, ? extends ImmutableCollection<V>> entry
+ : map.entrySet()) {
+ builder.addCopies(entry.getKey(), entry.getValue().size());
}
+ return builder.build();
}
+ private transient ImmutableCollection<V> values;
+
/**
* Returns an immutable collection of the values in this multimap. Its
* iterator traverses the values for the first key, the values for the second
@@ -631,12 +587,8 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
*/
@Override
public ImmutableCollection<V> values() {
- return (ImmutableCollection<V>) super.values();
- }
-
- @Override
- ImmutableCollection<V> createValues() {
- return new Values<V>(this);
+ ImmutableCollection<V> result = values;
+ return (result == null) ? (values = new Values<V>(this)) : result;
}
private static class Values<V> extends ImmutableCollection<V> {
@@ -647,7 +599,18 @@ public abstract class ImmutableMultimap<K, V> extends AbstractMultimap<K, V>
}
@Override public UnmodifiableIterator<V> iterator() {
- return Maps.valueIterator(multimap.entries().iterator());
+ final Iterator<? extends Entry<?, V>> entryIterator
+ = multimap.entries().iterator();
+ return new UnmodifiableIterator<V>() {
+ @Override
+ public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ @Override
+ public V next() {
+ return entryIterator.next().getValue();
+ }
+ };
}
@Override
diff --git a/guava/src/com/google/common/collect/ImmutableMultiset.java b/guava/src/com/google/common/collect/ImmutableMultiset.java
index 6680a2d..bd07423 100644
--- a/guava/src/com/google/common/collect/ImmutableMultiset.java
+++ b/guava/src/com/google/common/collect/ImmutableMultiset.java
@@ -19,6 +19,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.Multiset.Entry;
import com.google.common.primitives.Ints;
import java.io.Serializable;
@@ -28,6 +29,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import javax.annotation.Nullable;
@@ -39,10 +41,6 @@ import javax.annotation.Nullable;
* multiset contains multiple instances of an element, those instances are
* consecutive in the iteration order.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jared Levy
* @author Louis Wasserman
* @since 2.0 (imported from Google Collections Library)
@@ -136,6 +134,23 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
* Returns an immutable multiset containing the given elements.
*
* <p>The multiset is ordered by the first occurrence of each element. For
+ * example, {@code ImmutableMultiset.of(2, 3, 1, 3)} yields a multiset with
+ * elements in the order {@code 2, 3, 3, 1}.
+ *
+ * @throws NullPointerException if any of {@code elements} is null
+ * @deprecated use {@link #copyOf(Object[])}. <b>This method is scheduled for
+ * deletion in January 2012.</b>
+ * @since 2.0 (changed from varargs in 6.0)
+ */
+ @Deprecated
+ public static <E> ImmutableMultiset<E> of(E[] elements) {
+ return copyOf(Arrays.asList(elements));
+ }
+
+ /**
+ * Returns an immutable multiset containing the given elements.
+ *
+ * <p>The multiset is ordered by the first occurrence of each element. For
* example, {@code ImmutableMultiset.copyOf([2, 3, 1, 3])} yields a multiset
* with elements in the order {@code 2, 3, 3, 1}.
*
@@ -206,8 +221,7 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
if (size == 0) {
return of();
}
- return new RegularImmutableMultiset<E>(
- builder.build(), Ints.saturatedCast(size));
+ return new RegularImmutableMultiset<E>(builder.build(), Ints.saturatedCast(size));
}
/**
@@ -230,7 +244,8 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
ImmutableMultiset() {}
@Override public UnmodifiableIterator<E> iterator() {
- final Iterator<Entry<E>> entryIterator = entrySet().iterator();
+ final Iterator<Entry<E>> entryIterator = entryIterator();
+
return new UnmodifiableIterator<E>() {
int remaining;
E element;
@@ -267,9 +282,7 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final int add(E element, int occurrences) {
throw new UnsupportedOperationException();
@@ -279,9 +292,7 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final int remove(Object element, int occurrences) {
throw new UnsupportedOperationException();
@@ -291,9 +302,7 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final int setCount(E element, int count) {
throw new UnsupportedOperationException();
@@ -303,9 +312,7 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
* Guaranteed to throw an exception and leave the collection unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final boolean setCount(E element, int oldCount, int newCount) {
throw new UnsupportedOperationException();
@@ -341,17 +348,39 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
private transient ImmutableSet<Entry<E>> entrySet;
@Override
- public ImmutableSet<Entry<E>> entrySet() {
+ public Set<Entry<E>> entrySet() {
ImmutableSet<Entry<E>> es = entrySet;
return (es == null) ? (entrySet = createEntrySet()) : es;
}
- abstract ImmutableSet<Entry<E>> createEntrySet();
+ abstract UnmodifiableIterator<Entry<E>> entryIterator();
+
+ abstract int distinctElements();
+
+ ImmutableSet<Entry<E>> createEntrySet() {
+ return new EntrySet<E>(this);
+ }
+
+ static class EntrySet<E> extends ImmutableSet<Entry<E>> {
+ transient final ImmutableMultiset<E> multiset;
+
+ public EntrySet(ImmutableMultiset<E> multiset) {
+ this.multiset = multiset;
+ }
+
+ @Override
+ public UnmodifiableIterator<Entry<E>> iterator() {
+ return multiset.entryIterator();
+ }
+
+ @Override
+ public int size() {
+ return multiset.distinctElements();
+ }
- abstract class EntrySet extends ImmutableSet<Entry<E>> {
@Override
boolean isPartialView() {
- return ImmutableMultiset.this.isPartialView();
+ return multiset.isPartialView();
}
@Override
@@ -361,7 +390,7 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
if (entry.getCount() <= 0) {
return false;
}
- int count = count(entry.getElement());
+ int count = multiset.count(entry.getElement());
return count == entry.getCount();
}
return false;
@@ -401,29 +430,28 @@ public abstract class ImmutableMultiset<E> extends ImmutableCollection<E>
@Override
public int hashCode() {
- return ImmutableMultiset.this.hashCode();
+ return multiset.hashCode();
}
// We can't label this with @Override, because it doesn't override anything
// in the GWT emulated version.
- // TODO(cpovirk): try making all copies of this method @GwtIncompatible instead
Object writeReplace() {
- return new EntrySetSerializedForm<E>(ImmutableMultiset.this);
+ return new EntrySetSerializedForm<E>(multiset);
}
- private static final long serialVersionUID = 0;
- }
+ static class EntrySetSerializedForm<E> implements Serializable {
+ final ImmutableMultiset<E> multiset;
- static class EntrySetSerializedForm<E> implements Serializable {
- final ImmutableMultiset<E> multiset;
+ EntrySetSerializedForm(ImmutableMultiset<E> multiset) {
+ this.multiset = multiset;
+ }
- EntrySetSerializedForm(ImmutableMultiset<E> multiset) {
- this.multiset = multiset;
+ Object readResolve() {
+ return multiset.entrySet();
+ }
}
- Object readResolve() {
- return multiset.entrySet();
- }
+ private static final long serialVersionUID = 0;
}
private static class SerializedForm implements Serializable {
diff --git a/guava/src/com/google/common/collect/ImmutableRangeMap.java b/guava/src/com/google/common/collect/ImmutableRangeMap.java
deleted file mode 100644
index 9545f1d..0000000
--- a/guava/src/com/google/common/collect/ImmutableRangeMap.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkElementIndex;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.SortedLists.KeyAbsentBehavior;
-import com.google.common.collect.SortedLists.KeyPresentBehavior;
-
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Nullable;
-
-/**
- * An immutable implementation of {@code RangeMap}, supporting all query operations efficiently.
- *
- * <p>Like all {@code RangeMap} implementations, this supports neither null keys nor null values.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-@GwtIncompatible("NavigableMap")
-public class ImmutableRangeMap<K extends Comparable<?>, V> implements RangeMap<K, V> {
-
- @SuppressWarnings("unchecked")
- private static final ImmutableRangeMap EMPTY =
- new ImmutableRangeMap(ImmutableList.of(), ImmutableList.of());
-
- /**
- * Returns an empty immutable range map.
- */
- @SuppressWarnings("unchecked")
- public static final <K extends Comparable<?>, V> ImmutableRangeMap<K, V> of() {
- return EMPTY;
- }
-
- /**
- * Returns an immutable range map mapping a single range to a single value.
- */
- public static final <K extends Comparable<?>, V> ImmutableRangeMap<K, V> of(
- Range<K> range, V value) {
- return new ImmutableRangeMap<K, V>(ImmutableList.of(range), ImmutableList.of(value));
- }
-
- @SuppressWarnings("unchecked")
- public static final <K extends Comparable<?>, V> ImmutableRangeMap<K, V> copyOf(
- RangeMap<K, ? extends V> rangeMap) {
- if (rangeMap instanceof ImmutableRangeMap) {
- return (ImmutableRangeMap<K, V>) rangeMap;
- }
- Map<Range<K>, ? extends V> map = rangeMap.asMapOfRanges();
- ImmutableList.Builder<Range<K>> rangesBuilder = new ImmutableList.Builder<Range<K>>(map.size());
- ImmutableList.Builder<V> valuesBuilder = new ImmutableList.Builder<V>(map.size());
- for (Entry<Range<K>, ? extends V> entry : map.entrySet()) {
- rangesBuilder.add(entry.getKey());
- valuesBuilder.add(entry.getValue());
- }
- return new ImmutableRangeMap<K, V>(rangesBuilder.build(), valuesBuilder.build());
- }
-
- /**
- * Returns a new builder for an immutable range map.
- */
- public static <K extends Comparable<?>, V> Builder<K, V> builder() {
- return new Builder<K, V>();
- }
-
- /**
- * A builder for immutable range maps. Overlapping ranges are prohibited.
- */
- public static final class Builder<K extends Comparable<?>, V> {
- private final RangeSet<K> keyRanges;
- private final RangeMap<K, V> rangeMap;
-
- public Builder() {
- this.keyRanges = TreeRangeSet.create();
- this.rangeMap = TreeRangeMap.create();
- }
-
- /**
- * Associates the specified range with the specified value.
- *
- * @throws IllegalArgumentException if {@code range} overlaps with any other ranges inserted
- * into this builder, or if {@code range} is empty
- */
- public Builder<K, V> put(Range<K> range, V value) {
- checkNotNull(range);
- checkNotNull(value);
- checkArgument(!range.isEmpty(), "Range must not be empty, but was %s", range);
- if (!keyRanges.complement().encloses(range)) {
- // it's an error case; we can afford an expensive lookup
- for (Entry<Range<K>, V> entry : rangeMap.asMapOfRanges().entrySet()) {
- Range<K> key = entry.getKey();
- if (key.isConnected(range) && !key.intersection(range).isEmpty()) {
- throw new IllegalArgumentException(
- "Overlapping ranges: range " + range + " overlaps with entry " + entry);
- }
- }
- }
- keyRanges.add(range);
- rangeMap.put(range, value);
- return this;
- }
-
- /**
- * Copies all associations from the specified range map into this builder.
- *
- * @throws IllegalArgumentException if any of the ranges in {@code rangeMap} overlap with ranges
- * already in this builder
- */
- public Builder<K, V> putAll(RangeMap<K, ? extends V> rangeMap) {
- for (Entry<Range<K>, ? extends V> entry : rangeMap.asMapOfRanges().entrySet()) {
- put(entry.getKey(), entry.getValue());
- }
- return this;
- }
-
- /**
- * Returns an {@code ImmutableRangeMap} containing the associations previously added to this
- * builder.
- */
- public ImmutableRangeMap<K, V> build() {
- Map<Range<K>, V> map = rangeMap.asMapOfRanges();
- ImmutableList.Builder<Range<K>> rangesBuilder =
- new ImmutableList.Builder<Range<K>>(map.size());
- ImmutableList.Builder<V> valuesBuilder = new ImmutableList.Builder<V>(map.size());
- for (Entry<Range<K>, V> entry : map.entrySet()) {
- rangesBuilder.add(entry.getKey());
- valuesBuilder.add(entry.getValue());
- }
- return new ImmutableRangeMap<K, V>(rangesBuilder.build(), valuesBuilder.build());
- }
- }
-
- private final ImmutableList<Range<K>> ranges;
- private final ImmutableList<V> values;
-
- ImmutableRangeMap(ImmutableList<Range<K>> ranges, ImmutableList<V> values) {
- this.ranges = ranges;
- this.values = values;
- }
-
- @Override
- @Nullable
- public V get(K key) {
- int index = SortedLists.binarySearch(ranges, Range.<K>lowerBoundFn(),
- Cut.belowValue(key), KeyPresentBehavior.ANY_PRESENT, KeyAbsentBehavior.NEXT_LOWER);
- if (index == -1) {
- return null;
- } else {
- Range<K> range = ranges.get(index);
- return range.contains(key) ? values.get(index) : null;
- }
- }
-
- @Override
- @Nullable
- public Map.Entry<Range<K>, V> getEntry(K key) {
- int index = SortedLists.binarySearch(ranges, Range.<K>lowerBoundFn(),
- Cut.belowValue(key), KeyPresentBehavior.ANY_PRESENT, KeyAbsentBehavior.NEXT_LOWER);
- if (index == -1) {
- return null;
- } else {
- Range<K> range = ranges.get(index);
- return range.contains(key) ? Maps.immutableEntry(range, values.get(index)) : null;
- }
- }
-
- @Override
- public Range<K> span() {
- if (ranges.isEmpty()) {
- throw new NoSuchElementException();
- }
- Range<K> firstRange = ranges.get(0);
- Range<K> lastRange = ranges.get(ranges.size() - 1);
- return Range.create(firstRange.lowerBound, lastRange.upperBound);
- }
-
- @Override
- public void put(Range<K> range, V value) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void putAll(RangeMap<K, V> rangeMap) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(Range<K> range) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ImmutableMap<Range<K>, V> asMapOfRanges() {
- if (ranges.isEmpty()) {
- return ImmutableMap.of();
- }
- RegularImmutableSortedSet<Range<K>> rangeSet =
- new RegularImmutableSortedSet<Range<K>>(ranges, Range.RANGE_LEX_ORDERING);
- return new RegularImmutableSortedMap<Range<K>, V>(rangeSet, values);
- }
-
- @Override
- public ImmutableRangeMap<K, V> subRangeMap(final Range<K> range) {
- if (checkNotNull(range).isEmpty()) {
- return ImmutableRangeMap.of();
- } else if (ranges.isEmpty() || range.encloses(span())) {
- return this;
- }
- int lowerIndex = SortedLists.binarySearch(
- ranges, Range.<K>upperBoundFn(), range.lowerBound,
- KeyPresentBehavior.FIRST_AFTER, KeyAbsentBehavior.NEXT_HIGHER);
- int upperIndex = SortedLists.binarySearch(ranges,
- Range.<K>lowerBoundFn(), range.upperBound,
- KeyPresentBehavior.ANY_PRESENT, KeyAbsentBehavior.NEXT_HIGHER);
- if (lowerIndex >= upperIndex) {
- return ImmutableRangeMap.of();
- }
- final int off = lowerIndex;
- final int len = upperIndex - lowerIndex;
- ImmutableList<Range<K>> subRanges = new ImmutableList<Range<K>>() {
- @Override
- public int size() {
- return len;
- }
-
- @Override
- public Range<K> get(int index) {
- checkElementIndex(index, len);
- if (index == 0 || index == len - 1) {
- return ranges.get(index + off).intersection(range);
- } else {
- return ranges.get(index + off);
- }
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- };
- final ImmutableRangeMap<K, V> outer = this;
- return new ImmutableRangeMap<K, V>(
- subRanges, values.subList(lowerIndex, upperIndex)) {
- @Override
- public ImmutableRangeMap<K, V> subRangeMap(Range<K> subRange) {
- if (range.isConnected(subRange)) {
- return outer.subRangeMap(subRange.intersection(range));
- } else {
- return ImmutableRangeMap.of();
- }
- }
- };
- }
-
- @Override
- public int hashCode() {
- return asMapOfRanges().hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (o instanceof RangeMap) {
- RangeMap<?, ?> rangeMap = (RangeMap<?, ?>) o;
- return asMapOfRanges().equals(rangeMap.asMapOfRanges());
- }
- return false;
- }
-
- @Override
- public String toString() {
- return asMapOfRanges().toString();
- }
-}
diff --git a/guava/src/com/google/common/collect/ImmutableRangeSet.java b/guava/src/com/google/common/collect/ImmutableRangeSet.java
deleted file mode 100644
index bd21bbe..0000000
--- a/guava/src/com/google/common/collect/ImmutableRangeSet.java
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkElementIndex;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_LOWER;
-import static com.google.common.collect.SortedLists.KeyPresentBehavior.ANY_PRESENT;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.SortedLists.KeyAbsentBehavior;
-import com.google.common.collect.SortedLists.KeyPresentBehavior;
-import com.google.common.primitives.Ints;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * An efficient immutable implementation of a {@link RangeSet}.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-public final class ImmutableRangeSet<C extends Comparable> extends AbstractRangeSet<C>
- implements Serializable {
-
- @SuppressWarnings("unchecked")
- private static final ImmutableRangeSet EMPTY = new ImmutableRangeSet(ImmutableList.of());
-
- @SuppressWarnings("unchecked")
- private static final ImmutableRangeSet ALL = new ImmutableRangeSet(ImmutableList.of(Range.all()));
-
- /**
- * Returns an empty immutable range set.
- */
- @SuppressWarnings("unchecked")
- public static <C extends Comparable> ImmutableRangeSet<C> of() {
- return EMPTY;
- }
-
- /**
- * Returns an immutable range set containing the single range {@link Range#all()}.
- */
- @SuppressWarnings("unchecked")
- static <C extends Comparable> ImmutableRangeSet<C> all() {
- return ALL;
- }
-
- /**
- * Returns an immutable range set containing the specified single range. If {@link Range#isEmpty()
- * range.isEmpty()}, this is equivalent to {@link ImmutableRangeSet#of()}.
- */
- public static <C extends Comparable> ImmutableRangeSet<C> of(Range<C> range) {
- checkNotNull(range);
- if (range.isEmpty()) {
- return of();
- } else if (range.equals(Range.all())) {
- return all();
- } else {
- return new ImmutableRangeSet<C>(ImmutableList.of(range));
- }
- }
-
- /**
- * Returns an immutable copy of the specified {@code RangeSet}.
- */
- public static <C extends Comparable> ImmutableRangeSet<C> copyOf(RangeSet<C> rangeSet) {
- checkNotNull(rangeSet);
- if (rangeSet.isEmpty()) {
- return of();
- } else if (rangeSet.encloses(Range.<C>all())) {
- return all();
- }
-
- if (rangeSet instanceof ImmutableRangeSet) {
- ImmutableRangeSet<C> immutableRangeSet = (ImmutableRangeSet<C>) rangeSet;
- if (!immutableRangeSet.isPartialView()) {
- return immutableRangeSet;
- }
- }
- return new ImmutableRangeSet<C>(ImmutableList.copyOf(rangeSet.asRanges()));
- }
-
- ImmutableRangeSet(ImmutableList<Range<C>> ranges) {
- this.ranges = ranges;
- }
-
- private ImmutableRangeSet(ImmutableList<Range<C>> ranges, ImmutableRangeSet<C> complement) {
- this.ranges = ranges;
- this.complement = complement;
- }
-
- private transient final ImmutableList<Range<C>> ranges;
-
- @Override
- public boolean encloses(Range<C> otherRange) {
- int index = SortedLists.binarySearch(ranges,
- Range.<C>lowerBoundFn(),
- otherRange.lowerBound,
- Ordering.natural(),
- ANY_PRESENT,
- NEXT_LOWER);
- return index != -1 && ranges.get(index).encloses(otherRange);
- }
-
- @Override
- public Range<C> rangeContaining(C value) {
- int index = SortedLists.binarySearch(ranges,
- Range.<C>lowerBoundFn(),
- Cut.belowValue(value),
- Ordering.natural(),
- ANY_PRESENT,
- NEXT_LOWER);
- if (index != -1) {
- Range<C> range = ranges.get(index);
- return range.contains(value) ? range : null;
- }
- return null;
- }
-
- @Override
- public Range<C> span() {
- if (ranges.isEmpty()) {
- throw new NoSuchElementException();
- }
- return Range.create(
- ranges.get(0).lowerBound,
- ranges.get(ranges.size() - 1).upperBound);
- }
-
- @Override
- public boolean isEmpty() {
- return ranges.isEmpty();
- }
-
- @Override
- public void add(Range<C> range) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addAll(RangeSet<C> other) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(Range<C> range) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeAll(RangeSet<C> other) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ImmutableSet<Range<C>> asRanges() {
- if (ranges.isEmpty()) {
- return ImmutableSet.of();
- }
- return new RegularImmutableSortedSet<Range<C>>(ranges, Range.RANGE_LEX_ORDERING);
- }
-
- private transient ImmutableRangeSet<C> complement;
-
- private final class ComplementRanges extends ImmutableList<Range<C>> {
- // True if the "positive" range set is empty or bounded below.
- private final boolean positiveBoundedBelow;
-
- // True if the "positive" range set is empty or bounded above.
- private final boolean positiveBoundedAbove;
-
- private final int size;
-
- ComplementRanges() {
- this.positiveBoundedBelow = ranges.get(0).hasLowerBound();
- this.positiveBoundedAbove = Iterables.getLast(ranges).hasUpperBound();
-
- int size = ranges.size() - 1;
- if (positiveBoundedBelow) {
- size++;
- }
- if (positiveBoundedAbove) {
- size++;
- }
- this.size = size;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public Range<C> get(int index) {
- checkElementIndex(index, size);
-
- Cut<C> lowerBound;
- if (positiveBoundedBelow) {
- lowerBound = (index == 0) ? Cut.<C>belowAll() : ranges.get(index - 1).upperBound;
- } else {
- lowerBound = ranges.get(index).upperBound;
- }
-
- Cut<C> upperBound;
- if (positiveBoundedAbove && index == size - 1) {
- upperBound = Cut.<C>aboveAll();
- } else {
- upperBound = ranges.get(index + (positiveBoundedBelow ? 0 : 1)).lowerBound;
- }
-
- return Range.create(lowerBound, upperBound);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- }
-
- @Override
- public ImmutableRangeSet<C> complement() {
- ImmutableRangeSet<C> result = complement;
- if (result != null) {
- return result;
- } else if (ranges.isEmpty()) {
- return complement = all();
- } else if (ranges.size() == 1 && ranges.get(0).equals(Range.all())) {
- return complement = of();
- } else {
- ImmutableList<Range<C>> complementRanges = new ComplementRanges();
- result = complement = new ImmutableRangeSet<C>(complementRanges, this);
- }
- return result;
- }
-
- /**
- * Returns a list containing the nonempty intersections of {@code range}
- * with the ranges in this range set.
- */
- private ImmutableList<Range<C>> intersectRanges(final Range<C> range) {
- if (ranges.isEmpty() || range.isEmpty()) {
- return ImmutableList.of();
- } else if (range.encloses(span())) {
- return ranges;
- }
-
- final int fromIndex;
- if (range.hasLowerBound()) {
- fromIndex = SortedLists.binarySearch(
- ranges, Range.<C>upperBoundFn(), range.lowerBound, KeyPresentBehavior.FIRST_AFTER,
- KeyAbsentBehavior.NEXT_HIGHER);
- } else {
- fromIndex = 0;
- }
-
- int toIndex;
- if (range.hasUpperBound()) {
- toIndex = SortedLists.binarySearch(
- ranges, Range.<C>lowerBoundFn(), range.upperBound, KeyPresentBehavior.FIRST_PRESENT,
- KeyAbsentBehavior.NEXT_HIGHER);
- } else {
- toIndex = ranges.size();
- }
- final int length = toIndex - fromIndex;
- if (length == 0) {
- return ImmutableList.of();
- } else {
- return new ImmutableList<Range<C>>() {
- @Override
- public int size() {
- return length;
- }
-
- @Override
- public Range<C> get(int index) {
- checkElementIndex(index, length);
- if (index == 0 || index == length - 1) {
- return ranges.get(index + fromIndex).intersection(range);
- } else {
- return ranges.get(index + fromIndex);
- }
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- };
- }
- }
-
- /**
- * Returns a view of the intersection of this range set with the given range.
- */
- @Override
- public ImmutableRangeSet<C> subRangeSet(Range<C> range) {
- if (!isEmpty()) {
- Range<C> span = span();
- if (range.encloses(span)) {
- return this;
- } else if (range.isConnected(span)) {
- return new ImmutableRangeSet<C>(intersectRanges(range));
- }
- }
- return of();
- }
-
- /**
- * Returns an {@link ImmutableSortedSet} containing the same values in the given domain
- * {@linkplain RangeSet#contains contained} by this range set.
- *
- * <p><b>Note:</b> {@code a.asSet(d).equals(b.asSet(d))} does not imply {@code a.equals(b)}! For
- * example, {@code a} and {@code b} could be {@code [2..4]} and {@code (1..5)}, or the empty
- * ranges {@code [3..3)} and {@code [4..4)}.
- *
- * <p><b>Warning:</b> Be extremely careful what you do with the {@code asSet} view of a large
- * range set (such as {@code ImmutableRangeSet.of(Range.greaterThan(0))}). Certain operations on
- * such a set can be performed efficiently, but others (such as {@link Set#hashCode} or
- * {@link Collections#frequency}) can cause major performance problems.
- *
- * <p>The returned set's {@link Object#toString} method returns a short-hand form of the set's
- * contents, such as {@code "[1..100]}"}.
- *
- * @throws IllegalArgumentException if neither this range nor the domain has a lower bound, or if
- * neither has an upper bound
- */
- public ImmutableSortedSet<C> asSet(DiscreteDomain<C> domain) {
- checkNotNull(domain);
- if (isEmpty()) {
- return ImmutableSortedSet.of();
- }
- Range<C> span = span().canonical(domain);
- if (!span.hasLowerBound()) {
- // according to the spec of canonical, neither this ImmutableRangeSet nor
- // the range have a lower bound
- throw new IllegalArgumentException(
- "Neither the DiscreteDomain nor this range set are bounded below");
- } else if (!span.hasUpperBound()) {
- try {
- domain.maxValue();
- } catch (NoSuchElementException e) {
- throw new IllegalArgumentException(
- "Neither the DiscreteDomain nor this range set are bounded above");
- }
- }
-
- return new AsSet(domain);
- }
-
- private final class AsSet extends ImmutableSortedSet<C> {
- private final DiscreteDomain<C> domain;
-
- AsSet(DiscreteDomain<C> domain) {
- super(Ordering.natural());
- this.domain = domain;
- }
-
- private transient Integer size;
-
- @Override
- public int size() {
- // racy single-check idiom
- Integer result = size;
- if (result == null) {
- long total = 0;
- for (Range<C> range : ranges) {
- total += range.asSet(domain).size();
- if (total >= Integer.MAX_VALUE) {
- break;
- }
- }
- result = size = Ints.saturatedCast(total);
- }
- return result.intValue();
- }
-
- @Override
- public UnmodifiableIterator<C> iterator() {
- return new AbstractIterator<C>() {
- final Iterator<Range<C>> rangeItr = ranges.iterator();
- Iterator<C> elemItr = Iterators.emptyIterator();
-
- @Override
- protected C computeNext() {
- while (!elemItr.hasNext()) {
- if (rangeItr.hasNext()) {
- elemItr = rangeItr.next().asSet(domain).iterator();
- } else {
- return endOfData();
- }
- }
- return elemItr.next();
- }
- };
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- public UnmodifiableIterator<C> descendingIterator() {
- return new AbstractIterator<C>() {
- final Iterator<Range<C>> rangeItr = ranges.reverse().iterator();
- Iterator<C> elemItr = Iterators.emptyIterator();
-
- @Override
- protected C computeNext() {
- while (!elemItr.hasNext()) {
- if (rangeItr.hasNext()) {
- elemItr = rangeItr.next().asSet(domain).descendingIterator();
- } else {
- return endOfData();
- }
- }
- return elemItr.next();
- }
- };
- }
-
- ImmutableSortedSet<C> subSet(Range<C> range) {
- return subRangeSet(range).asSet(domain);
- }
-
- @Override
- ImmutableSortedSet<C> headSetImpl(C toElement, boolean inclusive) {
- return subSet(Range.upTo(toElement, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- ImmutableSortedSet<C> subSetImpl(
- C fromElement, boolean fromInclusive, C toElement, boolean toInclusive) {
- if (!fromInclusive && !toInclusive && Range.compareOrThrow(fromElement, toElement) == 0) {
- return ImmutableSortedSet.of();
- }
- return subSet(Range.range(
- fromElement, BoundType.forBoolean(fromInclusive),
- toElement, BoundType.forBoolean(toInclusive)));
- }
-
- @Override
- ImmutableSortedSet<C> tailSetImpl(C fromElement, boolean inclusive) {
- return subSet(Range.downTo(fromElement, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public boolean contains(@Nullable Object o) {
- if (o == null) {
- return false;
- }
- try {
- @SuppressWarnings("unchecked") // we catch CCE's
- C c = (C) o;
- return ImmutableRangeSet.this.contains(c);
- } catch (ClassCastException e) {
- return false;
- }
- }
-
- @Override
- int indexOf(Object target) {
- if (contains(target)) {
- @SuppressWarnings("unchecked") // if it's contained, it's definitely a C
- C c = (C) target;
- long total = 0;
- for (Range<C> range : ranges) {
- if (range.contains(c)) {
- return Ints.saturatedCast(total + range.asSet(domain).indexOf(c));
- } else {
- total += range.asSet(domain).size();
- }
- }
- throw new AssertionError("impossible");
- }
- return -1;
- }
-
- @Override
- boolean isPartialView() {
- return ranges.isPartialView();
- }
-
- @Override
- public String toString() {
- return ranges.toString();
- }
-
- @Override
- Object writeReplace() {
- return new AsSetSerializedForm<C>(ranges, domain);
- }
- }
-
- private static class AsSetSerializedForm<C extends Comparable> implements Serializable {
- private final ImmutableList<Range<C>> ranges;
- private final DiscreteDomain<C> domain;
-
- AsSetSerializedForm(ImmutableList<Range<C>> ranges, DiscreteDomain<C> domain) {
- this.ranges = ranges;
- this.domain = domain;
- }
-
- Object readResolve() {
- return new ImmutableRangeSet<C>(ranges).asSet(domain);
- }
- }
-
- boolean isPartialView() {
- return ranges.isPartialView();
- }
-
- /**
- * Returns a new builder for an immutable range set.
- */
- public static <C extends Comparable<?>> Builder<C> builder() {
- return new Builder<C>();
- }
-
- /**
- * A builder for immutable range sets.
- */
- public static class Builder<C extends Comparable<?>> {
- private final RangeSet<C> rangeSet;
-
- public Builder() {
- this.rangeSet = TreeRangeSet.create();
- }
-
- /**
- * Add the specified range to this builder. Adjacent/abutting ranges are permitted, but
- * empty ranges, or ranges with nonempty overlap, are forbidden.
- *
- * @throws IllegalArgumentException if {@code range} is empty or has nonempty intersection with
- * any ranges already added to the builder
- */
- public Builder<C> add(Range<C> range) {
- if (range.isEmpty()) {
- throw new IllegalArgumentException("range must not be empty, but was " + range);
- } else if (!rangeSet.complement().encloses(range)) {
- for (Range<C> currentRange : rangeSet.asRanges()) {
- checkArgument(
- !currentRange.isConnected(range) || currentRange.intersection(range).isEmpty(),
- "Ranges may not overlap, but received %s and %s", currentRange, range);
- }
- throw new AssertionError("should have thrown an IAE above");
- }
- rangeSet.add(range);
- return this;
- }
-
- /**
- * Add all ranges from the specified range set to this builder. Duplicate or connected ranges
- * are permitted, and will be merged in the resulting immutable range set.
- */
- public Builder<C> addAll(RangeSet<C> ranges) {
- for (Range<C> range : ranges.asRanges()) {
- add(range);
- }
- return this;
- }
-
- /**
- * Returns an {@code ImmutableRangeSet} containing the ranges added to this builder.
- */
- public ImmutableRangeSet<C> build() {
- return copyOf(rangeSet);
- }
- }
-
- private static final class SerializedForm<C extends Comparable> implements Serializable {
- private final ImmutableList<Range<C>> ranges;
-
- SerializedForm(ImmutableList<Range<C>> ranges) {
- this.ranges = ranges;
- }
-
- Object readResolve() {
- if (ranges.isEmpty()) {
- return of();
- } else if (ranges.equals(ImmutableList.of(Range.all()))) {
- return all();
- } else {
- return new ImmutableRangeSet<C>(ranges);
- }
- }
- }
-
- Object writeReplace() {
- return new SerializedForm<C>(ranges);
- }
-}
diff --git a/guava/src/com/google/common/collect/ImmutableSet.java b/guava/src/com/google/common/collect/ImmutableSet.java
index b96829c..fb60ce6 100644
--- a/guava/src/com/google/common/collect/ImmutableSet.java
+++ b/guava/src/com/google/common/collect/ImmutableSet.java
@@ -20,14 +20,12 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.primitives.Ints;
import java.io.Serializable;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@@ -59,10 +57,6 @@ import javax.annotation.Nullable;
* outside its package as it has no public or protected constructors. Thus,
* instances of this type are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @see ImmutableList
* @see ImmutableMap
* @author Kevin Bourrillion
@@ -102,7 +96,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @throws NullPointerException if any element is null
*/
public static <E> ImmutableSet<E> of(E e1, E e2) {
- return construct(2, e1, e2);
+ return construct(e1, e2);
}
/**
@@ -113,7 +107,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @throws NullPointerException if any element is null
*/
public static <E> ImmutableSet<E> of(E e1, E e2, E e3) {
- return construct(3, e1, e2, e3);
+ return construct(e1, e2, e3);
}
/**
@@ -124,7 +118,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @throws NullPointerException if any element is null
*/
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4) {
- return construct(4, e1, e2, e3, e4);
+ return construct(e1, e2, e3, e4);
}
/**
@@ -135,7 +129,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @throws NullPointerException if any element is null
*/
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5) {
- return construct(5, e1, e2, e3, e4, e5);
+ return construct(e1, e2, e3, e4, e5);
}
/**
@@ -156,72 +150,59 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
elements[3] = e4;
elements[4] = e5;
elements[5] = e6;
- System.arraycopy(others, 0, elements, paramCount, others.length);
- return construct(elements.length, elements);
+ for (int i = paramCount; i < elements.length; i++) {
+ elements[i] = others[i - paramCount];
+ }
+ return construct(elements);
}
- /**
- * Constructs an {@code ImmutableSet} from the first {@code n} elements of the specified array.
- * If {@code k} is the size of the returned {@code ImmutableSet}, then the unique elements of
- * {@code elements} will be in the first {@code k} positions, and {@code elements[i] == null} for
- * {@code k <= i < n}.
- *
- * <p>This may modify {@code elements}. Additionally, if {@code n == elements.length} and
- * {@code elements} contains no duplicates, {@code elements} may be used without copying in the
- * returned {@code ImmutableSet}, in which case it may no longer be modified.
- *
- * <p>{@code elements} may contain only values of type {@code E}.
- *
- * @throws NullPointerException if any of the first {@code n} elements of {@code elements} is
- * null
- */
- private static <E> ImmutableSet<E> construct(int n, Object... elements) {
- switch (n) {
- case 0:
- return of();
- case 1:
- @SuppressWarnings("unchecked") // safe; elements contains only E's
- E elem = (E) elements[0];
- return of(elem);
- default:
- // continue below to handle the general case
- }
- int tableSize = chooseTableSize(n);
+ /** {@code elements} has to be internally created array. */
+ private static <E> ImmutableSet<E> construct(Object... elements) {
+ int tableSize = chooseTableSize(elements.length);
Object[] table = new Object[tableSize];
int mask = tableSize - 1;
+ ArrayList<Object> uniqueElementsList = null;
int hashCode = 0;
- int uniques = 0;
- for (int i = 0; i < n; i++) {
- Object element = ObjectArrays.checkElementNotNull(elements[i], i);
+ for (int i = 0; i < elements.length; i++) {
+ Object element = elements[i];
int hash = element.hashCode();
for (int j = Hashing.smear(hash); ; j++) {
int index = j & mask;
Object value = table[index];
if (value == null) {
+ if (uniqueElementsList != null) {
+ uniqueElementsList.add(element);
+ }
// Came to an empty slot. Put the element here.
- elements[uniques++] = element;
table[index] = element;
hashCode += hash;
break;
} else if (value.equals(element)) {
+ if (uniqueElementsList == null) {
+ // first dup
+ uniqueElementsList = new ArrayList<Object>(elements.length);
+ for (int k = 0; k < i; k++) {
+ Object previous = elements[k];
+ uniqueElementsList.add(previous);
+ }
+ }
break;
}
}
}
- Arrays.fill(elements, uniques, n, null);
- if (uniques == 1) {
+ Object[] uniqueElements = uniqueElementsList == null
+ ? elements
+ : uniqueElementsList.toArray();
+ if (uniqueElements.length == 1) {
// There is only one element or elements are all duplicates
@SuppressWarnings("unchecked") // we are careful to only pass in E
- E element = (E) elements[0];
+ E element = (E) uniqueElements[0];
return new SingletonImmutableSet<E>(element, hashCode);
- } else if (tableSize != chooseTableSize(uniques)) {
+ } else if (tableSize > 2 * chooseTableSize(uniqueElements.length)) {
// Resize the table when the array includes too many duplicates.
// when this happens, we have already made a copy
- return construct(uniques, elements);
+ return construct(uniqueElements);
} else {
- Object[] uniqueElements = (uniques < elements.length)
- ? ObjectArrays.arraysCopyOf(elements, uniques)
- : elements;
return new RegularImmutableSet<E>(uniqueElements, hashCode, table, mask);
}
}
@@ -229,30 +210,18 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
// We use power-of-2 tables, and this is the highest int that's a power of 2
static final int MAX_TABLE_SIZE = Ints.MAX_POWER_OF_TWO;
- // Represents how tightly we can pack things, as a maximum.
- private static final double DESIRED_LOAD_FACTOR = 0.7;
-
// If the set has this many elements, it will "max out" the table size
- private static final int CUTOFF =
- (int) Math.floor(MAX_TABLE_SIZE * DESIRED_LOAD_FACTOR);
+ static final int CUTOFF = 1 << 29;
/**
* Returns an array size suitable for the backing array of a hash table that
- * uses open addressing with linear probing in its implementation. The
- * returned size is the smallest power of two that can hold setSize elements
- * with the desired load factor.
- *
- * <p>Do not call this method with setSize < 2.
+ * uses linear probing in its implementation. The returned size is the
+ * smallest power of two that can hold setSize elements while being at most
+ * 50% full, if possible.
*/
- @VisibleForTesting static int chooseTableSize(int setSize) {
- // Correct the size for open addressing to match desired load factor.
+ static int chooseTableSize(int setSize) {
if (setSize < CUTOFF) {
- // Round up to the next highest power of 2.
- int tableSize = Integer.highestOneBit(setSize - 1) << 1;
- while (tableSize * DESIRED_LOAD_FACTOR < setSize) {
- tableSize <<= 1;
- }
- return tableSize;
+ return Integer.highestOneBit(setSize) << 2;
}
// The table can't be completely full or we'll get infinite reprobes
@@ -277,7 +246,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
case 1:
return of(elements[0]);
default:
- return construct(elements.length, elements.clone());
+ return construct(elements.clone());
}
}
@@ -312,19 +281,9 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @throws NullPointerException if any of {@code elements} is null
*/
public static <E> ImmutableSet<E> copyOf(Iterator<? extends E> elements) {
- // We special-case for 0 or 1 elements, but anything further is madness.
- if (!elements.hasNext()) {
- return of();
- }
- E first = elements.next();
- if (!elements.hasNext()) {
- return of(first);
- } else {
- return new ImmutableSet.Builder<E>()
- .add(first)
- .addAll(elements)
- .build();
- }
+ // TODO(benyu): here we could avoid toArray() for 0 or 1-element list,
+ // worth it?
+ return copyFromCollection(Lists.newArrayList(elements));
}
/**
@@ -366,12 +325,6 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
if (!set.isPartialView()) {
return set;
}
- } else if (elements instanceof EnumSet) {
- EnumSet<?> enumSet = EnumSet.copyOf((EnumSet<?>) elements);
- @SuppressWarnings("unchecked")
- // immutable collections are safe for covariant casts
- ImmutableSet<E> result = (ImmutableSet<E>) ImmutableEnumSet.asImmutable(enumSet);
- return result;
}
return copyFromCollection(elements);
}
@@ -389,7 +342,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
default:
// safe to use the array without copying it
// as specified by Collection.toArray().
- return construct(elements.length, elements);
+ return construct(elements);
}
}
@@ -438,16 +391,30 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
return false;
}
+ /*
+ * The cast is safe because the only way to create an instance is via the
+ * create() method above, which only permits elements of type E.
+ */
+ @SuppressWarnings("unchecked")
@Override public UnmodifiableIterator<E> iterator() {
- return asList().iterator();
+ return (UnmodifiableIterator<E>) Iterators.forArray(elements);
}
@Override public Object[] toArray() {
- return asList().toArray();
+ Object[] array = new Object[size()];
+ System.arraycopy(elements, 0, array, 0, size());
+ return array;
}
@Override public <T> T[] toArray(T[] array) {
- return asList().toArray(array);
+ int size = size();
+ if (array.length < size) {
+ array = ObjectArrays.newArray(array, size);
+ } else if (array.length > size) {
+ array[size] = null;
+ }
+ System.arraycopy(elements, 0, array, 0, size);
+ return array;
}
@Override public boolean containsAll(Collection<?> targets) {
@@ -473,7 +440,65 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
}
@Override ImmutableList<E> createAsList() {
- return new RegularImmutableAsList<E>(this, elements);
+ return new ImmutableAsList<E>(elements, this);
+ }
+ }
+
+ /** such as ImmutableMap.keySet() */
+ abstract static class TransformedImmutableSet<D, E> extends ImmutableSet<E> {
+ final D[] source;
+ final int hashCode;
+
+ TransformedImmutableSet(D[] source, int hashCode) {
+ this.source = source;
+ this.hashCode = hashCode;
+ }
+
+ abstract E transform(D element);
+
+ @Override
+ public int size() {
+ return source.length;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public UnmodifiableIterator<E> iterator() {
+ return new AbstractIndexedListIterator<E>(source.length) {
+ @Override protected E get(int index) {
+ return transform(source[index]);
+ }
+ };
+ }
+
+ @Override public Object[] toArray() {
+ return toArray(new Object[size()]);
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ int size = size();
+ if (array.length < size) {
+ array = ObjectArrays.newArray(array, size);
+ } else if (array.length > size) {
+ array[size] = null;
+ }
+
+ // Writes will produce ArrayStoreException when the toArray() doc requires
+ Object[] objectArray = array;
+ for (int i = 0; i < source.length; i++) {
+ objectArray[i] = transform(source[i]);
+ }
+ return array;
+ }
+
+ @Override public final int hashCode() {
+ return hashCode;
+ }
+
+ @Override boolean isHashCodeFast() {
+ return true;
}
}
@@ -524,34 +549,14 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @since 2.0 (imported from Google Collections Library)
*/
public static class Builder<E> extends ImmutableCollection.Builder<E> {
- Object[] contents;
- int size;
+ // accessed directly by ImmutableSortedSet
+ final ArrayList<E> contents = Lists.newArrayList();
/**
* Creates a new builder. The returned builder is equivalent to the builder
* generated by {@link ImmutableSet#builder}.
*/
- public Builder() {
- this(DEFAULT_INITIAL_CAPACITY);
- }
-
- Builder(int capacity) {
- checkArgument(capacity >= 0, "capacity must be >= 0 but was %s", capacity);
- this.contents = new Object[capacity];
- this.size = 0;
- }
-
- /**
- * Expand the absolute capacity of the builder so it can accept at least
- * the specified number of elements without being resized.
- */
- Builder<E> ensureCapacity(int minCapacity) {
- if (contents.length < minCapacity) {
- contents = ObjectArrays.arraysCopyOf(
- contents, expandedCapacity(contents.length, minCapacity));
- }
- return this;
- }
+ public Builder() {}
/**
* Adds {@code element} to the {@code ImmutableSet}. If the {@code
@@ -563,8 +568,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* @throws NullPointerException if {@code element} is null
*/
@Override public Builder<E> add(E element) {
- ensureCapacity(size + 1);
- contents[size++] = checkNotNull(element);
+ contents.add(checkNotNull(element));
return this;
}
@@ -578,12 +582,8 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* null element
*/
@Override public Builder<E> add(E... elements) {
- for (int i = 0; i < elements.length; i++) {
- ObjectArrays.checkElementNotNull(elements[i], i);
- }
- ensureCapacity(size + elements.length);
- System.arraycopy(elements, 0, contents, size, elements.length);
- size += elements.length;
+ contents.ensureCapacity(contents.size() + elements.length);
+ super.add(elements);
return this;
}
@@ -599,7 +599,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
@Override public Builder<E> addAll(Iterable<? extends E> elements) {
if (elements instanceof Collection) {
Collection<?> collection = (Collection<?>) elements;
- ensureCapacity(size + collection.size());
+ contents.ensureCapacity(contents.size() + collection.size());
}
super.addAll(elements);
return this;
@@ -624,11 +624,7 @@ public abstract class ImmutableSet<E> extends ImmutableCollection<E>
* the {@code Builder}.
*/
@Override public ImmutableSet<E> build() {
- ImmutableSet<E> result = construct(size, contents);
- // construct has the side effect of deduping contents, so we update size
- // accordingly.
- size = result.size();
- return result;
+ return copyOf(contents);
}
}
}
diff --git a/guava/src/com/google/common/collect/ImmutableSetMultimap.java b/guava/src/com/google/common/collect/ImmutableSetMultimap.java
index 6eedf1a..04a6978 100644
--- a/guava/src/com/google/common/collect/ImmutableSetMultimap.java
+++ b/guava/src/com/google/common/collect/ImmutableSetMultimap.java
@@ -18,9 +18,9 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
import java.io.IOException;
import java.io.InvalidObjectException;
@@ -28,12 +28,10 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
+import java.util.TreeMap;
import javax.annotation.Nullable;
@@ -53,10 +51,6 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this class
* are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Mike Ward
* @since 2.0 (imported from Google Collections Library)
*/
@@ -151,7 +145,7 @@ public class ImmutableSetMultimap<K, V>
* Multimap for {@link ImmutableSetMultimap.Builder} that maintains key
* and value orderings and performs better than {@link LinkedHashMultimap}.
*/
- private static class BuilderMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
+ private static class BuilderMultimap<K, V> extends AbstractMultimap<K, V> {
BuilderMultimap() {
super(new LinkedHashMap<K, Collection<V>>());
}
@@ -162,6 +156,23 @@ public class ImmutableSetMultimap<K, V>
}
/**
+ * Multimap for {@link ImmutableSetMultimap.Builder} that sorts keys and
+ * maintains value orderings.
+ */
+ private static class SortedKeyBuilderMultimap<K, V>
+ extends AbstractMultimap<K, V> {
+ SortedKeyBuilderMultimap(
+ Comparator<? super K> keyComparator, Multimap<K, V> multimap) {
+ super(new TreeMap<K, Collection<V>>(keyComparator));
+ putAll(multimap);
+ }
+ @Override Collection<V> createCollection() {
+ return Sets.newLinkedHashSet();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ /**
* A builder for creating immutable {@code SetMultimap} instances, especially
* {@code public static final} multimaps ("constant multimaps"). Example:
* <pre> {@code
@@ -186,7 +197,7 @@ public class ImmutableSetMultimap<K, V>
* generated by {@link ImmutableSetMultimap#builder}.
*/
public Builder() {
- builderMultimap = new BuilderMultimap<K, V>();
+ builderMultimap = new BuilderMultimap<K, V>();
}
/**
@@ -235,25 +246,26 @@ public class ImmutableSetMultimap<K, V>
*
* @since 8.0
*/
- @Override
+ @Beta @Override
public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
- this.keyComparator = checkNotNull(keyComparator);
+ builderMultimap = new SortedKeyBuilderMultimap<K, V>(
+ checkNotNull(keyComparator), builderMultimap);
return this;
}
/**
* Specifies the ordering of the generated multimap's values for each key.
- *
- * <p>If this method is called, the sets returned by the {@code get()}
+ *
+ * <p>If this method is called, the sets returned by the {@code get()}
* method of the generated multimap and its {@link Multimap#asMap()} view
* are {@link ImmutableSortedSet} instances. However, serialization does not
* preserve that property, though it does maintain the key and value
* ordering.
- *
+ *
* @since 8.0
*/
// TODO: Make serialization behavior consistent.
- @Override
+ @Beta @Override
public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
super.orderValuesBy(valueComparator);
return this;
@@ -263,23 +275,6 @@ public class ImmutableSetMultimap<K, V>
* Returns a newly-created immutable set multimap.
*/
@Override public ImmutableSetMultimap<K, V> build() {
- if (keyComparator != null) {
- Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
- List<Map.Entry<K, Collection<V>>> entries = Lists.newArrayList(
- builderMultimap.asMap().entrySet());
- Collections.sort(
- entries,
- Ordering.from(keyComparator).onResultOf(new Function<Entry<K, Collection<V>>, K>() {
- @Override
- public K apply(Entry<K, Collection<V>> entry) {
- return entry.getKey();
- }
- }));
- for (Map.Entry<K, Collection<V>> entry : entries) {
- sortedCopy.putAll(entry.getKey(), entry.getValue());
- }
- builderMultimap = sortedCopy;
- }
return copyOf(builderMultimap, valueComparator);
}
}
@@ -302,7 +297,7 @@ public class ImmutableSetMultimap<K, V>
Multimap<? extends K, ? extends V> multimap) {
return copyOf(multimap, null);
}
-
+
private static <K, V> ImmutableSetMultimap<K, V> copyOf(
Multimap<? extends K, ? extends V> multimap,
Comparator<? super V> valueComparator) {
@@ -328,7 +323,7 @@ public class ImmutableSetMultimap<K, V>
K key = entry.getKey();
Collection<? extends V> values = entry.getValue();
ImmutableSet<V> set = (valueComparator == null)
- ? ImmutableSet.copyOf(values)
+ ? ImmutableSet.copyOf(values)
: ImmutableSortedSet.copyOf(valueComparator, values);
if (!set.isEmpty()) {
builder.put(key, set);
@@ -343,10 +338,10 @@ public class ImmutableSetMultimap<K, V>
// Returned by get() when values are sorted and a missing key is provided.
private final transient ImmutableSortedSet<V> emptySet;
- ImmutableSetMultimap(ImmutableMap<K, ImmutableSet<V>> map, int size,
+ ImmutableSetMultimap(ImmutableMap<K, ImmutableSet<V>> map, int size,
@Nullable Comparator<? super V> valueComparator) {
super(map, size);
- this.emptySet = (valueComparator == null)
+ this.emptySet = (valueComparator == null)
? null : ImmutableSortedSet.<V>emptySet(valueComparator);
}
@@ -375,13 +370,13 @@ public class ImmutableSetMultimap<K, V>
/**
* {@inheritDoc}
*
- * <p>Because an inverse of a set multimap cannot contain multiple pairs with
- * the same key and value, this method returns an {@code ImmutableSetMultimap}
- * rather than the {@code ImmutableMultimap} specified in the {@code
- * ImmutableMultimap} class.
+ * <p>Because an inverse of a set multimap cannot contain multiple pairs with the same key and
+ * value, this method returns an {@code ImmutableSetMultimap} rather than the
+ * {@code ImmutableMultimap} specified in the {@code ImmutableMultimap} class.
*
- * @since 11.0
+ * @since 11
*/
+ @Beta
public ImmutableSetMultimap<V, K> inverse() {
ImmutableSetMultimap<V, K> result = inverse;
return (result == null) ? (inverse = invert()) : result;
@@ -401,9 +396,8 @@ public class ImmutableSetMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableSet<V> removeAll(Object key) {
+ @Override public ImmutableSet<V> removeAll(Object key) {
throw new UnsupportedOperationException();
}
@@ -411,9 +405,8 @@ public class ImmutableSetMultimap<K, V>
* Guaranteed to throw an exception and leave the multimap unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public ImmutableSet<V> replaceValues(
+ @Override public ImmutableSet<V> replaceValues(
K key, Iterable<? extends V> values) {
throw new UnsupportedOperationException();
}
diff --git a/guava/src/com/google/common/collect/ImmutableSortedAsList.java b/guava/src/com/google/common/collect/ImmutableSortedAsList.java
index 98aab41..e557570 100644
--- a/guava/src/com/google/common/collect/ImmutableSortedAsList.java
+++ b/guava/src/com/google/common/collect/ImmutableSortedAsList.java
@@ -14,8 +14,7 @@
package com.google.common.collect;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Preconditions;
import java.util.Comparator;
@@ -27,60 +26,80 @@ import javax.annotation.Nullable;
* @author Jared Levy
* @author Louis Wasserman
*/
-@GwtCompatible(emulated = true)
@SuppressWarnings("serial")
-final class ImmutableSortedAsList<E> extends RegularImmutableAsList<E>
- implements SortedIterable<E> {
+final class ImmutableSortedAsList<E> extends ImmutableList<E> implements SortedIterable<E> {
+ private final transient ImmutableSortedSet<E> backingSet;
+ private final transient ImmutableList<E> backingList;
+
ImmutableSortedAsList(
ImmutableSortedSet<E> backingSet, ImmutableList<E> backingList) {
- super(backingSet, backingList);
- }
-
- @Override
- ImmutableSortedSet<E> delegateCollection() {
- return (ImmutableSortedSet<E>) super.delegateCollection();
+ this.backingSet = backingSet;
+ this.backingList = backingList;
}
@Override public Comparator<? super E> comparator() {
- return delegateCollection().comparator();
+ return backingSet.comparator();
}
- // Override indexOf() and lastIndexOf() to be O(log N) instead of O(N).
+ // Override contains(), indexOf(), and lastIndexOf() to be O(log N) instead of O(N).
+
+ @Override public boolean contains(@Nullable Object target) {
+ // TODO: why not contains(target)?
+ return backingSet.indexOf(target) >= 0;
+ }
- @GwtIncompatible("ImmutableSortedSet.indexOf")
- // TODO(cpovirk): consider manual binary search under GWT to preserve O(log N) lookup
@Override public int indexOf(@Nullable Object target) {
- int index = delegateCollection().indexOf(target);
+ return backingSet.indexOf(target);
+ }
- // TODO(kevinb): reconsider if it's really worth making feeble attempts at
- // sanity for inconsistent comparators.
+ @Override public int lastIndexOf(@Nullable Object target) {
+ return backingSet.indexOf(target);
+ }
- // The equals() check is needed when the comparator isn't compatible with
- // equals().
- return (index >= 0 && get(index).equals(target)) ? index : -1;
+ // The returned ImmutableSortedAsList maintains the contains(), indexOf(), and
+ // lastIndexOf() performance benefits.
+ @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
+ Preconditions.checkPositionIndexes(fromIndex, toIndex, size());
+ return (fromIndex == toIndex) ? ImmutableList.<E>of()
+ : new RegularImmutableSortedSet<E>(
+ backingList.subList(fromIndex, toIndex), backingSet.comparator())
+ .asList();
}
- @GwtIncompatible("ImmutableSortedSet.indexOf")
- @Override public int lastIndexOf(@Nullable Object target) {
- return indexOf(target);
+ // The ImmutableAsList serialized form has the correct behavior.
+ @Override Object writeReplace() {
+ return new ImmutableAsList.SerializedForm(backingSet);
+ }
+
+ @Override public UnmodifiableIterator<E> iterator() {
+ return backingList.iterator();
+ }
+
+ @Override public E get(int index) {
+ return backingList.get(index);
+ }
+
+ @Override public UnmodifiableListIterator<E> listIterator() {
+ return backingList.listIterator();
+ }
+
+ @Override public UnmodifiableListIterator<E> listIterator(int index) {
+ return backingList.listIterator(index);
+ }
+
+ @Override public int size() {
+ return backingList.size();
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ return backingList.equals(obj);
}
- @Override
- public boolean contains(Object target) {
- // Necessary for ISS's with comparators inconsistent with equals.
- return indexOf(target) >= 0;
+ @Override public int hashCode() {
+ return backingList.hashCode();
}
- @GwtIncompatible("super.subListUnchecked does not exist; inherited subList is valid if slow")
- /*
- * TODO(cpovirk): if we start to override indexOf/lastIndexOf under GWT, we'll want some way to
- * override subList to return an ImmutableSortedAsList for better performance. Right now, I'm not
- * sure there's any performance hit from our failure to override subListUnchecked under GWT
- */
- @Override
- ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
- return new RegularImmutableSortedSet<E>(
- super.subListUnchecked(fromIndex, toIndex), comparator())
- .asList();
+ @Override boolean isPartialView() {
+ return backingList.isPartialView();
}
}
diff --git a/guava/src/com/google/common/collect/ImmutableSortedMap.java b/guava/src/com/google/common/collect/ImmutableSortedMap.java
index d8420fe..c700f7f 100644
--- a/guava/src/com/google/common/collect/ImmutableSortedMap.java
+++ b/guava/src/com/google/common/collect/ImmutableSortedMap.java
@@ -18,17 +18,22 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Maps.keyOrNull;
+import static com.google.common.collect.SortedLists.KeyAbsentBehavior.INVERTED_INSERTION_INDEX;
+import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_HIGHER;
+import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_LOWER;
+import static com.google.common.collect.SortedLists.KeyPresentBehavior.ANY_PRESENT;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.SortedLists.KeyAbsentBehavior;
+import com.google.common.collect.SortedLists.KeyPresentBehavior;
+import java.io.Serializable;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
-import java.util.NavigableMap;
+import java.util.NoSuchElementException;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -48,64 +53,28 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this class are
* guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Jared Levy
* @author Louis Wasserman
- * @since 2.0 (imported from Google Collections Library; implements {@code
- * NavigableMap} since 12.0)
+ * @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(serializable = true, emulated = true)
-public abstract class ImmutableSortedMap<K, V>
- extends ImmutableSortedMapFauxverideShim<K, V> implements NavigableMap<K, V> {
+public class ImmutableSortedMap<K, V>
+ extends ImmutableSortedMapFauxverideShim<K, V> implements SortedMap<K, V> {
/*
* TODO(kevinb): Confirm that ImmutableSortedMap is faster to construct and
* uses less memory than TreeMap; then say so in the class Javadoc.
+ *
+ * TODO(kevinb): Create separate subclasses for empty, single-entry, and
+ * multiple-entry instances, if it's deemed beneficial.
*/
- private static final Comparator<Comparable> NATURAL_ORDER = Ordering.natural();
-
- private static final ImmutableSortedMap<Comparable, Object> NATURAL_EMPTY_MAP =
- new EmptyImmutableSortedMap<Comparable, Object>(NATURAL_ORDER);
-
- static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) {
- if (Ordering.natural().equals(comparator)) {
- return of();
- } else {
- return new EmptyImmutableSortedMap<K, V>(comparator);
- }
- }
-
- static <K, V> ImmutableSortedMap<K, V> fromSortedEntries(
- Comparator<? super K> comparator,
- Collection<? extends Entry<? extends K, ? extends V>> entries) {
- if (entries.isEmpty()) {
- return emptyMap(comparator);
- }
- ImmutableList.Builder<K> keyBuilder = ImmutableList.builder();
- ImmutableList.Builder<V> valueBuilder = ImmutableList.builder();
- for (Entry<? extends K, ? extends V> entry : entries) {
- keyBuilder.add(entry.getKey());
- valueBuilder.add(entry.getValue());
- }
+ private static final Comparator<Comparable> NATURAL_ORDER =
+ Ordering.natural();
- return new RegularImmutableSortedMap<K, V>(
- new RegularImmutableSortedSet<K>(keyBuilder.build(), comparator),
- valueBuilder.build());
- }
-
- static <K, V> ImmutableSortedMap<K, V> from(
- ImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
- if (keySet.isEmpty()) {
- return emptyMap(keySet.comparator());
- } else {
- return new RegularImmutableSortedMap<K, V>(
- (RegularImmutableSortedSet<K>) keySet,
- valueList);
- }
- }
+ private static final ImmutableSortedMap<Comparable, Object>
+ NATURAL_EMPTY_MAP =
+ new ImmutableSortedMap<Comparable, Object>(
+ ImmutableList.<Entry<Comparable, Object>>of(), NATURAL_ORDER);
/**
* Returns the empty sorted map.
@@ -117,12 +86,24 @@ public abstract class ImmutableSortedMap<K, V>
return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP;
}
+ @SuppressWarnings("unchecked")
+ private static <K, V> ImmutableSortedMap<K, V> emptyMap(
+ Comparator<? super K> comparator) {
+ if (NATURAL_ORDER.equals(comparator)) {
+ return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP;
+ } else {
+ return new ImmutableSortedMap<K, V>(
+ ImmutableList.<Entry<K, V>>of(), comparator);
+ }
+ }
+
/**
* Returns an immutable map containing a single entry.
*/
public static <K extends Comparable<? super K>, V>
ImmutableSortedMap<K, V> of(K k1, V v1) {
- return from(ImmutableSortedSet.of(k1), ImmutableList.of(v1));
+ return new ImmutableSortedMap<K, V>(
+ ImmutableList.of(entryOf(k1, v1)), Ordering.natural());
}
/**
@@ -249,7 +230,7 @@ public abstract class ImmutableSortedMap<K, V>
SortedMap<?, ?> sortedMap = (SortedMap<?, ?>) map;
Comparator<?> comparator2 = sortedMap.comparator();
sameComparator = (comparator2 == null)
- ? comparator == NATURAL_ORDER
+ ? comparator == NATURAL_ORDER
: comparator.equals(comparator2);
}
@@ -264,7 +245,7 @@ public abstract class ImmutableSortedMap<K, V>
}
// "adding" type params to an array of a raw type should be safe as
- // long as no one can ever cast that same array instance back to a
+ // long as no one can ever cast that same array instance back to a
// raw type.
@SuppressWarnings("unchecked")
Entry<K, V>[] entries = map.entrySet().toArray(new Entry[0]);
@@ -281,9 +262,9 @@ public abstract class ImmutableSortedMap<K, V>
validateEntries(list, comparator);
}
- return fromSortedEntries(comparator, list);
+ return new ImmutableSortedMap<K, V>(ImmutableList.copyOf(list), comparator);
}
-
+
private static <K, V> void sortEntries(
List<Entry<K, V>> entries, final Comparator<? super K> comparator) {
Comparator<Entry<K, V>> entryComparator = new Comparator<Entry<K, V>>() {
@@ -292,7 +273,7 @@ public abstract class ImmutableSortedMap<K, V>
return comparator.compare(entry1.getKey(), entry2.getKey());
}
};
-
+
Collections.sort(entries, entryComparator);
}
@@ -312,8 +293,13 @@ public abstract class ImmutableSortedMap<K, V>
* Returns a builder that creates immutable sorted maps whose keys are
* ordered by their natural ordering. The sorted maps use {@link
* Ordering#natural()} as the comparator.
+ *
+ * <p>Note: the type parameter {@code K} extends {@code Comparable<K>} rather
+ * than {@code Comparable<? super K>} as a workaround for javac <a
+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
+ * 6468354</a>.
*/
- public static <K extends Comparable<?>, V> Builder<K, V> naturalOrder() {
+ public static <K extends Comparable<K>, V> Builder<K, V> naturalOrder() {
return new Builder<K, V>(Ordering.natural());
}
@@ -332,8 +318,13 @@ public abstract class ImmutableSortedMap<K, V>
/**
* Returns a builder that creates immutable sorted maps whose keys are
* ordered by the reverse of their natural ordering.
+ *
+ * <p>Note: the type parameter {@code K} extends {@code Comparable<K>} rather
+ * than {@code Comparable<? super K>} as a workaround for javac <a
+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
+ * 6468354</a>.
*/
- public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
+ public static <K extends Comparable<K>, V> Builder<K, V> reverseOrder() {
return new Builder<K, V>(Ordering.natural().reverse());
}
@@ -414,48 +405,209 @@ public abstract class ImmutableSortedMap<K, V>
@Override public ImmutableSortedMap<K, V> build() {
sortEntries(entries, comparator);
validateEntries(entries, comparator);
- return fromSortedEntries(comparator, entries);
+ return new ImmutableSortedMap<K, V>(
+ ImmutableList.copyOf(entries), comparator);
}
}
- ImmutableSortedMap() {
- }
+ final transient ImmutableList<Entry<K, V>> entries;
+ private final transient Comparator<? super K> comparator;
- ImmutableSortedMap(ImmutableSortedMap<K, V> descendingMap) {
- this.descendingMap = descendingMap;
+ ImmutableSortedMap(
+ ImmutableList<Entry<K, V>> entries, Comparator<? super K> comparator) {
+ this.entries = entries;
+ this.comparator = comparator;
}
@Override
public int size() {
- return values().size();
+ return entries.size();
+ }
+
+ // Pretend the comparator can compare anything. If it turns out it can't
+ // compare two elements, it'll throw a CCE. Only methods that are specified to
+ // throw CCE should call this.
+ @SuppressWarnings("unchecked")
+ Comparator<Object> unsafeComparator() {
+ return (Comparator<Object>) comparator;
+ }
+
+ @Override public V get(@Nullable Object key) {
+ if (key == null) {
+ return null;
+ }
+ int i;
+ try {
+ i = index(key, ANY_PRESENT, INVERTED_INSERTION_INDEX);
+ } catch (ClassCastException e) {
+ return null;
+ }
+ return i >= 0 ? entries.get(i).getValue() : null;
}
@Override public boolean containsValue(@Nullable Object value) {
- return values().contains(value);
+ if (value == null) {
+ return false;
+ }
+ return Iterators.contains(valueIterator(), value);
}
@Override boolean isPartialView() {
- return keySet().isPartialView() || values().isPartialView();
+ return entries.isPartialView();
}
+ private transient ImmutableSet<Entry<K, V>> entrySet;
+
/**
* Returns an immutable set of the mappings in this map, sorted by the key
* ordering.
*/
@Override public ImmutableSet<Entry<K, V>> entrySet() {
- return super.entrySet();
+ ImmutableSet<Entry<K, V>> es = entrySet;
+ return (es == null) ? (entrySet = createEntrySet()) : es;
}
+ private ImmutableSet<Entry<K, V>> createEntrySet() {
+ return isEmpty() ? ImmutableSet.<Entry<K, V>>of()
+ : new EntrySet<K, V>(this);
+ }
+
+ @SuppressWarnings("serial") // uses writeReplace(), not default serialization
+ private static class EntrySet<K, V> extends ImmutableSet<Entry<K, V>> {
+ final transient ImmutableSortedMap<K, V> map;
+
+ EntrySet(ImmutableSortedMap<K, V> map) {
+ this.map = map;
+ }
+
+ @Override boolean isPartialView() {
+ return map.isPartialView();
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override public UnmodifiableIterator<Entry<K, V>> iterator() {
+ return map.entries.iterator();
+ }
+
+ @Override public boolean contains(Object target) {
+ if (target instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) target;
+ V mappedValue = map.get(entry.getKey());
+ return mappedValue != null && mappedValue.equals(entry.getValue());
+ }
+ return false;
+ }
+
+ @Override Object writeReplace() {
+ return new EntrySetSerializedForm<K, V>(map);
+ }
+ }
+
+ private static class EntrySetSerializedForm<K, V> implements Serializable {
+ final ImmutableSortedMap<K, V> map;
+ EntrySetSerializedForm(ImmutableSortedMap<K, V> map) {
+ this.map = map;
+ }
+ Object readResolve() {
+ return map.entrySet();
+ }
+ private static final long serialVersionUID = 0;
+ }
+
+ private transient ImmutableSortedSet<K> keySet;
+
/**
* Returns an immutable sorted set of the keys in this map.
*/
- @Override public abstract ImmutableSortedSet<K> keySet();
+ @Override public ImmutableSortedSet<K> keySet() {
+ ImmutableSortedSet<K> ks = keySet;
+ return (ks == null) ? (keySet = createKeySet()) : ks;
+ }
+
+ @SuppressWarnings("serial") // does not use default serialization
+ private ImmutableSortedSet<K> createKeySet() {
+ if (isEmpty()) {
+ return ImmutableSortedSet.emptySet(comparator);
+ }
+
+ return new RegularImmutableSortedSet<K>(
+ new TransformedImmutableList<Entry<K, V>, K>(entries) {
+
+ @Override K transform(Entry<K, V> entry) {
+ return entry.getKey();
+ }
+ }, comparator);
+ }
+
+ private transient ImmutableCollection<V> values;
/**
* Returns an immutable collection of the values in this map, sorted by the
* ordering of the corresponding keys.
*/
- @Override public abstract ImmutableCollection<V> values();
+ @Override public ImmutableCollection<V> values() {
+ ImmutableCollection<V> v = values;
+ return (v == null) ? (values = new Values<V>(this)) : v;
+ }
+
+ UnmodifiableIterator<V> valueIterator(){
+ final UnmodifiableIterator<Entry<K, V>> entryIterator = entries.iterator();
+ return new UnmodifiableIterator<V>() {
+
+ @Override public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+
+ @Override public V next() {
+ return entryIterator.next().getValue();
+ }
+ };
+ }
+
+ @SuppressWarnings("serial") // uses writeReplace(), not default serialization
+ private static class Values<V> extends ImmutableCollection<V> {
+ private final ImmutableSortedMap<?, V> map;
+
+ Values(ImmutableSortedMap<?, V> map) {
+ this.map = map;
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override public UnmodifiableIterator<V> iterator() {
+ return map.valueIterator();
+ }
+
+ @Override public boolean contains(Object target) {
+ return map.containsValue(target);
+ }
+
+ @Override boolean isPartialView() {
+ return true;
+ }
+
+ @Override Object writeReplace() {
+ return new ValuesSerializedForm<V>(map);
+ }
+ }
+
+ private static class ValuesSerializedForm<V> implements Serializable {
+ final ImmutableSortedMap<?, V> map;
+ ValuesSerializedForm(ImmutableSortedMap<?, V> map) {
+ this.map = map;
+ }
+ Object readResolve() {
+ return map.values();
+ }
+ private static final long serialVersionUID = 0;
+ }
/**
* Returns the comparator that orders the keys, which is
@@ -465,17 +617,23 @@ public abstract class ImmutableSortedMap<K, V>
*/
@Override
public Comparator<? super K> comparator() {
- return keySet().comparator();
+ return comparator;
}
@Override
public K firstKey() {
- return keySet().first();
+ if (isEmpty()) {
+ throw new NoSuchElementException();
+ }
+ return entries.get(0).getKey();
}
@Override
public K lastKey() {
- return keySet().last();
+ if (isEmpty()) {
+ throw new NoSuchElementException();
+ }
+ return entries.get(size() - 1).getKey();
}
/**
@@ -493,20 +651,15 @@ public abstract class ImmutableSortedMap<K, V>
return headMap(toKey, false);
}
- /**
- * This method returns a {@code ImmutableSortedMap}, consisting of the entries
- * whose keys are less than (or equal to, if {@code inclusive}) {@code toKey}.
- *
- * <p>The {@link SortedMap#headMap} documentation states that a submap of a
- * submap throws an {@link IllegalArgumentException} if passed a {@code toKey}
- * greater than an earlier {@code toKey}. However, this method doesn't throw
- * an exception in that situation, but instead keeps the original {@code
- * toKey}.
- *
- * @since 12.0
- */
- @Override
- public abstract ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive);
+ ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive){
+ int index;
+ if (inclusive) {
+ index = index(toKey, ANY_PRESENT, NEXT_LOWER) + 1;
+ } else {
+ index = index(toKey, ANY_PRESENT, NEXT_HIGHER);
+ }
+ return createSubmap(0, index);
+ }
/**
* This method returns a {@code ImmutableSortedMap}, consisting of the entries
@@ -526,29 +679,12 @@ public abstract class ImmutableSortedMap<K, V>
return subMap(fromKey, true, toKey, false);
}
- /**
- * This method returns a {@code ImmutableSortedMap}, consisting of the entries
- * whose keys ranges from {@code fromKey} to {@code toKey}, inclusive or
- * exclusive as indicated by the boolean flags.
- *
- * <p>The {@link SortedMap#subMap} documentation states that a submap of a
- * submap throws an {@link IllegalArgumentException} if passed a {@code
- * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
- * throw an exception in that situation, but instead keeps the original {@code
- * fromKey}. Similarly, this method keeps the original {@code toKey}, instead
- * of throwing an exception, if passed a {@code toKey} greater than an earlier
- * {@code toKey}.
- *
- * @since 12.0
- */
- @Override
- public ImmutableSortedMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey,
+ ImmutableSortedMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey,
boolean toInclusive) {
checkNotNull(fromKey);
checkNotNull(toKey);
- checkArgument(comparator().compare(fromKey, toKey) <= 0,
- "expected fromKey <= toKey but %s > %s", fromKey, toKey);
- return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive);
+ checkArgument(comparator.compare(fromKey, toKey) <= 0);
+ return tailMap(fromKey, fromInclusive).headMap(toKey, toInclusive);
}
/**
@@ -566,117 +702,39 @@ public abstract class ImmutableSortedMap<K, V>
return tailMap(fromKey, true);
}
- /**
- * This method returns a {@code ImmutableSortedMap}, consisting of the entries
- * whose keys are greater than (or equal to, if {@code inclusive})
- * {@code fromKey}.
- *
- * <p>The {@link SortedMap#tailMap} documentation states that a submap of a
- * submap throws an {@link IllegalArgumentException} if passed a {@code
- * fromKey} less than an earlier {@code fromKey}. However, this method doesn't
- * throw an exception in that situation, but instead keeps the original {@code
- * fromKey}.
- *
- * @since 12.0
- */
- @Override
- public abstract ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive);
-
- @Override
- public Entry<K, V> lowerEntry(K key) {
- return headMap(key, false).lastEntry();
- }
-
- @Override
- public K lowerKey(K key) {
- return keyOrNull(lowerEntry(key));
- }
-
- @Override
- public Entry<K, V> floorEntry(K key) {
- return headMap(key, true).lastEntry();
- }
-
- @Override
- public K floorKey(K key) {
- return keyOrNull(floorEntry(key));
- }
-
- @Override
- public Entry<K, V> ceilingEntry(K key) {
- return tailMap(key, true).firstEntry();
- }
-
- @Override
- public K ceilingKey(K key) {
- return keyOrNull(ceilingEntry(key));
- }
-
- @Override
- public Entry<K, V> higherEntry(K key) {
- return tailMap(key, false).firstEntry();
- }
-
- @Override
- public K higherKey(K key) {
- return keyOrNull(higherEntry(key));
- }
-
- @Override
- public Entry<K, V> firstEntry() {
- return isEmpty() ? null : entrySet().asList().get(0);
- }
-
- @Override
- public Entry<K, V> lastEntry() {
- return isEmpty() ? null : entrySet().asList().get(size() - 1);
+ ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) {
+ int index;
+ if (inclusive) {
+ index = index(fromKey, ANY_PRESENT, NEXT_HIGHER);
+ } else {
+ index = index(fromKey, ANY_PRESENT, NEXT_LOWER) + 1;
+ }
+ return createSubmap(index, size());
}
- /**
- * Guaranteed to throw an exception and leave the map unmodified.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
- */
- @Deprecated
- @Override
- public final Entry<K, V> pollFirstEntry() {
- throw new UnsupportedOperationException();
+ private ImmutableList<K> keyList() {
+ return new TransformedImmutableList<Entry<K, V>, K>(entries) {
+ @Override
+ K transform(Entry<K, V> entry) {
+ return entry.getKey();
+ }
+ };
}
- /**
- * Guaranteed to throw an exception and leave the map unmodified.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
- */
- @Deprecated
- @Override
- public final Entry<K, V> pollLastEntry() {
- throw new UnsupportedOperationException();
+ private int index(
+ Object key, KeyPresentBehavior presentBehavior, KeyAbsentBehavior absentBehavior) {
+ return SortedLists.binarySearch(
+ keyList(), checkNotNull(key), unsafeComparator(), presentBehavior, absentBehavior);
}
- private transient ImmutableSortedMap<K, V> descendingMap;
-
- @Override
- public ImmutableSortedMap<K, V> descendingMap() {
- ImmutableSortedMap<K, V> result = descendingMap;
- if (result == null) {
- result = descendingMap = createDescendingMap();
+ private ImmutableSortedMap<K, V> createSubmap(
+ int newFromIndex, int newToIndex) {
+ if (newFromIndex < newToIndex) {
+ return new ImmutableSortedMap<K, V>(
+ entries.subList(newFromIndex, newToIndex), comparator);
+ } else {
+ return emptyMap(comparator);
}
- return result;
- }
-
- abstract ImmutableSortedMap<K, V> createDescendingMap();
-
- @Override
- public ImmutableSortedSet<K> navigableKeySet() {
- return keySet();
- }
-
- @Override
- public ImmutableSortedSet<K> descendingKeySet() {
- return keySet().descendingSet();
}
/**
diff --git a/guava/src/com/google/common/collect/ImmutableSortedMultiset.java b/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
index dadcfb5..82f4abe 100644
--- a/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
+++ b/guava/src/com/google/common/collect/ImmutableSortedMultiset.java
@@ -14,13 +14,12 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -62,7 +61,7 @@ import java.util.List;
*
* {(x, y) | x.compareTo(y) == 0}}</pre>
*
- * <b>Warning:</b> Like most multisets, an {@code ImmutableSortedMultiset} will not function
+ * <b>Warning:</b> Like most multisets, an {@code ImmutableSortedMultiset} will not function
* correctly if an element is modified after being placed in the multiset. For this reason, and to
* avoid general confusion, it is strongly recommended to place only immutable objects into this
* collection.
@@ -70,16 +69,10 @@ import java.util.List;
* <p><b>Note:</b> Although this class is not final, it cannot be subclassed as it has no public or
* protected constructors. Thus, instances of this type are guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @author Louis Wasserman
- * @since 12.0
*/
-@Beta
@GwtIncompatible("hasn't been tested yet")
-public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultisetFauxverideShim<E>
+abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultisetFauxverideShim<E>
implements SortedMultiset<E> {
// TODO(user): GWT compatibility
@@ -100,11 +93,8 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
* Returns an immutable sorted multiset containing a single element.
*/
public static <E extends Comparable<? super E>> ImmutableSortedMultiset<E> of(E element) {
- RegularImmutableSortedSet<E> elementSet =
- (RegularImmutableSortedSet<E>) ImmutableSortedSet.of(element);
- int[] counts = {1};
- long[] cumulativeCounts = {0, 1};
- return new RegularImmutableSortedMultiset<E>(elementSet, counts, cumulativeCounts, 0, 1);
+ return RegularImmutableSortedMultiset.createFromSorted(
+ NATURAL_ORDER, ImmutableList.of(Multisets.immutableEntry(checkNotNull(element), 1)));
}
/**
@@ -161,9 +151,15 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*/
@SuppressWarnings("unchecked")
public static <E extends Comparable<? super E>> ImmutableSortedMultiset<E> of(
- E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) {
+ E e1,
+ E e2,
+ E e3,
+ E e4,
+ E e5,
+ E e6,
+ E... remaining) {
int size = remaining.length + 6;
- List<E> all = Lists.newArrayListWithCapacity(size);
+ List<E> all = new ArrayList<E>(size);
Collections.addAll(all, e1, e2, e3, e4, e5, e6);
Collections.addAll(all, remaining);
return copyOf(Ordering.natural(), all);
@@ -224,7 +220,7 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
// Unsafe, see ImmutableSortedMultisetFauxverideShim.
@SuppressWarnings("unchecked")
Ordering<E> naturalOrder = (Ordering<E>) Ordering.<Comparable>natural();
- return copyOf(naturalOrder, elements);
+ return copyOfInternal(naturalOrder, elements);
}
/**
@@ -236,7 +232,7 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
public static <E> ImmutableSortedMultiset<E> copyOf(
Comparator<? super E> comparator, Iterator<? extends E> elements) {
checkNotNull(comparator);
- return new Builder<E>(comparator).addAll(elements).build();
+ return copyOfInternal(comparator, elements);
}
/**
@@ -251,21 +247,8 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*/
public static <E> ImmutableSortedMultiset<E> copyOf(
Comparator<? super E> comparator, Iterable<? extends E> elements) {
- if (elements instanceof ImmutableSortedMultiset) {
- @SuppressWarnings("unchecked") // immutable collections are always safe for covariant casts
- ImmutableSortedMultiset<E> multiset = (ImmutableSortedMultiset<E>) elements;
- if (comparator.equals(multiset.comparator())) {
- if (multiset.isPartialView()) {
- return copyOfSortedEntries(comparator, multiset.entrySet().asList());
- } else {
- return multiset;
- }
- }
- }
- elements = Lists.newArrayList(elements); // defensive copy
- TreeMultiset<E> sortedCopy = TreeMultiset.create(checkNotNull(comparator));
- Iterables.addAll(sortedCopy, elements);
- return copyOfSortedEntries(comparator, sortedCopy.entrySet());
+ checkNotNull(comparator);
+ return copyOfInternal(comparator, elements);
}
/**
@@ -282,29 +265,50 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*
* @throws NullPointerException if {@code sortedMultiset} or any of its elements is null
*/
+ @SuppressWarnings("unchecked")
public static <E> ImmutableSortedMultiset<E> copyOfSorted(SortedMultiset<E> sortedMultiset) {
- return copyOfSortedEntries(sortedMultiset.comparator(),
- Lists.newArrayList(sortedMultiset.entrySet()));
+ Comparator<? super E> comparator = sortedMultiset.comparator();
+ if (comparator == null) {
+ comparator = (Comparator<? super E>) NATURAL_ORDER;
+ }
+ return copyOfInternal(comparator, sortedMultiset);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <E> ImmutableSortedMultiset<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterable<? extends E> iterable) {
+ if (SortedIterables.hasSameComparator(comparator, iterable)
+ && iterable instanceof ImmutableSortedMultiset<?>) {
+ ImmutableSortedMultiset<E> multiset = (ImmutableSortedMultiset<E>) iterable;
+ if (!multiset.isPartialView()) {
+ return (ImmutableSortedMultiset<E>) iterable;
+ }
+ }
+ ImmutableList<Entry<E>> entries =
+ (ImmutableList) ImmutableList.copyOf(SortedIterables.sortedCounts(comparator, iterable));
+ if (entries.isEmpty()) {
+ return emptyMultiset(comparator);
+ }
+ verifyEntries(entries);
+ return RegularImmutableSortedMultiset.createFromSorted(comparator, entries);
}
- private static <E> ImmutableSortedMultiset<E> copyOfSortedEntries(
- Comparator<? super E> comparator, Collection<Entry<E>> entries) {
+ private static <E> ImmutableSortedMultiset<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterator<? extends E> iterator) {
+ @SuppressWarnings("unchecked") // We can safely cast from IL<Entry<? extends E>> to IL<Entry<E>>
+ ImmutableList<Entry<E>> entries =
+ (ImmutableList) ImmutableList.copyOf(SortedIterables.sortedCounts(comparator, iterator));
if (entries.isEmpty()) {
return emptyMultiset(comparator);
}
- ImmutableList.Builder<E> elementsBuilder = new ImmutableList.Builder<E>(entries.size());
- int[] counts = new int[entries.size()];
- long[] cumulativeCounts = new long[entries.size() + 1];
- int i = 0;
+ verifyEntries(entries);
+ return RegularImmutableSortedMultiset.createFromSorted(comparator, entries);
+ }
+
+ private static <E> void verifyEntries(Collection<Entry<E>> entries) {
for (Entry<E> entry : entries) {
- elementsBuilder.add(entry.getElement());
- counts[i] = entry.getCount();
- cumulativeCounts[i + 1] = cumulativeCounts[i] + counts[i];
- i++;
+ checkNotNull(entry.getElement());
}
- return new RegularImmutableSortedMultiset<E>(
- new RegularImmutableSortedSet<E>(elementsBuilder.build(), comparator),
- counts, cumulativeCounts, 0, entries.size());
}
@SuppressWarnings("unchecked")
@@ -315,15 +319,49 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
return new EmptyImmutableSortedMultiset<E>(comparator);
}
- ImmutableSortedMultiset() {}
+ private final transient Comparator<? super E> comparator;
+
+ ImmutableSortedMultiset(Comparator<? super E> comparator) {
+ this.comparator = checkNotNull(comparator);
+ }
@Override
- public final Comparator<? super E> comparator() {
- return elementSet().comparator();
+ public Comparator<? super E> comparator() {
+ return comparator;
}
+ // Pretend the comparator can compare anything. If it turns out it can't
+ // compare two elements, it'll throw a CCE. Only methods that are specified to
+ // throw CCE should call this.
+ @SuppressWarnings("unchecked")
+ Comparator<Object> unsafeComparator() {
+ return (Comparator<Object>) comparator;
+ }
+
+ private transient Comparator<? super E> reverseComparator;
+
+ Comparator<? super E> reverseComparator() {
+ Comparator<? super E> result = reverseComparator;
+ if (result == null) {
+ return reverseComparator = Ordering.from(comparator).<E>reverse();
+ }
+ return result;
+ }
+
+ private transient ImmutableSortedSet<E> elementSet;
+
@Override
- public abstract ImmutableSortedSet<E> elementSet();
+ public ImmutableSortedSet<E> elementSet() {
+ ImmutableSortedSet<E> result = elementSet;
+ if (result == null) {
+ return elementSet = createElementSet();
+ }
+ return result;
+ }
+
+ abstract ImmutableSortedSet<E> createElementSet();
+
+ abstract ImmutableSortedSet<E> createDescendingElementSet();
transient ImmutableSortedMultiset<E> descendingMultiset;
@@ -336,15 +374,13 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
return result;
}
+ abstract UnmodifiableIterator<Entry<E>> descendingEntryIterator();
+
/**
* {@inheritDoc}
*
* <p>This implementation is guaranteed to throw an {@link UnsupportedOperationException}.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final Entry<E> pollFirstEntry() {
throw new UnsupportedOperationException();
@@ -354,13 +390,9 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
* {@inheritDoc}
*
* <p>This implementation is guaranteed to throw an {@link UnsupportedOperationException}.
- *
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
- public final Entry<E> pollLastEntry() {
+ public Entry<E> pollLastEntry() {
throw new UnsupportedOperationException();
}
@@ -370,8 +402,6 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
@Override
public ImmutableSortedMultiset<E> subMultiset(
E lowerBound, BoundType lowerBoundType, E upperBound, BoundType upperBoundType) {
- checkArgument(comparator().compare(lowerBound, upperBound) <= 0,
- "Expected lowerBound <= upperBound but %s > %s", lowerBound, upperBound);
return tailMultiset(lowerBound, lowerBoundType).headMultiset(upperBound, upperBoundType);
}
@@ -432,8 +462,6 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*
* Builder instances can be reused; it is safe to call {@link #build} multiple times to build
* multiple multisets in series.
- *
- * @since 12.0
*/
public static class Builder<E> extends ImmutableMultiset.Builder<E> {
private final Comparator<? super E> comparator;
@@ -538,7 +566,7 @@ public abstract class ImmutableSortedMultiset<E> extends ImmutableSortedMultiset
*/
@Override
public ImmutableSortedMultiset<E> build() {
- return copyOfSorted((SortedMultiset<E>) contents);
+ return copyOf(comparator, contents);
}
}
diff --git a/guava/src/com/google/common/collect/ImmutableSortedSet.java b/guava/src/com/google/common/collect/ImmutableSortedSet.java
index cfeb8a5..b2d871f 100644
--- a/guava/src/com/google/common/collect/ImmutableSortedSet.java
+++ b/guava/src/com/google/common/collect/ImmutableSortedSet.java
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
@@ -32,7 +31,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
-import java.util.NavigableSet;
import java.util.SortedSet;
import javax.annotation.Nullable;
@@ -80,20 +78,16 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this type are
* guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
* @see ImmutableSet
* @author Jared Levy
* @author Louis Wasserman
- * @since 2.0 (imported from Google Collections Library; implements {@code NavigableSet} since 12.0)
+ * @since 2.0 (imported from Google Collections Library)
*/
// TODO(benyu): benchmark and optimize all creation paths, which are a mess now
@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial") // we're overriding default serialization
public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxverideShim<E>
- implements NavigableSet<E>, SortedIterable<E> {
+ implements SortedSet<E>, SortedIterable<E> {
private static final Comparator<Comparable> NATURAL_ORDER =
Ordering.natural();
@@ -182,7 +176,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
E e1, E e2, E e3, E e4, E e5) {
return copyOf(Ordering.natural(), Arrays.asList(e1, e2, e3, e4, e5));
}
-
+
/**
* Returns an immutable sorted set containing the given elements sorted by
* their natural ordering. When multiple elements are equivalent according to
@@ -306,7 +300,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
// Unsafe, see ImmutableSortedSetFauxverideShim.
@SuppressWarnings("unchecked")
Ordering<E> naturalOrder = (Ordering<E>) Ordering.<Comparable>natural();
- return copyOf(naturalOrder, elements);
+ return copyOfInternal(naturalOrder, elements);
}
/**
@@ -320,7 +314,8 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
*/
public static <E> ImmutableSortedSet<E> copyOf(
Comparator<? super E> comparator, Iterator<? extends E> elements) {
- return copyOf(comparator, Lists.newArrayList(elements));
+ checkNotNull(comparator);
+ return copyOfInternal(comparator, elements);
}
/**
@@ -339,19 +334,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
public static <E> ImmutableSortedSet<E> copyOf(
Comparator<? super E> comparator, Iterable<? extends E> elements) {
checkNotNull(comparator);
- boolean hasSameComparator =
- SortedIterables.hasSameComparator(comparator, elements);
-
- if (hasSameComparator && (elements instanceof ImmutableSortedSet)) {
- @SuppressWarnings("unchecked")
- ImmutableSortedSet<E> original = (ImmutableSortedSet<E>) elements;
- if (!original.isPartialView()) {
- return original;
- }
- }
- @SuppressWarnings("unchecked") // elements only contains E's; it's safe.
- E[] array = (E[]) Iterables.toArray(elements);
- return construct(comparator, array.length, array);
+ return copyOfInternal(comparator, elements);
}
/**
@@ -374,7 +357,8 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
*/
public static <E> ImmutableSortedSet<E> copyOf(
Comparator<? super E> comparator, Collection<? extends E> elements) {
- return copyOf(comparator, (Iterable<? extends E>) elements);
+ checkNotNull(comparator);
+ return copyOfInternal(comparator, elements);
}
/**
@@ -394,69 +378,41 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
* @throws NullPointerException if {@code sortedSet} or any of its elements
* is null
*/
+ @SuppressWarnings("unchecked")
public static <E> ImmutableSortedSet<E> copyOfSorted(SortedSet<E> sortedSet) {
- Comparator<? super E> comparator = SortedIterables.comparator(sortedSet);
- Object[] elements = sortedSet.toArray();
- if (elements.length == 0) {
- return emptySet(comparator);
- } else {
- return new RegularImmutableSortedSet<E>(
- ImmutableList.<E>asImmutableList(elements), comparator);
+ Comparator<? super E> comparator = sortedSet.comparator();
+ if (comparator == null) {
+ comparator = (Comparator<? super E>) NATURAL_ORDER;
}
+ return copyOfInternal(comparator, sortedSet);
}
- /**
- * Sorts and eliminates duplicates from the first {@code n} positions in {@code contents}.
- * Returns the number of unique elements. If this returns {@code k}, then the first {@code k}
- * elements of {@code contents} will be the sorted, unique elements, and {@code
- * contents[i] == null} for {@code k <= i < n}.
- *
- * @throws NullPointerException if any of the first {@code n} elements of {@code contents} is
- * null
- */
- static <E> int sortAndUnique(
- Comparator<? super E> comparator, int n, E... contents) {
- if (n == 0) {
- return 0;
- }
- for (int i = 0; i < n; i++) {
- ObjectArrays.checkElementNotNull(contents[i], i);
- }
- Arrays.sort(contents, 0, n, comparator);
- int uniques = 1;
- for (int i = 1; i < n; i++) {
- E cur = contents[i];
- E prev = contents[uniques - 1];
- if (comparator.compare(cur, prev) != 0) {
- contents[uniques++] = cur;
+ private static <E> ImmutableSortedSet<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterable<? extends E> elements) {
+ boolean hasSameComparator =
+ SortedIterables.hasSameComparator(comparator, elements);
+
+ if (hasSameComparator && (elements instanceof ImmutableSortedSet)) {
+ @SuppressWarnings("unchecked")
+ ImmutableSortedSet<E> original = (ImmutableSortedSet<E>) elements;
+ if (!original.isPartialView()) {
+ return original;
}
}
- Arrays.fill(contents, uniques, n, null);
- return uniques;
+ ImmutableList<E> list = ImmutableList.copyOf(
+ SortedIterables.sortedUnique(comparator, elements));
+ return list.isEmpty()
+ ? ImmutableSortedSet.<E>emptySet(comparator)
+ : new RegularImmutableSortedSet<E>(list, comparator);
}
- /**
- * Constructs an {@code ImmutableSortedSet} from the first {@code n} elements of
- * {@code contents}. If {@code k} is the size of the returned {@code ImmutableSortedSet}, then
- * the sorted unique elements are in the first {@code k} positions of {@code contents}, and
- * {@code contents[i] == null} for {@code k <= i < n}.
- *
- * <p>If {@code k == contents.length}, then {@code contents} may no longer be safe for
- * modification.
- *
- * @throws NullPointerException if any of the first {@code n} elements of {@code contents} is
- * null
- */
- static <E> ImmutableSortedSet<E> construct(
- Comparator<? super E> comparator, int n, E... contents) {
- int uniques = sortAndUnique(comparator, n, contents);
- if (uniques == 0) {
- return emptySet(comparator);
- } else if (uniques < contents.length) {
- contents = ObjectArrays.arraysCopyOf(contents, uniques);
- }
- return new RegularImmutableSortedSet<E>(
- ImmutableList.<E>asImmutableList(contents), comparator);
+ private static <E> ImmutableSortedSet<E> copyOfInternal(
+ Comparator<? super E> comparator, Iterator<? extends E> elements) {
+ ImmutableList<E> list =
+ ImmutableList.copyOf(SortedIterables.sortedUnique(comparator, elements));
+ return list.isEmpty()
+ ? ImmutableSortedSet.<E>emptySet(comparator)
+ : new RegularImmutableSortedSet<E>(list, comparator);
}
/**
@@ -474,8 +430,13 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
/**
* Returns a builder that creates immutable sorted sets whose elements are
* ordered by the reverse of their natural ordering.
+ *
+ * <p>Note: the type parameter {@code E} extends {@code Comparable<E>} rather
+ * than {@code Comparable<? super E>} as a workaround for javac <a
+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
+ * 6468354</a>.
*/
- public static <E extends Comparable<?>> Builder<E> reverseOrder() {
+ public static <E extends Comparable<E>> Builder<E> reverseOrder() {
return new Builder<E>(Ordering.natural().reverse());
}
@@ -485,8 +446,13 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
* Ordering#natural()} as the comparator. This method provides more
* type-safety than {@link #builder}, as it can be called only for classes
* that implement {@link Comparable}.
+ *
+ * <p>Note: the type parameter {@code E} extends {@code Comparable<E>} rather
+ * than {@code Comparable<? super E>} as a workaround for javac <a
+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6468354">bug
+ * 6468354</a>.
*/
- public static <E extends Comparable<?>> Builder<E> naturalOrder() {
+ public static <E extends Comparable<E>> Builder<E> naturalOrder() {
return new Builder<E>(Ordering.natural());
}
@@ -577,11 +543,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
* of the {@code Builder} and its comparator.
*/
@Override public ImmutableSortedSet<E> build() {
- @SuppressWarnings("unchecked") // we're careful to put only E's in here
- E[] contentsArray = (E[]) contents;
- ImmutableSortedSet<E> result = construct(comparator, size, contentsArray);
- this.size = result.size(); // we eliminated duplicates in-place in contentsArray
- return result;
+ return copyOfInternal(comparator, contents.iterator());
}
}
@@ -636,12 +598,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
return headSet(toElement, false);
}
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public ImmutableSortedSet<E> headSet(E toElement, boolean inclusive) {
+ ImmutableSortedSet<E> headSet(E toElement, boolean inclusive) {
return headSetImpl(checkNotNull(toElement), inclusive);
}
@@ -663,12 +620,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
return subSet(fromElement, true, toElement, false);
}
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public ImmutableSortedSet<E> subSet(
+ ImmutableSortedSet<E> subSet(
E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
checkNotNull(fromElement);
checkNotNull(toElement);
@@ -692,12 +644,7 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
return tailSet(fromElement, true);
}
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public ImmutableSortedSet<E> tailSet(E fromElement, boolean inclusive) {
+ ImmutableSortedSet<E> tailSet(E fromElement, boolean inclusive) {
return tailSetImpl(checkNotNull(fromElement), inclusive);
}
@@ -713,110 +660,6 @@ public abstract class ImmutableSortedSet<E> extends ImmutableSortedSetFauxveride
abstract ImmutableSortedSet<E> tailSetImpl(E fromElement, boolean inclusive);
/**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public E lower(E e) {
- return Iterators.getNext(headSet(e, false).descendingIterator(), null);
- }
-
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public E floor(E e) {
- return Iterators.getNext(headSet(e, true).descendingIterator(), null);
- }
-
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public E ceiling(E e) {
- return Iterables.getFirst(tailSet(e, true), null);
- }
-
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public E higher(E e) {
- return Iterables.getFirst(tailSet(e, false), null);
- }
-
- @Override
- public E first() {
- return iterator().next();
- }
-
- @Override
- public E last() {
- return descendingIterator().next();
- }
-
- /**
- * Guaranteed to throw an exception and leave the set unmodified.
- *
- * @since 12.0
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
- */
- @Deprecated
- @GwtIncompatible("NavigableSet")
- @Override
- public final E pollFirst() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Guaranteed to throw an exception and leave the set unmodified.
- *
- * @since 12.0
- * @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
- */
- @Deprecated
- @GwtIncompatible("NavigableSet")
- @Override
- public final E pollLast() {
- throw new UnsupportedOperationException();
- }
-
- @GwtIncompatible("NavigableSet")
- transient ImmutableSortedSet<E> descendingSet;
-
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public ImmutableSortedSet<E> descendingSet() {
- // racy single-check idiom
- ImmutableSortedSet<E> result = descendingSet;
- if (result == null) {
- result = descendingSet = createDescendingSet();
- result.descendingSet = this;
- }
- return result;
- }
-
- @GwtIncompatible("NavigableSet")
- ImmutableSortedSet<E> createDescendingSet() {
- return new DescendingImmutableSortedSet<E>(this);
- }
-
- /**
- * @since 12.0
- */
- @GwtIncompatible("NavigableSet")
- @Override
- public abstract UnmodifiableIterator<E> descendingIterator();
-
- /**
* Returns the position of an element within the set, or -1 if not present.
*/
abstract int indexOf(@Nullable Object target);
diff --git a/guava/src/com/google/common/collect/ImmutableTable.java b/guava/src/com/google/common/collect/ImmutableTable.java
index 8296a83..debd49b 100644
--- a/guava/src/com/google/common/collect/ImmutableTable.java
+++ b/guava/src/com/google/common/collect/ImmutableTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.Comparator;
@@ -34,13 +35,10 @@ import javax.annotation.Nullable;
* it has no public or protected constructors. Thus, instances of this class are
* guaranteed to be immutable.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained">
- * immutable collections</a>.
- *
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
* @since 11.0
*/
+@Beta
@GwtCompatible
// TODO(gak): make serializable
public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
@@ -72,7 +70,7 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
*/
public static final <R, C, V> ImmutableTable<R, C, V> copyOf(
Table<? extends R, ? extends C, ? extends V> table) {
- if (table instanceof ImmutableTable) {
+ if (table instanceof ImmutableTable<?, ?, ?>) {
@SuppressWarnings("unchecked")
ImmutableTable<R, C, V> parameterizedTable
= (ImmutableTable<R, C, V>) table;
@@ -106,7 +104,7 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
/**
* Returns a new builder. The generated builder is equivalent to the builder
- * created by the {@link Builder#ImmutableTable.Builder()} constructor.
+ * created by the {@link Builder#Builder()} constructor.
*/
public static final <R, C, V> Builder<R, C, V> builder() {
return new Builder<R, C, V>();
@@ -256,8 +254,8 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
/**
* {@inheritDoc}
*
- * <p>The value {@code Map<R, V>} instances in the returned map are
- * {@link ImmutableMap} instances as well.
+ * <p>The value {@code Map<R, V>}s in the returned map are
+ * {@link ImmutableMap}s as well.
*/
@Override public abstract ImmutableMap<C, Map<R, V>> columnMap();
@@ -273,8 +271,8 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
/**
* {@inheritDoc}
*
- * <p>The value {@code Map<C, V>} instances in the returned map are
- * {@link ImmutableMap} instances as well.
+ * <p>The value {@code Map<C, V>}s in the returned map are
+ * {@link ImmutableMap}s as well.
*/
@Override public abstract ImmutableMap<R, Map<C, V>> rowMap();
@@ -282,9 +280,8 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
* Guaranteed to throw an exception and leave the table unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public final void clear() {
+ @Override public final void clear() {
throw new UnsupportedOperationException();
}
@@ -292,9 +289,8 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
* Guaranteed to throw an exception and leave the table unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public final V put(R rowKey, C columnKey, V value) {
+ @Override public final V put(R rowKey, C columnKey, V value) {
throw new UnsupportedOperationException();
}
@@ -302,9 +298,8 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
* Guaranteed to throw an exception and leave the table unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public final void putAll(
+ @Override public final void putAll(
Table<? extends R, ? extends C, ? extends V> table) {
throw new UnsupportedOperationException();
}
@@ -313,16 +308,15 @@ public abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
* Guaranteed to throw an exception and leave the table unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public final V remove(Object rowKey, Object columnKey) {
+ @Override public final V remove(Object rowKey, Object columnKey) {
throw new UnsupportedOperationException();
}
@Override public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
- } else if (obj instanceof Table) {
+ } else if (obj instanceof Table<?, ?, ?>) {
Table<?, ?, ?> that = (Table<?, ?, ?>) obj;
return this.cellSet().equals(that.cellSet());
} else {
diff --git a/guava/src/com/google/common/collect/Interners.java b/guava/src/com/google/common/collect/Interners.java
index bd592d6..f5a6c85 100644
--- a/guava/src/com/google/common/collect/Interners.java
+++ b/guava/src/com/google/common/collect/Interners.java
@@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Function;
import com.google.common.collect.MapMakerInternalMap.ReferenceEntry;
@@ -51,24 +51,16 @@ public final class Interners {
};
}
- /**
- * Returns a new thread-safe interner which retains a weak reference to each instance it has
- * interned, and so does not prevent these instances from being garbage-collected. This most
- * likely does not perform as well as {@link #newStrongInterner}, but is the best alternative
- * when the memory usage of that implementation is unacceptable. Note that unlike {@link
- * String#intern}, using this interner does not consume memory in the permanent generation.
- */
- @GwtIncompatible("java.lang.ref.WeakReference")
- public static <E> Interner<E> newWeakInterner() {
- return new WeakInterner<E>();
- }
-
- private static class WeakInterner<E> implements Interner<E> {
+ private static class CustomInterner<E> implements Interner<E> {
// MapMaker is our friend, we know about this type
- private final MapMakerInternalMap<E, Dummy> map = new MapMaker()
- .weakKeys()
- .keyEquivalence(Equivalence.equals())
+ private final MapMakerInternalMap<E, Dummy> map;
+
+ CustomInterner(GenericMapMaker<? super E, Object> mm) {
+ this.map = mm
+ .strongValues()
+ .keyEquivalence(Equivalences.equals())
.makeCustomMap();
+ }
@Override public E intern(E sample) {
while (true) {
@@ -100,6 +92,18 @@ public final class Interners {
}
/**
+ * Returns a new thread-safe interner which retains a weak reference to each instance it has
+ * interned, and so does not prevent these instances from being garbage-collected. This most
+ * likely does not perform as well as {@link #newStrongInterner}, but is the best alternative
+ * when the memory usage of that implementation is unacceptable. Note that unlike {@link
+ * String#intern}, using this interner does not consume memory in the permanent generation.
+ */
+ @GwtIncompatible("java.lang.ref.WeakReference")
+ public static <E> Interner<E> newWeakInterner() {
+ return new CustomInterner<E>(new MapMaker().weakKeys());
+ }
+
+ /**
* Returns a function that delegates to the {@link Interner#intern} method of the given interner.
*
* @since 8.0
@@ -125,7 +129,7 @@ public final class Interners {
}
@Override public boolean equals(Object other) {
- if (other instanceof InternerFunction) {
+ if (other instanceof InternerFunction<?>) {
InternerFunction<?> that = (InternerFunction<?>) other;
return interner.equals(that.interner);
}
diff --git a/guava/src/com/google/common/collect/Iterables.java b/guava/src/com/google/common/collect/Iterables.java
index 39ad2f2..a92c2b2 100644
--- a/guava/src/com/google/common/collect/Iterables.java
+++ b/guava/src/com/google/common/collect/Iterables.java
@@ -23,6 +23,7 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
+import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
@@ -31,6 +32,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
@@ -50,10 +52,6 @@ import javax.annotation.Nullable;
* produced in this class are <i>lazy</i>, which means that their iterators
* only advance the backing iteration when absolutely necessary.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Iterables">
- * {@code Iterables}</a>.
- *
* @author Kevin Bourrillion
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -84,7 +82,7 @@ public final class Iterables {
return checkNotNull(iterable);
}
- private static final class UnmodifiableIterable<T> extends FluentIterable<T> {
+ private static final class UnmodifiableIterable<T> implements Iterable<T> {
private final Iterable<T> iterable;
private UnmodifiableIterable(Iterable<T> iterable) {
@@ -113,14 +111,20 @@ public final class Iterables {
}
/**
- * Returns {@code true} if {@code iterable} contains any object for which {@code equals(element)}
- * is true.
+ * Returns {@code true} if {@code iterable} contains {@code element}; that is,
+ * any object for which {@code equals(element)} is true.
*/
public static boolean contains(Iterable<?> iterable, @Nullable Object element)
{
if (iterable instanceof Collection) {
Collection<?> collection = (Collection<?>) iterable;
- return Collections2.safeContains(collection, element);
+ try {
+ return collection.contains(element);
+ } catch (NullPointerException e) {
+ return false;
+ } catch (ClassCastException e) {
+ return false;
+ }
}
return Iterators.contains(iterable.iterator(), element);
}
@@ -242,13 +246,6 @@ public final class Iterables {
*/
public static boolean elementsEqual(
Iterable<?> iterable1, Iterable<?> iterable2) {
- if (iterable1 instanceof Collection && iterable2 instanceof Collection) {
- Collection<?> collection1 = (Collection<?>) iterable1;
- Collection<?> collection2 = (Collection<?>) iterable2;
- if (collection1.size() != collection2.size()) {
- return false;
- }
- }
return Iterators.elementsEqual(iterable1.iterator(), iterable2.iterator());
}
@@ -278,9 +275,8 @@ public final class Iterables {
* @throws IllegalArgumentException if the iterator contains multiple
* elements
*/
- @Nullable
public static <T> T getOnlyElement(
- Iterable<? extends T> iterable, @Nullable T defaultValue) {
+ Iterable<T> iterable, @Nullable T defaultValue) {
return Iterators.getOnlyElement(iterable.iterator(), defaultValue);
}
@@ -372,7 +368,7 @@ public final class Iterables {
*/
public static <T> Iterable<T> cycle(final Iterable<T> iterable) {
checkNotNull(iterable);
- return new FluentIterable<T>() {
+ return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.cycle(iterable);
@@ -487,7 +483,7 @@ public final class Iterables {
public static <T> Iterable<T> concat(
final Iterable<? extends Iterable<? extends T>> inputs) {
checkNotNull(inputs);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.concat(iterators(inputs));
@@ -538,7 +534,7 @@ public final class Iterables {
final Iterable<T> iterable, final int size) {
checkNotNull(iterable);
checkArgument(size > 0);
- return new FluentIterable<List<T>>() {
+ return new IterableWithToString<List<T>>() {
@Override
public Iterator<List<T>> iterator() {
return Iterators.partition(iterable.iterator(), size);
@@ -567,7 +563,7 @@ public final class Iterables {
final Iterable<T> iterable, final int size) {
checkNotNull(iterable);
checkArgument(size > 0);
- return new FluentIterable<List<T>>() {
+ return new IterableWithToString<List<T>>() {
@Override
public Iterator<List<T>> iterator() {
return Iterators.paddedPartition(iterable.iterator(), size);
@@ -583,7 +579,7 @@ public final class Iterables {
final Iterable<T> unfiltered, final Predicate<? super T> predicate) {
checkNotNull(unfiltered);
checkNotNull(predicate);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.filter(unfiltered.iterator(), predicate);
@@ -607,7 +603,7 @@ public final class Iterables {
final Iterable<?> unfiltered, final Class<T> type) {
checkNotNull(unfiltered);
checkNotNull(type);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.filter(unfiltered.iterator(), type);
@@ -616,7 +612,8 @@ public final class Iterables {
}
/**
- * Returns {@code true} if any element in {@code iterable} satisfies the predicate.
+ * Returns {@code true} if one or more elements in {@code iterable} satisfy
+ * the predicate.
*/
public static <T> boolean any(
Iterable<T> iterable, Predicate<? super T> predicate) {
@@ -635,8 +632,8 @@ public final class Iterables {
/**
* Returns the first element in {@code iterable} that satisfies the given
* predicate; use this method only when such an element is known to exist. If
- * it is possible that <i>no</i> element will match, use {@link #tryFind} or
- * {@link #find(Iterable, Predicate, Object)} instead.
+ * it is possible that <i>no</i> element will match, use {@link
+ * #tryFind)} or {@link #find(Iterable, Predicate, T)} instead.
*
* @throws NoSuchElementException if no element in {@code iterable} matches
* the given predicate
@@ -654,8 +651,7 @@ public final class Iterables {
*
* @since 7.0
*/
- @Nullable
- public static <T> T find(Iterable<? extends T> iterable,
+ public static <T> T find(Iterable<T> iterable,
Predicate<? super T> predicate, @Nullable T defaultValue) {
return Iterators.find(iterable.iterator(), predicate, defaultValue);
}
@@ -707,7 +703,7 @@ public final class Iterables {
final Function<? super F, ? extends T> function) {
checkNotNull(fromIterable);
checkNotNull(function);
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.transform(fromIterable.iterator(), function);
@@ -760,8 +756,8 @@ public final class Iterables {
* @throws IndexOutOfBoundsException if {@code position} is negative
* @since 4.0
*/
- @Nullable
- public static <T> T get(Iterable<? extends T> iterable, int position, @Nullable T defaultValue) {
+ public static <T> T get(Iterable<T> iterable, int position,
+ @Nullable T defaultValue) {
checkNotNull(iterable);
checkNonnegativeIndex(position);
@@ -777,16 +773,11 @@ public final class Iterables {
* the iterable is empty. The {@link Iterators} analog to this method is
* {@link Iterators#getNext}.
*
- * <p>If no default value is desired (and the caller instead wants a
- * {@link NoSuchElementException} to be thrown), it is recommended that
- * {@code iterable.iterator().next()} is used instead.
- *
* @param defaultValue the default value to return if the iterable is empty
* @return the first element of {@code iterable} or the default value
* @since 7.0
*/
- @Nullable
- public static <T> T getFirst(Iterable<? extends T> iterable, @Nullable T defaultValue) {
+ public static <T> T getFirst(Iterable<T> iterable, @Nullable T defaultValue) {
return Iterators.getNext(iterable.iterator(), defaultValue);
}
@@ -827,17 +818,16 @@ public final class Iterables {
* @return the last element of {@code iterable} or the default value
* @since 3.0
*/
- @Nullable
- public static <T> T getLast(Iterable<? extends T> iterable, @Nullable T defaultValue) {
+ public static <T> T getLast(Iterable<T> iterable, @Nullable T defaultValue) {
if (iterable instanceof Collection) {
- Collection<? extends T> collection = Collections2.cast(iterable);
+ Collection<T> collection = (Collection<T>) iterable;
if (collection.isEmpty()) {
return defaultValue;
}
}
if (iterable instanceof List) {
- List<? extends T> list = Lists.cast(iterable);
+ List<T> list = (List<T>) iterable;
return getLastInNonemptyList(list);
}
@@ -847,7 +837,7 @@ public final class Iterables {
* call this method.
*/
if (iterable instanceof SortedSet) {
- SortedSet<? extends T> sortedSet = Sets.cast(iterable);
+ SortedSet<T> sortedSet = (SortedSet<T>) iterable;
return sortedSet.last();
}
@@ -885,7 +875,7 @@ public final class Iterables {
if (iterable instanceof List) {
final List<T> list = (List<T>) iterable;
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
// TODO(kevinb): Support a concurrently modified collection?
@@ -896,12 +886,12 @@ public final class Iterables {
};
}
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
final Iterator<T> iterator = iterable.iterator();
- Iterators.advance(iterator, numberToSkip);
+ Iterators.skip(iterator, numberToSkip);
/*
* We can't just return the iterator because an immediate call to its
@@ -957,7 +947,7 @@ public final class Iterables {
final Iterable<T> iterable, final int limitSize) {
checkNotNull(iterable);
checkArgument(limitSize >= 0, "limit is negative");
- return new FluentIterable<T>() {
+ return new IterableWithToString<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.limit(iterable.iterator(), limitSize);
@@ -986,7 +976,7 @@ public final class Iterables {
*/
public static <T> Iterable<T> consumingIterable(final Iterable<T> iterable) {
if (iterable instanceof Queue) {
- return new FluentIterable<T>() {
+ return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return new ConsumingQueueIterator<T>((Queue<T>) iterable);
@@ -996,7 +986,7 @@ public final class Iterables {
checkNotNull(iterable);
- return new FluentIterable<T>() {
+ return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.consumingIterator(iterable.iterator());
@@ -1023,6 +1013,30 @@ public final class Iterables {
// Methods only in Iterables, not in Iterators
/**
+ * Adapts a list to an iterable with reversed iteration order. It is
+ * especially useful in foreach-style loops: <pre> {@code
+ *
+ * List<String> mylist = ...
+ * for (String str : Iterables.reverse(mylist)) {
+ * ...
+ * }}</pre>
+ *
+ * There is no corresponding method in {@link Iterators}, since {@link
+ * Iterable#iterator} can simply be invoked on the result of calling this
+ * method.
+ *
+ * @return an iterable with the same elements as the list, in reverse
+ *
+ * @deprecated use {@link Lists#reverse(List)} or {@link
+ * ImmutableList#reverse()}. <b>This method is scheduled for deletion in
+ * July 2012.</b>
+ */
+ @Deprecated
+ public static <T> Iterable<T> reverse(final List<T> list) {
+ return Lists.reverse(list);
+ }
+
+ /**
* Determines if the given iterable contains no elements.
*
* <p>There is no precise {@link Iterator} equivalent to this method, since
@@ -1038,6 +1052,43 @@ public final class Iterables {
return !iterable.iterator().hasNext();
}
+ // Non-public
+
+ /**
+ * Removes the specified element from the specified iterable.
+ *
+ * <p>This method iterates over the iterable, checking each element returned
+ * by the iterator in turn to see if it equals the object {@code o}. If they
+ * are equal, it is removed from the iterable with the iterator's
+ * {@code remove} method. At most one element is removed, even if the iterable
+ * contains multiple members that equal {@code o}.
+ *
+ * <p><b>Warning:</b> Do not use this method for a collection, such as a
+ * {@link HashSet}, that has a fast {@code remove} method.
+ *
+ * @param iterable the iterable from which to remove
+ * @param o an element to remove from the collection
+ * @return {@code true} if the iterable changed as a result
+ * @throws UnsupportedOperationException if the iterator does not support the
+ * {@code remove} method and the iterable contains the object
+ */
+ static boolean remove(Iterable<?> iterable, @Nullable Object o) {
+ Iterator<?> i = iterable.iterator();
+ while (i.hasNext()) {
+ if (Objects.equal(i.next(), o)) {
+ i.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ abstract static class IterableWithToString<E> implements Iterable<E> {
+ @Override public String toString() {
+ return Iterables.toString(this);
+ }
+ }
+
/**
* Returns an iterable over the merged contents of all given
* {@code iterables}. Equivalent entries will not be de-duplicated.
@@ -1056,7 +1107,7 @@ public final class Iterables {
final Comparator<? super T> comparator) {
checkNotNull(iterables, "iterables");
checkNotNull(comparator, "comparator");
- Iterable<T> iterable = new FluentIterable<T>() {
+ Iterable<T> iterable = new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return Iterators.mergeSorted(
diff --git a/guava/src/com/google/common/collect/Iterators.java b/guava/src/com/google/common/collect/Iterators.java
index 39e13c3..847d1dd 100644
--- a/guava/src/com/google/common/collect/Iterators.java
+++ b/guava/src/com/google/common/collect/Iterators.java
@@ -24,7 +24,6 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
-import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
@@ -38,7 +37,6 @@ import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
-import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.Queue;
@@ -54,10 +52,6 @@ import javax.annotation.Nullable;
* produced in this class are <i>lazy</i>, which means that they only advance
* the backing iteration when absolutely necessary.
*
- * <p>See the Guava User Guide section on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Iterables">
- * {@code Iterators}</a>.
- *
* @author Kevin Bourrillion
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
@@ -66,8 +60,8 @@ import javax.annotation.Nullable;
public final class Iterators {
private Iterators() {}
- static final UnmodifiableListIterator<Object> EMPTY_LIST_ITERATOR
- = new UnmodifiableListIterator<Object>() {
+ static final UnmodifiableIterator<Object> EMPTY_ITERATOR
+ = new UnmodifiableIterator<Object>() {
@Override
public boolean hasNext() {
return false;
@@ -76,22 +70,6 @@ public final class Iterators {
public Object next() {
throw new NoSuchElementException();
}
- @Override
- public boolean hasPrevious() {
- return false;
- }
- @Override
- public Object previous() {
- throw new NoSuchElementException();
- }
- @Override
- public int nextIndex() {
- return 0;
- }
- @Override
- public int previousIndex() {
- return -1;
- }
};
/**
@@ -100,20 +78,10 @@ public final class Iterators {
* <p>The {@link Iterable} equivalent of this method is {@link
* ImmutableSet#of()}.
*/
- public static <T> UnmodifiableIterator<T> emptyIterator() {
- return emptyListIterator();
- }
-
- /**
- * Returns the empty iterator.
- *
- * <p>The {@link Iterable} equivalent of this method is {@link
- * ImmutableSet#of()}.
- */
// Casting to any type is safe since there are no actual elements.
@SuppressWarnings("unchecked")
- static <T> UnmodifiableListIterator<T> emptyListIterator() {
- return (UnmodifiableListIterator<T>) EMPTY_LIST_ITERATOR;
+ public static <T> UnmodifiableIterator<T> emptyIterator() {
+ return (UnmodifiableIterator<T>) EMPTY_ITERATOR;
}
private static final Iterator<Object> EMPTY_MODIFIABLE_ITERATOR =
@@ -307,11 +275,15 @@ public final class Iterators {
* {@code hasNext()} method will return {@code false}.
*/
public static String toString(Iterator<?> iterator) {
- return Joiner.on(", ")
- .useForNull("null")
- .appendTo(new StringBuilder().append('['), iterator)
- .append(']')
- .toString();
+ if (!iterator.hasNext()) {
+ return "[]";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append('[').append(iterator.next());
+ while (iterator.hasNext()) {
+ builder.append(", ").append(iterator.next());
+ }
+ return builder.append(']').toString();
}
/**
@@ -347,8 +319,8 @@ public final class Iterators {
* @throws IllegalArgumentException if the iterator contains multiple
* elements. The state of the iterator is unspecified.
*/
- @Nullable
- public static <T> T getOnlyElement(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getOnlyElement(
+ Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? getOnlyElement(iterator) : defaultValue;
}
@@ -459,8 +431,8 @@ public final class Iterators {
/**
* Returns an iterator that cycles indefinitely over the provided elements.
*
- * <p>The returned iterator supports {@code remove()}. After {@code remove()}
- * is called, subsequent cycles omit the removed
+ * <p>The returned iterator supports {@code remove()} if the provided iterator
+ * does. After {@code remove()} is called, subsequent cycles omit the removed
* element, but {@code elements} does not change. The iterator's
* {@code hasNext()} method returns {@code true} until all of the original
* elements have been removed.
@@ -480,11 +452,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -502,11 +469,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -525,11 +487,6 @@ public final class Iterators {
*
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
@SuppressWarnings("unchecked")
public static <T> Iterator<T> concat(Iterator<? extends T> a,
@@ -550,11 +507,6 @@ public final class Iterators {
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it.
*
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
- *
* @throws NullPointerException if any of the provided iterators is null
*/
public static <T> Iterator<T> concat(Iterator<? extends T>... inputs) {
@@ -569,11 +521,6 @@ public final class Iterators {
* <p>The returned iterator supports {@code remove()} when the corresponding
* input iterator supports it. The methods of the returned iterator may throw
* {@code NullPointerException} if any of the input iterators is null.
- *
- * <p><b>Note:</b> the current implementation is not suitable for nested
- * concatenated iterators, i.e. the following should be avoided when in a loop:
- * {@code iterator = Iterators.concat(iterator, suffix);}, since iteration over the
- * resulting iterator has a cubic complexity to the depth of the nesting.
*/
public static <T> Iterator<T> concat(
final Iterator<? extends Iterator<? extends T>> inputs) {
@@ -764,8 +711,8 @@ public final class Iterators {
* predicate; use this method only when such an element is known to exist. If
* no such element is found, the iterator will be left exhausted: its {@code
* hasNext()} method will return {@code false}. If it is possible that
- * <i>no</i> element will match, use {@link #tryFind} or {@link
- * #find(Iterator, Predicate, Object)} instead.
+ * <i>no</i> element will match, use {@link #tryFind)} or {@link
+ * #find(Iterator, Predicate, T)} instead.
*
* @throws NoSuchElementException if no element in {@code iterator} matches
* the given predicate
@@ -785,10 +732,9 @@ public final class Iterators {
*
* @since 7.0
*/
- @Nullable
- public static <T> T find(Iterator<? extends T> iterator, Predicate<? super T> predicate,
+ public static <T> T find(Iterator<T> iterator, Predicate<? super T> predicate,
@Nullable T defaultValue) {
- UnmodifiableIterator<? extends T> filteredIterator = filter(iterator, predicate);
+ UnmodifiableIterator<T> filteredIterator = filter(iterator, predicate);
return filteredIterator.hasNext() ? filteredIterator.next() : defaultValue;
}
@@ -853,12 +799,22 @@ public final class Iterators {
*/
public static <F, T> Iterator<T> transform(final Iterator<F> fromIterator,
final Function<? super F, ? extends T> function) {
+ checkNotNull(fromIterator);
checkNotNull(function);
- return new TransformedIterator<F, T>(fromIterator) {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return fromIterator.hasNext();
+ }
@Override
- T transform(F from) {
+ public T next() {
+ F from = fromIterator.next();
return function.apply(from);
}
+ @Override
+ public void remove() {
+ fromIterator.remove();
+ }
};
}
@@ -910,8 +866,8 @@ public final class Iterators {
* @throws IndexOutOfBoundsException if {@code position} is negative
* @since 4.0
*/
- @Nullable
- public static <T> T get(Iterator<? extends T> iterator, int position, @Nullable T defaultValue) {
+ public static <T> T get(Iterator<T> iterator, int position,
+ @Nullable T defaultValue) {
checkNonnegative(position);
try {
@@ -930,8 +886,7 @@ public final class Iterators {
* @return the next element of {@code iterator} or the default value
* @since 7.0
*/
- @Nullable
- public static <T> T getNext(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getNext(Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? iterator.next() : defaultValue;
}
@@ -958,24 +913,24 @@ public final class Iterators {
* @return the last element of {@code iterator}
* @since 3.0
*/
- @Nullable
- public static <T> T getLast(Iterator<? extends T> iterator, @Nullable T defaultValue) {
+ public static <T> T getLast(Iterator<T> iterator, @Nullable T defaultValue) {
return iterator.hasNext() ? getLast(iterator) : defaultValue;
}
/**
- * Calls {@code next()} on {@code iterator}, either {@code numberToAdvance} times
+ * Calls {@code next()} on {@code iterator}, either {@code numberToSkip} times
* or until {@code hasNext()} returns {@code false}, whichever comes first.
*
- * @return the number of elements the iterator was advanced
- * @since 13.0 (since 3.0 as {@code Iterators.skip})
+ * @return the number of elements skipped
+ * @since 3.0
*/
- public static int advance(Iterator<?> iterator, int numberToAdvance) {
+ @Beta
+ public static <T> int skip(Iterator<T> iterator, int numberToSkip) {
checkNotNull(iterator);
- checkArgument(numberToAdvance >= 0, "number to advance cannot be negative");
+ checkArgument(numberToSkip >= 0, "number to skip cannot be negative");
int i;
- for (i = 0; i < numberToAdvance && iterator.hasNext(); i++) {
+ for (i = 0; i < numberToSkip && iterator.hasNext(); i++) {
iterator.next();
}
return i;
@@ -1051,21 +1006,6 @@ public final class Iterators {
};
}
- /**
- * Deletes and returns the next value from the iterator, or returns
- * {@code defaultValue} if there is no such value.
- */
- @Nullable
- static <T> T pollNext(Iterator<T> iterator) {
- if (iterator.hasNext()) {
- T result = iterator.next();
- iterator.remove();
- return result;
- } else {
- return null;
- }
- }
-
// Methods only in Iterators, not in Iterables
/**
@@ -1103,14 +1043,21 @@ public final class Iterators {
}
/**
- * Returns a list iterator containing the elements in the specified range of
- * {@code array} in order, starting at the specified index.
+ * Returns an iterator containing the elements in the specified range of
+ * {@code array} in order. The returned iterator is a view of the array;
+ * subsequent changes to the array will be reflected in the iterator.
*
* <p>The {@code Iterable} equivalent of this method is {@code
- * Arrays.asList(array).subList(offset, offset + length).listIterator(index)}.
+ * Arrays.asList(array).subList(offset, offset + length)}.
+ *
+ * @param array array to read elements out of
+ * @param offset index of first array element to retrieve
+ * @param length number of elements in iteration
+ * @throws IndexOutOfBoundsException if {@code offset} is negative, {@code
+ * length} is negative, or {@code offset + length > array.length}
*/
- static <T> UnmodifiableListIterator<T> forArray(
- final T[] array, final int offset, int length, int index) {
+ static <T> UnmodifiableIterator<T> forArray(
+ final T[] array, final int offset, int length) {
checkArgument(length >= 0);
int end = offset + length;
@@ -1122,7 +1069,7 @@ public final class Iterators {
* because the returned Iterator is a ListIterator that may be moved back
* past the beginning of the iteration.
*/
- return new AbstractIndexedListIterator<T>(length, index) {
+ return new AbstractIndexedListIterator<T>(length) {
@Override protected T get(int index) {
return array[offset + index];
}
@@ -1379,19 +1326,4 @@ public final class Iterators {
return next;
}
}
-
- /**
- * Precondition tester for {@code Iterator.remove()} that throws an exception with a consistent
- * error message.
- */
- static void checkRemove(boolean canRemove) {
- checkState(canRemove, "no calls to next() since the last call to remove()");
- }
-
- /**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
- */
- static <T> ListIterator<T> cast(Iterator<T> iterator) {
- return (ListIterator<T>) iterator;
- }
}
diff --git a/guava/src/com/google/common/collect/LinkedHashMultimap.java b/guava/src/com/google/common/collect/LinkedHashMultimap.java
index 47bbe6f..39c0bfb 100644
--- a/guava/src/com/google/common/collect/LinkedHashMultimap.java
+++ b/guava/src/com/google/common/collect/LinkedHashMultimap.java
@@ -16,24 +16,20 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Ints;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Set;
import javax.annotation.Nullable;
@@ -69,23 +65,29 @@ import javax.annotation.Nullable;
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedSetMultimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Jared Levy
- * @author Louis Wasserman
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(serializable = true, emulated = true)
public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
+ private static final int DEFAULT_VALUES_PER_KEY = 8;
+
+ @VisibleForTesting
+ transient int expectedValuesPerKey = DEFAULT_VALUES_PER_KEY;
+
+ /**
+ * Map entries with an iteration order corresponding to the order in which the
+ * key-value pairs were added to the multimap.
+ */
+ // package-private for GWT deserialization
+ transient Collection<Map.Entry<K, V>> linkedEntries;
/**
* Creates a new, empty {@code LinkedHashMultimap} with the default initial
* capacities.
*/
public static <K, V> LinkedHashMultimap<K, V> create() {
- return new LinkedHashMultimap<K, V>(DEFAULT_KEY_CAPACITY, DEFAULT_VALUE_SET_CAPACITY);
+ return new LinkedHashMultimap<K, V>();
}
/**
@@ -99,9 +101,7 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
*/
public static <K, V> LinkedHashMultimap<K, V> create(
int expectedKeys, int expectedValuesPerKey) {
- return new LinkedHashMultimap<K, V>(
- Maps.capacity(expectedKeys),
- Maps.capacity(expectedValuesPerKey));
+ return new LinkedHashMultimap<K, V>(expectedKeys, expectedValuesPerKey);
}
/**
@@ -115,158 +115,201 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
*/
public static <K, V> LinkedHashMultimap<K, V> create(
Multimap<? extends K, ? extends V> multimap) {
- LinkedHashMultimap<K, V> result = create(multimap.keySet().size(), DEFAULT_VALUE_SET_CAPACITY);
- result.putAll(multimap);
- return result;
- }
-
- private interface ValueSetLink<K, V> {
- ValueSetLink<K, V> getPredecessorInValueSet();
- ValueSetLink<K, V> getSuccessorInValueSet();
-
- void setPredecessorInValueSet(ValueSetLink<K, V> entry);
- void setSuccessorInValueSet(ValueSetLink<K, V> entry);
+ return new LinkedHashMultimap<K, V>(multimap);
}
- private static <K, V> void succeedsInValueSet(ValueSetLink<K, V> pred, ValueSetLink<K, V> succ) {
- pred.setSuccessorInValueSet(succ);
- succ.setPredecessorInValueSet(pred);
+ private LinkedHashMultimap() {
+ super(new LinkedHashMap<K, Collection<V>>());
+ linkedEntries = Sets.newLinkedHashSet();
}
- private static <K, V> void succeedsInMultimap(
- ValueEntry<K, V> pred, ValueEntry<K, V> succ) {
- pred.setSuccessorInMultimap(succ);
- succ.setPredecessorInMultimap(pred);
+ private LinkedHashMultimap(int expectedKeys, int expectedValuesPerKey) {
+ super(new LinkedHashMap<K, Collection<V>>(expectedKeys));
+ Preconditions.checkArgument(expectedValuesPerKey >= 0);
+ this.expectedValuesPerKey = expectedValuesPerKey;
+ linkedEntries = new LinkedHashSet<Map.Entry<K, V>>(
+ (int) Math.min(Ints.MAX_POWER_OF_TWO,
+ ((long) expectedKeys) * expectedValuesPerKey));
}
- private static <K, V> void deleteFromValueSet(ValueSetLink<K, V> entry) {
- succeedsInValueSet(entry.getPredecessorInValueSet(), entry.getSuccessorInValueSet());
+ private LinkedHashMultimap(Multimap<? extends K, ? extends V> multimap) {
+ super(new LinkedHashMap<K, Collection<V>>(
+ Maps.capacity(multimap.keySet().size())));
+ linkedEntries
+ = new LinkedHashSet<Map.Entry<K, V>>(Maps.capacity(multimap.size()));
+ putAll(multimap);
}
- private static <K, V> void deleteFromMultimap(ValueEntry<K, V> entry) {
- succeedsInMultimap(entry.getPredecessorInMultimap(), entry.getSuccessorInMultimap());
+ /**
+ * {@inheritDoc}
+ *
+ * <p>Creates an empty {@code LinkedHashSet} for a collection of values for
+ * one key.
+ *
+ * @return a new {@code LinkedHashSet} containing a collection of values for
+ * one key
+ */
+ @Override Set<V> createCollection() {
+ return new LinkedHashSet<V>(Maps.capacity(expectedValuesPerKey));
}
/**
- * LinkedHashMultimap entries are in no less than three coexisting linked lists:
- * a row in the hash table for a Set<V> associated with a key, the linked list
- * of insertion-ordered entries in that Set<V>, and the linked list of entries
- * in the LinkedHashMultimap as a whole.
+ * {@inheritDoc}
+ *
+ * <p>Creates a decorated {@code LinkedHashSet} that also keeps track of the
+ * order in which key-value pairs are added to the multimap.
+ *
+ * @param key key to associate with values in the collection
+ * @return a new decorated {@code LinkedHashSet} containing a collection of
+ * values for one key
*/
- @VisibleForTesting
- static final class ValueEntry<K, V> extends AbstractMapEntry<K, V>
- implements ValueSetLink<K, V> {
- final K key;
- final V value;
- final int valueHash;
-
- @Nullable ValueEntry<K, V> nextInValueSetHashRow;
-
- ValueSetLink<K, V> predecessorInValueSet;
- ValueSetLink<K, V> successorInValueSet;
+ @Override Collection<V> createCollection(@Nullable K key) {
+ return new SetDecorator(key, createCollection());
+ }
- ValueEntry<K, V> predecessorInMultimap;
- ValueEntry<K, V> successorInMultimap;
+ private class SetDecorator extends ForwardingSet<V> {
+ final Set<V> delegate;
+ final K key;
- ValueEntry(@Nullable K key, @Nullable V value, int valueHash,
- @Nullable ValueEntry<K, V> nextInValueSetHashRow) {
+ SetDecorator(@Nullable K key, Set<V> delegate) {
+ this.delegate = delegate;
this.key = key;
- this.value = value;
- this.valueHash = valueHash;
- this.nextInValueSetHashRow = nextInValueSetHashRow;
}
- @Override
- public K getKey() {
- return key;
+ @Override protected Set<V> delegate() {
+ return delegate;
}
- @Override
- public V getValue() {
- return value;
+ <E> Map.Entry<K, E> createEntry(@Nullable E value) {
+ return Maps.immutableEntry(key, value);
}
- @Override
- public ValueSetLink<K, V> getPredecessorInValueSet() {
- return predecessorInValueSet;
+ <E> Collection<Map.Entry<K, E>> createEntries(Collection<E> values) {
+ // converts a collection of values into a list of key/value map entries
+ Collection<Map.Entry<K, E>> entries
+ = Lists.newArrayListWithExpectedSize(values.size());
+ for (E value : values) {
+ entries.add(createEntry(value));
+ }
+ return entries;
}
- @Override
- public ValueSetLink<K, V> getSuccessorInValueSet() {
- return successorInValueSet;
+ @Override public boolean add(@Nullable V value) {
+ boolean changed = delegate.add(value);
+ if (changed) {
+ linkedEntries.add(createEntry(value));
+ }
+ return changed;
}
- @Override
- public void setPredecessorInValueSet(ValueSetLink<K, V> entry) {
- predecessorInValueSet = entry;
+ @Override public boolean addAll(Collection<? extends V> values) {
+ boolean changed = delegate.addAll(values);
+ if (changed) {
+ linkedEntries.addAll(createEntries(delegate()));
+ }
+ return changed;
}
- @Override
- public void setSuccessorInValueSet(ValueSetLink<K, V> entry) {
- successorInValueSet = entry;
+ @Override public void clear() {
+ for (V value : delegate) {
+ linkedEntries.remove(createEntry(value));
+ }
+ delegate.clear();
}
- public ValueEntry<K, V> getPredecessorInMultimap() {
- return predecessorInMultimap;
- }
+ @Override public Iterator<V> iterator() {
+ final Iterator<V> delegateIterator = delegate.iterator();
+ return new Iterator<V>() {
+ V value;
- public ValueEntry<K, V> getSuccessorInMultimap() {
- return successorInMultimap;
+ @Override
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+ @Override
+ public V next() {
+ value = delegateIterator.next();
+ return value;
+ }
+ @Override
+ public void remove() {
+ delegateIterator.remove();
+ linkedEntries.remove(createEntry(value));
+ }
+ };
}
- public void setSuccessorInMultimap(ValueEntry<K, V> multimapSuccessor) {
- this.successorInMultimap = multimapSuccessor;
+ @Override public boolean remove(@Nullable Object value) {
+ boolean changed = delegate.remove(value);
+ if (changed) {
+ /*
+ * linkedEntries.remove() will return false when this method is called
+ * by entries().iterator().remove()
+ */
+ linkedEntries.remove(createEntry(value));
+ }
+ return changed;
}
- public void setPredecessorInMultimap(ValueEntry<K, V> multimapPredecessor) {
- this.predecessorInMultimap = multimapPredecessor;
+ @Override public boolean removeAll(Collection<?> values) {
+ boolean changed = delegate.removeAll(values);
+ if (changed) {
+ linkedEntries.removeAll(createEntries(values));
+ }
+ return changed;
}
- }
-
- private static final int DEFAULT_KEY_CAPACITY = 16;
- private static final int DEFAULT_VALUE_SET_CAPACITY = 2;
- @VisibleForTesting static final double VALUE_SET_LOAD_FACTOR = 1.0;
- @VisibleForTesting transient int valueSetCapacity = DEFAULT_VALUE_SET_CAPACITY;
- private transient ValueEntry<K, V> multimapHeaderEntry;
-
- private LinkedHashMultimap(int keyCapacity, int valueSetCapacity) {
- super(new LinkedHashMap<K, Collection<V>>(keyCapacity));
-
- checkArgument(valueSetCapacity >= 0,
- "expectedValuesPerKey must be >= 0 but was %s", valueSetCapacity);
-
- this.valueSetCapacity = valueSetCapacity;
- this.multimapHeaderEntry = new ValueEntry<K, V>(null, null, 0, null);
- succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry);
+ @Override public boolean retainAll(Collection<?> values) {
+ /*
+ * Calling linkedEntries.retainAll() would incorrectly remove values
+ * with other keys.
+ */
+ boolean changed = false;
+ Iterator<V> iterator = delegate.iterator();
+ while (iterator.hasNext()) {
+ V value = iterator.next();
+ if (!values.contains(value)) {
+ iterator.remove();
+ linkedEntries.remove(Maps.immutableEntry(key, value));
+ changed = true;
+ }
+ }
+ return changed;
+ }
}
/**
* {@inheritDoc}
*
- * <p>Creates an empty {@code LinkedHashSet} for a collection of values for
- * one key.
+ * <p>Generates an iterator across map entries that follows the ordering in
+ * which the key-value pairs were added to the multimap.
*
- * @return a new {@code LinkedHashSet} containing a collection of values for
- * one key
+ * @return a key-value iterator with the correct ordering
*/
- @Override
- Set<V> createCollection() {
- return new LinkedHashSet<V>(valueSetCapacity);
- }
+ @Override Iterator<Map.Entry<K, V>> createEntryIterator() {
+ final Iterator<Map.Entry<K, V>> delegateIterator = linkedEntries.iterator();
- /**
- * {@inheritDoc}
- *
- * <p>Creates a decorated insertion-ordered set that also keeps track of the
- * order in which key-value pairs are added to the multimap.
- *
- * @param key key to associate with values in the collection
- * @return a new decorated set containing a collection of values for one key
- */
- @Override
- Collection<V> createCollection(K key) {
- return new ValueSet(key, valueSetCapacity);
+ return new Iterator<Map.Entry<K, V>>() {
+ Map.Entry<K, V> entry;
+
+ @Override
+ public boolean hasNext() {
+ return delegateIterator.hasNext();
+ }
+
+ @Override
+ public Map.Entry<K, V> next() {
+ entry = delegateIterator.next();
+ return entry;
+ }
+
+ @Override
+ public void remove() {
+ // Remove from iterator first to keep iterator valid.
+ delegateIterator.remove();
+ LinkedHashMultimap.this.remove(entry.getKey(), entry.getValue());
+ }
+ };
}
/**
@@ -277,8 +320,8 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
* However, the provided values always come last in the {@link #entries()} and
* {@link #values()} iteration orderings.
*/
- @Override
- public Set<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
+ @Override public Set<V> replaceValues(
+ @Nullable K key, Iterable<? extends V> values) {
return super.replaceValues(key, values);
}
@@ -309,265 +352,20 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
return super.values();
}
- @VisibleForTesting
- final class ValueSet extends Sets.ImprovedAbstractSet<V> implements ValueSetLink<K, V> {
- /*
- * We currently use a fixed load factor of 1.0, a bit higher than normal to reduce memory
- * consumption.
- */
-
- private final K key;
- @VisibleForTesting ValueEntry<K, V>[] hashTable;
- private int size = 0;
- private int modCount = 0;
-
- // We use the set object itself as the end of the linked list, avoiding an unnecessary
- // entry object per key.
- private ValueSetLink<K, V> firstEntry;
- private ValueSetLink<K, V> lastEntry;
-
- ValueSet(K key, int expectedValues) {
- this.key = key;
- this.firstEntry = this;
- this.lastEntry = this;
- // Round expected values up to a power of 2 to get the table size.
- int tableSize = Hashing.closedTableSize(expectedValues, VALUE_SET_LOAD_FACTOR);
-
- @SuppressWarnings("unchecked")
- ValueEntry<K, V>[] hashTable = new ValueEntry[tableSize];
- this.hashTable = hashTable;
- }
-
- @Override
- public ValueSetLink<K, V> getPredecessorInValueSet() {
- return lastEntry;
- }
-
- @Override
- public ValueSetLink<K, V> getSuccessorInValueSet() {
- return firstEntry;
- }
-
- @Override
- public void setPredecessorInValueSet(ValueSetLink<K, V> entry) {
- lastEntry = entry;
- }
-
- @Override
- public void setSuccessorInValueSet(ValueSetLink<K, V> entry) {
- firstEntry = entry;
- }
-
- @Override
- public Iterator<V> iterator() {
- return new Iterator<V>() {
- ValueSetLink<K, V> nextEntry = firstEntry;
- ValueEntry<K, V> toRemove;
- int expectedModCount = modCount;
-
- private void checkForComodification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
-
- @Override
- public boolean hasNext() {
- checkForComodification();
- return nextEntry != ValueSet.this;
- }
-
- @Override
- public V next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- ValueEntry<K, V> entry = (ValueEntry<K, V>) nextEntry;
- V result = entry.getValue();
- toRemove = entry;
- nextEntry = entry.getSuccessorInValueSet();
- return result;
- }
-
- @Override
- public void remove() {
- checkForComodification();
- Iterators.checkRemove(toRemove != null);
- Object o = toRemove.getValue();
- int hash = (o == null) ? 0 : o.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
- ValueEntry<K, V> prev = null;
- for (ValueEntry<K, V> entry = hashTable[row]; entry != null;
- prev = entry, entry = entry.nextInValueSetHashRow) {
- if (entry == toRemove) {
- if (prev == null) {
- // first entry in row
- hashTable[row] = entry.nextInValueSetHashRow;
- } else {
- prev.nextInValueSetHashRow = entry.nextInValueSetHashRow;
- }
- deleteFromValueSet(toRemove);
- deleteFromMultimap(toRemove);
- size--;
- expectedModCount = ++modCount;
- break;
- }
- }
- toRemove = null;
- }
- };
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public boolean contains(@Nullable Object o) {
- int hash = (o == null) ? 0 : o.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
-
- for (ValueEntry<K, V> entry = hashTable[row]; entry != null;
- entry = entry.nextInValueSetHashRow) {
- if (hash == entry.valueHash && Objects.equal(o, entry.getValue())) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean add(@Nullable V value) {
- int hash = (value == null) ? 0 : value.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
-
- ValueEntry<K, V> rowHead = hashTable[row];
- for (ValueEntry<K, V> entry = rowHead; entry != null;
- entry = entry.nextInValueSetHashRow) {
- if (hash == entry.valueHash && Objects.equal(value, entry.getValue())) {
- return false;
- }
- }
-
- ValueEntry<K, V> newEntry = new ValueEntry<K, V>(key, value, hash, rowHead);
- succeedsInValueSet(lastEntry, newEntry);
- succeedsInValueSet(newEntry, this);
- succeedsInMultimap(multimapHeaderEntry.getPredecessorInMultimap(), newEntry);
- succeedsInMultimap(newEntry, multimapHeaderEntry);
- hashTable[row] = newEntry;
- size++;
- modCount++;
- rehashIfNecessary();
- return true;
- }
-
- private void rehashIfNecessary() {
- if (Hashing.needsResizing(size, hashTable.length, VALUE_SET_LOAD_FACTOR)) {
- @SuppressWarnings("unchecked")
- ValueEntry<K, V>[] hashTable = new ValueEntry[this.hashTable.length * 2];
- this.hashTable = hashTable;
- int mask = hashTable.length - 1;
- for (ValueSetLink<K, V> entry = firstEntry;
- entry != this; entry = entry.getSuccessorInValueSet()) {
- ValueEntry<K, V> valueEntry = (ValueEntry<K, V>) entry;
- int row = Hashing.smear(valueEntry.valueHash) & mask;
- valueEntry.nextInValueSetHashRow = hashTable[row];
- hashTable[row] = valueEntry;
- }
- }
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- int hash = (o == null) ? 0 : o.hashCode();
- int row = Hashing.smear(hash) & (hashTable.length - 1);
-
- ValueEntry<K, V> prev = null;
- for (ValueEntry<K, V> entry = hashTable[row]; entry != null;
- prev = entry, entry = entry.nextInValueSetHashRow) {
- if (hash == entry.valueHash && Objects.equal(o, entry.getValue())) {
- if (prev == null) {
- // first entry in the row
- hashTable[row] = entry.nextInValueSetHashRow;
- } else {
- prev.nextInValueSetHashRow = entry.nextInValueSetHashRow;
- }
- deleteFromValueSet(entry);
- deleteFromMultimap(entry);
- size--;
- modCount++;
- return true;
- }
- }
- return false;
- }
-
- @Override
- public void clear() {
- Arrays.fill(hashTable, null);
- size = 0;
- for (ValueSetLink<K, V> entry = firstEntry;
- entry != this; entry = entry.getSuccessorInValueSet()) {
- ValueEntry<K, V> valueEntry = (ValueEntry<K, V>) entry;
- deleteFromMultimap(valueEntry);
- }
- succeedsInValueSet(this, this);
- modCount++;
- }
- }
-
- @Override
- Iterator<Map.Entry<K, V>> entryIterator() {
- return new Iterator<Map.Entry<K, V>>() {
- ValueEntry<K, V> nextEntry = multimapHeaderEntry.successorInMultimap;
- ValueEntry<K, V> toRemove;
-
- @Override
- public boolean hasNext() {
- return nextEntry != multimapHeaderEntry;
- }
-
- @Override
- public Map.Entry<K, V> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- ValueEntry<K, V> result = nextEntry;
- toRemove = result;
- nextEntry = nextEntry.successorInMultimap;
- return result;
- }
-
- @Override
- public void remove() {
- Iterators.checkRemove(toRemove != null);
- LinkedHashMultimap.this.remove(toRemove.getKey(), toRemove.getValue());
- toRemove = null;
- }
- };
- }
-
- @Override
- public void clear() {
- super.clear();
- succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry);
- }
+ // Unfortunately, the entries() ordering does not determine the key ordering;
+ // see the example in the LinkedListMultimap class Javadoc.
/**
- * @serialData the expected values per key, the number of distinct keys,
- * the number of entries, and the entries in order
+ * @serialData the number of distinct keys, and then for each distinct key:
+ * the first key, the number of values for that key, and the key's values,
+ * followed by successive keys and values from the entries() ordering
*/
@GwtIncompatible("java.io.ObjectOutputStream")
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
- stream.writeInt(valueSetCapacity);
- stream.writeInt(keySet().size());
- for (K key : keySet()) {
- stream.writeObject(key);
- }
- stream.writeInt(size());
- for (Map.Entry<K, V> entry : entries()) {
+ stream.writeInt(expectedValuesPerKey);
+ Serialization.writeMultimap(this, stream);
+ for (Map.Entry<K, V> entry : linkedEntries) {
stream.writeObject(entry.getKey());
stream.writeObject(entry.getValue());
}
@@ -577,28 +375,22 @@ public final class LinkedHashMultimap<K, V> extends AbstractSetMultimap<K, V> {
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- multimapHeaderEntry = new ValueEntry<K, V>(null, null, 0, null);
- succeedsInMultimap(multimapHeaderEntry, multimapHeaderEntry);
- valueSetCapacity = stream.readInt();
- int distinctKeys = stream.readInt();
- Map<K, Collection<V>> map =
- new LinkedHashMap<K, Collection<V>>(Maps.capacity(distinctKeys));
- for (int i = 0; i < distinctKeys; i++) {
- @SuppressWarnings("unchecked")
- K key = (K) stream.readObject();
- map.put(key, createCollection(key));
- }
- int entries = stream.readInt();
- for (int i = 0; i < entries; i++) {
- @SuppressWarnings("unchecked")
+ expectedValuesPerKey = stream.readInt();
+ int distinctKeys = Serialization.readCount(stream);
+ setMap(new LinkedHashMap<K, Collection<V>>(Maps.capacity(distinctKeys)));
+ linkedEntries = new LinkedHashSet<Map.Entry<K, V>>(
+ distinctKeys * expectedValuesPerKey);
+ Serialization.populateMultimap(this, stream, distinctKeys);
+ linkedEntries.clear(); // will clear and repopulate entries
+ for (int i = 0; i < size(); i++) {
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
K key = (K) stream.readObject();
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
V value = (V) stream.readObject();
- map.get(key).add(value);
+ linkedEntries.add(Maps.immutableEntry(key, value));
}
- setMap(map);
}
@GwtIncompatible("java serialization not supported")
- private static final long serialVersionUID = 1;
+ private static final long serialVersionUID = 0;
}
diff --git a/guava/src/com/google/common/collect/LinkedHashMultiset.java b/guava/src/com/google/common/collect/LinkedHashMultiset.java
index 9b8c45b..c8db8e2 100644
--- a/guava/src/com/google/common/collect/LinkedHashMultiset.java
+++ b/guava/src/com/google/common/collect/LinkedHashMultiset.java
@@ -31,10 +31,6 @@ import java.util.LinkedHashMap;
* element, those instances are consecutive in the iteration order. If all
* occurrences of an element are removed, after which that element is added to
* the multiset, the element will appear at the end of the iteration.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
*
* @author Kevin Bourrillion
* @author Jared Levy
diff --git a/guava/src/com/google/common/collect/LinkedListMultimap.java b/guava/src/com/google/common/collect/LinkedListMultimap.java
index 0a7b100..336ca72 100644
--- a/guava/src/com/google/common/collect/LinkedListMultimap.java
+++ b/guava/src/com/google/common/collect/LinkedListMultimap.java
@@ -17,7 +17,9 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Multisets.setCountImpl;
import static java.util.Collections.unmodifiableList;
import com.google.common.annotations.GwtCompatible;
@@ -29,10 +31,11 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
import java.util.AbstractSequentialList;
+import java.util.AbstractSet;
import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -92,10 +95,6 @@ import javax.annotation.Nullable;
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedListMultimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Mike Bostock
* @since 2.0 (imported from Google Collections Library)
*/
@@ -126,32 +125,12 @@ public class LinkedListMultimap<K, V>
return key + "=" + value;
}
}
-
- private static class KeyList<K, V> {
- Node<K, V> head;
- Node<K, V> tail;
- int count;
-
- KeyList(Node<K, V> firstNode) {
- this.head = firstNode;
- this.tail = firstNode;
- firstNode.previousSibling = null;
- firstNode.nextSibling = null;
- this.count = 1;
- }
- }
private transient Node<K, V> head; // the head for all keys
private transient Node<K, V> tail; // the tail for all keys
- private transient Map<K, KeyList<K, V>> keyToKeyList;
- private transient int size;
-
- /*
- * Tracks modifications to keyToKeyList so that addition or removal of keys invalidates
- * preexisting iterators. This does *not* track simple additions and removals of values
- * that are not the first to be added or last to be removed for their key.
- */
- private transient int modCount;
+ private transient Multiset<K> keyCount; // the number of values for each key
+ private transient Map<K, Node<K, V>> keyToKeyHead; // the head for a given key
+ private transient Map<K, Node<K, V>> keyToKeyTail; // the tail for a given key
/**
* Creates a new, empty {@code LinkedListMultimap} with the default initial
@@ -185,11 +164,15 @@ public class LinkedListMultimap<K, V>
}
LinkedListMultimap() {
- keyToKeyList = Maps.newHashMap();
+ keyCount = LinkedHashMultiset.create();
+ keyToKeyHead = Maps.newHashMap();
+ keyToKeyTail = Maps.newHashMap();
}
private LinkedListMultimap(int expectedKeys) {
- keyToKeyList = new HashMap<K, KeyList<K, V>>(expectedKeys);
+ keyCount = LinkedHashMultiset.create(expectedKeys);
+ keyToKeyHead = Maps.newHashMapWithExpectedSize(expectedKeys);
+ keyToKeyTail = Maps.newHashMapWithExpectedSize(expectedKeys);
}
private LinkedListMultimap(Multimap<? extends K, ? extends V> multimap) {
@@ -208,32 +191,27 @@ public class LinkedListMultimap<K, V>
Node<K, V> node = new Node<K, V>(key, value);
if (head == null) { // empty list
head = tail = node;
- keyToKeyList.put(key, new KeyList<K, V>(node));
- modCount++;
+ keyToKeyHead.put(key, node);
+ keyToKeyTail.put(key, node);
} else if (nextSibling == null) { // non-empty list, add to tail
tail.next = node;
node.previous = tail;
- tail = node;
- KeyList<K, V> keyList = keyToKeyList.get(key);
- if (keyList == null) {
- keyToKeyList.put(key, keyList = new KeyList<K, V>(node));
- modCount++;
+ Node<K, V> keyTail = keyToKeyTail.get(key);
+ if (keyTail == null) { // first for this key
+ keyToKeyHead.put(key, node);
} else {
- keyList.count++;
- Node<K, V> keyTail = keyList.tail;
keyTail.nextSibling = node;
node.previousSibling = keyTail;
- keyList.tail = node;
}
+ keyToKeyTail.put(key, node);
+ tail = node;
} else { // non-empty list, insert before nextSibling
- KeyList<K, V> keyList = keyToKeyList.get(key);
- keyList.count++;
node.previous = nextSibling.previous;
node.previousSibling = nextSibling.previousSibling;
node.next = nextSibling;
node.nextSibling = nextSibling;
if (nextSibling.previousSibling == null) { // nextSibling was key head
- keyToKeyList.get(key).head = node;
+ keyToKeyHead.put(key, node);
} else {
nextSibling.previousSibling.nextSibling = node;
}
@@ -245,7 +223,7 @@ public class LinkedListMultimap<K, V>
nextSibling.previous = node;
nextSibling.previousSibling = node;
}
- size++;
+ keyCount.add(key);
return node;
}
@@ -265,27 +243,21 @@ public class LinkedListMultimap<K, V>
} else { // node was tail
tail = node.previous;
}
- if (node.previousSibling == null && node.nextSibling == null) {
- KeyList<K, V> keyList = keyToKeyList.remove(node.key);
- keyList.count = 0;
- modCount++;
+ if (node.previousSibling != null) {
+ node.previousSibling.nextSibling = node.nextSibling;
+ } else if (node.nextSibling != null) { // node was key head
+ keyToKeyHead.put(node.key, node.nextSibling);
} else {
- KeyList<K, V> keyList = keyToKeyList.get(node.key);
- keyList.count--;
-
- if (node.previousSibling == null) {
- keyList.head = node.nextSibling;
- } else {
- node.previousSibling.nextSibling = node.nextSibling;
- }
-
- if (node.nextSibling == null) {
- keyList.tail = node.previousSibling;
- } else {
- node.nextSibling.previousSibling = node.previousSibling;
- }
+ keyToKeyHead.remove(node.key); // don't leak a key-null entry
}
- size--;
+ if (node.nextSibling != null) {
+ node.nextSibling.previousSibling = node.previousSibling;
+ } else if (node.previousSibling != null) { // node was key tail
+ keyToKeyTail.put(node.key, node.previousSibling);
+ } else {
+ keyToKeyTail.remove(node.key); // don't leak a key-null entry
+ }
+ keyCount.remove(node.key);
}
/** Removes all nodes for the specified key. */
@@ -309,7 +281,6 @@ public class LinkedListMultimap<K, V>
Node<K, V> next;
Node<K, V> current;
Node<K, V> previous;
- int expectedModCount = modCount;
NodeIterator() {
next = head;
@@ -331,19 +302,12 @@ public class LinkedListMultimap<K, V>
}
current = null;
}
- private void checkForConcurrentModification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
@Override
public boolean hasNext() {
- checkForConcurrentModification();
return next != null;
}
@Override
public Node<K, V> next() {
- checkForConcurrentModification();
checkElement(next);
previous = current = next;
next = next.next;
@@ -352,7 +316,6 @@ public class LinkedListMultimap<K, V>
}
@Override
public void remove() {
- checkForConcurrentModification();
checkState(current != null);
if (current != next) { // after call to next()
previous = current.previous;
@@ -362,16 +325,13 @@ public class LinkedListMultimap<K, V>
}
removeNode(current);
current = null;
- expectedModCount = modCount;
}
@Override
public boolean hasPrevious() {
- checkForConcurrentModification();
return previous != null;
}
@Override
public Node<K, V> previous() {
- checkForConcurrentModification();
checkElement(previous);
next = current = previous;
previous = previous.previous;
@@ -405,21 +365,13 @@ public class LinkedListMultimap<K, V>
final Set<K> seenKeys = Sets.<K>newHashSetWithExpectedSize(keySet().size());
Node<K, V> next = head;
Node<K, V> current;
- int expectedModCount = modCount;
-
- private void checkForConcurrentModification() {
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
+
@Override
public boolean hasNext() {
- checkForConcurrentModification();
return next != null;
}
@Override
public K next() {
- checkForConcurrentModification();
checkElement(next);
current = next;
seenKeys.add(current.key);
@@ -430,11 +382,9 @@ public class LinkedListMultimap<K, V>
}
@Override
public void remove() {
- checkForConcurrentModification();
checkState(current != null);
removeAllNodes(current.key);
current = null;
- expectedModCount = modCount;
}
}
@@ -449,8 +399,7 @@ public class LinkedListMultimap<K, V>
/** Constructs a new iterator over all values for the specified key. */
ValueForKeyIterator(@Nullable Object key) {
this.key = key;
- KeyList<K, V> keyList = keyToKeyList.get(key);
- next = (keyList == null) ? null : keyList.head;
+ next = keyToKeyHead.get(key);
}
/**
@@ -463,17 +412,16 @@ public class LinkedListMultimap<K, V>
* @throws IndexOutOfBoundsException if index is invalid
*/
public ValueForKeyIterator(@Nullable Object key, int index) {
- KeyList<K, V> keyList = keyToKeyList.get(key);
- int size = (keyList == null) ? 0 : keyList.count;
+ int size = keyCount.count(key);
Preconditions.checkPositionIndex(index, size);
if (index >= (size / 2)) {
- previous = (keyList == null) ? null : keyList.tail;
+ previous = keyToKeyTail.get(key);
nextIndex = size;
while (index++ < size) {
previous();
}
} else {
- next = (keyList == null) ? null : keyList.head;
+ next = keyToKeyHead.get(key);
while (index-- > 0) {
next();
}
@@ -552,7 +500,7 @@ public class LinkedListMultimap<K, V>
@Override
public int size() {
- return size;
+ return keyCount.size();
}
@Override
@@ -562,7 +510,7 @@ public class LinkedListMultimap<K, V>
@Override
public boolean containsKey(@Nullable Object key) {
- return keyToKeyList.containsKey(key);
+ return keyToKeyHead.containsKey(key);
}
@Override
@@ -689,9 +637,9 @@ public class LinkedListMultimap<K, V>
public void clear() {
head = null;
tail = null;
- keyToKeyList.clear();
- size = 0;
- modCount++;
+ keyCount.clear();
+ keyToKeyHead.clear();
+ keyToKeyTail.clear();
}
// Views
@@ -709,8 +657,7 @@ public class LinkedListMultimap<K, V>
public List<V> get(final @Nullable K key) {
return new AbstractSequentialList<V>() {
@Override public int size() {
- KeyList<K, V> keyList = keyToKeyList.get(key);
- return (keyList == null) ? 0 : keyList.count;
+ return keyCount.count(key);
}
@Override public ListIterator<V> listIterator(int index) {
return new ValueForKeyIterator(key, index);
@@ -730,19 +677,19 @@ public class LinkedListMultimap<K, V>
public Set<K> keySet() {
Set<K> result = keySet;
if (result == null) {
- keySet = result = new Sets.ImprovedAbstractSet<K>() {
+ keySet = result = new AbstractSet<K>() {
@Override public int size() {
- return keyToKeyList.size();
+ return keyCount.elementSet().size();
}
@Override public Iterator<K> iterator() {
return new DistinctKeyIterator();
}
@Override public boolean contains(Object key) { // for performance
- return containsKey(key);
+ return keyCount.contains(key);
}
- @Override
- public boolean remove(Object o) { // for performance
- return !LinkedListMultimap.this.removeAll(o).isEmpty();
+ @Override public boolean removeAll(Collection<?> c) {
+ checkNotNull(c); // eager for GWT
+ return super.removeAll(c);
}
};
}
@@ -760,50 +707,39 @@ public class LinkedListMultimap<K, V>
return result;
}
- private class MultisetView extends AbstractMultiset<K> {
- @Override
- public int size() {
- return size;
- }
+ private class MultisetView extends AbstractCollection<K>
+ implements Multiset<K> {
- @Override
- public int count(Object element) {
- KeyList<K, V> keyList = keyToKeyList.get(element);
- return (keyList == null) ? 0 : keyList.count;
+ @Override public int size() {
+ return keyCount.size();
}
- @Override
- Iterator<Entry<K>> entryIterator() {
- return new TransformedIterator<K, Entry<K>>(new DistinctKeyIterator()) {
+ @Override public Iterator<K> iterator() {
+ final Iterator<Node<K, V>> nodes = new NodeIterator();
+ return new Iterator<K>() {
@Override
- Entry<K> transform(final K key) {
- return new Multisets.AbstractEntry<K>() {
- @Override
- public K getElement() {
- return key;
- }
-
- @Override
- public int getCount() {
- return keyToKeyList.get(key).count;
- }
- };
+ public boolean hasNext() {
+ return nodes.hasNext();
+ }
+ @Override
+ public K next() {
+ return nodes.next().key;
+ }
+ @Override
+ public void remove() {
+ nodes.remove();
}
};
}
@Override
- int distinctElements() {
- return elementSet().size();
+ public int count(@Nullable Object key) {
+ return keyCount.count(key);
}
- @Override public Iterator<K> iterator() {
- return new TransformedIterator<Node<K, V>, K>(new NodeIterator()) {
- @Override
- K transform(Node<K, V> node) {
- return node.key;
- }
- };
+ @Override
+ public int add(@Nullable K key, int occurrences) {
+ throw new UnsupportedOperationException();
}
@Override
@@ -819,9 +755,77 @@ public class LinkedListMultimap<K, V>
}
@Override
+ public int setCount(K element, int count) {
+ return setCountImpl(this, element, count);
+ }
+
+ @Override
+ public boolean setCount(K element, int oldCount, int newCount) {
+ return setCountImpl(this, element, oldCount, newCount);
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Iterators.removeAll(iterator(), c);
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ return Iterators.retainAll(iterator(), c);
+ }
+
+ @Override
public Set<K> elementSet() {
return keySet();
}
+
+ @Override
+ public Set<Entry<K>> entrySet() {
+ // TODO(jlevy): lazy init?
+ return new AbstractSet<Entry<K>>() {
+ @Override public int size() {
+ return keyCount.elementSet().size();
+ }
+
+ @Override public Iterator<Entry<K>> iterator() {
+ final Iterator<K> keyIterator = new DistinctKeyIterator();
+ return new Iterator<Entry<K>>() {
+ @Override
+ public boolean hasNext() {
+ return keyIterator.hasNext();
+ }
+ @Override
+ public Entry<K> next() {
+ final K key = keyIterator.next();
+ return new Multisets.AbstractEntry<K>() {
+ @Override
+ public K getElement() {
+ return key;
+ }
+ @Override
+ public int getCount() {
+ return keyCount.count(key);
+ }
+ };
+ }
+ @Override
+ public void remove() {
+ keyIterator.remove();
+ }
+ };
+ }
+ };
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ return keyCount.equals(object);
+ }
+
+ @Override public int hashCode() {
+ return keyCount.hashCode();
+ }
+
+ @Override public String toString() {
+ return keyCount.toString(); // XXX observe order?
+ }
}
private transient List<V> valuesList;
@@ -841,20 +845,47 @@ public class LinkedListMultimap<K, V>
if (result == null) {
valuesList = result = new AbstractSequentialList<V>() {
@Override public int size() {
- return size;
+ return keyCount.size();
}
@Override
public ListIterator<V> listIterator(int index) {
final NodeIterator nodes = new NodeIterator(index);
- return new TransformedListIterator<Node<K, V>, V>(nodes) {
+ return new ListIterator<V>() {
@Override
- V transform(Node<K, V> node) {
- return node.value;
+ public boolean hasNext() {
+ return nodes.hasNext();
+ }
+ @Override
+ public V next() {
+ return nodes.next().value;
+ }
+ @Override
+ public boolean hasPrevious() {
+ return nodes.hasPrevious();
+ }
+ @Override
+ public V previous() {
+ return nodes.previous().value;
}
-
@Override
- public void set(V value) {
- nodes.setValue(value);
+ public int nextIndex() {
+ return nodes.nextIndex();
+ }
+ @Override
+ public int previousIndex() {
+ return nodes.previousIndex();
+ }
+ @Override
+ public void remove() {
+ nodes.remove();
+ }
+ @Override
+ public void set(V e) {
+ nodes.setValue(e);
+ }
+ @Override
+ public void add(V e) {
+ throw new UnsupportedOperationException();
}
};
}
@@ -905,14 +936,55 @@ public class LinkedListMultimap<K, V>
if (result == null) {
entries = result = new AbstractSequentialList<Entry<K, V>>() {
@Override public int size() {
- return size;
+ return keyCount.size();
}
@Override public ListIterator<Entry<K, V>> listIterator(int index) {
- return new TransformedListIterator<Node<K, V>, Entry<K, V>>(new NodeIterator(index)) {
+ final ListIterator<Node<K, V>> nodes = new NodeIterator(index);
+ return new ListIterator<Entry<K, V>>() {
+ @Override
+ public boolean hasNext() {
+ return nodes.hasNext();
+ }
+
+ @Override
+ public Entry<K, V> next() {
+ return createEntry(nodes.next());
+ }
+
+ @Override
+ public void remove() {
+ nodes.remove();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return nodes.hasPrevious();
+ }
+
+ @Override
+ public Map.Entry<K, V> previous() {
+ return createEntry(nodes.previous());
+ }
+
+ @Override
+ public int nextIndex() {
+ return nodes.nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return nodes.previousIndex();
+ }
+
+ @Override
+ public void set(Map.Entry<K, V> e) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
- Entry<K, V> transform(Node<K, V> node) {
- return createEntry(node);
+ public void add(Map.Entry<K, V> e) {
+ throw new UnsupportedOperationException();
}
};
}
@@ -921,39 +993,75 @@ public class LinkedListMultimap<K, V>
return result;
}
+ private class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
+ @Override public int size() {
+ return keyCount.elementSet().size();
+ }
+
+ @Override public Iterator<Entry<K, Collection<V>>> iterator() {
+ final Iterator<K> keyIterator = new DistinctKeyIterator();
+ return new Iterator<Entry<K, Collection<V>>>() {
+ @Override
+ public boolean hasNext() {
+ return keyIterator.hasNext();
+ }
+
+ @Override
+ public Entry<K, Collection<V>> next() {
+ final K key = keyIterator.next();
+ return new AbstractMapEntry<K, Collection<V>>() {
+ @Override public K getKey() {
+ return key;
+ }
+
+ @Override public Collection<V> getValue() {
+ return LinkedListMultimap.this.get(key);
+ }
+ };
+ }
+
+ @Override
+ public void remove() {
+ keyIterator.remove();
+ }
+ };
+ }
+
+ // TODO(jlevy): Override contains() and remove() for better performance.
+ }
+
private transient Map<K, Collection<V>> map;
@Override
public Map<K, Collection<V>> asMap() {
Map<K, Collection<V>> result = map;
if (result == null) {
- map = result = new Multimaps.AsMap<K, V>() {
- @Override
- public int size() {
- return keyToKeyList.size();
+ map = result = new AbstractMap<K, Collection<V>>() {
+ Set<Entry<K, Collection<V>>> entrySet;
+
+ @Override public Set<Entry<K, Collection<V>>> entrySet() {
+ Set<Entry<K, Collection<V>>> result = entrySet;
+ if (result == null) {
+ entrySet = result = new AsMapEntries();
+ }
+ return result;
}
- @Override
- Multimap<K, V> multimap() {
- return LinkedListMultimap.this;
+ // The following methods are included for performance.
+
+ @Override public boolean containsKey(@Nullable Object key) {
+ return LinkedListMultimap.this.containsKey(key);
}
- @Override
- Iterator<Entry<K, Collection<V>>> entryIterator() {
- return new TransformedIterator<K, Entry<K, Collection<V>>>(new DistinctKeyIterator()) {
- @Override
- Entry<K, Collection<V>> transform(final K key) {
- return new AbstractMapEntry<K, Collection<V>>() {
- @Override public K getKey() {
- return key;
- }
+ @SuppressWarnings("unchecked")
+ @Override public Collection<V> get(@Nullable Object key) {
+ Collection<V> collection = LinkedListMultimap.this.get((K) key);
+ return collection.isEmpty() ? null : collection;
+ }
- @Override public Collection<V> getValue() {
- return LinkedListMultimap.this.get(key);
- }
- };
- }
- };
+ @Override public Collection<V> remove(@Nullable Object key) {
+ Collection<V> collection = removeAll(key);
+ return collection.isEmpty() ? null : collection;
}
};
}
@@ -1020,7 +1128,9 @@ public class LinkedListMultimap<K, V>
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- keyToKeyList = Maps.newLinkedHashMap();
+ keyCount = LinkedHashMultiset.create();
+ keyToKeyHead = Maps.newHashMap();
+ keyToKeyTail = Maps.newHashMap();
int size = stream.readInt();
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked") // reading data stored by writeObject
diff --git a/guava/src/com/google/common/collect/ListMultimap.java b/guava/src/com/google/common/collect/ListMultimap.java
index a83b81a..cf4cbaa 100644
--- a/guava/src/com/google/common/collect/ListMultimap.java
+++ b/guava/src/com/google/common/collect/ListMultimap.java
@@ -26,16 +26,11 @@ import javax.annotation.Nullable;
/**
* A {@code Multimap} that can hold duplicate key-value pairs and that maintains
- * the insertion ordering of values for a given key. See the {@link Multimap}
- * documentation for information common to all multimaps.
+ * the insertion ordering of values for a given key.
*
* <p>The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods
* each return a {@link List} of values. Though the method signature doesn't say
* so explicitly, the map returned by {@link #asMap} has {@code List} values.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
*
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
diff --git a/guava/src/com/google/common/collect/Lists.java b/guava/src/com/google/common/collect/Lists.java
index 271da37..850d87e 100644
--- a/guava/src/com/google/common/collect/Lists.java
+++ b/guava/src/com/google/common/collect/Lists.java
@@ -25,7 +25,6 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Objects;
@@ -44,24 +43,19 @@ import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
-import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.Nullable;
/**
* Static utility methods pertaining to {@link List} instances. Also see this
- * class's counterparts {@link Sets}, {@link Maps} and {@link Queues}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Lists">
- * {@code Lists}</a>.
+ * class's counterparts {@link Sets} and {@link Maps}.
*
* @author Kevin Bourrillion
* @author Mike Bostock
* @author Louis Wasserman
* @since 2.0 (imported from Google Collections Library)
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public final class Lists {
private Lists() {}
@@ -227,38 +221,6 @@ public final class Lists {
}
/**
- * Creates an empty {@code CopyOnWriteArrayList} instance.
- *
- * <p><b>Note:</b> if you need an immutable empty {@link List}, use
- * {@link Collections#emptyList} instead.
- *
- * @return a new, empty {@code CopyOnWriteArrayList}
- * @since 12.0
- */
- @GwtIncompatible("CopyOnWriteArrayList")
- public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList() {
- return new CopyOnWriteArrayList<E>();
- }
-
- /**
- * Creates a {@code CopyOnWriteArrayList} instance containing the given elements.
- *
- * @param elements the elements that the list should contain, in order
- * @return a new {@code CopyOnWriteArrayList} containing those elements
- * @since 12.0
- */
- @GwtIncompatible("CopyOnWriteArrayList")
- public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList(
- Iterable<? extends E> elements) {
- // We copy elements to an ArrayList first, rather than incurring the
- // quadratic cost of adding them to the COWAL directly.
- Collection<? extends E> elementsCollection = (elements instanceof Collection)
- ? Collections2.cast(elements)
- : newArrayList(elements);
- return new CopyOnWriteArrayList<E>(elementsCollection);
- }
-
- /**
* Returns an unmodifiable list containing the specified first element and
* backed by the specified array of additional elements. Changes to the {@code
* rest} array will be reflected in the returned list. Unlike {@link
@@ -352,127 +314,6 @@ public final class Lists {
}
/**
- * Returns every possible list that can be formed by choosing one element
- * from each of the given lists in order; the "n-ary
- * <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
- * product</a>" of the lists. For example: <pre> {@code
- *
- * Lists.cartesianProduct(ImmutableList.of(
- * ImmutableList.of(1, 2),
- * ImmutableList.of("A", "B", "C")))}</pre>
- *
- * returns a list containing six lists in the following order:
- *
- * <ul>
- * <li>{@code ImmutableList.of(1, "A")}
- * <li>{@code ImmutableList.of(1, "B")}
- * <li>{@code ImmutableList.of(1, "C")}
- * <li>{@code ImmutableList.of(2, "A")}
- * <li>{@code ImmutableList.of(2, "B")}
- * <li>{@code ImmutableList.of(2, "C")}
- * </ul>
- *
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : lists.get(0)) {
- * for (B b1 : lists.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input list is empty, the Cartesian product will also be
- * empty. If no lists at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
- *
- * <p><i>Performance notes:</i> while the cartesian product of lists of size
- * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory
- * consumption is much smaller. When the cartesian product is constructed, the
- * input lists are merely copied. Only as the resulting list is iterated are
- * the individual lists created, and these are not retained after iteration.
- *
- * @param lists the lists to choose elements from, in the order that
- * the elements chosen from those lists should appear in the resulting
- * lists
- * @param <B> any common base class shared by all axes (often just {@link
- * Object})
- * @return the Cartesian product, as an immutable list containing immutable
- * lists
- * @throws IllegalArgumentException if the size of the cartesian product would
- * be greater than {@link Integer#MAX_VALUE}
- * @throws NullPointerException if {@code lists}, any one of the {@code lists},
- * or any element of a provided list is null
- */
- static <B> List<List<B>> cartesianProduct(
- List<? extends List<? extends B>> lists) {
- return CartesianList.create(lists);
- }
-
- /**
- * Returns every possible list that can be formed by choosing one element
- * from each of the given lists in order; the "n-ary
- * <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
- * product</a>" of the lists. For example: <pre> {@code
- *
- * Lists.cartesianProduct(ImmutableList.of(
- * ImmutableList.of(1, 2),
- * ImmutableList.of("A", "B", "C")))}</pre>
- *
- * returns a list containing six lists in the following order:
- *
- * <ul>
- * <li>{@code ImmutableList.of(1, "A")}
- * <li>{@code ImmutableList.of(1, "B")}
- * <li>{@code ImmutableList.of(1, "C")}
- * <li>{@code ImmutableList.of(2, "A")}
- * <li>{@code ImmutableList.of(2, "B")}
- * <li>{@code ImmutableList.of(2, "C")}
- * </ul>
- *
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : lists.get(0)) {
- * for (B b1 : lists.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input list is empty, the Cartesian product will also be
- * empty. If no lists at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
- *
- * <p><i>Performance notes:</i> while the cartesian product of lists of size
- * {@code m, n, p} is a list of size {@code m x n x p}, its actual memory
- * consumption is much smaller. When the cartesian product is constructed, the
- * input lists are merely copied. Only as the resulting list is iterated are
- * the individual lists created, and these are not retained after iteration.
- *
- * @param lists the lists to choose elements from, in the order that
- * the elements chosen from those lists should appear in the resulting
- * lists
- * @param <B> any common base class shared by all axes (often just {@link
- * Object})
- * @return the Cartesian product, as an immutable list containing immutable
- * lists
- * @throws IllegalArgumentException if the size of the cartesian product would
- * be greater than {@link Integer#MAX_VALUE}
- * @throws NullPointerException if {@code lists}, any one of the
- * {@code lists}, or any element of a provided list is null
- */
- static <B> List<List<B>> cartesianProduct(List<? extends B>... lists) {
- return cartesianProduct(Arrays.asList(lists));
- }
-
- /**
* Returns a list that applies {@code function} to each element of {@code
* fromList}. The returned list is a transformed view of {@code fromList};
* changes to {@code fromList} will be reflected in the returned list and vice
@@ -491,19 +332,13 @@ public final class Lists {
* view, copy the returned list into a new list of your choosing.
*
* <p>If {@code fromList} implements {@link RandomAccess}, so will the
- * returned list. The returned list is threadsafe if the supplied list and
- * function are.
+ * returned list. The returned list always implements {@link Serializable},
+ * but serialization will succeed only when {@code fromList} and
+ * {@code function} are serializable. The returned list is threadsafe if the
+ * supplied list and function are.
*
* <p>If only a {@code Collection} or {@code Iterable} input is available, use
* {@link Collections2#transform} or {@link Iterables#transform}.
- *
- * <p><b>Note:</b> serializing the returned list is implemented by serializing
- * {@code fromList}, its contents, and {@code function} -- <i>not</i> by
- * serializing the transformed values. This can lead to surprising behavior,
- * so serializing the returned list is <b>not recommended</b>. Instead,
- * copy the list using {@link ImmutableList#copyOf(Collection)} (for example),
- * then serialize the copy. Other methods similar to this do not implement
- * serialization at all for this reason.
*/
public static <F, T> List<T> transform(
List<F> fromList, Function<? super F, ? extends T> function) {
@@ -539,10 +374,51 @@ public final class Lists {
return fromList.size();
}
@Override public ListIterator<T> listIterator(final int index) {
- return new TransformedListIterator<F, T>(fromList.listIterator(index)) {
+ final ListIterator<F> delegate = fromList.listIterator(index);
+ return new ListIterator<T>() {
+ @Override
+ public void add(T e) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return delegate.hasNext();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return delegate.hasPrevious();
+ }
+
+ @Override
+ public T next() {
+ return function.apply(delegate.next());
+ }
+
+ @Override
+ public int nextIndex() {
+ return delegate.nextIndex();
+ }
+
+ @Override
+ public T previous() {
+ return function.apply(delegate.previous());
+ }
+
+ @Override
+ public int previousIndex() {
+ return delegate.previousIndex();
+ }
+
@Override
- T transform(F from) {
- return function.apply(from);
+ public void remove() {
+ delegate.remove();
+ }
+
+ @Override
+ public void set(T e) {
+ throw new UnsupportedOperationException("not supported");
}
};
}
@@ -670,6 +546,10 @@ public final class Lists {
this.string = string;
}
+ @Override public boolean contains(@Nullable Object object) {
+ return indexOf(object) >= 0;
+ }
+
@Override public int indexOf(@Nullable Object object) {
return (object instanceof Character)
? string.indexOf((Character) object) : -1;
@@ -680,9 +560,17 @@ public final class Lists {
? string.lastIndexOf((Character) object) : -1;
}
+ @Override public UnmodifiableListIterator<Character> listIterator(
+ int index) {
+ return new AbstractIndexedListIterator<Character>(size(), index) {
+ @Override protected Character get(int index) {
+ return string.charAt(index);
+ }
+ };
+ }
+
@Override public ImmutableList<Character> subList(
int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size()); // for GWT
return charactersOf(string.substring(fromIndex, toIndex));
}
@@ -691,7 +579,6 @@ public final class Lists {
}
@Override public Character get(int index) {
- checkElementIndex(index, size()); // for GWT
return string.charAt(index);
}
@@ -758,7 +645,6 @@ public final class Lists {
}
@Override public Character get(int index) {
- checkElementIndex(index, size()); // for GWT
return sequence.charAt(index);
}
@@ -795,7 +681,6 @@ public final class Lists {
}
@Override public List<Character> subList(int fromIndex, int toIndex) {
- checkPositionIndexes(fromIndex, toIndex, size()); // for GWT
return charactersOf(sequence.subSequence(fromIndex, toIndex));
}
@@ -1003,13 +888,10 @@ public final class Lists {
/**
* An implementation of {@link List#hashCode()}.
*/
- static int hashCodeImpl(List<?> list) {
+ static int hashCodeImpl(List<?> list){
int hashCode = 1;
for (Object o : list) {
hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
-
- hashCode = ~~hashCode;
- // needed to deal with GWT integer overflow
}
return hashCode;
}
@@ -1146,11 +1028,4 @@ public final class Lists {
super(backingList);
}
}
-
- /**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
- */
- static <T> List<T> cast(Iterable<T> iterable) {
- return (List<T>) iterable;
- }
}
diff --git a/guava/src/com/google/common/collect/MapConstraints.java b/guava/src/com/google/common/collect/MapConstraints.java
index 090625d..11351bb 100644
--- a/guava/src/com/google/common/collect/MapConstraints.java
+++ b/guava/src/com/google/common/collect/MapConstraints.java
@@ -21,7 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
@@ -396,7 +395,7 @@ public final class MapConstraints {
/** @see MapConstraints#constrainedMultimap */
private static class ConstrainedMultimap<K, V>
- extends ForwardingMultimap<K, V> implements Serializable {
+ extends ForwardingMultimap<K, V> {
final MapConstraint<? super K, ? super V> constraint;
final Multimap<K, V> delegate;
transient Collection<Entry<K, V>> entries;
diff --git a/guava/src/com/google/common/collect/MapMaker.java b/guava/src/com/google/common/collect/MapMaker.java
index a5a035e..330018e 100644
--- a/guava/src/com/google/common/collect/MapMaker.java
+++ b/guava/src/com/google/common/collect/MapMaker.java
@@ -18,12 +18,12 @@ import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.MapMakerInternalMap.Strength.SOFT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Ascii;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Throwables;
@@ -51,6 +51,8 @@ import javax.annotation.Nullable;
* <ul>
* <li>keys or values automatically wrapped in {@linkplain WeakReference weak} or {@linkplain
* SoftReference soft} references
+ * <li>least-recently-used eviction when a maximum size is exceeded
+ * <li>time-based expiration of entries, measured since last access or last write
* <li>notification of evicted (or otherwise removed) entries
* <li>on-demand computation of values for keys not already present
* </ul>
@@ -60,6 +62,8 @@ import javax.annotation.Nullable;
* ConcurrentMap<Key, Graph> graphs = new MapMaker()
* .concurrencyLevel(4)
* .weakKeys()
+ * .maximumSize(10000)
+ * .expireAfterWrite(10, TimeUnit.MINUTES)
* .makeComputingMap(
* new Function<Key, Graph>() {
* public Graph apply(Key key) {
@@ -75,9 +79,10 @@ import javax.annotation.Nullable;
* interface. It does not permit null keys or values.
*
* <p><b>Note:</b> by default, the returned map uses equality comparisons (the {@link Object#equals
- * equals} method) to determine equality for keys or values. However, if {@link #weakKeys} was
- * specified, the map uses identity ({@code ==}) comparisons instead for keys. Likewise, if {@link
- * #weakValues} or {@link #softValues} was specified, the map uses identity comparisons for values.
+ * equals} method) to determine equality for keys or values. However, if {@link #weakKeys} or {@link
+ * #softKeys} was specified, the map uses identity ({@code ==}) comparisons instead for keys.
+ * Likewise, if {@link #weakValues} or {@link #softValues} was specified, the map uses identity
+ * comparisons for values.
*
* <p>The view collections of the returned map have <i>weakly consistent iterators</i>. This means
* that they are safe for concurrent use, but if other threads modify the map after the iterator is
@@ -129,6 +134,7 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
RemovalCause nullRemovalCause;
Equivalence<Object> keyEquivalence;
+ Equivalence<Object> valueEquivalence;
Ticker ticker;
@@ -138,12 +144,16 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
*/
public MapMaker() {}
+ private boolean useNullMap() {
+ return (nullRemovalCause == null);
+ }
+
/**
* Sets a custom {@code Equivalence} strategy for comparing keys.
*
- * <p>By default, the map uses {@link Equivalence#identity} to determine key equality when {@link
- * #weakKeys} is specified, and {@link Equivalence#equals()} otherwise. The only place this is
- * used is in {@link Interners.WeakInterner}.
+ * <p>By default, the map uses {@link Equivalences#identity} to determine key equality when
+ * {@link #weakKeys} or {@link #softKeys} is specified, and {@link Equivalences#equals()}
+ * otherwise.
*/
@GwtIncompatible("To be supported")
@Override
@@ -159,6 +169,27 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
}
/**
+ * Sets a custom {@code Equivalence} strategy for comparing values.
+ *
+ * <p>By default, the map uses {@link Equivalences#identity} to determine value equality when
+ * {@link #weakValues} or {@link #softValues} is specified, and {@link Equivalences#equals()}
+ * otherwise.
+ */
+ @GwtIncompatible("To be supported")
+ @Override
+ MapMaker valueEquivalence(Equivalence<Object> equivalence) {
+ checkState(valueEquivalence == null,
+ "value equivalence was already set to %s", valueEquivalence);
+ this.valueEquivalence = checkNotNull(equivalence);
+ this.useCustomMap = true;
+ return this;
+ }
+
+ Equivalence<Object> getValueEquivalence() {
+ return firstNonNull(valueEquivalence, getValueStrength().defaultEquivalence());
+ }
+
+ /**
* Sets the minimum total size for the internal hash tables. For example, if the initial capacity
* is {@code 60}, and the concurrency level is {@code 8}, then eight segments are created, each
* having a hash table of size eight. Providing a large enough estimate at construction time
@@ -200,9 +231,7 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
* @throws IllegalStateException if a maximum size was already set
* @deprecated Caching functionality in {@code MapMaker} is being moved to
* {@link com.google.common.cache.CacheBuilder}, with {@link #maximumSize} being
- * replaced by {@link com.google.common.cache.CacheBuilder#maximumSize}. Note that {@code
- * CacheBuilder} is simply an enhanced API for an implementation which was branched from
- * {@code MapMaker}.
+ * replaced by {@link com.google.common.cache.CacheBuilder#maximumSize}.
*/
@Deprecated
@Override
@@ -252,6 +281,16 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
}
/**
+ * Specifies that each key (not value) stored in the map should be strongly referenced.
+ *
+ * @throws IllegalStateException if the key strength was already set
+ */
+ @Override
+ MapMaker strongKeys() {
+ return setKeyStrength(Strength.STRONG);
+ }
+
+ /**
* Specifies that each key (not value) stored in the map should be wrapped in a {@link
* WeakReference} (by default, strong references are used).
*
@@ -268,10 +307,36 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
return setKeyStrength(Strength.WEAK);
}
+ /**
+ * <b>This method is broken.</b> Maps with soft keys offer no functional advantage over maps with
+ * weak keys, and they waste memory by keeping unreachable elements in the map. If your goal is to
+ * create a memory-sensitive map, then consider using soft values instead.
+ *
+ * <p>Specifies that each key (not value) stored in the map should be wrapped in a
+ * {@link SoftReference} (by default, strong references are used). Softly-referenced objects will
+ * be garbage-collected in a <i>globally</i> least-recently-used manner, in response to memory
+ * demand.
+ *
+ * <p><b>Warning:</b> when this method is used, the resulting map will use identity ({@code ==})
+ * comparison to determine equality of keys, which is a technical violation of the {@link Map}
+ * specification, and may not be what you expect.
+ *
+ * @throws IllegalStateException if the key strength was already set
+ * @see SoftReference
+ * @deprecated use {@link #softValues} to create a memory-sensitive map, or {@link #weakKeys} to
+ * create a map that doesn't hold strong references to the keys.
+ * <b>This method is scheduled for deletion in January 2013.</b>
+ */
+ @Deprecated
+ @GwtIncompatible("java.lang.ref.SoftReference")
+ @Override
+ public MapMaker softKeys() {
+ return setKeyStrength(Strength.SOFT);
+ }
+
MapMaker setKeyStrength(Strength strength) {
checkState(keyStrength == null, "Key strength was already set to %s", keyStrength);
keyStrength = checkNotNull(strength);
- checkArgument(keyStrength != SOFT, "Soft keys are not supported");
if (strength != Strength.STRONG) {
// STRONG could be used during deserialization.
useCustomMap = true;
@@ -284,6 +349,16 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
}
/**
+ * Specifies that each value (not key) stored in the map should be strongly referenced.
+ *
+ * @throws IllegalStateException if the value strength was already set
+ */
+ @Override
+ MapMaker strongValues() {
+ return setValueStrength(Strength.STRONG);
+ }
+
+ /**
* Specifies that each value (not key) stored in the map should be wrapped in a
* {@link WeakReference} (by default, strong references are used).
*
@@ -347,6 +422,22 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
}
/**
+ * Old name of {@link #expireAfterWrite}.
+ *
+ * @deprecated Caching functionality in {@code MapMaker} is being moved to
+ * {@link com.google.common.cache.CacheBuilder}. Functionality equivalent to
+ * {@link MapMaker#expiration} is provided by
+ * {@link com.google.common.cache.CacheBuilder#expireAfterWrite}.
+ * <b>This method is scheduled for deletion in July 2012.</b>
+ */
+ @Deprecated
+ @Override
+ public
+ MapMaker expiration(long duration, TimeUnit unit) {
+ return expireAfterWrite(duration, unit);
+ }
+
+ /**
* Specifies that each entry should be automatically removed from the map once a fixed duration
* has elapsed after the entry's creation, or the most recent replacement of its value.
*
@@ -367,9 +458,7 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
* @throws IllegalStateException if the time to live or time to idle was already set
* @deprecated Caching functionality in {@code MapMaker} is being moved to
* {@link com.google.common.cache.CacheBuilder}, with {@link #expireAfterWrite} being
- * replaced by {@link com.google.common.cache.CacheBuilder#expireAfterWrite}. Note that {@code
- * CacheBuilder} is simply an enhanced API for an implementation which was branched from
- * {@code MapMaker}.
+ * replaced by {@link com.google.common.cache.CacheBuilder#expireAfterWrite}.
*/
@Deprecated
@Override
@@ -417,9 +506,7 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
* @throws IllegalStateException if the time to idle or time to live was already set
* @deprecated Caching functionality in {@code MapMaker} is being moved to
* {@link com.google.common.cache.CacheBuilder}, with {@link #expireAfterAccess} being
- * replaced by {@link com.google.common.cache.CacheBuilder#expireAfterAccess}. Note that
- * {@code CacheBuilder} is simply an enhanced API for an implementation which was branched
- * from {@code MapMaker}.
+ * replaced by {@link com.google.common.cache.CacheBuilder#expireAfterAccess}.
*/
@Deprecated
@GwtIncompatible("To be supported")
@@ -469,9 +556,7 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
* @throws IllegalStateException if a removal listener was already set
* @deprecated Caching functionality in {@code MapMaker} is being moved to
* {@link com.google.common.cache.CacheBuilder}, with {@link #removalListener} being
- * replaced by {@link com.google.common.cache.CacheBuilder#removalListener}. Note that {@code
- * CacheBuilder} is simply an enhanced API for an implementation which was branched from
- * {@code MapMaker}.
+ * replaced by {@link com.google.common.cache.CacheBuilder#removalListener}.
*/
@Deprecated
@GwtIncompatible("To be supported")
@@ -571,16 +656,17 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
* @return a serializable concurrent map having the requested features
* @deprecated Caching functionality in {@code MapMaker} is being moved to
* {@link com.google.common.cache.CacheBuilder}, with {@link #makeComputingMap} being replaced
- * by {@link com.google.common.cache.CacheBuilder#build}. See the
- * <a href="http://code.google.com/p/guava-libraries/wiki/MapMakerMigration">MapMaker
- * Migration Guide</a> for more details.
+ * by {@link com.google.common.cache.CacheBuilder#build}. Note that uses of
+ * {@link #makeComputingMap} with {@code AtomicLong} values can often be migrated to
+ * {@link AtomicLongMap}.
* <b>This method is scheduled for deletion in February 2013.</b>
+ *
*/
@Deprecated
@Override
public <K, V> ConcurrentMap<K, V> makeComputingMap(
Function<? super K, ? extends V> computingFunction) {
- return (nullRemovalCause == null)
+ return useNullMap()
? new MapMaker.ComputingMapAdapter<K, V>(this, computingFunction)
: new NullComputingConcurrentMap<K, V>(this, computingFunction);
}
@@ -616,6 +702,9 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
if (keyEquivalence != null) {
s.addValue("keyEquivalence");
}
+ if (valueEquivalence != null) {
+ s.addValue("valueEquivalence");
+ }
if (removalListener != null) {
s.addValue("removalListener");
}
@@ -706,8 +795,9 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
},
/**
- * The entry was removed automatically because its key or value was garbage-collected. This can
- * occur when using {@link #softValues}, {@link #weakKeys}, or {@link #weakValues}.
+ * The entry was removed automatically because its key or value was garbage-collected. This
+ * can occur when using {@link #softKeys}, {@link #softValues}, {@link #weakKeys}, or {@link
+ * #weakValues}.
*/
COLLECTED {
@Override
@@ -862,10 +952,6 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
* Overrides get() to compute on demand. Also throws an exception when {@code null} is returned
* from a computation.
*/
- /*
- * This might make more sense in ComputingConcurrentHashMap, but it causes a javac crash in some
- * cases there: http://code.google.com/p/guava-libraries/issues/detail?id=950
- */
static final class ComputingMapAdapter<K, V>
extends ComputingConcurrentHashMap<K, V> implements Serializable {
private static final long serialVersionUID = 0;
@@ -893,4 +979,5 @@ public final class MapMaker extends GenericMapMaker<Object, Object> {
return value;
}
}
+
}
diff --git a/guava/src/com/google/common/collect/MapMakerInternalMap.java b/guava/src/com/google/common/collect/MapMakerInternalMap.java
index b2d05bd..a5a6be8 100644
--- a/guava/src/com/google/common/collect/MapMakerInternalMap.java
+++ b/guava/src/com/google/common/collect/MapMakerInternalMap.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Ticker;
import com.google.common.collect.GenericMapMaker.NullListener;
import com.google.common.collect.MapMaker.RemovalCause;
@@ -199,7 +200,7 @@ class MapMakerInternalMap<K, V>
valueStrength = builder.getValueStrength();
keyEquivalence = builder.getKeyEquivalence();
- valueEquivalence = valueStrength.defaultEquivalence();
+ valueEquivalence = builder.getValueEquivalence();
maximumSize = builder.maximumSize;
expireAfterAccessNanos = builder.getExpireAfterAccessNanos();
@@ -301,7 +302,7 @@ class MapMakerInternalMap<K, V>
@Override
Equivalence<Object> defaultEquivalence() {
- return Equivalence.equals();
+ return Equivalences.equals();
}
},
@@ -314,7 +315,7 @@ class MapMakerInternalMap<K, V>
@Override
Equivalence<Object> defaultEquivalence() {
- return Equivalence.identity();
+ return Equivalences.identity();
}
},
@@ -327,7 +328,7 @@ class MapMakerInternalMap<K, V>
@Override
Equivalence<Object> defaultEquivalence() {
- return Equivalence.identity();
+ return Equivalences.identity();
}
};
@@ -403,6 +404,60 @@ class MapMakerInternalMap<K, V>
}
},
+ SOFT {
+ @Override
+ <K, V> ReferenceEntry<K, V> newEntry(
+ Segment<K, V> segment, K key, int hash, @Nullable ReferenceEntry<K, V> next) {
+ return new SoftEntry<K, V>(segment.keyReferenceQueue, key, hash, next);
+ }
+ },
+ SOFT_EXPIRABLE {
+ @Override
+ <K, V> ReferenceEntry<K, V> newEntry(
+ Segment<K, V> segment, K key, int hash, @Nullable ReferenceEntry<K, V> next) {
+ return new SoftExpirableEntry<K, V>(segment.keyReferenceQueue, key, hash, next);
+ }
+
+ @Override
+ <K, V> ReferenceEntry<K, V> copyEntry(
+ Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) {
+ ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext);
+ copyExpirableEntry(original, newEntry);
+ return newEntry;
+ }
+ },
+ SOFT_EVICTABLE {
+ @Override
+ <K, V> ReferenceEntry<K, V> newEntry(
+ Segment<K, V> segment, K key, int hash, @Nullable ReferenceEntry<K, V> next) {
+ return new SoftEvictableEntry<K, V>(segment.keyReferenceQueue, key, hash, next);
+ }
+
+ @Override
+ <K, V> ReferenceEntry<K, V> copyEntry(
+ Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) {
+ ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext);
+ copyEvictableEntry(original, newEntry);
+ return newEntry;
+ }
+ },
+ SOFT_EXPIRABLE_EVICTABLE {
+ @Override
+ <K, V> ReferenceEntry<K, V> newEntry(
+ Segment<K, V> segment, K key, int hash, @Nullable ReferenceEntry<K, V> next) {
+ return new SoftExpirableEvictableEntry<K, V>(segment.keyReferenceQueue, key, hash, next);
+ }
+
+ @Override
+ <K, V> ReferenceEntry<K, V> copyEntry(
+ Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) {
+ ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext);
+ copyExpirableEntry(original, newEntry);
+ copyEvictableEntry(original, newEntry);
+ return newEntry;
+ }
+ },
+
WEAK {
@Override
<K, V> ReferenceEntry<K, V> newEntry(
@@ -469,7 +524,7 @@ class MapMakerInternalMap<K, V>
*/
static final EntryFactory[][] factories = {
{ STRONG, STRONG_EXPIRABLE, STRONG_EVICTABLE, STRONG_EXPIRABLE_EVICTABLE },
- {}, // no support for SOFT keys
+ { SOFT, SOFT_EXPIRABLE, SOFT_EVICTABLE, SOFT_EXPIRABLE_EVICTABLE },
{ WEAK, WEAK_EXPIRABLE, WEAK_EVICTABLE, WEAK_EXPIRABLE_EVICTABLE }
};
@@ -550,11 +605,8 @@ class MapMakerInternalMap<K, V>
/**
* Creates a copy of this reference for the given entry.
- *
- * <p>{@code value} may be null only for a loading reference.
*/
- ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, @Nullable V value, ReferenceEntry<K, V> entry);
+ ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry);
/**
* Clears this reference object.
@@ -587,8 +639,8 @@ class MapMakerInternalMap<K, V>
}
@Override
- public ValueReference<Object, Object> copyFor(ReferenceQueue<Object> queue,
- @Nullable Object value, ReferenceEntry<Object, Object> entry) {
+ public ValueReference<Object, Object> copyFor(
+ ReferenceQueue<Object> queue, ReferenceEntry<Object, Object> entry) {
return this;
}
@@ -783,7 +835,7 @@ class MapMakerInternalMap<K, V>
public void setPreviousEvictable(ReferenceEntry<Object, Object> previous) {}
}
- abstract static class AbstractReferenceEntry<K, V> implements ReferenceEntry<K, V> {
+ static abstract class AbstractReferenceEntry<K, V> implements ReferenceEntry<K, V> {
@Override
public ValueReference<K, V> getValueReference() {
throw new UnsupportedOperationException();
@@ -1704,8 +1756,8 @@ class MapMakerInternalMap<K, V>
@Override
public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return new WeakValueReference<K, V>(queue, value, entry);
+ ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new WeakValueReference<K, V>(queue, get(), entry);
}
@Override
@@ -1742,9 +1794,8 @@ class MapMakerInternalMap<K, V>
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
- return new SoftValueReference<K, V>(queue, value, entry);
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ return new SoftValueReference<K, V>(queue, get(), entry);
}
@Override
@@ -1779,8 +1830,7 @@ class MapMakerInternalMap<K, V>
}
@Override
- public ValueReference<K, V> copyFor(
- ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
return this;
}
@@ -2129,26 +2179,11 @@ class MapMakerInternalMap<K, V>
return map.entryFactory.newEntry(this, key, hash, next);
}
- /**
- * Copies {@code original} into a new entry chained to {@code newNext}. Returns the new entry,
- * or {@code null} if {@code original} was already garbage collected.
- */
@GuardedBy("Segment.this")
ReferenceEntry<K, V> copyEntry(ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) {
- if (original.getKey() == null) {
- // key collected
- return null;
- }
-
ValueReference<K, V> valueReference = original.getValueReference();
- V value = valueReference.get();
- if ((value == null) && !valueReference.isComputingReference()) {
- // value collected
- return null;
- }
-
ReferenceEntry<K, V> newEntry = map.entryFactory.copyEntry(this, original, newNext);
- newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, value, newEntry));
+ newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, newEntry));
return newEntry;
}
@@ -2617,14 +2652,14 @@ class MapMakerInternalMap<K, V>
// Clone nodes leading up to the tail.
for (ReferenceEntry<K, V> e = head; e != tail; e = e.getNext()) {
- int newIndex = e.getHash() & newMask;
- ReferenceEntry<K, V> newNext = newTable.get(newIndex);
- ReferenceEntry<K, V> newFirst = copyEntry(e, newNext);
- if (newFirst != null) {
- newTable.set(newIndex, newFirst);
- } else {
+ if (isCollected(e)) {
removeCollectedEntry(e);
newCount--;
+ } else {
+ int newIndex = e.getHash() & newMask;
+ ReferenceEntry<K, V> newNext = newTable.get(newIndex);
+ ReferenceEntry<K, V> newFirst = copyEntry(e, newNext);
+ newTable.set(newIndex, newFirst);
}
}
}
@@ -2867,12 +2902,11 @@ class MapMakerInternalMap<K, V>
int newCount = count;
ReferenceEntry<K, V> newFirst = entry.getNext();
for (ReferenceEntry<K, V> e = first; e != entry; e = e.getNext()) {
- ReferenceEntry<K, V> next = copyEntry(e, newFirst);
- if (next != null) {
- newFirst = next;
- } else {
+ if (isCollected(e)) {
removeCollectedEntry(e);
newCount--;
+ } else {
+ newFirst = copyEntry(e, newFirst);
}
}
this.count = newCount;
@@ -3008,6 +3042,17 @@ class MapMakerInternalMap<K, V>
}
/**
+ * Returns {@code true} if the entry has been partially collected, meaning that either the key
+ * is null, or the value is null and it is not computing.
+ */
+ boolean isCollected(ReferenceEntry<K, V> entry) {
+ if (entry.getKey() == null) {
+ return true;
+ }
+ return isCollected(entry.getValueReference());
+ }
+
+ /**
* Returns {@code true} if the value has been partially collected, meaning that the value is
* null and it is not computing.
*/
@@ -3215,7 +3260,7 @@ class MapMakerInternalMap<K, V>
@Override
public Iterator<ReferenceEntry<K, V>> iterator() {
- return new AbstractSequentialIterator<ReferenceEntry<K, V>>(peek()) {
+ return new AbstractLinkedIterator<ReferenceEntry<K, V>>(peek()) {
@Override
protected ReferenceEntry<K, V> computeNext(ReferenceEntry<K, V> previous) {
ReferenceEntry<K, V> next = previous.getNextEvictable();
@@ -3351,7 +3396,7 @@ class MapMakerInternalMap<K, V>
@Override
public Iterator<ReferenceEntry<K, V>> iterator() {
- return new AbstractSequentialIterator<ReferenceEntry<K, V>>(peek()) {
+ return new AbstractLinkedIterator<ReferenceEntry<K, V>>(peek()) {
@Override
protected ReferenceEntry<K, V> computeNext(ReferenceEntry<K, V> previous) {
ReferenceEntry<K, V> next = previous.getNextExpirable();
@@ -3446,6 +3491,17 @@ class MapMakerInternalMap<K, V>
return segmentFor(hash).getEntry(key, hash);
}
+ /**
+ * Returns the live internal entry for the specified key. Does not impact recency ordering.
+ */
+ ReferenceEntry<K, V> getLiveEntry(@Nullable Object key) {
+ if (key == null) {
+ return null;
+ }
+ int hash = hash(key);
+ return segmentFor(hash).getLiveEntry(key, hash);
+ }
+
@Override
public boolean containsKey(@Nullable Object key) {
if (key == null) {
@@ -3466,7 +3522,7 @@ class MapMakerInternalMap<K, V>
// such that none of the subsequent iterations observed it, despite the fact that at every point
// in time it was present somewhere int the map. This becomes increasingly unlikely as
// CONTAINS_VALUE_RETRIES increases, though without locking it is theoretically possible.
- final Segment<K, V>[] segments = this.segments;
+ final Segment<K,V>[] segments = this.segments;
long last = -1L;
for (int i = 0; i < CONTAINS_VALUE_RETRIES; i++) {
long sum = 0L;
@@ -3476,7 +3532,7 @@ class MapMakerInternalMap<K, V>
int c = segment.count; // read-volatile
AtomicReferenceArray<ReferenceEntry<K, V>> table = segment.table;
- for (int j = 0; j < table.length(); j++) {
+ for (int j = 0 ; j < table.length(); j++) {
for (ReferenceEntry<K, V> e = table.get(j); e != null; e = e.getNext()) {
V v = segment.getLiveValue(e);
if (v != null && valueEquivalence.equivalent(value, v)) {
@@ -3561,7 +3617,7 @@ class MapMakerInternalMap<K, V>
}
}
- transient Set<K> keySet;
+ Set<K> keySet;
@Override
public Set<K> keySet() {
@@ -3569,7 +3625,7 @@ class MapMakerInternalMap<K, V>
return (ks != null) ? ks : (keySet = new KeySet());
}
- transient Collection<V> values;
+ Collection<V> values;
@Override
public Collection<V> values() {
@@ -3577,7 +3633,7 @@ class MapMakerInternalMap<K, V>
return (vs != null) ? vs : (values = new Values());
}
- transient Set<Entry<K, V>> entrySet;
+ Set<Entry<K, V>> entrySet;
@Override
public Set<Entry<K, V>> entrySet() {
@@ -3587,7 +3643,7 @@ class MapMakerInternalMap<K, V>
// Iterator Support
- abstract class HashIterator<E> implements Iterator<E> {
+ abstract class HashIterator {
int nextSegmentIndex;
int nextTableIndex;
@@ -3603,8 +3659,6 @@ class MapMakerInternalMap<K, V>
advance();
}
- public abstract E next();
-
final void advance() {
nextExternal = null;
@@ -3696,7 +3750,7 @@ class MapMakerInternalMap<K, V>
}
}
- final class KeyIterator extends HashIterator<K> {
+ final class KeyIterator extends HashIterator implements Iterator<K> {
@Override
public K next() {
@@ -3704,7 +3758,7 @@ class MapMakerInternalMap<K, V>
}
}
- final class ValueIterator extends HashIterator<V> {
+ final class ValueIterator extends HashIterator implements Iterator<V> {
@Override
public V next() {
@@ -3759,7 +3813,7 @@ class MapMakerInternalMap<K, V>
}
}
- final class EntryIterator extends HashIterator<Entry<K, V>> {
+ final class EntryIterator extends HashIterator implements Iterator<Entry<K, V>> {
@Override
public Entry<K, V> next() {
@@ -3945,6 +3999,7 @@ class MapMakerInternalMap<K, V>
.setKeyStrength(keyStrength)
.setValueStrength(valueStrength)
.keyEquivalence(keyEquivalence)
+ .valueEquivalence(valueEquivalence)
.concurrencyLevel(concurrencyLevel);
mapMaker.removalListener(removalListener);
if (expireAfterWriteNanos > 0) {
diff --git a/guava/src/com/google/common/collect/Maps.java b/guava/src/com/google/common/collect/Maps.java
index 9569a52..4215869 100644
--- a/guava/src/com/google/common/collect/Maps.java
+++ b/guava/src/com/google/common/collect/Maps.java
@@ -23,6 +23,7 @@ import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalences;
import com.google.common.base.Function;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.base.Objects;
@@ -35,6 +36,7 @@ import com.google.common.primitives.Ints;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractMap;
+import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -46,25 +48,17 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
-import java.util.SortedSet;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nullable;
/**
- * Static utility methods pertaining to {@link Map} instances (including instances of
- * {@link SortedMap}, {@link BiMap}, etc.). Also see this class's counterparts
- * {@link Lists}, {@link Sets} and {@link Queues}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Maps">
- * {@code Maps}</a>.
+ * Static utility methods pertaining to {@link Map} instances. Also see this
+ * class's counterparts {@link Lists} and {@link Sets}.
*
* @author Kevin Bourrillion
* @author Mike Bostock
@@ -76,60 +70,6 @@ import javax.annotation.Nullable;
public final class Maps {
private Maps() {}
- private enum EntryFunction implements Function<Entry, Object> {
- KEY {
- @Override
- @Nullable
- public Object apply(Entry entry) {
- return entry.getKey();
- }
- },
- VALUE {
- @Override
- @Nullable
- public Object apply(Entry entry) {
- return entry.getValue();
- }
- };
- }
-
- @SuppressWarnings("unchecked")
- static <K> Function<Entry<K, ?>, K> keyFunction() {
- return (Function) EntryFunction.KEY;
- }
-
- static <V> Function<Entry<?, V>, V> valueFunction() {
- return (Function) EntryFunction.VALUE;
- }
-
- /**
- * Returns an immutable map instance containing the given entries.
- * Internally, the returned set will be backed by an {@link EnumMap}.
- *
- * <p>The iteration order of the returned map follows the enum's iteration
- * order, not the order in which the elements appear in the given map.
- *
- * @param map the map to make an immutable copy of
- * @return an immutable map containing those entries
- * @since 14.0
- */
- @GwtCompatible(serializable = true)
- @Beta
- public static <K extends Enum<K>, V> ImmutableMap<K, V> immutableEnumMap(
- Map<K, V> map) {
- if (map instanceof ImmutableEnumMap) {
- return (ImmutableEnumMap<K, V>) map;
- } else if (map.isEmpty()) {
- return ImmutableMap.of();
- } else {
- for (Map.Entry<K, V> entry : map.entrySet()) {
- checkNotNull(entry.getKey());
- checkNotNull(entry.getValue());
- }
- return ImmutableEnumMap.asImmutable(new EnumMap<K, V>(map));
- }
- }
-
/**
* Creates a <i>mutable</i>, empty {@code HashMap} instance.
*
@@ -285,9 +225,9 @@ public final class Maps {
* @param comparator the comparator to sort the keys with
* @return a new, empty {@code TreeMap}
*/
- public static <C, K extends C, V> TreeMap<K, V> newTreeMap(
- @Nullable Comparator<C> comparator) {
- // Ideally, the extra type parameter "C" shouldn't be necessary. It is a
+ public static <K, V> TreeMap<K, V> newTreeMap(
+ @Nullable Comparator<? super K> comparator) {
+ // Ideally, the "? super" shouldn't be necessary. It is a
// work-around of a compiler type inference quirk that prevents the
// following code from being compiled:
// Comparator<Class<?>> comparator = null;
@@ -329,6 +269,38 @@ public final class Maps {
}
/**
+ * Returns a synchronized (thread-safe) bimap backed by the specified bimap.
+ * In order to guarantee serial access, it is critical that <b>all</b> access
+ * to the backing bimap is accomplished through the returned bimap.
+ *
+ * <p>It is imperative that the user manually synchronize on the returned map
+ * when accessing any of its collection views: <pre> {@code
+ *
+ * BiMap<Long, String> map = Maps.synchronizedBiMap(
+ * HashBiMap.<Long, String>create());
+ * ...
+ * Set<Long> set = map.keySet(); // Needn't be in synchronized block
+ * ...
+ * synchronized (map) { // Synchronizing on map, not set!
+ * Iterator<Long> it = set.iterator(); // Must be in synchronized block
+ * while (it.hasNext()) {
+ * foo(it.next());
+ * }
+ * }}</pre>
+ *
+ * Failure to follow this advice may result in non-deterministic behavior.
+ *
+ * <p>The returned bimap will be serializable if the specified bimap is
+ * serializable.
+ *
+ * @param bimap the bimap to be wrapped in a synchronized view
+ * @return a sychronized view of the specified bimap
+ */
+ public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
+ return Synchronized.biMap(bimap, null);
+ }
+
+ /**
* Computes the difference between two maps. This difference is an immutable
* snapshot of the state of the maps at the time this method is called. It
* will never change, even if the maps change at a later time.
@@ -352,7 +324,7 @@ public final class Maps {
SortedMapDifference<K, V> result = difference(sortedLeft, right);
return result;
}
- return difference(left, right, Equivalence.equals());
+ return difference(left, right, Equivalences.equals());
}
/**
@@ -524,7 +496,7 @@ public final class Maps {
}
@Override public boolean equals(@Nullable Object object) {
- if (object instanceof MapDifference.ValueDifference) {
+ if (object instanceof MapDifference.ValueDifference<?>) {
MapDifference.ValueDifference<?> that =
(MapDifference.ValueDifference<?>) object;
return Objects.equal(this.left, that.leftValue())
@@ -561,6 +533,7 @@ public final class Maps {
* @return the difference between the two maps
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMapDifference<K, V> difference(
SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
checkNotNull(left);
@@ -645,484 +618,6 @@ public final class Maps {
}
return (Comparator<E>) Ordering.natural();
}
-
- /**
- * Returns a view of the set as a map, mapping keys from the set according to
- * the specified function.
- *
- * <p>Specifically, for each {@code k} in the backing set, the returned map
- * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
- * keySet}, {@code values}, and {@code entrySet} views of the returned map
- * iterate in the same order as the backing set.
- *
- * <p>Modifications to the backing set are read through to the returned map.
- * The returned map supports removal operations if the backing set does.
- * Removal operations write through to the backing set. The returned map
- * does not support put operations.
- *
- * <p><b>Warning</b>: If the function rejects {@code null}, caution is
- * required to make sure the set does not contain {@code null}, because the
- * view cannot stop {@code null} from being added to the set.
- *
- * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
- * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also
- * of type {@code K}. Using a key type for which this may not hold, such as
- * {@code ArrayList}, may risk a {@code ClassCastException} when calling
- * methods on the resulting map view.
- *
- * @since 14.0
- */
- @Beta
- public static <K, V> Map<K, V> asMap(
- Set<K> set, Function<? super K, V> function) {
- if (set instanceof SortedSet) {
- return asMap((SortedSet<K>) set, function);
- } else {
- return new AsMapView<K, V>(set, function);
- }
- }
-
- /**
- * Returns a view of the sorted set as a map, mapping keys from the set
- * according to the specified function.
- *
- * <p>Specifically, for each {@code k} in the backing set, the returned map
- * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
- * keySet}, {@code values}, and {@code entrySet} views of the returned map
- * iterate in the same order as the backing set.
- *
- * <p>Modifications to the backing set are read through to the returned map.
- * The returned map supports removal operations if the backing set does.
- * Removal operations write through to the backing set. The returned map does
- * not support put operations.
- *
- * <p><b>Warning</b>: If the function rejects {@code null}, caution is
- * required to make sure the set does not contain {@code null}, because the
- * view cannot stop {@code null} from being added to the set.
- *
- * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
- * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also of
- * type {@code K}. Using a key type for which this may not hold, such as
- * {@code ArrayList}, may risk a {@code ClassCastException} when calling
- * methods on the resulting map view.
- *
- * @since 14.0
- */
- @Beta
- public static <K, V> SortedMap<K, V> asMap(
- SortedSet<K> set, Function<? super K, V> function) {
- return Platform.mapsAsMapSortedSet(set, function);
- }
-
- static <K, V> SortedMap<K, V> asMapSortedIgnoreNavigable(SortedSet<K> set,
- Function<? super K, V> function) {
- return new SortedAsMapView<K, V>(set, function);
- }
-
- /**
- * Returns a view of the navigable set as a map, mapping keys from the set
- * according to the specified function.
- *
- * <p>Specifically, for each {@code k} in the backing set, the returned map
- * has an entry mapping {@code k} to {@code function.apply(k)}. The {@code
- * keySet}, {@code values}, and {@code entrySet} views of the returned map
- * iterate in the same order as the backing set.
- *
- * <p>Modifications to the backing set are read through to the returned map.
- * The returned map supports removal operations if the backing set does.
- * Removal operations write through to the backing set. The returned map
- * does not support put operations.
- *
- * <p><b>Warning</b>: If the function rejects {@code null}, caution is
- * required to make sure the set does not contain {@code null}, because the
- * view cannot stop {@code null} from being added to the set.
- *
- * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
- * key type {@code K}, {@code k.equals(k2)} implies that {@code k2} is also
- * of type {@code K}. Using a key type for which this may not hold, such as
- * {@code ArrayList}, may risk a {@code ClassCastException} when calling
- * methods on the resulting map view.
- *
- * @since 14.0
- */
- @Beta
- @GwtIncompatible("NavigableMap")
- public static <K, V> NavigableMap<K, V> asMap(
- NavigableSet<K> set, Function<? super K, V> function) {
- return new NavigableAsMapView<K, V>(set, function);
- }
-
- private static class AsMapView<K, V> extends ImprovedAbstractMap<K, V> {
-
- private final Set<K> set;
- final Function<? super K, V> function;
-
- Set<K> backingSet() {
- return set;
- }
-
- AsMapView(Set<K> set, Function<? super K, V> function) {
- this.set = checkNotNull(set);
- this.function = checkNotNull(function);
- }
-
- @Override
- public Set<K> keySet() {
- // probably not worth caching
- return removeOnlySet(backingSet());
- }
-
- @Override
- public Collection<V> values() {
- // probably not worth caching
- return Collections2.transform(set, function);
- }
-
- @Override
- public int size() {
- return backingSet().size();
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return backingSet().contains(key);
- }
-
- @Override
- public V get(@Nullable Object key) {
- if (backingSet().contains(key)) {
- @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
- K k = (K) key;
- return function.apply(k);
- } else {
- return null;
- }
- }
-
- @Override
- public V remove(@Nullable Object key) {
- if (backingSet().remove(key)) {
- @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
- K k = (K) key;
- return function.apply(k);
- } else {
- return null;
- }
- }
-
- @Override
- public void clear() {
- backingSet().clear();
- }
-
- @Override
- protected Set<Entry<K, V>> createEntrySet() {
- return new EntrySet<K, V>() {
- @Override
- Map<K, V> map() {
- return AsMapView.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return asSetEntryIterator(backingSet(), function);
- }
- };
- }
- }
-
- private static <K, V> Iterator<Entry<K, V>> asSetEntryIterator(
- Set<K> set, final Function<? super K, V> function) {
- return new TransformedIterator<K, Entry<K,V>>(set.iterator()) {
- @Override
- Entry<K, V> transform(K key) {
- return Maps.immutableEntry(key, function.apply(key));
- }
- };
- }
-
- private static class SortedAsMapView<K, V> extends AsMapView<K, V>
- implements SortedMap<K, V> {
-
- SortedAsMapView(SortedSet<K> set, Function<? super K, V> function) {
- super(set, function);
- }
-
- @Override
- SortedSet<K> backingSet() {
- return (SortedSet<K>) super.backingSet();
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return backingSet().comparator();
- }
-
- @Override
- public Set<K> keySet() {
- return removeOnlySortedSet(backingSet());
- }
-
- @Override
- public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return asMap(backingSet().subSet(fromKey, toKey), function);
- }
-
- @Override
- public SortedMap<K, V> headMap(K toKey) {
- return asMap(backingSet().headSet(toKey), function);
- }
-
- @Override
- public SortedMap<K, V> tailMap(K fromKey) {
- return asMap(backingSet().tailSet(fromKey), function);
- }
-
- @Override
- public K firstKey() {
- return backingSet().first();
- }
-
- @Override
- public K lastKey() {
- return backingSet().last();
- }
- }
-
- @GwtIncompatible("NavigableMap")
- private static final class NavigableAsMapView<K, V>
- extends AbstractNavigableMap<K, V> {
- /*
- * Using AbstractNavigableMap is simpler than extending SortedAsMapView and rewriting all the
- * NavigableMap methods.
- */
-
- private final NavigableSet<K> set;
- private final Function<? super K, V> function;
-
- NavigableAsMapView(NavigableSet<K> ks, Function<? super K, V> vFunction) {
- this.set = checkNotNull(ks);
- this.function = checkNotNull(vFunction);
- }
-
- @Override
- public NavigableMap<K, V> subMap(
- K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return asMap(set.subSet(fromKey, fromInclusive, toKey, toInclusive), function);
- }
-
- @Override
- public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- return asMap(set.headSet(toKey, inclusive), function);
- }
-
- @Override
- public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- return asMap(set.tailSet(fromKey, inclusive), function);
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return set.comparator();
- }
-
- @Override
- @Nullable
- public V get(@Nullable Object key) {
- if (set.contains(key)) {
- @SuppressWarnings("unchecked") // unsafe, but Javadoc warns about it
- K k = (K) key;
- return function.apply(k);
- } else {
- return null;
- }
- }
-
- @Override
- public void clear() {
- set.clear();
- }
-
- @Override
- Iterator<Entry<K, V>> entryIterator() {
- return asSetEntryIterator(set, function);
- }
-
- @Override
- Iterator<Entry<K, V>> descendingEntryIterator() {
- return descendingMap().entrySet().iterator();
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return removeOnlyNavigableSet(set);
- }
-
- @Override
- public int size() {
- return set.size();
- }
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- return asMap(set.descendingSet(), function);
- }
- }
-
- private static <E> Set<E> removeOnlySet(final Set<E> set) {
- return new ForwardingSet<E>() {
- @Override
- protected Set<E> delegate() {
- return set;
- }
-
- @Override
- public boolean add(E element) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean addAll(Collection<? extends E> es) {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- private static <E> SortedSet<E> removeOnlySortedSet(final SortedSet<E> set) {
- return new ForwardingSortedSet<E>() {
- @Override
- protected SortedSet<E> delegate() {
- return set;
- }
-
- @Override
- public boolean add(E element) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean addAll(Collection<? extends E> es) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SortedSet<E> headSet(E toElement) {
- return removeOnlySortedSet(super.headSet(toElement));
- }
-
- @Override
- public SortedSet<E> subSet(E fromElement, E toElement) {
- return removeOnlySortedSet(super.subSet(fromElement, toElement));
- }
-
- @Override
- public SortedSet<E> tailSet(E fromElement) {
- return removeOnlySortedSet(super.tailSet(fromElement));
- }
- };
- }
-
- @GwtIncompatible("NavigableSet")
- private static <E> NavigableSet<E> removeOnlyNavigableSet(final NavigableSet<E> set) {
- return new ForwardingNavigableSet<E>() {
- @Override
- protected NavigableSet<E> delegate() {
- return set;
- }
-
- @Override
- public boolean add(E element) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean addAll(Collection<? extends E> es) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SortedSet<E> headSet(E toElement) {
- return removeOnlySortedSet(super.headSet(toElement));
- }
-
- @Override
- public SortedSet<E> subSet(E fromElement, E toElement) {
- return removeOnlySortedSet(
- super.subSet(fromElement, toElement));
- }
-
- @Override
- public SortedSet<E> tailSet(E fromElement) {
- return removeOnlySortedSet(super.tailSet(fromElement));
- }
-
- @Override
- public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- return removeOnlyNavigableSet(super.headSet(toElement, inclusive));
- }
-
- @Override
- public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- return removeOnlyNavigableSet(super.tailSet(fromElement, inclusive));
- }
-
- @Override
- public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
- E toElement, boolean toInclusive) {
- return removeOnlyNavigableSet(super.subSet(
- fromElement, fromInclusive, toElement, toInclusive));
- }
-
- @Override
- public NavigableSet<E> descendingSet() {
- return removeOnlyNavigableSet(super.descendingSet());
- }
- };
- }
-
- /**
- * Returns an immutable map for which the given {@code keys} are mapped to
- * values by the given function in the order they appear in the original
- * iterable. If {@code keys} contains duplicate elements, the returned map
- * will contain each distinct key once in the order it first appears in
- * {@code keys}.
- *
- * @throws NullPointerException if any element of {@code keys} is
- * {@code null}, or if {@code valueFunction} produces {@code null}
- * for any key
- * @since 14.0
- */
- @Beta
- public static <K, V> ImmutableMap<K, V> toMap(Iterable<K> keys,
- Function<? super K, V> valueFunction) {
- return toMap(keys.iterator(), valueFunction);
- }
-
- /**
- * Returns an immutable map for which the given {@code keys} are mapped to
- * values by the given function in the order they appear in the original
- * iterator. If {@code keys} contains duplicate elements, the returned map
- * will contain each distinct key once in the order it first appears in
- * {@code keys}.
- *
- * @throws NullPointerException if any element of {@code keys} is
- * {@code null}, or if {@code valueFunction} produces {@code null}
- * for any key
- * @since 14.0
- */
- @Beta
- public static <K, V> ImmutableMap<K, V> toMap(Iterator<K> keys,
- Function<? super K, V> valueFunction) {
- checkNotNull(valueFunction);
- // Using LHM instead of a builder so as not to fail on duplicate keys
- Map<K, V> builder = newLinkedHashMap();
- while (keys.hasNext()) {
- K key = keys.next();
- builder.put(key, valueFunction.apply(key));
- }
- return ImmutableMap.copyOf(builder);
- }
-
/**
* Returns an immutable map for which the {@link Map#values} are the given
* elements in the given order, and each key is the product of invoking a
@@ -1143,6 +638,24 @@ public final class Maps {
}
/**
+ * <b>Deprecated.</b>
+ *
+ * @since 10.0
+ * @deprecated use {@link #uniqueIndex(Iterator, Function)} by casting {@code
+ * values} to {@code Iterator<V>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled
+ * for deletion in March 2012.</b>
+ */
+ @Beta
+ @Deprecated
+ public static <K, V, I extends Object & Iterable<V> & Iterator<V>>
+ ImmutableMap<K, V> uniqueIndex(
+ I values, Function<? super V, K> keyFunction) {
+ Iterable<V> valuesIterable = checkNotNull(values);
+ return uniqueIndex(valuesIterable, keyFunction);
+ }
+
+ /**
* Returns an immutable map for which the {@link Map#values} are the given
* elements in the given order, and each key is the product of invoking a
* supplied function on its corresponding value.
@@ -1330,38 +843,6 @@ public final class Maps {
}
/**
- * Returns a synchronized (thread-safe) bimap backed by the specified bimap.
- * In order to guarantee serial access, it is critical that <b>all</b> access
- * to the backing bimap is accomplished through the returned bimap.
- *
- * <p>It is imperative that the user manually synchronize on the returned map
- * when accessing any of its collection views: <pre> {@code
- *
- * BiMap<Long, String> map = Maps.synchronizedBiMap(
- * HashBiMap.<Long, String>create());
- * ...
- * Set<Long> set = map.keySet(); // Needn't be in synchronized block
- * ...
- * synchronized (map) { // Synchronizing on map, not set!
- * Iterator<Long> it = set.iterator(); // Must be in synchronized block
- * while (it.hasNext()) {
- * foo(it.next());
- * }
- * }}</pre>
- *
- * Failure to follow this advice may result in non-deterministic behavior.
- *
- * <p>The returned bimap will be serializable if the specified bimap is
- * serializable.
- *
- * @param bimap the bimap to be wrapped in a synchronized view
- * @return a sychronized view of the specified bimap
- */
- public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
- return Synchronized.biMap(bimap, null);
- }
-
- /**
* Returns an unmodifiable view of the specified bimap. This method allows
* modules to provide users with "read-only" access to internal bimaps. Query
* operations on the returned bimap "read through" to the specified bimap, and
@@ -1384,7 +865,7 @@ public final class Maps {
extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable {
final Map<K, V> unmodifiableMap;
final BiMap<? extends K, ? extends V> delegate;
- BiMap<V, K> inverse;
+ transient BiMap<V, K> inverse;
transient Set<V> values;
UnmodifiableBiMap(BiMap<? extends K, ? extends V> delegate,
@@ -1458,8 +939,16 @@ public final class Maps {
* a view, copy the returned map into a new map of your choosing.
*/
public static <K, V1, V2> Map<K, V2> transformValues(
- Map<K, V1> fromMap, Function<? super V1, V2> function) {
- return transformEntries(fromMap, asEntryTransformer(function));
+ Map<K, V1> fromMap, final Function<? super V1, V2> function) {
+ checkNotNull(function);
+ EntryTransformer<K, V1, V2> transformer =
+ new EntryTransformer<K, V1, V2>() {
+ @Override
+ public V2 transformEntry(K key, V1 value) {
+ return function.apply(value);
+ }
+ };
+ return transformEntries(fromMap, transformer);
}
/**
@@ -1501,67 +990,18 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V1, V2> SortedMap<K, V2> transformValues(
- SortedMap<K, V1> fromMap, Function<? super V1, V2> function) {
- return transformEntries(fromMap, asEntryTransformer(function));
- }
-
- /**
- * Returns a view of a navigable map where each value is transformed by a
- * function. All other properties of the map, such as iteration order, are
- * left intact. For example, the code: <pre> {@code
- *
- * NavigableMap<String, Integer> map = Maps.newTreeMap();
- * map.put("a", 4);
- * map.put("b", 9);
- * Function<Integer, Double> sqrt =
- * new Function<Integer, Double>() {
- * public Double apply(Integer in) {
- * return Math.sqrt((int) in);
- * }
- * };
- * NavigableMap<String, Double> transformed =
- * Maps.transformNavigableValues(map, sqrt);
- * System.out.println(transformed);}</pre>
- *
- * ... prints {@code {a=2.0, b=3.0}}.
- *
- * Changes in the underlying map are reflected in this view.
- * Conversely, this view supports removal operations, and these are reflected
- * in the underlying map.
- *
- * <p>It's acceptable for the underlying map to contain null keys, and even
- * null values provided that the function is capable of accepting null input.
- * The transformed map might contain null values, if the function sometimes
- * gives a null result.
- *
- * <p>The returned map is not thread-safe or serializable, even if the
- * underlying map is.
- *
- * <p>The function is applied lazily, invoked when needed. This is necessary
- * for the returned map to be a view, but it means that the function will be
- * applied many times for bulk operations like {@link Map#containsValue} and
- * {@code Map.toString()}. For this to perform well, {@code function} should
- * be fast. To avoid lazy evaluation when the returned map doesn't need to be
- * a view, copy the returned map into a new map of your choosing.
- *
- * @since 13.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V1, V2> NavigableMap<K, V2> transformValues(
- NavigableMap<K, V1> fromMap, Function<? super V1, V2> function) {
- return transformEntries(fromMap, asEntryTransformer(function));
- }
-
- private static <K, V1, V2> EntryTransformer<K, V1, V2>
- asEntryTransformer(final Function<? super V1, V2> function) {
+ SortedMap<K, V1> fromMap, final Function<? super V1, V2> function) {
checkNotNull(function);
- return new EntryTransformer<K, V1, V2>() {
- @Override
- public V2 transformEntry(K key, V1 value) {
- return function.apply(value);
- }
- };
+ EntryTransformer<K, V1, V2> transformer =
+ new EntryTransformer<K, V1, V2>() {
+ @Override
+ public V2 transformEntry(K key, V1 value) {
+ return function.apply(value);
+ }
+ };
+ return transformEntries(fromMap, transformer);
}
/**
@@ -1676,74 +1116,9 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V1, V2> SortedMap<K, V2> transformEntries(
- SortedMap<K, V1> fromMap,
- EntryTransformer<? super K, ? super V1, V2> transformer) {
- return Platform.mapsTransformEntriesSortedMap(fromMap, transformer);
- }
-
- /**
- * Returns a view of a navigable map whose values are derived from the
- * original navigable map's entries. In contrast to {@link
- * #transformValues}, this method's entry-transformation logic may
- * depend on the key as well as the value.
- *
- * <p>All other properties of the transformed map, such as iteration order,
- * are left intact. For example, the code: <pre> {@code
- *
- * NavigableMap<String, Boolean> options = Maps.newTreeMap();
- * options.put("verbose", false);
- * options.put("sort", true);
- * EntryTransformer<String, Boolean, String> flagPrefixer =
- * new EntryTransformer<String, Boolean, String>() {
- * public String transformEntry(String key, Boolean value) {
- * return value ? key : ("yes" + key);
- * }
- * };
- * NavigableMap<String, String> transformed =
- * LabsMaps.transformNavigableEntries(options, flagPrefixer);
- * System.out.println(transformed);}</pre>
- *
- * ... prints {@code {sort=yessort, verbose=verbose}}.
- *
- * <p>Changes in the underlying map are reflected in this view.
- * Conversely, this view supports removal operations, and these are reflected
- * in the underlying map.
- *
- * <p>It's acceptable for the underlying map to contain null keys and null
- * values provided that the transformer is capable of accepting null inputs.
- * The transformed map might contain null values if the transformer sometimes
- * gives a null result.
- *
- * <p>The returned map is not thread-safe or serializable, even if the
- * underlying map is.
- *
- * <p>The transformer is applied lazily, invoked when needed. This is
- * necessary for the returned map to be a view, but it means that the
- * transformer will be applied many times for bulk operations like {@link
- * Map#containsValue} and {@link Object#toString}. For this to perform well,
- * {@code transformer} should be fast. To avoid lazy evaluation when the
- * returned map doesn't need to be a view, copy the returned map into a new
- * map of your choosing.
- *
- * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
- * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
- * that {@code k2} is also of type {@code K}. Using an {@code
- * EntryTransformer} key type for which this may not hold, such as {@code
- * ArrayList}, may risk a {@code ClassCastException} when calling methods on
- * the transformed map.
- *
- * @since 13.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V1, V2> NavigableMap<K, V2> transformEntries(
- final NavigableMap<K, V1> fromMap,
- EntryTransformer<? super K, ? super V1, V2> transformer) {
- return new TransformedEntriesNavigableMap<K, V1, V2>(fromMap, transformer);
- }
-
- static <K, V1, V2> SortedMap<K, V2> transformEntriesIgnoreNavigable(
- SortedMap<K, V1> fromMap,
+ final SortedMap<K, V1> fromMap,
EntryTransformer<? super K, ? super V1, V2> transformer) {
return new TransformedEntriesSortedMap<K, V1, V2>(fromMap, transformer);
}
@@ -1835,23 +1210,17 @@ public final class Maps {
}
@Override public Iterator<Entry<K, V2>> iterator() {
- return new TransformedIterator<Entry<K, V1>, Entry<K, V2>>(
- fromMap.entrySet().iterator()) {
- @Override
- Entry<K, V2> transform(final Entry<K, V1> entry) {
- return new AbstractMapEntry<K, V2>() {
- @Override
- public K getKey() {
- return entry.getKey();
+ final Iterator<Entry<K, V1>> backingIterator =
+ fromMap.entrySet().iterator();
+ return Iterators.transform(backingIterator,
+ new Function<Entry<K, V1>, Entry<K, V2>>() {
+ @Override public Entry<K, V2> apply(Entry<K, V1> entry) {
+ return immutableEntry(
+ entry.getKey(),
+ transformer.transformEntry(entry.getKey(),
+ entry.getValue()));
}
-
- @Override
- public V2 getValue() {
- return transformer.transformEntry(entry.getKey(), entry.getValue());
- }
- };
- }
- };
+ });
}
};
}
@@ -1909,144 +1278,7 @@ public final class Maps {
@Override public SortedMap<K, V2> tailMap(K fromKey) {
return transformEntries(fromMap().tailMap(fromKey), transformer);
}
- }
-
- @GwtIncompatible("NavigableMap")
- private static class TransformedEntriesNavigableMap<K, V1, V2>
- extends TransformedEntriesSortedMap<K, V1, V2>
- implements NavigableMap<K, V2> {
-
- TransformedEntriesNavigableMap(NavigableMap<K, V1> fromMap,
- EntryTransformer<? super K, ? super V1, V2> transformer) {
- super(fromMap, transformer);
- }
-
- @Override public Entry<K, V2> ceilingEntry(K key) {
- return transformEntry(fromMap().ceilingEntry(key));
- }
-
- @Override public K ceilingKey(K key) {
- return fromMap().ceilingKey(key);
- }
-
- @Override public NavigableSet<K> descendingKeySet() {
- return fromMap().descendingKeySet();
- }
-
- @Override public NavigableMap<K, V2> descendingMap() {
- return transformEntries(fromMap().descendingMap(), transformer);
- }
-
- @Override public Entry<K, V2> firstEntry() {
- return transformEntry(fromMap().firstEntry());
- }
- @Override public Entry<K, V2> floorEntry(K key) {
- return transformEntry(fromMap().floorEntry(key));
- }
-
- @Override public K floorKey(K key) {
- return fromMap().floorKey(key);
- }
-
- @Override public NavigableMap<K, V2> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override public NavigableMap<K, V2> headMap(K toKey, boolean inclusive) {
- return transformEntries(
- fromMap().headMap(toKey, inclusive), transformer);
- }
-
- @Override public Entry<K, V2> higherEntry(K key) {
- return transformEntry(fromMap().higherEntry(key));
- }
-
- @Override public K higherKey(K key) {
- return fromMap().higherKey(key);
- }
-
- @Override public Entry<K, V2> lastEntry() {
- return transformEntry(fromMap().lastEntry());
- }
-
- @Override public Entry<K, V2> lowerEntry(K key) {
- return transformEntry(fromMap().lowerEntry(key));
- }
- @Override public K lowerKey(K key) {
- return fromMap().lowerKey(key);
- }
-
- @Override public NavigableSet<K> navigableKeySet() {
- return fromMap().navigableKeySet();
- }
-
- @Override public Entry<K, V2> pollFirstEntry() {
- return transformEntry(fromMap().pollFirstEntry());
- }
-
- @Override public Entry<K, V2> pollLastEntry() {
- return transformEntry(fromMap().pollLastEntry());
- }
-
- @Override public NavigableMap<K, V2> subMap(
- K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return transformEntries(
- fromMap().subMap(fromKey, fromInclusive, toKey, toInclusive),
- transformer);
- }
-
- @Override public NavigableMap<K, V2> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override public NavigableMap<K, V2> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override public NavigableMap<K, V2> tailMap(K fromKey, boolean inclusive) {
- return transformEntries(
- fromMap().tailMap(fromKey, inclusive), transformer);
- }
-
- private Entry<K, V2> transformEntry(Entry<K, V1> entry) {
- if (entry == null) {
- return null;
- }
- K key = entry.getKey();
- V2 v2 = transformer.transformEntry(key, entry.getValue());
- return Maps.immutableEntry(key, v2);
- }
-
- @Override protected NavigableMap<K, V1> fromMap() {
- return (NavigableMap<K, V1>) super.fromMap();
- }
- }
-
- private static final class KeyPredicate<K, V> implements Predicate<Entry<K, V>> {
- private final Predicate<? super K> keyPredicate;
-
- KeyPredicate(Predicate<? super K> keyPredicate) {
- this.keyPredicate = checkNotNull(keyPredicate);
- }
-
- @Override
- public boolean apply(Entry<K, V> input) {
- return keyPredicate.apply(input.getKey());
- }
- }
-
- private static final class ValuePredicate<K, V> implements Predicate<Entry<K, V>> {
- private final Predicate<? super V> valuePredicate;
-
- ValuePredicate(Predicate<? super V> valuePredicate) {
- this.valuePredicate = checkNotNull(valuePredicate);
- }
-
- @Override
- public boolean apply(Entry<K, V> input) {
- return valuePredicate.apply(input.getValue());
- }
}
/**
@@ -2081,11 +1313,15 @@ public final class Maps {
Map<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
if (unfiltered instanceof SortedMap) {
return filterKeys((SortedMap<K, V>) unfiltered, keyPredicate);
- } else if (unfiltered instanceof BiMap) {
- return filterKeys((BiMap<K, V>) unfiltered, keyPredicate);
}
checkNotNull(keyPredicate);
- Predicate<Entry<K, V>> entryPredicate = new KeyPredicate<K, V>(keyPredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return keyPredicate.apply(input.getKey());
+ }
+ };
return (unfiltered instanceof AbstractFilteredMap)
? filterFiltered((AbstractFilteredMap<K, V>) unfiltered, entryPredicate)
: new FilteredKeyMap<K, V>(
@@ -2122,80 +1358,19 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMap<K, V> filterKeys(
SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
- // TODO(user): Return a subclass of Maps.FilteredKeyMap for slightly better
- // performance.
- return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate));
- }
-
- /**
- * Returns a navigable map containing the mappings in {@code unfiltered} whose
- * keys satisfy a predicate. The returned map is a live view of {@code
- * unfiltered}; changes to one affect the other.
- *
- * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
- * values()} views have iterators that don't support {@code remove()}, but all
- * other methods are supported by the map and its views. When given a key that
- * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()}
- * methods throw an {@link IllegalArgumentException}.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called
- * on the filtered map or its views, only mappings whose keys satisfy the
- * filter will be removed from the underlying map.
- *
- * <p>The returned map isn't threadsafe or serializable, even if {@code
- * unfiltered} is.
- *
- * <p>Many of the filtered map's methods, such as {@code size()},
- * iterate across every key/value mapping in the underlying map and determine
- * which satisfy the filter. When a live view is <i>not</i> needed, it may be
- * faster to copy the filtered map and use the copy.
- *
- * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with
- * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
- * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
- * inconsistent with equals.
- *
- * @since 14.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V> NavigableMap<K, V> filterKeys(
- NavigableMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
- // TODO(user): Return a subclass of Maps.FilteredKeyMap for slightly better
+ // TODO: Return a subclass of Maps.FilteredKeyMap for slightly better
// performance.
- return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate));
- }
-
- /**
- * Returns a bimap containing the mappings in {@code unfiltered} whose keys satisfy a predicate.
- * The returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
- *
- * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
- * iterators that don't support {@code remove()}, but all other methods are supported by the
- * bimap and its views. When given a key that doesn't satisfy the predicate, the bimap's {@code
- * put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
- * IllegalArgumentException}.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
- * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
- * bimap.
- *
- * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
- *
- * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every key in
- * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
- * needed, it may be faster to copy the filtered bimap and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as
- * documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- public static <K, V> BiMap<K, V> filterKeys(
- BiMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
checkNotNull(keyPredicate);
- return filterEntries(unfiltered, new KeyPredicate<K, V>(keyPredicate));
+ Predicate<Entry<K, V>> entryPredicate = new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return keyPredicate.apply(input.getKey());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -2231,10 +1406,16 @@ public final class Maps {
Map<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
if (unfiltered instanceof SortedMap) {
return filterValues((SortedMap<K, V>) unfiltered, valuePredicate);
- } else if (unfiltered instanceof BiMap) {
- return filterValues((BiMap<K, V>) unfiltered, valuePredicate);
}
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
+ checkNotNull(valuePredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return valuePredicate.apply(input.getValue());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -2268,79 +1449,18 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMap<K, V> filterValues(
SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
- }
-
- /**
- * Returns a navigable map containing the mappings in {@code unfiltered} whose
- * values satisfy a predicate. The returned map is a live view of {@code
- * unfiltered}; changes to one affect the other.
- *
- * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
- * values()} views have iterators that don't support {@code remove()}, but all
- * other methods are supported by the map and its views. When given a value
- * that doesn't satisfy the predicate, the map's {@code put()}, {@code
- * putAll()}, and {@link Entry#setValue} methods throw an {@link
- * IllegalArgumentException}.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called
- * on the filtered map or its views, only mappings whose values satisfy the
- * filter will be removed from the underlying map.
- *
- * <p>The returned map isn't threadsafe or serializable, even if {@code
- * unfiltered} is.
- *
- * <p>Many of the filtered map's methods, such as {@code size()},
- * iterate across every key/value mapping in the underlying map and determine
- * which satisfy the filter. When a live view is <i>not</i> needed, it may be
- * faster to copy the filtered map and use the copy.
- *
- * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
- * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
- * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
- * inconsistent with equals.
- *
- * @since 14.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V> NavigableMap<K, V> filterValues(
- NavigableMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
- }
-
- /**
- * Returns a bimap containing the mappings in {@code unfiltered} whose values satisfy a
- * predicate. The returned bimap is a live view of {@code unfiltered}; changes to one affect the
- * other.
- *
- * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
- * iterators that don't support {@code remove()}, but all other methods are supported by the
- * bimap and its views. When given a value that doesn't satisfy the predicate, the bimap's
- * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an {@link
- * IllegalArgumentException}. Similarly, the map's entries have a {@link Entry#setValue} method
- * that throws an {@link IllegalArgumentException} when the provided value doesn't satisfy the
- * predicate.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
- * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
- * bimap.
- *
- * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
- *
- * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every value in
- * the underlying bimap and determine which satisfy the filter. When a live view is <i>not</i>
- * needed, it may be faster to copy the filtered bimap and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as
- * documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- public static <K, V> BiMap<K, V> filterValues(
- BiMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
- return filterEntries(unfiltered, new ValuePredicate<K, V>(valuePredicate));
+ checkNotNull(valuePredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return valuePredicate.apply(input.getValue());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -2376,8 +1496,6 @@ public final class Maps {
Map<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
if (unfiltered instanceof SortedMap) {
return filterEntries((SortedMap<K, V>) unfiltered, entryPredicate);
- } else if (unfiltered instanceof BiMap) {
- return filterEntries((BiMap<K, V>) unfiltered, entryPredicate);
}
checkNotNull(entryPredicate);
return (unfiltered instanceof AbstractFilteredMap)
@@ -2416,15 +1534,10 @@ public final class Maps {
*
* @since 11.0
*/
+ @Beta
public static <K, V> SortedMap<K, V> filterEntries(
SortedMap<K, V> unfiltered,
Predicate<? super Entry<K, V>> entryPredicate) {
- return Platform.mapsFilterSortedMap(unfiltered, entryPredicate);
- }
-
- static <K, V> SortedMap<K, V> filterSortedIgnoreNavigable(
- SortedMap<K, V> unfiltered,
- Predicate<? super Entry<K, V>> entryPredicate) {
checkNotNull(entryPredicate);
return (unfiltered instanceof FilteredEntrySortedMap)
? filterFiltered((FilteredEntrySortedMap<K, V>) unfiltered, entryPredicate)
@@ -2432,83 +1545,6 @@ public final class Maps {
}
/**
- * Returns a sorted map containing the mappings in {@code unfiltered} that
- * satisfy a predicate. The returned map is a live view of {@code unfiltered};
- * changes to one affect the other.
- *
- * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
- * values()} views have iterators that don't support {@code remove()}, but all
- * other methods are supported by the map and its views. When given a
- * key/value pair that doesn't satisfy the predicate, the map's {@code put()}
- * and {@code putAll()} methods throw an {@link IllegalArgumentException}.
- * Similarly, the map's entries have a {@link Entry#setValue} method that
- * throws an {@link IllegalArgumentException} when the existing key and the
- * provided value don't satisfy the predicate.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called
- * on the filtered map or its views, only mappings that satisfy the filter
- * will be removed from the underlying map.
- *
- * <p>The returned map isn't threadsafe or serializable, even if {@code
- * unfiltered} is.
- *
- * <p>Many of the filtered map's methods, such as {@code size()},
- * iterate across every key/value mapping in the underlying map and determine
- * which satisfy the filter. When a live view is <i>not</i> needed, it may be
- * faster to copy the filtered map and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
- * equals</i>, as documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V> NavigableMap<K, V> filterEntries(
- NavigableMap<K, V> unfiltered,
- Predicate<? super Entry<K, V>> entryPredicate) {
- checkNotNull(entryPredicate);
- return (unfiltered instanceof FilteredEntryNavigableMap)
- ? filterFiltered((FilteredEntryNavigableMap<K, V>) unfiltered, entryPredicate)
- : new FilteredEntryNavigableMap<K, V>(checkNotNull(unfiltered), entryPredicate);
- }
-
- /**
- * Returns a bimap containing the mappings in {@code unfiltered} that satisfy a predicate. The
- * returned bimap is a live view of {@code unfiltered}; changes to one affect the other.
- *
- * <p>The resulting bimap's {@code keySet()}, {@code entrySet()}, and {@code values()} views have
- * iterators that don't support {@code remove()}, but all other methods are supported by the bimap
- * and its views. When given a key/value pair that doesn't satisfy the predicate, the bimap's
- * {@code put()}, {@code forcePut()} and {@code putAll()} methods throw an
- * {@link IllegalArgumentException}. Similarly, the map's entries have an {@link Entry#setValue}
- * method that throws an {@link IllegalArgumentException} when the existing key and the provided
- * value don't satisfy the predicate.
- *
- * <p>When methods such as {@code removeAll()} and {@code clear()} are called on the filtered
- * bimap or its views, only mappings that satisfy the filter will be removed from the underlying
- * bimap.
- *
- * <p>The returned bimap isn't threadsafe or serializable, even if {@code unfiltered} is.
- *
- * <p>Many of the filtered bimap's methods, such as {@code size()}, iterate across every
- * key/value mapping in the underlying bimap and determine which satisfy the filter. When a live
- * view is <i>not</i> needed, it may be faster to copy the filtered bimap and use the copy.
- *
- * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with equals </i>, as
- * documented at {@link Predicate#apply}.
- *
- * @since 14.0
- */
- public static <K, V> BiMap<K, V> filterEntries(
- BiMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
- checkNotNull(unfiltered);
- checkNotNull(entryPredicate);
- return (unfiltered instanceof FilteredEntryBiMap)
- ? filterFiltered((FilteredEntryBiMap<K, V>) unfiltered, entryPredicate)
- : new FilteredEntryBiMap<K, V>(unfiltered, entryPredicate);
- }
-
- /**
* Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
* filtering a filtered map.
*/
@@ -2653,7 +1689,6 @@ public final class Maps {
}
}
}
-
/**
* Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
* filtering a filtered sorted map.
@@ -2714,251 +1749,6 @@ public final class Maps {
}
}
- /**
- * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
- * filtering a filtered navigable map.
- */
- @GwtIncompatible("NavigableMap")
- private static <K, V> NavigableMap<K, V> filterFiltered(
- FilteredEntryNavigableMap<K, V> map,
- Predicate<? super Entry<K, V>> entryPredicate) {
- Predicate<Entry<K, V>> predicate
- = Predicates.and(map.predicate, entryPredicate);
- return new FilteredEntryNavigableMap<K, V>(map.sortedMap(), predicate);
- }
-
- @GwtIncompatible("NavigableMap")
- private static class FilteredEntryNavigableMap<K, V> extends FilteredEntrySortedMap<K, V>
- implements NavigableMap<K, V> {
-
- FilteredEntryNavigableMap(
- NavigableMap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
- super(unfiltered, entryPredicate);
- }
-
- @Override
- NavigableMap<K, V> sortedMap() {
- return (NavigableMap<K, V>) super.sortedMap();
- }
-
- @Override
- public Entry<K, V> lowerEntry(K key) {
- return headMap(key, false).lastEntry();
- }
-
- @Override
- public K lowerKey(K key) {
- return keyOrNull(lowerEntry(key));
- }
-
- @Override
- public Entry<K, V> floorEntry(K key) {
- return headMap(key, true).lastEntry();
- }
-
- @Override
- public K floorKey(K key) {
- return keyOrNull(floorEntry(key));
- }
-
- @Override
- public Entry<K, V> ceilingEntry(K key) {
- return tailMap(key, true).firstEntry();
- }
-
- @Override
- public K ceilingKey(K key) {
- return keyOrNull(ceilingEntry(key));
- }
-
- @Override
- public Entry<K, V> higherEntry(K key) {
- return tailMap(key, false).firstEntry();
- }
-
- @Override
- public K higherKey(K key) {
- return keyOrNull(higherEntry(key));
- }
-
- @Override
- public Entry<K, V> firstEntry() {
- return Iterables.getFirst(entrySet(), null);
- }
-
- @Override
- public Entry<K, V> lastEntry() {
- return Iterables.getFirst(descendingMap().entrySet(), null);
- }
-
- @Override
- public Entry<K, V> pollFirstEntry() {
- return pollFirstSatisfyingEntry(sortedMap().entrySet().iterator());
- }
-
- @Override
- public Entry<K, V> pollLastEntry() {
- return pollFirstSatisfyingEntry(sortedMap().descendingMap().entrySet().iterator());
- }
-
- @Nullable
- Entry<K, V> pollFirstSatisfyingEntry(Iterator<Entry<K, V>> entryIterator) {
- while (entryIterator.hasNext()) {
- Entry<K, V> entry = entryIterator.next();
- if (predicate.apply(entry)) {
- entryIterator.remove();
- return entry;
- }
- }
- return null;
- }
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- return filterEntries(sortedMap().descendingMap(), predicate);
- }
-
- @Override
- public NavigableSet<K> keySet() {
- return (NavigableSet<K>) super.keySet();
- }
-
- @Override
- NavigableSet<K> createKeySet() {
- return new NavigableKeySet<K, V>(this) {
- @Override
- public boolean removeAll(Collection<?> c) {
- boolean changed = false;
- Iterator<Entry<K, V>> entryIterator = sortedMap().entrySet().iterator();
- while (entryIterator.hasNext()) {
- Entry<K, V> entry = entryIterator.next();
- if (c.contains(entry.getKey()) && predicate.apply(entry)) {
- entryIterator.remove();
- changed = true;
- }
- }
- return changed;
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- boolean changed = false;
- Iterator<Entry<K, V>> entryIterator = sortedMap().entrySet().iterator();
- while (entryIterator.hasNext()) {
- Entry<K, V> entry = entryIterator.next();
- if (!c.contains(entry.getKey()) && predicate.apply(entry)) {
- entryIterator.remove();
- changed = true;
- }
- }
- return changed;
- }
- };
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return keySet();
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return descendingMap().navigableKeySet();
- }
-
- @Override
- public NavigableMap<K, V> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override
- public NavigableMap<K, V> subMap(
- K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return filterEntries(
- sortedMap().subMap(fromKey, fromInclusive, toKey, toInclusive), predicate);
- }
-
- @Override
- public NavigableMap<K, V> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override
- public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- return filterEntries(sortedMap().headMap(toKey, inclusive), predicate);
- }
-
- @Override
- public NavigableMap<K, V> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override
- public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- return filterEntries(sortedMap().tailMap(fromKey, inclusive), predicate);
- }
- }
-
- /**
- * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
- * filtering a filtered map.
- */
- private static <K, V> BiMap<K, V> filterFiltered(
- FilteredEntryBiMap<K, V> map, Predicate<? super Entry<K, V>> entryPredicate) {
- Predicate<Entry<K, V>> predicate = Predicates.and(map.predicate, entryPredicate);
- return new FilteredEntryBiMap<K, V>(map.unfiltered(), predicate);
- }
-
- static final class FilteredEntryBiMap<K, V> extends FilteredEntryMap<K, V>
- implements BiMap<K, V> {
- private final BiMap<V, K> inverse;
-
- private static <K, V> Predicate<Entry<V, K>> inversePredicate(
- final Predicate<? super Entry<K, V>> forwardPredicate) {
- return new Predicate<Entry<V, K>>() {
- @Override
- public boolean apply(Entry<V, K> input) {
- return forwardPredicate.apply(
- Maps.immutableEntry(input.getValue(), input.getKey()));
- }
- };
- }
-
- FilteredEntryBiMap(BiMap<K, V> delegate,
- Predicate<? super Entry<K, V>> predicate) {
- super(delegate, predicate);
- this.inverse = new FilteredEntryBiMap<V, K>(
- delegate.inverse(), inversePredicate(predicate), this);
- }
-
- private FilteredEntryBiMap(
- BiMap<K, V> delegate, Predicate<? super Entry<K, V>> predicate,
- BiMap<V, K> inverse) {
- super(delegate, predicate);
- this.inverse = inverse;
- }
-
- BiMap<K, V> unfiltered() {
- return (BiMap<K, V>) unfiltered;
- }
-
- @Override
- public V forcePut(@Nullable K key, @Nullable V value) {
- checkArgument(predicate.apply(Maps.immutableEntry(key, value)));
- return unfiltered().forcePut(key, value);
- }
-
- @Override
- public BiMap<V, K> inverse() {
- return inverse;
- }
-
- @Override
- public Set<V> values() {
- return inverse.keySet();
- }
- }
-
private static class FilteredKeyMap<K, V> extends AbstractFilteredMap<K, V> {
Predicate<? super K> keyPredicate;
@@ -3050,14 +1840,10 @@ public final class Maps {
@Override public Set<K> keySet() {
Set<K> result = keySet;
- return (result == null) ? keySet = createKeySet() : result;
+ return (result == null) ? keySet = new KeySet() : result;
}
- Set<K> createKeySet() {
- return new KeySet();
- }
-
- private class KeySet extends Sets.ImprovedAbstractSet<K> {
+ private class KeySet extends AbstractSet<K> {
@Override public Iterator<K> iterator() {
final Iterator<Entry<K, V>> iterator = filteredEntrySet.iterator();
return new UnmodifiableIterator<K>() {
@@ -3093,13 +1879,22 @@ public final class Maps {
return false;
}
+ @Override public boolean removeAll(Collection<?> collection) {
+ checkNotNull(collection); // for GWT
+ boolean changed = false;
+ for (Object obj : collection) {
+ changed |= remove(obj);
+ }
+ return changed;
+ }
+
@Override public boolean retainAll(Collection<?> collection) {
checkNotNull(collection); // for GWT
boolean changed = false;
Iterator<Entry<K, V>> iterator = unfiltered.entrySet().iterator();
while (iterator.hasNext()) {
Entry<K, V> entry = iterator.next();
- if (predicate.apply(entry) && !collection.contains(entry.getKey())) {
+ if (!collection.contains(entry.getKey()) && predicate.apply(entry)) {
iterator.remove();
changed = true;
}
@@ -3119,224 +1914,6 @@ public final class Maps {
}
/**
- * Returns an unmodifiable view of the specified navigable map. Query operations on the returned
- * map read through to the specified map, and attempts to modify the returned map, whether direct
- * or via its views, result in an {@code UnsupportedOperationException}.
- *
- * <p>The returned navigable map will be serializable if the specified navigable map is
- * serializable.
- *
- * @param map the navigable map for which an unmodifiable view is to be returned
- * @return an unmodifiable view of the specified navigable map
- * @since 12.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V> NavigableMap<K, V> unmodifiableNavigableMap(NavigableMap<K, V> map) {
- checkNotNull(map);
- if (map instanceof UnmodifiableNavigableMap) {
- return map;
- } else {
- return new UnmodifiableNavigableMap<K, V>(map);
- }
- }
-
- @Nullable private static <K, V> Entry<K, V> unmodifiableOrNull(@Nullable Entry<K, V> entry) {
- return (entry == null) ? null : Maps.unmodifiableEntry(entry);
- }
-
- @GwtIncompatible("NavigableMap")
- static class UnmodifiableNavigableMap<K, V>
- extends ForwardingSortedMap<K, V> implements NavigableMap<K, V>, Serializable {
- private final NavigableMap<K, V> delegate;
-
- UnmodifiableNavigableMap(NavigableMap<K, V> delegate) {
- this.delegate = delegate;
- }
-
- @Override
- protected SortedMap<K, V> delegate() {
- return Collections.unmodifiableSortedMap(delegate);
- }
-
- @Override
- public Entry<K, V> lowerEntry(K key) {
- return unmodifiableOrNull(delegate.lowerEntry(key));
- }
-
- @Override
- public K lowerKey(K key) {
- return delegate.lowerKey(key);
- }
-
- @Override
- public Entry<K, V> floorEntry(K key) {
- return unmodifiableOrNull(delegate.floorEntry(key));
- }
-
- @Override
- public K floorKey(K key) {
- return delegate.floorKey(key);
- }
-
- @Override
- public Entry<K, V> ceilingEntry(K key) {
- return unmodifiableOrNull(delegate.ceilingEntry(key));
- }
-
- @Override
- public K ceilingKey(K key) {
- return delegate.ceilingKey(key);
- }
-
- @Override
- public Entry<K, V> higherEntry(K key) {
- return unmodifiableOrNull(delegate.higherEntry(key));
- }
-
- @Override
- public K higherKey(K key) {
- return delegate.higherKey(key);
- }
-
- @Override
- public Entry<K, V> firstEntry() {
- return unmodifiableOrNull(delegate.firstEntry());
- }
-
- @Override
- public Entry<K, V> lastEntry() {
- return unmodifiableOrNull(delegate.lastEntry());
- }
-
- @Override
- public final Entry<K, V> pollFirstEntry() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public final Entry<K, V> pollLastEntry() {
- throw new UnsupportedOperationException();
- }
-
- private transient UnmodifiableNavigableMap<K, V> descendingMap;
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- UnmodifiableNavigableMap<K, V> result = descendingMap;
- if (result == null) {
- descendingMap = result = new UnmodifiableNavigableMap<K, V>(delegate.descendingMap());
- result.descendingMap = this;
- }
- return result;
- }
-
- @Override
- public Set<K> keySet() {
- return navigableKeySet();
- }
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- return Sets.unmodifiableNavigableSet(delegate.navigableKeySet());
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return Sets.unmodifiableNavigableSet(delegate.descendingKeySet());
- }
-
- @Override
- public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override
- public SortedMap<K, V> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override
- public SortedMap<K, V> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override
- public
- NavigableMap<K, V>
- subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return Maps.unmodifiableNavigableMap(delegate.subMap(
- fromKey,
- fromInclusive,
- toKey,
- toInclusive));
- }
-
- @Override
- public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- return Maps.unmodifiableNavigableMap(delegate.headMap(toKey, inclusive));
- }
-
- @Override
- public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- return Maps.unmodifiableNavigableMap(delegate.tailMap(fromKey, inclusive));
- }
- }
-
- /**
- * Returns a synchronized (thread-safe) navigable map backed by the specified
- * navigable map. In order to guarantee serial access, it is critical that
- * <b>all</b> access to the backing navigable map is accomplished
- * through the returned navigable map (or its views).
- *
- * <p>It is imperative that the user manually synchronize on the returned
- * navigable map when iterating over any of its collection views, or the
- * collections views of any of its {@code descendingMap}, {@code subMap},
- * {@code headMap} or {@code tailMap} views. <pre> {@code
- *
- * NavigableMap<K, V> map = synchronizedNavigableMap(new TreeMap<K, V>());
- *
- * // Needn't be in synchronized block
- * NavigableSet<K> set = map.navigableKeySet();
- *
- * synchronized (map) { // Synchronizing on map, not set!
- * Iterator<K> it = set.iterator(); // Must be in synchronized block
- * while (it.hasNext()){
- * foo(it.next());
- * }
- * }}</pre>
- *
- * or: <pre> {@code
- *
- * NavigableMap<K, V> map = synchronizedNavigableMap(new TreeMap<K, V>());
- * NavigableMap<K, V> map2 = map.subMap(foo, false, bar, true);
- *
- * // Needn't be in synchronized block
- * NavigableSet<K> set2 = map2.descendingKeySet();
- *
- * synchronized (map) { // Synchronizing on map, not map2 or set2!
- * Iterator<K> it = set2.iterator(); // Must be in synchronized block
- * while (it.hasNext()){
- * foo(it.next());
- * }
- * }}</pre>
- *
- * Failure to follow this advice may result in non-deterministic behavior.
- *
- * <p>The returned navigable map will be serializable if the specified
- * navigable map is serializable.
- *
- * @param navigableMap the navigable map to be "wrapped" in a synchronized
- * navigable map.
- * @return a synchronized view of the specified navigable map.
- * @since 13.0
- */
- @GwtIncompatible("NavigableMap")
- public static <K, V> NavigableMap<K, V> synchronizedNavigableMap(
- NavigableMap<K, V> navigableMap) {
- return Synchronized.navigableMap(navigableMap);
- }
-
- /**
* {@code AbstractMap} extension that implements {@link #isEmpty()} as {@code
* entrySet().isEmpty()} instead of {@code size() == 0} to speed up
* implementations where {@code size()} is O(n), and it delegates the {@code
@@ -3344,7 +1921,7 @@ public final class Maps {
* implementation.
*/
@GwtCompatible
- abstract static class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> {
+ static abstract class ImprovedAbstractMap<K, V> extends AbstractMap<K, V> {
/**
* Creates the entry set to be returned by {@link #entrySet()}. This method
* is invoked at most once on a given map, at the time when {@code entrySet}
@@ -3381,7 +1958,7 @@ public final class Maps {
@Override public Collection<V> values() {
Collection<V> result = values;
if (result == null) {
- return values = new Values<K, V>() {
+ return values = new Values<K, V>(){
@Override Map<K, V> map() {
return ImprovedAbstractMap.this;
}
@@ -3389,6 +1966,17 @@ public final class Maps {
}
return result;
}
+
+ /**
+ * Returns {@code true} if this map contains no key-value mappings.
+ *
+ * <p>The implementation returns {@code entrySet().isEmpty()}.
+ *
+ * @return {@code true} if this map contains no key-value mappings
+ */
+ @Override public boolean isEmpty() {
+ return entrySet().isEmpty();
+ }
}
static final MapJoiner STANDARD_JOINER =
@@ -3396,46 +1984,25 @@ public final class Maps {
/**
* Delegates to {@link Map#get}. Returns {@code null} on {@code
- * ClassCastException} and {@code NullPointerException}.
+ * ClassCastException}.
*/
static <V> V safeGet(Map<?, V> map, Object key) {
- checkNotNull(map);
try {
return map.get(key);
} catch (ClassCastException e) {
return null;
- } catch (NullPointerException e) {
- return null;
}
}
/**
* Delegates to {@link Map#containsKey}. Returns {@code false} on {@code
- * ClassCastException} and {@code NullPointerException}.
+ * ClassCastException}
*/
static boolean safeContainsKey(Map<?, ?> map, Object key) {
- checkNotNull(map);
try {
return map.containsKey(key);
} catch (ClassCastException e) {
return false;
- } catch (NullPointerException e) {
- return false;
- }
- }
-
- /**
- * Delegates to {@link Map#remove}. Returns {@code null} on {@code
- * ClassCastException} and {@code NullPointerException}.
- */
- static <V> V safeRemove(Map<?, V> map, Object key) {
- checkNotNull(map);
- try {
- return map.remove(key);
- } catch (ClassCastException e) {
- return null;
- } catch (NullPointerException e) {
- return null;
}
}
@@ -3494,6 +2061,13 @@ public final class Maps {
}
/**
+ * An implementation of {@link Map#hashCode}.
+ */
+ static int hashCodeImpl(Map<?, ?> map) {
+ return Sets.hashCodeImpl(map.entrySet());
+ }
+
+ /**
* An implementation of {@link Map#toString}.
*/
static String toStringImpl(Map<?, ?> map) {
@@ -3517,30 +2091,36 @@ public final class Maps {
* An admittedly inefficient implementation of {@link Map#containsKey}.
*/
static boolean containsKeyImpl(Map<?, ?> map, @Nullable Object key) {
- return Iterators.contains(keyIterator(map.entrySet().iterator()), key);
+ for (Entry<?, ?> entry : map.entrySet()) {
+ if (Objects.equal(entry.getKey(), key)) {
+ return true;
+ }
+ }
+ return false;
}
/**
* An implementation of {@link Map#containsValue}.
*/
static boolean containsValueImpl(Map<?, ?> map, @Nullable Object value) {
- return Iterators.contains(valueIterator(map.entrySet().iterator()), value);
- }
-
- static <K, V> Iterator<K> keyIterator(Iterator<Entry<K, V>> entryIterator) {
- return new TransformedIterator<Entry<K, V>, K>(entryIterator) {
- @Override
- K transform(Entry<K, V> entry) {
- return entry.getKey();
+ for (Entry<?, ?> entry : map.entrySet()) {
+ if (Objects.equal(entry.getValue(), value)) {
+ return true;
}
- };
+ }
+ return false;
}
- abstract static class KeySet<K, V> extends Sets.ImprovedAbstractSet<K> {
+ abstract static class KeySet<K, V> extends AbstractSet<K> {
abstract Map<K, V> map();
@Override public Iterator<K> iterator() {
- return keyIterator(map().entrySet().iterator());
+ return Iterators.transform(map().entrySet().iterator(),
+ new Function<Map.Entry<K, V>, K>() {
+ @Override public K apply(Entry<K, V> entry) {
+ return entry.getKey();
+ }
+ });
}
@Override public int size() {
@@ -3563,153 +2143,27 @@ public final class Maps {
return false;
}
- @Override public void clear() {
- map().clear();
- }
- }
-
- @Nullable
- static <K> K keyOrNull(@Nullable Entry<K, ?> entry) {
- return (entry == null) ? null : entry.getKey();
- }
-
- @Nullable
- static <V> V valueOrNull(@Nullable Entry<?, V> entry) {
- return (entry == null) ? null : entry.getValue();
- }
-
- @GwtIncompatible("NavigableMap")
- static class NavigableKeySet<K, V> extends KeySet<K, V> implements NavigableSet<K> {
- private final NavigableMap<K, V> map;
-
- NavigableKeySet(NavigableMap<K, V> map) {
- this.map = checkNotNull(map);
- }
-
- @Override
- NavigableMap<K, V> map() {
- return map;
- }
-
- @Override
- public Comparator<? super K> comparator() {
- return map().comparator();
- }
-
- @Override
- public K first() {
- return map().firstKey();
- }
-
- @Override
- public K last() {
- return map().lastKey();
- }
-
- @Override
- public K lower(K e) {
- return map().lowerKey(e);
- }
-
- @Override
- public K floor(K e) {
- return map().floorKey(e);
- }
-
- @Override
- public K ceiling(K e) {
- return map().ceilingKey(e);
- }
-
- @Override
- public K higher(K e) {
- return map().higherKey(e);
- }
-
- @Override
- public K pollFirst() {
- return keyOrNull(map().pollFirstEntry());
- }
-
- @Override
- public K pollLast() {
- return keyOrNull(map().pollLastEntry());
- }
-
- @Override
- public NavigableSet<K> descendingSet() {
- return map().descendingKeySet();
- }
-
- @Override
- public Iterator<K> descendingIterator() {
- return descendingSet().iterator();
- }
-
- @Override
- public NavigableSet<K> subSet(
- K fromElement,
- boolean fromInclusive,
- K toElement,
- boolean toInclusive) {
- return map().subMap(fromElement, fromInclusive, toElement, toInclusive).navigableKeySet();
- }
-
- @Override
- public NavigableSet<K> headSet(K toElement, boolean inclusive) {
- return map().headMap(toElement, inclusive).navigableKeySet();
- }
-
- @Override
- public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
- return map().tailMap(fromElement, inclusive).navigableKeySet();
- }
-
- @Override
- public SortedSet<K> subSet(K fromElement, K toElement) {
- return subSet(fromElement, true, toElement, false);
- }
-
@Override
- public SortedSet<K> headSet(K toElement) {
- return headSet(toElement, false);
+ public boolean removeAll(Collection<?> c) {
+ // TODO(user): find out why this is necessary to make GWT tests pass.
+ return super.removeAll(checkNotNull(c));
}
- @Override
- public SortedSet<K> tailSet(K fromElement) {
- return tailSet(fromElement, true);
+ @Override public void clear() {
+ map().clear();
}
}
- static <K, V> Iterator<V> valueIterator(Iterator<Entry<K, V>> entryIterator) {
- return new TransformedIterator<Entry<K, V>, V>(entryIterator) {
- @Override
- V transform(Entry<K, V> entry) {
- return entry.getValue();
- }
- };
- }
-
- static <K, V> UnmodifiableIterator<V> valueIterator(
- final UnmodifiableIterator<Entry<K, V>> entryIterator) {
- return new UnmodifiableIterator<V>() {
- @Override
- public boolean hasNext() {
- return entryIterator.hasNext();
- }
-
- @Override
- public V next() {
- return entryIterator.next().getValue();
- }
- };
- }
-
abstract static class Values<K, V> extends AbstractCollection<V> {
abstract Map<K, V> map();
@Override public Iterator<V> iterator() {
- return valueIterator(map().entrySet().iterator());
+ return Iterators.transform(map().entrySet().iterator(),
+ new Function<Entry<K, V>, V>() {
+ @Override public V apply(Entry<K, V> entry) {
+ return entry.getValue();
+ }
+ });
}
@Override public boolean remove(Object o) {
@@ -3771,8 +2225,7 @@ public final class Maps {
}
}
- abstract static class EntrySet<K, V>
- extends Sets.ImprovedAbstractSet<Entry<K, V>> {
+ abstract static class EntrySet<K, V> extends AbstractSet<Entry<K, V>> {
abstract Map<K, V> map();
@Override public int size() {
@@ -3835,197 +2288,4 @@ public final class Maps {
}
}
}
-
- @GwtIncompatible("NavigableMap")
- abstract static class DescendingMap<K, V> extends ForwardingMap<K, V>
- implements NavigableMap<K, V> {
-
- abstract NavigableMap<K, V> forward();
-
- @Override
- protected final Map<K, V> delegate() {
- return forward();
- }
-
- private transient Comparator<? super K> comparator;
-
- @SuppressWarnings("unchecked")
- @Override
- public Comparator<? super K> comparator() {
- Comparator<? super K> result = comparator;
- if (result == null) {
- Comparator<? super K> forwardCmp = forward().comparator();
- if (forwardCmp == null) {
- forwardCmp = (Comparator) Ordering.natural();
- }
- result = comparator = reverse(forwardCmp);
- }
- return result;
- }
-
- // If we inline this, we get a javac error.
- private static <T> Ordering<T> reverse(Comparator<T> forward) {
- return Ordering.from(forward).reverse();
- }
-
- @Override
- public K firstKey() {
- return forward().lastKey();
- }
-
- @Override
- public K lastKey() {
- return forward().firstKey();
- }
-
- @Override
- public Entry<K, V> lowerEntry(K key) {
- return forward().higherEntry(key);
- }
-
- @Override
- public K lowerKey(K key) {
- return forward().higherKey(key);
- }
-
- @Override
- public Entry<K, V> floorEntry(K key) {
- return forward().ceilingEntry(key);
- }
-
- @Override
- public K floorKey(K key) {
- return forward().ceilingKey(key);
- }
-
- @Override
- public Entry<K, V> ceilingEntry(K key) {
- return forward().floorEntry(key);
- }
-
- @Override
- public K ceilingKey(K key) {
- return forward().floorKey(key);
- }
-
- @Override
- public Entry<K, V> higherEntry(K key) {
- return forward().lowerEntry(key);
- }
-
- @Override
- public K higherKey(K key) {
- return forward().lowerKey(key);
- }
-
- @Override
- public Entry<K, V> firstEntry() {
- return forward().lastEntry();
- }
-
- @Override
- public Entry<K, V> lastEntry() {
- return forward().firstEntry();
- }
-
- @Override
- public Entry<K, V> pollFirstEntry() {
- return forward().pollLastEntry();
- }
-
- @Override
- public Entry<K, V> pollLastEntry() {
- return forward().pollFirstEntry();
- }
-
- @Override
- public NavigableMap<K, V> descendingMap() {
- return forward();
- }
-
- private transient Set<Entry<K, V>> entrySet;
-
- @Override
- public Set<Entry<K, V>> entrySet() {
- Set<Entry<K, V>> result = entrySet;
- return (result == null) ? entrySet = createEntrySet() : result;
- }
-
- abstract Iterator<Entry<K, V>> entryIterator();
-
- Set<Entry<K, V>> createEntrySet() {
- return new EntrySet<K, V>() {
-
- @Override
- Map<K, V> map() {
- return DescendingMap.this;
- }
-
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return entryIterator();
- }
- };
- }
-
- @Override
- public Set<K> keySet() {
- return navigableKeySet();
- }
-
- private transient NavigableSet<K> navigableKeySet;
-
- @Override
- public NavigableSet<K> navigableKeySet() {
- NavigableSet<K> result = navigableKeySet;
- return (result == null) ? navigableKeySet = new NavigableKeySet<K, V>(this) : result;
- }
-
- @Override
- public NavigableSet<K> descendingKeySet() {
- return forward().navigableKeySet();
- }
-
- @Override
- public
- NavigableMap<K, V>
- subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- return forward().subMap(toKey, toInclusive, fromKey, fromInclusive).descendingMap();
- }
-
- @Override
- public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- return forward().tailMap(toKey, inclusive).descendingMap();
- }
-
- @Override
- public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- return forward().headMap(fromKey, inclusive).descendingMap();
- }
-
- @Override
- public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override
- public SortedMap<K, V> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override
- public SortedMap<K, V> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- @Override
- public Collection<V> values() {
- return new Values<K, V>() {
- @Override
- Map<K, V> map() {
- return DescendingMap.this;
- }
- };
- }
- }
}
diff --git a/guava/src/com/google/common/collect/MinMaxPriorityQueue.java b/guava/src/com/google/common/collect/MinMaxPriorityQueue.java
index f9c2d92..4429c34 100644
--- a/guava/src/com/google/common/collect/MinMaxPriorityQueue.java
+++ b/guava/src/com/google/common/collect/MinMaxPriorityQueue.java
@@ -26,13 +26,13 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.math.IntMath;
import java.util.AbstractQueue;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
@@ -85,7 +85,7 @@ import java.util.Queue;
* @author Torbjorn Gannholm
* @since 8.0
*/
-// TODO(kevinb): GWT compatibility
+// TODO(kevinb): @GwtCompatible
@Beta
public final class MinMaxPriorityQueue<E> extends AbstractQueue<E> {
@@ -747,6 +747,7 @@ public final class MinMaxPriorityQueue<E> extends AbstractQueue<E> {
private class QueueIterator implements Iterator<E> {
private int cursor = -1;
private int expectedModCount = modCount;
+ // TODO(user): Switch to ArrayDeque once Guava supports it.
private Queue<E> forgetMeNot;
private List<E> skipMe;
private E lastFromForgetMeNot;
@@ -787,7 +788,7 @@ public final class MinMaxPriorityQueue<E> extends AbstractQueue<E> {
MoveDesc<E> moved = removeAt(cursor);
if (moved != null) {
if (forgetMeNot == null) {
- forgetMeNot = new ArrayDeque<E>();
+ forgetMeNot = new LinkedList<E>();
skipMe = new ArrayList<E>(3);
}
forgetMeNot.add(moved.toTrickle);
diff --git a/guava/src/com/google/common/collect/Multimap.java b/guava/src/com/google/common/collect/Multimap.java
index ed5afb3..900f820 100644
--- a/guava/src/com/google/common/collect/Multimap.java
+++ b/guava/src/com/google/common/collect/Multimap.java
@@ -19,139 +19,40 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
/**
- * A collection that maps keys to values, similar to {@link Map}, but in which
- * each key may be associated with <i>multiple</i> values. You can visualize the
- * contents of a multimap either as a map from keys to <i>nonempty</i>
- * collections of values:
+ * A collection similar to a {@code Map}, but which may associate multiple
+ * values with a single key. If you call {@link #put} twice, with the same key
+ * but different values, the multimap contains mappings from the key to both
+ * values.
*
- * <ul>
- * <li>a → 1, 2
- * <li>b → 3
- * </ul>
+ * <p>The methods {@link #get}, {@link #keySet}, {@link #keys}, {@link #values},
+ * {@link #entries}, and {@link #asMap} return collections that are views of the
+ * multimap. If the multimap is modifiable, updating it can change the contents
+ * of those collections, and updating the collections will change the multimap.
+ * In contrast, {@link #replaceValues} and {@link #removeAll} return collections
+ * that are independent of subsequent multimap changes.
*
- * ... or as a single "flattened" collection of key-value pairs:
+ * <p>Depending on the implementation, a multimap may or may not allow duplicate
+ * key-value pairs. In other words, the multimap contents after adding the same
+ * key and value twice varies between implementations. In multimaps allowing
+ * duplicates, the multimap will contain two mappings, and {@code get} will
+ * return a collection that includes the value twice. In multimaps not
+ * supporting duplicates, the multimap will contain a single mapping from the
+ * key to the value, and {@code get} will return a collection that includes the
+ * value once.
*
- * <ul>
- * <li>a → 1
- * <li>a → 2
- * <li>b → 3
- * </ul>
- *
- * <p><b>Important:</b> although the first interpretation resembles how most
- * multimaps are <i>implemented</i>, the design of the {@code Multimap} API is
- * based on the <i>second</i> form. So, using the multimap shown above as an
- * example, the {@link #size} is {@code 3}, not {@code 2}, and the {@link
- * #values} collection is {@code [1, 2, 3]}, not {@code [[1, 2], [3]]}. For
- * those times when the first style is more useful, use the multimap's {@link
- * #asMap} view (or create a {@code Map<K, Collection<V>>} in the first place).
- *
- * <h3>Example</h3>
- *
- * <p>The following code: <pre> {@code
- *
- * ListMultimap<String, String> multimap = ArrayListMultimap.create();
- * for (President pres : US_PRESIDENTS_IN_ORDER) {
- * multimap.put(pres.firstName(), pres.lastName());
- * }
- * for (String firstName : multimap.keySet()) {
- * List<String> lastNames = multimap.get(firstName);
- * out.println(firstName + ": " + lastNames);
- * }}</pre>
- *
- * ... produces output such as: <pre> {@code
- *
- * Zachary: [Taylor]
- * John: [Adams, Adams, Tyler, Kennedy]
- * George: [Washington, Bush, Bush]
- * Grover: [Cleveland]
- * ...}</pre>
- *
- * <h3>Views</h3>
- *
- * <p>Much of the power of the multimap API comes from the <i>view
- * collections</i> it provides. These always reflect the latest state of the
- * multimap itself. When they support modification, the changes are
- * <i>write-through</i> (they automatically update the backing multimap). These
- * view collections are:
- *
- * <ul>
- * <li>{@link #asMap}, mentioned above</li>
- * <li>{@link #keys}, {@link #keySet}, {@link #values}, {@link #entries}, which
- * are similar to the corresponding view collections of {@link Map}
- * <li>and, notably, even the collection returned by {@link #get get(key)} is an
- * active view of the values corresponding to {@code key}
- * </ul>
- *
- * <p>The collections returned by the {@link #replaceValues replaceValues} and
- * {@link #removeAll removeAll} methods, which contain values that have just
- * been removed from the multimap, are naturally <i>not</i> views.
- *
- * <h3>Subinterfaces</h3>
- *
- * <p>Instead of using the {@code Multimap} interface directly, prefer the
- * subinterfaces {@link ListMultimap} and {@link SetMultimap}. These take their
- * names from the fact that the collections they return from {@code get} behave
- * like (and, of course, implement) {@link List} and {@link Set}, respectively.
- *
- * <p>For example, the "presidents" code snippet above used a {@code
- * ListMultimap}; if it had used a {@code SetMultimap} instead, two presidents
- * would have vanished, and last names might or might not appear in
- * chronological order.
- *
- * <p><b>Warning:</b> instances of type {@code Multimap} may not implement
- * {@link Object#equals} in the way you expect (multimaps containing the same
- * key-value pairs, even in the same order, may or may not be equal). The
- * recommended subinterfaces provide a much stronger guarantee.
- *
- * <h3>Comparison to a map of collections</h3>
- *
- * <p>Multimaps are commonly used in places where a {@code Map<K,
- * Collection<V>>} would otherwise have appeared. The differences include:
- *
- * <ul>
- * <li>There is no need to populate an empty collection before adding an entry
- * with {@link #put put}.
- * <li>{@code get} never returns {@code null}, only an empty collection.
- * <li>A key contained in the multimap always maps to at least one value. Any
- * operation that causes a key to have zero associated values has the effect
- * of <i>removing</i> that key from the multimap.
- * <li>The total entry count is available as {@link #size}.
- * <li>Many complex operations become easier; for example, {@code
- * Collections.min(multimap.values())} finds the smallest value across all
- * keys.
- * </ul>
- *
- * <h3>Implementations</h3>
- *
- * <p>As always, prefer the immutable implementations, {@link
- * ImmutableListMultimap} and {@link ImmutableSetMultimap}. General-purpose
- * mutable implementations are listed above under "All Known Implementing
- * Classes". You can also create a <i>custom</i> multimap, backed by any {@code
- * Map} and {@link Collection} types, using the {@link Multimaps#newMultimap
- * Multimaps.newMultimap} family of methods. Finally, another popular way to
- * obtain a multimap is using {@link Multimaps#index Multimaps.index}. See
- * the {@link Multimaps} class for these and other static utilities related
- * to multimaps.
- *
- * <h3>Other Notes</h3>
- *
- * <p>All methods that modify the multimap are optional. The view collections
- * returned by the multimap may or may not be modifiable. Any modification
- * method that is not supported will throw {@link
- * UnsupportedOperationException}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
+ * <p>All methods that alter the multimap are optional, and the views returned
+ * by the multimap may or may not be modifiable. When modification isn't
+ * supported, those methods will throw an {@link UnsupportedOperationException}.
*
* @author Jared Levy
+ * @param <K> the type of keys maintained by this multimap
+ * @param <V> the type of mapped values
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible
@@ -207,7 +108,7 @@ public interface Multimap<K, V> {
boolean put(@Nullable K key, @Nullable V value);
/**
- * Removes a single key-value pair from the multimap.
+ * Removes a key-value pair from the multimap.
*
* @param key key of entry to remove from the multimap
* @param value value of entry to remove the multimap
@@ -268,17 +169,15 @@ public interface Multimap<K, V> {
// Views
/**
- * Returns a collection view containing the values associated with {@code key}
- * in this multimap, if any. Note that even when ({@code containsKey(key)} is
- * false, {@code get(key)} still returns an empty collection, not {@code
- * null}.
+ * Returns a collection view of all values associated with a key. If no
+ * mappings in the multimap have the provided key, an empty collection is
+ * returned.
*
* <p>Changes to the returned collection will update the underlying multimap,
* and vice versa.
*
* @param key key to search for in multimap
- * @return a view collection containing the zero or more values that the key
- * maps to
+ * @return the collection of values that the key maps to
*/
Collection<V> get(@Nullable K key);
diff --git a/guava/src/com/google/common/collect/Multimaps.java b/guava/src/com/google/common/collect/Multimaps.java
index 92e5d06..e2f593e 100644
--- a/guava/src/com/google/common/collect/Multimaps.java
+++ b/guava/src/com/google/common/collect/Multimaps.java
@@ -20,14 +20,17 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
+import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
+import com.google.common.collect.Collections2.TransformedCollection;
import com.google.common.collect.Maps.EntryTransformer;
import java.io.IOException;
@@ -35,6 +38,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.AbstractCollection;
+import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -52,10 +56,6 @@ import javax.annotation.Nullable;
/**
* Provides static methods acting on or generating a {@code Multimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multimaps">
- * {@code Multimaps}</a>.
- *
* @author Jared Levy
* @author Robert Konigsberg
* @author Mike Bostock
@@ -67,14 +67,9 @@ public final class Multimaps {
private Multimaps() {}
/**
- * Creates a new {@code Multimap} backed by {@code map}, whose internal value
- * collections are generated by {@code factory}.
- *
- * <b>Warning: do not use</b> this method when the collections returned by
- * {@code factory} implement either {@link List} or {@code Set}! Use the more
- * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link
- * #newSortedSetMultimap} instead, to avoid very surprising behavior from
- * {@link Multimap#equals}.
+ * Creates a new {@code Multimap} that uses the provided map and factory. It
+ * can generate a multimap based on arbitrary {@link Map} and
+ * {@link Collection} classes.
*
* <p>The {@code factory}-generated and {@code map} classes determine the
* multimap iteration order. They also specify the behavior of the
@@ -114,7 +109,7 @@ public final class Multimaps {
return new CustomMultimap<K, V>(map, factory);
}
- private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
+ private static class CustomMultimap<K, V> extends AbstractMultimap<K, V> {
transient Supplier<? extends Collection<V>> factory;
CustomMultimap(Map<K, Collection<V>> map,
@@ -423,13 +418,13 @@ public final class Multimaps {
* <p>It is imperative that the user manually synchronize on the returned
* multimap when accessing any of its collection views: <pre> {@code
*
- * Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
+ * Multimap<K, V> m = Multimaps.synchronizedMultimap(
* HashMultimap.<K, V>create());
* ...
- * Collection<V> values = multimap.get(key); // Needn't be in synchronized block
+ * Set<K> s = m.keySet(); // Needn't be in synchronized block
* ...
- * synchronized (multimap) { // Synchronizing on multimap, not values!
- * Iterator<V> i = values.iterator(); // Must be in synchronized block
+ * synchronized (m) { // Synchronizing on m, not s!
+ * Iterator<K> i = s.iterator(); // Must be in synchronized block
* while (i.hasNext()) {
* foo(i.next());
* }
@@ -630,7 +625,7 @@ public final class Multimaps {
}
@Override public Iterator<Collection<V>> iterator() {
final Iterator<Collection<V>> iterator = delegate.iterator();
- return new UnmodifiableIterator<Collection<V>>() {
+ return new Iterator<Collection<V>>() {
@Override
public boolean hasNext() {
return iterator.hasNext();
@@ -639,6 +634,10 @@ public final class Multimaps {
public Collection<V> next() {
return unmodifiableValueCollection(iterator.next());
}
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
};
}
@Override public Object[] toArray() {
@@ -1061,7 +1060,7 @@ public final class Multimaps {
@Override
public Set<V> get(final K key) {
- return new Sets.ImprovedAbstractSet<V>() {
+ return new AbstractSet<V>() {
@Override public Iterator<V> iterator() {
return new Iterator<V>() {
int i;
@@ -1142,7 +1141,7 @@ public final class Multimaps {
@Override
public Multiset<K> keys() {
- return new Multimaps.Keys<K, V>(this);
+ return Multisets.forSet(map.keySet());
}
@Override
@@ -1193,27 +1192,35 @@ public final class Multimaps {
}
/** @see MapMultimap#asMap */
- class AsMapEntries extends Sets.ImprovedAbstractSet<Entry<K, Collection<V>>> {
+ class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
@Override public int size() {
return map.size();
}
@Override public Iterator<Entry<K, Collection<V>>> iterator() {
- return new TransformedIterator<K, Entry<K, Collection<V>>>(map.keySet().iterator()) {
+ return new Iterator<Entry<K, Collection<V>>>() {
+ final Iterator<K> keys = map.keySet().iterator();
+
@Override
- Entry<K, Collection<V>> transform(final K key) {
+ public boolean hasNext() {
+ return keys.hasNext();
+ }
+ @Override
+ public Entry<K, Collection<V>> next() {
+ final K key = keys.next();
return new AbstractMapEntry<K, Collection<V>>() {
- @Override
- public K getKey() {
+ @Override public K getKey() {
return key;
}
-
- @Override
- public Collection<V> getValue() {
+ @Override public Collection<V> getValue() {
return get(key);
}
};
}
+ @Override
+ public void remove() {
+ keys.remove();
+ }
};
}
@@ -1315,6 +1322,7 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> Multimap<K, V2> transformValues(
Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
checkNotNull(function);
@@ -1383,29 +1391,15 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> Multimap<K, V2> transformEntries(
Multimap<K, V1> fromMap,
EntryTransformer<? super K, ? super V1, V2> transformer) {
return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer);
}
-
- static final class ValueFunction<K, V1, V2> implements Function<V1, V2> {
- private final K key;
- private final EntryTransformer<? super K, ? super V1, V2> transformer;
-
- ValueFunction(K key, EntryTransformer<? super K, ? super V1, V2> transformer) {
- this.key = key;
- this.transformer = transformer;
- }
-
- @Override
- public V2 apply(@Nullable V1 value) {
- return transformer.transformEntry(key, value);
- }
- }
private static class TransformedEntriesMultimap<K, V1, V2>
- extends AbstractMultimap<K, V2> {
+ implements Multimap<K, V2> {
final Multimap<K, V1> fromMultimap;
final EntryTransformer<? super K, ? super V1, V2> transformer;
@@ -1415,25 +1409,30 @@ public final class Multimaps {
this.transformer = checkNotNull(transformer);
}
- Collection<V2> transform(K key, Collection<V1> values) {
- Function<V1, V2> function = new ValueFunction<K, V1, V2>(key, transformer);
- if (values instanceof List) {
- return Lists.transform((List<V1>) values, function);
- } else {
- return Collections2.transform(values, function);
- }
+ Collection<V2> transform(final K key, Collection<V1> values) {
+ return Collections2.transform(values, new Function<V1, V2>() {
+ @Override public V2 apply(V1 value) {
+ return transformer.transformEntry(key, value);
+ }
+ });
}
- @Override
- Map<K, Collection<V2>> createAsMap() {
- return Maps.transformEntries(fromMultimap.asMap(),
- new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
+ private transient Map<K, Collection<V2>> asMap;
- @Override public Collection<V2> transformEntry(
- K key, Collection<V1> value) {
- return transform(key, value);
- }
- });
+ @Override public Map<K, Collection<V2>> asMap() {
+ if (asMap == null) {
+ Map<K, Collection<V2>> aM = Maps.transformEntries(fromMultimap.asMap(),
+ new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
+
+ @Override public Collection<V2> transformEntry(
+ K key, Collection<V1> value) {
+ return transform(key, value);
+ }
+ });
+ asMap = aM;
+ return aM;
+ }
+ return asMap;
}
@Override public void clear() {
@@ -1454,25 +1453,58 @@ public final class Multimaps {
return values().contains(value);
}
- @Override
- Iterator<Entry<K, V2>> entryIterator() {
- return Iterators.transform(
- fromMultimap.entries().iterator(), new Function<Entry<K, V1>, Entry<K, V2>>() {
- @Override
- public Entry<K, V2> apply(final Entry<K, V1> entry) {
- return new AbstractMapEntry<K, V2>() {
- @Override
- public K getKey() {
- return entry.getKey();
- }
+ private transient Collection<Entry<K, V2>> entries;
+
+ @Override public Collection<Entry<K, V2>> entries() {
+ if (entries == null) {
+ Collection<Entry<K, V2>> es = new TransformedEntries(transformer);
+ entries = es;
+ return es;
+ }
+ return entries;
+ }
+
+ private class TransformedEntries
+ extends TransformedCollection<Entry<K, V1>, Entry<K, V2>> {
+
+ TransformedEntries(
+ final EntryTransformer<? super K, ? super V1, V2> transformer) {
+ super(fromMultimap.entries(),
+ new Function<Entry<K, V1>, Entry<K, V2>>() {
+ @Override public Entry<K, V2> apply(final Entry<K, V1> entry) {
+ return new AbstractMapEntry<K, V2>() {
+
+ @Override public K getKey() {
+ return entry.getKey();
+ }
+
+ @Override public V2 getValue() {
+ return transformer.transformEntry(
+ entry.getKey(), entry.getValue());
+ }
+ };
+ }
+ });
+ }
+
+ @Override public boolean contains(Object o) {
+ if (o instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ return containsEntry(entry.getKey(), entry.getValue());
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override public boolean remove(Object o) {
+ if (o instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ Collection<V2> values = get((K) entry.getKey());
+ return values.remove(entry.getValue());
+ }
+ return false;
+ }
- @Override
- public V2 getValue() {
- return transformer.transformEntry(entry.getKey(), entry.getValue());
- }
- };
- }
- });
}
@Override public Collection<V2> get(final K key) {
@@ -1522,16 +1554,39 @@ public final class Multimaps {
@Override public int size() {
return fromMultimap.size();
}
-
- @Override
- Collection<V2> createValues() {
- return Collections2.transform(
- fromMultimap.entries(), new Function<Entry<K, V1>, V2>() {
- @Override public V2 apply(Entry<K, V1> entry) {
- return transformer.transformEntry(
- entry.getKey(), entry.getValue());
- }
- });
+
+ private transient Collection<V2> values;
+
+ @Override public Collection<V2> values() {
+ if (values == null) {
+ Collection<V2> vs = Collections2.transform(
+ fromMultimap.entries(), new Function<Entry<K, V1>, V2>() {
+
+ @Override public V2 apply(Entry<K, V1> entry) {
+ return transformer.transformEntry(
+ entry.getKey(), entry.getValue());
+ }
+ });
+ values = vs;
+ return vs;
+ }
+ return values;
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof Multimap) {
+ Multimap<?, ?> other = (Multimap<?, ?>) obj;
+ return asMap().equals(other.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return asMap().hashCode();
+ }
+
+ @Override public String toString() {
+ return asMap().toString();
}
}
@@ -1576,6 +1631,7 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> ListMultimap<K, V2> transformValues(
ListMultimap<K, V1> fromMultimap,
final Function<? super V1, V2> function) {
@@ -1642,6 +1698,7 @@ public final class Multimaps {
*
* @since 7.0
*/
+ @Beta
public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
ListMultimap<K, V1> fromMap,
EntryTransformer<? super K, ? super V1, V2> transformer) {
@@ -1728,6 +1785,24 @@ public final class Multimaps {
}
/**
+ * <b>Deprecated.</b>
+ *
+ * @since 10.0
+ * @deprecated use {@link #index(Iterator, Function)} by casting {@code
+ * values} to {@code Iterator<V>}, or better yet, by implementing only
+ * {@code Iterator} and not {@code Iterable}. <b>This method is scheduled
+ * for deletion in March 2012.</b>
+ */
+ @Beta
+ @Deprecated
+ public static <K, V, I extends Object & Iterable<V> & Iterator<V>>
+ ImmutableListMultimap<K, V> index(
+ I values, Function<? super V, K> keyFunction) {
+ Iterable<V> valuesIterable = checkNotNull(values);
+ return index(valuesIterable, keyFunction);
+ }
+
+ /**
* Creates an index {@code ImmutableListMultimap} that contains the results of
* applying a specified function to each item in an {@code Iterator} of
* values. Each value will be stored as a value in the resulting multimap,
@@ -1783,36 +1858,39 @@ public final class Multimaps {
return builder.build();
}
- static class Keys<K, V> extends AbstractMultiset<K> {
- final Multimap<K, V> multimap;
-
- Keys(Multimap<K, V> multimap) {
- this.multimap = multimap;
- }
+ static abstract class Keys<K, V> extends AbstractMultiset<K> {
+ abstract Multimap<K, V> multimap();
@Override Iterator<Multiset.Entry<K>> entryIterator() {
- return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>(
- multimap.asMap().entrySet().iterator()) {
- @Override
- Multiset.Entry<K> transform(
- final Map.Entry<K, Collection<V>> backingEntry) {
+ final Iterator<Map.Entry<K, Collection<V>>> backingIterator =
+ multimap().asMap().entrySet().iterator();
+ return new Iterator<Multiset.Entry<K>>() {
+ @Override public boolean hasNext() {
+ return backingIterator.hasNext();
+ }
+
+ @Override public Multiset.Entry<K> next() {
+ final Map.Entry<K, Collection<V>> backingEntry =
+ backingIterator.next();
return new Multisets.AbstractEntry<K>() {
- @Override
- public K getElement() {
+ @Override public K getElement() {
return backingEntry.getKey();
}
- @Override
- public int getCount() {
+ @Override public int getCount() {
return backingEntry.getValue().size();
}
};
}
+
+ @Override public void remove() {
+ backingIterator.remove();
+ }
};
}
@Override int distinctElements() {
- return multimap.asMap().size();
+ return multimap().asMap().size();
}
@Override Set<Multiset.Entry<K>> createEntrySet() {
@@ -1833,22 +1911,22 @@ public final class Multimaps {
}
@Override public boolean isEmpty() {
- return multimap.isEmpty();
+ return multimap().isEmpty();
}
@Override public boolean contains(@Nullable Object o) {
- if (o instanceof Multiset.Entry) {
+ if (o instanceof Multiset.Entry<?>) {
Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
- Collection<V> collection = multimap.asMap().get(entry.getElement());
+ Collection<V> collection = multimap().asMap().get(entry.getElement());
return collection != null && collection.size() == entry.getCount();
}
return false;
}
@Override public boolean remove(@Nullable Object o) {
- if (o instanceof Multiset.Entry) {
+ if (o instanceof Multiset.Entry<?>) {
Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
- Collection<V> collection = multimap.asMap().get(entry.getElement());
+ Collection<V> collection = multimap().asMap().get(entry.getElement());
if (collection != null && collection.size() == entry.getCount()) {
collection.clear();
return true;
@@ -1859,16 +1937,30 @@ public final class Multimaps {
}
@Override public boolean contains(@Nullable Object element) {
- return multimap.containsKey(element);
+ return multimap().containsKey(element);
}
@Override public Iterator<K> iterator() {
- return Maps.keyIterator(multimap.entries().iterator());
+ return Iterators.transform(multimap().entries().iterator(),
+ new Function<Map.Entry<K, V>, K>() {
+ @Override public K apply(Map.Entry<K, V> entry) {
+ return entry.getKey();
+ }
+ });
}
@Override public int count(@Nullable Object element) {
- Collection<V> values = Maps.safeGet(multimap.asMap(), element);
- return (values == null) ? 0 : values.size();
+ try {
+ if (multimap().containsKey(element)) {
+ Collection<V> values = multimap().asMap().get(element);
+ return (values == null) ? 0 : values.size();
+ }
+ return 0;
+ } catch (ClassCastException e) {
+ return 0;
+ } catch (NullPointerException e) {
+ return 0;
+ }
}
@Override public int remove(@Nullable Object element, int occurrences) {
@@ -1877,7 +1969,14 @@ public final class Multimaps {
return count(element);
}
- Collection<V> values = Maps.safeGet(multimap.asMap(), element);
+ Collection<V> values;
+ try {
+ values = multimap().asMap().get(element);
+ } catch (ClassCastException e) {
+ return 0;
+ } catch (NullPointerException e) {
+ return 0;
+ }
if (values == null) {
return 0;
@@ -1897,35 +1996,45 @@ public final class Multimaps {
}
@Override public void clear() {
- multimap.clear();
+ multimap().clear();
}
@Override public Set<K> elementSet() {
- return multimap.keySet();
+ return multimap().keySet();
}
}
- static class Values<K, V> extends AbstractCollection<V> {
- final Multimap<K, V> multimap;
-
- Values(Multimap<K, V> multimap) {
- this.multimap = multimap;
- }
+ static abstract class Values<K, V> extends AbstractCollection<V> {
+ abstract Multimap<K, V> multimap();
@Override public Iterator<V> iterator() {
- return Maps.valueIterator(multimap.entries().iterator());
+ final Iterator<Map.Entry<K, V>> backingIterator =
+ multimap().entries().iterator();
+ return new Iterator<V>() {
+ @Override public boolean hasNext() {
+ return backingIterator.hasNext();
+ }
+
+ @Override public V next() {
+ return backingIterator.next().getValue();
+ }
+
+ @Override public void remove() {
+ backingIterator.remove();
+ }
+ };
}
@Override public int size() {
- return multimap.size();
+ return multimap().size();
}
@Override public boolean contains(@Nullable Object o) {
- return multimap.containsValue(o);
+ return multimap().containsValue(o);
}
@Override public void clear() {
- multimap.clear();
+ multimap().clear();
}
}
@@ -1941,7 +2050,7 @@ public final class Multimaps {
}
@Override public boolean contains(@Nullable Object o) {
- if (o instanceof Map.Entry) {
+ if (o instanceof Map.Entry<?, ?>) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
return multimap().containsEntry(entry.getKey(), entry.getValue());
}
@@ -1949,7 +2058,7 @@ public final class Multimaps {
}
@Override public boolean remove(@Nullable Object o) {
- if (o instanceof Map.Entry) {
+ if (o instanceof Map.Entry<?, ?>) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
return multimap().remove(entry.getKey(), entry.getValue());
}
@@ -2047,8 +2156,8 @@ public final class Multimaps {
* <p>The resulting multimap's views have iterators that don't support
* {@code remove()}, but all other methods are supported by the multimap and
* its views. When adding a key that doesn't satisfy the predicate, the
- * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
- * methods throw an {@link IllegalArgumentException}.
+ * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods
+ * throw an {@link IllegalArgumentException}.
*
* <p>When methods such as {@code removeAll()} and {@code clear()} are called on
* the filtered multimap or its views, only mappings whose keys satisfy the
@@ -2069,21 +2178,19 @@ public final class Multimaps {
*
* @since 11.0
*/
+ @Beta
@GwtIncompatible(value = "untested")
public static <K, V> Multimap<K, V> filterKeys(
- Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
- if (unfiltered instanceof FilteredKeyMultimap) {
- FilteredKeyMultimap<K, V> prev = (FilteredKeyMultimap<K, V>) unfiltered;
- return new FilteredKeyMultimap<K, V>(prev.unfiltered,
- Predicates.and(prev.keyPredicate, keyPredicate));
- } else if (unfiltered instanceof FilteredMultimap) {
- FilteredMultimap<K, V> prev = (FilteredMultimap<K, V>) unfiltered;
- return new FilteredEntryMultimap<K, V>(prev.unfiltered,
- Predicates.<Entry<K, V>>and(prev.entryPredicate(),
- Predicates.compose(keyPredicate, Maps.<K>keyFunction())));
- } else {
- return new FilteredKeyMultimap<K, V>(unfiltered, keyPredicate);
- }
+ Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
+ checkNotNull(keyPredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return keyPredicate.apply(input.getKey());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -2094,8 +2201,8 @@ public final class Multimaps {
* <p>The resulting multimap's views have iterators that don't support
* {@code remove()}, but all other methods are supported by the multimap and
* its views. When adding a value that doesn't satisfy the predicate, the
- * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
- * methods throw an {@link IllegalArgumentException}.
+ * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods
+ * throw an {@link IllegalArgumentException}.
*
* <p>When methods such as {@code removeAll()} and {@code clear()} are called on
* the filtered multimap or its views, only mappings whose value satisfy the
@@ -2116,10 +2223,19 @@ public final class Multimaps {
*
* @since 11.0
*/
+ @Beta
@GwtIncompatible(value = "untested")
public static <K, V> Multimap<K, V> filterValues(
- Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
- return filterEntries(unfiltered, Predicates.compose(valuePredicate, Maps.<V>valueFunction()));
+ Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
+ checkNotNull(valuePredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return valuePredicate.apply(input.getValue());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
}
/**
@@ -2130,8 +2246,8 @@ public final class Multimaps {
* <p>The resulting multimap's views have iterators that don't support
* {@code remove()}, but all other methods are supported by the multimap and
* its views. When adding a key/value pair that doesn't satisfy the predicate,
- * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
- * methods throw an {@link IllegalArgumentException}.
+ * multimap's {@code put()}, {@code putAll()}, and {@replaceValues()} methods
+ * throw an {@link IllegalArgumentException}.
*
* <p>When methods such as {@code removeAll()} and {@code clear()} are called on
* the filtered multimap or its views, only mappings whose keys satisfy the
@@ -2150,27 +2266,489 @@ public final class Multimaps {
*
* @since 11.0
*/
+ @Beta
@GwtIncompatible(value = "untested")
public static <K, V> Multimap<K, V> filterEntries(
- Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
+ Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
checkNotNull(entryPredicate);
return (unfiltered instanceof FilteredMultimap)
? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate)
- : new FilteredEntryMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
+ : new FilteredMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
}
/**
* Support removal operations when filtering a filtered multimap. Since a
* filtered multimap has iterators that don't support remove, passing one to
- * the FilteredEntryMultimap constructor would lead to a multimap whose removal
+ * the FilteredMultimap constructor would lead to a multimap whose removal
* operations would fail. This method combines the predicates to avoid that
* problem.
*/
- private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> multimap,
+ private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> map,
Predicate<? super Entry<K, V>> entryPredicate) {
Predicate<Entry<K, V>> predicate
- = Predicates.and(multimap.entryPredicate(), entryPredicate);
- return new FilteredEntryMultimap<K, V>(multimap.unfiltered, predicate);
+ = Predicates.and(map.predicate, entryPredicate);
+ return new FilteredMultimap<K, V>(map.unfiltered, predicate);
+ }
+
+ private static class FilteredMultimap<K, V> implements Multimap<K, V> {
+ final Multimap<K, V> unfiltered;
+ final Predicate<? super Entry<K, V>> predicate;
+
+ FilteredMultimap(Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> predicate) {
+ this.unfiltered = unfiltered;
+ this.predicate = predicate;
+ }
+
+ @Override public int size() {
+ return entries().size();
+ }
+
+ @Override public boolean isEmpty() {
+ return entries().isEmpty();
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return asMap().containsKey(key);
+ }
+
+ @Override public boolean containsValue(Object value) {
+ return values().contains(value);
+ }
+
+ // This method should be called only when key is a K and value is a V.
+ @SuppressWarnings("unchecked")
+ boolean satisfiesPredicate(Object key, Object value) {
+ return predicate.apply(Maps.immutableEntry((K) key, (V) value));
+ }
+
+ @Override public boolean containsEntry(Object key, Object value) {
+ return unfiltered.containsEntry(key, value) && satisfiesPredicate(key, value);
+ }
+
+ @Override public boolean put(K key, V value) {
+ checkArgument(satisfiesPredicate(key, value));
+ return unfiltered.put(key, value);
+ }
+
+ @Override public boolean remove(Object key, Object value) {
+ return containsEntry(key, value) ? unfiltered.remove(key, value) : false;
+ }
+
+ @Override public boolean putAll(K key, Iterable<? extends V> values) {
+ for (V value : values) {
+ checkArgument(satisfiesPredicate(key, value));
+ }
+ return unfiltered.putAll(key, values);
+ }
+
+ @Override public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
+ for (Entry<? extends K, ? extends V> entry : multimap.entries()) {
+ checkArgument(satisfiesPredicate(entry.getKey(), entry.getValue()));
+ }
+ return unfiltered.putAll(multimap);
+ }
+
+ @Override public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
+ for (V value : values) {
+ checkArgument(satisfiesPredicate(key, value));
+ }
+ // Not calling unfiltered.replaceValues() since values that don't satisify
+ // the filter should remain in the multimap.
+ Collection<V> oldValues = removeAll(key);
+ unfiltered.putAll(key, values);
+ return oldValues;
+ }
+
+ @Override public Collection<V> removeAll(Object key) {
+ List<V> removed = Lists.newArrayList();
+ Collection<V> values = unfiltered.asMap().get(key);
+ if (values != null) {
+ Iterator<V> iterator = values.iterator();
+ while (iterator.hasNext()) {
+ V value = iterator.next();
+ if (satisfiesPredicate(key, value)) {
+ removed.add(value);
+ iterator.remove();
+ }
+ }
+ }
+ if (unfiltered instanceof SetMultimap) {
+ return Collections.unmodifiableSet(Sets.newLinkedHashSet(removed));
+ } else {
+ return Collections.unmodifiableList(removed);
+ }
+ }
+
+ @Override public void clear() {
+ entries().clear();
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Multimap) {
+ Multimap<?, ?> that = (Multimap<?, ?>) object;
+ return asMap().equals(that.asMap());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return asMap().hashCode();
+ }
+
+ @Override public String toString() {
+ return asMap().toString();
+ }
+
+ class ValuePredicate implements Predicate<V> {
+ final K key;
+ ValuePredicate(K key) {
+ this.key = key;
+ }
+ @Override public boolean apply(V value) {
+ return satisfiesPredicate(key, value);
+ }
+ }
+
+ Collection<V> filterCollection(Collection<V> collection, Predicate<V> predicate) {
+ if (collection instanceof Set) {
+ return Sets.filter((Set<V>) collection, predicate);
+ } else {
+ return Collections2.filter(collection, predicate);
+ }
+ }
+
+ @Override public Collection<V> get(K key) {
+ return filterCollection(unfiltered.get(key), new ValuePredicate(key));
+ }
+
+ @Override public Set<K> keySet() {
+ return asMap().keySet();
+ }
+
+ Collection<V> values;
+
+ @Override public Collection<V> values() {
+ return (values == null) ? values = new Values() : values;
+ }
+
+ class Values extends Multimaps.Values<K, V> {
+ @Override Multimap<K, V> multimap() {
+ return FilteredMultimap.this;
+ }
+
+ @Override public boolean contains(@Nullable Object o) {
+ return Iterators.contains(iterator(), o);
+ }
+
+ // Override remove methods since iterator doesn't support remove.
+
+ @Override public boolean remove(Object o) {
+ Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
+ while (iterator.hasNext()) {
+ Entry<K, V> entry = iterator.next();
+ if (Objects.equal(o, entry.getValue()) && predicate.apply(entry)) {
+ iterator.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ boolean changed = false;
+ Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
+ while (iterator.hasNext()) {
+ Entry<K, V> entry = iterator.next();
+ if (c.contains(entry.getValue()) && predicate.apply(entry)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override public boolean retainAll(Collection<?> c) {
+ boolean changed = false;
+ Iterator<Entry<K, V>> iterator = unfiltered.entries().iterator();
+ while (iterator.hasNext()) {
+ Entry<K, V> entry = iterator.next();
+ if (!c.contains(entry.getValue()) && predicate.apply(entry)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+ }
+
+ Collection<Entry<K, V>> entries;
+
+ @Override public Collection<Entry<K, V>> entries() {
+ return (entries == null)
+ ? entries = Collections2.filter(unfiltered.entries(), predicate)
+ : entries;
+ }
+
+ /**
+ * Remove all filtered asMap() entries that satisfy the predicate.
+ */
+ boolean removeEntriesIf(Predicate<Map.Entry<K, Collection<V>>> removalPredicate) {
+ Iterator<Map.Entry<K, Collection<V>>> iterator = unfiltered.asMap().entrySet().iterator();
+ boolean changed = false;
+ while (iterator.hasNext()) {
+ // Determine whether to remove the filtered values with this key.
+ Map.Entry<K, Collection<V>> entry = iterator.next();
+ K key = entry.getKey();
+ Collection<V> collection = entry.getValue();
+ Predicate<V> valuePredicate = new ValuePredicate(key);
+ Collection<V> filteredCollection = filterCollection(collection, valuePredicate);
+ Map.Entry<K, Collection<V>> filteredEntry = Maps.immutableEntry(key, filteredCollection);
+ if (removalPredicate.apply(filteredEntry) && !filteredCollection.isEmpty()) {
+ changed = true;
+ if (Iterables.all(collection, valuePredicate)) {
+ iterator.remove(); // Remove all values for the key.
+ } else {
+ filteredCollection.clear(); // Remove the filtered values only.
+ }
+ }
+ }
+ return changed;
+ }
+
+ Map<K, Collection<V>> asMap;
+
+ @Override public Map<K, Collection<V>> asMap() {
+ return (asMap == null) ? asMap = createAsMap() : asMap;
+ }
+
+ static final Predicate<Collection<?>> NOT_EMPTY = new Predicate<Collection<?>>() {
+ @Override public boolean apply(Collection<?> input) {
+ return !input.isEmpty();
+ }
+ };
+
+ Map<K, Collection<V>> createAsMap() {
+ // Select the values that satisify the predicate.
+ EntryTransformer<K, Collection<V>, Collection<V>> transformer
+ = new EntryTransformer<K, Collection<V>, Collection<V>>() {
+ @Override public Collection<V> transformEntry(K key, Collection<V> collection) {
+ return filterCollection(collection, new ValuePredicate(key));
+ }
+ };
+ Map<K, Collection<V>> transformed
+ = Maps.transformEntries(unfiltered.asMap(), transformer);
+
+ // Select the keys that have at least one value remaining.
+ Map<K, Collection<V>> filtered = Maps.filterValues(transformed, NOT_EMPTY);
+
+ // Override the removal methods, since removing a map entry should not
+ // affect values that don't satisfy the filter.
+ return new AsMap(filtered);
+ }
+
+ class AsMap extends ForwardingMap<K, Collection<V>> {
+ final Map<K, Collection<V>> delegate;
+
+ AsMap(Map<K, Collection<V>> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override protected Map<K, Collection<V>> delegate() {
+ return delegate;
+ }
+
+ @Override public Collection<V> remove(Object o) {
+ Collection<V> output = FilteredMultimap.this.removeAll(o);
+ return output.isEmpty() ? null : output;
+ }
+
+ @Override public void clear() {
+ FilteredMultimap.this.clear();
+ }
+
+ Set<K> keySet;
+
+ @Override public Set<K> keySet() {
+ return (keySet == null) ? keySet = new KeySet() : keySet;
+ }
+
+ class KeySet extends Maps.KeySet<K, Collection<V>> {
+ @Override Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public boolean remove(Object o) {
+ Collection<V> collection = delegate.get(o);
+ if (collection == null) {
+ return false;
+ }
+ collection.clear();
+ return true;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Sets.removeAllImpl(this, c);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return !c.contains(entry.getKey());
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+
+ Values asMapValues;
+
+ @Override public Collection<Collection<V>> values() {
+ return (asMapValues == null) ? asMapValues = new Values() : asMapValues;
+ }
+
+ class Values extends Maps.Values<K, Collection<V>> {
+ @Override Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public boolean remove(Object o) {
+ for (Collection<V> collection : this) {
+ if (collection.equals(o)) {
+ collection.clear();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean removeAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return c.contains(entry.getValue());
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return !c.contains(entry.getValue());
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+
+ EntrySet entrySet;
+
+ @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
+ return (entrySet == null) ? entrySet = new EntrySet(super.entrySet()) : entrySet;
+ }
+
+ class EntrySet extends Maps.EntrySet<K, Collection<V>> {
+ Set<Map.Entry<K, Collection<V>>> delegateEntries;
+
+ public EntrySet(Set<Map.Entry<K, Collection<V>>> delegateEntries) {
+ this.delegateEntries = delegateEntries;
+ }
+
+ @Override Map<K, Collection<V>> map() {
+ return AsMap.this;
+ }
+
+ @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
+ return delegateEntries.iterator();
+ }
+
+ @Override public boolean remove(Object o) {
+ if (o instanceof Entry<?, ?>) {
+ Entry<?, ?> entry = (Entry<?, ?>) o;
+ Collection<V> collection = delegate.get(entry.getKey());
+ if (collection != null && collection.equals(entry.getValue())) {
+ collection.clear();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean removeAll(Collection<?> c) {
+ return Sets.removeAllImpl(this, c);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ return !c.contains(entry);
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+ }
+
+ AbstractMultiset<K> keys;
+
+ @Override public Multiset<K> keys() {
+ return (keys == null) ? keys = new Keys() : keys;
+ }
+
+ class Keys extends Multimaps.Keys<K, V> {
+ @Override Multimap<K, V> multimap() {
+ return FilteredMultimap.this;
+ }
+
+ @Override public int remove(Object o, int occurrences) {
+ checkArgument(occurrences >= 0);
+ Collection<V> values = unfiltered.asMap().get(o);
+ if (values == null) {
+ return 0;
+ }
+ int priorCount = 0;
+ int removed = 0;
+ Iterator<V> iterator = values.iterator();
+ while (iterator.hasNext()) {
+ if (satisfiesPredicate(o, iterator.next())) {
+ priorCount++;
+ if (removed < occurrences) {
+ iterator.remove();
+ removed++;
+ }
+ }
+ }
+ return priorCount;
+ }
+
+ @Override Set<Multiset.Entry<K>> createEntrySet() {
+ return new EntrySet();
+ }
+
+ class EntrySet extends Multimaps.Keys<K, V>.KeysEntrySet {
+ @Override public boolean removeAll(Collection<?> c) {
+ return Sets.removeAllImpl(this, c);
+ }
+
+ @Override public boolean retainAll(final Collection<?> c) {
+ Predicate<Map.Entry<K, Collection<V>>> removalPredicate
+ = new Predicate<Map.Entry<K, Collection<V>>>() {
+ @Override public boolean apply(Map.Entry<K, Collection<V>> entry) {
+ Multiset.Entry<K> multisetEntry
+ = Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
+ return !c.contains(multisetEntry);
+ }
+ };
+ return removeEntriesIf(removalPredicate);
+ }
+ }
+ }
}
// TODO(jlevy): Create methods that filter a SetMultimap or SortedSetMultimap.
diff --git a/guava/src/com/google/common/collect/Multiset.java b/guava/src/com/google/common/collect/Multiset.java
index bb254c9..823750e 100644
--- a/guava/src/com/google/common/collect/Multiset.java
+++ b/guava/src/com/google/common/collect/Multiset.java
@@ -31,13 +31,13 @@ import javax.annotation.Nullable;
* may have duplicate elements. A multiset is also sometimes called a
* <i>bag</i>.
*
- * <p>Elements of a multiset that are equal to one another are referred to as
- * <i>occurrences</i> of the same single element. The total number of
- * occurrences of an element in a multiset is called the <i>count</i> of that
- * element (the terms "frequency" and "multiplicity" are equivalent, but not
- * used in this API). Since the count of an element is represented as an {@code
- * int}, a multiset may never contain more than {@link Integer#MAX_VALUE}
- * occurrences of any one element.
+ * <p>Elements of a multiset that are equal to one another (see "Note on
+ * element equivalence", below) are referred to as <i>occurrences</i> of the
+ * same single element. The total number of occurrences of an element in a
+ * multiset is called the <i>count</i> of that element (the terms "frequency"
+ * and "multiplicity" are equivalent, but not used in this API). Since the count
+ * of an element is represented as an {@code int}, a multiset may never contain
+ * more than {@link Integer#MAX_VALUE} occurrences of any one element.
*
* <p>{@code Multiset} refines the specifications of several methods from
* {@code Collection}. It also defines an additional query operation, {@link
@@ -77,10 +77,6 @@ import javax.annotation.Nullable;
* may wish to use {@link com.google.common.util.concurrent.AtomicLongMap}
* instead. Note, however, that unlike {@code Multiset}, {@code AtomicLongMap}
* does not automatically remove zeros.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
*
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
diff --git a/guava/src/com/google/common/collect/Multisets.java b/guava/src/com/google/common/collect/Multisets.java
index d0ab028..dbd54c3 100644
--- a/guava/src/com/google/common/collect/Multisets.java
+++ b/guava/src/com/google/common/collect/Multisets.java
@@ -18,33 +18,32 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Multiset.Entry;
-import com.google.common.primitives.Ints;
+import static com.google.common.base.Preconditions.checkState;
import java.io.Serializable;
+import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.SortedSet;
import javax.annotation.Nullable;
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.collect.Multiset.Entry;
+import com.google.common.primitives.Ints;
+
/**
* Provides static utility methods for creating and working with {@link
* Multiset} instances.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multisets">
- * {@code Multisets}</a>.
- *
* @author Kevin Bourrillion
* @author Mike Bostock
* @author Louis Wasserman
@@ -194,10 +193,92 @@ public final class Multisets {
@Beta
public static <E> SortedMultiset<E> unmodifiableSortedMultiset(
SortedMultiset<E> sortedMultiset) {
- // it's in its own file so it can be emulated for GWT
return new UnmodifiableSortedMultiset<E>(checkNotNull(sortedMultiset));
}
+ private static final class UnmodifiableSortedMultiset<E>
+ extends UnmodifiableMultiset<E> implements SortedMultiset<E> {
+ private UnmodifiableSortedMultiset(SortedMultiset<E> delegate) {
+ super(delegate);
+ }
+
+ @Override
+ protected SortedMultiset<E> delegate() {
+ return (SortedMultiset<E>) super.delegate();
+ }
+
+ @Override
+ public Comparator<? super E> comparator() {
+ return delegate().comparator();
+ }
+
+ @Override
+ SortedSet<E> createElementSet() {
+ return Collections.unmodifiableSortedSet(delegate().elementSet());
+ }
+
+ @Override
+ public SortedSet<E> elementSet() {
+ return (SortedSet<E>) super.elementSet();
+ }
+
+ private transient UnmodifiableSortedMultiset<E> descendingMultiset;
+
+ @Override
+ public SortedMultiset<E> descendingMultiset() {
+ UnmodifiableSortedMultiset<E> result = descendingMultiset;
+ if (result == null) {
+ result = new UnmodifiableSortedMultiset<E>(
+ delegate().descendingMultiset());
+ result.descendingMultiset = this;
+ return descendingMultiset = result;
+ }
+ return result;
+ }
+
+ @Override
+ public Entry<E> firstEntry() {
+ return delegate().firstEntry();
+ }
+
+ @Override
+ public Entry<E> lastEntry() {
+ return delegate().lastEntry();
+ }
+
+ @Override
+ public Entry<E> pollFirstEntry() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Entry<E> pollLastEntry() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
+ return unmodifiableSortedMultiset(
+ delegate().headMultiset(upperBound, boundType));
+ }
+
+ @Override
+ public SortedMultiset<E> subMultiset(
+ E lowerBound, BoundType lowerBoundType,
+ E upperBound, BoundType upperBoundType) {
+ return unmodifiableSortedMultiset(delegate().subMultiset(
+ lowerBound, lowerBoundType, upperBound, upperBoundType));
+ }
+
+ @Override
+ public SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
+ return unmodifiableSortedMultiset(
+ delegate().tailMultiset(lowerBound, boundType));
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
/**
* Returns an immutable multiset entry with the specified element and count.
* The entry will be serializable if {@code e} is.
@@ -235,125 +316,152 @@ public final class Multisets {
}
/**
- * Returns a view of the elements of {@code unfiltered} that satisfy a predicate. The returned
- * multiset is a live view of {@code unfiltered}; changes to one affect the other.
- *
- * <p>The resulting multiset's iterators, and those of its {@code entrySet()} and
- * {@code elementSet()}, do not support {@code remove()}. However, all other multiset methods
- * supported by {@code unfiltered} are supported by the returned multiset. When given an element
- * that doesn't satisfy the predicate, the multiset's {@code add()} and {@code addAll()} methods
- * throw an {@link IllegalArgumentException}. When methods such as {@code removeAll()} and
- * {@code clear()} are called on the filtered multiset, only elements that satisfy the filter
- * will be removed from the underlying multiset.
+ * Returns a multiset view of the specified set. The multiset is backed by the
+ * set, so changes to the set are reflected in the multiset, and vice versa.
+ * If the set is modified while an iteration over the multiset is in progress
+ * (except through the iterator's own {@code remove} operation) the results of
+ * the iteration are undefined.
*
- * <p>The returned multiset isn't threadsafe or serializable, even if {@code unfiltered} is.
+ * <p>The multiset supports element removal, which removes the corresponding
+ * element from the set. It does not support the {@code add} or {@code addAll}
+ * operations, nor does it support the use of {@code setCount} to add
+ * elements.
*
- * <p>Many of the filtered multiset's methods, such as {@code size()}, iterate across every
- * element in the underlying multiset and determine which elements satisfy the filter. When a
- * live view is <i>not</i> needed, it may be faster to copy the returned multiset and use the
- * copy.
+ * <p>The returned multiset will be serializable if the specified set is
+ * serializable. The multiset is threadsafe if the set is threadsafe.
*
- * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>, as documented at
- * {@link Predicate#apply}. Do not provide a predicate such as
- * {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent with equals. (See
- * {@link Iterables#filter(Iterable, Class)} for related functionality.)
- *
- * @since 14.0
+ * @param set the backing set for the returned multiset view
*/
- @Beta
- public static <E> Multiset<E> filter(Multiset<E> unfiltered, Predicate<? super E> predicate) {
- if (unfiltered instanceof FilteredMultiset) {
- // Support clear(), removeAll(), and retainAll() when filtering a filtered
- // collection.
- FilteredMultiset<E> filtered = (FilteredMultiset<E>) unfiltered;
- Predicate<E> combinedPredicate
- = Predicates.<E>and(filtered.predicate, predicate);
- return new FilteredMultiset<E>(filtered.unfiltered, combinedPredicate);
- }
- return new FilteredMultiset<E>(unfiltered, predicate);
+ static <E> Multiset<E> forSet(Set<E> set) {
+ return new SetMultiset<E>(set);
}
- private static final class FilteredMultiset<E> extends AbstractMultiset<E> {
- final Multiset<E> unfiltered;
- final Predicate<? super E> predicate;
+ /** @see Multisets#forSet */
+ private static class SetMultiset<E> extends ForwardingCollection<E>
+ implements Multiset<E>, Serializable {
+ final Set<E> delegate;
- FilteredMultiset(Multiset<E> unfiltered, Predicate<? super E> predicate) {
- this.unfiltered = checkNotNull(unfiltered);
- this.predicate = checkNotNull(predicate);
+ SetMultiset(Set<E> set) {
+ delegate = checkNotNull(set);
}
- @Override
- Set<E> createElementSet() {
- return Sets.filter(unfiltered.elementSet(), predicate);
+ @Override protected Set<E> delegate() {
+ return delegate;
}
@Override
- Set<Entry<E>> createEntrySet() {
- return Sets.filter(unfiltered.entrySet(), new Predicate<Entry<E>>() {
- @Override
- public boolean apply(Entry<E> entry) {
- return predicate.apply(entry.getElement());
- }
- });
+ public int count(Object element) {
+ return delegate.contains(element) ? 1 : 0;
}
@Override
- Iterator<Entry<E>> entryIterator() {
- throw new AssertionError("should never be called");
+ public int add(E element, int occurrences) {
+ throw new UnsupportedOperationException();
}
@Override
- int distinctElements() {
- return elementSet().size();
+ public int remove(Object element, int occurrences) {
+ if (occurrences == 0) {
+ return count(element);
+ }
+ checkArgument(occurrences > 0);
+ return delegate.remove(element) ? 1 : 0;
}
+ transient Set<E> elementSet;
+
@Override
- public boolean contains(@Nullable Object element) {
- return count(element) > 0;
+ public Set<E> elementSet() {
+ Set<E> es = elementSet;
+ return (es == null) ? elementSet = new ElementSet() : es;
}
- @Override
- public int count(@Nullable Object element) {
- int count = unfiltered.count(element);
- if (count > 0) {
- @SuppressWarnings("unchecked") // element is equal to an E
- E e = (E) element;
- return predicate.apply(e) ? count : 0;
+ transient Set<Entry<E>> entrySet;
+
+ @Override public Set<Entry<E>> entrySet() {
+ Set<Entry<E>> es = entrySet;
+ if (es == null) {
+ es = entrySet = new EntrySet<E>() {
+ @Override Multiset<E> multiset() {
+ return SetMultiset.this;
+ }
+
+ @Override public Iterator<Entry<E>> iterator() {
+ return Iterators.transform(delegate.iterator(),
+ new Function<E, Entry<E>>() {
+ @Override public Entry<E> apply(E elem) {
+ return immutableEntry(elem, 1);
+ }
+ });
+ }
+
+ @Override public int size() {
+ return delegate.size();
+ }
+ };
}
- return 0;
+ return es;
}
- @Override
- public int add(@Nullable E element, int occurrences) {
- checkArgument(predicate.apply(element),
- "Element %s does not match predicate %s", element, predicate);
- return unfiltered.add(element, occurrences);
+ @Override public boolean add(E o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean addAll(Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
}
@Override
- public int remove(@Nullable Object element, int occurrences) {
- Multisets.checkNonnegative(occurrences, "occurrences");
- if (occurrences == 0) {
- return count(element);
+ public int setCount(E element, int count) {
+ checkNonnegative(count, "count");
+
+ if (count == count(element)) {
+ return count;
+ } else if (count == 0) {
+ remove(element);
+ return 1;
} else {
- return contains(element) ? unfiltered.remove(element, occurrences) : 0;
+ throw new UnsupportedOperationException();
}
}
@Override
- public boolean removeAll(Collection<?> c) {
- return elementSet().removeAll(c);
+ public boolean setCount(E element, int oldCount, int newCount) {
+ return setCountImpl(this, element, oldCount, newCount);
}
- @Override
- public boolean retainAll(Collection<?> c) {
- return elementSet().retainAll(c);
+ @Override public boolean equals(@Nullable Object object) {
+ if (object instanceof Multiset) {
+ Multiset<?> that = (Multiset<?>) object;
+ return this.size() == that.size() && delegate.equals(that.elementSet());
+ }
+ return false;
}
- @Override
- public void clear() {
- elementSet().clear();
+ @Override public int hashCode() {
+ int sum = 0;
+ for (E e : this) {
+ sum += ((e == null) ? 0 : e.hashCode()) ^ 1;
+ }
+ return sum;
+ }
+
+ /** @see SetMultiset#elementSet */
+ class ElementSet extends ForwardingSet<E> {
+ @Override protected Set<E> delegate() {
+ return delegate;
+ }
+
+ @Override public boolean add(E o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override public boolean addAll(Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
}
+
+ private static final long serialVersionUID = 0;
}
/**
@@ -370,93 +478,16 @@ public final class Multisets {
}
/**
- * Returns an unmodifiable view of the union of two multisets.
- * In the returned multiset, the count of each element is the <i>maximum</i>
- * of its counts in the two backing multisets. The iteration order of the
- * returned multiset matches that of the element set of {@code multiset1}
- * followed by the members of the element set of {@code multiset2} that are
- * not contained in {@code multiset1}, with repeated occurrences of the same
+ * Returns an unmodifiable <b>view</b> of the intersection of two multisets.
+ * An element's count in the multiset is the smaller of its counts in the two
+ * backing multisets. The iteration order of the returned multiset matches the
+ * element set of {@code multiset1}, with repeated occurrences of the same
* element appearing consecutively.
*
* <p>Results are undefined if {@code multiset1} and {@code multiset2} are
* based on different equivalence relations (as {@code HashMultiset} and
* {@code TreeMultiset} are).
*
- * @since 14.0
- */
- @Beta
- public static <E> Multiset<E> union(
- final Multiset<? extends E> multiset1, final Multiset<? extends E> multiset2) {
- checkNotNull(multiset1);
- checkNotNull(multiset2);
-
- return new AbstractMultiset<E>() {
- @Override
- public boolean contains(@Nullable Object element) {
- return multiset1.contains(element) || multiset2.contains(element);
- }
-
- @Override
- public boolean isEmpty() {
- return multiset1.isEmpty() && multiset2.isEmpty();
- }
-
- @Override
- public int count(Object element) {
- return Math.max(multiset1.count(element), multiset2.count(element));
- }
-
- @Override
- Set<E> createElementSet() {
- return Sets.union(multiset1.elementSet(), multiset2.elementSet());
- }
-
- @Override
- Iterator<Entry<E>> entryIterator() {
- final Iterator<? extends Entry<? extends E>> iterator1
- = multiset1.entrySet().iterator();
- final Iterator<? extends Entry<? extends E>> iterator2
- = multiset2.entrySet().iterator();
- return new AbstractIterator<Entry<E>>() {
- @Override
- protected Entry<E> computeNext() {
- if (iterator1.hasNext()) {
- Entry<? extends E> entry1 = iterator1.next();
- E element = entry1.getElement();
- int count = Math.max(entry1.getCount(), multiset2.count(element));
- return immutableEntry(element, count);
- }
- while (iterator2.hasNext()) {
- Entry<? extends E> entry2 = iterator2.next();
- E element = entry2.getElement();
- if (!multiset1.contains(element)) {
- return immutableEntry(element, entry2.getCount());
- }
- }
- return endOfData();
- }
- };
- }
-
- @Override
- int distinctElements() {
- return elementSet().size();
- }
- };
- }
-
- /**
- * Returns an unmodifiable view of the intersection of two multisets.
- * In the returned multiset, the count of each element is the <i>minimum</i>
- * of its counts in the two backing multisets, with elements that would have
- * a count of 0 not included. The iteration order of the returned multiset
- * matches that of the element set of {@code multiset1}, with repeated
- * occurrences of the same element appearing consecutively.
- *
- * <p>Results are undefined if {@code multiset1} and {@code multiset2} are
- * based on different equivalence relations (as {@code HashMultiset} and
- * {@code TreeMultiset} are).
- *
* @since 2.0
*/
public static <E> Multiset<E> intersection(
@@ -488,88 +519,7 @@ public final class Multisets {
E element = entry1.getElement();
int count = Math.min(entry1.getCount(), multiset2.count(element));
if (count > 0) {
- return immutableEntry(element, count);
- }
- }
- return endOfData();
- }
- };
- }
-
- @Override
- int distinctElements() {
- return elementSet().size();
- }
- };
- }
-
- /**
- * Returns an unmodifiable view of the sum of two multisets.
- * In the returned multiset, the count of each element is the <i>sum</i> of
- * its counts in the two backing multisets. The iteration order of the
- * returned multiset matches that of the element set of {@code multiset1}
- * followed by the members of the element set of {@code multiset2} that that
- * are not contained in {@code multiset1}, with repeated occurrences of the
- * same element appearing consecutively.
- *
- * <p>Results are undefined if {@code multiset1} and {@code multiset2} are
- * based on different equivalence relations (as {@code HashMultiset} and
- * {@code TreeMultiset} are).
- *
- * @since 14.0
- */
- @Beta
- public static <E> Multiset<E> sum(
- final Multiset<? extends E> multiset1, final Multiset<? extends E> multiset2) {
- checkNotNull(multiset1);
- checkNotNull(multiset2);
-
- return new AbstractMultiset<E>() {
- @Override
- public boolean contains(@Nullable Object element) {
- return multiset1.contains(element) || multiset2.contains(element);
- }
-
- @Override
- public boolean isEmpty() {
- return multiset1.isEmpty() && multiset2.isEmpty();
- }
-
- @Override
- public int size() {
- return multiset1.size() + multiset2.size();
- }
-
- @Override
- public int count(Object element) {
- return multiset1.count(element) + multiset2.count(element);
- }
-
- @Override
- Set<E> createElementSet() {
- return Sets.union(multiset1.elementSet(), multiset2.elementSet());
- }
-
- @Override
- Iterator<Entry<E>> entryIterator() {
- final Iterator<? extends Entry<? extends E>> iterator1
- = multiset1.entrySet().iterator();
- final Iterator<? extends Entry<? extends E>> iterator2
- = multiset2.entrySet().iterator();
- return new AbstractIterator<Entry<E>>() {
- @Override
- protected Entry<E> computeNext() {
- if (iterator1.hasNext()) {
- Entry<? extends E> entry1 = iterator1.next();
- E element = entry1.getElement();
- int count = entry1.getCount() + multiset2.count(element);
- return immutableEntry(element, count);
- }
- while (iterator2.hasNext()) {
- Entry<? extends E> entry2 = iterator2.next();
- E element = entry2.getElement();
- if (!multiset1.contains(element)) {
- return immutableEntry(element, entry2.getCount());
+ return Multisets.immutableEntry(element, count);
}
}
return endOfData();
@@ -585,66 +535,12 @@ public final class Multisets {
}
/**
- * Returns an unmodifiable view of the difference of two multisets.
- * In the returned multiset, the count of each element is the result of the
- * <i>zero-truncated subtraction</i> of its count in the second multiset from
- * its count in the first multiset, with elements that would have a count of
- * 0 not included. The iteration order of the returned multiset matches that
- * of the element set of {@code multiset1}, with repeated occurrences of the
- * same element appearing consecutively.
- *
- * <p>Results are undefined if {@code multiset1} and {@code multiset2} are
- * based on different equivalence relations (as {@code HashMultiset} and
- * {@code TreeMultiset} are).
- *
- * @since 14.0
- */
- @Beta
- public static <E> Multiset<E> difference(
- final Multiset<E> multiset1, final Multiset<?> multiset2) {
- checkNotNull(multiset1);
- checkNotNull(multiset2);
-
- return new AbstractMultiset<E>() {
- @Override
- public int count(@Nullable Object element) {
- int count1 = multiset1.count(element);
- return (count1 == 0) ? 0 :
- Math.max(0, count1 - multiset2.count(element));
- }
-
- @Override
- Iterator<Entry<E>> entryIterator() {
- final Iterator<Entry<E>> iterator1 = multiset1.entrySet().iterator();
- return new AbstractIterator<Entry<E>>() {
- @Override
- protected Entry<E> computeNext() {
- while (iterator1.hasNext()) {
- Entry<E> entry1 = iterator1.next();
- E element = entry1.getElement();
- int count = entry1.getCount() - multiset2.count(element);
- if (count > 0) {
- return immutableEntry(element, count);
- }
- }
- return endOfData();
- }
- };
- }
-
- @Override
- int distinctElements() {
- return Iterators.size(entryIterator());
- }
- };
- }
-
- /**
* Returns {@code true} if {@code subMultiset.count(o) <=
* superMultiset.count(o)} for all {@code o}.
*
* @since 10.0
*/
+ @Beta
public static boolean containsOccurrences(
Multiset<?> superMultiset, Multiset<?> subMultiset) {
checkNotNull(superMultiset);
@@ -677,7 +573,7 @@ public final class Multisets {
* of this operation
* @since 10.0
*/
- public static boolean retainOccurrences(Multiset<?> multisetToModify,
+ @Beta public static boolean retainOccurrences(Multiset<?> multisetToModify,
Multiset<?> multisetToRetain) {
return retainOccurrencesImpl(multisetToModify, multisetToRetain);
}
@@ -729,7 +625,7 @@ public final class Multisets {
* this operation
* @since 10.0
*/
- public static boolean removeOccurrences(
+ @Beta public static boolean removeOccurrences(
Multiset<?> multisetToModify, Multiset<?> occurrencesToRemove) {
return removeOccurrencesImpl(multisetToModify, occurrencesToRemove);
}
@@ -864,7 +760,6 @@ public final class Multisets {
*/
static boolean retainAllImpl(
Multiset<?> self, Collection<?> elementsToRetain) {
- checkNotNull(elementsToRetain);
Collection<?> collection = (elementsToRetain instanceof Multiset)
? ((Multiset<?>) elementsToRetain).elementSet() : elementsToRetain;
@@ -905,7 +800,7 @@ public final class Multisets {
}
}
- abstract static class ElementSet<E> extends Sets.ImprovedAbstractSet<E> {
+ static abstract class ElementSet<E> extends AbstractSet<E> {
abstract Multiset<E> multiset();
@Override public void clear() {
@@ -925,12 +820,12 @@ public final class Multisets {
}
@Override public Iterator<E> iterator() {
- return new TransformedIterator<Entry<E>, E>(multiset().entrySet().iterator()) {
- @Override
- E transform(Entry<E> entry) {
- return entry.getElement();
- }
- };
+ return Iterators.transform(multiset().entrySet().iterator(),
+ new Function<Entry<E>, E>() {
+ @Override public E apply(Entry<E> entry) {
+ return entry.getElement();
+ }
+ });
}
@Override
@@ -948,14 +843,11 @@ public final class Multisets {
}
}
- abstract static class EntrySet<E> extends Sets.ImprovedAbstractSet<Entry<E>> {
+ static abstract class EntrySet<E> extends AbstractSet<Entry<E>>{
abstract Multiset<E> multiset();
@Override public boolean contains(@Nullable Object o) {
if (o instanceof Entry) {
- /*
- * The GWT compiler wrongly issues a warning here.
- */
@SuppressWarnings("cast")
Entry<?> entry = (Entry<?>) o;
if (entry.getCount() <= 0) {
@@ -968,21 +860,10 @@ public final class Multisets {
return false;
}
- // GWT compiler warning; see contains().
@SuppressWarnings("cast")
- @Override public boolean remove(Object object) {
- if (object instanceof Multiset.Entry) {
- Entry<?> entry = (Entry<?>) object;
- Object element = entry.getElement();
- int entryCount = entry.getCount();
- if (entryCount != 0) {
- // Safe as long as we never add a new entry, which we won't.
- @SuppressWarnings("unchecked")
- Multiset<Object> multiset = (Multiset) multiset();
- return multiset.setCount(element, entryCount, 0);
- }
- }
- return false;
+ @Override public boolean remove(Object o) {
+ return contains(o)
+ && multiset().elementSet().remove(((Entry<?>) o).getElement());
}
@Override public void clear() {
@@ -1035,7 +916,8 @@ public final class Multisets {
@Override
public void remove() {
- Iterators.checkRemove(canRemove);
+ checkState(
+ canRemove, "no calls to next() since the last call to remove()");
if (totalCount == 1) {
entryIterator.remove();
} else {
diff --git a/guava/src/com/google/common/collect/MutableClassToInstanceMap.java b/guava/src/com/google/common/collect/MutableClassToInstanceMap.java
index c723cea..b40e801 100644
--- a/guava/src/com/google/common/collect/MutableClassToInstanceMap.java
+++ b/guava/src/com/google/common/collect/MutableClassToInstanceMap.java
@@ -25,10 +25,6 @@ import java.util.Map;
/**
* A mutable class-to-instance map backed by an arbitrary user-provided map.
* See also {@link ImmutableClassToInstanceMap}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#ClassToInstanceMap">
- * {@code ClassToInstanceMap}</a>.
*
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
diff --git a/guava/src/com/google/common/collect/ObjectArrays.java b/guava/src/com/google/common/collect/ObjectArrays.java
index dfd1fe9..954a30e 100644
--- a/guava/src/com/google/common/collect/ObjectArrays.java
+++ b/guava/src/com/google/common/collect/ObjectArrays.java
@@ -19,7 +19,6 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import java.lang.reflect.Array;
import java.util.Collection;
import javax.annotation.Nullable;
@@ -32,8 +31,6 @@ import javax.annotation.Nullable;
*/
@GwtCompatible(emulated = true)
public final class ObjectArrays {
- static final Object[] EMPTY_ARRAY = new Object[0];
-
private ObjectArrays() {}
/**
@@ -43,9 +40,8 @@ public final class ObjectArrays {
* @param length the length of the new array
*/
@GwtIncompatible("Array.newInstance(Class, int)")
- @SuppressWarnings("unchecked")
public static <T> T[] newArray(Class<T> type, int length) {
- return (T[]) Array.newInstance(type, length);
+ return Platform.newArray(type, length);
}
/**
@@ -69,8 +65,8 @@ public final class ObjectArrays {
@GwtIncompatible("Array.newInstance(Class, int)")
public static <T> T[] concat(T[] first, T[] second, Class<T> type) {
T[] result = newArray(type, first.length + second.length);
- System.arraycopy(first, 0, result, 0, first.length);
- System.arraycopy(second, 0, result, first.length, second.length);
+ Platform.unsafeArrayCopy(first, 0, result, 0, first.length);
+ Platform.unsafeArrayCopy(second, 0, result, first.length, second.length);
return result;
}
@@ -86,7 +82,7 @@ public final class ObjectArrays {
public static <T> T[] concat(@Nullable T element, T[] array) {
T[] result = newArray(array, array.length + 1);
result[0] = element;
- System.arraycopy(array, 0, result, 1, array.length);
+ Platform.unsafeArrayCopy(array, 0, result, 1, array.length);
return result;
}
@@ -108,7 +104,7 @@ public final class ObjectArrays {
/** GWT safe version of Arrays.copyOf. */
static <T> T[] arraysCopyOf(T[] original, int newLength) {
T[] copy = newArray(original, newLength);
- System.arraycopy(
+ Platform.unsafeArrayCopy(
original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
@@ -183,13 +179,4 @@ public final class ObjectArrays {
array[i] = array[j];
array[j] = temp;
}
-
- // We do this instead of Preconditions.checkNotNull to save boxing and array
- // creation cost.
- static Object checkElementNotNull(Object element, int index) {
- if (element == null) {
- throw new NullPointerException("at index " + index);
- }
- return element;
- }
}
diff --git a/guava/src/com/google/common/collect/Ordering.java b/guava/src/com/google/common/collect/Ordering.java
index 9ee9c48..1f0c6e3 100644
--- a/guava/src/com/google/common/collect/Ordering.java
+++ b/guava/src/com/google/common/collect/Ordering.java
@@ -19,13 +19,12 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@@ -35,15 +34,13 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.SortedMap;
import java.util.SortedSet;
-import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
/**
- * A comparator, with additional methods to support common operations. This is
- * an "enriched" version of {@code Comparator}, in the same sense that {@link
- * FluentIterable} is an enriched {@link Iterable}). For example: <pre> {@code
+ * A comparator with added methods to support common functions. For example:
+ * <pre> {@code
*
* if (Ordering.from(comparator).reverse().isOrdered(list)) { ... }}</pre>
*
@@ -62,17 +59,13 @@ import javax.annotation.Nullable;
* are. For example, if {@code ordering} and {@code function} can themselves be
* serialized, then {@code ordering.onResultOf(function)} can as well.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/OrderingExplained">
- * {@code Ordering}</a>.
- *
* @author Jesse Wilson
* @author Kevin Bourrillion
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible
public abstract class Ordering<T> implements Comparator<T> {
- // Natural order
+ // Static factories
/**
* Returns a serializable ordering that uses the natural order of the values.
@@ -89,17 +82,13 @@ public abstract class Ordering<T> implements Comparator<T> {
return (Ordering<C>) NaturalOrdering.INSTANCE;
}
- // Static factories
-
/**
- * Returns an ordering based on an <i>existing</i> comparator instance. Note
- * that there's no need to create a <i>new</i> comparator just to pass it in
- * here; simply subclass {@code Ordering} and implement its {@code compareTo}
- * method directly instead.
+ * Returns an ordering for a pre-existing {@code comparator}. Note
+ * that if the comparator is not pre-existing, and you don't require
+ * serialization, you can subclass {@code Ordering} and implement its
+ * {@link #compare(Object, Object) compare} method instead.
*
* @param comparator the comparator that defines the order
- * @return comparator itself if it is already an {@code Ordering}; otherwise
- * an ordering that wraps that comparator
*/
@GwtCompatible(serializable = true)
public static <T> Ordering<T> from(Comparator<T> comparator) {
@@ -173,48 +162,23 @@ public abstract class Ordering<T> implements Comparator<T> {
return explicit(Lists.asList(leastValue, remainingValuesInOrder));
}
- // Ordering<Object> singletons
-
/**
- * Returns an ordering which treats all values as equal, indicating "no
- * ordering." Passing this ordering to any <i>stable</i> sort algorithm
- * results in no change to the order of elements. Note especially that {@link
- * #sortedCopy} and {@link #immutableSortedCopy} are stable, and in the
- * returned instance these are implemented by simply copying the source list.
- *
- * <p>Example: <pre> {@code
- *
- * Ordering.allEqual().nullsLast().sortedCopy(
- * asList(t, null, e, s, null, t, null))}</pre>
- *
- * Assuming {@code t}, {@code e} and {@code s} are non-null, this returns
- * {@code [t, e, s, t, null, null, null]} regardlesss of the true comparison
- * order of those three values (which might not even implement {@link
- * Comparable} at all).
- *
- * <p><b>Warning:</b> by definition, this comparator is not <i>consistent with
- * equals</i> (as defined {@linkplain Comparator here}). Avoid its use in
- * APIs, such as {@link TreeSet#TreeSet(Comparator)}, where such consistency
- * is expected.
- *
- * <p>The returned comparator is serializable.
+ * Exception thrown by a {@link Ordering#explicit(List)} or {@link
+ * Ordering#explicit(Object, Object[])} comparator when comparing a value
+ * outside the set of values it can compare. Extending {@link
+ * ClassCastException} may seem odd, but it is required.
*/
- @GwtCompatible(serializable = true)
- @SuppressWarnings("unchecked")
- public static Ordering<Object> allEqual() {
- return AllEqualOrdering.INSTANCE;
- }
+ // TODO(kevinb): make this public, document it right
+ @VisibleForTesting
+ static class IncomparableValueException extends ClassCastException {
+ final Object value;
- /**
- * Returns an ordering that compares objects by the natural ordering of their
- * string representations as returned by {@code toString()}. It does not
- * support null values.
- *
- * <p>The comparator is serializable.
- */
- @GwtCompatible(serializable = true)
- public static Ordering<Object> usingToString() {
- return UsingToStringOrdering.INSTANCE;
+ IncomparableValueException(Object value) {
+ super("Cannot compare value: " + value);
+ this.value = value;
+ }
+
+ private static final long serialVersionUID = 0;
}
/**
@@ -256,10 +220,6 @@ public abstract class Ordering<T> implements Comparator<T> {
@Override public int compare(Object left, Object right) {
if (left == right) {
return 0;
- } else if (left == null) {
- return -1;
- } else if (right == null) {
- return 1;
}
int leftCode = identityHashCode(left);
int rightCode = identityHashCode(right);
@@ -292,62 +252,46 @@ public abstract class Ordering<T> implements Comparator<T> {
}
}
- // Constructor
-
/**
- * Constructs a new instance of this class (only invokable by the subclass
- * constructor, typically implicit).
- */
- protected Ordering() {}
-
- // Instance-based factories (and any static equivalents)
-
- /**
- * Returns the reverse of this ordering; the {@code Ordering} equivalent to
- * {@link Collections#reverseOrder(Comparator)}.
+ * Returns an ordering that compares objects by the natural ordering of their
+ * string representations as returned by {@code toString()}. It does not
+ * support null values.
+ *
+ * <p>The comparator is serializable.
*/
- // type parameter <S> lets us avoid the extra <String> in statements like:
- // Ordering<String> o = Ordering.<String>natural().reverse();
@GwtCompatible(serializable = true)
- public <S extends T> Ordering<S> reverse() {
- return new ReverseOrdering<S>(this);
+ public static Ordering<Object> usingToString() {
+ return UsingToStringOrdering.INSTANCE;
}
/**
- * Returns an ordering that treats {@code null} as less than all other values
- * and uses {@code this} to compare non-null values.
+ * Returns an ordering which tries each given comparator in order until a
+ * non-zero result is found, returning that result, and returning zero only if
+ * all comparators return zero. The returned ordering is based on the state of
+ * the {@code comparators} iterable at the time it was provided to this
+ * method.
+ *
+ * <p>The returned ordering is equivalent to that produced using {@code
+ * Ordering.from(comp1).compound(comp2).compound(comp3) . . .}.
+ *
+ * <p><b>Warning:</b> Supplying an argument with undefined iteration order,
+ * such as a {@link HashSet}, will produce non-deterministic results.
+ *
+ * @param comparators the comparators to try in order
*/
- // type parameter <S> lets us avoid the extra <String> in statements like:
- // Ordering<String> o = Ordering.<String>natural().nullsFirst();
@GwtCompatible(serializable = true)
- public <S extends T> Ordering<S> nullsFirst() {
- return new NullsFirstOrdering<S>(this);
+ public static <T> Ordering<T> compound(
+ Iterable<? extends Comparator<? super T>> comparators) {
+ return new CompoundOrdering<T>(comparators);
}
/**
- * Returns an ordering that treats {@code null} as greater than all other
- * values and uses this ordering to compare non-null values.
+ * Constructs a new instance of this class (only invokable by the subclass
+ * constructor, typically implicit).
*/
- // type parameter <S> lets us avoid the extra <String> in statements like:
- // Ordering<String> o = Ordering.<String>natural().nullsLast();
- @GwtCompatible(serializable = true)
- public <S extends T> Ordering<S> nullsLast() {
- return new NullsLastOrdering<S>(this);
- }
+ protected Ordering() {}
- /**
- * Returns a new ordering on {@code F} which orders elements by first applying
- * a function to them, then comparing those results using {@code this}. For
- * example, to compare objects by their string forms, in a case-insensitive
- * manner, use: <pre> {@code
- *
- * Ordering.from(String.CASE_INSENSITIVE_ORDER)
- * .onResultOf(Functions.toStringFunction())}</pre>
- */
- @GwtCompatible(serializable = true)
- public <F> Ordering<F> onResultOf(Function<F, ? extends T> function) {
- return new ByFunctionOrdering<F, T>(function, this);
- }
+ // Non-static factories
/**
* Returns an ordering which first uses the ordering {@code this}, but which
@@ -367,24 +311,28 @@ public abstract class Ordering<T> implements Comparator<T> {
}
/**
- * Returns an ordering which tries each given comparator in order until a
- * non-zero result is found, returning that result, and returning zero only if
- * all comparators return zero. The returned ordering is based on the state of
- * the {@code comparators} iterable at the time it was provided to this
- * method.
- *
- * <p>The returned ordering is equivalent to that produced using {@code
- * Ordering.from(comp1).compound(comp2).compound(comp3) . . .}.
- *
- * <p><b>Warning:</b> Supplying an argument with undefined iteration order,
- * such as a {@link HashSet}, will produce non-deterministic results.
+ * Returns the reverse of this ordering; the {@code Ordering} equivalent to
+ * {@link Collections#reverseOrder(Comparator)}.
+ */
+ // type parameter <S> lets us avoid the extra <String> in statements like:
+ // Ordering<String> o = Ordering.<String>natural().reverse();
+ @GwtCompatible(serializable = true)
+ public <S extends T> Ordering<S> reverse() {
+ return new ReverseOrdering<S>(this);
+ }
+
+ /**
+ * Returns a new ordering on {@code F} which orders elements by first applying
+ * a function to them, then comparing those results using {@code this}. For
+ * example, to compare objects by their string forms, in a case-insensitive
+ * manner, use: <pre> {@code
*
- * @param comparators the comparators to try in order
+ * Ordering.from(String.CASE_INSENSITIVE_ORDER)
+ * .onResultOf(Functions.toStringFunction())}</pre>
*/
@GwtCompatible(serializable = true)
- public static <T> Ordering<T> compound(
- Iterable<? extends Comparator<? super T>> comparators) {
- return new CompoundOrdering<T>(comparators);
+ public <F> Ordering<F> onResultOf(Function<F, ? extends T> function) {
+ return new ByFunctionOrdering<F, T>(function, this);
}
/**
@@ -416,162 +364,32 @@ public abstract class Ordering<T> implements Comparator<T> {
return new LexicographicalOrdering<S>(this);
}
- // Regular instance methods
-
- // Override to add @Nullable
- @Override public abstract int compare(@Nullable T left, @Nullable T right);
-
- /**
- * Returns the least of the specified values according to this ordering. If
- * there are multiple least values, the first of those is returned. The
- * iterator will be left exhausted: its {@code hasNext()} method will return
- * {@code false}.
- *
- * @param iterator the iterator whose minimum element is to be determined
- * @throws NoSuchElementException if {@code iterator} is empty
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
- *
- * @since 11.0
- */
- public <E extends T> E min(Iterator<E> iterator) {
- // let this throw NoSuchElementException as necessary
- E minSoFar = iterator.next();
-
- while (iterator.hasNext()) {
- minSoFar = min(minSoFar, iterator.next());
- }
-
- return minSoFar;
- }
-
- /**
- * Returns the least of the specified values according to this ordering. If
- * there are multiple least values, the first of those is returned.
- *
- * @param iterable the iterable whose minimum element is to be determined
- * @throws NoSuchElementException if {@code iterable} is empty
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
- */
- public <E extends T> E min(Iterable<E> iterable) {
- return min(iterable.iterator());
- }
-
- /**
- * Returns the lesser of the two values according to this ordering. If the
- * values compare as 0, the first is returned.
- *
- * <p><b>Implementation note:</b> this method is invoked by the default
- * implementations of the other {@code min} overloads, so overriding it will
- * affect their behavior.
- *
- * @param a value to compare, returned if less than or equal to b.
- * @param b value to compare.
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
- */
- public <E extends T> E min(@Nullable E a, @Nullable E b) {
- return (compare(a, b) <= 0) ? a : b;
- }
-
- /**
- * Returns the least of the specified values according to this ordering. If
- * there are multiple least values, the first of those is returned.
- *
- * @param a value to compare, returned if less than or equal to the rest.
- * @param b value to compare
- * @param c value to compare
- * @param rest values to compare
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
- */
- public <E extends T> E min(
- @Nullable E a, @Nullable E b, @Nullable E c, E... rest) {
- E minSoFar = min(min(a, b), c);
-
- for (E r : rest) {
- minSoFar = min(minSoFar, r);
- }
-
- return minSoFar;
- }
-
/**
- * Returns the greatest of the specified values according to this ordering. If
- * there are multiple greatest values, the first of those is returned. The
- * iterator will be left exhausted: its {@code hasNext()} method will return
- * {@code false}.
- *
- * @param iterator the iterator whose maximum element is to be determined
- * @throws NoSuchElementException if {@code iterator} is empty
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
- *
- * @since 11.0
- */
- public <E extends T> E max(Iterator<E> iterator) {
- // let this throw NoSuchElementException as necessary
- E maxSoFar = iterator.next();
-
- while (iterator.hasNext()) {
- maxSoFar = max(maxSoFar, iterator.next());
- }
-
- return maxSoFar;
- }
-
- /**
- * Returns the greatest of the specified values according to this ordering. If
- * there are multiple greatest values, the first of those is returned.
- *
- * @param iterable the iterable whose maximum element is to be determined
- * @throws NoSuchElementException if {@code iterable} is empty
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
+ * Returns an ordering that treats {@code null} as less than all other values
+ * and uses {@code this} to compare non-null values.
*/
- public <E extends T> E max(Iterable<E> iterable) {
- return max(iterable.iterator());
+ // type parameter <S> lets us avoid the extra <String> in statements like:
+ // Ordering<String> o = Ordering.<String>natural().nullsFirst();
+ @GwtCompatible(serializable = true)
+ public <S extends T> Ordering<S> nullsFirst() {
+ return new NullsFirstOrdering<S>(this);
}
/**
- * Returns the greater of the two values according to this ordering. If the
- * values compare as 0, the first is returned.
- *
- * <p><b>Implementation note:</b> this method is invoked by the default
- * implementations of the other {@code max} overloads, so overriding it will
- * affect their behavior.
- *
- * @param a value to compare, returned if greater than or equal to b.
- * @param b value to compare.
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
+ * Returns an ordering that treats {@code null} as greater than all other
+ * values and uses this ordering to compare non-null values.
*/
- public <E extends T> E max(@Nullable E a, @Nullable E b) {
- return (compare(a, b) >= 0) ? a : b;
+ // type parameter <S> lets us avoid the extra <String> in statements like:
+ // Ordering<String> o = Ordering.<String>natural().nullsLast();
+ @GwtCompatible(serializable = true)
+ public <S extends T> Ordering<S> nullsLast() {
+ return new NullsLastOrdering<S>(this);
}
- /**
- * Returns the greatest of the specified values according to this ordering. If
- * there are multiple greatest values, the first of those is returned.
- *
- * @param a value to compare, returned if greater than or equal to the rest.
- * @param b value to compare
- * @param c value to compare
- * @param rest values to compare
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i> under this ordering.
- */
- public <E extends T> E max(
- @Nullable E a, @Nullable E b, @Nullable E c, E... rest) {
- E maxSoFar = max(max(a, b), c);
-
- for (E r : rest) {
- maxSoFar = max(maxSoFar, r);
- }
+ // Regular instance methods
- return maxSoFar;
- }
+ // Override to add @Nullable
+ @Override public abstract int compare(@Nullable T left, @Nullable T right);
/**
* Returns the {@code k} least elements of the given iterable according to
@@ -587,130 +405,64 @@ public abstract class Ordering<T> implements Comparator<T> {
* @throws IllegalArgumentException if {@code k} is negative
* @since 8.0
*/
+ @Beta
public <E extends T> List<E> leastOf(Iterable<E> iterable, int k) {
- if (iterable instanceof Collection) {
- Collection<E> collection = (Collection<E>) iterable;
- if (collection.size() <= 2L * k) {
- // In this case, just dumping the collection to an array and sorting is
- // faster than using the implementation for Iterator, which is
- // specialized for k much smaller than n.
-
- @SuppressWarnings("unchecked") // c only contains E's and doesn't escape
- E[] array = (E[]) collection.toArray();
- Arrays.sort(array, this);
- if (array.length > k) {
- array = ObjectArrays.arraysCopyOf(array, k);
- }
- return Collections.unmodifiableList(Arrays.asList(array));
- }
+ checkArgument(k >= 0, "%d is negative", k);
+
+ // values is not an E[], but we use it as such for readability. Hack.
+ @SuppressWarnings("unchecked")
+ E[] values = (E[]) Iterables.toArray(iterable);
+
+ // TODO(nshupe): also sort whole list if k is *near* values.length?
+ // TODO(kevinb): benchmark this impl against hand-coded heap
+ E[] resultArray;
+ if (values.length <= k) {
+ Arrays.sort(values, this);
+ resultArray = values;
+ } else {
+ quicksortLeastK(values, 0, values.length - 1, k);
+
+ // this is not an E[], but we use it as such for readability. Hack.
+ @SuppressWarnings("unchecked")
+ E[] tmp = (E[]) new Object[k];
+ resultArray = tmp;
+ System.arraycopy(values, 0, resultArray, 0, k);
}
- return leastOf(iterable.iterator(), k);
+
+ return Collections.unmodifiableList(Arrays.asList(resultArray));
}
/**
- * Returns the {@code k} least elements from the given iterator according to
- * this ordering, in order from least to greatest. If there are fewer than
+ * Returns the {@code k} greatest elements of the given iterable according to
+ * this ordering, in order from greatest to least. If there are fewer than
* {@code k} elements present, all will be included.
*
* <p>The implementation does not necessarily use a <i>stable</i> sorting
* algorithm; when multiple elements are equivalent, it is undefined which
* will come first.
*
- * @return an immutable {@code RandomAccess} list of the {@code k} least
- * elements in ascending order
+ * @return an immutable {@code RandomAccess} list of the {@code k} greatest
+ * elements in <i>descending order</i>
* @throws IllegalArgumentException if {@code k} is negative
- * @since 14.0
+ * @since 8.0
*/
- public <E extends T> List<E> leastOf(Iterator<E> elements, int k) {
- checkNotNull(elements);
- checkArgument(k >= 0, "k (%s) must be nonnegative", k);
-
- if (k == 0 || !elements.hasNext()) {
- return ImmutableList.of();
- } else if (k >= Integer.MAX_VALUE / 2) {
- // k is really large; just do a straightforward sorted-copy-and-sublist
- ArrayList<E> list = Lists.newArrayList(elements);
- Collections.sort(list, this);
- if (list.size() > k) {
- list.subList(k, list.size()).clear();
- }
- list.trimToSize();
- return Collections.unmodifiableList(list);
- }
-
- /*
- * Our goal is an O(n) algorithm using only one pass and O(k) additional
- * memory.
- *
- * We use the following algorithm: maintain a buffer of size 2*k. Every time
- * the buffer gets full, find the median and partition around it, keeping
- * only the lowest k elements. This requires n/k find-median-and-partition
- * steps, each of which take O(k) time with a traditional quickselect.
- *
- * After sorting the output, the whole algorithm is O(n + k log k). It
- * degrades gracefully for worst-case input (descending order), performs
- * competitively or wins outright for randomly ordered input, and doesn't
- * require the whole collection to fit into memory.
- */
- int bufferCap = k * 2;
- @SuppressWarnings("unchecked") // we'll only put E's in
- E[] buffer = (E[]) new Object[bufferCap];
- E threshold = elements.next();
- buffer[0] = threshold;
- int bufferSize = 1;
- // threshold is the kth smallest element seen so far. Once bufferSize >= k,
- // anything larger than threshold can be ignored immediately.
-
- while (bufferSize < k && elements.hasNext()) {
- E e = elements.next();
- buffer[bufferSize++] = e;
- threshold = max(threshold, e);
- }
-
- while (elements.hasNext()) {
- E e = elements.next();
- if (compare(e, threshold) >= 0) {
- continue;
- }
-
- buffer[bufferSize++] = e;
- if (bufferSize == bufferCap) {
- // We apply the quickselect algorithm to partition about the median,
- // and then ignore the last k elements.
- int left = 0;
- int right = bufferCap - 1;
-
- int minThresholdPosition = 0;
- // The leftmost position at which the greatest of the k lower elements
- // -- the new value of threshold -- might be found.
-
- while (left < right) {
- int pivotIndex = (left + right + 1) >>> 1;
- int pivotNewIndex = partition(buffer, left, right, pivotIndex);
- if (pivotNewIndex > k) {
- right = pivotNewIndex - 1;
- } else if (pivotNewIndex < k) {
- left = Math.max(pivotNewIndex, left + 1);
- minThresholdPosition = pivotNewIndex;
- } else {
- break;
- }
- }
- bufferSize = k;
+ @Beta
+ public <E extends T> List<E> greatestOf(Iterable<E> iterable, int k) {
+ // TODO(kevinb): see if delegation is hurting performance noticeably
+ // TODO(kevinb): if we change this implementation, add full unit tests.
+ return reverse().leastOf(iterable, k);
+ }
- threshold = buffer[minThresholdPosition];
- for (int i = minThresholdPosition + 1; i < bufferSize; i++) {
- threshold = max(threshold, buffer[i]);
- }
+ private <E extends T> void quicksortLeastK(
+ E[] values, int left, int right, int k) {
+ if (right > left) {
+ int pivotIndex = (left + right) >>> 1; // left + ((right - left) / 2)
+ int pivotNewIndex = partition(values, left, right, pivotIndex);
+ quicksortLeastK(values, left, pivotNewIndex - 1, k);
+ if (pivotNewIndex < k) {
+ quicksortLeastK(values, pivotNewIndex + 1, right, k);
}
}
-
- Arrays.sort(buffer, 0, bufferSize, this);
-
- bufferSize = Math.min(bufferSize, k);
- return Collections.unmodifiableList(
- Arrays.asList(ObjectArrays.arraysCopyOf(buffer, bufferSize)));
- // We can't use ImmutableList; we have to be null-friendly!
}
private <E extends T> int partition(
@@ -732,41 +484,15 @@ public abstract class Ordering<T> implements Comparator<T> {
}
/**
- * Returns the {@code k} greatest elements of the given iterable according to
- * this ordering, in order from greatest to least. If there are fewer than
- * {@code k} elements present, all will be included.
- *
- * <p>The implementation does not necessarily use a <i>stable</i> sorting
- * algorithm; when multiple elements are equivalent, it is undefined which
- * will come first.
- *
- * @return an immutable {@code RandomAccess} list of the {@code k} greatest
- * elements in <i>descending order</i>
- * @throws IllegalArgumentException if {@code k} is negative
- * @since 8.0
- */
- public <E extends T> List<E> greatestOf(Iterable<E> iterable, int k) {
- // TODO(kevinb): see if delegation is hurting performance noticeably
- // TODO(kevinb): if we change this implementation, add full unit tests.
- return reverse().leastOf(iterable, k);
- }
-
- /**
- * Returns the {@code k} greatest elements from the given iterator according to
- * this ordering, in order from greatest to least. If there are fewer than
- * {@code k} elements present, all will be included.
- *
- * <p>The implementation does not necessarily use a <i>stable</i> sorting
- * algorithm; when multiple elements are equivalent, it is undefined which
- * will come first.
+ * {@link Collections#binarySearch(List, Object, Comparator) Searches}
+ * {@code sortedList} for {@code key} using the binary search algorithm. The
+ * list must be sorted using this ordering.
*
- * @return an immutable {@code RandomAccess} list of the {@code k} greatest
- * elements in <i>descending order</i>
- * @throws IllegalArgumentException if {@code k} is negative
- * @since 14.0
+ * @param sortedList the list to be searched
+ * @param key the key to be searched for
*/
- public <E extends T> List<E> greatestOf(Iterator<E> iterator, int k) {
- return reverse().leastOf(iterator, k);
+ public int binarySearch(List<? extends T> sortedList, @Nullable T key) {
+ return Collections.binarySearch(sortedList, key, this);
}
/**
@@ -783,10 +509,9 @@ public abstract class Ordering<T> implements Comparator<T> {
* @return a new list containing the given elements in sorted order
*/
public <E extends T> List<E> sortedCopy(Iterable<E> iterable) {
- @SuppressWarnings("unchecked") // does not escape, and contains only E's
- E[] array = (E[]) Iterables.toArray(iterable);
- Arrays.sort(array, this);
- return Lists.newArrayList(Arrays.asList(array));
+ List<E> list = Lists.newArrayList(iterable);
+ Collections.sort(list, this);
+ return list;
}
/**
@@ -806,13 +531,7 @@ public abstract class Ordering<T> implements Comparator<T> {
*/
public <E extends T> ImmutableList<E> immutableSortedCopy(
Iterable<E> iterable) {
- @SuppressWarnings("unchecked") // we'll only ever have E's in here
- E[] elements = (E[]) Iterables.toArray(iterable);
- for (E e : elements) {
- checkNotNull(e);
- }
- Arrays.sort(elements, this);
- return ImmutableList.asImmutableList(elements);
+ return ImmutableList.copyOf(sortedCopy(iterable));
}
/**
@@ -858,34 +577,157 @@ public abstract class Ordering<T> implements Comparator<T> {
}
/**
- * {@link Collections#binarySearch(List, Object, Comparator) Searches}
- * {@code sortedList} for {@code key} using the binary search algorithm. The
- * list must be sorted using this ordering.
+ * Returns the greatest of the specified values according to this ordering. If
+ * there are multiple greatest values, the first of those is returned. The
+ * iterator will be left exhausted: its {@code hasNext()} method will return
+ * {@code false}.
*
- * @param sortedList the list to be searched
- * @param key the key to be searched for
+ * @param iterator the iterator whose maximum element is to be determined
+ * @throws NoSuchElementException if {@code iterator} is empty
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ *
+ * @since 11.0
*/
- public int binarySearch(List<? extends T> sortedList, @Nullable T key) {
- return Collections.binarySearch(sortedList, key, this);
+ @Beta
+ public <E extends T> E max(Iterator<E> iterator) {
+ // let this throw NoSuchElementException as necessary
+ E maxSoFar = iterator.next();
+
+ while (iterator.hasNext()) {
+ maxSoFar = max(maxSoFar, iterator.next());
+ }
+
+ return maxSoFar;
}
/**
- * Exception thrown by a {@link Ordering#explicit(List)} or {@link
- * Ordering#explicit(Object, Object[])} comparator when comparing a value
- * outside the set of values it can compare. Extending {@link
- * ClassCastException} may seem odd, but it is required.
+ * Returns the greatest of the specified values according to this ordering. If
+ * there are multiple greatest values, the first of those is returned.
+ *
+ * @param iterable the iterable whose maximum element is to be determined
+ * @throws NoSuchElementException if {@code iterable} is empty
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
*/
- // TODO(kevinb): make this public, document it right
- @VisibleForTesting
- static class IncomparableValueException extends ClassCastException {
- final Object value;
+ public <E extends T> E max(Iterable<E> iterable) {
+ return max(iterable.iterator());
+ }
- IncomparableValueException(Object value) {
- super("Cannot compare value: " + value);
- this.value = value;
+ /**
+ * Returns the greatest of the specified values according to this ordering. If
+ * there are multiple greatest values, the first of those is returned.
+ *
+ * @param a value to compare, returned if greater than or equal to the rest.
+ * @param b value to compare
+ * @param c value to compare
+ * @param rest values to compare
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E max(
+ @Nullable E a, @Nullable E b, @Nullable E c, E... rest) {
+ E maxSoFar = max(max(a, b), c);
+
+ for (E r : rest) {
+ maxSoFar = max(maxSoFar, r);
}
- private static final long serialVersionUID = 0;
+ return maxSoFar;
+ }
+
+ /**
+ * Returns the greater of the two values according to this ordering. If the
+ * values compare as 0, the first is returned.
+ *
+ * <p><b>Implementation note:</b> this method is invoked by the default
+ * implementations of the other {@code max} overloads, so overriding it will
+ * affect their behavior.
+ *
+ * @param a value to compare, returned if greater than or equal to b.
+ * @param b value to compare.
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E max(@Nullable E a, @Nullable E b) {
+ return compare(a, b) >= 0 ? a : b;
+ }
+
+ /**
+ * Returns the least of the specified values according to this ordering. If
+ * there are multiple least values, the first of those is returned. The
+ * iterator will be left exhausted: its {@code hasNext()} method will return
+ * {@code false}.
+ *
+ * @param iterator the iterator whose minimum element is to be determined
+ * @throws NoSuchElementException if {@code iterator} is empty
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ *
+ * @since 11.0
+ */
+ @Beta
+ public <E extends T> E min(Iterator<E> iterator) {
+ // let this throw NoSuchElementException as necessary
+ E minSoFar = iterator.next();
+
+ while (iterator.hasNext()) {
+ minSoFar = min(minSoFar, iterator.next());
+ }
+
+ return minSoFar;
+ }
+
+ /**
+ * Returns the least of the specified values according to this ordering. If
+ * there are multiple least values, the first of those is returned.
+ *
+ * @param iterable the iterable whose minimum element is to be determined
+ * @throws NoSuchElementException if {@code iterable} is empty
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E min(Iterable<E> iterable) {
+ return min(iterable.iterator());
+ }
+
+ /**
+ * Returns the least of the specified values according to this ordering. If
+ * there are multiple least values, the first of those is returned.
+ *
+ * @param a value to compare, returned if less than or equal to the rest.
+ * @param b value to compare
+ * @param c value to compare
+ * @param rest values to compare
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E min(
+ @Nullable E a, @Nullable E b, @Nullable E c, E... rest) {
+ E minSoFar = min(min(a, b), c);
+
+ for (E r : rest) {
+ minSoFar = min(minSoFar, r);
+ }
+
+ return minSoFar;
+ }
+
+ /**
+ * Returns the lesser of the two values according to this ordering. If the
+ * values compare as 0, the first is returned.
+ *
+ * <p><b>Implementation note:</b> this method is invoked by the default
+ * implementations of the other {@code min} overloads, so overriding it will
+ * affect their behavior.
+ *
+ * @param a value to compare, returned if less than or equal to b.
+ * @param b value to compare.
+ * @throws ClassCastException if the parameters are not <i>mutually
+ * comparable</i> under this ordering.
+ */
+ public <E extends T> E min(@Nullable E a, @Nullable E b) {
+ return compare(a, b) <= 0 ? a : b;
}
// Never make these public
diff --git a/guava/src/com/google/common/collect/PeekingIterator.java b/guava/src/com/google/common/collect/PeekingIterator.java
index 294b2e6..be8989d 100644
--- a/guava/src/com/google/common/collect/PeekingIterator.java
+++ b/guava/src/com/google/common/collect/PeekingIterator.java
@@ -23,10 +23,6 @@ import java.util.NoSuchElementException;
/**
* An iterator that supports a one-element lookahead while iterating.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionHelpersExplained#PeekingIterator">
- * {@code PeekingIterator}</a>.
*
* @author Mick Killianey
* @since 2.0 (imported from Google Collections Library)
diff --git a/guava/src/com/google/common/collect/Platform.java b/guava/src/com/google/common/collect/Platform.java
index cd321e8..408563b 100644
--- a/guava/src/com/google/common/collect/Platform.java
+++ b/guava/src/com/google/common/collect/Platform.java
@@ -17,16 +17,9 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Maps.EntryTransformer;
+import com.google.common.annotations.GwtIncompatible;
import java.lang.reflect.Array;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.SortedMap;
-import java.util.SortedSet;
/**
* Methods factored out so that they can be emulated differently in GWT.
@@ -44,6 +37,35 @@ class Platform {
}
/**
+ * Wrapper around {@link System#arraycopy} so that it can be emulated
+ * correctly in GWT.
+ *
+ * <p>It is only intended for the case {@code src} and {@code dest} are
+ * different. It also doesn't validate the types and indices.
+ *
+ * <p>As of GWT 2.0, The built-in {@link System#arraycopy} doesn't work
+ * in general case. See
+ * http://code.google.com/p/google-web-toolkit/issues/detail?id=3621
+ * for more details.
+ */
+ static void unsafeArrayCopy(
+ Object[] src, int srcPos, Object[] dest, int destPos, int length) {
+ System.arraycopy(src, srcPos, dest, destPos, length);
+ }
+
+ /**
+ * Returns a new array of the given length with the specified component type.
+ *
+ * @param type the component type
+ * @param length the length of the new array
+ */
+ @GwtIncompatible("Array.newInstance(Class, int)")
+ @SuppressWarnings("unchecked")
+ static <T> T[] newArray(Class<T> type, int length) {
+ return (T[]) Array.newInstance(type, length);
+ }
+
+ /**
* Returns a new array of the given length with the same type as a reference
* array.
*
@@ -70,34 +92,5 @@ class Platform {
return mapMaker.weakKeys();
}
- static <K, V1, V2> SortedMap<K, V2> mapsTransformEntriesSortedMap(
- SortedMap<K, V1> fromMap,
- EntryTransformer<? super K, ? super V1, V2> transformer) {
- return (fromMap instanceof NavigableMap)
- ? Maps.transformEntries((NavigableMap<K, V1>) fromMap, transformer)
- : Maps.transformEntriesIgnoreNavigable(fromMap, transformer);
- }
-
- static <K, V> SortedMap<K, V> mapsAsMapSortedSet(SortedSet<K> set,
- Function<? super K, V> function) {
- return (set instanceof NavigableSet)
- ? Maps.asMap((NavigableSet<K>) set, function)
- : Maps.asMapSortedIgnoreNavigable(set, function);
- }
-
- static <E> SortedSet<E> setsFilterSortedSet(SortedSet<E> set,
- Predicate<? super E> predicate) {
- return (set instanceof NavigableSet)
- ? Sets.filter((NavigableSet<E>) set, predicate)
- : Sets.filterSortedIgnoreNavigable(set, predicate);
- }
-
- static <K, V> SortedMap<K, V> mapsFilterSortedMap(SortedMap<K, V> map,
- Predicate<? super Map.Entry<K, V>> predicate) {
- return (map instanceof NavigableMap)
- ? Maps.filterEntries((NavigableMap<K, V>) map, predicate)
- : Maps.filterSortedIgnoreNavigable(map, predicate);
- }
-
private Platform() {}
}
diff --git a/guava/src/com/google/common/collect/Queues.java b/guava/src/com/google/common/collect/Queues.java
index d2bf4ad..d68146a 100644
--- a/guava/src/com/google/common/collect/Queues.java
+++ b/guava/src/com/google/common/collect/Queues.java
@@ -19,7 +19,6 @@ import com.google.common.base.Preconditions;
import java.util.ArrayDeque;
import java.util.Collection;
-import java.util.Deque;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
@@ -32,12 +31,14 @@ import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
/**
- * Static utility methods pertaining to {@link Queue} and {@link Deque} instances.
- * Also see this class's counterparts {@link Lists}, {@link Sets}, and {@link Maps}.
+ * Static utility methods pertaining to {@link Queue}
+ * instances. Also see this class's counterparts
+ * {@link Lists}, {@link Sets}, and {@link Maps}.
*
* @author Kurt Alfred Kluever
* @since 11.0
*/
+@Beta
public final class Queues {
private Queues() {}
@@ -54,32 +55,6 @@ public final class Queues {
// ArrayDeque
- /**
- * Creates an empty {@code ArrayDeque} instance.
- *
- * @return a new, empty {@code ArrayDeque}
- * @since 12.0
- */
- public static <E> ArrayDeque<E> newArrayDeque() {
- return new ArrayDeque<E>();
- }
-
- /**
- * Creates an {@code ArrayDeque} instance containing the given elements.
- *
- * @param elements the elements that the queue should contain, in order
- * @return a new {@code ArrayDeque} containing those elements
- * @since 12.0
- */
- public static <E> ArrayDeque<E> newArrayDeque(Iterable<? extends E> elements) {
- if (elements instanceof Collection) {
- return new ArrayDeque<E>(Collections2.cast(elements));
- }
- ArrayDeque<E> deque = new ArrayDeque<E>();
- Iterables.addAll(deque, elements);
- return deque;
- }
-
// ConcurrentLinkedQueue
/**
@@ -109,44 +84,6 @@ public final class Queues {
// LinkedBlockingDeque
- /**
- * Creates an empty {@code LinkedBlockingDeque} instance.
- *
- * @return a new, empty {@code LinkedBlockingDeque}
- * @since 12.0
- */
- public static <E> LinkedBlockingDeque<E> newLinkedBlockingDeque() {
- return new LinkedBlockingDeque<E>();
- }
-
- /**
- * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
- *
- * @param capacity the capacity of this deque
- * @return a new, empty {@code LinkedBlockingDeque}
- * @throws IllegalArgumentException if {@code capacity} is less than 1
- * @since 12.0
- */
- public static <E> LinkedBlockingDeque<E> newLinkedBlockingDeque(int capacity) {
- return new LinkedBlockingDeque<E>(capacity);
- }
-
- /**
- * Creates an {@code LinkedBlockingDeque} instance containing the given elements.
- *
- * @param elements the elements that the queue should contain, in order
- * @return a new {@code LinkedBlockingDeque} containing those elements
- * @since 12.0
- */
- public static <E> LinkedBlockingDeque<E> newLinkedBlockingDeque(Iterable<? extends E> elements) {
- if (elements instanceof Collection) {
- return new LinkedBlockingDeque<E>(Collections2.cast(elements));
- }
- LinkedBlockingDeque<E> deque = new LinkedBlockingDeque<E>();
- Iterables.addAll(deque, elements);
- return deque;
- }
-
// LinkedBlockingQueue
/**
@@ -249,12 +186,12 @@ public final class Queues {
public static <E> SynchronousQueue<E> newSynchronousQueue() {
return new SynchronousQueue<E>();
}
-
+
/**
- * Drains the queue as {@link BlockingQueue#drainTo(Collection, int)}, but if the requested
+ * Drains the queue as {@link BlockingQueue#drainTo(Collection, int)}, but if the requested
* {@code numElements} elements are not available, it will wait for them up to the specified
* timeout.
- *
+ *
* @param q the blocking queue to be drained
* @param buffer where to add the transferred elements
* @param numElements the number of elements to be waited for
@@ -263,7 +200,6 @@ public final class Queues {
* @return the number of elements transferred
* @throws InterruptedException if interrupted while waiting
*/
- @Beta
public static <E> int drain(BlockingQueue<E> q, Collection<? super E> buffer, int numElements,
long timeout, TimeUnit unit) throws InterruptedException {
Preconditions.checkNotNull(buffer);
@@ -289,13 +225,13 @@ public final class Queues {
}
return added;
}
-
+
/**
- * Drains the queue as {@linkplain #drain(BlockingQueue, Collection, int, long, TimeUnit)},
- * but with a different behavior in case it is interrupted while waiting. In that case, the
- * operation will continue as usual, and in the end the thread's interruption status will be set
- * (no {@code InterruptedException} is thrown).
- *
+ * Drains the queue as {@linkplain #drain(BlockingQueue, Collection, int, long, TimeUnit)},
+ * but with a different behavior in case it is interrupted while waiting. In that case, the
+ * operation will continue as usual, and in the end the thread's interruption status will be set
+ * (no {@code InterruptedException} is thrown).
+ *
* @param q the blocking queue to be drained
* @param buffer where to add the transferred elements
* @param numElements the number of elements to be waited for
@@ -303,8 +239,7 @@ public final class Queues {
* @param unit a {@code TimeUnit} determining how to interpret the timeout parameter
* @return the number of elements transferred
*/
- @Beta
- public static <E> int drainUninterruptibly(BlockingQueue<E> q, Collection<? super E> buffer,
+ public static <E> int drainUninterruptibly(BlockingQueue<E> q, Collection<? super E> buffer,
int numElements, long timeout, TimeUnit unit) {
Preconditions.checkNotNull(buffer);
long deadline = System.nanoTime() + unit.toNanos(timeout);
@@ -312,7 +247,7 @@ public final class Queues {
boolean interrupted = false;
try {
while (added < numElements) {
- // we could rely solely on #poll, but #drainTo might be more efficient when there are
+ // we could rely solely on #poll, but #drainTo might be more efficient when there are
// multiple elements already available (e.g. LinkedBlockingQueue#drainTo locks only once)
added += q.drainTo(buffer, numElements - added);
if (added < numElements) { // not enough elements immediately available; will have to poll
@@ -339,36 +274,4 @@ public final class Queues {
}
return added;
}
-
- /**
- * Returns a synchronized (thread-safe) queue backed by the specified queue. In order to
- * guarantee serial access, it is critical that <b>all</b> access to the backing queue is
- * accomplished through the returned queue.
- *
- * <p>It is imperative that the user manually synchronize on the returned queue when accessing
- * the queue's iterator: <pre> {@code
- *
- * Queue<E> queue = Queues.synchronizedQueue(MinMaxPriorityQueue<E>.create());
- * ...
- * queue.add(element); // Needn't be in synchronized block
- * ...
- * synchronized (queue) { // Must synchronize on queue!
- * Iterator<E> i = queue.iterator(); // Must be in synchronized block
- * while (i.hasNext()) {
- * foo(i.next());
- * }
- * }}</pre>
- *
- * Failure to follow this advice may result in non-deterministic behavior.
- *
- * <p>The returned queue will be serializable if the specified queue is serializable.
- *
- * @param queue the queue to be wrapped in a synchronized view
- * @return a synchronized view of the specified queue
- * @since 14.0
- */
- @Beta
- public static <E> Queue<E> synchronizedQueue(Queue<E> queue) {
- return Synchronized.queue(queue, null);
- }
}
diff --git a/guava/src/com/google/common/collect/Range.java b/guava/src/com/google/common/collect/Range.java
index e70c34f..c6a9189 100644
--- a/guava/src/com/google/common/collect/Range.java
+++ b/guava/src/com/google/common/collect/Range.java
@@ -17,17 +17,15 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Ranges.create;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Function;
import com.google.common.base.Predicate;
import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
@@ -35,338 +33,94 @@ import java.util.SortedSet;
import javax.annotation.Nullable;
/**
- * A range (or "interval") defines the <i>boundaries</i> around a contiguous span of values of some
- * {@code Comparable} type; for example, "integers from 1 to 100 inclusive." Note that it is not
- * possible to <i>iterate</i> over these contained values. To do so, pass this range instance and
- * an appropriate {@link DiscreteDomain} to {@link ContiguousSet#create}.
+ * A range, sometimes known as an <i>interval</i>, is a <i>convex</i>
+ * (informally, "contiguous" or "unbroken") portion of a particular domain.
+ * Formally, convexity means that for any {@code a <= b <= c},
+ * {@code range.contains(a) && range.contains(c)} implies that {@code
+ * range.contains(b)}.
*
- * <h3>Types of ranges</h3>
+ * <p>A range is characterized by its lower and upper <i>bounds</i> (extremes),
+ * each of which can <i>open</i> (exclusive of its endpoint), <i>closed</i>
+ * (inclusive of its endpoint), or <i>unbounded</i>. This yields nine basic
+ * types of ranges:
*
- * <p>Each end of the range may be bounded or unbounded. If bounded, there is an associated
- * <i>endpoint</i> value, and the range is considered to be either <i>open</i> (does not include the
- * endpoint) or <i>closed</i> (includes the endpoint) on that side. With three possibilities on each
- * side, this yields nine basic types of ranges, enumerated below. (Notation: a square bracket
- * ({@code [ ]}) indicates that the range is closed on that side; a parenthesis ({@code ( )}) means
- * it is either open or unbounded. The construct {@code {x | statement}} is read "the set of all
- * <i>x</i> such that <i>statement</i>.")
+ * <ul>
+ * <li>{@code (a..b) = {x | a < x < b}}
+ * <li>{@code [a..b] = {x | a <= x <= b}}
+ * <li>{@code [a..b) = {x | a <= x < b}}
+ * <li>{@code (a..b] = {x | a < x <= b}}
+ * <li>{@code (a..+∞) = {x | x > a}}
+ * <li>{@code [a..+∞) = {x | x >= a}}
+ * <li>{@code (-∞..b) = {x | x < b}}
+ * <li>{@code (-∞..b] = {x | x <= b}}
+ * <li>{@code (-∞..+∞) = all values}
+ * </ul>
+ *
+ * (The notation {@code {x | statement}} is read "the set of all <i>x</i> such
+ * that <i>statement</i>.")
*
- * <blockquote><table>
- * <tr><td><b>Notation</b> <td><b>Definition</b> <td><b>Factory method</b>
- * <tr><td>{@code (a..b)} <td>{@code {x | a < x < b}} <td>{@link Range#open open}
- * <tr><td>{@code [a..b]} <td>{@code {x | a <= x <= b}}<td>{@link Range#closed closed}
- * <tr><td>{@code (a..b]} <td>{@code {x | a < x <= b}} <td>{@link Range#openClosed openClosed}
- * <tr><td>{@code [a..b)} <td>{@code {x | a <= x < b}} <td>{@link Range#closedOpen closedOpen}
- * <tr><td>{@code (a..+∞)} <td>{@code {x | x > a}} <td>{@link Range#greaterThan greaterThan}
- * <tr><td>{@code [a..+∞)} <td>{@code {x | x >= a}} <td>{@link Range#atLeast atLeast}
- * <tr><td>{@code (-∞..b)} <td>{@code {x | x < b}} <td>{@link Range#lessThan lessThan}
- * <tr><td>{@code (-∞..b]} <td>{@code {x | x <= b}} <td>{@link Range#atMost atMost}
- * <tr><td>{@code (-∞..+∞)}<td>{@code {x}} <td>{@link Range#all all}
- * </table></blockquote>
+ * <p>Notice that we use a square bracket ({@code [ ]}) to denote that an range
+ * is closed on that end, and a parenthesis ({@code ( )}) when it is open or
+ * unbounded.
*
- * <p>When both endpoints exist, the upper endpoint may not be less than the lower. The endpoints
- * may be equal only if at least one of the bounds is closed:
+ * <p>The values {@code a} and {@code b} used above are called <i>endpoints</i>.
+ * The upper endpoint may not be less than the lower endpoint. The endpoints may
+ * be equal only if at least one of the bounds is closed:
*
* <ul>
- * <li>{@code [a..a]} : a singleton range
- * <li>{@code [a..a); (a..a]} : {@linkplain #isEmpty empty} ranges; also valid
- * <li>{@code (a..a)} : <b>invalid</b>; an exception will be thrown
+ * <li>{@code [a..a]} : singleton range
+ * <li>{@code [a..a); (a..a]} : {@linkplain #isEmpty empty}, but valid
+ * <li>{@code (a..a)} : <b>invalid</b>
* </ul>
*
- * <h3>Warnings</h3>
+ * <p>Instances of this type can be obtained using the static factory methods in
+ * the {@link Ranges} class.
*
- * <ul>
- * <li>Use immutable value types only, if at all possible. If you must use a mutable type, <b>do
- * not</b> allow the endpoint instances to mutate after the range is created!
- * <li>Your value type's comparison method should be {@linkplain Comparable consistent with equals}
- * if at all possible. Otherwise, be aware that concepts used throughout this documentation such
- * as "equal", "same", "unique" and so on actually refer to whether {@link Comparable#compareTo
- * compareTo} returns zero, not whether {@link Object#equals equals} returns {@code true}.
- * <li>A class which implements {@code Comparable<UnrelatedType>} is very broken, and will cause
- * undefined horrible things to happen in {@code Range}. For now, the Range API does not prevent
- * its use, because this would also rule out all ungenerified (pre-JDK1.5) data types. <b>This
- * may change in the future.</b>
- * </ul>
+ * <p>Instances of {@code Range} are immutable. It is strongly encouraged to
+ * use this class only with immutable data types. When creating a range over a
+ * mutable type, take great care not to allow the value objects to mutate after
+ * the range is created.
*
- * <h3>Other notes</h3>
+ * <p>In this and other range-related specifications, concepts like "equal",
+ * "same", "unique" and so on are based on {@link Comparable#compareTo}
+ * returning zero, not on {@link Object#equals} returning {@code true}. Of
+ * course, when these methods are kept <i>consistent</i> (as defined in {@link
+ * Comparable}), this is not an issue.
*
- * <ul>
- * <li>Instances of this type are obtained using the static factory methods in this class.
- * <li>Ranges are <i>convex</i>: whenever two values are contained, all values in between them must
- * also be contained. More formally, for any {@code c1 <= c2 <= c3} of type {@code C}, {@code
- * r.contains(c1) && r.contains(c3)} implies {@code r.contains(c2)}). This means that a {@code
- * Range<Integer>} can never be used to represent, say, "all <i>prime</i> numbers from 1 to
- * 100."
- * <li>When evaluated as a {@link Predicate}, a range yields the same result as invoking {@link
- * #contains}.
- * <li>Terminology note: a range {@code a} is said to be the <i>maximal</i> range having property
- * <i>P</i> if, for all ranges {@code b} also having property <i>P</i>, {@code a.encloses(b)}.
- * Likewise, {@code a} is <i>minimal</i> when {@code b.encloses(a)} for all {@code b} having
- * property <i>P</i>. See, for example, the definition of {@link #intersection intersection}.
- * </ul>
+ * <p>A range {@code a} is said to be the <i>maximal</i> range having property
+ * <i>P</i> if, for all ranges {@code b} also having property <i>P</i>, {@code
+ * a.encloses(b)}. Likewise, {@code a} is <i>minimal</i> when {@code
+ * b.encloses(a)} for all {@code b} having property <i>P</i>. See, for example,
+ * the definition of {@link #intersection}.
*
- * <h3>Further reading</h3>
+ * <p>This class can be used with any type which implements {@code Comparable};
+ * it does not require {@code Comparable<? super C>} because this would be
+ * incompatible with pre-Java 5 types. If this class is used with a perverse
+ * {@code Comparable} type ({@code Foo implements Comparable<Bar>} where {@code
+ * Bar} is not a supertype of {@code Foo}), any of its methods may throw {@link
+ * ClassCastException}. (There is no good reason for such a type to exist.)
*
- * <p>See the Guava User Guide article on
- * <a href="http://code.google.com/p/guava-libraries/wiki/RangesExplained">{@code Range}</a>.
+ * <p>When evaluated as a {@link Predicate}, a range yields the same result as
+ * invoking {@link #contains}.
*
* @author Kevin Bourrillion
* @author Gregory Kick
* @since 10.0
*/
@GwtCompatible
-@SuppressWarnings("rawtypes")
-public final class Range<C extends Comparable> implements Predicate<C>, Serializable {
-
- private static final Function<Range, Cut> LOWER_BOUND_FN = new Function<Range, Cut>() {
- @Override
- public Cut apply(Range range) {
- return range.lowerBound;
- }
- };
-
- @SuppressWarnings("unchecked")
- static <C extends Comparable<?>> Function<Range<C>, Cut<C>> lowerBoundFn() {
- return (Function) LOWER_BOUND_FN;
- }
-
- private static final Function<Range, Cut> UPPER_BOUND_FN = new Function<Range, Cut>() {
- @Override
- public Cut apply(Range range) {
- return range.upperBound;
- }
- };
-
- @SuppressWarnings("unchecked")
- static <C extends Comparable<?>> Function<Range<C>, Cut<C>> upperBoundFn() {
- return (Function) UPPER_BOUND_FN;
- }
-
- static final Ordering<Range<?>> RANGE_LEX_ORDERING = new Ordering<Range<?>>() {
- @Override
- public int compare(Range<?> left, Range<?> right) {
- return ComparisonChain.start()
- .compare(left.lowerBound, right.lowerBound)
- .compare(left.upperBound, right.upperBound)
- .result();
- }
- };
-
- static <C extends Comparable<?>> Range<C> create(
- Cut<C> lowerBound, Cut<C> upperBound) {
- return new Range<C>(lowerBound, upperBound);
- }
-
- /**
- * Returns a range that contains all values strictly greater than {@code
- * lower} and strictly less than {@code upper}.
- *
- * @throws IllegalArgumentException if {@code lower} is greater than <i>or
- * equal to</i> {@code upper}
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> open(C lower, C upper) {
- return create(Cut.aboveValue(lower), Cut.belowValue(upper));
- }
-
- /**
- * Returns a range that contains all values greater than or equal to
- * {@code lower} and less than or equal to {@code upper}.
- *
- * @throws IllegalArgumentException if {@code lower} is greater than {@code
- * upper}
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> closed(C lower, C upper) {
- return create(Cut.belowValue(lower), Cut.aboveValue(upper));
- }
-
- /**
- * Returns a range that contains all values greater than or equal to
- * {@code lower} and strictly less than {@code upper}.
- *
- * @throws IllegalArgumentException if {@code lower} is greater than {@code
- * upper}
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> closedOpen(
- C lower, C upper) {
- return create(Cut.belowValue(lower), Cut.belowValue(upper));
- }
-
- /**
- * Returns a range that contains all values strictly greater than {@code
- * lower} and less than or equal to {@code upper}.
- *
- * @throws IllegalArgumentException if {@code lower} is greater than {@code
- * upper}
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> openClosed(
- C lower, C upper) {
- return create(Cut.aboveValue(lower), Cut.aboveValue(upper));
- }
-
- /**
- * Returns a range that contains any value from {@code lower} to {@code
- * upper}, where each endpoint may be either inclusive (closed) or exclusive
- * (open).
- *
- * @throws IllegalArgumentException if {@code lower} is greater than {@code
- * upper}
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> range(
- C lower, BoundType lowerType, C upper, BoundType upperType) {
- checkNotNull(lowerType);
- checkNotNull(upperType);
-
- Cut<C> lowerBound = (lowerType == BoundType.OPEN)
- ? Cut.aboveValue(lower)
- : Cut.belowValue(lower);
- Cut<C> upperBound = (upperType == BoundType.OPEN)
- ? Cut.belowValue(upper)
- : Cut.aboveValue(upper);
- return create(lowerBound, upperBound);
- }
-
- /**
- * Returns a range that contains all values strictly less than {@code
- * endpoint}.
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> lessThan(C endpoint) {
- return create(Cut.<C>belowAll(), Cut.belowValue(endpoint));
- }
-
- /**
- * Returns a range that contains all values less than or equal to
- * {@code endpoint}.
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> atMost(C endpoint) {
- return create(Cut.<C>belowAll(), Cut.aboveValue(endpoint));
- }
-
- /**
- * Returns a range with no lower bound up to the given endpoint, which may be
- * either inclusive (closed) or exclusive (open).
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> upTo(
- C endpoint, BoundType boundType) {
- switch (boundType) {
- case OPEN:
- return lessThan(endpoint);
- case CLOSED:
- return atMost(endpoint);
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Returns a range that contains all values strictly greater than {@code
- * endpoint}.
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> greaterThan(C endpoint) {
- return create(Cut.aboveValue(endpoint), Cut.<C>aboveAll());
- }
-
- /**
- * Returns a range that contains all values greater than or equal to
- * {@code endpoint}.
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> atLeast(C endpoint) {
- return create(Cut.belowValue(endpoint), Cut.<C>aboveAll());
- }
-
- /**
- * Returns a range from the given endpoint, which may be either inclusive
- * (closed) or exclusive (open), with no upper bound.
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> downTo(
- C endpoint, BoundType boundType) {
- switch (boundType) {
- case OPEN:
- return greaterThan(endpoint);
- case CLOSED:
- return atLeast(endpoint);
- default:
- throw new AssertionError();
- }
- }
-
- private static final Range<Comparable> ALL =
- new Range<Comparable>(Cut.belowAll(), Cut.aboveAll());
-
- /**
- * Returns a range that contains every value of type {@code C}.
- *
- * @since 14.0
- */
- @SuppressWarnings("unchecked")
- public static <C extends Comparable<?>> Range<C> all() {
- return (Range) ALL;
- }
-
- /**
- * Returns a range that {@linkplain Range#contains(Comparable) contains} only
- * the given value. The returned range is {@linkplain BoundType#CLOSED closed}
- * on both ends.
- *
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> singleton(C value) {
- return closed(value, value);
- }
-
- /**
- * Returns the minimal range that
- * {@linkplain Range#contains(Comparable) contains} all of the given values.
- * The returned range is {@linkplain BoundType#CLOSED closed} on both ends.
- *
- * @throws ClassCastException if the parameters are not <i>mutually
- * comparable</i>
- * @throws NoSuchElementException if {@code values} is empty
- * @throws NullPointerException if any of {@code values} is null
- * @since 14.0
- */
- public static <C extends Comparable<?>> Range<C> encloseAll(
- Iterable<C> values) {
- checkNotNull(values);
- if (values instanceof ContiguousSet) {
- return ((ContiguousSet<C>) values).range();
- }
- Iterator<C> valueIterator = values.iterator();
- C min = checkNotNull(valueIterator.next());
- C max = min;
- while (valueIterator.hasNext()) {
- C value = checkNotNull(valueIterator.next());
- min = Ordering.natural().min(min, value);
- max = Ordering.natural().max(max, value);
- }
- return closed(min, max);
- }
-
+@Beta
+public final class Range<C extends Comparable>
+ implements Predicate<C>, Serializable {
final Cut<C> lowerBound;
final Cut<C> upperBound;
- private Range(Cut<C> lowerBound, Cut<C> upperBound) {
- if (lowerBound.compareTo(upperBound) > 0 || lowerBound == Cut.<C>aboveAll()
- || upperBound == Cut.<C>belowAll()) {
- throw new IllegalArgumentException("Invalid range: " + toString(lowerBound, upperBound));
+ Range(Cut<C> lowerBound, Cut<C> upperBound) {
+ if (lowerBound.compareTo(upperBound) > 0) {
+ throw new IllegalArgumentException(
+ "Invalid range: " + toString(lowerBound, upperBound));
}
- this.lowerBound = checkNotNull(lowerBound);
- this.upperBound = checkNotNull(upperBound);
+ this.lowerBound = lowerBound;
+ this.upperBound = upperBound;
}
/**
@@ -379,19 +133,20 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
/**
* Returns the lower endpoint of this range.
*
- * @throws IllegalStateException if this range is unbounded below (that is, {@link
- * #hasLowerBound()} returns {@code false})
+ * @throws IllegalStateException if this range is unbounded below (that is,
+ * {@link #hasLowerBound()} returns {@code false})
*/
public C lowerEndpoint() {
return lowerBound.endpoint();
}
/**
- * Returns the type of this range's lower bound: {@link BoundType#CLOSED} if the range includes
- * its lower endpoint, {@link BoundType#OPEN} if it does not.
+ * Returns the type of this range's lower bound: {@link BoundType#CLOSED} if
+ * the range includes its lower endpoint, {@link BoundType#OPEN} if it does
+ * not.
*
- * @throws IllegalStateException if this range is unbounded below (that is, {@link
- * #hasLowerBound()} returns {@code false})
+ * @throws IllegalStateException if this range is unbounded below (that is,
+ * {@link #hasLowerBound()} returns {@code false})
*/
public BoundType lowerBoundType() {
return lowerBound.typeAsLowerBound();
@@ -407,41 +162,42 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
/**
* Returns the upper endpoint of this range.
*
- * @throws IllegalStateException if this range is unbounded above (that is, {@link
- * #hasUpperBound()} returns {@code false})
+ * @throws IllegalStateException if this range is unbounded above (that is,
+ * {@link #hasUpperBound()} returns {@code false})
*/
public C upperEndpoint() {
return upperBound.endpoint();
}
/**
- * Returns the type of this range's upper bound: {@link BoundType#CLOSED} if the range includes
- * its upper endpoint, {@link BoundType#OPEN} if it does not.
+ * Returns the type of this range's upper bound: {@link BoundType#CLOSED} if
+ * the range includes its upper endpoint, {@link BoundType#OPEN} if it does
+ * not.
*
- * @throws IllegalStateException if this range is unbounded above (that is, {@link
- * #hasUpperBound()} returns {@code false})
+ * @throws IllegalStateException if this range is unbounded above (that is,
+ * {@link #hasUpperBound()} returns {@code false})
*/
public BoundType upperBoundType() {
return upperBound.typeAsUpperBound();
}
/**
- * Returns {@code true} if this range is of the form {@code [v..v)} or {@code (v..v]}. (This does
- * not encompass ranges of the form {@code (v..v)}, because such ranges are <i>invalid</i> and
- * can't be constructed at all.)
+ * Returns {@code true} if this range is of the form {@code [v..v)} or {@code
+ * (v..v]}. (This does not encompass ranges of the form {@code (v..v)},
+ * because such ranges are <i>invalid</i> and can't be constructed at all.)
*
- * <p>Note that certain discrete ranges such as the integer range {@code (3..4)} are <b>not</b>
- * considered empty, even though they contain no actual values. In these cases, it may be
- * helpful to preprocess ranges with {@link #canonical(DiscreteDomain)}.
+ * <p>Note that certain discrete ranges such as the integer range {@code
+ * (3..4)} are <b>not</b> considered empty, even though they contain no actual
+ * values.
*/
public boolean isEmpty() {
return lowerBound.equals(upperBound);
}
/**
- * Returns {@code true} if {@code value} is within the bounds of this range. For example, on the
- * range {@code [0..2)}, {@code contains(1)} returns {@code true}, while {@code contains(2)}
- * returns {@code false}.
+ * Returns {@code true} if {@code value} is within the bounds of this
+ * range. For example, on the range {@code [0..2)}, {@code contains(1)}
+ * returns {@code true}, while {@code contains(2)} returns {@code false}.
*/
public boolean contains(C value) {
checkNotNull(value);
@@ -450,16 +206,17 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
}
/**
- * Equivalent to {@link #contains}; provided only to satisfy the {@link Predicate} interface. When
- * using a reference of type {@code Range}, always invoke {@link #contains} directly instead.
+ * Equivalent to {@link #contains}; provided only to satisfy the {@link
+ * Predicate} interface. When using a reference of type {@code Range}, always
+ * invoke {@link #contains} directly instead.
*/
@Override public boolean apply(C input) {
return contains(input);
}
/**
- * Returns {@code true} if every element in {@code values} is {@linkplain #contains contained} in
- * this range.
+ * Returns {@code true} if every element in {@code values} is {@linkplain
+ * #contains contained} in this range.
*/
public boolean containsAll(Iterable<? extends C> values) {
if (Iterables.isEmpty(values)) {
@@ -484,27 +241,42 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
}
/**
- * Returns {@code true} if the bounds of {@code other} do not extend outside the bounds of this
- * range. Examples:
+ * Returns {@code true} if the bounds of {@code other} do not extend outside
+ * the bounds of this range. Examples:
*
* <ul>
* <li>{@code [3..6]} encloses {@code [4..5]}
* <li>{@code (3..6)} encloses {@code (3..6)}
- * <li>{@code [3..6]} encloses {@code [4..4)} (even though the latter is empty)
+ * <li>{@code [3..6]} encloses {@code [4..4)} (even though the latter is
+ * empty)
* <li>{@code (3..6]} does not enclose {@code [3..6]}
- * <li>{@code [4..5]} does not enclose {@code (3..6)} (even though it contains every value
- * contained by the latter range)
- * <li>{@code [3..6]} does not enclose {@code (1..1]} (even though it contains every value
- * contained by the latter range)
+ * <li>{@code [4..5]} does not enclose {@code (3..6)} (even though it contains
+ * every value contained by the latter range)
+ * <li>{@code [3..6]} does not enclose {@code (1..1]} (even though it contains
+ * every value contained by the latter range)
* </ul>
*
- * Note that if {@code a.encloses(b)}, then {@code b.contains(v)} implies {@code a.contains(v)},
- * but as the last two examples illustrate, the converse is not always true.
+ * Note that if {@code a.encloses(b)}, then {@code b.contains(v)} implies
+ * {@code a.contains(v)}, but as the last two examples illustrate, the
+ * converse is not always true.
*
- * <p>Being reflexive, antisymmetric and transitive, the {@code encloses} relation defines a
- * <i>partial order</i> over ranges. There exists a unique {@linkplain Range#all maximal} range
- * according to this relation, and also numerous {@linkplain #isEmpty minimal} ranges. Enclosure
- * also implies {@linkplain #isConnected connectedness}.
+ * <p>The encloses relation has the following properties:
+ *
+ * <ul>
+ * <li>reflexive: {@code a.encloses(a)} is always true
+ * <li>antisymmetric: {@code a.encloses(b) && b.encloses(a)} implies {@code
+ * a.equals(b)}
+ * <li>transitive: {@code a.encloses(b) && b.encloses(c)} implies {@code
+ * a.encloses(c)}
+ * <li>not a total ordering: {@code !a.encloses(b)} does not imply {@code
+ * b.encloses(a)}
+ * <li>there exists a {@linkplain Ranges#all maximal} range, for which
+ * {@code encloses} is always true
+ * <li>there also exist {@linkplain #isEmpty minimal} ranges, for
+ * which {@code encloses(b)} is always false when {@code !equals(b)}
+ * <li>if {@code a.encloses(b)}, then {@link #isConnected a.isConnected(b)}
+ * is {@code true}.
+ * </ul>
*/
public boolean encloses(Range<C> other) {
return lowerBound.compareTo(other.lowerBound) <= 0
@@ -512,133 +284,160 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
}
/**
- * Returns {@code true} if there exists a (possibly empty) range which is {@linkplain #encloses
- * enclosed} by both this range and {@code other}.
+ * Returns the maximal range {@linkplain #encloses enclosed} by both this
+ * range and {@code other}, if such a range exists.
+ *
+ * <p>For example, the intersection of {@code [1..5]} and {@code (3..7)} is
+ * {@code (3..5]}. The resulting range may be empty; for example,
+ * {@code [1..5)} intersected with {@code [5..7)} yields the empty range
+ * {@code [5..5)}.
+ *
+ * <p>Generally, the intersection exists if and only if this range and
+ * {@code other} are {@linkplain #isConnected connected}.
+ *
+ * <p>The intersection operation has the following properties:
*
- * <p>For example,
* <ul>
- * <li>{@code [2, 4)} and {@code [5, 7)} are not connected
- * <li>{@code [2, 4)} and {@code [3, 5)} are connected, because both enclose {@code [3, 4)}
- * <li>{@code [2, 4)} and {@code [4, 6)} are connected, because both enclose the empty range
- * {@code [4, 4)}
+ * <li>commutative: {@code a.intersection(b)} produces the same result as
+ * {@code b.intersection(a)}
+ * <li>associative: {@code a.intersection(b).intersection(c)} produces the
+ * same result as {@code a.intersection(b.intersection(c))}
+ * <li>idempotent: {@code a.intersection(a)} equals {@code a}
+ * <li>identity ({@link Ranges#all}): {@code a.intersection(Ranges.all())}
+ * equals {@code a}
* </ul>
*
- * <p>Note that this range and {@code other} have a well-defined {@linkplain #span union} and
- * {@linkplain #intersection intersection} (as a single, possibly-empty range) if and only if this
- * method returns {@code true}.
- *
- * <p>The connectedness relation is both reflexive and symmetric, but does not form an {@linkplain
- * Equivalence equivalence relation} as it is not transitive.
- *
- * <p>Note that certain discrete ranges are not considered connected, even though there are no
- * elements "between them." For example, {@code [3, 5]} is not considered connected to {@code
- * [6, 10]}. In these cases, it may be desirable for both input ranges to be preprocessed with
- * {@link #canonical(DiscreteDomain)} before testing for connectedness.
+ * @throws IllegalArgumentException if no range exists that is enclosed by
+ * both these ranges
*/
- public boolean isConnected(Range<C> other) {
- return lowerBound.compareTo(other.upperBound) <= 0
- && other.lowerBound.compareTo(upperBound) <= 0;
+ public Range<C> intersection(Range<C> other) {
+ Cut<C> newLower = Ordering.natural().max(lowerBound, other.lowerBound);
+ Cut<C> newUpper = Ordering.natural().min(upperBound, other.upperBound);
+ return create(newLower, newUpper);
}
/**
- * Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code
- * connectedRange}, if such a range exists.
- *
- * <p>For example, the intersection of {@code [1..5]} and {@code (3..7)} is {@code (3..5]}. The
- * resulting range may be empty; for example, {@code [1..5)} intersected with {@code [5..7)}
- * yields the empty range {@code [5..5)}.
- *
- * <p>The intersection exists if and only if the two ranges are {@linkplain #isConnected
- * connected}.
- *
- * <p>The intersection operation is commutative, associative and idempotent, and its identity
- * element is {@link Range#all}).
+ * Returns {@code true} if there exists a (possibly empty) range which is
+ * {@linkplain #encloses enclosed} by both this range and {@code other}.
+ *
+ * <p>For example,
+ * <ul>
+ * <li>{@code [2, 4)} and {@code [5, 7)} are not connected
+ * <li>{@code [2, 4)} and {@code [3, 5)} are connected, because both enclose
+ * {@code [3, 4)}
+ * <li>{@code [2, 4)} and {@code [4, 6)} are connected, because both enclose
+ * the empty range {@code [4, 4)}
+ * </ul>
+ *
+ * <p>Note that this range and {@code other} have a well-defined {@linkplain
+ * #span union} and {@linkplain #intersection intersection} (as a single,
+ * possibly-empty range) if and only if this method returns {@code true}.
+ *
+ * <p>The connectedness relation has the following properties:
*
- * @throws IllegalArgumentException if {@code isConnected(connectedRange)} is {@code false}
+ * <ul>
+ * <li>symmetric: {@code a.isConnected(b)} produces the same result as
+ * {@code b.isConnected(a)}
+ * <li>reflexive: {@code a.isConnected(a)} returns {@code true}
+ * </ul>
*/
- public Range<C> intersection(Range<C> connectedRange) {
- int lowerCmp = lowerBound.compareTo(connectedRange.lowerBound);
- int upperCmp = upperBound.compareTo(connectedRange.upperBound);
- if (lowerCmp >= 0 && upperCmp <= 0) {
- return this;
- } else if (lowerCmp <= 0 && upperCmp >= 0) {
- return connectedRange;
- } else {
- Cut<C> newLower = (lowerCmp >= 0) ? lowerBound : connectedRange.lowerBound;
- Cut<C> newUpper = (upperCmp <= 0) ? upperBound : connectedRange.upperBound;
- return create(newLower, newUpper);
- }
+ public boolean isConnected(Range<C> other) {
+ return lowerBound.compareTo(other.upperBound) <= 0
+ && other.lowerBound.compareTo(upperBound) <= 0;
}
/**
- * Returns the minimal range that {@linkplain #encloses encloses} both this range and {@code
- * other}. For example, the span of {@code [1..3]} and {@code (5..7)} is {@code [1..7)}.
+ * Returns the minimal range that {@linkplain #encloses encloses} both this
+ * range and {@code other}. For example, the span of {@code [1..3]} and
+ * {@code (5..7)} is {@code [1..7)}. Note that the span may contain values
+ * that are not contained by either original range.
*
- * <p><i>If</i> the input ranges are {@linkplain #isConnected connected}, the returned range can
- * also be called their <i>union</i>. If they are not, note that the span might contain values
- * that are not contained in either input range.
+ * <p>The span operation has the following properties:
*
- * <p>Like {@link #intersection(Range) intersection}, this operation is commutative, associative
- * and idempotent. Unlike it, it is always well-defined for any two input ranges.
+ * <ul>
+ * <li>closed: the range {@code a.span(b)} exists for all ranges {@code a} and
+ * {@code b}
+ * <li>commutative: {@code a.span(b)} equals {@code b.span(a)}
+ * <li>associative: {@code a.span(b).span(c)} equals {@code a.span(b.span(c))}
+ * <li>idempotent: {@code a.span(a)} equals {@code a}
+ * </ul>
+ *
+ * <p>Note that the returned range is also called the <i>union</i> of this
+ * range and {@code other} if and only if the ranges are
+ * {@linkplain #isConnected connected}.
*/
public Range<C> span(Range<C> other) {
- int lowerCmp = lowerBound.compareTo(other.lowerBound);
- int upperCmp = upperBound.compareTo(other.upperBound);
- if (lowerCmp <= 0 && upperCmp >= 0) {
- return this;
- } else if (lowerCmp >= 0 && upperCmp <= 0) {
- return other;
- } else {
- Cut<C> newLower = (lowerCmp <= 0) ? lowerBound : other.lowerBound;
- Cut<C> newUpper = (upperCmp >= 0) ? upperBound : other.upperBound;
- return create(newLower, newUpper);
- }
+ Cut<C> newLower = Ordering.natural().min(lowerBound, other.lowerBound);
+ Cut<C> newUpper = Ordering.natural().max(upperBound, other.upperBound);
+ return create(newLower, newUpper);
}
/**
- * Returns an {@link ContiguousSet} containing the same values in the given domain
- * {@linkplain Range#contains contained} by this range.
+ * Returns an {@link ImmutableSortedSet} containing the same values in the
+ * given domain {@linkplain Range#contains contained} by this range.
*
- * <p><b>Note:</b> {@code a.asSet(d).equals(b.asSet(d))} does not imply {@code a.equals(b)}! For
- * example, {@code a} and {@code b} could be {@code [2..4]} and {@code (1..5)}, or the empty
- * ranges {@code [3..3)} and {@code [4..4)}.
+ * <p><b>Note:</b> {@code a.asSet().equals(b.asSet())} does not imply {@code
+ * a.equals(b)}! For example, {@code a} and {@code b} could be {@code [2..4]}
+ * and {@code (1..5)}, or the empty ranges {@code [3..3)} and {@code [4..4)}.
*
- * <p><b>Warning:</b> Be extremely careful what you do with the {@code asSet} view of a large
- * range (such as {@code Range.greaterThan(0)}). Certain operations on such a set can be
- * performed efficiently, but others (such as {@link Set#hashCode} or {@link
- * Collections#frequency}) can cause major performance problems.
+ * <p><b>Warning:</b> Be extremely careful what you do with the {@code asSet}
+ * view of a large range (such as {@code Ranges.greaterThan(0)}). Certain
+ * operations on such a set can be performed efficiently, but others (such as
+ * {@link Set#hashCode} or {@link Collections#frequency}) can cause major
+ * performance problems.
*
- * <p>The returned set's {@link Object#toString} method returns a short-hand form of the set's
- * contents, such as {@code "[1..100]}"}.
+ * <p>The returned set's {@link Object#toString} method returns a short-hand
+ * form of set's contents such as {@code "[1..100]}"}.
*
- * @throws IllegalArgumentException if neither this range nor the domain has a lower bound, or if
- * neither has an upper bound
- * @deprecated Use {@code ContiguousSet.create(range, domain)} instead.
+ * @throws IllegalArgumentException if neither this range nor the domain has a
+ * lower bound, or if neither has an upper bound
*/
// TODO(kevinb): commit in spec to which methods are efficient?
- @Beta
@GwtCompatible(serializable = false)
- @Deprecated
public ContiguousSet<C> asSet(DiscreteDomain<C> domain) {
- return ContiguousSet.create(this, domain);
+ checkNotNull(domain);
+ Range<C> effectiveRange = this;
+ try {
+ if (!hasLowerBound()) {
+ effectiveRange = effectiveRange.intersection(
+ Ranges.atLeast(domain.minValue()));
+ }
+ if (!hasUpperBound()) {
+ effectiveRange = effectiveRange.intersection(
+ Ranges.atMost(domain.maxValue()));
+ }
+ } catch (NoSuchElementException e) {
+ throw new IllegalArgumentException(e);
+ }
+
+ // Per class spec, we are allowed to throw CCE if necessary
+ boolean empty = effectiveRange.isEmpty()
+ || compareOrThrow(
+ lowerBound.leastValueAbove(domain),
+ upperBound.greatestValueBelow(domain)) > 0;
+
+ return empty
+ ? new EmptyContiguousSet<C>(domain)
+ : new RegularContiguousSet<C>(effectiveRange, domain);
}
/**
- * Returns the canonical form of this range in the given domain. The canonical form has the
- * following properties:
+ * Returns the canonical form of this range in the given domain. The canonical
+ * form has the following properties:
*
* <ul>
- * <li>equivalence: {@code a.canonical().contains(v) == a.contains(v)} for all {@code v} (in other
- * words, {@code ContiguousSet.create(a.canonical(domain), domain).equals(
- * ContiguousSet.create(a, domain))}
+ * <li>equivalence: {@code a.canonical().contains(v) == a.contains(v)} for
+ * all {@code v} (in other words, {@code
+ * a.canonical(domain).asSet(domain).equals(a.asSet(domain))}
* <li>uniqueness: unless {@code a.isEmpty()},
- * {@code ContiguousSet.create(a, domain).equals(ContiguousSet.create(b, domain))} implies
+ * {@code a.asSet(domain).equals(b.asSet(domain))} implies
* {@code a.canonical(domain).equals(b.canonical(domain))}
- * <li>idempotence: {@code a.canonical(domain).canonical(domain).equals(a.canonical(domain))}
+ * <li>idempotence: {@code
+ * a.canonical(domain).canonical(domain).equals(a.canonical(domain))}
* </ul>
*
- * Furthermore, this method guarantees that the range returned will be one of the following
- * canonical forms:
+ * Furthermore, this method guarantees that the range returned will be one
+ * of the following canonical forms:
*
* <ul>
* <li>[start..end)
@@ -651,15 +450,18 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
checkNotNull(domain);
Cut<C> lower = lowerBound.canonical(domain);
Cut<C> upper = upperBound.canonical(domain);
- return (lower == lowerBound && upper == upperBound) ? this : create(lower, upper);
+ return (lower == lowerBound && upper == upperBound)
+ ? this : create(lower, upper);
}
/**
- * Returns {@code true} if {@code object} is a range having the same endpoints and bound types as
- * this range. Note that discrete ranges such as {@code (1..4)} and {@code [2..3]} are <b>not</b>
- * equal to one another, despite the fact that they each contain precisely the same set of values.
- * Similarly, empty ranges are not equal unless they have exactly the same representation, so
- * {@code [3..3)}, {@code (3..3]}, {@code (4..4]} are all unequal.
+ * Returns {@code true} if {@code object} is a range having the same
+ * endpoints and bound types as this range. Note that discrete ranges
+ * such as {@code (1..4)} and {@code [2..3]} are <b>not</b> equal to one
+ * another, despite the fact that they each contain precisely the same set of
+ * values. Similarly, empty ranges are not equal unless they have exactly
+ * the same representation, so {@code [3..3)}, {@code (3..3]}, {@code (4..4]}
+ * are all unequal.
*/
@Override public boolean equals(@Nullable Object object) {
if (object instanceof Range) {
@@ -676,8 +478,8 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
}
/**
- * Returns a string representation of this range, such as {@code "[3..5)"} (other examples are
- * listed in the class documentation).
+ * Returns a string representation of this range, such as {@code "[3..5)"}
+ * (other examples are listed in the class documentation).
*/
@Override public String toString() {
return toString(lowerBound, upperBound);
@@ -698,14 +500,6 @@ public final class Range<C extends Comparable> implements Predicate<C>, Serializ
return (SortedSet<T>) iterable;
}
- Object readResolve() {
- if (this.equals(ALL)) {
- return all();
- } else {
- return this;
- }
- }
-
@SuppressWarnings("unchecked") // this method may throw CCE
static int compareOrThrow(Comparable left, Comparable right) {
return left.compareTo(right);
diff --git a/guava/src/com/google/common/collect/RangeMap.java b/guava/src/com/google/common/collect/RangeMap.java
deleted file mode 100644
index ba42985..0000000
--- a/guava/src/com/google/common/collect/RangeMap.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.Beta;
-
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-/**
- * A mapping from disjoint nonempty ranges to non-null values. Queries look up the value
- * associated with the range (if any) that contains a specified key.
- *
- * <p>In contrast to {@link RangeSet}, no "coalescing" is done of {@linkplain
- * Range#isConnected(Range) connected} ranges, even if they are mapped to the same value.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-public interface RangeMap<K extends Comparable, V> {
- /**
- * Returns the value associated with the specified key, or {@code null} if there is no
- * such value.
- *
- * <p>Specifically, if any range in this range map contains the specified key, the value
- * associated with that range is returned.
- */
- @Nullable
- V get(K key);
-
- /**
- * Returns the range containing this key and its associated value, if such a range is present
- * in the range map, or {@code null} otherwise.
- */
- @Nullable
- Map.Entry<Range<K>, V> getEntry(K key);
-
- /**
- * Returns the minimal range {@linkplain Range#encloses(Range) enclosing} the ranges
- * in this {@code RangeMap}.
- *
- * @throws NoSuchElementException if this range map is empty
- */
- Range<K> span();
-
- /**
- * Maps a range to a specified value (optional operation).
- *
- * <p>Specifically, after a call to {@code put(range, value)}, if
- * {@link Range#contains(Comparable) range.contains(k)}, then {@link #get(Comparable) get(k)}
- * will return {@code value}.
- *
- * <p>If {@code range} {@linkplain Range#isEmpty() is empty}, then this is a no-op.
- */
- void put(Range<K> range, V value);
-
- /**
- * Puts all the associations from {@code rangeMap} into this range map (optional operation).
- */
- void putAll(RangeMap<K, V> rangeMap);
-
- /**
- * Removes all associations from this range map (optional operation).
- */
- void clear();
-
- /**
- * Removes all associations from this range map in the specified range (optional operation).
- *
- * <p>If {@code !range.contains(k)}, {@link #get(Comparable) get(k)} will return the same result
- * before and after a call to {@code remove(range)}. If {@code range.contains(k)}, then
- * after a call to {@code remove(range)}, {@code get(k)} will return {@code null}.
- */
- void remove(Range<K> range);
-
- /**
- * Returns a view of this range map as an unmodifiable {@code Map<Range<K>, V>}.
- * Modifications to this range map are guaranteed to read through to the returned {@code Map}.
- *
- * <p>It is guaranteed that no empty ranges will be in the returned {@code Map}.
- */
- Map<Range<K>, V> asMapOfRanges();
-
- /**
- * Returns a view of the part of this range map that intersects with {@code range}.
- *
- * <p>For example, if {@code rangeMap} had the entries
- * {@code [1, 5] => "foo", (6, 8) => "bar", (10, \u2025) => "baz"}
- * then {@code rangeMap.subRangeMap(Range.open(3, 12))} would return a range map
- * with the entries {@code (3, 5) => "foo", (6, 8) => "bar", (10, 12) => "baz"}.
- *
- * <p>The returned range map supports all optional operations that this range map supports,
- * except for {@code asMapOfRanges().iterator().remove()}.
- *
- * <p>The returned range map will throw an {@link IllegalArgumentException} on an attempt to
- * insert a range not {@linkplain Range#encloses(Range) enclosed} by {@code range}.
- */
- RangeMap<K, V> subRangeMap(Range<K> range);
-
- /**
- * Returns {@code true} if {@code obj} is another {@code RangeMap} that has an equivalent
- * {@link #asMapOfRanges()}.
- */
- @Override
- boolean equals(@Nullable Object o);
-
- /**
- * Returns {@code asMapOfRanges().hashCode()}.
- */
- @Override
- int hashCode();
-
- /**
- * Returns a readable string representation of this range map.
- */
- @Override
- String toString();
-}
diff --git a/guava/src/com/google/common/collect/RangeSet.java b/guava/src/com/google/common/collect/RangeSet.java
deleted file mode 100644
index f07c1fc..0000000
--- a/guava/src/com/google/common/collect/RangeSet.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.Beta;
-
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * A set comprising zero or more {@linkplain Range#isEmpty nonempty},
- * {@linkplain Range#isConnected(Range) disconnected} ranges of type {@code C}.
- *
- * <p>Implementations that choose to support the {@link #add(Range)} operation are required to
- * ignore empty ranges and coalesce connected ranges. For example: <pre> {@code
- *
- * RangeSet<Integer> rangeSet = TreeRangeSet.create();
- * rangeSet.add(Range.closed(1, 10)); // {[1, 10]}
- * rangeSet.add(Range.closedOpen(11, 15)); // {[1, 10], [11, 15)}
- * rangeSet.add(Range.open(15, 20)); // disconnected range; {[1, 10], [11, 20)}
- * rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 20)}
- * rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 20)}}</pre>
- *
- * <p>Note that the behavior of {@link Range#isEmpty()} and {@link Range#isConnected(Range)} may
- * not be as expected on discrete ranges. See the Javadoc of those methods for details.
- *
- * <p>For a {@link Set} whose contents are specified by a {@link Range}, see {@link ContiguousSet}.
- *
- * @author Kevin Bourrillion
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-public interface RangeSet<C extends Comparable> {
-
- // Query methods
-
- /**
- * Determines whether any of this range set's member ranges contains {@code value}.
- */
- boolean contains(C value);
-
- /**
- * Returns the unique range from this range set that {@linkplain Range#contains contains}
- * {@code value}, or {@code null} if this range set does not contain {@code value}.
- */
- Range<C> rangeContaining(C value);
-
- /**
- * Returns {@code true} if there exists a member range in this range set which
- * {@linkplain Range#encloses encloses} the specified range.
- */
- boolean encloses(Range<C> otherRange);
-
- /**
- * Returns {@code true} if for each member range in {@code other} there exists a member range in
- * this range set which {@linkplain Range#encloses encloses} it. It follows that
- * {@code this.contains(value)} whenever {@code other.contains(value)}. Returns {@code true} if
- * {@code other} is empty.
- *
- * <p>This is equivalent to checking if this range set {@link #encloses} each of the ranges in
- * {@code other}.
- */
- boolean enclosesAll(RangeSet<C> other);
-
- /**
- * Returns {@code true} if this range set contains no ranges.
- */
- boolean isEmpty();
-
- /**
- * Returns the minimal range which {@linkplain Range#encloses(Range) encloses} all ranges
- * in this range set.
- *
- * @throws NoSuchElementException if this range set is {@linkplain #isEmpty() empty}
- */
- Range<C> span();
-
- // Views
-
- /**
- * Returns a view of the {@linkplain Range#isConnected disconnected} ranges that make up this
- * range set. The returned set may be empty. The iterators returned by its
- * {@link Iterable#iterator} method return the ranges in increasing order of lower bound
- * (equivalently, of upper bound).
- */
- Set<Range<C>> asRanges();
-
- /**
- * Returns a view of the complement of this {@code RangeSet}.
- *
- * <p>The returned view supports the {@link #add} operation if this {@code RangeSet} supports
- * {@link #remove}, and vice versa.
- */
- RangeSet<C> complement();
-
- /**
- * Returns a view of the intersection of this {@code RangeSet} with the specified range.
- *
- * <p>The returned view supports all optional operations supported by this {@code RangeSet}, with
- * the caveat that an {@link IllegalArgumentException} is thrown on an attempt to
- * {@linkplain #add(Range) add} any range not {@linkplain Range#encloses(Range) enclosed} by
- * {@code view}.
- */
- RangeSet<C> subRangeSet(Range<C> view);
-
- // Modification
-
- /**
- * Adds the specified range to this {@code RangeSet} (optional operation). That is, for equal
- * range sets a and b, the result of {@code a.add(range)} is that {@code a} will be the minimal
- * range set for which both {@code a.enclosesAll(b)} and {@code a.encloses(range)}.
- *
- * <p>Note that {@code range} will be {@linkplain Range#span(Range) coalesced} with any ranges in
- * the range set that are {@linkplain Range#isConnected(Range) connected} with it. Moreover,
- * if {@code range} is empty, this is a no-op.
- *
- * @throws UnsupportedOperationException if this range set does not support the {@code add}
- * operation
- */
- void add(Range<C> range);
-
- /**
- * Removes the specified range from this {@code RangeSet} (optional operation). After this
- * operation, if {@code range.contains(c)}, {@code this.contains(c)} will return {@code false}.
- *
- * <p>If {@code range} is empty, this is a no-op.
- *
- * @throws UnsupportedOperationException if this range set does not support the {@code remove}
- * operation
- */
- void remove(Range<C> range);
-
- /**
- * Removes all ranges from this {@code RangeSet} (optional operation). After this operation,
- * {@code this.contains(c)} will return false for all {@code c}.
- *
- * <p>This is equivalent to {@code remove(Range.all())}.
- *
- * @throws UnsupportedOperationException if this range set does not support the {@code clear}
- * operation
- */
- void clear();
-
- /**
- * Adds all of the ranges from the specified range set to this range set (optional operation).
- * After this operation, this range set is the minimal range set that
- * {@linkplain #enclosesAll(RangeSet) encloses} both the original range set and {@code other}.
- *
- * <p>This is equivalent to calling {@link #add} on each of the ranges in {@code other} in turn.
- *
- * @throws UnsupportedOperationException if this range set does not support the {@code addAll}
- * operation
- */
- void addAll(RangeSet<C> other);
-
- /**
- * Removes all of the ranges from the specified range set from this range set (optional
- * operation). After this operation, if {@code other.contains(c)}, {@code this.contains(c)} will
- * return {@code false}.
- *
- * <p>This is equivalent to calling {@link #remove} on each of the ranges in {@code other} in
- * turn.
- *
- * @throws UnsupportedOperationException if this range set does not support the {@code removeAll}
- * operation
- */
- void removeAll(RangeSet<C> other);
-
- // Object methods
-
- /**
- * Returns {@code true} if {@code obj} is another {@code RangeSet} that contains the same ranges
- * according to {@link Range#equals(Object)}.
- */
- @Override
- boolean equals(@Nullable Object obj);
-
- /**
- * Returns {@code asRanges().hashCode()}.
- */
- @Override
- int hashCode();
-
- /**
- * Returns a readable string representation of this range set. For example, if this
- * {@code RangeSet} consisted of {@code Ranges.closed(1, 3)} and {@code Ranges.greaterThan(4)},
- * this might return {@code " [1‥3](4‥+∞)}"}.
- */
- @Override
- String toString();
-}
diff --git a/guava/src/com/google/common/collect/Ranges.java b/guava/src/com/google/common/collect/Ranges.java
index 75cbc1e..131bf3b 100644
--- a/guava/src/com/google/common/collect/Ranges.java
+++ b/guava/src/com/google/common/collect/Ranges.java
@@ -16,9 +16,12 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
+import java.util.Iterator;
import java.util.NoSuchElementException;
/**
@@ -59,21 +62,20 @@ import java.util.NoSuchElementException;
* <dd>{@link #upTo}
* </dl>
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/RangesExplained">
- * {@code Range}</a>.
- *
* @author Kevin Bourrillion
* @author Gregory Kick
* @since 10.0
- * @deprecated Use the corresponding method in {@link Range}.
*/
-@Deprecated
@GwtCompatible
@Beta
public final class Ranges {
private Ranges() {}
+ static <C extends Comparable<?>> Range<C> create(
+ Cut<C> lowerBound, Cut<C> upperBound) {
+ return new Range<C>(lowerBound, upperBound);
+ }
+
/**
* Returns a range that contains all values strictly greater than {@code
* lower} and strictly less than {@code upper}.
@@ -82,7 +84,7 @@ public final class Ranges {
* equal to</i> {@code upper}
*/
public static <C extends Comparable<?>> Range<C> open(C lower, C upper) {
- return Range.open(lower, upper);
+ return create(Cut.aboveValue(lower), Cut.belowValue(upper));
}
/**
@@ -93,7 +95,7 @@ public final class Ranges {
* upper}
*/
public static <C extends Comparable<?>> Range<C> closed(C lower, C upper) {
- return Range.closed(lower, upper);
+ return create(Cut.belowValue(lower), Cut.aboveValue(upper));
}
/**
@@ -105,7 +107,7 @@ public final class Ranges {
*/
public static <C extends Comparable<?>> Range<C> closedOpen(
C lower, C upper) {
- return Range.closedOpen(lower, upper);
+ return create(Cut.belowValue(lower), Cut.belowValue(upper));
}
/**
@@ -117,7 +119,7 @@ public final class Ranges {
*/
public static <C extends Comparable<?>> Range<C> openClosed(
C lower, C upper) {
- return Range.openClosed(lower, upper);
+ return create(Cut.aboveValue(lower), Cut.aboveValue(upper));
}
/**
@@ -130,7 +132,16 @@ public final class Ranges {
*/
public static <C extends Comparable<?>> Range<C> range(
C lower, BoundType lowerType, C upper, BoundType upperType) {
- return Range.range(lower, lowerType, upper, upperType);
+ checkNotNull(lowerType);
+ checkNotNull(upperType);
+
+ Cut<C> lowerBound = (lowerType == BoundType.OPEN)
+ ? Cut.aboveValue(lower)
+ : Cut.belowValue(lower);
+ Cut<C> upperBound = (upperType == BoundType.OPEN)
+ ? Cut.belowValue(upper)
+ : Cut.aboveValue(upper);
+ return create(lowerBound, upperBound);
}
/**
@@ -138,7 +149,7 @@ public final class Ranges {
* endpoint}.
*/
public static <C extends Comparable<?>> Range<C> lessThan(C endpoint) {
- return Range.lessThan(endpoint);
+ return create(Cut.<C>belowAll(), Cut.belowValue(endpoint));
}
/**
@@ -146,7 +157,7 @@ public final class Ranges {
* {@code endpoint}.
*/
public static <C extends Comparable<?>> Range<C> atMost(C endpoint) {
- return Range.atMost(endpoint);
+ return create(Cut.<C>belowAll(), Cut.aboveValue(endpoint));
}
/**
@@ -155,7 +166,14 @@ public final class Ranges {
*/
public static <C extends Comparable<?>> Range<C> upTo(
C endpoint, BoundType boundType) {
- return Range.upTo(endpoint, boundType);
+ switch (boundType) {
+ case OPEN:
+ return lessThan(endpoint);
+ case CLOSED:
+ return atMost(endpoint);
+ default:
+ throw new AssertionError();
+ }
}
/**
@@ -163,7 +181,7 @@ public final class Ranges {
* endpoint}.
*/
public static <C extends Comparable<?>> Range<C> greaterThan(C endpoint) {
- return Range.greaterThan(endpoint);
+ return create(Cut.aboveValue(endpoint), Cut.<C>aboveAll());
}
/**
@@ -171,7 +189,7 @@ public final class Ranges {
* {@code endpoint}.
*/
public static <C extends Comparable<?>> Range<C> atLeast(C endpoint) {
- return Range.atLeast(endpoint);
+ return create(Cut.belowValue(endpoint), Cut.<C>aboveAll());
}
/**
@@ -180,12 +198,19 @@ public final class Ranges {
*/
public static <C extends Comparable<?>> Range<C> downTo(
C endpoint, BoundType boundType) {
- return Range.downTo(endpoint, boundType);
+ switch (boundType) {
+ case OPEN:
+ return greaterThan(endpoint);
+ case CLOSED:
+ return atLeast(endpoint);
+ default:
+ throw new AssertionError();
+ }
}
/** Returns a range that contains every value of type {@code C}. */
public static <C extends Comparable<?>> Range<C> all() {
- return Range.all();
+ return create(Cut.<C>belowAll(), Cut.<C>aboveAll());
}
/**
@@ -194,7 +219,7 @@ public final class Ranges {
* on both ends.
*/
public static <C extends Comparable<?>> Range<C> singleton(C value) {
- return Range.singleton(value);
+ return closed(value, value);
}
/**
@@ -209,6 +234,18 @@ public final class Ranges {
*/
public static <C extends Comparable<?>> Range<C> encloseAll(
Iterable<C> values) {
- return Range.encloseAll(values);
+ checkNotNull(values);
+ if (values instanceof ContiguousSet) {
+ return ((ContiguousSet<C>) values).range();
+ }
+ Iterator<C> valueIterator = values.iterator();
+ C min = checkNotNull(valueIterator.next());
+ C max = min;
+ while (valueIterator.hasNext()) {
+ C value = checkNotNull(valueIterator.next());
+ min = Ordering.natural().min(min, value);
+ max = Ordering.natural().max(max, value);
+ }
+ return closed(min, max);
}
}
diff --git a/guava/src/com/google/common/collect/RegularContiguousSet.java b/guava/src/com/google/common/collect/RegularContiguousSet.java
index 7948fe8..10b26f9 100644
--- a/guava/src/com/google/common/collect/RegularContiguousSet.java
+++ b/guava/src/com/google/common/collect/RegularContiguousSet.java
@@ -41,38 +41,32 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
this.range = range;
}
- private ContiguousSet<C> intersectionInCurrentDomain(Range<C> other) {
- return (range.isConnected(other))
- ? ContiguousSet.create(range.intersection(other), domain)
- : new EmptyContiguousSet<C>(domain);
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ ContiguousSet<C> headSetImpl(C toElement, boolean inclusive) {
+ return range.intersection(Ranges.upTo(toElement, BoundType.forBoolean(inclusive)))
+ .asSet(domain);
}
- @Override ContiguousSet<C> headSetImpl(C toElement, boolean inclusive) {
- return intersectionInCurrentDomain(Range.upTo(toElement, BoundType.forBoolean(inclusive)));
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ int indexOf(Object target) {
+ return contains(target) ? (int) domain.distance(first(), (C) target) : -1;
}
- @Override ContiguousSet<C> subSetImpl(C fromElement, boolean fromInclusive, C toElement,
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ ContiguousSet<C> subSetImpl(C fromElement, boolean fromInclusive, C toElement,
boolean toInclusive) {
- if (fromElement.compareTo(toElement) == 0 && !fromInclusive && !toInclusive) {
- // Range would reject our attempt to create (x, x).
- return new EmptyContiguousSet<C>(domain);
- }
- return intersectionInCurrentDomain(Range.range(
- fromElement, BoundType.forBoolean(fromInclusive),
- toElement, BoundType.forBoolean(toInclusive)));
+ return range.intersection(Ranges.range(fromElement, BoundType.forBoolean(fromInclusive),
+ toElement, BoundType.forBoolean(toInclusive))).asSet(domain);
}
- @Override ContiguousSet<C> tailSetImpl(C fromElement, boolean inclusive) {
- return intersectionInCurrentDomain(Range.downTo(fromElement, BoundType.forBoolean(inclusive)));
- }
-
- @GwtIncompatible("not used by GWT emulation")
- @Override int indexOf(Object target) {
- return contains(target) ? (int) domain.distance(first(), (C) target) : -1;
+ // Abstract method doesn't exist in GWT emulation
+ /* @Override */ ContiguousSet<C> tailSetImpl(C fromElement, boolean inclusive) {
+ return range.intersection(Ranges.downTo(fromElement, BoundType.forBoolean(inclusive)))
+ .asSet(domain);
}
@Override public UnmodifiableIterator<C> iterator() {
- return new AbstractSequentialIterator<C>(first()) {
+ return new AbstractLinkedIterator<C>(first()) {
final C last = last();
@Override
@@ -82,18 +76,6 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
};
}
- @GwtIncompatible("NavigableSet")
- @Override public UnmodifiableIterator<C> descendingIterator() {
- return new AbstractSequentialIterator<C>(last()) {
- final C first = first();
-
- @Override
- protected C computeNext(C previous) {
- return equalsOrThrow(previous, first) ? null : domain.previous(previous);
- }
- };
- }
-
private static boolean equalsOrThrow(Comparable<?> left, @Nullable Comparable<?> right) {
return right != null && Range.compareOrThrow(left, right) == 0;
}
@@ -115,10 +97,7 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
return (distance >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) distance + 1;
}
- @Override public boolean contains(@Nullable Object object) {
- if (object == null) {
- return false;
- }
+ @Override public boolean contains(Object object) {
try {
return range.contains((C) object);
} catch (ClassCastException e) {
@@ -127,7 +106,11 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
}
@Override public boolean containsAll(Collection<?> targets) {
- return Collections2.containsAllImpl(this, targets);
+ try {
+ return range.containsAll((Iterable<? extends C>) targets);
+ } catch (ClassCastException e) {
+ return false;
+ }
}
@Override public boolean isEmpty() {
@@ -153,7 +136,7 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
C lowerEndpoint = Ordering.natural().max(this.first(), other.first());
C upperEndpoint = Ordering.natural().min(this.last(), other.last());
return (lowerEndpoint.compareTo(upperEndpoint) < 0)
- ? ContiguousSet.create(Range.closed(lowerEndpoint, upperEndpoint), domain)
+ ? Ranges.closed(lowerEndpoint, upperEndpoint).asSet(domain)
: new EmptyContiguousSet<C>(domain);
}
}
@@ -163,14 +146,14 @@ final class RegularContiguousSet<C extends Comparable> extends ContiguousSet<C>
}
@Override public Range<C> range(BoundType lowerBoundType, BoundType upperBoundType) {
- return Range.create(range.lowerBound.withLowerBoundType(lowerBoundType, domain),
+ return Ranges.create(range.lowerBound.withLowerBoundType(lowerBoundType, domain),
range.upperBound.withUpperBoundType(upperBoundType, domain));
}
- @Override public boolean equals(@Nullable Object object) {
+ @Override public boolean equals(Object object) {
if (object == this) {
return true;
- } else if (object instanceof RegularContiguousSet) {
+ } else if (object instanceof RegularContiguousSet<?>) {
RegularContiguousSet<?> that = (RegularContiguousSet<?>) object;
if (this.domain.equals(that.domain)) {
return this.first().equals(that.first())
diff --git a/guava/src/com/google/common/collect/RegularImmutableAsList.java b/guava/src/com/google/common/collect/RegularImmutableAsList.java
deleted file mode 100644
index c137d6b..0000000
--- a/guava/src/com/google/common/collect/RegularImmutableAsList.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * An {@link ImmutableAsList} implementation specialized for when the delegate collection is
- * already backed by an {@code ImmutableList} or array.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-@SuppressWarnings("serial") // uses writeReplace, not default serialization
-class RegularImmutableAsList<E> extends ImmutableAsList<E> {
- private final ImmutableCollection<E> delegate;
- private final ImmutableList<? extends E> delegateList;
-
- RegularImmutableAsList(ImmutableCollection<E> delegate, ImmutableList<? extends E> delegateList) {
- this.delegate = delegate;
- this.delegateList = delegateList;
- }
-
- RegularImmutableAsList(ImmutableCollection<E> delegate, Object[] array) {
- this(delegate, ImmutableList.<E>asImmutableList(array));
- }
-
- @Override
- ImmutableCollection<E> delegateCollection() {
- return delegate;
- }
-
- ImmutableList<? extends E> delegateList() {
- return delegateList;
- }
-
- @SuppressWarnings("unchecked") // safe covariant cast!
- @Override
- public UnmodifiableListIterator<E> listIterator(int index) {
- return (UnmodifiableListIterator<E>) delegateList.listIterator(index);
- }
-
- @Override
- public Object[] toArray() {
- return delegateList.toArray();
- }
-
- @Override
- public <T> T[] toArray(T[] other) {
- return delegateList.toArray(other);
- }
-
- @Override
- public int indexOf(Object object) {
- return delegateList.indexOf(object);
- }
-
- @Override
- public int lastIndexOf(Object object) {
- return delegateList.lastIndexOf(object);
- }
-
- @Override
- public boolean equals(Object obj) {
- return delegateList.equals(obj);
- }
-
- @Override
- public int hashCode() {
- return delegateList.hashCode();
- }
-
- @Override
- public E get(int index) {
- return delegateList.get(index);
- }
-}
diff --git a/guava/src/com/google/common/collect/RegularImmutableBiMap.java b/guava/src/com/google/common/collect/RegularImmutableBiMap.java
index b67aa76..dca1f05 100644
--- a/guava/src/com/google/common/collect/RegularImmutableBiMap.java
+++ b/guava/src/com/google/common/collect/RegularImmutableBiMap.java
@@ -16,283 +16,45 @@
package com.google.common.collect;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.GwtCompatible;
-import java.io.Serializable;
-import java.util.Collection;
-
-import javax.annotation.Nullable;
-
/**
- * Bimap with two or more mappings.
- *
- * @author Louis Wasserman
+ * Bimap with one or more mappings.
+ *
+ * @author Jared Levy
*/
@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial") // uses writeReplace(), not default serialization
class RegularImmutableBiMap<K, V> extends ImmutableBiMap<K, V> {
- private static class BiMapEntry<K, V> extends ImmutableEntry<K, V> {
- BiMapEntry(K key, V value) {
- super(key, value);
- }
-
- @Nullable
- BiMapEntry<K, V> getNextInKToVBucket() {
- return null;
- }
-
- @Nullable
- BiMapEntry<K, V> getNextInVToKBucket() {
- return null;
- }
- }
-
- private static class NonTerminalBiMapEntry<K, V> extends BiMapEntry<K, V> {
- @Nullable private final BiMapEntry<K, V> nextInKToVBucket;
- @Nullable private final BiMapEntry<K, V> nextInVToKBucket;
-
- NonTerminalBiMapEntry(K key, V value, @Nullable BiMapEntry<K, V> nextInKToVBucket,
- @Nullable BiMapEntry<K, V> nextInVToKBucket) {
- super(key, value);
- this.nextInKToVBucket = nextInKToVBucket;
- this.nextInVToKBucket = nextInVToKBucket;
- }
+ final transient ImmutableMap<K, V> delegate;
+ final transient ImmutableBiMap<V, K> inverse;
- @Override
- @Nullable
- BiMapEntry<K, V> getNextInKToVBucket() {
- return nextInKToVBucket;
- }
-
- @Override
- @Nullable
- BiMapEntry<K, V> getNextInVToKBucket() {
- return nextInVToKBucket;
- }
- }
-
- static final double MAX_LOAD_FACTOR = 1.2;
-
- private transient final BiMapEntry<K, V>[] kToVTable;
- private transient final BiMapEntry<K, V>[] vToKTable;
- private transient final BiMapEntry<K, V>[] entries;
- private transient final int mask;
- private transient final int hashCode;
-
- RegularImmutableBiMap(Collection<? extends Entry<? extends K, ? extends V>> entriesToAdd) {
- int n = entriesToAdd.size();
- int tableSize = Hashing.closedTableSize(n, MAX_LOAD_FACTOR);
- this.mask = tableSize - 1;
- BiMapEntry<K, V>[] kToVTable = createEntryArray(tableSize);
- BiMapEntry<K, V>[] vToKTable = createEntryArray(tableSize);
- BiMapEntry<K, V>[] entries = createEntryArray(n);
- int i = 0;
- int hashCode = 0;
-
- for (Entry<? extends K, ? extends V> entry : entriesToAdd) {
- K key = checkNotNull(entry.getKey());
- V value = checkNotNull(entry.getValue());
-
- int keyHash = key.hashCode();
- int valueHash = value.hashCode();
- int keyBucket = Hashing.smear(keyHash) & mask;
- int valueBucket = Hashing.smear(valueHash) & mask;
-
- BiMapEntry<K, V> nextInKToVBucket = kToVTable[keyBucket];
- for (BiMapEntry<K, V> kToVEntry = nextInKToVBucket; kToVEntry != null;
- kToVEntry = kToVEntry.getNextInKToVBucket()) {
- if (key.equals(kToVEntry.getKey())) {
- throw new IllegalArgumentException("Multiple entries with same key: " +
- entry + " and " + kToVEntry);
- }
- }
- BiMapEntry<K, V> nextInVToKBucket = vToKTable[valueBucket];
- for (BiMapEntry<K, V> vToKEntry = nextInVToKBucket; vToKEntry != null;
- vToKEntry = vToKEntry.getNextInVToKBucket()) {
- if (value.equals(vToKEntry.getValue())) {
- throw new IllegalArgumentException("Multiple entries with same value: "
- + entry + " and " + vToKEntry);
- }
- }
- BiMapEntry<K, V> newEntry =
- (nextInKToVBucket == null && nextInVToKBucket == null)
- ? new BiMapEntry<K, V>(key, value)
- : new NonTerminalBiMapEntry<K, V>(key, value, nextInKToVBucket, nextInVToKBucket);
- kToVTable[keyBucket] = newEntry;
- vToKTable[valueBucket] = newEntry;
- entries[i++] = newEntry;
- hashCode += keyHash ^ valueHash;
- }
-
- this.kToVTable = kToVTable;
- this.vToKTable = vToKTable;
- this.entries = entries;
- this.hashCode = hashCode;
- }
-
- @SuppressWarnings("unchecked")
- private static <K, V> BiMapEntry<K, V>[] createEntryArray(int length) {
- return new BiMapEntry[length];
- }
+ RegularImmutableBiMap(ImmutableMap<K, V> delegate) {
+ this.delegate = delegate;
- @Override
- @Nullable
- public V get(@Nullable Object key) {
- if (key == null) {
- return null;
- }
- int bucket = Hashing.smear(key.hashCode()) & mask;
- for (BiMapEntry<K, V> entry = kToVTable[bucket]; entry != null;
- entry = entry.getNextInKToVBucket()) {
- if (key.equals(entry.getKey())) {
- return entry.getValue();
- }
+ ImmutableMap.Builder<V, K> builder = ImmutableMap.builder();
+ for (Entry<K, V> entry : delegate.entrySet()) {
+ builder.put(entry.getValue(), entry.getKey());
}
- return null;
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- return new ImmutableMapEntrySet<K, V>() {
- @Override
- ImmutableMap<K, V> map() {
- return RegularImmutableBiMap.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<K, V>> createAsList() {
- return new RegularImmutableAsList<Entry<K, V>>(this, entries);
- }
-
- @Override
- boolean isHashCodeFast() {
- return true;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
- };
+ ImmutableMap<V, K> backwardMap = builder.build();
+ this.inverse = new RegularImmutableBiMap<V, K>(backwardMap, this);
}
- @Override
- boolean isPartialView() {
- return false;
+ RegularImmutableBiMap(ImmutableMap<K, V> delegate,
+ ImmutableBiMap<V, K> inverse) {
+ this.delegate = delegate;
+ this.inverse = inverse;
}
- @Override
- public int size() {
- return entries.length;
+ @Override ImmutableMap<K, V> delegate() {
+ return delegate;
}
-
- private transient ImmutableBiMap<V, K> inverse;
- @Override
- public ImmutableBiMap<V, K> inverse() {
- ImmutableBiMap<V, K> result = inverse;
- return (result == null) ? inverse = new Inverse() : result;
+ @Override public ImmutableBiMap<V, K> inverse() {
+ return inverse;
}
-
- private final class Inverse extends ImmutableBiMap<V, K> {
-
- @Override
- public int size() {
- return inverse().size();
- }
-
- @Override
- public ImmutableBiMap<K, V> inverse() {
- return RegularImmutableBiMap.this;
- }
-
- @Override
- public K get(@Nullable Object value) {
- if (value == null) {
- return null;
- }
- int bucket = Hashing.smear(value.hashCode()) & mask;
- for (BiMapEntry<K, V> entry = vToKTable[bucket]; entry != null;
- entry = entry.getNextInVToKBucket()) {
- if (value.equals(entry.getValue())) {
- return entry.getKey();
- }
- }
- return null;
- }
-
- @Override
- ImmutableSet<Entry<V, K>> createEntrySet() {
- return new InverseEntrySet();
- }
-
- final class InverseEntrySet extends ImmutableMapEntrySet<V, K> {
- @Override
- ImmutableMap<V, K> map() {
- return Inverse.this;
- }
- @Override
- boolean isHashCodeFast() {
- return true;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
-
- @Override
- public UnmodifiableIterator<Entry<V, K>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<V, K>> createAsList() {
- return new ImmutableAsList<Entry<V, K>>() {
- @Override
- public Entry<V, K> get(int index) {
- Entry<K, V> entry = entries[index];
- return Maps.immutableEntry(entry.getValue(), entry.getKey());
- }
-
- @Override
- ImmutableCollection<Entry<V, K>> delegateCollection() {
- return InverseEntrySet.this;
- }
- };
- }
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
-
- @Override
- Object writeReplace() {
- return new InverseSerializedForm<K, V>(RegularImmutableBiMap.this);
- }
- }
-
- private static class InverseSerializedForm<K, V> implements Serializable {
- private final ImmutableBiMap<K, V> forward;
-
- InverseSerializedForm(ImmutableBiMap<K, V> forward) {
- this.forward = forward;
- }
-
- Object readResolve() {
- return forward.inverse();
- }
-
- private static final long serialVersionUID = 1;
+ @Override boolean isPartialView() {
+ return delegate.isPartialView() || inverse.delegate().isPartialView();
}
}
diff --git a/guava/src/com/google/common/collect/RegularImmutableList.java b/guava/src/com/google/common/collect/RegularImmutableList.java
index 4314b6e..27f47f5 100644
--- a/guava/src/com/google/common/collect/RegularImmutableList.java
+++ b/guava/src/com/google/common/collect/RegularImmutableList.java
@@ -58,6 +58,16 @@ class RegularImmutableList<E> extends ImmutableList<E> {
return offset != 0 || size != array.length;
}
+ @Override public boolean contains(@Nullable Object target) {
+ return indexOf(target) != -1;
+ }
+
+ // The fake cast to E is safe because the creation methods only allow E's
+ @SuppressWarnings("unchecked")
+ @Override public UnmodifiableIterator<E> iterator() {
+ return (UnmodifiableIterator<E>) Iterators.forArray(array, offset, size);
+ }
+
@Override public Object[] toArray() {
Object[] newArray = new Object[size()];
System.arraycopy(array, offset, newArray, 0, size);
@@ -82,19 +92,45 @@ class RegularImmutableList<E> extends ImmutableList<E> {
return (E) array[index + offset];
}
- @Override
- ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
- return new RegularImmutableList<E>(
- array, offset + fromIndex, toIndex - fromIndex);
+ @Override public int indexOf(@Nullable Object target) {
+ if (target != null) {
+ for (int i = offset; i < offset + size; i++) {
+ if (array[i].equals(target)) {
+ return i - offset;
+ }
+ }
+ }
+ return -1;
}
- @SuppressWarnings("unchecked")
- @Override
- public UnmodifiableListIterator<E> listIterator(int index) {
- // for performance
- // The fake cast to E is safe because the creation methods only allow E's
- return (UnmodifiableListIterator<E>)
- Iterators.forArray(array, offset, size, index);
+ @Override public int lastIndexOf(@Nullable Object target) {
+ if (target != null) {
+ for (int i = offset + size - 1; i >= offset; i--) {
+ if (array[i].equals(target)) {
+ return i - offset;
+ }
+ }
+ }
+ return -1;
+ }
+
+ @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
+ Preconditions.checkPositionIndexes(fromIndex, toIndex, size);
+ return (fromIndex == toIndex)
+ ? ImmutableList.<E>of()
+ : new RegularImmutableList<E>(
+ array, offset + fromIndex, toIndex - fromIndex);
+ }
+
+ @Override public UnmodifiableListIterator<E> listIterator(final int start) {
+ return new AbstractIndexedListIterator<E>(size, start) {
+ // The fake cast to E is safe because the creation methods only allow E's
+ @SuppressWarnings("unchecked")
+ @Override protected E get(int index) {
+ return (E) array[index + offset];
+ }
+
+ };
}
@Override public boolean equals(@Nullable Object object) {
@@ -128,6 +164,16 @@ class RegularImmutableList<E> extends ImmutableList<E> {
return true;
}
+ @Override public int hashCode() {
+ // not caching hash code since it could change if the elements are mutable
+ // in a way that modifies their hash codes
+ int hashCode = 1;
+ for (int i = offset; i < offset + size; i++) {
+ hashCode = 31 * hashCode + array[i].hashCode();
+ }
+ return hashCode;
+ }
+
@Override public String toString() {
StringBuilder sb = Collections2.newStringBuilderForCollection(size())
.append('[').append(array[offset]);
diff --git a/guava/src/com/google/common/collect/RegularImmutableMap.java b/guava/src/com/google/common/collect/RegularImmutableMap.java
index 6d9be99..e2b7150 100644
--- a/guava/src/com/google/common/collect/RegularImmutableMap.java
+++ b/guava/src/com/google/common/collect/RegularImmutableMap.java
@@ -19,6 +19,8 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.ImmutableSet.ArrayImmutableSet;
+import com.google.common.collect.ImmutableSet.TransformedImmutableSet;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@@ -39,6 +41,7 @@ final class RegularImmutableMap<K, V> extends ImmutableMap<K, V> {
private final transient LinkedEntry<K, V>[] table;
// 'and' with an int to get a table index
private final transient int mask;
+ private final transient int keySetHashCode;
// TODO(gak): investigate avoiding the creation of ImmutableEntries since we
// re-copy them anyway.
@@ -46,16 +49,18 @@ final class RegularImmutableMap<K, V> extends ImmutableMap<K, V> {
int size = immutableEntries.length;
entries = createEntryArray(size);
- int tableSize = Hashing.closedTableSize(size, MAX_LOAD_FACTOR);
+ int tableSize = chooseTableSize(size);
table = createEntryArray(tableSize);
mask = tableSize - 1;
+ int keySetHashCodeMutable = 0;
for (int entryIndex = 0; entryIndex < size; entryIndex++) {
// each of our 6 callers carefully put only Entry<K, V>s into the array!
@SuppressWarnings("unchecked")
Entry<K, V> entry = (Entry<K, V>) immutableEntries[entryIndex];
K key = entry.getKey();
int keyHashCode = key.hashCode();
+ keySetHashCodeMutable += keyHashCode;
int tableIndex = Hashing.smear(keyHashCode) & mask;
@Nullable LinkedEntry<K, V> existing = table[tableIndex];
// prepend, not append, so the entries can be immutable
@@ -68,14 +73,15 @@ final class RegularImmutableMap<K, V> extends ImmutableMap<K, V> {
existing = existing.next();
}
}
+ keySetHashCode = keySetHashCodeMutable;
}
- /**
- * Closed addressing tends to perform well even with high load factors.
- * Being conservative here ensures that the table is still likely to be
- * relatively sparse (hence it misses fast) while saving space.
- */
- private static final double MAX_LOAD_FACTOR = 1.2;
+ private static int chooseTableSize(int size) {
+ // least power of 2 greater than size
+ int tableSize = Integer.highestOneBit(size) << 1;
+ checkArgument(tableSize > 0, "table too large: %s", size);
+ return tableSize;
+ }
/**
* Creates a {@link LinkedEntry} array to hold parameterized entries. The
@@ -160,31 +166,125 @@ final class RegularImmutableMap<K, V> extends ImmutableMap<K, V> {
public int size() {
return entries.length;
}
-
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public boolean containsValue(@Nullable Object value) {
+ if (value == null) {
+ return false;
+ }
+ for (Entry<K, V> entry : entries) {
+ if (entry.getValue().equals(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override boolean isPartialView() {
return false;
}
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- return new EntrySet();
+ private transient ImmutableSet<Entry<K, V>> entrySet;
+
+ @Override public ImmutableSet<Entry<K, V>> entrySet() {
+ ImmutableSet<Entry<K, V>> es = entrySet;
+ return (es == null) ? (entrySet = new EntrySet<K, V>(this)) : es;
}
@SuppressWarnings("serial") // uses writeReplace(), not default serialization
- private class EntrySet extends ImmutableMapEntrySet<K, V> {
- @Override ImmutableMap<K, V> map() {
- return RegularImmutableMap.this;
+ private static class EntrySet<K, V> extends ArrayImmutableSet<Entry<K, V>> {
+ final transient RegularImmutableMap<K, V> map;
+
+ EntrySet(RegularImmutableMap<K, V> map) {
+ super(map.entries);
+ this.map = map;
}
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return asList().iterator();
+ @Override public boolean contains(Object target) {
+ if (target instanceof Entry) {
+ Entry<?, ?> entry = (Entry<?, ?>) target;
+ V mappedValue = map.get(entry.getKey());
+ return mappedValue != null && mappedValue.equals(entry.getValue());
+ }
+ return false;
+ }
+ }
+
+ private transient ImmutableSet<K> keySet;
+
+ @Override public ImmutableSet<K> keySet() {
+ ImmutableSet<K> ks = keySet;
+ return (ks == null) ? (keySet = new KeySet<K, V>(this)) : ks;
+ }
+
+ @SuppressWarnings("serial") // uses writeReplace(), not default serialization
+ private static class KeySet<K, V>
+ extends TransformedImmutableSet<Entry<K, V>, K> {
+ final RegularImmutableMap<K, V> map;
+
+ KeySet(RegularImmutableMap<K, V> map) {
+ super(map.entries, map.keySetHashCode);
+ this.map = map;
+ }
+
+ @Override K transform(Entry<K, V> element) {
+ return element.getKey();
+ }
+
+ @Override public boolean contains(Object target) {
+ return map.containsKey(target);
+ }
+
+ @Override boolean isPartialView() {
+ return true;
+ }
+ }
+
+ private transient ImmutableCollection<V> values;
+
+ @Override public ImmutableCollection<V> values() {
+ ImmutableCollection<V> v = values;
+ return (v == null) ? (values = new Values<V>(this)) : v;
+ }
+
+ @SuppressWarnings("serial") // uses writeReplace(), not default serialization
+ private static class Values<V> extends ImmutableCollection<V> {
+ final RegularImmutableMap<?, V> map;
+
+ Values(RegularImmutableMap<?, V> map) {
+ this.map = map;
}
@Override
- ImmutableList<Entry<K, V>> createAsList() {
- return new RegularImmutableAsList<Entry<K, V>>(this, entries);
+ public int size() {
+ return map.entries.length;
+ }
+
+ @Override public UnmodifiableIterator<V> iterator() {
+ return new AbstractIndexedListIterator<V>(map.entries.length) {
+ @Override protected V get(int index) {
+ return map.entries[index].getValue();
+ }
+ };
}
+
+ @Override public boolean contains(Object target) {
+ return map.containsValue(target);
+ }
+
+ @Override boolean isPartialView() {
+ return true;
+ }
+ }
+
+ @Override public String toString() {
+ StringBuilder result
+ = Collections2.newStringBuilderForCollection(size()).append('{');
+ Collections2.STANDARD_JOINER.appendTo(result, entries);
+ return result.append('}').toString();
}
// This class is never actually serialized directly, but we have to make the
diff --git a/guava/src/com/google/common/collect/RegularImmutableMultiset.java b/guava/src/com/google/common/collect/RegularImmutableMultiset.java
index e46f424..090c091 100644
--- a/guava/src/com/google/common/collect/RegularImmutableMultiset.java
+++ b/guava/src/com/google/common/collect/RegularImmutableMultiset.java
@@ -18,13 +18,14 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
+import java.util.Iterator;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Implementation of {@link ImmutableMultiset} with one or more elements.
- *
+ *
* @author Jared Levy
* @author Louis Wasserman
*/
@@ -66,45 +67,31 @@ class RegularImmutableMultiset<E> extends ImmutableMultiset<E> {
return map.keySet();
}
- private static <E> Entry<E> entryFromMapEntry(Map.Entry<E, Integer> entry) {
- return Multisets.immutableEntry(entry.getKey(), entry.getValue());
- }
-
@Override
- ImmutableSet<Entry<E>> createEntrySet() {
- return new EntrySet();
- }
-
- private class EntrySet extends ImmutableMultiset<E>.EntrySet {
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public UnmodifiableIterator<Entry<E>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<E>> createAsList() {
- final ImmutableList<Map.Entry<E, Integer>> entryList = map.entrySet().asList();
- return new ImmutableAsList<Entry<E>>() {
- @Override
- public Entry<E> get(int index) {
- return entryFromMapEntry(entryList.get(index));
- }
-
- @Override
- ImmutableCollection<Entry<E>> delegateCollection() {
- return EntrySet.this;
- }
- };
- }
+ UnmodifiableIterator<Entry<E>> entryIterator() {
+ final Iterator<Map.Entry<E, Integer>> mapIterator =
+ map.entrySet().iterator();
+ return new UnmodifiableIterator<Entry<E>>() {
+ @Override
+ public boolean hasNext() {
+ return mapIterator.hasNext();
+ }
+
+ @Override
+ public Entry<E> next() {
+ Map.Entry<E, Integer> mapEntry = mapIterator.next();
+ return Multisets.immutableEntry(mapEntry.getKey(), mapEntry.getValue());
+ }
+ };
}
@Override
public int hashCode() {
return map.hashCode();
}
+
+ @Override
+ int distinctElements() {
+ return map.size();
+ }
}
diff --git a/guava/src/com/google/common/collect/RegularImmutableSortedMap.java b/guava/src/com/google/common/collect/RegularImmutableSortedMap.java
deleted file mode 100644
index dd93b7f..0000000
--- a/guava/src/com/google/common/collect/RegularImmutableSortedMap.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import javax.annotation.Nullable;
-
-/**
- * An implementation of an immutable sorted map with one or more entries.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-@SuppressWarnings("serial") // uses writeReplace, not default serialization
-final class RegularImmutableSortedMap<K, V> extends ImmutableSortedMap<K, V> {
- private final transient RegularImmutableSortedSet<K> keySet;
- private final transient ImmutableList<V> valueList;
-
- RegularImmutableSortedMap(RegularImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
- this.keySet = keySet;
- this.valueList = valueList;
- }
-
- RegularImmutableSortedMap(
- RegularImmutableSortedSet<K> keySet,
- ImmutableList<V> valueList,
- ImmutableSortedMap<K, V> descendingMap) {
- super(descendingMap);
- this.keySet = keySet;
- this.valueList = valueList;
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- return new EntrySet();
- }
-
- private class EntrySet extends ImmutableMapEntrySet<K, V> {
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Entry<K, V>> createAsList() {
- return new ImmutableAsList<Entry<K, V>>() {
- // avoid additional indirection
- private final ImmutableList<K> keyList = keySet().asList();
-
- @Override
- public Entry<K, V> get(int index) {
- return Maps.immutableEntry(keyList.get(index), valueList.get(index));
- }
-
- @Override
- ImmutableCollection<Entry<K, V>> delegateCollection() {
- return EntrySet.this;
- }
- };
- }
-
- @Override
- ImmutableMap<K, V> map() {
- return RegularImmutableSortedMap.this;
- }
- }
-
- @Override
- public ImmutableSortedSet<K> keySet() {
- return keySet;
- }
-
- @Override
- public ImmutableCollection<V> values() {
- return valueList;
- }
-
- @Override
- public V get(@Nullable Object key) {
- int index = keySet.indexOf(key);
- return (index == -1) ? null : valueList.get(index);
- }
-
- private ImmutableSortedMap<K, V> getSubMap(int fromIndex, int toIndex) {
- if (fromIndex == 0 && toIndex == size()) {
- return this;
- } else if (fromIndex == toIndex) {
- return emptyMap(comparator());
- } else {
- return from(
- keySet.getSubSet(fromIndex, toIndex),
- valueList.subList(fromIndex, toIndex));
- }
- }
-
- @Override
- public ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive) {
- return getSubMap(0, keySet.headIndex(checkNotNull(toKey), inclusive));
- }
-
- @Override
- public ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive) {
- return getSubMap(keySet.tailIndex(checkNotNull(fromKey), inclusive), size());
- }
-
- @Override
- ImmutableSortedMap<K, V> createDescendingMap() {
- return new RegularImmutableSortedMap<K, V>(
- (RegularImmutableSortedSet<K>) keySet.descendingSet(),
- valueList.reverse(),
- this);
- }
-
-}
diff --git a/guava/src/com/google/common/collect/RegularImmutableSortedMultiset.java b/guava/src/com/google/common/collect/RegularImmutableSortedMultiset.java
index 3db3405..7318d9b 100644
--- a/guava/src/com/google/common/collect/RegularImmutableSortedMultiset.java
+++ b/guava/src/com/google/common/collect/RegularImmutableSortedMultiset.java
@@ -15,11 +15,16 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static com.google.common.collect.BoundType.CLOSED;
+import static com.google.common.collect.SortedLists.KeyAbsentBehavior.INVERTED_INSERTION_INDEX;
+import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_HIGHER;
+import static com.google.common.collect.SortedLists.KeyAbsentBehavior.NEXT_LOWER;
+import static com.google.common.collect.SortedLists.KeyPresentBehavior.ANY_PRESENT;
import com.google.common.primitives.Ints;
+import java.util.Comparator;
+import java.util.List;
+
import javax.annotation.Nullable;
/**
@@ -27,119 +32,167 @@ import javax.annotation.Nullable;
*
* @author Louis Wasserman
*/
-@SuppressWarnings("serial") // uses writeReplace, not default serialization
final class RegularImmutableSortedMultiset<E> extends ImmutableSortedMultiset<E> {
- private final transient RegularImmutableSortedSet<E> elementSet;
- private final transient int[] counts;
- private final transient long[] cumulativeCounts;
- private final transient int offset;
- private final transient int length;
+ private static final class CumulativeCountEntry<E> extends Multisets.AbstractEntry<E> {
+ final E element;
+ final int count;
+ final long cumulativeCount;
+
+ CumulativeCountEntry(E element, int count, @Nullable CumulativeCountEntry<E> previous) {
+ this.element = element;
+ this.count = count;
+ this.cumulativeCount = count + ((previous == null) ? 0 : previous.cumulativeCount);
+ }
+
+ @Override
+ public E getElement() {
+ return element;
+ }
+
+ @Override
+ public int getCount() {
+ return count;
+ }
+ }
+
+ static <E> RegularImmutableSortedMultiset<E> createFromSorted(Comparator<? super E> comparator,
+ List<? extends Multiset.Entry<E>> entries) {
+ List<CumulativeCountEntry<E>> newEntries = Lists.newArrayListWithCapacity(entries.size());
+ CumulativeCountEntry<E> previous = null;
+ for (Multiset.Entry<E> entry : entries) {
+ newEntries.add(
+ previous = new CumulativeCountEntry<E>(entry.getElement(), entry.getCount(), previous));
+ }
+ return new RegularImmutableSortedMultiset<E>(comparator, ImmutableList.copyOf(newEntries));
+ }
+
+ final transient ImmutableList<CumulativeCountEntry<E>> entries;
RegularImmutableSortedMultiset(
- RegularImmutableSortedSet<E> elementSet,
- int[] counts,
- long[] cumulativeCounts,
- int offset,
- int length) {
- this.elementSet = elementSet;
- this.counts = counts;
- this.cumulativeCounts = cumulativeCounts;
- this.offset = offset;
- this.length = length;
+ Comparator<? super E> comparator, ImmutableList<CumulativeCountEntry<E>> entries) {
+ super(comparator);
+ this.entries = entries;
+ assert !entries.isEmpty();
}
- private Entry<E> getEntry(int index) {
- return Multisets.immutableEntry(
- elementSet.asList().get(index),
- counts[offset + index]);
+ ImmutableList<E> elementList() {
+ return new TransformedImmutableList<CumulativeCountEntry<E>, E>(entries) {
+ @Override
+ E transform(CumulativeCountEntry<E> entry) {
+ return entry.getElement();
+ }
+ };
}
@Override
- public Entry<E> firstEntry() {
- return getEntry(0);
+ ImmutableSortedSet<E> createElementSet() {
+ return new RegularImmutableSortedSet<E>(elementList(), comparator());
}
@Override
- public Entry<E> lastEntry() {
- return getEntry(length - 1);
+ ImmutableSortedSet<E> createDescendingElementSet() {
+ return new RegularImmutableSortedSet<E>(elementList().reverse(), reverseComparator());
}
+ @SuppressWarnings("unchecked")
@Override
- public int count(@Nullable Object element) {
- int index = elementSet.indexOf(element);
- return (index == -1) ? 0 : counts[index + offset];
+ UnmodifiableIterator<Multiset.Entry<E>> entryIterator() {
+ return (UnmodifiableIterator) entries.iterator();
}
+ @SuppressWarnings("unchecked")
@Override
- public int size() {
- long size = cumulativeCounts[offset + length] - cumulativeCounts[offset];
- return Ints.saturatedCast(size);
+ UnmodifiableIterator<Multiset.Entry<E>> descendingEntryIterator() {
+ return (UnmodifiableIterator) entries.reverse().iterator();
}
@Override
- public ImmutableSortedSet<E> elementSet() {
- return elementSet;
+ public CumulativeCountEntry<E> firstEntry() {
+ return entries.get(0);
}
@Override
- public ImmutableSortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
- return getSubMultiset(0, elementSet.headIndex(upperBound, checkNotNull(boundType) == CLOSED));
+ public CumulativeCountEntry<E> lastEntry() {
+ return entries.get(entries.size() - 1);
}
@Override
- public ImmutableSortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
- return getSubMultiset(elementSet.tailIndex(lowerBound, checkNotNull(boundType) == CLOSED),
- length);
+ public int size() {
+ CumulativeCountEntry<E> firstEntry = firstEntry();
+ CumulativeCountEntry<E> lastEntry = lastEntry();
+ return Ints.saturatedCast(
+ lastEntry.cumulativeCount - firstEntry.cumulativeCount + firstEntry.count);
}
- ImmutableSortedMultiset<E> getSubMultiset(int from, int to) {
- checkPositionIndexes(from, to, length);
- if (from == to) {
- return emptyMultiset(comparator());
- } else if (from == 0 && to == length) {
- return this;
- } else {
- RegularImmutableSortedSet<E> subElementSet =
- (RegularImmutableSortedSet<E>) elementSet.getSubSet(from, to);
- return new RegularImmutableSortedMultiset<E>(
- subElementSet, counts, cumulativeCounts, offset + from, to - from);
- }
+ @Override
+ int distinctElements() {
+ return entries.size();
}
@Override
- ImmutableSet<Entry<E>> createEntrySet() {
- return new EntrySet();
+ boolean isPartialView() {
+ return entries.isPartialView();
}
- private final class EntrySet extends ImmutableMultiset<E>.EntrySet {
- @Override
- public int size() {
- return length;
+ @SuppressWarnings("unchecked")
+ @Override
+ public int count(@Nullable Object element) {
+ if (element == null) {
+ return 0;
}
-
- @Override
- public UnmodifiableIterator<Entry<E>> iterator() {
- return asList().iterator();
+ try {
+ int index = SortedLists.binarySearch(
+ elementList(), (E) element, comparator(), ANY_PRESENT, INVERTED_INSERTION_INDEX);
+ return (index >= 0) ? entries.get(index).getCount() : 0;
+ } catch (ClassCastException e) {
+ return 0;
}
+ }
- @Override
- ImmutableList<Entry<E>> createAsList() {
- return new ImmutableAsList<Entry<E>>() {
- @Override
- public Entry<E> get(int index) {
- return getEntry(index);
- }
-
- @Override
- ImmutableCollection<Entry<E>> delegateCollection() {
- return EntrySet.this;
- }
- };
+ @Override
+ public ImmutableSortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
+ int index;
+ switch (boundType) {
+ case OPEN:
+ index = SortedLists.binarySearch(
+ elementList(), checkNotNull(upperBound), comparator(), ANY_PRESENT, NEXT_HIGHER);
+ break;
+ case CLOSED:
+ index = SortedLists.binarySearch(
+ elementList(), checkNotNull(upperBound), comparator(), ANY_PRESENT, NEXT_LOWER) + 1;
+ break;
+ default:
+ throw new AssertionError();
}
+ return createSubMultiset(0, index);
}
@Override
- boolean isPartialView() {
- return offset > 0 || length < counts.length;
+ public ImmutableSortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
+ int index;
+ switch (boundType) {
+ case OPEN:
+ index = SortedLists.binarySearch(
+ elementList(), checkNotNull(lowerBound), comparator(), ANY_PRESENT, NEXT_LOWER) + 1;
+ break;
+ case CLOSED:
+ index = SortedLists.binarySearch(
+ elementList(), checkNotNull(lowerBound), comparator(), ANY_PRESENT, NEXT_HIGHER);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ return createSubMultiset(index, distinctElements());
+ }
+
+ private ImmutableSortedMultiset<E> createSubMultiset(int newFromIndex, int newToIndex) {
+ if (newFromIndex == 0 && newToIndex == entries.size()) {
+ return this;
+ } else if (newFromIndex >= newToIndex) {
+ return emptyMultiset(comparator());
+ } else {
+ return new RegularImmutableSortedMultiset<E>(
+ comparator(), entries.subList(newFromIndex, newToIndex));
+ }
}
}
diff --git a/guava/src/com/google/common/collect/RegularImmutableSortedSet.java b/guava/src/com/google/common/collect/RegularImmutableSortedSet.java
index 9dc2e5c..3d2b7e0 100644
--- a/guava/src/com/google/common/collect/RegularImmutableSortedSet.java
+++ b/guava/src/com/google/common/collect/RegularImmutableSortedSet.java
@@ -25,7 +25,6 @@ import static com.google.common.collect.SortedLists.KeyPresentBehavior.FIRST_AFT
import static com.google.common.collect.SortedLists.KeyPresentBehavior.FIRST_PRESENT;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.util.Collection;
import java.util.Collections;
@@ -60,11 +59,6 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
return elements.iterator();
}
- @GwtIncompatible("NavigableSet")
- @Override public UnmodifiableIterator<E> descendingIterator() {
- return elements.reverse().iterator();
- }
-
@Override public boolean isEmpty() {
return false;
}
@@ -75,8 +69,11 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
}
@Override public boolean contains(Object o) {
+ if (o == null) {
+ return false;
+ }
try {
- return o != null && unsafeBinarySearch(o) >= 0;
+ return binarySearch(o) >= 0;
} catch (ClassCastException e) {
return false;
}
@@ -87,7 +84,7 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
// targets.size() < size() / log(size())
// TODO(kevinb): see if we can share code with OrderedIterator after it
// graduates from labs.
- if (!SortedIterables.hasSameComparator(comparator(), targets)
+ if (!SortedIterables.hasSameComparator(comparator(), targets)
|| (targets.size() <= 1)) {
return super.containsAll(targets);
}
@@ -128,8 +125,18 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
return false;
}
- private int unsafeBinarySearch(Object key) throws ClassCastException {
- return Collections.binarySearch(elements, key, unsafeComparator());
+ private int binarySearch(Object key) {
+ // TODO(kevinb): split this into binarySearch(E) and
+ // unsafeBinarySearch(Object), use each appropriately. name all methods that
+ // might throw CCE "unsafe*".
+
+ // Pretend the comparator can compare anything. If it turns out it can't
+ // compare a and b, we should get a CCE on the subsequent line. Only methods
+ // that are spec'd to throw CCE should call this.
+ @SuppressWarnings("unchecked")
+ Comparator<Object> unsafeComparator = (Comparator<Object>) comparator;
+
+ return Collections.binarySearch(elements, key, unsafeComparator);
}
@Override boolean isPartialView() {
@@ -190,38 +197,16 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
}
@Override
- public E lower(E element) {
- int index = headIndex(element, false) - 1;
- return (index == -1) ? null : elements.get(index);
- }
-
- @Override
- public E floor(E element) {
- int index = headIndex(element, true) - 1;
- return (index == -1) ? null : elements.get(index);
- }
-
- @Override
- public E ceiling(E element) {
- int index = tailIndex(element, true);
- return (index == size()) ? null : elements.get(index);
- }
-
- @Override
- public E higher(E element) {
- int index = tailIndex(element, false);
- return (index == size()) ? null : elements.get(index);
- }
-
- @Override
ImmutableSortedSet<E> headSetImpl(E toElement, boolean inclusive) {
- return getSubSet(0, headIndex(toElement, inclusive));
- }
-
- int headIndex(E toElement, boolean inclusive) {
- return SortedLists.binarySearch(
- elements, checkNotNull(toElement), comparator(),
- inclusive ? FIRST_AFTER : FIRST_PRESENT, NEXT_HIGHER);
+ int index;
+ if (inclusive) {
+ index = SortedLists.binarySearch(
+ elements, checkNotNull(toElement), comparator(), FIRST_AFTER, NEXT_HIGHER);
+ } else {
+ index = SortedLists.binarySearch(
+ elements, checkNotNull(toElement), comparator(), FIRST_PRESENT, NEXT_HIGHER);
+ }
+ return createSubset(0, index);
}
@Override
@@ -233,15 +218,15 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
@Override
ImmutableSortedSet<E> tailSetImpl(E fromElement, boolean inclusive) {
- return getSubSet(tailIndex(fromElement, inclusive), size());
- }
-
- int tailIndex(E fromElement, boolean inclusive) {
- return SortedLists.binarySearch(
- elements,
- checkNotNull(fromElement),
- comparator(),
- inclusive ? FIRST_PRESENT : FIRST_AFTER, NEXT_HIGHER);
+ int index;
+ if (inclusive) {
+ index = SortedLists.binarySearch(
+ elements, checkNotNull(fromElement), comparator(), FIRST_PRESENT, NEXT_HIGHER);
+ } else {
+ index = SortedLists.binarySearch(
+ elements, checkNotNull(fromElement), comparator(), FIRST_AFTER, NEXT_HIGHER);
+ }
+ return createSubset(index, size());
}
// Pretend the comparator can compare anything. If it turns out it can't
@@ -252,7 +237,7 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
return (Comparator<Object>) comparator;
}
- ImmutableSortedSet<E> getSubSet(int newFromIndex, int newToIndex) {
+ private ImmutableSortedSet<E> createSubset(int newFromIndex, int newToIndex) {
if (newFromIndex == 0 && newToIndex == size()) {
return this;
} else if (newFromIndex < newToIndex) {
@@ -263,27 +248,28 @@ final class RegularImmutableSortedSet<E> extends ImmutableSortedSet<E> {
}
}
+ @SuppressWarnings("unchecked")
@Override int indexOf(@Nullable Object target) {
if (target == null) {
return -1;
}
int position;
try {
- position = SortedLists.binarySearch(elements, target, unsafeComparator(),
+ position = SortedLists.binarySearch(elements, (E) target, comparator(),
ANY_PRESENT, INVERTED_INSERTION_INDEX);
} catch (ClassCastException e) {
return -1;
}
- return (position >= 0) ? position : -1;
+ // TODO(kevinb): reconsider if it's really worth making feeble attempts at
+ // sanity for inconsistent comparators.
+
+ // The equals() check is needed when the comparator isn't compatible with
+ // equals().
+ return (position >= 0 && elements.get(position).equals(target))
+ ? position : -1;
}
@Override ImmutableList<E> createAsList() {
return new ImmutableSortedAsList<E>(this, elements);
}
-
- @Override
- ImmutableSortedSet<E> createDescendingSet() {
- return new RegularImmutableSortedSet<E>(elements.reverse(),
- Ordering.from(comparator).reverse());
- }
}
diff --git a/guava/src/com/google/common/collect/RegularImmutableTable.java b/guava/src/com/google/common/collect/RegularImmutableTable.java
index e4bfb70..c6ae3eb 100644
--- a/guava/src/com/google/common/collect/RegularImmutableTable.java
+++ b/guava/src/com/google/common/collect/RegularImmutableTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,11 +21,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Objects;
import java.util.Collections;
import java.util.Comparator;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -36,63 +36,56 @@ import javax.annotation.concurrent.Immutable;
* An implementation of {@link ImmutableTable} holding an arbitrary number of
* cells.
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
@GwtCompatible
abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
- private RegularImmutableTable() {}
-
- private transient ImmutableCollection<V> values;
+ private final ImmutableSet<Cell<R, C, V>> cellSet;
- @Override public final ImmutableCollection<V> values() {
- ImmutableCollection<V> result = values;
- return (result == null) ? values = createValues() : result;
+ private RegularImmutableTable(ImmutableSet<Cell<R, C, V>> cellSet) {
+ this.cellSet = cellSet;
}
-
- abstract ImmutableCollection<V> createValues();
- @Override public abstract int size();
+ private static final Function<Cell<Object, Object, Object>, Object>
+ GET_VALUE_FUNCTION =
+ new Function<Cell<Object, Object, Object>, Object>() {
+ @Override public Object apply(Cell<Object, Object, Object> from) {
+ return from.getValue();
+ }
+ };
+
+ @SuppressWarnings("unchecked")
+ private Function<Cell<R, C, V>, V> getValueFunction() {
+ return (Function) GET_VALUE_FUNCTION;
+ }
- @Override public final boolean containsValue(@Nullable Object value) {
- return values().contains(value);
+ @Nullable private transient volatile ImmutableList<V> valueList;
+
+ @Override public final ImmutableCollection<V> values() {
+ ImmutableList<V> result = valueList;
+ if (result == null) {
+ valueList = result = ImmutableList.copyOf(
+ Iterables.transform(cellSet(), getValueFunction()));
+ }
+ return result;
}
-
- private transient ImmutableSet<Cell<R, C, V>> cellSet;
- @Override
- public final ImmutableSet<Cell<R, C, V>> cellSet() {
- ImmutableSet<Cell<R, C, V>> result = cellSet;
- return (result == null) ? cellSet = createCellSet() : result;
+ @Override public final int size() {
+ return cellSet().size();
}
-
- abstract ImmutableSet<Cell<R, C, V>> createCellSet();
-
- abstract class CellSet extends ImmutableSet<Cell<R, C, V>> {
- @Override
- public int size() {
- return RegularImmutableTable.this.size();
- }
-
- @Override
- public boolean contains(@Nullable Object object) {
- if (object instanceof Cell) {
- Cell<?, ?, ?> cell = (Cell<?, ?, ?>) object;
- Object value = get(cell.getRowKey(), cell.getColumnKey());
- return value != null && value.equals(cell.getValue());
- }
- return false;
- }
- @Override
- boolean isPartialView() {
- return false;
- }
+ @Override public final boolean containsValue(@Nullable Object value) {
+ return values().contains(value);
}
@Override public final boolean isEmpty() {
return false;
}
+ @Override public final ImmutableSet<Cell<R, C, V>> cellSet() {
+ return cellSet;
+ }
+
static final <R, C, V> RegularImmutableTable<R, C, V> forCells(
List<Cell<R, C, V>> cells,
@Nullable final Comparator<? super R> rowComparator,
@@ -137,13 +130,15 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
forCellsInternal(Iterable<Cell<R, C, V>> cells,
@Nullable Comparator<? super R> rowComparator,
@Nullable Comparator<? super C> columnComparator) {
+ ImmutableSet.Builder<Cell<R, C, V>> cellSetBuilder = ImmutableSet.builder();
ImmutableSet.Builder<R> rowSpaceBuilder = ImmutableSet.builder();
ImmutableSet.Builder<C> columnSpaceBuilder = ImmutableSet.builder();
- ImmutableList<Cell<R, C, V>> cellList = ImmutableList.copyOf(cells);
- for (Cell<R, C, V> cell : cellList) {
+ for (Cell<R, C, V> cell : cells) {
+ cellSetBuilder.add(cell);
rowSpaceBuilder.add(cell.getRowKey());
columnSpaceBuilder.add(cell.getColumnKey());
}
+ ImmutableSet<Cell<R, C, V>> cellSet = cellSetBuilder.build();
ImmutableSet<R> rowSpace = rowSpaceBuilder.build();
if (rowComparator != null) {
@@ -160,9 +155,9 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
// use a dense table if more than half of the cells have values
// TODO(gak): tune this condition based on empirical evidence
- return (cellList.size() > ((rowSpace.size() * columnSpace.size()) / 2)) ?
- new DenseImmutableTable<R, C, V>(cellList, rowSpace, columnSpace) :
- new SparseImmutableTable<R, C, V>(cellList, rowSpace, columnSpace);
+ return (cellSet.size() > ((rowSpace.size() * columnSpace.size()) / 2 )) ?
+ new DenseImmutableTable<R, C, V>(cellSet, rowSpace, columnSpace) :
+ new SparseImmutableTable<R, C, V>(cellSet, rowSpace, columnSpace);
}
/**
@@ -175,52 +170,50 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
private final ImmutableMap<R, Map<C, V>> rowMap;
private final ImmutableMap<C, Map<R, V>> columnMap;
- private final int[] iterationOrderRow;
- private final int[] iterationOrderColumn;
- SparseImmutableTable(ImmutableList<Cell<R, C, V>> cellList,
- ImmutableSet<R> rowSpace, ImmutableSet<C> columnSpace) {
- Map<R, Integer> rowIndex = Maps.newHashMap();
- Map<R, Map<C, V>> rows = Maps.newLinkedHashMap();
- for (R row : rowSpace) {
- rowIndex.put(row, rows.size());
- rows.put(row, new LinkedHashMap<C, V>());
- }
- Map<C, Map<R, V>> columns = Maps.newLinkedHashMap();
- for (C col : columnSpace) {
- columns.put(col, new LinkedHashMap<R, V>());
+ /**
+ * Creates a {@link Map} over the key space with
+ * {@link ImmutableMap.Builder}s ready for values.
+ */
+ private static final <A, B, V> Map<A, ImmutableMap.Builder<B, V>>
+ makeIndexBuilder(ImmutableSet<A> keySpace) {
+ Map<A, ImmutableMap.Builder<B, V>> indexBuilder = Maps.newLinkedHashMap();
+ for (A key : keySpace) {
+ indexBuilder.put(key, ImmutableMap.<B, V>builder());
}
- int[] iterationOrderRow = new int[cellList.size()];
- int[] iterationOrderColumn = new int[cellList.size()];
- for (int i = 0; i < cellList.size(); i++) {
- Cell<R, C, V> cell = cellList.get(i);
+ return indexBuilder;
+ }
+
+ /**
+ * Builds the value maps of the index and creates an immutable copy of the
+ * map.
+ */
+ private static final <A, B, V> ImmutableMap<A, Map<B, V>> buildIndex(
+ Map<A, ImmutableMap.Builder<B, V>> indexBuilder) {
+ return ImmutableMap.copyOf(Maps.transformValues(indexBuilder,
+ new Function<ImmutableMap.Builder<B, V>, Map<B, V>>() {
+ @Override public Map<B, V> apply(ImmutableMap.Builder<B, V> from) {
+ return from.build();
+ }
+ }));
+ }
+
+ SparseImmutableTable(ImmutableSet<Cell<R, C, V>> cellSet,
+ ImmutableSet<R> rowSpace, ImmutableSet<C> columnSpace) {
+ super(cellSet);
+ Map<R, ImmutableMap.Builder<C, V>> rowIndexBuilder
+ = makeIndexBuilder(rowSpace);
+ Map<C, ImmutableMap.Builder<R, V>> columnIndexBuilder
+ = makeIndexBuilder(columnSpace);
+ for (Cell<R, C, V> cell : cellSet) {
R rowKey = cell.getRowKey();
C columnKey = cell.getColumnKey();
V value = cell.getValue();
-
- iterationOrderRow[i] = rowIndex.get(rowKey);
- Map<C, V> thisRow = rows.get(rowKey);
- iterationOrderColumn[i] = thisRow.size();
- V oldValue = thisRow.put(columnKey, value);
- if (oldValue != null) {
- throw new IllegalArgumentException("Duplicate value for row=" + rowKey + ", column="
- + columnKey + ": " + value + ", " + oldValue);
- }
- columns.get(columnKey).put(rowKey, value);
- }
- this.iterationOrderRow = iterationOrderRow;
- this.iterationOrderColumn = iterationOrderColumn;
- ImmutableMap.Builder<R, Map<C, V>> rowBuilder = ImmutableMap.builder();
- for (Map.Entry<R, Map<C, V>> row : rows.entrySet()) {
- rowBuilder.put(row.getKey(), ImmutableMap.copyOf(row.getValue()));
+ rowIndexBuilder.get(rowKey).put(columnKey, value);
+ columnIndexBuilder.get(columnKey).put(rowKey, value);
}
- this.rowMap = rowBuilder.build();
-
- ImmutableMap.Builder<C, Map<R, V>> columnBuilder = ImmutableMap.builder();
- for (Map.Entry<C, Map<R, V>> col : columns.entrySet()) {
- columnBuilder.put(col.getKey(), ImmutableMap.copyOf(col.getValue()));
- }
- this.columnMap = columnBuilder.build();
+ this.rowMap = buildIndex(rowIndexBuilder);
+ this.columnMap = buildIndex(columnIndexBuilder);
}
@Override public ImmutableMap<R, V> column(C columnKey) {
@@ -272,153 +265,6 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
Map<C, V> row = rowMap.get(rowKey);
return (row == null) ? null : row.get(columnKey);
}
-
- @Override
- ImmutableCollection<V> createValues() {
- return new ImmutableList<V>() {
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- public V get(int index) {
- int rowIndex = iterationOrderRow[index];
- ImmutableMap<C, V> row = (ImmutableMap<C, V>) rowMap.values().asList().get(rowIndex);
- int columnIndex = iterationOrderColumn[index];
- return row.values().asList().get(columnIndex);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- };
- }
-
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- ImmutableSet<Cell<R, C, V>> createCellSet() {
- return new SparseCellSet();
- }
-
- class SparseCellSet extends CellSet {
- @Override
- public UnmodifiableIterator<Cell<R, C, V>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Cell<R, C, V>> createAsList() {
- return new ImmutableAsList<Cell<R, C, V>>() {
- @Override
- public Cell<R, C, V> get(int index) {
- int rowIndex = iterationOrderRow[index];
- Map.Entry<R, Map<C, V>> rowEntry = rowMap.entrySet().asList().get(rowIndex);
- ImmutableMap<C, V> row = (ImmutableMap<C, V>) rowEntry.getValue();
- int columnIndex = iterationOrderColumn[index];
- Map.Entry<C, V> colEntry = row.entrySet().asList().get(columnIndex);
- return Tables.immutableCell(rowEntry.getKey(), colEntry.getKey(), colEntry.getValue());
- }
-
- @Override
- ImmutableCollection<Cell<R, C, V>> delegateCollection() {
- return SparseCellSet.this;
- }
- };
- }
- }
- }
-
- /**
- * An immutable map implementation backed by an indexed nullable array, used in
- * DenseImmutableTable.
- */
- private abstract static class ImmutableArrayMap<K, V> extends ImmutableMap<K, V> {
- private final int size;
-
- ImmutableArrayMap(int size) {
- this.size = size;
- }
-
- abstract ImmutableMap<K, Integer> keyToIndex();
-
- // True if getValue never returns null.
- private boolean isFull() {
- return size == keyToIndex().size();
- }
-
- K getKey(int index) {
- return keyToIndex().keySet().asList().get(index);
- }
-
- @Nullable abstract V getValue(int keyIndex);
-
- @Override
- ImmutableSet<K> createKeySet() {
- return isFull() ? keyToIndex().keySet() : super.createKeySet();
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public V get(@Nullable Object key) {
- Integer keyIndex = keyToIndex().get(key);
- return (keyIndex == null) ? null : getValue(keyIndex);
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- if (isFull()) {
- return new ImmutableMapEntrySet<K, V>() {
- @Override ImmutableMap<K, V> map() {
- return ImmutableArrayMap.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return new AbstractIndexedListIterator<Entry<K, V>>(size()) {
- @Override
- protected Entry<K, V> get(int index) {
- return Maps.immutableEntry(getKey(index), getValue(index));
- }
- };
- }
- };
- } else {
- return new ImmutableMapEntrySet<K, V>() {
- @Override ImmutableMap<K, V> map() {
- return ImmutableArrayMap.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return new AbstractIterator<Entry<K, V>>() {
- private int index = -1;
- private final int maxIndex = keyToIndex().size();
-
- @Override
- protected Entry<K, V> computeNext() {
- for (index++; index < maxIndex; index++) {
- V value = getValue(index);
- if (value != null) {
- return Maps.immutableEntry(getKey(index), value);
- }
- }
- return endOfData();
- }
- };
- }
- };
- }
- }
}
/**
@@ -428,20 +274,14 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
static final class DenseImmutableTable<R, C, V>
extends RegularImmutableTable<R, C, V> {
- private final ImmutableMap<R, Integer> rowKeyToIndex;
- private final ImmutableMap<C, Integer> columnKeyToIndex;
- private final ImmutableMap<R, Map<C, V>> rowMap;
- private final ImmutableMap<C, Map<R, V>> columnMap;
- private final int[] rowCounts;
- private final int[] columnCounts;
+ private final ImmutableBiMap<R, Integer> rowKeyToIndex;
+ private final ImmutableBiMap<C, Integer> columnKeyToIndex;
private final V[][] values;
- private final int[] iterationOrderRow;
- private final int[] iterationOrderColumn;
- private static <E> ImmutableMap<E, Integer> makeIndex(
+ private static <E> ImmutableBiMap<E, Integer> makeIndex(
ImmutableSet<E> set) {
- ImmutableMap.Builder<E, Integer> indexBuilder =
- ImmutableMap.builder();
+ ImmutableBiMap.Builder<E, Integer> indexBuilder =
+ ImmutableBiMap.builder();
int i = 0;
for (E key : set) {
indexBuilder.put(key, i);
@@ -450,19 +290,15 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
return indexBuilder.build();
}
- DenseImmutableTable(ImmutableList<Cell<R, C, V>> cellList,
+ DenseImmutableTable(ImmutableSet<Cell<R, C, V>> cellSet,
ImmutableSet<R> rowSpace, ImmutableSet<C> columnSpace) {
+ super(cellSet);
@SuppressWarnings("unchecked")
V[][] array = (V[][]) new Object[rowSpace.size()][columnSpace.size()];
this.values = array;
this.rowKeyToIndex = makeIndex(rowSpace);
this.columnKeyToIndex = makeIndex(columnSpace);
- rowCounts = new int[rowKeyToIndex.size()];
- columnCounts = new int[columnKeyToIndex.size()];
- int[] iterationOrderRow = new int[cellList.size()];
- int[] iterationOrderColumn = new int[cellList.size()];
- for (int i = 0; i < cellList.size(); i++) {
- Cell<R, C, V> cell = cellList.get(i);
+ for (Cell<R, C, V> cell : cellSet) {
R rowKey = cell.getRowKey();
C columnKey = cell.getColumnKey();
int rowIndex = rowKeyToIndex.get(rowKey);
@@ -471,113 +307,25 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
checkArgument(existingValue == null, "duplicate key: (%s, %s)", rowKey,
columnKey);
values[rowIndex][columnIndex] = cell.getValue();
- rowCounts[rowIndex]++;
- columnCounts[columnIndex]++;
- iterationOrderRow[i] = rowIndex;
- iterationOrderColumn[i] = columnIndex;
- }
- this.iterationOrderRow = iterationOrderRow;
- this.iterationOrderColumn = iterationOrderColumn;
- this.rowMap = new RowMap();
- this.columnMap = new ColumnMap();
- }
-
- private final class Row extends ImmutableArrayMap<C, V> {
- private final int rowIndex;
-
- Row(int rowIndex) {
- super(rowCounts[rowIndex]);
- this.rowIndex = rowIndex;
- }
-
- @Override
- ImmutableMap<C, Integer> keyToIndex() {
- return columnKeyToIndex;
- }
-
- @Override
- V getValue(int keyIndex) {
- return values[rowIndex][keyIndex];
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- }
-
- private final class Column extends ImmutableArrayMap<R, V> {
- private final int columnIndex;
-
- Column(int columnIndex) {
- super(columnCounts[columnIndex]);
- this.columnIndex = columnIndex;
- }
-
- @Override
- ImmutableMap<R, Integer> keyToIndex() {
- return rowKeyToIndex;
- }
-
- @Override
- V getValue(int keyIndex) {
- return values[keyIndex][columnIndex];
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- }
-
- private final class RowMap extends ImmutableArrayMap<R, Map<C, V>> {
- private RowMap() {
- super(rowCounts.length);
- }
-
- @Override
- ImmutableMap<R, Integer> keyToIndex() {
- return rowKeyToIndex;
- }
-
- @Override
- Map<C, V> getValue(int keyIndex) {
- return new Row(keyIndex);
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
- }
-
- private final class ColumnMap extends ImmutableArrayMap<C, Map<R, V>> {
- private ColumnMap() {
- super(columnCounts.length);
- }
-
- @Override
- ImmutableMap<C, Integer> keyToIndex() {
- return columnKeyToIndex;
- }
-
- @Override
- Map<R, V> getValue(int keyIndex) {
- return new Column(keyIndex);
- }
-
- @Override
- boolean isPartialView() {
- return false;
}
}
@Override public ImmutableMap<R, V> column(C columnKey) {
- Integer columnIndex = columnKeyToIndex.get(checkNotNull(columnKey));
- if (columnIndex == null) {
+ checkNotNull(columnKey);
+ Integer columnIndexInteger = columnKeyToIndex.get(columnKey);
+ if (columnIndexInteger == null) {
return ImmutableMap.of();
} else {
- return new Column(columnIndex);
+ // unbox only once
+ int columnIndex = columnIndexInteger;
+ ImmutableMap.Builder<R, V> columnBuilder = ImmutableMap.builder();
+ for (int i = 0; i < values.length; i++) {
+ V value = values[i][columnIndex];
+ if (value != null) {
+ columnBuilder.put(rowKeyToIndex.inverse().get(i), value);
+ }
+ }
+ return columnBuilder.build();
}
}
@@ -585,8 +333,31 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
return columnKeyToIndex.keySet();
}
+ private transient volatile ImmutableMap<C, Map<R, V>> columnMap;
+
+ private ImmutableMap<C, Map<R, V>> makeColumnMap() {
+ ImmutableMap.Builder<C, Map<R, V>> columnMapBuilder =
+ ImmutableMap.builder();
+ for (int c = 0; c < columnKeyToIndex.size(); c++) {
+ ImmutableMap.Builder<R, V> rowMapBuilder = ImmutableMap.builder();
+ for (int r = 0; r < rowKeyToIndex.size(); r++) {
+ V value = values[r][c];
+ if (value != null) {
+ rowMapBuilder.put(rowKeyToIndex.inverse().get(r), value);
+ }
+ }
+ columnMapBuilder.put(columnKeyToIndex.inverse().get(c),
+ rowMapBuilder.build());
+ }
+ return columnMapBuilder.build();
+ }
+
@Override public ImmutableMap<C, Map<R, V>> columnMap() {
- return columnMap;
+ ImmutableMap<C, Map<R, V>> result = columnMap;
+ if (result == null) {
+ columnMap = result = makeColumnMap();
+ }
+ return result;
}
@Override public boolean contains(@Nullable Object rowKey,
@@ -616,7 +387,15 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
if (rowIndex == null) {
return ImmutableMap.of();
} else {
- return new Row(rowIndex);
+ ImmutableMap.Builder<C, V> rowBuilder = ImmutableMap.builder();
+ V[] row = values[rowIndex];
+ for (int r = 0; r < row.length; r++) {
+ V value = row[r];
+ if (value != null) {
+ rowBuilder.put(columnKeyToIndex.inverse().get(r), value);
+ }
+ }
+ return rowBuilder.build();
}
}
@@ -624,66 +403,31 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
return rowKeyToIndex.keySet();
}
- @Override
- public ImmutableMap<R, Map<C, V>> rowMap() {
- return rowMap;
- }
+ private transient volatile ImmutableMap<R, Map<C, V>> rowMap;
- @Override
- ImmutableCollection<V> createValues() {
- return new ImmutableList<V>() {
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- public V get(int index) {
- return values[iterationOrderRow[index]][iterationOrderColumn[index]];
- }
-
- @Override
- boolean isPartialView() {
- return true;
+ private ImmutableMap<R, Map<C, V>> makeRowMap() {
+ ImmutableMap.Builder<R, Map<C, V>> rowMapBuilder = ImmutableMap.builder();
+ for (int r = 0; r < values.length; r++) {
+ V[] row = values[r];
+ ImmutableMap.Builder<C, V> columnMapBuilder = ImmutableMap.builder();
+ for (int c = 0; c < row.length; c++) {
+ V value = row[c];
+ if (value != null) {
+ columnMapBuilder.put(columnKeyToIndex.inverse().get(c), value);
+ }
}
- };
- }
-
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- ImmutableSet<Cell<R, C, V>> createCellSet() {
- return new DenseCellSet();
- }
-
- class DenseCellSet extends CellSet {
- @Override
- public UnmodifiableIterator<Cell<R, C, V>> iterator() {
- return asList().iterator();
+ rowMapBuilder.put(rowKeyToIndex.inverse().get(r),
+ columnMapBuilder.build());
}
+ return rowMapBuilder.build();
+ }
- @Override
- ImmutableList<Cell<R, C, V>> createAsList() {
- return new ImmutableAsList<Cell<R, C, V>>() {
- @Override
- public Cell<R, C, V> get(int index) {
- int rowIndex = iterationOrderRow[index];
- int columnIndex = iterationOrderColumn[index];
- R rowKey = rowKeySet().asList().get(rowIndex);
- C columnKey = columnKeySet().asList().get(columnIndex);
- V value = values[rowIndex][columnIndex];
- return Tables.immutableCell(rowKey, columnKey, value);
- }
-
- @Override
- ImmutableCollection<Cell<R, C, V>> delegateCollection() {
- return DenseCellSet.this;
- }
- };
+ @Override public ImmutableMap<R, Map<C, V>> rowMap() {
+ ImmutableMap<R, Map<C, V>> result = rowMap;
+ if (result == null) {
+ rowMap = result = makeRowMap();
}
+ return result;
}
}
}
diff --git a/guava/src/com/google/common/collect/SetMultimap.java b/guava/src/com/google/common/collect/SetMultimap.java
index 18f4a18..1409d8d 100644
--- a/guava/src/com/google/common/collect/SetMultimap.java
+++ b/guava/src/com/google/common/collect/SetMultimap.java
@@ -26,22 +26,13 @@ import javax.annotation.Nullable;
/**
* A {@code Multimap} that cannot hold duplicate key-value pairs. Adding a
- * key-value pair that's already in the multimap has no effect. See the {@link
- * Multimap} documentation for information common to all multimaps.
+ * key-value pair that's already in the multimap has no effect.
*
* <p>The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods
* each return a {@link Set} of values, while {@link #entries} returns a {@code
* Set} of map entries. Though the method signature doesn't say so explicitly,
* the map returned by {@link #asMap} has {@code Set} values.
*
- * <p>If the values corresponding to a single key should be ordered according to
- * a {@link java.util.Comparator} (or the natural order), see the
- * {@link SortedSetMultimap} subinterface.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
diff --git a/guava/src/com/google/common/collect/Sets.java b/guava/src/com/google/common/collect/Sets.java
index 95298e7..14ad867 100644
--- a/guava/src/com/google/common/collect/Sets.java
+++ b/guava/src/com/google/common/collect/Sets.java
@@ -19,11 +19,16 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2.FilteredCollection;
+import com.google.common.math.IntMath;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -39,22 +44,16 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
-import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
-import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.Nullable;
/**
* Static utility methods pertaining to {@link Set} instances. Also see this
- * class's counterparts {@link Lists}, {@link Maps} and {@link Queues}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Sets">
- * {@code Sets}</a>.
+ * class's counterparts {@link Lists} and {@link Maps}.
*
* @author Kevin Bourrillion
* @author Jared Levy
@@ -66,22 +65,6 @@ public final class Sets {
private Sets() {}
/**
- * {@link AbstractSet} substitute without the potentially-quadratic
- * {@code removeAll} implementation.
- */
- abstract static class ImprovedAbstractSet<E> extends AbstractSet<E> {
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeAllImpl(this, c);
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return super.retainAll(checkNotNull(c)); // GWT compatibility
- }
- }
-
- /**
* Returns an immutable set instance containing the given enum elements.
* Internally, the returned set will be backed by an {@link EnumSet}.
*
@@ -96,7 +79,7 @@ public final class Sets {
@GwtCompatible(serializable = true)
public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(
E anElement, E... otherElements) {
- return ImmutableEnumSet.asImmutable(EnumSet.of(anElement, otherElements));
+ return new ImmutableEnumSet<E>(EnumSet.of(anElement, otherElements));
}
/**
@@ -114,25 +97,20 @@ public final class Sets {
@GwtCompatible(serializable = true)
public static <E extends Enum<E>> ImmutableSet<E> immutableEnumSet(
Iterable<E> elements) {
- if (elements instanceof ImmutableEnumSet) {
- return (ImmutableEnumSet<E>) elements;
- } else if (elements instanceof Collection) {
- Collection<E> collection = (Collection<E>) elements;
- if (collection.isEmpty()) {
- return ImmutableSet.of();
- } else {
- return ImmutableEnumSet.asImmutable(EnumSet.copyOf(collection));
- }
- } else {
- Iterator<E> itr = elements.iterator();
- if (itr.hasNext()) {
- EnumSet<E> enumSet = EnumSet.of(itr.next());
- Iterators.addAll(enumSet, itr);
- return ImmutableEnumSet.asImmutable(enumSet);
- } else {
- return ImmutableSet.of();
- }
+ Iterator<E> iterator = elements.iterator();
+ if (!iterator.hasNext()) {
+ return ImmutableSet.of();
+ }
+ if (elements instanceof EnumSet) {
+ EnumSet<E> enumSetClone = EnumSet.copyOf((EnumSet<E>) elements);
+ return new ImmutableEnumSet<E>(enumSetClone);
}
+ E first = iterator.next();
+ EnumSet<E> set = EnumSet.of(first);
+ while (iterator.hasNext()) {
+ set.add(iterator.next());
+ }
+ return new ImmutableEnumSet<E>(set);
}
/**
@@ -143,6 +121,20 @@ public final class Sets {
*/
public static <E extends Enum<E>> EnumSet<E> newEnumSet(Iterable<E> iterable,
Class<E> elementType) {
+ /*
+ * TODO(cpovirk): noneOf() and addAll() will both throw
+ * NullPointerExceptions when appropriate. However, NullPointerTester will
+ * fail on this method because it passes in Class.class instead of an enum
+ * type. This means that, when iterable is null but elementType is not,
+ * noneOf() will throw a ClassCastException before addAll() has a chance to
+ * throw a NullPointerException. NullPointerTester considers this a failure.
+ * Ideally the test would be fixed, but it would require a special case for
+ * Class<E> where E extends Enum. Until that happens (if ever), leave
+ * checkNotNull() here. For now, contemplate the irony that checking
+ * elementType, the problem argument, is harmful, while checking iterable,
+ * the innocent bystander, is effective.
+ */
+ checkNotNull(iterable);
EnumSet<E> set = EnumSet.noneOf(elementType);
Iterables.addAll(set, iterable);
return set;
@@ -367,38 +359,6 @@ public final class Sets {
}
/**
- * Creates an empty {@code CopyOnWriteArraySet} instance.
- *
- * <p><b>Note:</b> if you need an immutable empty {@link Set}, use
- * {@link Collections#emptySet} instead.
- *
- * @return a new, empty {@code CopyOnWriteArraySet}
- * @since 12.0
- */
- @GwtIncompatible("CopyOnWriteArraySet")
- public static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet() {
- return new CopyOnWriteArraySet<E>();
- }
-
- /**
- * Creates a {@code CopyOnWriteArraySet} instance containing the given elements.
- *
- * @param elements the elements that the set should contain, in order
- * @return a new {@code CopyOnWriteArraySet} containing those elements
- * @since 12.0
- */
- @GwtIncompatible("CopyOnWriteArraySet")
- public static <E> CopyOnWriteArraySet<E> newCopyOnWriteArraySet(
- Iterable<? extends E> elements) {
- // We copy elements to an ArrayList first, rather than incurring the
- // quadratic cost of adding them to the COWAS directly.
- Collection<? extends E> elementsCollection = (elements instanceof Collection)
- ? Collections2.cast(elements)
- : Lists.newArrayList(elements);
- return new CopyOnWriteArraySet<E>(elementsCollection);
- }
-
- /**
* Creates an {@code EnumSet} consisting of all enum values that are not in
* the specified collection. If the collection is an {@link EnumSet}, this
* method has the same behavior as {@link EnumSet#complementOf}. Otherwise,
@@ -618,11 +578,6 @@ public final class Sets {
* <p><b>Note:</b> The returned view performs better when {@code set1} is the
* smaller of the two sets. If you have reason to believe one of your sets
* will generally be smaller than the other, pass it first.
- *
- * <p>Further, note that the current implementation is not suitable for nested
- * {@code union} views, i.e. the following should be avoided when in a loop:
- * {@code union = Sets.union(union, anotherSet);}, since iterating over the resulting
- * set has a cubic complexity to the depth of the nesting.
*/
public static <E> SetView<E> union(
final Set<? extends E> set1, final Set<? extends E> set2) {
@@ -853,13 +808,10 @@ public final class Sets {
*
* @since 11.0
*/
+ @Beta
+ @SuppressWarnings("unchecked")
public static <E> SortedSet<E> filter(
SortedSet<E> unfiltered, Predicate<? super E> predicate) {
- return Platform.setsFilterSortedSet(unfiltered, predicate);
- }
-
- static <E> SortedSet<E> filterSortedIgnoreNavigable(
- SortedSet<E> unfiltered, Predicate<? super E> predicate) {
if (unfiltered instanceof FilteredSet) {
// Support clear(), removeAll(), and retainAll() when filtering a filtered
// collection.
@@ -874,13 +826,21 @@ public final class Sets {
checkNotNull(unfiltered), checkNotNull(predicate));
}
- private static class FilteredSortedSet<E> extends FilteredSet<E>
+ private static class FilteredSortedSet<E> extends FilteredCollection<E>
implements SortedSet<E> {
FilteredSortedSet(SortedSet<E> unfiltered, Predicate<? super E> predicate) {
super(unfiltered, predicate);
}
+ @Override public boolean equals(@Nullable Object object) {
+ return equalsImpl(this, object);
+ }
+
+ @Override public int hashCode() {
+ return hashCodeImpl(this);
+ }
+
@Override
public Comparator<? super E> comparator() {
return ((SortedSet<E>) unfiltered).comparator();
@@ -921,145 +881,6 @@ public final class Sets {
}
/**
- * Returns the elements of a {@code NavigableSet}, {@code unfiltered}, that
- * satisfy a predicate. The returned set is a live view of {@code unfiltered};
- * changes to one affect the other.
- *
- * <p>The resulting set's iterator does not support {@code remove()}, but all
- * other set methods are supported. When given an element that doesn't satisfy
- * the predicate, the set's {@code add()} and {@code addAll()} methods throw
- * an {@link IllegalArgumentException}. When methods such as
- * {@code removeAll()} and {@code clear()} are called on the filtered set,
- * only elements that satisfy the filter will be removed from the underlying
- * set.
- *
- * <p>The returned set isn't threadsafe or serializable, even if
- * {@code unfiltered} is.
- *
- * <p>Many of the filtered set's methods, such as {@code size()}, iterate across
- * every element in the underlying set and determine which elements satisfy
- * the filter. When a live view is <i>not</i> needed, it may be faster to copy
- * {@code Iterables.filter(unfiltered, predicate)} and use the copy.
- *
- * <p><b>Warning:</b> {@code predicate} must be <i>consistent with equals</i>,
- * as documented at {@link Predicate#apply}. Do not provide a predicate such as
- * {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent with
- * equals. (See {@link Iterables#filter(Iterable, Class)} for related
- * functionality.)
- *
- * @since 14.0
- */
- @GwtIncompatible("NavigableSet")
- @SuppressWarnings("unchecked")
- public static <E> NavigableSet<E> filter(
- NavigableSet<E> unfiltered, Predicate<? super E> predicate) {
- if (unfiltered instanceof FilteredSet) {
- // Support clear(), removeAll(), and retainAll() when filtering a filtered
- // collection.
- FilteredSet<E> filtered = (FilteredSet<E>) unfiltered;
- Predicate<E> combinedPredicate
- = Predicates.<E>and(filtered.predicate, predicate);
- return new FilteredNavigableSet<E>(
- (NavigableSet<E>) filtered.unfiltered, combinedPredicate);
- }
-
- return new FilteredNavigableSet<E>(
- checkNotNull(unfiltered), checkNotNull(predicate));
- }
-
- @GwtIncompatible("NavigableSet")
- private static class FilteredNavigableSet<E> extends FilteredSortedSet<E>
- implements NavigableSet<E> {
- FilteredNavigableSet(NavigableSet<E> unfiltered, Predicate<? super E> predicate) {
- super(unfiltered, predicate);
- }
-
- NavigableSet<E> unfiltered() {
- return (NavigableSet<E>) unfiltered;
- }
-
- @Override
- @Nullable
- public E lower(E e) {
- return Iterators.getNext(headSet(e, false).descendingIterator(), null);
- }
-
- @Override
- @Nullable
- public E floor(E e) {
- return Iterators.getNext(headSet(e, true).descendingIterator(), null);
- }
-
- @Override
- public E ceiling(E e) {
- return Iterables.getFirst(tailSet(e, true), null);
- }
-
- @Override
- public E higher(E e) {
- return Iterables.getFirst(tailSet(e, false), null);
- }
-
- @Override
- public E pollFirst() {
- Iterator<E> unfilteredIterator = unfiltered().iterator();
- while (unfilteredIterator.hasNext()) {
- E e = unfilteredIterator.next();
- if (predicate.apply(e)) {
- unfilteredIterator.remove();
- return e;
- }
- }
- return null;
- }
-
- @Override
- public E pollLast() {
- Iterator<E> unfilteredIterator = unfiltered().descendingIterator();
- while (unfilteredIterator.hasNext()) {
- E e = unfilteredIterator.next();
- if (predicate.apply(e)) {
- unfilteredIterator.remove();
- return e;
- }
- }
- return null;
- }
-
- @Override
- public NavigableSet<E> descendingSet() {
- return Sets.filter(unfiltered().descendingSet(), predicate);
- }
-
- @Override
- public Iterator<E> descendingIterator() {
- return Iterators.filter(unfiltered().descendingIterator(), predicate);
- }
-
- @Override
- public E last() {
- return descendingIterator().next();
- }
-
- @Override
- public NavigableSet<E> subSet(
- E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
- return filter(
- unfiltered().subSet(fromElement, fromInclusive, toElement, toInclusive), predicate);
- }
-
- @Override
- public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- return filter(unfiltered().headSet(toElement, inclusive), predicate);
- }
-
- @Override
- public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- return filter(unfiltered().tailSet(fromElement, inclusive), predicate);
- }
- }
-
- /**
* Returns every possible list that can be formed by choosing one element
* from each of the given sets in order; the "n-ary
* <a href="http://en.wikipedia.org/wiki/Cartesian_product">Cartesian
@@ -1080,22 +901,12 @@ public final class Sets {
* <li>{@code ImmutableList.of(2, "C")}
* </ul>
*
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : sets.get(0)) {
- * for (B b1 : sets.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input set is empty, the Cartesian product will also be
- * empty. If no sets at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
+ * The order in which these lists are returned is not guaranteed, however the
+ * position of an element inside a tuple always corresponds to the position of
+ * the set from which it came in the input list. Note that if any input set is
+ * empty, the Cartesian product will also be empty. If no sets at all are
+ * provided (an empty list), the resulting Cartesian product has one element,
+ * an empty list (counter-intuitive, but mathematically consistent).
*
* <p><i>Performance notes:</i> while the cartesian product of sets of size
* {@code m, n, p} is a set of size {@code m x n x p}, its actual memory
@@ -1121,7 +932,8 @@ public final class Sets {
return ImmutableSet.of();
}
}
- return CartesianSet.create(sets);
+ CartesianSet<B> cartesianSet = new CartesianSet<B>(sets);
+ return cartesianSet;
}
/**
@@ -1145,22 +957,12 @@ public final class Sets {
* <li>{@code ImmutableList.of(2, "C")}
* </ul>
*
- * The result is guaranteed to be in the "traditional", lexicographical
- * order for Cartesian products that you would get from nesting for loops:
- * <pre> {@code
- *
- * for (B b0 : sets.get(0)) {
- * for (B b1 : sets.get(1)) {
- * ...
- * ImmutableList<B> tuple = ImmutableList.of(b0, b1, ...);
- * // operate on tuple
- * }
- * }}</pre>
- *
- * Note that if any input set is empty, the Cartesian product will also be
- * empty. If no sets at all are provided (an empty list), the resulting
- * Cartesian product has one element, an empty list (counter-intuitive, but
- * mathematically consistent).
+ * The order in which these lists are returned is not guaranteed, however the
+ * position of an element inside a tuple always corresponds to the position of
+ * the set from which it came in the input list. Note that if any input set is
+ * empty, the Cartesian product will also be empty. If no sets at all are
+ * provided, the resulting Cartesian product has one element, an empty list
+ * (counter-intuitive, but mathematically consistent).
*
* <p><i>Performance notes:</i> while the cartesian product of sets of size
* {@code m, n, p} is a set of size {@code m x n x p}, its actual memory
@@ -1184,51 +986,73 @@ public final class Sets {
return cartesianProduct(Arrays.asList(sets));
}
- private static final class CartesianSet<E>
- extends ForwardingCollection<List<E>> implements Set<List<E>> {
- private transient final ImmutableList<ImmutableSet<E>> axes;
- private transient final CartesianList<E> delegate;
-
- static <E> Set<List<E>> create(List<? extends Set<? extends E>> sets) {
- ImmutableList.Builder<ImmutableSet<E>> axesBuilder =
- new ImmutableList.Builder<ImmutableSet<E>>(sets.size());
- for (Set<? extends E> set : sets) {
- ImmutableSet<E> copy = ImmutableSet.copyOf(set);
- if (copy.isEmpty()) {
- return ImmutableSet.of();
+ private static class CartesianSet<B> extends AbstractSet<List<B>> {
+ final ImmutableList<Axis> axes;
+ final int size;
+
+ CartesianSet(List<? extends Set<? extends B>> sets) {
+ int dividend = 1;
+ ImmutableList.Builder<Axis> builder = ImmutableList.builder();
+ try {
+ for (Set<? extends B> set : sets) {
+ Axis axis = new Axis(set, dividend);
+ builder.add(axis);
+ dividend = IntMath.checkedMultiply(dividend, axis.size());
}
- axesBuilder.add(copy);
+ } catch (ArithmeticException overflow) {
+ throw new IllegalArgumentException("cartesian product too big");
}
- final ImmutableList<ImmutableSet<E>> axes = axesBuilder.build();
- ImmutableList<List<E>> listAxes = new ImmutableList<List<E>>() {
+ this.axes = builder.build();
+ size = dividend;
+ }
- @Override
- public int size() {
- return axes.size();
- }
+ @Override public int size() {
+ return size;
+ }
+
+ @Override public UnmodifiableIterator<List<B>> iterator() {
+ return new UnmodifiableIterator<List<B>>() {
+ int index;
@Override
- public List<E> get(int index) {
- return axes.get(index).asList();
+ public boolean hasNext() {
+ return index < size;
}
@Override
- boolean isPartialView() {
- return true;
+ public List<B> next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ Object[] tuple = new Object[axes.size()];
+ for (int i = 0 ; i < tuple.length; i++) {
+ tuple[i] = axes.get(i).getForIndex(index);
+ }
+ index++;
+
+ @SuppressWarnings("unchecked") // only B's are put in here
+ List<B> result = (ImmutableList<B>) ImmutableList.copyOf(tuple);
+ return result;
}
};
- return new CartesianSet<E>(axes, new CartesianList<E>(listAxes));
}
- private CartesianSet(
- ImmutableList<ImmutableSet<E>> axes, CartesianList<E> delegate) {
- this.axes = axes;
- this.delegate = delegate;
- }
-
- @Override
- protected Collection<List<E>> delegate() {
- return delegate;
+ @Override public boolean contains(Object element) {
+ if (!(element instanceof List<?>)) {
+ return false;
+ }
+ List<?> tuple = (List<?>) element;
+ int dimensions = axes.size();
+ if (tuple.size() != dimensions) {
+ return false;
+ }
+ for (int i = 0; i < dimensions; i++) {
+ if (!axes.get(i).contains(tuple.get(i))) {
+ return false;
+ }
+ }
+ return true;
}
@Override public boolean equals(@Nullable Object object) {
@@ -1241,26 +1065,56 @@ public final class Sets {
return super.equals(object);
}
- @Override
- public int hashCode() {
+ @Override public int hashCode() {
// Warning: this is broken if size() == 0, so it is critical that we
// substitute an empty ImmutableSet to the user in place of this
// It's a weird formula, but tests prove it works.
- int adjust = size() - 1;
+ int adjust = size - 1;
for (int i = 0; i < axes.size(); i++) {
adjust *= 31;
- adjust = ~~adjust;
- // in GWT, we have to deal with integer overflow carefully
}
- int hash = 1;
- for (Set<E> axis : axes) {
- hash = 31 * hash + (size() / axis.size() * axis.hashCode());
+ return axes.hashCode() + adjust;
+ }
+
+ private class Axis {
+ final ImmutableSet<? extends B> choices;
+ final ImmutableList<? extends B> choicesList;
+ final int dividend;
+
+ Axis(Set<? extends B> set, int dividend) {
+ choices = ImmutableSet.copyOf(set);
+ choicesList = choices.asList();
+ this.dividend = dividend;
+ }
+
+ int size() {
+ return choices.size();
+ }
+
+ B getForIndex(int index) {
+ return choicesList.get(index / dividend % size());
+ }
+
+ boolean contains(Object target) {
+ return choices.contains(target);
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof CartesianSet.Axis) {
+ CartesianSet.Axis that = (CartesianSet.Axis) obj;
+ return this.choices.equals(that.choices);
+ // dividends must be equal or we wouldn't have gotten this far
+ }
+ return false;
+ }
- hash = ~~hash;
+ @Override public int hashCode() {
+ // Because Axis instances are not exposed, we can
+ // opportunistically choose whatever bizarre formula happens
+ // to make CartesianSet.hashCode() as simple as possible.
+ return size / choices.size() * choices.hashCode();
}
- hash += adjust;
- return ~~hash;
}
}
@@ -1398,9 +1252,6 @@ public final class Sets {
int hashCode = 0;
for (Object o : s) {
hashCode += o != null ? o.hashCode() : 0;
-
- hashCode = ~~hashCode;
- // Needed to deal with unusual integer overflow in GWT.
}
return hashCode;
}
@@ -1427,345 +1278,117 @@ public final class Sets {
}
/**
- * Returns an unmodifiable view of the specified navigable set. This method
- * allows modules to provide users with "read-only" access to internal
- * navigable sets. Query operations on the returned set "read through" to the
- * specified set, and attempts to modify the returned set, whether direct or
- * via its collection views, result in an
- * {@code UnsupportedOperationException}.
- *
- * <p>The returned navigable set will be serializable if the specified
- * navigable set is serializable.
- *
- * @param set the navigable set for which an unmodifiable view is to be
- * returned
- * @return an unmodifiable view of the specified navigable set
- * @since 12.0
+ * Creates a view of Set<B> for a Set<A>, given a bijection between A and B.
+ * (Modelled for now as InvertibleFunction<A, B>, can't be Converter<A, B>
+ * because that's not in Guava, though both designs are less than optimal).
+ * Note that the bijection is treated as undefined for values not in the
+ * given Set<A> - it doesn't have to define a true bijection for those.
+ *
+ * <p>Note that the returned Set's contains method is unsafe -
+ * you *must* pass an instance of B to it, since the bijection
+ * can only invert B's (not any Object) back to A, so we can
+ * then delegate the call to the original Set<A>.
*/
- @GwtIncompatible("NavigableSet")
- public static <E> NavigableSet<E> unmodifiableNavigableSet(
- NavigableSet<E> set) {
- if (set instanceof ImmutableSortedSet
- || set instanceof UnmodifiableNavigableSet) {
- return set;
- }
- return new UnmodifiableNavigableSet<E>(set);
+ static <A, B> Set<B> transform(
+ Set<A> set, InvertibleFunction<A, B> bijection) {
+ return new TransformedSet<A, B>(
+ Preconditions.checkNotNull(set, "set"),
+ Preconditions.checkNotNull(bijection, "bijection")
+ );
}
- @GwtIncompatible("NavigableSet")
- static final class UnmodifiableNavigableSet<E>
- extends ForwardingSortedSet<E> implements NavigableSet<E>, Serializable {
- private final NavigableSet<E> delegate;
-
- UnmodifiableNavigableSet(NavigableSet<E> delegate) {
- this.delegate = checkNotNull(delegate);
- }
-
- @Override
- protected SortedSet<E> delegate() {
- return Collections.unmodifiableSortedSet(delegate);
- }
+ /**
+ * Stop-gap measure since there is no bijection related type in Guava.
+ */
+ abstract static class InvertibleFunction<A, B> implements Function<A, B> {
+ abstract A invert(B b);
- @Override
- public E lower(E e) {
- return delegate.lower(e);
- }
+ public InvertibleFunction<B, A> inverse() {
+ return new InvertibleFunction<B, A>() {
+ @Override public A apply(B b) {
+ return InvertibleFunction.this.invert(b);
+ }
- @Override
- public E floor(E e) {
- return delegate.floor(e);
- }
+ @Override B invert(A a) {
+ return InvertibleFunction.this.apply(a);
+ }
- @Override
- public E ceiling(E e) {
- return delegate.ceiling(e);
+ // Not required per se, but just for good karma.
+ @Override public InvertibleFunction<A, B> inverse() {
+ return InvertibleFunction.this;
+ }
+ };
}
+ }
- @Override
- public E higher(E e) {
- return delegate.higher(e);
- }
+ private static class TransformedSet<A, B> extends AbstractSet<B> {
+ final Set<A> delegate;
+ final InvertibleFunction<A, B> bijection;
- @Override
- public E pollFirst() {
- throw new UnsupportedOperationException();
+ TransformedSet(Set<A> delegate, InvertibleFunction<A, B> bijection) {
+ this.delegate = delegate;
+ this.bijection = bijection;
}
- @Override
- public E pollLast() {
- throw new UnsupportedOperationException();
+ @Override public Iterator<B> iterator() {
+ return Iterators.transform(delegate.iterator(), bijection);
}
- private transient UnmodifiableNavigableSet<E> descendingSet;
-
- @Override
- public NavigableSet<E> descendingSet() {
- UnmodifiableNavigableSet<E> result = descendingSet;
- if (result == null) {
- result = descendingSet = new UnmodifiableNavigableSet<E>(
- delegate.descendingSet());
- result.descendingSet = this;
- }
- return result;
+ @Override public int size() {
+ return delegate.size();
}
- @Override
- public Iterator<E> descendingIterator() {
- return Iterators.unmodifiableIterator(delegate.descendingIterator());
+ @SuppressWarnings("unchecked") // unsafe, passed object *must* be B
+ @Override public boolean contains(Object o) {
+ B b = (B) o;
+ A a = bijection.invert(b);
+ /*
+ * Mathematically, Converter<A, B> defines a bijection between ALL A's
+ * on ALL B's. Here we concern ourselves with a subset
+ * of this relation: we only want the part that is defined by a *subset*
+ * of all A's (defined by that Set<A> delegate), and the image
+ * of *that* on B (which is this set). We don't care whether
+ * the converter is *not* a bijection for A's that are not in Set<A>
+ * or B's not in this Set<B>.
+ *
+ * We only want to return true if and only f the user passes a B instance
+ * that is contained in precisely in the image of Set<A>.
+ *
+ * The first test is whether the inverse image of this B is indeed
+ * in Set<A>. But we don't know whether that B belongs in this Set<B>
+ * or not; if not, the converter is free to return
+ * anything it wants, even an element of Set<A> (and this relationship
+ * is not part of the Set<A> <--> Set<B> bijection), and we must not
+ * be confused by that. So we have to do a final check to see if the
+ * image of that A is really equivalent to the passed B, which proves
+ * that the given B belongs indeed in the image of Set<A>.
+ */
+ return delegate.contains(a) && Objects.equal(bijection.apply(a), o);
}
- @Override
- public NavigableSet<E> subSet(
- E fromElement,
- boolean fromInclusive,
- E toElement,
- boolean toInclusive) {
- return unmodifiableNavigableSet(delegate.subSet(
- fromElement,
- fromInclusive,
- toElement,
- toInclusive));
+ @Override public boolean add(B b) {
+ return delegate.add(bijection.invert(b));
}
- @Override
- public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- return unmodifiableNavigableSet(delegate.headSet(toElement, inclusive));
+ @SuppressWarnings("unchecked") // unsafe, passed object *must* be B
+ @Override public boolean remove(Object o) {
+ return contains(o) && delegate.remove(bijection.invert((B) o));
}
- @Override
- public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- return unmodifiableNavigableSet(
- delegate.tailSet(fromElement, inclusive));
+ @Override public void clear() {
+ delegate.clear();
}
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns a synchronized (thread-safe) navigable set backed by the specified
- * navigable set. In order to guarantee serial access, it is critical that
- * <b>all</b> access to the backing navigable set is accomplished
- * through the returned navigable set (or its views).
- *
- * <p>It is imperative that the user manually synchronize on the returned
- * sorted set when iterating over it or any of its {@code descendingSet},
- * {@code subSet}, {@code headSet}, or {@code tailSet} views. <pre> {@code
- *
- * NavigableSet<E> set = synchronizedNavigableSet(new TreeSet<E>());
- * ...
- * synchronized (set) {
- * // Must be in the synchronized block
- * Iterator<E> it = set.iterator();
- * while (it.hasNext()){
- * foo(it.next());
- * }
- * }}</pre>
- *
- * or: <pre> {@code
- *
- * NavigableSet<E> set = synchronizedNavigableSet(new TreeSet<E>());
- * NavigableSet<E> set2 = set.descendingSet().headSet(foo);
- * ...
- * synchronized (set) { // Note: set, not set2!!!
- * // Must be in the synchronized block
- * Iterator<E> it = set2.descendingIterator();
- * while (it.hasNext())
- * foo(it.next());
- * }
- * }}</pre>
- *
- * Failure to follow this advice may result in non-deterministic behavior.
- *
- * <p>The returned navigable set will be serializable if the specified
- * navigable set is serializable.
- *
- * @param navigableSet the navigable set to be "wrapped" in a synchronized
- * navigable set.
- * @return a synchronized view of the specified navigable set.
- * @since 13.0
- */
- @GwtIncompatible("NavigableSet")
- public static <E> NavigableSet<E> synchronizedNavigableSet(
- NavigableSet<E> navigableSet) {
- return Synchronized.navigableSet(navigableSet);
}
/**
* Remove each element in an iterable from a set.
*/
- static boolean removeAllImpl(Set<?> set, Iterator<?> iterator) {
+ static boolean removeAllImpl(Set<?> set, Iterable<?> iterable) {
+ // TODO(jlevy): Have ForwardingSet.standardRemoveAll() call this method.
boolean changed = false;
- while (iterator.hasNext()) {
- changed |= set.remove(iterator.next());
+ for (Object o : iterable) {
+ changed |= set.remove(o);
}
return changed;
}
-
- static boolean removeAllImpl(Set<?> set, Collection<?> collection) {
- checkNotNull(collection); // for GWT
- if (collection instanceof Multiset) {
- collection = ((Multiset<?>) collection).elementSet();
- }
- /*
- * AbstractSet.removeAll(List) has quadratic behavior if the list size
- * is just less than the set's size. We augment the test by
- * assuming that sets have fast contains() performance, and other
- * collections don't. See
- * http://code.google.com/p/guava-libraries/issues/detail?id=1013
- */
- if (collection instanceof Set && collection.size() > set.size()) {
- Iterator<?> setIterator = set.iterator();
- boolean changed = false;
- while (setIterator.hasNext()) {
- if (collection.contains(setIterator.next())) {
- changed = true;
- setIterator.remove();
- }
- }
- return changed;
- } else {
- return removeAllImpl(set, collection.iterator());
- }
- }
-
- @GwtIncompatible("NavigableSet")
- static class DescendingSet<E> extends ForwardingNavigableSet<E> {
- private final NavigableSet<E> forward;
-
- DescendingSet(NavigableSet<E> forward) {
- this.forward = forward;
- }
-
- @Override
- protected NavigableSet<E> delegate() {
- return forward;
- }
-
- @Override
- public E lower(E e) {
- return forward.higher(e);
- }
-
- @Override
- public E floor(E e) {
- return forward.ceiling(e);
- }
-
- @Override
- public E ceiling(E e) {
- return forward.floor(e);
- }
-
- @Override
- public E higher(E e) {
- return forward.lower(e);
- }
-
- @Override
- public E pollFirst() {
- return forward.pollLast();
- }
-
- @Override
- public E pollLast() {
- return forward.pollFirst();
- }
-
- @Override
- public NavigableSet<E> descendingSet() {
- return forward;
- }
-
- @Override
- public Iterator<E> descendingIterator() {
- return forward.iterator();
- }
-
- @Override
- public NavigableSet<E> subSet(
- E fromElement,
- boolean fromInclusive,
- E toElement,
- boolean toInclusive) {
- return forward.subSet(toElement, toInclusive, fromElement, fromInclusive).descendingSet();
- }
-
- @Override
- public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- return forward.tailSet(toElement, inclusive).descendingSet();
- }
-
- @Override
- public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- return forward.headSet(fromElement, inclusive).descendingSet();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Comparator<? super E> comparator() {
- Comparator<? super E> forwardComparator = forward.comparator();
- if (forwardComparator == null) {
- return (Comparator) Ordering.natural().reverse();
- } else {
- return reverse(forwardComparator);
- }
- }
-
- // If we inline this, we get a javac error.
- private static <T> Ordering<T> reverse(Comparator<T> forward) {
- return Ordering.from(forward).reverse();
- }
-
- @Override
- public E first() {
- return forward.last();
- }
-
- @Override
- public SortedSet<E> headSet(E toElement) {
- return standardHeadSet(toElement);
- }
-
- @Override
- public E last() {
- return forward.first();
- }
-
- @Override
- public SortedSet<E> subSet(E fromElement, E toElement) {
- return standardSubSet(fromElement, toElement);
- }
-
- @Override
- public SortedSet<E> tailSet(E fromElement) {
- return standardTailSet(fromElement);
- }
-
- @Override
- public Iterator<E> iterator() {
- return forward.descendingIterator();
- }
-
- @Override
- public Object[] toArray() {
- return standardToArray();
- }
-
- @Override
- public <T> T[] toArray(T[] array) {
- return standardToArray(array);
- }
-
- @Override
- public String toString() {
- return standardToString();
- }
- }
-
- /**
- * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
- */
- static <T> SortedSet<T> cast(Iterable<T> iterable) {
- return (SortedSet<T>) iterable;
- }
}
diff --git a/guava/src/com/google/common/collect/SingletonImmutableBiMap.java b/guava/src/com/google/common/collect/SingletonImmutableBiMap.java
deleted file mode 100644
index 2b6f462..0000000
--- a/guava/src/com/google/common/collect/SingletonImmutableBiMap.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-
-import javax.annotation.Nullable;
-
-/**
- * Implementation of {@link ImmutableMap} with exactly one entry.
- *
- * @author Jesse Wilson
- * @author Kevin Bourrillion
- */
-@GwtCompatible(serializable = true, emulated = true)
-@SuppressWarnings("serial") // uses writeReplace(), not default serialization
-final class SingletonImmutableBiMap<K, V> extends ImmutableBiMap<K, V> {
-
- final transient K singleKey;
- final transient V singleValue;
-
- SingletonImmutableBiMap(K singleKey, V singleValue) {
- this.singleKey = singleKey;
- this.singleValue = singleValue;
- }
-
- private SingletonImmutableBiMap(K singleKey, V singleValue,
- ImmutableBiMap<V, K> inverse) {
- this.singleKey = singleKey;
- this.singleValue = singleValue;
- this.inverse = inverse;
- }
-
- SingletonImmutableBiMap(Entry<K, V> entry) {
- this(entry.getKey(), entry.getValue());
- }
-
- @Override public V get(@Nullable Object key) {
- return singleKey.equals(key) ? singleValue : null;
- }
-
- @Override
- public int size() {
- return 1;
- }
-
- @Override public boolean containsKey(@Nullable Object key) {
- return singleKey.equals(key);
- }
-
- @Override public boolean containsValue(@Nullable Object value) {
- return singleValue.equals(value);
- }
-
- @Override boolean isPartialView() {
- return false;
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- return ImmutableSet.of(Maps.immutableEntry(singleKey, singleValue));
- }
-
- @Override
- ImmutableSet<K> createKeySet() {
- return ImmutableSet.of(singleKey);
- }
-
- transient ImmutableBiMap<V, K> inverse;
-
- @Override
- public ImmutableBiMap<V, K> inverse() {
- // racy single-check idiom
- ImmutableBiMap<V, K> result = inverse;
- if (result == null) {
- return inverse = new SingletonImmutableBiMap<V, K>(
- singleValue, singleKey, this);
- } else {
- return result;
- }
- }
-}
diff --git a/guava/src/com/google/common/collect/SingletonImmutableList.java b/guava/src/com/google/common/collect/SingletonImmutableList.java
index 2e20c41..e546d2b 100644
--- a/guava/src/com/google/common/collect/SingletonImmutableList.java
+++ b/guava/src/com/google/common/collect/SingletonImmutableList.java
@@ -22,6 +22,7 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
import java.util.List;
+import java.util.NoSuchElementException;
import javax.annotation.Nullable;
@@ -55,7 +56,47 @@ final class SingletonImmutableList<E> extends ImmutableList<E> {
}
@Override public int lastIndexOf(@Nullable Object object) {
- return indexOf(object);
+ return element.equals(object) ? 0 : -1;
+ }
+
+ @Override public UnmodifiableListIterator<E> listIterator(final int start) {
+ Preconditions.checkPositionIndex(start, 1);
+ return new UnmodifiableListIterator<E>() {
+
+ boolean hasNext = start == 0;
+
+ @Override public boolean hasNext() {
+ return hasNext;
+ }
+
+ @Override public boolean hasPrevious() {
+ return !hasNext;
+ }
+
+ @Override public E next() {
+ if (!hasNext) {
+ throw new NoSuchElementException();
+ }
+ hasNext = false;
+ return element;
+ }
+
+ @Override public int nextIndex() {
+ return hasNext ? 0 : 1;
+ }
+
+ @Override public E previous() {
+ if (hasNext) {
+ throw new NoSuchElementException();
+ }
+ hasNext = true;
+ return element;
+ }
+
+ @Override public int previousIndex() {
+ return hasNext ? -1 : 0;
+ }
+ };
}
@Override
@@ -76,7 +117,7 @@ final class SingletonImmutableList<E> extends ImmutableList<E> {
return element.equals(object);
}
- @Override public boolean equals(@Nullable Object object) {
+ @Override public boolean equals(Object object) {
if (object == this) {
return true;
}
diff --git a/guava/src/com/google/common/collect/SingletonImmutableMap.java b/guava/src/com/google/common/collect/SingletonImmutableMap.java
new file mode 100644
index 0000000..9dd6e60
--- /dev/null
+++ b/guava/src/com/google/common/collect/SingletonImmutableMap.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+/**
+ * Implementation of {@link ImmutableMap} with exactly one entry.
+ *
+ * @author Jesse Wilson
+ * @author Kevin Bourrillion
+ */
+@GwtCompatible(serializable = true, emulated = true)
+@SuppressWarnings("serial") // uses writeReplace(), not default serialization
+final class SingletonImmutableMap<K, V> extends ImmutableMap<K, V> {
+
+ final transient K singleKey;
+ final transient V singleValue;
+
+ private transient Entry<K, V> entry;
+
+ SingletonImmutableMap(K singleKey, V singleValue) {
+ this.singleKey = singleKey;
+ this.singleValue = singleValue;
+ }
+
+ SingletonImmutableMap(Entry<K, V> entry) {
+ this.entry = entry;
+ this.singleKey = entry.getKey();
+ this.singleValue = entry.getValue();
+ }
+
+ private Entry<K, V> entry() {
+ Entry<K, V> e = entry;
+ return (e == null)
+ ? (entry = Maps.immutableEntry(singleKey, singleValue)) : e;
+ }
+
+ @Override public V get(@Nullable Object key) {
+ return singleKey.equals(key) ? singleValue : null;
+ }
+
+ @Override
+ public int size() {
+ return 1;
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ @Override public boolean containsKey(@Nullable Object key) {
+ return singleKey.equals(key);
+ }
+
+ @Override public boolean containsValue(@Nullable Object value) {
+ return singleValue.equals(value);
+ }
+
+ @Override boolean isPartialView() {
+ return false;
+ }
+
+ private transient ImmutableSet<Entry<K, V>> entrySet;
+
+ @Override public ImmutableSet<Entry<K, V>> entrySet() {
+ ImmutableSet<Entry<K, V>> es = entrySet;
+ return (es == null) ? (entrySet = ImmutableSet.of(entry())) : es;
+ }
+
+ private transient ImmutableSet<K> keySet;
+
+ @Override public ImmutableSet<K> keySet() {
+ ImmutableSet<K> ks = keySet;
+ return (ks == null) ? (keySet = ImmutableSet.of(singleKey)) : ks;
+ }
+
+ private transient ImmutableCollection<V> values;
+
+ @Override public ImmutableCollection<V> values() {
+ ImmutableCollection<V> v = values;
+ return (v == null) ? (values = new Values<V>(singleValue)) : v;
+ }
+
+ @SuppressWarnings("serial") // uses writeReplace(), not default serialization
+ private static class Values<V> extends ImmutableCollection<V> {
+ final V singleValue;
+
+ Values(V singleValue) {
+ this.singleValue = singleValue;
+ }
+
+ @Override public boolean contains(Object object) {
+ return singleValue.equals(object);
+ }
+
+ @Override public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public int size() {
+ return 1;
+ }
+
+ @Override public UnmodifiableIterator<V> iterator() {
+ return Iterators.singletonIterator(singleValue);
+ }
+
+ @Override boolean isPartialView() {
+ return true;
+ }
+ }
+
+ @Override public boolean equals(@Nullable Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof Map) {
+ Map<?, ?> that = (Map<?, ?>) object;
+ if (that.size() != 1) {
+ return false;
+ }
+ Entry<?, ?> entry = that.entrySet().iterator().next();
+ return singleKey.equals(entry.getKey())
+ && singleValue.equals(entry.getValue());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ return singleKey.hashCode() ^ singleValue.hashCode();
+ }
+
+ @Override public String toString() {
+ return new StringBuilder()
+ .append('{')
+ .append(singleKey.toString())
+ .append('=')
+ .append(singleValue.toString())
+ .append('}')
+ .toString();
+ }
+}
diff --git a/guava/src/com/google/common/collect/SingletonImmutableTable.java b/guava/src/com/google/common/collect/SingletonImmutableTable.java
index e6e850c..4e33aea 100644
--- a/guava/src/com/google/common/collect/SingletonImmutableTable.java
+++ b/guava/src/com/google/common/collect/SingletonImmutableTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import javax.annotation.Nullable;
/**
* An implementation of {@link ImmutableTable} that holds a single cell.
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
@GwtCompatible
final class SingletonImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
@@ -119,7 +119,7 @@ final class SingletonImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
@Override public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
- } else if (obj instanceof Table) {
+ } else if (obj instanceof Table<?, ?, ?>) {
Table<?, ?, ?> that = (Table<?, ?, ?>) obj;
if (that.size() == 1) {
Cell<?, ?, ?> thatCell = that.cellSet().iterator().next();
diff --git a/guava/src/com/google/common/collect/SortedIterables.java b/guava/src/com/google/common/collect/SortedIterables.java
index 2158e9f..8089b10 100644
--- a/guava/src/com/google/common/collect/SortedIterables.java
+++ b/guava/src/com/google/common/collect/SortedIterables.java
@@ -17,8 +17,16 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Function;
+import com.google.common.collect.Multiset.Entry;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import java.util.SortedSet;
/**
@@ -39,22 +47,149 @@ final class SortedIterables {
checkNotNull(elements);
Comparator<?> comparator2;
if (elements instanceof SortedSet) {
- comparator2 = comparator((SortedSet<?>) elements);
+ SortedSet<?> sortedSet = (SortedSet<?>) elements;
+ comparator2 = sortedSet.comparator();
+ if (comparator2 == null) {
+ comparator2 = (Comparator) Ordering.natural();
+ }
} else if (elements instanceof SortedIterable) {
comparator2 = ((SortedIterable<?>) elements).comparator();
} else {
- return false;
+ comparator2 = null;
}
return comparator.equals(comparator2);
}
+ /**
+ * Returns a sorted collection of the unique elements according to the specified comparator. Does
+ * not check for null.
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> Collection<E> sortedUnique(
+ Comparator<? super E> comparator, Iterator<E> elements) {
+ SortedSet<E> sortedSet = Sets.newTreeSet(comparator);
+ Iterators.addAll(sortedSet, elements);
+ return sortedSet;
+ }
+
+ /**
+ * Returns a sorted collection of the unique elements according to the specified comparator. Does
+ * not check for null.
+ */
@SuppressWarnings("unchecked")
- // if sortedSet.comparator() is null, the set must be naturally ordered
- public static <E> Comparator<? super E> comparator(SortedSet<E> sortedSet) {
- Comparator<? super E> result = sortedSet.comparator();
- if (result == null) {
- result = (Comparator<? super E>) Ordering.natural();
+ public static <E> Collection<E> sortedUnique(
+ Comparator<? super E> comparator, Iterable<E> elements) {
+ if (elements instanceof Multiset) {
+ elements = ((Multiset<E>) elements).elementSet();
+ }
+ if (elements instanceof Set) {
+ if (hasSameComparator(comparator, elements)) {
+ return (Set<E>) elements;
+ }
+ List<E> list = Lists.newArrayList(elements);
+ Collections.sort(list, comparator);
+ return list;
+ }
+ E[] array = (E[]) Iterables.toArray(elements);
+ if (!hasSameComparator(comparator, elements)) {
+ Arrays.sort(array, comparator);
+ }
+ return uniquifySortedArray(comparator, array);
+ }
+
+ private static <E> Collection<E> uniquifySortedArray(
+ Comparator<? super E> comparator, E[] array) {
+ if (array.length == 0) {
+ return Collections.emptySet();
}
- return result;
+ int length = 1;
+ for (int i = 1; i < array.length; i++) {
+ int cmp = comparator.compare(array[i], array[length - 1]);
+ if (cmp != 0) {
+ array[length++] = array[i];
+ }
+ }
+ if (length < array.length) {
+ array = ObjectArrays.arraysCopyOf(array, length);
+ }
+ return Arrays.asList(array);
+ }
+
+ /**
+ * Returns a collection of multiset entries representing the counts of the distinct elements, in
+ * sorted order. Does not check for null.
+ */
+ public static <E> Collection<Multiset.Entry<E>> sortedCounts(
+ Comparator<? super E> comparator, Iterator<E> elements) {
+ TreeMultiset<E> multiset = TreeMultiset.create(comparator);
+ Iterators.addAll(multiset, elements);
+ return multiset.entrySet();
+ }
+
+ /**
+ * Returns a collection of multiset entries representing the counts of the distinct elements, in
+ * sorted order. Does not check for null.
+ */
+ public static <E> Collection<Multiset.Entry<E>> sortedCounts(
+ Comparator<? super E> comparator, Iterable<E> elements) {
+ if (elements instanceof Multiset) {
+ Multiset<E> multiset = (Multiset<E>) elements;
+ if (hasSameComparator(comparator, elements)) {
+ return multiset.entrySet();
+ }
+ List<Multiset.Entry<E>> entries = Lists.newArrayList(multiset.entrySet());
+ Collections.sort(
+ entries, Ordering.from(comparator).onResultOf(new Function<Multiset.Entry<E>, E>() {
+ @Override
+ public E apply(Entry<E> entry) {
+ return entry.getElement();
+ }
+ }));
+ return entries;
+ } else if (elements instanceof Set) { // known distinct
+ Collection<E> sortedElements;
+ if (hasSameComparator(comparator, elements)) {
+ sortedElements = (Collection<E>) elements;
+ } else {
+ List<E> list = Lists.newArrayList(elements);
+ Collections.sort(list, comparator);
+ sortedElements = list;
+ }
+ return singletonEntries(sortedElements);
+ } else if (hasSameComparator(comparator, elements)) {
+ E current = null;
+ int currentCount = 0;
+ List<Multiset.Entry<E>> sortedEntries = Lists.newArrayList();
+ for (E e : elements) {
+ if (currentCount > 0) {
+ if (comparator.compare(current, e) == 0) {
+ currentCount++;
+ } else {
+ sortedEntries.add(Multisets.immutableEntry(current, currentCount));
+ current = e;
+ currentCount = 1;
+ }
+ } else {
+ current = e;
+ currentCount = 1;
+ }
+ }
+ if (currentCount > 0) {
+ sortedEntries.add(Multisets.immutableEntry(current, currentCount));
+ }
+ return sortedEntries;
+ }
+ TreeMultiset<E> multiset = TreeMultiset.create(comparator);
+ Iterables.addAll(multiset, elements);
+ return multiset.entrySet();
+ }
+
+ static <E> Collection<Multiset.Entry<E>> singletonEntries(Collection<E> set) {
+ return Collections2.transform(set, new Function<E, Multiset.Entry<E>>() {
+ @Override
+ public Entry<E> apply(E elem) {
+ return Multisets.immutableEntry(elem, 1);
+ }
+ });
}
}
diff --git a/guava/src/com/google/common/collect/SortedLists.java b/guava/src/com/google/common/collect/SortedLists.java
index 6fc0d71..afcec59 100644
--- a/guava/src/com/google/common/collect/SortedLists.java
+++ b/guava/src/com/google/common/collect/SortedLists.java
@@ -143,7 +143,7 @@ import javax.annotation.Nullable;
*/
NEXT_LOWER {
@Override
- int resultIndex(int higherIndex) {
+ <E> int resultIndex(int higherIndex) {
return higherIndex - 1;
}
},
@@ -153,7 +153,7 @@ import javax.annotation.Nullable;
*/
NEXT_HIGHER {
@Override
- public int resultIndex(int higherIndex) {
+ public <E> int resultIndex(int higherIndex) {
return higherIndex;
}
},
@@ -171,12 +171,12 @@ import javax.annotation.Nullable;
*/
INVERTED_INSERTION_INDEX {
@Override
- public int resultIndex(int higherIndex) {
+ public <E> int resultIndex(int higherIndex) {
return ~higherIndex;
}
};
- abstract int resultIndex(int higherIndex);
+ abstract <E> int resultIndex(int higherIndex);
}
/**
@@ -200,7 +200,7 @@ import javax.annotation.Nullable;
* KeyAbsentBehavior)} using {@link Ordering#natural}.
*/
public static <E, K extends Comparable> int binarySearch(List<E> list,
- Function<? super E, K> keyFunction, @Nullable K key, KeyPresentBehavior presentBehavior,
+ Function<? super E, K> keyFunction, K key, KeyPresentBehavior presentBehavior,
KeyAbsentBehavior absentBehavior) {
return binarySearch(
list,
@@ -221,7 +221,7 @@ import javax.annotation.Nullable;
public static <E, K> int binarySearch(
List<E> list,
Function<? super E, K> keyFunction,
- @Nullable K key,
+ K key,
Comparator<? super K> keyComparator,
KeyPresentBehavior presentBehavior,
KeyAbsentBehavior absentBehavior) {
diff --git a/guava/src/com/google/common/collect/SortedMapDifference.java b/guava/src/com/google/common/collect/SortedMapDifference.java
index 07f75ee..f44aa1a 100644
--- a/guava/src/com/google/common/collect/SortedMapDifference.java
+++ b/guava/src/com/google/common/collect/SortedMapDifference.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import java.util.SortedMap;
@@ -26,6 +27,7 @@ import java.util.SortedMap;
* @author Louis Wasserman
* @since 8.0
*/
+@Beta
@GwtCompatible
public interface SortedMapDifference<K, V> extends MapDifference<K, V> {
diff --git a/guava/src/com/google/common/collect/SortedMaps.java b/guava/src/com/google/common/collect/SortedMaps.java
new file mode 100644
index 0000000..0055cbd
--- /dev/null
+++ b/guava/src/com/google/common/collect/SortedMaps.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+
+import javax.annotation.Nullable;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Maps.EntryTransformer;
+
+/**
+ * Static utility methods pertaining to {@link SortedMap} instances.
+ *
+ * @author Louis Wasserman
+ * @since 8.0
+ * @deprecated Use the identical methods in {@link Maps}. This class is
+ * scheduled for deletion from Guava in Guava release 12.0.
+ */
+@Beta
+@Deprecated
+@GwtCompatible
+public final class SortedMaps {
+ private SortedMaps() {}
+
+ /**
+ * Returns a view of a sorted map where each value is transformed by a
+ * function. All other properties of the map, such as iteration order, are
+ * left intact. For example, the code: <pre> {@code
+ *
+ * SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
+ * Function<Integer, Double> sqrt =
+ * new Function<Integer, Double>() {
+ * public Double apply(Integer in) {
+ * return Math.sqrt((int) in);
+ * }
+ * };
+ * SortedMap<String, Double> transformed =
+ * Maps.transformSortedValues(map, sqrt);
+ * System.out.println(transformed);}</pre>
+ *
+ * ... prints {@code {a=2.0, b=3.0}}.
+ *
+ * <p>Changes in the underlying map are reflected in this view. Conversely,
+ * this view supports removal operations, and these are reflected in the
+ * underlying map.
+ *
+ * <p>It's acceptable for the underlying map to contain null keys, and even
+ * null values provided that the function is capable of accepting null input.
+ * The transformed map might contain null values, if the function sometimes
+ * gives a null result.
+ *
+ * <p>The returned map is not thread-safe or serializable, even if the
+ * underlying map is.
+ *
+ * <p>The function is applied lazily, invoked when needed. This is necessary
+ * for the returned map to be a view, but it means that the function will be
+ * applied many times for bulk operations like {@link Map#containsValue} and
+ * {@code Map.toString()}. For this to perform well, {@code function} should
+ * be fast. To avoid lazy evaluation when the returned map doesn't need to be
+ * a view, copy the returned map into a new map of your choosing.
+ *
+ * @deprecated Use {@link Maps#transformValues(SortedMap, Function)}
+ */
+ @Deprecated public static <K, V1, V2> SortedMap<K, V2> transformValues(
+ SortedMap<K, V1> fromMap, final Function<? super V1, V2> function) {
+ return Maps.transformValues(fromMap, function);
+ }
+
+ /**
+ * Returns a view of a sorted map whose values are derived from the original
+ * sorted map's entries. In contrast to {@link #transformValues}, this
+ * method's entry-transformation logic may depend on the key as well as the
+ * value.
+ *
+ * <p>All other properties of the transformed map, such as iteration order,
+ * are left intact. For example, the code: <pre> {@code
+ *
+ * Map<String, Boolean> options =
+ * ImmutableSortedMap.of("verbose", true, "sort", false);
+ * EntryTransformer<String, Boolean, String> flagPrefixer =
+ * new EntryTransformer<String, Boolean, String>() {
+ * public String transformEntry(String key, Boolean value) {
+ * return value ? key : "yes" + key;
+ * }
+ * };
+ * SortedMap<String, String> transformed =
+ * LabsMaps.transformSortedEntries(options, flagPrefixer);
+ * System.out.println(transformed);}</pre>
+ *
+ * ... prints {@code {sort=yessort, verbose=verbose}}.
+ *
+ * <p>Changes in the underlying map are reflected in this view. Conversely,
+ * this view supports removal operations, and these are reflected in the
+ * underlying map.
+ *
+ * <p>It's acceptable for the underlying map to contain null keys and null
+ * values provided that the transformer is capable of accepting null inputs.
+ * The transformed map might contain null values if the transformer sometimes
+ * gives a null result.
+ *
+ * <p>The returned map is not thread-safe or serializable, even if the
+ * underlying map is.
+ *
+ * <p>The transformer is applied lazily, invoked when needed. This is
+ * necessary for the returned map to be a view, but it means that the
+ * transformer will be applied many times for bulk operations like {@link
+ * Map#containsValue} and {@link Object#toString}. For this to perform well,
+ * {@code transformer} should be fast. To avoid lazy evaluation when the
+ * returned map doesn't need to be a view, copy the returned map into a new
+ * map of your choosing.
+ *
+ * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
+ * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
+ * that {@code k2} is also of type {@code K}. Using an {@code
+ * EntryTransformer} key type for which this may not hold, such as {@code
+ * ArrayList}, may risk a {@code ClassCastException} when calling methods on
+ * the transformed map.
+ *
+ * @deprecated Use {@link Maps#transformEntries(SortedMap, EntryTransformer)}
+ */
+ @Deprecated public static <K, V1, V2> SortedMap<K, V2> transformEntries(
+ final SortedMap<K, V1> fromMap,
+ EntryTransformer<? super K, ? super V1, V2> transformer) {
+ return Maps.transformEntries(fromMap, transformer);
+ }
+
+ /**
+ * Computes the difference between two sorted maps, using the comparator of
+ * the left map, or {@code Ordering.natural()} if the left map uses the
+ * natural ordering of its elements. This difference is an immutable snapshot
+ * of the state of the maps at the time this method is called. It will never
+ * change, even if the maps change at a later time.
+ *
+ * <p>Since this method uses {@code TreeMap} instances internally, the keys of
+ * the right map must all compare as distinct according to the comparator
+ * of the left map.
+ *
+ * <p><b>Note:</b>If you only need to know whether two sorted maps have the
+ * same mappings, call {@code left.equals(right)} instead of this method.
+ *
+ * @param left the map to treat as the "left" map for purposes of comparison
+ * @param right the map to treat as the "right" map for purposes of comparison
+ * @return the difference between the two maps
+ * @deprecated Use {@link Maps#difference(SortedMap, Map)}
+ */
+ @Deprecated public static <K, V> SortedMapDifference<K, V> difference(
+ SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
+ return Maps.difference(left, right);
+ }
+
+ /**
+ * Returns the specified comparator if not null; otherwise returns {@code
+ * Ordering.natural()}. This method is an abomination of generics; the only
+ * purpose of this method is to contain the ugly type-casting in one place.
+ */
+ @SuppressWarnings("unchecked")
+ static <E> Comparator<? super E> orNaturalOrder(
+ @Nullable Comparator<? super E> comparator) {
+ if (comparator != null) { // can't use ? : because of javac bug 5080917
+ return comparator;
+ }
+ return (Comparator<E>) Ordering.natural();
+ }
+
+ /**
+ * Returns a sorted map containing the mappings in {@code unfiltered} whose
+ * keys satisfy a predicate. The returned map is a live view of {@code
+ * unfiltered}; changes to one affect the other.
+ *
+ * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
+ * values()} views have iterators that don't support {@code remove()}, but all
+ * other methods are supported by the map and its views. When given a key that
+ * doesn't satisfy the predicate, the map's {@code put()} and {@code putAll()}
+ * methods throw an {@link IllegalArgumentException}.
+ *
+ * <p>When methods such as {@code removeAll()} and {@code clear()} are called
+ * on the filtered map or its views, only mappings whose keys satisfy the
+ * filter will be removed from the underlying map.
+ *
+ * <p>The returned map isn't threadsafe or serializable, even if {@code
+ * unfiltered} is.
+ *
+ * <p>Many of the filtered map's methods, such as {@code size()},
+ * iterate across every key/value mapping in the underlying map and determine
+ * which satisfy the filter. When a live view is <i>not</i> needed, it may be
+ * faster to copy the filtered map and use the copy.
+ *
+ * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with
+ * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
+ * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
+ * inconsistent with equals.
+ */
+ @GwtIncompatible("untested")
+ public static <K, V> SortedMap<K, V> filterKeys(
+ SortedMap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
+ // TODO: Return a subclass of Maps.FilteredKeyMap for slightly better
+ // performance.
+ checkNotNull(keyPredicate);
+ Predicate<Entry<K, V>> entryPredicate = new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return keyPredicate.apply(input.getKey());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
+ }
+
+ /**
+ * Returns a sorted map containing the mappings in {@code unfiltered} whose
+ * values satisfy a predicate. The returned map is a live view of {@code
+ * unfiltered}; changes to one affect the other.
+ *
+ * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
+ * values()} views have iterators that don't support {@code remove()}, but all
+ * other methods are supported by the map and its views. When given a value
+ * that doesn't satisfy the predicate, the map's {@code put()}, {@code
+ * putAll()}, and {@link Entry#setValue} methods throw an {@link
+ * IllegalArgumentException}.
+ *
+ * <p>When methods such as {@code removeAll()} and {@code clear()} are called
+ * on the filtered map or its views, only mappings whose values satisfy the
+ * filter will be removed from the underlying map.
+ *
+ * <p>The returned map isn't threadsafe or serializable, even if {@code
+ * unfiltered} is.
+ *
+ * <p>Many of the filtered map's methods, such as {@code size()},
+ * iterate across every key/value mapping in the underlying map and determine
+ * which satisfy the filter. When a live view is <i>not</i> needed, it may be
+ * faster to copy the filtered map and use the copy.
+ *
+ * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
+ * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
+ * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
+ * inconsistent with equals.
+ */
+ @GwtIncompatible("untested")
+ public static <K, V> SortedMap<K, V> filterValues(
+ SortedMap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
+ checkNotNull(valuePredicate);
+ Predicate<Entry<K, V>> entryPredicate =
+ new Predicate<Entry<K, V>>() {
+ @Override
+ public boolean apply(Entry<K, V> input) {
+ return valuePredicate.apply(input.getValue());
+ }
+ };
+ return filterEntries(unfiltered, entryPredicate);
+ }
+
+ /**
+ * Returns a sorted map containing the mappings in {@code unfiltered} that
+ * satisfy a predicate. The returned map is a live view of {@code unfiltered};
+ * changes to one affect the other.
+ *
+ * <p>The resulting map's {@code keySet()}, {@code entrySet()}, and {@code
+ * values()} views have iterators that don't support {@code remove()}, but all
+ * other methods are supported by the map and its views. When given a
+ * key/value pair that doesn't satisfy the predicate, the map's {@code put()}
+ * and {@code putAll()} methods throw an {@link IllegalArgumentException}.
+ * Similarly, the map's entries have a {@link Entry#setValue} method that
+ * throws an {@link IllegalArgumentException} when the existing key and the
+ * provided value don't satisfy the predicate.
+ *
+ * <p>When methods such as {@code removeAll()} and {@code clear()} are called
+ * on the filtered map or its views, only mappings that satisfy the filter
+ * will be removed from the underlying map.
+ *
+ * <p>The returned map isn't threadsafe or serializable, even if {@code
+ * unfiltered} is.
+ *
+ * <p>Many of the filtered map's methods, such as {@code size()},
+ * iterate across every key/value mapping in the underlying map and determine
+ * which satisfy the filter. When a live view is <i>not</i> needed, it may be
+ * faster to copy the filtered map and use the copy.
+ *
+ * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
+ * equals</i>, as documented at {@link Predicate#apply}.
+ */
+ @GwtIncompatible("untested")
+ public static <K, V> SortedMap<K, V> filterEntries(
+ SortedMap<K, V> unfiltered,
+ Predicate<? super Entry<K, V>> entryPredicate) {
+ checkNotNull(entryPredicate);
+ return (unfiltered instanceof FilteredSortedMap)
+ ? filterFiltered((FilteredSortedMap<K, V>) unfiltered, entryPredicate)
+ : new FilteredSortedMap<K, V>(checkNotNull(unfiltered), entryPredicate);
+ }
+
+ /**
+ * Support {@code clear()}, {@code removeAll()}, and {@code retainAll()} when
+ * filtering a filtered sorted map.
+ */
+ private static <K, V> SortedMap<K, V> filterFiltered(
+ FilteredSortedMap<K, V> map,
+ Predicate<? super Entry<K, V>> entryPredicate) {
+ Predicate<Entry<K, V>> predicate
+ = Predicates.and(map.predicate, entryPredicate);
+ return new FilteredSortedMap<K, V>(map.sortedMap(), predicate);
+ }
+
+ private static class FilteredSortedMap<K, V>
+ extends Maps.FilteredEntryMap<K, V> implements SortedMap<K, V> {
+
+ FilteredSortedMap(SortedMap<K, V> unfiltered,
+ Predicate<? super Entry<K, V>> entryPredicate) {
+ super(unfiltered, entryPredicate);
+ }
+
+ SortedMap<K, V> sortedMap() {
+ return (SortedMap<K, V>) unfiltered;
+ }
+
+ @Override public Comparator<? super K> comparator() {
+ return sortedMap().comparator();
+ }
+
+ @Override public K firstKey() {
+ // correctly throws NoSuchElementException when filtered map is empty.
+ return keySet().iterator().next();
+ }
+
+ @Override public K lastKey() {
+ SortedMap<K, V> headMap = sortedMap();
+ while (true) {
+ // correctly throws NoSuchElementException when filtered map is empty.
+ K key = headMap.lastKey();
+ if (apply(key, unfiltered.get(key))) {
+ return key;
+ }
+ headMap = sortedMap().headMap(key);
+ }
+ }
+
+ @Override public SortedMap<K, V> headMap(K toKey) {
+ return new FilteredSortedMap<K, V>(sortedMap().headMap(toKey), predicate);
+ }
+
+ @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
+ return new FilteredSortedMap<K, V>(
+ sortedMap().subMap(fromKey, toKey), predicate);
+ }
+
+ @Override public SortedMap<K, V> tailMap(K fromKey) {
+ return new FilteredSortedMap<K, V>(
+ sortedMap().tailMap(fromKey), predicate);
+ }
+ }
+}
diff --git a/guava/src/com/google/common/collect/SortedMultiset.java b/guava/src/com/google/common/collect/SortedMultiset.java
index 9e14a80..0713151 100644
--- a/guava/src/com/google/common/collect/SortedMultiset.java
+++ b/guava/src/com/google/common/collect/SortedMultiset.java
@@ -22,7 +22,7 @@ import com.google.common.annotations.GwtCompatible;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
-import java.util.NavigableSet;
+import java.util.SortedSet;
/**
* A {@link Multiset} which maintains the ordering of its elements, according to
@@ -36,16 +36,12 @@ import java.util.NavigableSet;
* resulting multiset will violate the {@link Collection} contract, which it is
* specified in terms of {@link Object#equals}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
- *
* @author Louis Wasserman
* @since 11.0
*/
@Beta
-@GwtCompatible(emulated = true)
-public interface SortedMultiset<E> extends SortedMultisetBridge<E>, SortedIterable<E> {
+@GwtCompatible
+public interface SortedMultiset<E> extends Multiset<E>, SortedIterable<E> {
/**
* Returns the comparator that orders this multiset, or
* {@link Ordering#natural()} if the natural ordering of the elements is used.
@@ -77,11 +73,9 @@ public interface SortedMultiset<E> extends SortedMultisetBridge<E>, SortedIterab
Entry<E> pollLastEntry();
/**
- * Returns a {@link NavigableSet} view of the distinct elements in this multiset.
- *
- * @since 14.0 (present with return type {@code SortedSet} since 11.0)
+ * Returns a {@link SortedSet} view of the distinct elements in this multiset.
*/
- @Override NavigableSet<E> elementSet();
+ @Override SortedSet<E> elementSet();
/**
* {@inheritDoc}
diff --git a/guava/src/com/google/common/collect/SortedMultisetBridge.java b/guava/src/com/google/common/collect/SortedMultisetBridge.java
deleted file mode 100644
index 669b54d..0000000
--- a/guava/src/com/google/common/collect/SortedMultisetBridge.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import java.util.SortedSet;
-
-/**
- * Superinterface of {@link SortedMultiset} to introduce a bridge method for
- * {@code elementSet()}, to ensure binary compatibility with older Guava versions
- * that specified {@code elementSet()} to return {@code SortedSet}.
- *
- * @author Louis Wasserman
- */
-interface SortedMultisetBridge<E> extends Multiset<E> {
- @Override
- SortedSet<E> elementSet();
-}
diff --git a/guava/src/com/google/common/collect/SortedMultisets.java b/guava/src/com/google/common/collect/SortedMultisets.java
index 1055664..ff18b74 100644
--- a/guava/src/com/google/common/collect/SortedMultisets.java
+++ b/guava/src/com/google/common/collect/SortedMultisets.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,28 +16,22 @@
package com.google.common.collect;
-import static com.google.common.collect.BoundType.CLOSED;
-import static com.google.common.collect.BoundType.OPEN;
-
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Multiset.Entry;
import java.util.Comparator;
import java.util.Iterator;
-import java.util.NavigableSet;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.SortedSet;
-import javax.annotation.Nullable;
-
/**
* Provides static utility methods for creating and working with
* {@link SortedMultiset} instances.
- *
+ *
* @author Louis Wasserman
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
final class SortedMultisets {
private SortedMultisets() {
}
@@ -45,32 +39,26 @@ final class SortedMultisets {
/**
* A skeleton implementation for {@link SortedMultiset#elementSet}.
*/
- static class ElementSet<E> extends Multisets.ElementSet<E> implements
+ static abstract class ElementSet<E> extends Multisets.ElementSet<E> implements
SortedSet<E> {
- private final SortedMultiset<E> multiset;
-
- ElementSet(SortedMultiset<E> multiset) {
- this.multiset = multiset;
- }
-
- @Override final SortedMultiset<E> multiset() {
- return multiset;
- }
+ @Override abstract SortedMultiset<E> multiset();
@Override public Comparator<? super E> comparator() {
return multiset().comparator();
}
@Override public SortedSet<E> subSet(E fromElement, E toElement) {
- return multiset().subMultiset(fromElement, CLOSED, toElement, OPEN).elementSet();
+ return multiset().subMultiset(fromElement, BoundType.CLOSED, toElement,
+ BoundType.OPEN).elementSet();
}
@Override public SortedSet<E> headSet(E toElement) {
- return multiset().headMultiset(toElement, OPEN).elementSet();
+ return multiset().headMultiset(toElement, BoundType.OPEN).elementSet();
}
@Override public SortedSet<E> tailSet(E fromElement) {
- return multiset().tailMultiset(fromElement, CLOSED).elementSet();
+ return multiset().tailMultiset(fromElement, BoundType.CLOSED)
+ .elementSet();
}
@Override public E first() {
@@ -82,84 +70,127 @@ final class SortedMultisets {
}
}
+ private static <E> E getElementOrThrow(Entry<E> entry) {
+ if (entry == null) {
+ throw new NoSuchElementException();
+ }
+ return entry.getElement();
+ }
+
/**
- * A skeleton navigable implementation for {@link SortedMultiset#elementSet}.
+ * A skeleton implementation of a descending multiset. Only needs
+ * {@code forwardMultiset()} and {@code entryIterator()}.
*/
- @GwtIncompatible("Navigable")
- static class NavigableElementSet<E> extends ElementSet<E> implements NavigableSet<E> {
- NavigableElementSet(SortedMultiset<E> multiset) {
- super(multiset);
+ static abstract class DescendingMultiset<E> extends ForwardingMultiset<E>
+ implements SortedMultiset<E> {
+ abstract SortedMultiset<E> forwardMultiset();
+
+ private transient Comparator<? super E> comparator;
+
+ @Override public Comparator<? super E> comparator() {
+ Comparator<? super E> result = comparator;
+ if (result == null) {
+ return comparator =
+ Ordering.from(forwardMultiset().comparator()).<E>reverse();
+ }
+ return result;
}
- @Override
- public E lower(E e) {
- return getElementOrNull(multiset().headMultiset(e, OPEN).lastEntry());
+ private transient SortedSet<E> elementSet;
+
+ @Override public SortedSet<E> elementSet() {
+ SortedSet<E> result = elementSet;
+ if (result == null) {
+ return elementSet = new SortedMultisets.ElementSet<E>() {
+ @Override SortedMultiset<E> multiset() {
+ return DescendingMultiset.this;
+ }
+ };
+ }
+ return result;
}
- @Override
- public E floor(E e) {
- return getElementOrNull(multiset().headMultiset(e, CLOSED).lastEntry());
+ @Override public Entry<E> pollFirstEntry() {
+ return forwardMultiset().pollLastEntry();
}
- @Override
- public E ceiling(E e) {
- return getElementOrNull(multiset().tailMultiset(e, CLOSED).firstEntry());
+ @Override public Entry<E> pollLastEntry() {
+ return forwardMultiset().pollFirstEntry();
}
- @Override
- public E higher(E e) {
- return getElementOrNull(multiset().tailMultiset(e, OPEN).firstEntry());
+ @Override public SortedMultiset<E> headMultiset(E toElement,
+ BoundType boundType) {
+ return forwardMultiset().tailMultiset(toElement, boundType)
+ .descendingMultiset();
}
- @Override
- public NavigableSet<E> descendingSet() {
- return new NavigableElementSet<E>(multiset().descendingMultiset());
+ @Override public SortedMultiset<E> subMultiset(E fromElement,
+ BoundType fromBoundType, E toElement, BoundType toBoundType) {
+ return forwardMultiset().subMultiset(toElement, toBoundType, fromElement,
+ fromBoundType).descendingMultiset();
}
- @Override
- public Iterator<E> descendingIterator() {
- return descendingSet().iterator();
+ @Override public SortedMultiset<E> tailMultiset(E fromElement,
+ BoundType boundType) {
+ return forwardMultiset().headMultiset(fromElement, boundType)
+ .descendingMultiset();
}
- @Override
- public E pollFirst() {
- return getElementOrNull(multiset().pollFirstEntry());
+ @Override protected Multiset<E> delegate() {
+ return forwardMultiset();
}
- @Override
- public E pollLast() {
- return getElementOrNull(multiset().pollLastEntry());
+ @Override public SortedMultiset<E> descendingMultiset() {
+ return forwardMultiset();
}
- @Override
- public NavigableSet<E> subSet(
- E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
- return new NavigableElementSet<E>(multiset().subMultiset(
- fromElement, BoundType.forBoolean(fromInclusive),
- toElement, BoundType.forBoolean(toInclusive)));
+ @Override public Entry<E> firstEntry() {
+ return forwardMultiset().lastEntry();
}
- @Override
- public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- return new NavigableElementSet<E>(
- multiset().headMultiset(toElement, BoundType.forBoolean(inclusive)));
+ @Override public Entry<E> lastEntry() {
+ return forwardMultiset().firstEntry();
}
- @Override
- public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- return new NavigableElementSet<E>(
- multiset().tailMultiset(fromElement, BoundType.forBoolean(inclusive)));
+ abstract Iterator<Entry<E>> entryIterator();
+
+ private transient Set<Entry<E>> entrySet;
+
+ @Override public Set<Entry<E>> entrySet() {
+ Set<Entry<E>> result = entrySet;
+ return (result == null) ? entrySet = createEntrySet() : result;
}
- }
- private static <E> E getElementOrThrow(Entry<E> entry) {
- if (entry == null) {
- throw new NoSuchElementException();
+ Set<Entry<E>> createEntrySet() {
+ return new Multisets.EntrySet<E>() {
+ @Override Multiset<E> multiset() {
+ return DescendingMultiset.this;
+ }
+
+ @Override public Iterator<Entry<E>> iterator() {
+ return entryIterator();
+ }
+
+ @Override public int size() {
+ return forwardMultiset().entrySet().size();
+ }
+ };
+ }
+
+ @Override public Iterator<E> iterator() {
+ return Multisets.iteratorImpl(this);
+ }
+
+ @Override public Object[] toArray() {
+ return standardToArray();
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return standardToArray(array);
}
- return entry.getElement();
- }
- private static <E> E getElementOrNull(@Nullable Entry<E> entry) {
- return (entry == null) ? null : entry.getElement();
+ @Override public String toString() {
+ return entrySet().toString();
+ }
}
}
diff --git a/guava/src/com/google/common/collect/SortedSetMultimap.java b/guava/src/com/google/common/collect/SortedSetMultimap.java
index 1b9c641..4785de3 100644
--- a/guava/src/com/google/common/collect/SortedSetMultimap.java
+++ b/guava/src/com/google/common/collect/SortedSetMultimap.java
@@ -31,18 +31,13 @@ import javax.annotation.Nullable;
* that is, they comprise a {@link SortedSet}. It cannot hold duplicate
* key-value pairs; adding a key-value pair that's already in the multimap has
* no effect. This interface does not specify the ordering of the multimap's
- * keys. See the {@link Multimap} documentation for information common to all
- * multimaps.
+ * keys.
*
* <p>The {@link #get}, {@link #removeAll}, and {@link #replaceValues} methods
* each return a {@link SortedSet} of values, while {@link Multimap#entries()}
* returns a {@link Set} of map entries. Though the method signature doesn't say
* so explicitly, the map returned by {@link #asMap} has {@code SortedSet}
* values.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
*
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
diff --git a/guava/src/com/google/common/collect/StandardTable.java b/guava/src/com/google/common/collect/StandardTable.java
index 22c0a90..5edee5b 100644
--- a/guava/src/com/google/common/collect/StandardTable.java
+++ b/guava/src/com/google/common/collect/StandardTable.java
@@ -391,13 +391,17 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
@Override
public V remove(Object key) {
- Map<C, V> backingRowMap = backingRowMap();
- if (backingRowMap == null) {
+ try {
+ Map<C, V> backingRowMap = backingRowMap();
+ if (backingRowMap == null) {
+ return null;
+ }
+ V result = backingRowMap.remove(key);
+ maintainEmptyInvariant();
+ return result;
+ } catch (ClassCastException e) {
return null;
}
- V result = Maps.safeRemove(backingRowMap, key);
- maintainEmptyInvariant();
- return result;
}
@Override
@@ -555,7 +559,7 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
return changed;
}
- class EntrySet extends Sets.ImprovedAbstractSet<Entry<R, V>> {
+ class EntrySet extends AbstractSet<Entry<R, V>> {
@Override public Iterator<Entry<R, V>> iterator() {
return new EntrySetIterator();
}
@@ -595,6 +599,14 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
return false;
}
+ @Override public boolean removeAll(Collection<?> c) {
+ boolean changed = false;
+ for (Object obj : c) {
+ changed |= remove(obj);
+ }
+ return changed;
+ }
+
@Override public boolean retainAll(Collection<?> c) {
return removePredicate(Predicates.not(Predicates.in(c)));
}
@@ -631,9 +643,9 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
return result == null ? keySet = new KeySet() : result;
}
- class KeySet extends Sets.ImprovedAbstractSet<R> {
+ class KeySet extends AbstractSet<R> {
@Override public Iterator<R> iterator() {
- return Maps.keyIterator(Column.this.entrySet().iterator());
+ return keyIteratorImpl(Column.this);
}
@Override public int size() {
@@ -656,6 +668,14 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
entrySet().clear();
}
+ @Override public boolean removeAll(final Collection<?> c) {
+ boolean changed = false;
+ for (Object obj : c) {
+ changed |= remove(obj);
+ }
+ return changed;
+ }
+
@Override public boolean retainAll(final Collection<?> c) {
checkNotNull(c);
Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() {
@@ -670,7 +690,7 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
class Values extends AbstractCollection<V> {
@Override public Iterator<V> iterator() {
- return Maps.valueIterator(Column.this.entrySet().iterator());
+ return valueIteratorImpl(Column.this);
}
@Override public int size() {
@@ -736,7 +756,7 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
class RowKeySet extends TableSet<R> {
@Override public Iterator<R> iterator() {
- return Maps.keyIterator(rowMap().entrySet().iterator());
+ return keyIteratorImpl(rowMap());
}
@Override public int size() {
@@ -890,10 +910,16 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
private class Values extends TableCollection<V> {
@Override public Iterator<V> iterator() {
- return new TransformedIterator<Cell<R, C, V>, V>(cellSet().iterator()) {
- @Override
- V transform(Cell<R, C, V> cell) {
- return cell.getValue();
+ final Iterator<Cell<R, C, V>> cellIterator = cellSet().iterator();
+ return new Iterator<V>() {
+ @Override public boolean hasNext() {
+ return cellIterator.hasNext();
+ }
+ @Override public V next() {
+ return cellIterator.next().getValue();
+ }
+ @Override public void remove() {
+ cellIterator.remove();
}
};
}
@@ -935,13 +961,7 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
class EntrySet extends TableSet<Entry<R, Map<C, V>>> {
@Override public Iterator<Entry<R, Map<C, V>>> iterator() {
- return new TransformedIterator<R, Entry<R, Map<C, V>>>(
- backingMap.keySet().iterator()) {
- @Override
- Entry<R, Map<C, V>> transform(R rowKey) {
- return new ImmutableEntry<R, Map<C, V>>(rowKey, row(rowKey));
- }
- };
+ return new EntryIterator();
}
@Override public int size() {
@@ -968,6 +988,23 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
return false;
}
}
+
+ class EntryIterator implements Iterator<Entry<R, Map<C, V>>> {
+ final Iterator<R> delegate = backingMap.keySet().iterator();
+
+ @Override public boolean hasNext() {
+ return delegate.hasNext();
+ }
+
+ @Override public Entry<R, Map<C, V>> next() {
+ R rowKey = delegate.next();
+ return new ImmutableEntry<R, Map<C, V>>(rowKey, row(rowKey));
+ }
+
+ @Override public void remove() {
+ delegate.remove();
+ }
+ }
}
private transient ColumnMap columnMap;
@@ -1011,10 +1048,13 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
class ColumnMapEntrySet extends TableSet<Entry<C, Map<R, V>>> {
@Override public Iterator<Entry<C, Map<R, V>>> iterator() {
- return new TransformedIterator<C, Entry<C, Map<R, V>>>(
- columnKeySet().iterator()) {
- @Override
- Entry<C, Map<R, V>> transform(C columnKey) {
+ final Iterator<C> columnIterator = columnKeySet().iterator();
+ return new UnmodifiableIterator<Entry<C, Map<R, V>>>() {
+ @Override public boolean hasNext() {
+ return columnIterator.hasNext();
+ }
+ @Override public Entry<C, Map<R, V>> next() {
+ C columnKey = columnIterator.next();
return new ImmutableEntry<C, Map<R, V>>(
columnKey, column(columnKey));
}
@@ -1071,7 +1111,7 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
private class ColumnMapValues extends TableCollection<Map<R, V>> {
@Override public Iterator<Map<R, V>> iterator() {
- return Maps.valueIterator(ColumnMap.this.entrySet().iterator());
+ return valueIteratorImpl(ColumnMap.this);
}
@Override public boolean remove(Object obj) {
@@ -1115,4 +1155,44 @@ class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
}
private static final long serialVersionUID = 0;
+
+ // TODO(kevinb): Move keyIteratorImpl and valueIteratorImpl to Maps, reuse
+
+ /**
+ * Generates the iterator of a map's key set from the map's entry set
+ * iterator.
+ */
+ static <K, V> Iterator<K> keyIteratorImpl(Map<K, V> map) {
+ final Iterator<Entry<K, V>> entryIterator = map.entrySet().iterator();
+ return new Iterator<K>() {
+ @Override public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ @Override public K next() {
+ return entryIterator.next().getKey();
+ }
+ @Override public void remove() {
+ entryIterator.remove();
+ }
+ };
+ }
+
+ /**
+ * Generates the iterator of a map's value collection from the map's entry set
+ * iterator.
+ */
+ static <K, V> Iterator<V> valueIteratorImpl(Map<K, V> map) {
+ final Iterator<Entry<K, V>> entryIterator = map.entrySet().iterator();
+ return new Iterator<V>() {
+ @Override public boolean hasNext() {
+ return entryIterator.hasNext();
+ }
+ @Override public V next() {
+ return entryIterator.next().getValue();
+ }
+ @Override public void remove() {
+ entryIterator.remove();
+ }
+ };
+ }
}
diff --git a/guava/src/com/google/common/collect/Synchronized.java b/guava/src/com/google/common/collect/Synchronized.java
index bbf4c1e..c021c55 100644
--- a/guava/src/com/google/common/collect/Synchronized.java
+++ b/guava/src/com/google/common/collect/Synchronized.java
@@ -31,10 +31,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
-import java.util.Queue;
import java.util.RandomAccess;
import java.util.Set;
import java.util.SortedMap;
@@ -211,7 +207,7 @@ final class Synchronized {
static class SynchronizedSet<E>
extends SynchronizedCollection<E> implements Set<E> {
-
+
SynchronizedSet(Set<E> delegate, @Nullable Object mutex) {
super(delegate, mutex);
}
@@ -851,7 +847,7 @@ final class Synchronized {
}
@Override public Map.Entry<K, Collection<V>> next() {
- final Map.Entry<K, Collection<V>> entry = super.next();
+ final Map.Entry<K, Collection<V>> entry = iterator.next();
return new ForwardingMapEntry<K, Collection<V>>() {
@Override protected Map.Entry<K, Collection<V>> delegate() {
return entry;
@@ -1043,12 +1039,12 @@ final class Synchronized {
private static final long serialVersionUID = 0;
}
-
+
static <K, V> SortedMap<K, V> sortedMap(
SortedMap<K, V> sortedMap, @Nullable Object mutex) {
return new SynchronizedSortedMap<K, V>(sortedMap, mutex);
}
-
+
static class SynchronizedSortedMap<K, V> extends SynchronizedMap<K, V>
implements SortedMap<K, V> {
@@ -1212,410 +1208,11 @@ final class Synchronized {
return iterator;
}
@Override public Collection<V> next() {
- return typePreservingCollection(super.next(), mutex);
+ return typePreservingCollection(iterator.next(), mutex);
}
};
}
private static final long serialVersionUID = 0;
}
-
- @GwtIncompatible("NavigableSet")
- @VisibleForTesting
- static class SynchronizedNavigableSet<E> extends SynchronizedSortedSet<E>
- implements NavigableSet<E> {
- SynchronizedNavigableSet(NavigableSet<E> delegate, @Nullable Object mutex) {
- super(delegate, mutex);
- }
-
- @Override NavigableSet<E> delegate() {
- return (NavigableSet<E>) super.delegate();
- }
-
- @Override public E ceiling(E e) {
- synchronized (mutex) {
- return delegate().ceiling(e);
- }
- }
-
- @Override public Iterator<E> descendingIterator() {
- return delegate().descendingIterator(); // manually synchronized
- }
-
- transient NavigableSet<E> descendingSet;
-
- @Override public NavigableSet<E> descendingSet() {
- synchronized (mutex) {
- if (descendingSet == null) {
- NavigableSet<E> dS =
- Synchronized.navigableSet(delegate().descendingSet(), mutex);
- descendingSet = dS;
- return dS;
- }
- return descendingSet;
- }
- }
-
- @Override public E floor(E e) {
- synchronized (mutex) {
- return delegate().floor(e);
- }
- }
-
- @Override public NavigableSet<E> headSet(E toElement, boolean inclusive) {
- synchronized (mutex) {
- return Synchronized.navigableSet(
- delegate().headSet(toElement, inclusive), mutex);
- }
- }
-
- @Override public E higher(E e) {
- synchronized (mutex) {
- return delegate().higher(e);
- }
- }
-
- @Override public E lower(E e) {
- synchronized (mutex) {
- return delegate().lower(e);
- }
- }
-
- @Override public E pollFirst() {
- synchronized (mutex) {
- return delegate().pollFirst();
- }
- }
-
- @Override public E pollLast() {
- synchronized (mutex) {
- return delegate().pollLast();
- }
- }
-
- @Override public NavigableSet<E> subSet(E fromElement,
- boolean fromInclusive, E toElement, boolean toInclusive) {
- synchronized (mutex) {
- return Synchronized.navigableSet(delegate().subSet(
- fromElement, fromInclusive, toElement, toInclusive), mutex);
- }
- }
-
- @Override public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
- synchronized (mutex) {
- return Synchronized.navigableSet(
- delegate().tailSet(fromElement, inclusive), mutex);
- }
- }
-
- @Override public SortedSet<E> headSet(E toElement) {
- return headSet(toElement, false);
- }
-
- @Override public SortedSet<E> subSet(E fromElement, E toElement) {
- return subSet(fromElement, true, toElement, false);
- }
-
- @Override public SortedSet<E> tailSet(E fromElement) {
- return tailSet(fromElement, true);
- }
-
- private static final long serialVersionUID = 0;
- }
-
- @GwtIncompatible("NavigableSet")
- static <E> NavigableSet<E> navigableSet(
- NavigableSet<E> navigableSet, @Nullable Object mutex) {
- return new SynchronizedNavigableSet<E>(navigableSet, mutex);
- }
-
- @GwtIncompatible("NavigableSet")
- static <E> NavigableSet<E> navigableSet(NavigableSet<E> navigableSet) {
- return navigableSet(navigableSet, null);
- }
-
- @GwtIncompatible("NavigableMap")
- static <K, V> NavigableMap<K, V> navigableMap(
- NavigableMap<K, V> navigableMap) {
- return navigableMap(navigableMap, null);
- }
-
- @GwtIncompatible("NavigableMap")
- static <K, V> NavigableMap<K, V> navigableMap(
- NavigableMap<K, V> navigableMap, @Nullable Object mutex) {
- return new SynchronizedNavigableMap<K, V>(navigableMap, mutex);
- }
-
- @GwtIncompatible("NavigableMap")
- @VisibleForTesting static class SynchronizedNavigableMap<K, V>
- extends SynchronizedSortedMap<K, V> implements NavigableMap<K, V> {
-
- SynchronizedNavigableMap(
- NavigableMap<K, V> delegate, @Nullable Object mutex) {
- super(delegate, mutex);
- }
-
- @Override NavigableMap<K, V> delegate() {
- return (NavigableMap<K, V>) super.delegate();
- }
-
- @Override public Entry<K, V> ceilingEntry(K key) {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().ceilingEntry(key), mutex);
- }
- }
-
- @Override public K ceilingKey(K key) {
- synchronized (mutex) {
- return delegate().ceilingKey(key);
- }
- }
-
- transient NavigableSet<K> descendingKeySet;
-
- @Override public NavigableSet<K> descendingKeySet() {
- synchronized (mutex) {
- if (descendingKeySet == null) {
- return descendingKeySet =
- Synchronized.navigableSet(delegate().descendingKeySet(), mutex);
- }
- return descendingKeySet;
- }
- }
-
- transient NavigableMap<K, V> descendingMap;
-
- @Override public NavigableMap<K, V> descendingMap() {
- synchronized (mutex) {
- if (descendingMap == null) {
- return descendingMap =
- navigableMap(delegate().descendingMap(), mutex);
- }
- return descendingMap;
- }
- }
-
- @Override public Entry<K, V> firstEntry() {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().firstEntry(), mutex);
- }
- }
-
- @Override public Entry<K, V> floorEntry(K key) {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().floorEntry(key), mutex);
- }
- }
-
- @Override public K floorKey(K key) {
- synchronized (mutex) {
- return delegate().floorKey(key);
- }
- }
-
- @Override public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
- synchronized (mutex) {
- return navigableMap(
- delegate().headMap(toKey, inclusive), mutex);
- }
- }
-
- @Override public Entry<K, V> higherEntry(K key) {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().higherEntry(key), mutex);
- }
- }
-
- @Override public K higherKey(K key) {
- synchronized (mutex) {
- return delegate().higherKey(key);
- }
- }
-
- @Override public Entry<K, V> lastEntry() {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().lastEntry(), mutex);
- }
- }
-
- @Override public Entry<K, V> lowerEntry(K key) {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().lowerEntry(key), mutex);
- }
- }
-
- @Override public K lowerKey(K key) {
- synchronized (mutex) {
- return delegate().lowerKey(key);
- }
- }
-
- @Override public Set<K> keySet() {
- return navigableKeySet();
- }
-
- transient NavigableSet<K> navigableKeySet;
-
- @Override public NavigableSet<K> navigableKeySet() {
- synchronized (mutex) {
- if (navigableKeySet == null) {
- return navigableKeySet =
- Synchronized.navigableSet(delegate().navigableKeySet(), mutex);
- }
- return navigableKeySet;
- }
- }
-
- @Override public Entry<K, V> pollFirstEntry() {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().pollFirstEntry(), mutex);
- }
- }
-
- @Override public Entry<K, V> pollLastEntry() {
- synchronized (mutex) {
- return nullableSynchronizedEntry(delegate().pollLastEntry(), mutex);
- }
- }
-
- @Override public NavigableMap<K, V> subMap(
- K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
- synchronized (mutex) {
- return navigableMap(
- delegate().subMap(fromKey, fromInclusive, toKey, toInclusive),
- mutex);
- }
- }
-
- @Override public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
- synchronized (mutex) {
- return navigableMap(
- delegate().tailMap(fromKey, inclusive), mutex);
- }
- }
-
- @Override public SortedMap<K, V> headMap(K toKey) {
- return headMap(toKey, false);
- }
-
- @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
- return subMap(fromKey, true, toKey, false);
- }
-
- @Override public SortedMap<K, V> tailMap(K fromKey) {
- return tailMap(fromKey, true);
- }
-
- private static final long serialVersionUID = 0;
- }
-
- @GwtIncompatible("works but is needed only for NavigableMap")
- private static <K, V> Entry<K, V> nullableSynchronizedEntry(
- @Nullable Entry<K, V> entry, @Nullable Object mutex) {
- if (entry == null) {
- return null;
- }
- return new SynchronizedEntry<K, V>(entry, mutex);
- }
-
- @GwtIncompatible("works but is needed only for NavigableMap")
- private static class SynchronizedEntry<K, V> extends SynchronizedObject
- implements Entry<K, V> {
-
- SynchronizedEntry(Entry<K, V> delegate, @Nullable Object mutex) {
- super(delegate, mutex);
- }
-
- @SuppressWarnings("unchecked") // guaranteed by the constructor
- @Override Entry<K, V> delegate() {
- return (Entry<K, V>) super.delegate();
- }
-
- @Override public boolean equals(Object obj) {
- synchronized (mutex) {
- return delegate().equals(obj);
- }
- }
-
- @Override public int hashCode() {
- synchronized (mutex) {
- return delegate().hashCode();
- }
- }
-
- @Override public K getKey() {
- synchronized (mutex) {
- return delegate().getKey();
- }
- }
-
- @Override public V getValue() {
- synchronized (mutex) {
- return delegate().getValue();
- }
- }
-
- @Override public V setValue(V value) {
- synchronized (mutex) {
- return delegate().setValue(value);
- }
- }
-
- private static final long serialVersionUID = 0;
- }
-
- static <E> Queue<E> queue(Queue<E> queue, @Nullable Object mutex) {
- return (queue instanceof SynchronizedQueue)
- ? queue
- : new SynchronizedQueue<E>(queue, mutex);
- }
-
- private static class SynchronizedQueue<E> extends SynchronizedCollection<E>
- implements Queue<E> {
-
- SynchronizedQueue(Queue<E> delegate, @Nullable Object mutex) {
- super(delegate, mutex);
- }
-
- @Override Queue<E> delegate() {
- return (Queue<E>) super.delegate();
- }
-
- @Override
- public E element() {
- synchronized (mutex) {
- return delegate().element();
- }
- }
-
- @Override
- public boolean offer(E e) {
- synchronized (mutex) {
- return delegate().offer(e);
- }
- }
-
- @Override
- public E peek() {
- synchronized (mutex) {
- return delegate().peek();
- }
- }
-
- @Override
- public E poll() {
- synchronized (mutex) {
- return delegate().poll();
- }
- }
-
- @Override
- public E remove() {
- synchronized (mutex) {
- return delegate().remove();
- }
- }
-
- private static final long serialVersionUID = 0;
- }
}
diff --git a/guava/src/com/google/common/collect/Table.java b/guava/src/com/google/common/collect/Table.java
index c384bf8..f2313be 100644
--- a/guava/src/com/google/common/collect/Table.java
+++ b/guava/src/com/google/common/collect/Table.java
@@ -16,6 +16,7 @@
package com.google.common.collect;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
@@ -43,10 +44,6 @@ import javax.annotation.Nullable;
* <p>All methods that modify the table are optional, and the views returned by
* the table may or may not be modifiable. When modification isn't supported,
* those methods will throw an {@link UnsupportedOperationException}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table">
- * {@code Table}</a>.
*
* @author Jared Levy
* @param <R> the type of the table row keys
@@ -55,6 +52,7 @@ import javax.annotation.Nullable;
* @since 7.0
*/
@GwtCompatible
+@Beta
public interface Table<R, C, V> {
// TODO(jlevy): Consider adding methods similar to ConcurrentMap methods.
@@ -261,6 +259,7 @@ public interface Table<R, C, V> {
*
* @since 7.0
*/
+ @Beta
interface Cell<R, C, V> {
/**
* Returns the row key of this cell.
diff --git a/guava/src/com/google/common/collect/Tables.java b/guava/src/com/google/common/collect/Tables.java
index 028aba3..a9c69b9 100644
--- a/guava/src/com/google/common/collect/Tables.java
+++ b/guava/src/com/google/common/collect/Tables.java
@@ -39,16 +39,13 @@ import javax.annotation.Nullable;
/**
* Provides static methods that involve a {@code Table}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Tables">
- * {@code Tables}</a>.
*
* @author Jared Levy
* @author Louis Wasserman
* @since 7.0
*/
@GwtCompatible
+@Beta
public final class Tables {
private Tables() {}
@@ -364,7 +361,6 @@ public final class Tables {
* @throws IllegalArgumentException if {@code backingMap} is not empty
* @since 10.0
*/
- @Beta
public static <R, C, V> Table<R, C, V> newCustomTable(
Map<R, Map<C, V>> backingMap, Supplier<? extends Map<C, V>> factory) {
checkArgument(backingMap.isEmpty());
@@ -399,7 +395,6 @@ public final class Tables {
*
* @since 10.0
*/
- @Beta
public static <R, C, V1, V2> Table<R, C, V2> transformValues(
Table<R, C, V1> fromTable, Function<? super V1, V2> function) {
return new TransformedTable<R, C, V1, V2>(fromTable, function);
@@ -701,7 +696,6 @@ public final class Tables {
* @return an unmodifiable view of the specified table
* @since 11.0
*/
- @Beta
public static <R, C, V> RowSortedTable<R, C, V> unmodifiableRowSortedTable(
RowSortedTable<R, ? extends C, ? extends V> table) {
/*
diff --git a/guava/src/com/google/common/collect/TransformedImmutableList.java b/guava/src/com/google/common/collect/TransformedImmutableList.java
new file mode 100644
index 0000000..d9e8588
--- /dev/null
+++ b/guava/src/com/google/common/collect/TransformedImmutableList.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.annotations.GwtCompatible;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+/**
+ * A transforming wrapper around an ImmutableList. For internal use only. {@link
+ * #transform(Object)} must be functional.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+@SuppressWarnings("serial") // uses writeReplace(), not default serialization
+abstract class TransformedImmutableList<D, E> extends ImmutableList<E> {
+ private class TransformedView extends TransformedImmutableList<D, E> {
+ TransformedView(ImmutableList<D> backingList) {
+ super(backingList);
+ }
+
+ @Override E transform(D d) {
+ return TransformedImmutableList.this.transform(d);
+ }
+ }
+
+ private transient final ImmutableList<D> backingList;
+
+ TransformedImmutableList(ImmutableList<D> backingList) {
+ this.backingList = checkNotNull(backingList);
+ }
+
+ abstract E transform(D d);
+
+ @Override public int indexOf(@Nullable Object object) {
+ if (object == null) {
+ return -1;
+ }
+ for (int i = 0; i < size(); i++) {
+ if (get(i).equals(object)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override public int lastIndexOf(@Nullable Object object) {
+ if (object == null) {
+ return -1;
+ }
+ for (int i = size() - 1; i >= 0; i--) {
+ if (get(i).equals(object)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override public E get(int index) {
+ return transform(backingList.get(index));
+ }
+
+ @Override public UnmodifiableListIterator<E> listIterator(int index) {
+ return new AbstractIndexedListIterator<E>(size(), index) {
+ @Override protected E get(int index) {
+ return TransformedImmutableList.this.get(index);
+ }
+ };
+ }
+
+ @Override public int size() {
+ return backingList.size();
+ }
+
+ @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
+ return new TransformedView(backingList.subList(fromIndex, toIndex));
+ }
+
+ @Override public boolean equals(@Nullable Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof List) {
+ List<?> list = (List<?>) obj;
+ return size() == list.size()
+ && Iterators.elementsEqual(iterator(), list.iterator());
+ }
+ return false;
+ }
+
+ @Override public int hashCode() {
+ int hashCode = 1;
+ for (E e : this) {
+ hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
+ }
+ return hashCode;
+ }
+
+ @Override public Object[] toArray() {
+ return ObjectArrays.toArrayImpl(this);
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return ObjectArrays.toArrayImpl(this, array);
+ }
+
+ @Override boolean isPartialView() {
+ return true;
+ }
+}
diff --git a/guava/src/com/google/common/collect/TransformedIterator.java b/guava/src/com/google/common/collect/TransformedIterator.java
deleted file mode 100644
index c082d7d..0000000
--- a/guava/src/com/google/common/collect/TransformedIterator.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.GwtCompatible;
-
-import java.util.Iterator;
-
-/**
- * An iterator that transforms a backing iterator; for internal use. This avoids
- * the object overhead of constructing a {@link Function} for internal methods.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-abstract class TransformedIterator<F, T> implements Iterator<T> {
- final Iterator<? extends F> backingIterator;
-
- TransformedIterator(Iterator<? extends F> backingIterator) {
- this.backingIterator = checkNotNull(backingIterator);
- }
-
- abstract T transform(F from);
-
- @Override
- public final boolean hasNext() {
- return backingIterator.hasNext();
- }
-
- @Override
- public final T next() {
- return transform(backingIterator.next());
- }
-
- @Override
- public final void remove() {
- backingIterator.remove();
- }
-}
diff --git a/guava/src/com/google/common/collect/TransformedListIterator.java b/guava/src/com/google/common/collect/TransformedListIterator.java
deleted file mode 100644
index c743030..0000000
--- a/guava/src/com/google/common/collect/TransformedListIterator.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
-
-import java.util.ListIterator;
-
-/**
- * An iterator that transforms a backing list iterator; for internal use. This
- * avoids the object overhead of constructing a {@link Function} for internal
- * methods.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-abstract class TransformedListIterator<F, T> extends TransformedIterator<F, T>
- implements ListIterator<T> {
- TransformedListIterator(ListIterator<? extends F> backingIterator) {
- super(backingIterator);
- }
-
- private ListIterator<? extends F> backingIterator() {
- return Iterators.cast(backingIterator);
- }
-
- @Override
- public final boolean hasPrevious() {
- return backingIterator().hasPrevious();
- }
-
- @Override
- public final T previous() {
- return transform(backingIterator().previous());
- }
-
- @Override
- public final int nextIndex() {
- return backingIterator().nextIndex();
- }
-
- @Override
- public final int previousIndex() {
- return backingIterator().previousIndex();
- }
-
- @Override
- public void set(T element) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(T element) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/guava/src/com/google/common/collect/TreeBasedTable.java b/guava/src/com/google/common/collect/TreeBasedTable.java
index 2ead64e..d996c27 100644
--- a/guava/src/com/google/common/collect/TreeBasedTable.java
+++ b/guava/src/com/google/common/collect/TreeBasedTable.java
@@ -66,10 +66,6 @@ import javax.annotation.Nullable;
* access this table concurrently and one of the threads modifies the table, it
* must be synchronized externally.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Table">
- * {@code Table}</a>.
- *
* @author Jared Levy
* @author Louis Wasserman
* @since 7.0
diff --git a/guava/src/com/google/common/collect/TreeMultimap.java b/guava/src/com/google/common/collect/TreeMultimap.java
index 433774d..efd11be 100644
--- a/guava/src/com/google/common/collect/TreeMultimap.java
+++ b/guava/src/com/google/common/collect/TreeMultimap.java
@@ -26,14 +26,11 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.Comparator;
-import java.util.NavigableMap;
-import java.util.NavigableSet;
+import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
-import javax.annotation.Nullable;
-
/**
* Implementation of {@code Multimap} whose keys and values are ordered by
* their natural ordering or by supplied comparators. In all cases, this
@@ -67,16 +64,11 @@ import javax.annotation.Nullable;
* update operations, wrap your multimap with a call to {@link
* Multimaps#synchronizedSortedSetMultimap}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
- * {@code Multimap}</a>.
- *
* @author Jared Levy
- * @author Louis Wasserman
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(serializable = true, emulated = true)
-public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V> {
+public class TreeMultimap<K, V> extends AbstractSortedSetMultimap<K, V> {
private transient Comparator<? super K> keyComparator;
private transient Comparator<? super V> valueComparator;
@@ -142,14 +134,6 @@ public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V>
return new TreeSet<V>(valueComparator);
}
- @Override
- Collection<V> createCollection(@Nullable K key) {
- if (key == null) {
- keyComparator().compare(key, key);
- }
- return super.createCollection(key);
- }
-
/**
* Returns the comparator that orders the multimap keys.
*/
@@ -162,79 +146,26 @@ public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V>
return valueComparator;
}
- /*
- * The following @GwtIncompatible methods override the methods in
- * AbstractSortedKeySortedSetMultimap, so GWT will fall back to the ASKSSM implementations,
- * which return SortedSets and SortedMaps.
- */
-
- @Override
- @GwtIncompatible("NavigableMap")
- NavigableMap<K, Collection<V>> backingMap() {
- return (NavigableMap<K, Collection<V>>) super.backingMap();
- }
-
- /**
- * @since 14.0 (present with return type {@code SortedSet} since 2.0)
- */
- @Override
- @GwtIncompatible("NavigableSet")
- public NavigableSet<V> get(@Nullable K key) {
- return (NavigableSet<V>) super.get(key);
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- Collection<V> unmodifiableCollectionSubclass(Collection<V> collection) {
- return Sets.unmodifiableNavigableSet((NavigableSet<V>) collection);
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- Collection<V> wrapCollection(K key, Collection<V> collection) {
- return new WrappedNavigableSet(key, (NavigableSet<V>) collection, null);
- }
-
/**
* {@inheritDoc}
*
* <p>Because a {@code TreeMultimap} has unique sorted keys, this method
- * returns a {@link NavigableSet}, instead of the {@link java.util.Set} specified
+ * returns a {@link SortedSet}, instead of the {@link java.util.Set} specified
* in the {@link Multimap} interface.
- *
- * @since 14.0 (present with return type {@code SortedSet} since 2.0)
*/
- @Override
- @GwtIncompatible("NavigableSet")
- public NavigableSet<K> keySet() {
- return (NavigableSet<K>) super.keySet();
- }
-
- @Override
- @GwtIncompatible("NavigableSet")
- NavigableSet<K> createKeySet() {
- return new NavigableKeySet(backingMap());
+ @Override public SortedSet<K> keySet() {
+ return (SortedSet<K>) super.keySet();
}
/**
* {@inheritDoc}
*
* <p>Because a {@code TreeMultimap} has unique sorted keys, this method
- * returns a {@link NavigableMap}, instead of the {@link java.util.Map} specified
+ * returns a {@link SortedMap}, instead of the {@link java.util.Map} specified
* in the {@link Multimap} interface.
- *
- * @since 14.0 (present with return type {@code SortedMap} since 2.0)
*/
- @Override
- @GwtIncompatible("NavigableMap")
- public NavigableMap<K, Collection<V>> asMap() {
- return (NavigableMap<K, Collection<V>>) super.asMap();
- }
-
- @Override
- @GwtIncompatible("NavigableMap")
- NavigableMap<K, Collection<V>> createAsMap() {
- return new NavigableAsMap(backingMap());
+ @Override public SortedMap<K, Collection<V>> asMap() {
+ return (SortedMap<K, Collection<V>>) super.asMap();
}
/**
diff --git a/guava/src/com/google/common/collect/TreeMultiset.java b/guava/src/com/google/common/collect/TreeMultiset.java
index 6876cd0..d44a4bb 100644
--- a/guava/src/com/google/common/collect/TreeMultiset.java
+++ b/guava/src/com/google/common/collect/TreeMultiset.java
@@ -17,12 +17,10 @@
package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Objects;
-import com.google.common.primitives.Ints;
+import static com.google.common.collect.BstSide.LEFT;
+import static com.google.common.collect.BstSide.RIGHT;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -31,207 +29,160 @@ import java.io.Serializable;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
-import java.util.NoSuchElementException;
import javax.annotation.Nullable;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.primitives.Ints;
+
/**
- * A multiset which maintains the ordering of its elements, according to either their natural order
- * or an explicit {@link Comparator}. In all cases, this implementation uses
- * {@link Comparable#compareTo} or {@link Comparator#compare} instead of {@link Object#equals} to
- * determine equivalence of instances.
+ * A multiset which maintains the ordering of its elements, according to either
+ * their natural order or an explicit {@link Comparator}. In all cases, this
+ * implementation uses {@link Comparable#compareTo} or {@link
+ * Comparator#compare} instead of {@link Object#equals} to determine
+ * equivalence of instances.
*
- * <p><b>Warning:</b> The comparison must be <i>consistent with equals</i> as explained by the
- * {@link Comparable} class specification. Otherwise, the resulting multiset will violate the
- * {@link java.util.Collection} contract, which is specified in terms of {@link Object#equals}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multiset">
- * {@code Multiset}</a>.
+ * <p><b>Warning:</b> The comparison must be <i>consistent with equals</i> as
+ * explained by the {@link Comparable} class specification. Otherwise, the
+ * resulting multiset will violate the {@link java.util.Collection} contract,
+ * which is specified in terms of {@link Object#equals}.
*
* @author Louis Wasserman
* @author Jared Levy
* @since 2.0 (imported from Google Collections Library)
*/
@GwtCompatible(emulated = true)
-public final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements Serializable {
+public final class TreeMultiset<E> extends AbstractSortedMultiset<E>
+ implements Serializable {
/**
- * Creates a new, empty multiset, sorted according to the elements' natural order. All elements
- * inserted into the multiset must implement the {@code Comparable} interface. Furthermore, all
- * such elements must be <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
- * {@code ClassCastException} for any elements {@code e1} and {@code e2} in the multiset. If the
- * user attempts to add an element to the multiset that violates this constraint (for example,
- * the user attempts to add a string element to a set whose elements are integers), the
- * {@code add(Object)} call will throw a {@code ClassCastException}.
+ * Creates a new, empty multiset, sorted according to the elements' natural
+ * order. All elements inserted into the multiset must implement the
+ * {@code Comparable} interface. Furthermore, all such elements must be
+ * <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
+ * {@code ClassCastException} for any elements {@code e1} and {@code e2} in
+ * the multiset. If the user attempts to add an element to the multiset that
+ * violates this constraint (for example, the user attempts to add a string
+ * element to a set whose elements are integers), the {@code add(Object)}
+ * call will throw a {@code ClassCastException}.
*
- * <p>The type specification is {@code <E extends Comparable>}, instead of the more specific
- * {@code <E extends Comparable<? super E>>}, to support classes defined without generics.
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
*/
public static <E extends Comparable> TreeMultiset<E> create() {
return new TreeMultiset<E>(Ordering.natural());
}
/**
- * Creates a new, empty multiset, sorted according to the specified comparator. All elements
- * inserted into the multiset must be <i>mutually comparable</i> by the specified comparator:
- * {@code comparator.compare(e1,
- * e2)} must not throw a {@code ClassCastException} for any elements {@code e1} and {@code e2} in
- * the multiset. If the user attempts to add an element to the multiset that violates this
- * constraint, the {@code add(Object)} call will throw a {@code ClassCastException}.
+ * Creates a new, empty multiset, sorted according to the specified
+ * comparator. All elements inserted into the multiset must be <i>mutually
+ * comparable</i> by the specified comparator: {@code comparator.compare(e1,
+ * e2)} must not throw a {@code ClassCastException} for any elements {@code
+ * e1} and {@code e2} in the multiset. If the user attempts to add an element
+ * to the multiset that violates this constraint, the {@code add(Object)} call
+ * will throw a {@code ClassCastException}.
*
- * @param comparator
- * the comparator that will be used to sort this multiset. A null value indicates that
- * the elements' <i>natural ordering</i> should be used.
+ * @param comparator the comparator that will be used to sort this multiset. A
+ * null value indicates that the elements' <i>natural ordering</i> should
+ * be used.
*/
@SuppressWarnings("unchecked")
- public static <E> TreeMultiset<E> create(@Nullable Comparator<? super E> comparator) {
+ public static <E> TreeMultiset<E> create(
+ @Nullable Comparator<? super E> comparator) {
return (comparator == null)
- ? new TreeMultiset<E>((Comparator) Ordering.natural())
- : new TreeMultiset<E>(comparator);
+ ? new TreeMultiset<E>((Comparator) Ordering.natural())
+ : new TreeMultiset<E>(comparator);
}
/**
- * Creates an empty multiset containing the given initial elements, sorted according to the
- * elements' natural order.
+ * Creates an empty multiset containing the given initial elements, sorted
+ * according to the elements' natural order.
*
- * <p>This implementation is highly efficient when {@code elements} is itself a {@link Multiset}.
+ * <p>This implementation is highly efficient when {@code elements} is itself
+ * a {@link Multiset}.
*
- * <p>The type specification is {@code <E extends Comparable>}, instead of the more specific
- * {@code <E extends Comparable<? super E>>}, to support classes defined without generics.
+ * <p>The type specification is {@code <E extends Comparable>}, instead of the
+ * more specific {@code <E extends Comparable<? super E>>}, to support
+ * classes defined without generics.
*/
- public static <E extends Comparable> TreeMultiset<E> create(Iterable<? extends E> elements) {
+ public static <E extends Comparable> TreeMultiset<E> create(
+ Iterable<? extends E> elements) {
TreeMultiset<E> multiset = create();
Iterables.addAll(multiset, elements);
return multiset;
}
- private final transient Reference<AvlNode<E>> rootReference;
- private final transient GeneralRange<E> range;
- private final transient AvlNode<E> header;
-
- TreeMultiset(Reference<AvlNode<E>> rootReference, GeneralRange<E> range, AvlNode<E> endLink) {
- super(range.comparator());
- this.rootReference = rootReference;
- this.range = range;
- this.header = endLink;
+ /**
+ * Returns an iterator over the elements contained in this collection.
+ */
+ @Override
+ public Iterator<E> iterator() {
+ // Needed to avoid Javadoc bug.
+ return super.iterator();
}
- TreeMultiset(Comparator<? super E> comparator) {
+ private TreeMultiset(Comparator<? super E> comparator) {
super(comparator);
this.range = GeneralRange.all(comparator);
- this.header = new AvlNode<E>(null, 1);
- successor(header, header);
- this.rootReference = new Reference<AvlNode<E>>();
+ this.rootReference = new Reference<Node<E>>();
}
- /**
- * A function which can be summed across a subtree.
- */
- private enum Aggregate {
- SIZE {
- @Override
- int nodeAggregate(AvlNode<?> node) {
- return node.elemCount;
- }
+ private TreeMultiset(GeneralRange<E> range, Reference<Node<E>> root) {
+ super(range.comparator());
+ this.range = range;
+ this.rootReference = root;
+ }
- @Override
- long treeAggregate(@Nullable AvlNode<?> root) {
- return (root == null) ? 0 : root.totalCount;
- }
- },
- DISTINCT {
- @Override
- int nodeAggregate(AvlNode<?> node) {
- return 1;
- }
+ @SuppressWarnings("unchecked")
+ E checkElement(Object o) {
+ return (E) o;
+ }
- @Override
- long treeAggregate(@Nullable AvlNode<?> root) {
- return (root == null) ? 0 : root.distinctElements;
- }
- };
- abstract int nodeAggregate(AvlNode<?> node);
+ private transient final GeneralRange<E> range;
- abstract long treeAggregate(@Nullable AvlNode<?> root);
- }
+ private transient final Reference<Node<E>> rootReference;
- private long aggregateForEntries(Aggregate aggr) {
- AvlNode<E> root = rootReference.get();
- long total = aggr.treeAggregate(root);
- if (range.hasLowerBound()) {
- total -= aggregateBelowRange(aggr, root);
- }
- if (range.hasUpperBound()) {
- total -= aggregateAboveRange(aggr, root);
- }
- return total;
- }
+ static final class Reference<T> {
+ T value;
- private long aggregateBelowRange(Aggregate aggr, @Nullable AvlNode<E> node) {
- if (node == null) {
- return 0;
- }
- int cmp = comparator().compare(range.getLowerEndpoint(), node.elem);
- if (cmp < 0) {
- return aggregateBelowRange(aggr, node.left);
- } else if (cmp == 0) {
- switch (range.getLowerBoundType()) {
- case OPEN:
- return aggr.nodeAggregate(node) + aggr.treeAggregate(node.left);
- case CLOSED:
- return aggr.treeAggregate(node.left);
- default:
- throw new AssertionError();
- }
- } else {
- return aggr.treeAggregate(node.left) + aggr.nodeAggregate(node)
- + aggregateBelowRange(aggr, node.right);
- }
- }
+ public Reference() {}
- private long aggregateAboveRange(Aggregate aggr, @Nullable AvlNode<E> node) {
- if (node == null) {
- return 0;
+ public T get() {
+ return value;
}
- int cmp = comparator().compare(range.getUpperEndpoint(), node.elem);
- if (cmp > 0) {
- return aggregateAboveRange(aggr, node.right);
- } else if (cmp == 0) {
- switch (range.getUpperBoundType()) {
- case OPEN:
- return aggr.nodeAggregate(node) + aggr.treeAggregate(node.right);
- case CLOSED:
- return aggr.treeAggregate(node.right);
- default:
- throw new AssertionError();
+
+ public boolean compareAndSet(T expected, T newValue) {
+ if (value == expected) {
+ value = newValue;
+ return true;
}
- } else {
- return aggr.treeAggregate(node.right) + aggr.nodeAggregate(node)
- + aggregateAboveRange(aggr, node.left);
+ return false;
}
}
@Override
- public int size() {
- return Ints.saturatedCast(aggregateForEntries(Aggregate.SIZE));
+ int distinctElements() {
+ Node<E> root = rootReference.get();
+ return Ints.checkedCast(BstRangeOps.totalInRange(distinctAggregate(), range, root));
}
@Override
- int distinctElements() {
- return Ints.saturatedCast(aggregateForEntries(Aggregate.DISTINCT));
+ public int size() {
+ Node<E> root = rootReference.get();
+ return Ints.saturatedCast(BstRangeOps.totalInRange(sizeAggregate(), range, root));
}
@Override
public int count(@Nullable Object element) {
try {
- @SuppressWarnings("unchecked")
- E e = (E) element;
- AvlNode<E> root = rootReference.get();
- if (!range.contains(e) || root == null) {
- return 0;
+ E e = checkElement(element);
+ if (range.contains(e)) {
+ Node<E> node = BstOperations.seek(comparator(), rootReference.get(), e);
+ return countOrZero(node);
}
- return root.count(comparator(), e);
+ return 0;
} catch (ClassCastException e) {
return 0;
} catch (NullPointerException e) {
@@ -239,718 +190,360 @@ public final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements
}
}
+ private int mutate(@Nullable E e, MultisetModifier modifier) {
+ BstMutationRule<E, Node<E>> mutationRule = BstMutationRule.createRule(
+ modifier,
+ BstCountBasedBalancePolicies.
+ <E, Node<E>>singleRebalancePolicy(distinctAggregate()),
+ nodeFactory());
+ BstMutationResult<E, Node<E>> mutationResult =
+ BstOperations.mutate(comparator(), mutationRule, rootReference.get(), e);
+ if (!rootReference.compareAndSet(
+ mutationResult.getOriginalRoot(), mutationResult.getChangedRoot())) {
+ throw new ConcurrentModificationException();
+ }
+ Node<E> original = mutationResult.getOriginalTarget();
+ return countOrZero(original);
+ }
+
@Override
- public int add(@Nullable E element, int occurrences) {
- checkArgument(occurrences >= 0, "occurrences must be >= 0 but was %s", occurrences);
+ public int add(E element, int occurrences) {
+ checkElement(element);
if (occurrences == 0) {
return count(element);
}
checkArgument(range.contains(element));
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- comparator().compare(element, element);
- AvlNode<E> newRoot = new AvlNode<E>(element, occurrences);
- successor(header, newRoot, header);
- rootReference.checkAndSet(root, newRoot);
- return 0;
- }
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot = root.add(comparator(), element, occurrences, result);
- rootReference.checkAndSet(root, newRoot);
- return result[0];
+ return mutate(element, new AddModifier(occurrences));
}
@Override
public int remove(@Nullable Object element, int occurrences) {
- checkArgument(occurrences >= 0, "occurrences must be >= 0 but was %s", occurrences);
- if (occurrences == 0) {
+ if (element == null) {
+ return 0;
+ } else if (occurrences == 0) {
return count(element);
}
- AvlNode<E> root = rootReference.get();
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot;
try {
- @SuppressWarnings("unchecked")
- E e = (E) element;
- if (!range.contains(e) || root == null) {
- return 0;
- }
- newRoot = root.remove(comparator(), e, occurrences, result);
+ E e = checkElement(element);
+ return range.contains(e) ? mutate(e, new RemoveModifier(occurrences)) : 0;
} catch (ClassCastException e) {
return 0;
- } catch (NullPointerException e) {
- return 0;
}
- rootReference.checkAndSet(root, newRoot);
- return result[0];
}
@Override
- public int setCount(@Nullable E element, int count) {
- checkArgument(count >= 0);
- if (!range.contains(element)) {
- checkArgument(count == 0);
- return 0;
- }
-
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- if (count > 0) {
- add(element, count);
- }
- return 0;
- }
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot = root.setCount(comparator(), element, count, result);
- rootReference.checkAndSet(root, newRoot);
- return result[0];
+ public boolean setCount(E element, int oldCount, int newCount) {
+ checkElement(element);
+ checkArgument(range.contains(element));
+ return mutate(element, new ConditionalSetCountModifier(oldCount, newCount))
+ == oldCount;
}
@Override
- public boolean setCount(@Nullable E element, int oldCount, int newCount) {
- checkArgument(newCount >= 0);
- checkArgument(oldCount >= 0);
+ public int setCount(E element, int count) {
+ checkElement(element);
checkArgument(range.contains(element));
-
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- if (oldCount == 0) {
- if (newCount > 0) {
- add(element, newCount);
- }
- return true;
- } else {
- return false;
- }
- }
- int[] result = new int[1]; // used as a mutable int reference to hold result
- AvlNode<E> newRoot = root.setCount(comparator(), element, oldCount, newCount, result);
- rootReference.checkAndSet(root, newRoot);
- return result[0] == oldCount;
+ return mutate(element, new SetCountModifier(count));
}
- private Entry<E> wrapEntry(final AvlNode<E> baseEntry) {
- return new Multisets.AbstractEntry<E>() {
- @Override
- public E getElement() {
- return baseEntry.getElement();
- }
-
- @Override
- public int getCount() {
- int result = baseEntry.getCount();
- if (result == 0) {
- return count(getElement());
- } else {
- return result;
- }
- }
- };
+ private BstPathFactory<Node<E>, BstInOrderPath<Node<E>>> pathFactory() {
+ return BstInOrderPath.inOrderFactory();
}
- /**
- * Returns the first node in the tree that is in range.
- */
- @Nullable private AvlNode<E> firstNode() {
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- return null;
- }
- AvlNode<E> node;
- if (range.hasLowerBound()) {
- E endpoint = range.getLowerEndpoint();
- node = rootReference.get().ceiling(comparator(), endpoint);
- if (node == null) {
- return null;
- }
- if (range.getLowerBoundType() == BoundType.OPEN
- && comparator().compare(endpoint, node.getElement()) == 0) {
- node = node.succ;
- }
- } else {
- node = header.succ;
- }
- return (node == header || !range.contains(node.getElement())) ? null : node;
+ @Override
+ Iterator<Entry<E>> entryIterator() {
+ Node<E> root = rootReference.get();
+ final BstInOrderPath<Node<E>> startingPath =
+ BstRangeOps.furthestPath(range, LEFT, pathFactory(), root);
+ return iteratorInDirection(startingPath, RIGHT);
}
- @Nullable private AvlNode<E> lastNode() {
- AvlNode<E> root = rootReference.get();
- if (root == null) {
- return null;
- }
- AvlNode<E> node;
- if (range.hasUpperBound()) {
- E endpoint = range.getUpperEndpoint();
- node = rootReference.get().floor(comparator(), endpoint);
- if (node == null) {
- return null;
- }
- if (range.getUpperBoundType() == BoundType.OPEN
- && comparator().compare(endpoint, node.getElement()) == 0) {
- node = node.pred;
- }
- } else {
- node = header.pred;
- }
- return (node == header || !range.contains(node.getElement())) ? null : node;
+ @Override
+ Iterator<Entry<E>> descendingEntryIterator() {
+ Node<E> root = rootReference.get();
+ final BstInOrderPath<Node<E>> startingPath =
+ BstRangeOps.furthestPath(range, RIGHT, pathFactory(), root);
+ return iteratorInDirection(startingPath, LEFT);
}
- @Override
- Iterator<Entry<E>> entryIterator() {
+ private Iterator<Entry<E>> iteratorInDirection(
+ @Nullable BstInOrderPath<Node<E>> start, final BstSide direction) {
+ final Iterator<BstInOrderPath<Node<E>>> pathIterator =
+ new AbstractLinkedIterator<BstInOrderPath<Node<E>>>(start) {
+ @Override
+ protected BstInOrderPath<Node<E>> computeNext(BstInOrderPath<Node<E>> previous) {
+ if (!previous.hasNext(direction)) {
+ return null;
+ }
+ BstInOrderPath<Node<E>> next = previous.next(direction);
+ // TODO(user): only check against one side
+ return range.contains(next.getTip().getKey()) ? next : null;
+ }
+ };
return new Iterator<Entry<E>>() {
- AvlNode<E> current = firstNode();
- Entry<E> prevEntry;
+ E toRemove = null;
@Override
public boolean hasNext() {
- if (current == null) {
- return false;
- } else if (range.tooHigh(current.getElement())) {
- current = null;
- return false;
- } else {
- return true;
- }
+ return pathIterator.hasNext();
}
@Override
public Entry<E> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- Entry<E> result = wrapEntry(current);
- prevEntry = result;
- if (current.succ == header) {
- current = null;
- } else {
- current = current.succ;
- }
- return result;
+ BstInOrderPath<Node<E>> path = pathIterator.next();
+ return new LiveEntry(
+ toRemove = path.getTip().getKey(), path.getTip().elemCount());
}
@Override
public void remove() {
- checkState(prevEntry != null);
- setCount(prevEntry.getElement(), 0);
- prevEntry = null;
+ checkState(toRemove != null);
+ setCount(toRemove, 0);
+ toRemove = null;
}
};
}
- @Override
- Iterator<Entry<E>> descendingEntryIterator() {
- return new Iterator<Entry<E>>() {
- AvlNode<E> current = lastNode();
- Entry<E> prevEntry = null;
+ class LiveEntry extends Multisets.AbstractEntry<E> {
+ private Node<E> expectedRoot;
+ private final E element;
+ private int count;
- @Override
- public boolean hasNext() {
- if (current == null) {
- return false;
- } else if (range.tooLow(current.getElement())) {
- current = null;
- return false;
- } else {
- return true;
- }
- }
+ private LiveEntry(E element, int count) {
+ this.expectedRoot = rootReference.get();
+ this.element = element;
+ this.count = count;
+ }
- @Override
- public Entry<E> next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- Entry<E> result = wrapEntry(current);
- prevEntry = result;
- if (current.pred == header) {
- current = null;
- } else {
- current = current.pred;
- }
- return result;
- }
+ @Override
+ public E getElement() {
+ return element;
+ }
- @Override
- public void remove() {
- checkState(prevEntry != null);
- setCount(prevEntry.getElement(), 0);
- prevEntry = null;
+ @Override
+ public int getCount() {
+ if (rootReference.get() == expectedRoot) {
+ return count;
+ } else {
+ // check for updates
+ expectedRoot = rootReference.get();
+ return count = TreeMultiset.this.count(element);
}
- };
+ }
}
@Override
- public SortedMultiset<E> headMultiset(@Nullable E upperBound, BoundType boundType) {
- return new TreeMultiset<E>(rootReference, range.intersect(GeneralRange.upTo(
- comparator(),
- upperBound,
- boundType)), header);
+ public void clear() {
+ Node<E> root = rootReference.get();
+ Node<E> cleared = BstRangeOps.minusRange(range,
+ BstCountBasedBalancePolicies.<E, Node<E>>fullRebalancePolicy(distinctAggregate()),
+ nodeFactory(), root);
+ if (!rootReference.compareAndSet(root, cleared)) {
+ throw new ConcurrentModificationException();
+ }
}
@Override
- public SortedMultiset<E> tailMultiset(@Nullable E lowerBound, BoundType boundType) {
- return new TreeMultiset<E>(rootReference, range.intersect(GeneralRange.downTo(
- comparator(),
- lowerBound,
- boundType)), header);
+ public SortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
+ checkNotNull(upperBound);
+ return new TreeMultiset<E>(
+ range.intersect(GeneralRange.upTo(comparator, upperBound, boundType)), rootReference);
}
- static int distinctElements(@Nullable AvlNode<?> node) {
- return (node == null) ? 0 : node.distinctElements;
+ @Override
+ public SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
+ checkNotNull(lowerBound);
+ return new TreeMultiset<E>(
+ range.intersect(GeneralRange.downTo(comparator, lowerBound, boundType)), rootReference);
}
- private static final class Reference<T> {
- @Nullable private T value;
-
- @Nullable public T get() {
- return value;
- }
-
- public void checkAndSet(@Nullable T expected, T newValue) {
- if (value != expected) {
- throw new ConcurrentModificationException();
- }
- value = newValue;
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @since 11.0
+ */
+ @Override
+ public Comparator<? super E> comparator() {
+ return super.comparator();
}
- private static final class AvlNode<E> extends Multisets.AbstractEntry<E> {
- @Nullable private final E elem;
-
- // elemCount is 0 iff this node has been deleted.
- private int elemCount;
+ private static final class Node<E> extends BstNode<E, Node<E>> implements Serializable {
+ private final long size;
+ private final int distinct;
- private int distinctElements;
- private long totalCount;
- private int height;
- private AvlNode<E> left;
- private AvlNode<E> right;
- private AvlNode<E> pred;
- private AvlNode<E> succ;
-
- AvlNode(@Nullable E elem, int elemCount) {
+ private Node(E key, int elemCount, @Nullable Node<E> left,
+ @Nullable Node<E> right) {
+ super(key, left, right);
checkArgument(elemCount > 0);
- this.elem = elem;
- this.elemCount = elemCount;
- this.totalCount = elemCount;
- this.distinctElements = 1;
- this.height = 1;
- this.left = null;
- this.right = null;
- }
-
- public int count(Comparator<? super E> comparator, E e) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- return (left == null) ? 0 : left.count(comparator, e);
- } else if (cmp > 0) {
- return (right == null) ? 0 : right.count(comparator, e);
- } else {
- return elemCount;
- }
+ this.size = (long) elemCount + sizeOrZero(left) + sizeOrZero(right);
+ this.distinct = 1 + distinctOrZero(left) + distinctOrZero(right);
}
- private AvlNode<E> addRightChild(E e, int count) {
- right = new AvlNode<E>(e, count);
- successor(this, right, succ);
- height = Math.max(2, height);
- distinctElements++;
- totalCount += count;
- return this;
+ int elemCount() {
+ long result = size - sizeOrZero(childOrNull(LEFT))
+ - sizeOrZero(childOrNull(RIGHT));
+ return Ints.checkedCast(result);
}
- private AvlNode<E> addLeftChild(E e, int count) {
- left = new AvlNode<E>(e, count);
- successor(pred, left, this);
- height = Math.max(2, height);
- distinctElements++;
- totalCount += count;
- return this;
- }
-
- AvlNode<E> add(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
- /*
- * It speeds things up considerably to unconditionally add count to totalCount here,
- * but that destroys failure atomicity in the case of count overflow. =(
- */
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- return addLeftChild(e, count);
- }
- int initHeight = initLeft.height;
-
- left = initLeft.add(comparator, e, count, result);
- if (result[0] == 0) {
- distinctElements++;
- }
- this.totalCount += count;
- return (left.height == initHeight) ? this : rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- return addRightChild(e, count);
- }
- int initHeight = initRight.height;
-
- right = initRight.add(comparator, e, count, result);
- if (result[0] == 0) {
- distinctElements++;
- }
- this.totalCount += count;
- return (right.height == initHeight) ? this : rebalance();
- }
-
- // adding count to me! No rebalance possible.
- result[0] = elemCount;
- long resultCount = (long) elemCount + count;
- checkArgument(resultCount <= Integer.MAX_VALUE);
- this.elemCount += count;
- this.totalCount += count;
- return this;
+ private Node(E key, int elemCount) {
+ this(key, elemCount, null, null);
}
- AvlNode<E> remove(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- return this;
- }
+ private static final long serialVersionUID = 0;
+ }
- left = initLeft.remove(comparator, e, count, result);
+ private static long sizeOrZero(@Nullable Node<?> node) {
+ return (node == null) ? 0 : node.size;
+ }
- if (result[0] > 0) {
- if (count >= result[0]) {
- this.distinctElements--;
- this.totalCount -= result[0];
- } else {
- this.totalCount -= count;
- }
- }
- return (result[0] == 0) ? this : rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- return this;
- }
+ private static int distinctOrZero(@Nullable Node<?> node) {
+ return (node == null) ? 0 : node.distinct;
+ }
- right = initRight.remove(comparator, e, count, result);
+ private static int countOrZero(@Nullable Node<?> entry) {
+ return (entry == null) ? 0 : entry.elemCount();
+ }
- if (result[0] > 0) {
- if (count >= result[0]) {
- this.distinctElements--;
- this.totalCount -= result[0];
- } else {
- this.totalCount -= count;
- }
- }
- return rebalance();
- }
+ @SuppressWarnings("unchecked")
+ private BstAggregate<Node<E>> distinctAggregate() {
+ return (BstAggregate) DISTINCT_AGGREGATE;
+ }
- // removing count from me!
- result[0] = elemCount;
- if (count >= elemCount) {
- return deleteMe();
- } else {
- this.elemCount -= count;
- this.totalCount -= count;
- return this;
- }
+ private static final BstAggregate<Node<Object>> DISTINCT_AGGREGATE =
+ new BstAggregate<Node<Object>>() {
+ @Override
+ public int entryValue(Node<Object> entry) {
+ return 1;
}
- AvlNode<E> setCount(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- return (count > 0) ? addLeftChild(e, count) : this;
- }
-
- left = initLeft.setCount(comparator, e, count, result);
-
- if (count == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (count > 0 && result[0] == 0) {
- this.distinctElements++;
- }
-
- this.totalCount += count - result[0];
- return rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- return (count > 0) ? addRightChild(e, count) : this;
- }
-
- right = initRight.setCount(comparator, e, count, result);
-
- if (count == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (count > 0 && result[0] == 0) {
- this.distinctElements++;
- }
-
- this.totalCount += count - result[0];
- return rebalance();
- }
-
- // setting my count
- result[0] = elemCount;
- if (count == 0) {
- return deleteMe();
- }
- this.totalCount += count - elemCount;
- this.elemCount = count;
- return this;
+ @Override
+ public long treeValue(@Nullable Node<Object> tree) {
+ return distinctOrZero(tree);
}
+ };
- AvlNode<E> setCount(
- Comparator<? super E> comparator,
- @Nullable E e,
- int expectedCount,
- int newCount,
- int[] result) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- AvlNode<E> initLeft = left;
- if (initLeft == null) {
- result[0] = 0;
- if (expectedCount == 0 && newCount > 0) {
- return addLeftChild(e, newCount);
- }
- return this;
- }
-
- left = initLeft.setCount(comparator, e, expectedCount, newCount, result);
+ @SuppressWarnings("unchecked")
+ private BstAggregate<Node<E>> sizeAggregate() {
+ return (BstAggregate) SIZE_AGGREGATE;
+ }
- if (result[0] == expectedCount) {
- if (newCount == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (newCount > 0 && result[0] == 0) {
- this.distinctElements++;
- }
- this.totalCount += newCount - result[0];
- }
- return rebalance();
- } else if (cmp > 0) {
- AvlNode<E> initRight = right;
- if (initRight == null) {
- result[0] = 0;
- if (expectedCount == 0 && newCount > 0) {
- return addRightChild(e, newCount);
- }
- return this;
+ private static final BstAggregate<Node<Object>> SIZE_AGGREGATE =
+ new BstAggregate<Node<Object>>() {
+ @Override
+ public int entryValue(Node<Object> entry) {
+ return entry.elemCount();
}
- right = initRight.setCount(comparator, e, expectedCount, newCount, result);
-
- if (result[0] == expectedCount) {
- if (newCount == 0 && result[0] != 0) {
- this.distinctElements--;
- } else if (newCount > 0 && result[0] == 0) {
- this.distinctElements++;
- }
- this.totalCount += newCount - result[0];
+ @Override
+ public long treeValue(@Nullable Node<Object> tree) {
+ return sizeOrZero(tree);
}
- return rebalance();
- }
+ };
- // setting my count
- result[0] = elemCount;
- if (expectedCount == elemCount) {
- if (newCount == 0) {
- return deleteMe();
- }
- this.totalCount += newCount - elemCount;
- this.elemCount = newCount;
- }
- return this;
- }
+ @SuppressWarnings("unchecked")
+ private BstNodeFactory<Node<E>> nodeFactory() {
+ return (BstNodeFactory) NODE_FACTORY;
+ }
- private AvlNode<E> deleteMe() {
- int oldElemCount = this.elemCount;
- this.elemCount = 0;
- successor(pred, succ);
- if (left == null) {
- return right;
- } else if (right == null) {
- return left;
- } else if (left.height >= right.height) {
- AvlNode<E> newTop = pred;
- // newTop is the maximum node in my left subtree
- newTop.left = left.removeMax(newTop);
- newTop.right = right;
- newTop.distinctElements = distinctElements - 1;
- newTop.totalCount = totalCount - oldElemCount;
- return newTop.rebalance();
- } else {
- AvlNode<E> newTop = succ;
- newTop.right = right.removeMin(newTop);
- newTop.left = left;
- newTop.distinctElements = distinctElements - 1;
- newTop.totalCount = totalCount - oldElemCount;
- return newTop.rebalance();
- }
- }
+ private static final BstNodeFactory<Node<Object>> NODE_FACTORY =
+ new BstNodeFactory<Node<Object>>() {
+ @Override
+ public Node<Object> createNode(Node<Object> source, @Nullable Node<Object> left,
+ @Nullable Node<Object> right) {
+ return new Node<Object>(source.getKey(), source.elemCount(), left, right);
+ }
+ };
- // Removes the minimum node from this subtree to be reused elsewhere
- private AvlNode<E> removeMin(AvlNode<E> node) {
- if (left == null) {
- return right;
- } else {
- left = left.removeMin(node);
- distinctElements--;
- totalCount -= node.elemCount;
- return rebalance();
- }
- }
+ private abstract class MultisetModifier implements BstModifier<E, Node<E>> {
+ abstract int newCount(int oldCount);
- // Removes the maximum node from this subtree to be reused elsewhere
- private AvlNode<E> removeMax(AvlNode<E> node) {
- if (right == null) {
- return left;
+ @Nullable
+ @Override
+ public BstModificationResult<Node<E>> modify(E key, @Nullable Node<E> originalEntry) {
+ int oldCount = countOrZero(originalEntry);
+ int newCount = newCount(oldCount);
+ if (oldCount == newCount) {
+ return BstModificationResult.identity(originalEntry);
+ } else if (newCount == 0) {
+ return BstModificationResult.rebalancingChange(originalEntry, null);
+ } else if (oldCount == 0) {
+ return BstModificationResult.rebalancingChange(null, new Node<E>(key, newCount));
} else {
- right = right.removeMax(node);
- distinctElements--;
- totalCount -= node.elemCount;
- return rebalance();
+ return BstModificationResult.rebuildingChange(originalEntry,
+ new Node<E>(originalEntry.getKey(), newCount));
}
}
+ }
- private void recomputeMultiset() {
- this.distinctElements = 1 + TreeMultiset.distinctElements(left)
- + TreeMultiset.distinctElements(right);
- this.totalCount = elemCount + totalCount(left) + totalCount(right);
- }
-
- private void recomputeHeight() {
- this.height = 1 + Math.max(height(left), height(right));
- }
+ private final class AddModifier extends MultisetModifier {
+ private final int countToAdd;
- private void recompute() {
- recomputeMultiset();
- recomputeHeight();
+ private AddModifier(int countToAdd) {
+ checkArgument(countToAdd > 0);
+ this.countToAdd = countToAdd;
}
- private AvlNode<E> rebalance() {
- switch (balanceFactor()) {
- case -2:
- if (right.balanceFactor() > 0) {
- right = right.rotateRight();
- }
- return rotateLeft();
- case 2:
- if (left.balanceFactor() < 0) {
- left = left.rotateLeft();
- }
- return rotateRight();
- default:
- recomputeHeight();
- return this;
- }
+ @Override
+ int newCount(int oldCount) {
+ checkArgument(countToAdd <= Integer.MAX_VALUE - oldCount, "Cannot add this many elements");
+ return oldCount + countToAdd;
}
+ }
- private int balanceFactor() {
- return height(left) - height(right);
- }
+ private final class RemoveModifier extends MultisetModifier {
+ private final int countToRemove;
- private AvlNode<E> rotateLeft() {
- checkState(right != null);
- AvlNode<E> newTop = right;
- this.right = newTop.left;
- newTop.left = this;
- newTop.totalCount = this.totalCount;
- newTop.distinctElements = this.distinctElements;
- this.recompute();
- newTop.recomputeHeight();
- return newTop;
+ private RemoveModifier(int countToRemove) {
+ checkArgument(countToRemove > 0);
+ this.countToRemove = countToRemove;
}
- private AvlNode<E> rotateRight() {
- checkState(left != null);
- AvlNode<E> newTop = left;
- this.left = newTop.right;
- newTop.right = this;
- newTop.totalCount = this.totalCount;
- newTop.distinctElements = this.distinctElements;
- this.recompute();
- newTop.recomputeHeight();
- return newTop;
+ @Override
+ int newCount(int oldCount) {
+ return Math.max(0, oldCount - countToRemove);
}
+ }
- private static long totalCount(@Nullable AvlNode<?> node) {
- return (node == null) ? 0 : node.totalCount;
- }
+ private final class SetCountModifier extends MultisetModifier {
+ private final int countToSet;
- private static int height(@Nullable AvlNode<?> node) {
- return (node == null) ? 0 : node.height;
- }
-
- @Nullable private AvlNode<E> ceiling(Comparator<? super E> comparator, E e) {
- int cmp = comparator.compare(e, elem);
- if (cmp < 0) {
- return (left == null) ? this : Objects.firstNonNull(left.ceiling(comparator, e), this);
- } else if (cmp == 0) {
- return this;
- } else {
- return (right == null) ? null : right.ceiling(comparator, e);
- }
- }
-
- @Nullable private AvlNode<E> floor(Comparator<? super E> comparator, E e) {
- int cmp = comparator.compare(e, elem);
- if (cmp > 0) {
- return (right == null) ? this : Objects.firstNonNull(right.floor(comparator, e), this);
- } else if (cmp == 0) {
- return this;
- } else {
- return (left == null) ? null : left.floor(comparator, e);
- }
+ private SetCountModifier(int countToSet) {
+ checkArgument(countToSet >= 0);
+ this.countToSet = countToSet;
}
@Override
- public E getElement() {
- return elem;
+ int newCount(int oldCount) {
+ return countToSet;
}
+ }
- @Override
- public int getCount() {
- return elemCount;
+ private final class ConditionalSetCountModifier extends MultisetModifier {
+ private final int expectedCount;
+ private final int setCount;
+
+ private ConditionalSetCountModifier(int expectedCount, int setCount) {
+ checkArgument(setCount >= 0 & expectedCount >= 0);
+ this.expectedCount = expectedCount;
+ this.setCount = setCount;
}
@Override
- public String toString() {
- return Multisets.immutableEntry(getElement(), getCount()).toString();
+ int newCount(int oldCount) {
+ return (oldCount == expectedCount) ? setCount : oldCount;
}
}
- private static <T> void successor(AvlNode<T> a, AvlNode<T> b) {
- a.succ = b;
- b.pred = a;
- }
-
- private static <T> void successor(AvlNode<T> a, AvlNode<T> b, AvlNode<T> c) {
- successor(a, b);
- successor(b, c);
- }
-
/*
- * TODO(jlevy): Decide whether entrySet() should return entries with an equals() method that
- * calls the comparator to compare the two keys. If that change is made,
- * AbstractMultiset.equals() can simply check whether two multisets have equal entry sets.
+ * TODO(jlevy): Decide whether entrySet() should return entries with an
+ * equals() method that calls the comparator to compare the two keys. If that
+ * change is made, AbstractMultiset.equals() can simply check whether two
+ * multisets have equal entry sets.
*/
/**
- * @serialData the comparator, the number of distinct elements, the first element, its count, the
- * second element, its count, and so on
+ * @serialData the comparator, the number of distinct elements, the first
+ * element, its count, the second element, its count, and so on
*/
@GwtIncompatible("java.io.ObjectOutputStream")
private void writeObject(ObjectOutputStream stream) throws IOException {
@@ -960,23 +553,19 @@ public final class TreeMultiset<E> extends AbstractSortedMultiset<E> implements
}
@GwtIncompatible("java.io.ObjectInputStream")
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- @SuppressWarnings("unchecked")
- // reading data stored by writeObject
+ @SuppressWarnings("unchecked") // reading data stored by writeObject
Comparator<? super E> comparator = (Comparator<? super E>) stream.readObject();
Serialization.getFieldSetter(AbstractSortedMultiset.class, "comparator").set(this, comparator);
- Serialization.getFieldSetter(TreeMultiset.class, "range").set(
- this,
+ Serialization.getFieldSetter(TreeMultiset.class, "range").set(this,
GeneralRange.all(comparator));
- Serialization.getFieldSetter(TreeMultiset.class, "rootReference").set(
- this,
- new Reference<AvlNode<E>>());
- AvlNode<E> header = new AvlNode<E>(null, 1);
- Serialization.getFieldSetter(TreeMultiset.class, "header").set(this, header);
- successor(header, header);
+ Serialization.getFieldSetter(TreeMultiset.class, "rootReference").set(this,
+ new Reference<Node<E>>());
Serialization.populateMultiset(this, stream);
}
- @GwtIncompatible("not needed in emulated source") private static final long serialVersionUID = 1;
+ @GwtIncompatible("not needed in emulated source")
+ private static final long serialVersionUID = 1;
}
diff --git a/guava/src/com/google/common/collect/TreeRangeMap.java b/guava/src/com/google/common/collect/TreeRangeMap.java
deleted file mode 100644
index e5b5f47..0000000
--- a/guava/src/com/google/common/collect/TreeRangeMap.java
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Predicates.compose;
-import static com.google.common.base.Predicates.in;
-import static com.google.common.base.Predicates.not;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-
-import java.util.AbstractMap;
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * An implementation of {@code RangeMap} based on a {@code TreeMap}, supporting
- * all optional operations.
- *
- * <p>Like all {@code RangeMap} implementations, this supports neither null
- * keys nor null values.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-@GwtIncompatible("NavigableMap")
-public final class TreeRangeMap<K extends Comparable, V> implements RangeMap<K, V> {
-
- private final NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound;
-
- public static <K extends Comparable, V> TreeRangeMap<K, V> create() {
- return new TreeRangeMap<K, V>();
- }
-
- private TreeRangeMap() {
- this.entriesByLowerBound = Maps.newTreeMap();
- }
-
- private static final class RangeMapEntry<K extends Comparable, V>
- extends AbstractMapEntry<Range<K>, V> {
- private final Range<K> range;
- private final V value;
-
- RangeMapEntry(Cut<K> lowerBound, Cut<K> upperBound, V value) {
- this(Range.create(lowerBound, upperBound), value);
- }
-
- RangeMapEntry(Range<K> range, V value) {
- this.range = range;
- this.value = value;
- }
-
- @Override
- public Range<K> getKey() {
- return range;
- }
-
- @Override
- public V getValue() {
- return value;
- }
-
- public boolean contains(K value) {
- return range.contains(value);
- }
-
- Cut<K> getLowerBound() {
- return range.lowerBound;
- }
-
- Cut<K> getUpperBound() {
- return range.upperBound;
- }
- }
-
- @Override
- @Nullable
- public V get(K key) {
- Entry<Range<K>, V> entry = getEntry(key);
- return (entry == null) ? null : entry.getValue();
- }
-
- @Override
- @Nullable
- public Entry<Range<K>, V> getEntry(K key) {
- Map.Entry<Cut<K>, RangeMapEntry<K, V>> mapEntry =
- entriesByLowerBound.floorEntry(Cut.belowValue(key));
- if (mapEntry != null && mapEntry.getValue().contains(key)) {
- return mapEntry.getValue();
- } else {
- return null;
- }
- }
-
- @Override
- public void put(Range<K> range, V value) {
- if (!range.isEmpty()) {
- checkNotNull(value);
- remove(range);
- entriesByLowerBound.put(range.lowerBound, new RangeMapEntry<K, V>(range, value));
- }
- }
-
- @Override
- public void putAll(RangeMap<K, V> rangeMap) {
- for (Map.Entry<Range<K>, V> entry : rangeMap.asMapOfRanges().entrySet()) {
- put(entry.getKey(), entry.getValue());
- }
- }
-
- @Override
- public void clear() {
- entriesByLowerBound.clear();
- }
-
- @Override
- public Range<K> span() {
- Entry<Cut<K>, RangeMapEntry<K, V>> firstEntry = entriesByLowerBound.firstEntry();
- Entry<Cut<K>, RangeMapEntry<K, V>> lastEntry = entriesByLowerBound.lastEntry();
- if (firstEntry == null) {
- throw new NoSuchElementException();
- }
- return Range.create(
- firstEntry.getValue().getKey().lowerBound,
- lastEntry.getValue().getKey().upperBound);
- }
-
- private void putRangeMapEntry(Cut<K> lowerBound, Cut<K> upperBound, V value) {
- entriesByLowerBound.put(lowerBound, new RangeMapEntry<K, V>(lowerBound, upperBound, value));
- }
-
- @Override
- public void remove(Range<K> rangeToRemove) {
- if (rangeToRemove.isEmpty()) {
- return;
- }
-
- /*
- * The comments for this method will use [ ] to indicate the bounds of rangeToRemove and ( ) to
- * indicate the bounds of ranges in the range map.
- */
- Map.Entry<Cut<K>, RangeMapEntry<K, V>> mapEntryBelowToTruncate =
- entriesByLowerBound.lowerEntry(rangeToRemove.lowerBound);
- if (mapEntryBelowToTruncate != null) {
- // we know ( [
- RangeMapEntry<K, V> rangeMapEntry = mapEntryBelowToTruncate.getValue();
- if (rangeMapEntry.getUpperBound().compareTo(rangeToRemove.lowerBound) > 0) {
- // we know ( [ )
- if (rangeMapEntry.getUpperBound().compareTo(rangeToRemove.upperBound) > 0) {
- // we know ( [ ] ), so insert the range ] ) back into the map --
- // it's being split apart
- putRangeMapEntry(rangeToRemove.upperBound, rangeMapEntry.getUpperBound(),
- mapEntryBelowToTruncate.getValue().getValue());
- }
- // overwrite mapEntryToTruncateBelow with a truncated range
- putRangeMapEntry(rangeMapEntry.getLowerBound(), rangeToRemove.lowerBound,
- mapEntryBelowToTruncate.getValue().getValue());
- }
- }
-
- Map.Entry<Cut<K>, RangeMapEntry<K, V>> mapEntryAboveToTruncate =
- entriesByLowerBound.lowerEntry(rangeToRemove.upperBound);
- if (mapEntryAboveToTruncate != null) {
- // we know ( ]
- RangeMapEntry<K, V> rangeMapEntry = mapEntryAboveToTruncate.getValue();
- if (rangeMapEntry.getUpperBound().compareTo(rangeToRemove.upperBound) > 0) {
- // we know ( ] ), and since we dealt with truncating below already,
- // we know [ ( ] )
- putRangeMapEntry(rangeToRemove.upperBound, rangeMapEntry.getUpperBound(),
- mapEntryAboveToTruncate.getValue().getValue());
- entriesByLowerBound.remove(rangeToRemove.lowerBound);
- }
- }
- entriesByLowerBound.subMap(rangeToRemove.lowerBound, rangeToRemove.upperBound).clear();
- }
-
- @Override
- public Map<Range<K>, V> asMapOfRanges() {
- return new AsMapOfRanges();
- }
-
- private final class AsMapOfRanges extends AbstractMap<Range<K>, V> {
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return get(key) != null;
- }
-
- @Override
- public V get(@Nullable Object key) {
- if (key instanceof Range) {
- Range<?> range = (Range<?>) key;
- RangeMapEntry<K, V> rangeMapEntry = entriesByLowerBound.get(range.lowerBound);
- if (rangeMapEntry != null && rangeMapEntry.getKey().equals(range)) {
- return rangeMapEntry.getValue();
- }
- }
- return null;
- }
-
- @Override
- public Set<Entry<Range<K>, V>> entrySet() {
- return new AbstractSet<Entry<Range<K>, V>>() {
-
- @SuppressWarnings("unchecked") // it's safe to upcast iterators
- @Override
- public Iterator<Entry<Range<K>, V>> iterator() {
- return (Iterator) entriesByLowerBound.values().iterator();
- }
-
- @Override
- public int size() {
- return entriesByLowerBound.size();
- }
- };
- }
- }
-
- @Override
- public RangeMap<K, V> subRangeMap(Range<K> subRange) {
- if (subRange.equals(Range.all())) {
- return this;
- } else {
- return new SubRangeMap(subRange);
- }
- }
-
- @SuppressWarnings("unchecked")
- private RangeMap<K, V> emptySubRangeMap() {
- return EMPTY_SUB_RANGE_MAP;
- }
-
- private static final RangeMap EMPTY_SUB_RANGE_MAP =
- new RangeMap() {
- @Override
- @Nullable
- public Object get(Comparable key) {
- return null;
- }
-
- @Override
- @Nullable
- public Entry<Range, Object> getEntry(Comparable key) {
- return null;
- }
-
- @Override
- public Range span() {
- throw new NoSuchElementException();
- }
-
- @Override
- public void put(Range range, Object value) {
- checkNotNull(range);
- throw new IllegalArgumentException(
- "Cannot insert range " + range + " into an empty subRangeMap");
- }
-
- @Override
- public void putAll(RangeMap rangeMap) {
- if (!rangeMap.asMapOfRanges().isEmpty()) {
- throw new IllegalArgumentException(
- "Cannot putAll(nonEmptyRangeMap) into an empty " + "subRangeMap");
- }
- }
-
- @Override
- public void clear() {}
-
- @Override
- public void remove(Range range) {
- checkNotNull(range);
- }
-
- @Override
- public Map<Range, Object> asMapOfRanges() {
- return Collections.emptyMap();
- }
-
- @Override
- public RangeMap subRangeMap(Range range) {
- checkNotNull(range);
- return this;
- }
- };
-
- private class SubRangeMap implements RangeMap<K, V> {
-
- private final Range<K> subRange;
-
- SubRangeMap(Range<K> subRange) {
- this.subRange = subRange;
- }
-
- @Override
- @Nullable
- public V get(K key) {
- return subRange.contains(key)
- ? TreeRangeMap.this.get(key)
- : null;
- }
-
- @Override
- @Nullable
- public Entry<Range<K>, V> getEntry(K key) {
- if (subRange.contains(key)) {
- Entry<Range<K>, V> entry = TreeRangeMap.this.getEntry(key);
- if (entry != null) {
- return Maps.immutableEntry(entry.getKey().intersection(subRange), entry.getValue());
- }
- }
- return null;
- }
-
- @Override
- public Range<K> span() {
- Cut<K> lowerBound;
- Entry<Cut<K>, RangeMapEntry<K, V>> lowerEntry =
- entriesByLowerBound.floorEntry(subRange.lowerBound);
- if (lowerEntry != null &&
- lowerEntry.getValue().getUpperBound().compareTo(subRange.lowerBound) > 0) {
- lowerBound = subRange.lowerBound;
- } else {
- lowerBound = entriesByLowerBound.ceilingKey(subRange.lowerBound);
- if (lowerBound == null || lowerBound.compareTo(subRange.upperBound) >= 0) {
- throw new NoSuchElementException();
- }
- }
-
- Cut<K> upperBound;
- Entry<Cut<K>, RangeMapEntry<K, V>> upperEntry =
- entriesByLowerBound.lowerEntry(subRange.upperBound);
- if (upperEntry == null) {
- throw new NoSuchElementException();
- } else if (upperEntry.getValue().getUpperBound().compareTo(subRange.upperBound) >= 0) {
- upperBound = subRange.upperBound;
- } else {
- upperBound = upperEntry.getValue().getUpperBound();
- }
- return Range.create(lowerBound, upperBound);
- }
-
- @Override
- public void put(Range<K> range, V value) {
- checkArgument(subRange.encloses(range),
- "Cannot put range %s into a subRangeMap(%s)", range, subRange);
- TreeRangeMap.this.put(range, value);
- }
-
- @Override
- public void putAll(RangeMap<K, V> rangeMap) {
- if (rangeMap.asMapOfRanges().isEmpty()) {
- return;
- }
- Range<K> span = rangeMap.span();
- checkArgument(subRange.encloses(span),
- "Cannot putAll rangeMap with span %s into a subRangeMap(%s)", span, subRange);
- TreeRangeMap.this.putAll(rangeMap);
- }
-
- @Override
- public void clear() {
- TreeRangeMap.this.remove(subRange);
- }
-
- @Override
- public void remove(Range<K> range) {
- if (range.isConnected(subRange)) {
- TreeRangeMap.this.remove(range.intersection(subRange));
- }
- }
-
- @Override
- public RangeMap<K, V> subRangeMap(Range<K> range) {
- if (!range.isConnected(subRange)) {
- return emptySubRangeMap();
- } else {
- return TreeRangeMap.this.subRangeMap(range.intersection(subRange));
- }
- }
-
- @Override
- public Map<Range<K>, V> asMapOfRanges() {
- return new SubRangeMapAsMap();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (o instanceof RangeMap) {
- RangeMap<?, ?> rangeMap = (RangeMap<?, ?>) o;
- return asMapOfRanges().equals(rangeMap.asMapOfRanges());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return asMapOfRanges().hashCode();
- }
-
- @Override
- public String toString() {
- return asMapOfRanges().toString();
- }
-
- class SubRangeMapAsMap extends AbstractMap<Range<K>, V> {
-
- @Override
- public boolean containsKey(Object key) {
- return get(key) != null;
- }
-
- @Override
- public V get(Object key) {
- try {
- if (key instanceof Range) {
- @SuppressWarnings("unchecked") // we catch ClassCastExceptions
- Range<K> r = (Range<K>) key;
- if (!subRange.encloses(r) || r.isEmpty()) {
- return null;
- }
- RangeMapEntry<K, V> candidate = null;
- if (r.lowerBound.compareTo(subRange.lowerBound) == 0) {
- // r could be truncated on the left
- Entry<Cut<K>, RangeMapEntry<K, V>> entry =
- entriesByLowerBound.floorEntry(r.lowerBound);
- if (entry != null) {
- candidate = entry.getValue();
- }
- } else {
- candidate = entriesByLowerBound.get(r.lowerBound);
- }
-
- if (candidate != null && candidate.getKey().isConnected(subRange)
- && candidate.getKey().intersection(subRange).equals(r)) {
- return candidate.getValue();
- }
- }
- } catch (ClassCastException e) {
- return null;
- }
- return null;
- }
-
- @Override
- public V remove(Object key) {
- V value = get(key);
- if (value != null) {
- @SuppressWarnings("unchecked") // it's definitely in the map, so safe
- Range<K> range = (Range<K>) key;
- TreeRangeMap.this.remove(range);
- return value;
- }
- return null;
- }
-
- @Override
- public void clear() {
- SubRangeMap.this.clear();
- }
-
- private boolean removeIf(Predicate<? super Entry<Range<K>, V>> predicate) {
- List<Range<K>> toRemove = Lists.newArrayList();
- for (Entry<Range<K>, V> entry : entrySet()) {
- if (predicate.apply(entry)) {
- toRemove.add(entry.getKey());
- }
- }
- for (Range<K> range : toRemove) {
- TreeRangeMap.this.remove(range);
- }
- return !toRemove.isEmpty();
- }
-
- @Override
- public Set<Range<K>> keySet() {
- return new Maps.KeySet<Range<K>, V>() {
- @Override
- Map<Range<K>, V> map() {
- return SubRangeMapAsMap.this;
- }
-
- @Override
- public boolean remove(@Nullable Object o) {
- return SubRangeMapAsMap.this.remove(o) != null;
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(compose(not(in(c)), Maps.<Range<K>>keyFunction()));
- }
- };
- }
-
- @Override
- public Set<Entry<Range<K>, V>> entrySet() {
- return new Maps.EntrySet<Range<K>, V>() {
- @Override
- Map<Range<K>, V> map() {
- return SubRangeMapAsMap.this;
- }
-
- @Override
- public Iterator<Entry<Range<K>, V>> iterator() {
- if (subRange.isEmpty()) {
- return Iterators.emptyIterator();
- }
- Cut<K> cutToStart = Objects.firstNonNull(
- entriesByLowerBound.floorKey(subRange.lowerBound),
- subRange.lowerBound);
- final Iterator<RangeMapEntry<K, V>> backingItr =
- entriesByLowerBound.tailMap(cutToStart, true).values().iterator();
- return new AbstractIterator<Entry<Range<K>, V>>() {
-
- @Override
- protected Entry<Range<K>, V> computeNext() {
- while (backingItr.hasNext()) {
- RangeMapEntry<K, V> entry = backingItr.next();
- if (entry.getLowerBound().compareTo(subRange.upperBound) >= 0) {
- break;
- } else if (entry.getUpperBound().compareTo(subRange.lowerBound) > 0) {
- // this might not be true e.g. at the start of the iteration
- return Maps.immutableEntry(
- entry.getKey().intersection(subRange), entry.getValue());
- }
- }
- return endOfData();
- }
- };
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(not(in(c)));
- }
-
- @Override
- public int size() {
- return Iterators.size(iterator());
- }
-
- @Override
- public boolean isEmpty() {
- return !iterator().hasNext();
- }
- };
- }
-
- @Override
- public Collection<V> values() {
- return new Maps.Values<Range<K>, V>() {
- @Override
- Map<Range<K>, V> map() {
- return SubRangeMapAsMap.this;
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- return removeIf(compose(in(c), Maps.<V>valueFunction()));
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- return removeIf(compose(not(in(c)), Maps.<V>valueFunction()));
- }
- };
- }
- }
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (o instanceof RangeMap) {
- RangeMap<?, ?> rangeMap = (RangeMap<?, ?>) o;
- return asMapOfRanges().equals(rangeMap.asMapOfRanges());
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return asMapOfRanges().hashCode();
- }
-
- @Override
- public String toString() {
- return entriesByLowerBound.values().toString();
- }
-}
diff --git a/guava/src/com/google/common/collect/TreeRangeSet.java b/guava/src/com/google/common/collect/TreeRangeSet.java
deleted file mode 100644
index d67c5f4..0000000
--- a/guava/src/com/google/common/collect/TreeRangeSet.java
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Map.Entry;
-import java.util.NavigableMap;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.TreeMap;
-
-import javax.annotation.Nullable;
-
-/**
- * An implementation of {@link RangeSet} backed by a {@link TreeMap}.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-@GwtIncompatible("uses NavigableMap")
-public class TreeRangeSet<C extends Comparable<?>>
- extends AbstractRangeSet<C> {
-
- @VisibleForTesting
- final NavigableMap<Cut<C>, Range<C>> rangesByLowerBound;
-
- /**
- * Creates an empty {@code TreeRangeSet} instance.
- */
- public static <C extends Comparable<?>> TreeRangeSet<C> create() {
- return new TreeRangeSet<C>(new TreeMap<Cut<C>, Range<C>>());
- }
-
- /**
- * Returns a {@code TreeRangeSet} initialized with the ranges in the specified range set.
- */
- public static <C extends Comparable<?>> TreeRangeSet<C> create(RangeSet<C> rangeSet) {
- TreeRangeSet<C> result = create();
- result.addAll(rangeSet);
- return result;
- }
-
- private TreeRangeSet(NavigableMap<Cut<C>, Range<C>> rangesByLowerCut) {
- this.rangesByLowerBound = rangesByLowerCut;
- }
-
- private transient Set<Range<C>> asRanges;
-
- @Override
- public Set<Range<C>> asRanges() {
- Set<Range<C>> result = asRanges;
- return (result == null) ? asRanges = new AsRanges() : result;
- }
-
- final class AsRanges extends ForwardingCollection<Range<C>> implements Set<Range<C>> {
- @Override
- protected Collection<Range<C>> delegate() {
- return rangesByLowerBound.values();
- }
-
- @Override
- public int hashCode() {
- return Sets.hashCodeImpl(this);
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- return Sets.equalsImpl(this, o);
- }
- }
-
- @Override
- @Nullable
- public Range<C> rangeContaining(C value) {
- checkNotNull(value);
- Entry<Cut<C>, Range<C>> floorEntry = rangesByLowerBound.floorEntry(Cut.belowValue(value));
- if (floorEntry != null && floorEntry.getValue().contains(value)) {
- return floorEntry.getValue();
- } else {
- // TODO(kevinb): revisit this design choice
- return null;
- }
- }
-
- @Override
- public boolean encloses(Range<C> range) {
- checkNotNull(range);
- Entry<Cut<C>, Range<C>> floorEntry = rangesByLowerBound.floorEntry(range.lowerBound);
- return floorEntry != null && floorEntry.getValue().encloses(range);
- }
-
- @Nullable
- private Range<C> rangeEnclosing(Range<C> range) {
- checkNotNull(range);
- Entry<Cut<C>, Range<C>> floorEntry = rangesByLowerBound.floorEntry(range.lowerBound);
- return (floorEntry != null && floorEntry.getValue().encloses(range))
- ? floorEntry.getValue()
- : null;
- }
-
- @Override
- public Range<C> span() {
- Entry<Cut<C>, Range<C>> firstEntry = rangesByLowerBound.firstEntry();
- Entry<Cut<C>, Range<C>> lastEntry = rangesByLowerBound.lastEntry();
- if (firstEntry == null) {
- throw new NoSuchElementException();
- }
- return Range.create(firstEntry.getValue().lowerBound, lastEntry.getValue().upperBound);
- }
-
- @Override
- public void add(Range<C> rangeToAdd) {
- checkNotNull(rangeToAdd);
-
- if (rangeToAdd.isEmpty()) {
- return;
- }
-
- // We will use { } to illustrate ranges currently in the range set, and < >
- // to illustrate rangeToAdd.
- Cut<C> lbToAdd = rangeToAdd.lowerBound;
- Cut<C> ubToAdd = rangeToAdd.upperBound;
-
- Entry<Cut<C>, Range<C>> entryBelowLB = rangesByLowerBound.lowerEntry(lbToAdd);
- if (entryBelowLB != null) {
- // { <
- Range<C> rangeBelowLB = entryBelowLB.getValue();
- if (rangeBelowLB.upperBound.compareTo(lbToAdd) >= 0) {
- // { < }, and we will need to coalesce
- if (rangeBelowLB.upperBound.compareTo(ubToAdd) >= 0) {
- // { < > }
- ubToAdd = rangeBelowLB.upperBound;
- /*
- * TODO(cpovirk): can we just "return;" here? Or, can we remove this if() entirely? If
- * not, add tests to demonstrate the problem with each approach
- */
- }
- lbToAdd = rangeBelowLB.lowerBound;
- }
- }
-
- Entry<Cut<C>, Range<C>> entryBelowUB = rangesByLowerBound.floorEntry(ubToAdd);
- if (entryBelowUB != null) {
- // { >
- Range<C> rangeBelowUB = entryBelowUB.getValue();
- if (rangeBelowUB.upperBound.compareTo(ubToAdd) >= 0) {
- // { > }, and we need to coalesce
- ubToAdd = rangeBelowUB.upperBound;
- }
- }
-
- // Remove ranges which are strictly enclosed.
- rangesByLowerBound.subMap(lbToAdd, ubToAdd).clear();
-
- replaceRangeWithSameLowerBound(Range.create(lbToAdd, ubToAdd));
- }
-
- @Override
- public void remove(Range<C> rangeToRemove) {
- checkNotNull(rangeToRemove);
-
- if (rangeToRemove.isEmpty()) {
- return;
- }
-
- // We will use { } to illustrate ranges currently in the range set, and < >
- // to illustrate rangeToRemove.
-
- Entry<Cut<C>, Range<C>> entryBelowLB = rangesByLowerBound.lowerEntry(rangeToRemove.lowerBound);
- if (entryBelowLB != null) {
- // { <
- Range<C> rangeBelowLB = entryBelowLB.getValue();
- if (rangeBelowLB.upperBound.compareTo(rangeToRemove.lowerBound) >= 0) {
- // { < }, and we will need to subdivide
- if (rangeToRemove.hasUpperBound()
- && rangeBelowLB.upperBound.compareTo(rangeToRemove.upperBound) >= 0) {
- // { < > }
- replaceRangeWithSameLowerBound(
- Range.create(rangeToRemove.upperBound, rangeBelowLB.upperBound));
- }
- replaceRangeWithSameLowerBound(
- Range.create(rangeBelowLB.lowerBound, rangeToRemove.lowerBound));
- }
- }
-
- Entry<Cut<C>, Range<C>> entryBelowUB = rangesByLowerBound.floorEntry(rangeToRemove.upperBound);
- if (entryBelowUB != null) {
- // { >
- Range<C> rangeBelowUB = entryBelowUB.getValue();
- if (rangeToRemove.hasUpperBound()
- && rangeBelowUB.upperBound.compareTo(rangeToRemove.upperBound) >= 0) {
- // { > }
- replaceRangeWithSameLowerBound(
- Range.create(rangeToRemove.upperBound, rangeBelowUB.upperBound));
- }
- }
-
- rangesByLowerBound.subMap(rangeToRemove.lowerBound, rangeToRemove.upperBound).clear();
- }
-
- private void replaceRangeWithSameLowerBound(Range<C> range) {
- if (range.isEmpty()) {
- rangesByLowerBound.remove(range.lowerBound);
- } else {
- rangesByLowerBound.put(range.lowerBound, range);
- }
- }
-
- private transient RangeSet<C> complement;
-
- @Override
- public RangeSet<C> complement() {
- RangeSet<C> result = complement;
- return (result == null) ? complement = new Complement() : result;
- }
-
- @VisibleForTesting
- static final class RangesByUpperBound<C extends Comparable<?>>
- extends AbstractNavigableMap<Cut<C>, Range<C>> {
- private final NavigableMap<Cut<C>, Range<C>> rangesByLowerBound;
-
- /**
- * upperBoundWindow represents the headMap/subMap/tailMap view of the entire "ranges by upper
- * bound" map; it's a constraint on the *keys*, and does not affect the values.
- */
- private final Range<Cut<C>> upperBoundWindow;
-
- RangesByUpperBound(NavigableMap<Cut<C>, Range<C>> rangesByLowerBound) {
- this.rangesByLowerBound = rangesByLowerBound;
- this.upperBoundWindow = Range.all();
- }
-
- private RangesByUpperBound(
- NavigableMap<Cut<C>, Range<C>> rangesByLowerBound, Range<Cut<C>> upperBoundWindow) {
- this.rangesByLowerBound = rangesByLowerBound;
- this.upperBoundWindow = upperBoundWindow;
- }
-
- private NavigableMap<Cut<C>, Range<C>> subMap(Range<Cut<C>> window) {
- if (window.isConnected(upperBoundWindow)) {
- return new RangesByUpperBound<C>(rangesByLowerBound, window.intersection(upperBoundWindow));
- } else {
- return ImmutableSortedMap.of();
- }
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> subMap(
- Cut<C> fromKey, boolean fromInclusive, Cut<C> toKey, boolean toInclusive) {
- return subMap(Range.range(
- fromKey, BoundType.forBoolean(fromInclusive),
- toKey, BoundType.forBoolean(toInclusive)));
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> headMap(Cut<C> toKey, boolean inclusive) {
- return subMap(Range.upTo(toKey, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> tailMap(Cut<C> fromKey, boolean inclusive) {
- return subMap(Range.downTo(fromKey, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public Comparator<? super Cut<C>> comparator() {
- return Ordering.<Cut<C>>natural();
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return get(key) != null;
- }
-
- @Override
- public Range<C> get(@Nullable Object key) {
- if (key instanceof Cut) {
- try {
- @SuppressWarnings("unchecked") // we catch CCEs
- Cut<C> cut = (Cut<C>) key;
- if (!upperBoundWindow.contains(cut)) {
- return null;
- }
- Entry<Cut<C>, Range<C>> candidate = rangesByLowerBound.lowerEntry(cut);
- if (candidate != null && candidate.getValue().upperBound.equals(cut)) {
- return candidate.getValue();
- }
- } catch (ClassCastException e) {
- return null;
- }
- }
- return null;
- }
-
- @Override
- Iterator<Entry<Cut<C>, Range<C>>> entryIterator() {
- /*
- * We want to start the iteration at the first range where the upper bound is in
- * upperBoundWindow.
- */
- final Iterator<Range<C>> backingItr;
- if (!upperBoundWindow.hasLowerBound()) {
- backingItr = rangesByLowerBound.values().iterator();
- } else {
- Entry<Cut<C>, Range<C>> lowerEntry =
- rangesByLowerBound.lowerEntry(upperBoundWindow.lowerEndpoint());
- if (lowerEntry == null) {
- backingItr = rangesByLowerBound.values().iterator();
- } else if (upperBoundWindow.lowerBound.isLessThan(lowerEntry.getValue().upperBound)) {
- backingItr = rangesByLowerBound.tailMap(lowerEntry.getKey(), true).values().iterator();
- } else {
- backingItr = rangesByLowerBound.tailMap(upperBoundWindow.lowerEndpoint(), true)
- .values().iterator();
- }
- }
- return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
- @Override
- protected Entry<Cut<C>, Range<C>> computeNext() {
- if (!backingItr.hasNext()) {
- return endOfData();
- }
- Range<C> range = backingItr.next();
- if (upperBoundWindow.upperBound.isLessThan(range.upperBound)) {
- return endOfData();
- } else {
- return Maps.immutableEntry(range.upperBound, range);
- }
- }
- };
- }
-
- @Override
- Iterator<Entry<Cut<C>, Range<C>>> descendingEntryIterator() {
- Collection<Range<C>> candidates;
- if (upperBoundWindow.hasUpperBound()) {
- candidates = rangesByLowerBound.headMap(upperBoundWindow.upperEndpoint(), false)
- .descendingMap().values();
- } else {
- candidates = rangesByLowerBound.descendingMap().values();
- }
- final PeekingIterator<Range<C>> backingItr = Iterators.peekingIterator(candidates.iterator());
- if (backingItr.hasNext()
- && upperBoundWindow.upperBound.isLessThan(backingItr.peek().upperBound)) {
- backingItr.next();
- }
- return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
- @Override
- protected Entry<Cut<C>, Range<C>> computeNext() {
- if (!backingItr.hasNext()) {
- return endOfData();
- }
- Range<C> range = backingItr.next();
- return upperBoundWindow.lowerBound.isLessThan(range.upperBound)
- ? Maps.immutableEntry(range.upperBound, range)
- : endOfData();
- }
- };
- }
-
- @Override
- public int size() {
- if (upperBoundWindow.equals(Range.all())) {
- return rangesByLowerBound.size();
- }
- return Iterators.size(entryIterator());
- }
-
- @Override
- public boolean isEmpty() {
- return upperBoundWindow.equals(Range.all())
- ? rangesByLowerBound.isEmpty()
- : !entryIterator().hasNext();
- }
- }
-
- private static final class ComplementRangesByLowerBound<C extends Comparable<?>>
- extends AbstractNavigableMap<Cut<C>, Range<C>> {
- private final NavigableMap<Cut<C>, Range<C>> positiveRangesByLowerBound;
- private final NavigableMap<Cut<C>, Range<C>> positiveRangesByUpperBound;
-
- /**
- * complementLowerBoundWindow represents the headMap/subMap/tailMap view of the entire
- * "complement ranges by lower bound" map; it's a constraint on the *keys*, and does not affect
- * the values.
- */
- private final Range<Cut<C>> complementLowerBoundWindow;
-
- ComplementRangesByLowerBound(NavigableMap<Cut<C>, Range<C>> positiveRangesByLowerBound) {
- this(positiveRangesByLowerBound, Range.<Cut<C>>all());
- }
-
- private ComplementRangesByLowerBound(NavigableMap<Cut<C>, Range<C>> positiveRangesByLowerBound,
- Range<Cut<C>> window) {
- this.positiveRangesByLowerBound = positiveRangesByLowerBound;
- this.positiveRangesByUpperBound = new RangesByUpperBound<C>(positiveRangesByLowerBound);
- this.complementLowerBoundWindow = window;
- }
-
- private NavigableMap<Cut<C>, Range<C>> subMap(Range<Cut<C>> subWindow) {
- if (!complementLowerBoundWindow.isConnected(subWindow)) {
- return ImmutableSortedMap.of();
- } else {
- subWindow = subWindow.intersection(complementLowerBoundWindow);
- return new ComplementRangesByLowerBound<C>(positiveRangesByLowerBound, subWindow);
- }
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> subMap(
- Cut<C> fromKey, boolean fromInclusive, Cut<C> toKey, boolean toInclusive) {
- return subMap(Range.range(
- fromKey, BoundType.forBoolean(fromInclusive),
- toKey, BoundType.forBoolean(toInclusive)));
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> headMap(Cut<C> toKey, boolean inclusive) {
- return subMap(Range.upTo(toKey, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> tailMap(Cut<C> fromKey, boolean inclusive) {
- return subMap(Range.downTo(fromKey, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public Comparator<? super Cut<C>> comparator() {
- return Ordering.<Cut<C>>natural();
- }
-
- @Override
- Iterator<Entry<Cut<C>, Range<C>>> entryIterator() {
- /*
- * firstComplementRangeLowerBound is the first complement range lower bound inside
- * complementLowerBoundWindow. Complement range lower bounds are either positive range upper
- * bounds, or Cut.belowAll().
- *
- * positiveItr starts at the first positive range with lower bound greater than
- * firstComplementRangeLowerBound. (Positive range lower bounds correspond to complement range
- * upper bounds.)
- */
- Collection<Range<C>> positiveRanges;
- if (complementLowerBoundWindow.hasLowerBound()) {
- positiveRanges = positiveRangesByUpperBound.tailMap(
- complementLowerBoundWindow.lowerEndpoint(),
- complementLowerBoundWindow.lowerBoundType() == BoundType.CLOSED).values();
- } else {
- positiveRanges = positiveRangesByUpperBound.values();
- }
- final PeekingIterator<Range<C>> positiveItr = Iterators.peekingIterator(
- positiveRanges.iterator());
- final Cut<C> firstComplementRangeLowerBound;
- if (complementLowerBoundWindow.contains(Cut.<C>belowAll()) &&
- (!positiveItr.hasNext() || positiveItr.peek().lowerBound != Cut.<C>belowAll())) {
- firstComplementRangeLowerBound = Cut.belowAll();
- } else if (positiveItr.hasNext()) {
- firstComplementRangeLowerBound = positiveItr.next().upperBound;
- } else {
- return Iterators.emptyIterator();
- }
- return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
- Cut<C> nextComplementRangeLowerBound = firstComplementRangeLowerBound;
-
- @Override
- protected Entry<Cut<C>, Range<C>> computeNext() {
- if (complementLowerBoundWindow.upperBound.isLessThan(nextComplementRangeLowerBound)
- || nextComplementRangeLowerBound == Cut.<C>aboveAll()) {
- return endOfData();
- }
- Range<C> negativeRange;
- if (positiveItr.hasNext()) {
- Range<C> positiveRange = positiveItr.next();
- negativeRange = Range.create(nextComplementRangeLowerBound, positiveRange.lowerBound);
- nextComplementRangeLowerBound = positiveRange.upperBound;
- } else {
- negativeRange = Range.create(nextComplementRangeLowerBound, Cut.<C>aboveAll());
- nextComplementRangeLowerBound = Cut.aboveAll();
- }
- return Maps.immutableEntry(negativeRange.lowerBound, negativeRange);
- }
- };
- }
-
- @Override
- Iterator<Entry<Cut<C>, Range<C>>> descendingEntryIterator() {
- Iterator<Range<C>> itr;
- /*
- * firstComplementRangeUpperBound is the upper bound of the last complement range with lower
- * bound inside complementLowerBoundWindow.
- *
- * positiveItr starts at the first positive range with upper bound less than
- * firstComplementRangeUpperBound. (Positive range upper bounds correspond to complement range
- * lower bounds.)
- */
- Cut<C> startingPoint = complementLowerBoundWindow.hasUpperBound()
- ? complementLowerBoundWindow.upperEndpoint()
- : Cut.<C>aboveAll();
- boolean inclusive = complementLowerBoundWindow.hasUpperBound()
- && complementLowerBoundWindow.upperBoundType() == BoundType.CLOSED;
- final PeekingIterator<Range<C>> positiveItr =
- Iterators.peekingIterator(positiveRangesByUpperBound.headMap(startingPoint, inclusive)
- .descendingMap().values().iterator());
- Cut<C> cut;
- if (positiveItr.hasNext()) {
- cut = (positiveItr.peek().upperBound == Cut.<C>aboveAll())
- ? positiveItr.next().lowerBound
- : positiveRangesByLowerBound.higherKey(positiveItr.peek().upperBound);
- } else if (!complementLowerBoundWindow.contains(Cut.<C>belowAll())
- || positiveRangesByLowerBound.containsKey(Cut.belowAll())) {
- return Iterators.emptyIterator();
- } else {
- cut = positiveRangesByLowerBound.higherKey(Cut.<C>belowAll());
- }
- final Cut<C> firstComplementRangeUpperBound = Objects.firstNonNull(cut, Cut.<C>aboveAll());
- return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
- Cut<C> nextComplementRangeUpperBound = firstComplementRangeUpperBound;
-
- @Override
- protected Entry<Cut<C>, Range<C>> computeNext() {
- if (nextComplementRangeUpperBound == Cut.<C>belowAll()) {
- return endOfData();
- } else if (positiveItr.hasNext()) {
- Range<C> positiveRange = positiveItr.next();
- Range<C> negativeRange =
- Range.create(positiveRange.upperBound, nextComplementRangeUpperBound);
- nextComplementRangeUpperBound = positiveRange.lowerBound;
- if (complementLowerBoundWindow.lowerBound.isLessThan(negativeRange.lowerBound)) {
- return Maps.immutableEntry(negativeRange.lowerBound, negativeRange);
- }
- } else if (complementLowerBoundWindow.lowerBound.isLessThan(Cut.<C>belowAll())) {
- Range<C> negativeRange =
- Range.create(Cut.<C>belowAll(), nextComplementRangeUpperBound);
- nextComplementRangeUpperBound = Cut.belowAll();
- return Maps.immutableEntry(Cut.<C>belowAll(), negativeRange);
- }
- return endOfData();
- }
- };
- }
-
- @Override
- public int size() {
- return Iterators.size(entryIterator());
- }
-
- @Override
- @Nullable
- public Range<C> get(Object key) {
- if (key instanceof Cut) {
- try {
- @SuppressWarnings("unchecked")
- Cut<C> cut = (Cut<C>) key;
- // tailMap respects the current window
- Entry<Cut<C>, Range<C>> firstEntry = tailMap(cut, true).firstEntry();
- if (firstEntry != null && firstEntry.getKey().equals(cut)) {
- return firstEntry.getValue();
- }
- } catch (ClassCastException e) {
- return null;
- }
- }
- return null;
- }
-
- @Override
- public boolean containsKey(Object key) {
- return get(key) != null;
- }
- }
-
- private final class Complement extends TreeRangeSet<C> {
- Complement() {
- super(new ComplementRangesByLowerBound<C>(TreeRangeSet.this.rangesByLowerBound));
- }
-
- @Override
- public void add(Range<C> rangeToAdd) {
- TreeRangeSet.this.remove(rangeToAdd);
- }
-
- @Override
- public void remove(Range<C> rangeToRemove) {
- TreeRangeSet.this.add(rangeToRemove);
- }
-
- @Override
- public boolean contains(C value) {
- return !TreeRangeSet.this.contains(value);
- }
-
- @Override
- public RangeSet<C> complement() {
- return TreeRangeSet.this;
- }
- }
-
- private static final class SubRangeSetRangesByLowerBound<C extends Comparable<?>>
- extends AbstractNavigableMap<Cut<C>, Range<C>> {
- /**
- * lowerBoundWindow is the headMap/subMap/tailMap view; it only restricts the keys, and does not
- * affect the values.
- */
- private final Range<Cut<C>> lowerBoundWindow;
-
- /**
- * restriction is the subRangeSet view; ranges are truncated to their intersection with
- * restriction.
- */
- private final Range<C> restriction;
-
- private final NavigableMap<Cut<C>, Range<C>> rangesByLowerBound;
- private final NavigableMap<Cut<C>, Range<C>> rangesByUpperBound;
-
- private SubRangeSetRangesByLowerBound(Range<Cut<C>> lowerBoundWindow, Range<C> restriction,
- NavigableMap<Cut<C>, Range<C>> rangesByLowerBound) {
- this.lowerBoundWindow = checkNotNull(lowerBoundWindow);
- this.restriction = checkNotNull(restriction);
- this.rangesByLowerBound = checkNotNull(rangesByLowerBound);
- this.rangesByUpperBound = new RangesByUpperBound<C>(rangesByLowerBound);
- }
-
- private NavigableMap<Cut<C>, Range<C>> subMap(Range<Cut<C>> window) {
- if (!window.isConnected(lowerBoundWindow)) {
- return ImmutableSortedMap.of();
- } else {
- return new SubRangeSetRangesByLowerBound<C>(
- lowerBoundWindow.intersection(window), restriction, rangesByLowerBound);
- }
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> subMap(
- Cut<C> fromKey, boolean fromInclusive, Cut<C> toKey, boolean toInclusive) {
- return subMap(Range.range(
- fromKey, BoundType.forBoolean(fromInclusive), toKey, BoundType.forBoolean(toInclusive)));
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> headMap(Cut<C> toKey, boolean inclusive) {
- return subMap(Range.upTo(toKey, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public NavigableMap<Cut<C>, Range<C>> tailMap(Cut<C> fromKey, boolean inclusive) {
- return subMap(Range.downTo(fromKey, BoundType.forBoolean(inclusive)));
- }
-
- @Override
- public Comparator<? super Cut<C>> comparator() {
- return Ordering.<Cut<C>>natural();
- }
-
- @Override
- public boolean containsKey(@Nullable Object key) {
- return get(key) != null;
- }
-
- @Override
- @Nullable
- public Range<C> get(@Nullable Object key) {
- if (key instanceof Cut) {
- try {
- @SuppressWarnings("unchecked") // we catch CCE's
- Cut<C> cut = (Cut<C>) key;
- if (!lowerBoundWindow.contains(cut) || cut.compareTo(restriction.lowerBound) < 0
- || cut.compareTo(restriction.upperBound) >= 0) {
- return null;
- } else if (cut.equals(restriction.lowerBound)) {
- // it might be present, truncated on the left
- Range<C> candidate = Maps.valueOrNull(rangesByLowerBound.floorEntry(cut));
- if (candidate != null && candidate.upperBound.compareTo(restriction.lowerBound) > 0) {
- return candidate.intersection(restriction);
- }
- } else {
- Range<C> result = rangesByLowerBound.get(cut);
- if (result != null) {
- return result.intersection(restriction);
- }
- }
- } catch (ClassCastException e) {
- return null;
- }
- }
- return null;
- }
-
- @Override
- Iterator<Entry<Cut<C>, Range<C>>> entryIterator() {
- if (restriction.isEmpty()) {
- return Iterators.emptyIterator();
- }
- final Iterator<Range<C>> completeRangeItr;
- if (lowerBoundWindow.upperBound.isLessThan(restriction.lowerBound)) {
- return Iterators.emptyIterator();
- } else if (lowerBoundWindow.lowerBound.isLessThan(restriction.lowerBound)) {
- // starts at the first range with upper bound strictly greater than restriction.lowerBound
- completeRangeItr =
- rangesByUpperBound.tailMap(restriction.lowerBound, false).values().iterator();
- } else {
- // starts at the first range with lower bound above lowerBoundWindow.lowerBound
- completeRangeItr = rangesByLowerBound.tailMap(lowerBoundWindow.lowerBound.endpoint(),
- lowerBoundWindow.lowerBoundType() == BoundType.CLOSED).values().iterator();
- }
- final Cut<Cut<C>> upperBoundOnLowerBounds = Ordering.natural()
- .min(lowerBoundWindow.upperBound, Cut.belowValue(restriction.upperBound));
- return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
- @Override
- protected Entry<Cut<C>, Range<C>> computeNext() {
- if (!completeRangeItr.hasNext()) {
- return endOfData();
- }
- Range<C> nextRange = completeRangeItr.next();
- if (upperBoundOnLowerBounds.isLessThan(nextRange.lowerBound)) {
- return endOfData();
- } else {
- nextRange = nextRange.intersection(restriction);
- return Maps.immutableEntry(nextRange.lowerBound, nextRange);
- }
- }
- };
- }
-
- @Override
- Iterator<Entry<Cut<C>, Range<C>>> descendingEntryIterator() {
- if (restriction.isEmpty()) {
- return Iterators.emptyIterator();
- }
- Cut<Cut<C>> upperBoundOnLowerBounds = Ordering.natural()
- .min(lowerBoundWindow.upperBound, Cut.belowValue(restriction.upperBound));
- final Iterator<Range<C>> completeRangeItr = rangesByLowerBound.headMap(
- upperBoundOnLowerBounds.endpoint(),
- upperBoundOnLowerBounds.typeAsUpperBound() == BoundType.CLOSED)
- .descendingMap().values().iterator();
- return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
- @Override
- protected Entry<Cut<C>, Range<C>> computeNext() {
- if (!completeRangeItr.hasNext()) {
- return endOfData();
- }
- Range<C> nextRange = completeRangeItr.next();
- if (restriction.lowerBound.compareTo(nextRange.upperBound) >= 0) {
- return endOfData();
- }
- nextRange = nextRange.intersection(restriction);
- if (lowerBoundWindow.contains(nextRange.lowerBound)) {
- return Maps.immutableEntry(nextRange.lowerBound, nextRange);
- } else {
- return endOfData();
- }
- }
- };
- }
-
- @Override
- public int size() {
- return Iterators.size(entryIterator());
- }
- }
-
- @Override
- public RangeSet<C> subRangeSet(Range<C> view) {
- return view.equals(Range.<C>all()) ? this : new SubRangeSet(view);
- }
-
- private final class SubRangeSet extends TreeRangeSet<C> {
- private final Range<C> restriction;
-
- SubRangeSet(Range<C> restriction) {
- super(new SubRangeSetRangesByLowerBound<C>(
- Range.<Cut<C>>all(), restriction, TreeRangeSet.this.rangesByLowerBound));
- this.restriction = restriction;
- }
-
- @Override
- public boolean encloses(Range<C> range) {
- if (!restriction.isEmpty() && restriction.encloses(range)) {
- Range<C> enclosing = TreeRangeSet.this.rangeEnclosing(range);
- return enclosing != null && !enclosing.intersection(restriction).isEmpty();
- }
- return false;
- }
-
- @Override
- @Nullable
- public Range<C> rangeContaining(C value) {
- if (!restriction.contains(value)) {
- return null;
- }
- Range<C> result = TreeRangeSet.this.rangeContaining(value);
- return (result == null) ? null : result.intersection(restriction);
- }
-
- @Override
- public void add(Range<C> rangeToAdd) {
- checkArgument(restriction.encloses(rangeToAdd), "Cannot add range %s to subRangeSet(%s)",
- rangeToAdd, restriction);
- super.add(rangeToAdd);
- }
-
- @Override
- public void remove(Range<C> rangeToRemove) {
- if (rangeToRemove.isConnected(restriction)) {
- TreeRangeSet.this.remove(rangeToRemove.intersection(restriction));
- }
- }
-
- @Override
- public boolean contains(C value) {
- return restriction.contains(value) && TreeRangeSet.this.contains(value);
- }
-
- @Override
- public void clear() {
- TreeRangeSet.this.remove(restriction);
- }
-
- @Override
- public RangeSet<C> subRangeSet(Range<C> view) {
- if (view.encloses(restriction)) {
- return this;
- } else if (view.isConnected(restriction)) {
- return new SubRangeSet(restriction.intersection(view));
- } else {
- return ImmutableRangeSet.of();
- }
- }
- }
-}
diff --git a/guava/src/com/google/common/collect/UnmodifiableIterator.java b/guava/src/com/google/common/collect/UnmodifiableIterator.java
index 55ceef9..5cff61b 100644
--- a/guava/src/com/google/common/collect/UnmodifiableIterator.java
+++ b/guava/src/com/google/common/collect/UnmodifiableIterator.java
@@ -30,14 +30,12 @@ import java.util.Iterator;
public abstract class UnmodifiableIterator<E> implements Iterator<E> {
/** Constructor for use by subclasses. */
protected UnmodifiableIterator() {}
-
+
/**
* Guaranteed to throw an exception and leave the underlying data unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated
@Override
public final void remove() {
throw new UnsupportedOperationException();
diff --git a/guava/src/com/google/common/collect/UnmodifiableListIterator.java b/guava/src/com/google/common/collect/UnmodifiableListIterator.java
index 8e535a3..fa71bdc 100644
--- a/guava/src/com/google/common/collect/UnmodifiableListIterator.java
+++ b/guava/src/com/google/common/collect/UnmodifiableListIterator.java
@@ -37,9 +37,8 @@ public abstract class UnmodifiableListIterator<E>
* Guaranteed to throw an exception and leave the underlying data unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public final void add(E e) {
+ @Override public final void add(E e) {
throw new UnsupportedOperationException();
}
@@ -47,9 +46,8 @@ public abstract class UnmodifiableListIterator<E>
* Guaranteed to throw an exception and leave the underlying data unmodified.
*
* @throws UnsupportedOperationException always
- * @deprecated Unsupported operation.
*/
- @Deprecated @Override public final void set(E e) {
+ @Override public final void set(E e) {
throw new UnsupportedOperationException();
}
}
diff --git a/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java b/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
deleted file mode 100644
index 4b353cb..0000000
--- a/guava/src/com/google/common/collect/UnmodifiableSortedMultiset.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multisets.UnmodifiableMultiset;
-
-import java.util.Comparator;
-import java.util.NavigableSet;
-
-/**
- * Implementation of {@link Multisets#unmodifiableSortedMultiset(SortedMultiset)},
- * split out into its own file so it can be GWT emulated (to deal with the differing
- * elementSet() types in GWT and non-GWT).
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-final class UnmodifiableSortedMultiset<E>
- extends UnmodifiableMultiset<E> implements SortedMultiset<E> {
- UnmodifiableSortedMultiset(SortedMultiset<E> delegate) {
- super(delegate);
- }
-
- @Override
- protected SortedMultiset<E> delegate() {
- return (SortedMultiset<E>) super.delegate();
- }
-
- @Override
- public Comparator<? super E> comparator() {
- return delegate().comparator();
- }
-
- @Override
- NavigableSet<E> createElementSet() {
- return Sets.unmodifiableNavigableSet(delegate().elementSet());
- }
-
- @Override
- public NavigableSet<E> elementSet() {
- return (NavigableSet<E>) super.elementSet();
- }
-
- private transient UnmodifiableSortedMultiset<E> descendingMultiset;
-
- @Override
- public SortedMultiset<E> descendingMultiset() {
- UnmodifiableSortedMultiset<E> result = descendingMultiset;
- if (result == null) {
- result = new UnmodifiableSortedMultiset<E>(
- delegate().descendingMultiset());
- result.descendingMultiset = this;
- return descendingMultiset = result;
- }
- return result;
- }
-
- @Override
- public Entry<E> firstEntry() {
- return delegate().firstEntry();
- }
-
- @Override
- public Entry<E> lastEntry() {
- return delegate().lastEntry();
- }
-
- @Override
- public Entry<E> pollFirstEntry() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Entry<E> pollLastEntry() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public SortedMultiset<E> headMultiset(E upperBound, BoundType boundType) {
- return Multisets.unmodifiableSortedMultiset(
- delegate().headMultiset(upperBound, boundType));
- }
-
- @Override
- public SortedMultiset<E> subMultiset(
- E lowerBound, BoundType lowerBoundType,
- E upperBound, BoundType upperBoundType) {
- return Multisets.unmodifiableSortedMultiset(delegate().subMultiset(
- lowerBound, lowerBoundType, upperBound, upperBoundType));
- }
-
- @Override
- public SortedMultiset<E> tailMultiset(E lowerBound, BoundType boundType) {
- return Multisets.unmodifiableSortedMultiset(
- delegate().tailMultiset(lowerBound, boundType));
- }
-
- private static final long serialVersionUID = 0;
-} \ No newline at end of file
diff --git a/guava/src/com/google/common/collect/UsingToStringOrdering.java b/guava/src/com/google/common/collect/UsingToStringOrdering.java
index adb6aa7..d1c9feb 100644
--- a/guava/src/com/google/common/collect/UsingToStringOrdering.java
+++ b/guava/src/com/google/common/collect/UsingToStringOrdering.java
@@ -20,10 +20,7 @@ import com.google.common.annotations.GwtCompatible;
import java.io.Serializable;
-/**
- * An ordering that uses the natural order of the string representation of the
- * values.
- */
+/** An ordering that uses the reverse of the natural order of the values. */
@GwtCompatible(serializable = true)
final class UsingToStringOrdering
extends Ordering<Object> implements Serializable {
diff --git a/guava/src/com/google/common/collect/WellBehavedMap.java b/guava/src/com/google/common/collect/WellBehavedMap.java
index c68cc5e..e8aa1f6 100644
--- a/guava/src/com/google/common/collect/WellBehavedMap.java
+++ b/guava/src/com/google/common/collect/WellBehavedMap.java
@@ -18,35 +18,32 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
-import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
- * Workaround for
+ * Workaround for
* <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6312706">
* EnumMap bug</a>. If you want to pass an {@code EnumMap}, with the
* intention of using its {@code entrySet()} method, you should
- * wrap the {@code EnumMap} in this class instead.
- *
- * <p>This class is not thread-safe even if the underlying map is.
- *
+ * wrap the {@code EnumMap} in this class instead.
+ *
* @author Dimitris Andreou
*/
@GwtCompatible
final class WellBehavedMap<K, V> extends ForwardingMap<K, V> {
private final Map<K, V> delegate;
private Set<Entry<K, V>> entrySet;
-
+
private WellBehavedMap(Map<K, V> delegate) {
this.delegate = delegate;
}
-
+
/**
* Wraps the given map into a {@code WellBehavedEntriesMap}, which
- * intercepts its {@code entrySet()} method by taking the
+ * intercepts its {@code entrySet()} method by taking the
* {@code Set<K> keySet()} and transforming it to
- * {@code Set<Entry<K, V>>}. All other invocations are delegated as-is.
+ * {@code Set<Entry<K, V>>}. All other invocations are delegated as-is.
*/
static <K, V> WellBehavedMap<K, V> wrap(Map<K, V> delegate) {
return new WellBehavedMap<K, V>(delegate);
@@ -61,38 +58,34 @@ final class WellBehavedMap<K, V> extends ForwardingMap<K, V> {
if (es != null) {
return es;
}
- return entrySet = new EntrySet();
+ return entrySet = Sets.transform(
+ delegate.keySet(), new KeyToEntryConverter<K, V>(this));
}
-
- private final class EntrySet extends Maps.EntrySet<K, V> {
- @Override
- Map<K, V> map() {
- return WellBehavedMap.this;
+
+ private static class KeyToEntryConverter<K, V>
+ extends Sets.InvertibleFunction<K, Map.Entry<K, V>> {
+ final Map<K, V> map;
+
+ KeyToEntryConverter(Map<K, V> map) {
+ this.map = map;
}
- @Override
- public Iterator<Entry<K, V>> iterator() {
- return new TransformedIterator<K, Entry<K, V>>(keySet().iterator()) {
- @Override
- Entry<K, V> transform(final K key) {
- return new AbstractMapEntry<K, V>() {
- @Override
- public K getKey() {
- return key;
- }
-
- @Override
- public V getValue() {
- return get(key);
- }
-
- @Override
- public V setValue(V value) {
- return put(key, value);
- }
- };
+ @Override public Map.Entry<K, V> apply(final K key) {
+ return new AbstractMapEntry<K, V>() {
+ @Override public K getKey() {
+ return key;
+ }
+ @Override public V getValue() {
+ return map.get(key);
+ }
+ @Override public V setValue(V value) {
+ return map.put(key, value);
}
};
}
+
+ @Override public K invert(Map.Entry<K, V> entry) {
+ return entry.getKey();
+ }
}
}
diff --git a/guava/src/com/google/common/collect/package-info.java b/guava/src/com/google/common/collect/package-info.java
index 3ffbad9..f5c833c 100644
--- a/guava/src/com/google/common/collect/package-info.java
+++ b/guava/src/com/google/common/collect/package-info.java
@@ -85,7 +85,7 @@
* <ul>
* <li>{@link com.google.common.collect.ImmutableSet}
* <li>{@link com.google.common.collect.ImmutableSortedSet}
- * <li>{@link com.google.common.collect.ContiguousSet} (see {@code Range})
+ * <li>{@link com.google.common.collect.ContiguousSet} (see {@code Ranges})
* </ul>
*
* <h3>of {@link java.util.Map}</h3>
@@ -147,10 +147,10 @@
* <li>{@link com.google.common.collect.Iterables}
* <li>{@link com.google.common.collect.Lists}
* <li>{@link com.google.common.collect.Maps}
- * <li>{@link com.google.common.collect.Queues}
* <li>{@link com.google.common.collect.Sets}
* <li>{@link com.google.common.collect.Multisets}
* <li>{@link com.google.common.collect.Multimaps}
+ * <li>{@link com.google.common.collect.SortedMaps}
* <li>{@link com.google.common.collect.Tables}
* <li>{@link com.google.common.collect.ObjectArrays}
* </ul>
@@ -166,7 +166,7 @@
*
* <ul>
* <li>{@link com.google.common.collect.AbstractIterator}
- * <li>{@link com.google.common.collect.AbstractSequentialIterator}
+ * <li>{@link com.google.common.collect.AbstractLinkedIterator}
* <li>{@link com.google.common.collect.ImmutableCollection}
* <li>{@link com.google.common.collect.UnmodifiableIterator}
* <li>{@link com.google.common.collect.UnmodifiableListIterator}
@@ -176,6 +176,7 @@
*
* <ul>
* <li>{@link com.google.common.collect.Range}
+ * <li>{@link com.google.common.collect.Ranges}
* <li>{@link com.google.common.collect.DiscreteDomain}
* <li>{@link com.google.common.collect.DiscreteDomains}
* <li>{@link com.google.common.collect.ContiguousSet}
@@ -209,13 +210,12 @@
* <li>{@link com.google.common.collect.ForwardingMapEntry}
* <li>{@link com.google.common.collect.ForwardingMultimap}
* <li>{@link com.google.common.collect.ForwardingMultiset}
- * <li>{@link com.google.common.collect.ForwardingNavigableMap}
- * <li>{@link com.google.common.collect.ForwardingNavigableSet}
* <li>{@link com.google.common.collect.ForwardingObject}
* <li>{@link com.google.common.collect.ForwardingQueue}
* <li>{@link com.google.common.collect.ForwardingSet}
* <li>{@link com.google.common.collect.ForwardingSetMultimap}
* <li>{@link com.google.common.collect.ForwardingSortedMap}
+ * <li>{@link com.google.common.collect.ForwardingSortedMultiset}
* <li>{@link com.google.common.collect.ForwardingSortedSet}
* <li>{@link com.google.common.collect.ForwardingSortedSetMultimap}
* <li>{@link com.google.common.collect.ForwardingTable}
diff --git a/guava/src/com/google/common/eventbus/AllowConcurrentEvents.java b/guava/src/com/google/common/eventbus/AllowConcurrentEvents.java
index f614598..5699d73 100644
--- a/guava/src/com/google/common/eventbus/AllowConcurrentEvents.java
+++ b/guava/src/com/google/common/eventbus/AllowConcurrentEvents.java
@@ -17,7 +17,6 @@
package com.google.common.eventbus;
import com.google.common.annotations.Beta;
-
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/guava/src/com/google/common/eventbus/AnnotatedHandlerFinder.java b/guava/src/com/google/common/eventbus/AnnotatedHandlerFinder.java
index fe93b21..7153c66 100644
--- a/guava/src/com/google/common/eventbus/AnnotatedHandlerFinder.java
+++ b/guava/src/com/google/common/eventbus/AnnotatedHandlerFinder.java
@@ -16,97 +16,50 @@
package com.google.common.eventbus;
-import com.google.common.base.Throwables;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
-import com.google.common.reflect.TypeToken;
-import com.google.common.util.concurrent.UncheckedExecutionException;
-
import java.lang.reflect.Method;
-import java.util.Set;
/**
- * A {@link HandlerFindingStrategy} for collecting all event handler methods that are marked with
- * the {@link Subscribe} annotation.
+ * A {@link HandlerFindingStrategy} for collecting all event handler methods
+ * that are marked with the {@link Subscribe} annotation.
*
* @author Cliff Biffle
- * @author Louis Wasserman
*/
class AnnotatedHandlerFinder implements HandlerFindingStrategy {
- /**
- * A thread-safe cache that contains the mapping from each class to all methods in that class and
- * all super-classes, that are annotated with {@code @Subscribe}. The cache is shared across all
- * instances of this class; this greatly improves performance if multiple EventBus instances are
- * created and objects of the same class are registered on all of them.
- */
- private static final LoadingCache<Class<?>, ImmutableList<Method>> handlerMethodsCache =
- CacheBuilder.newBuilder()
- .weakKeys()
- .build(new CacheLoader<Class<?>, ImmutableList<Method>>() {
- @Override
- public ImmutableList<Method> load(Class<?> concreteClass) throws Exception {
- return getAnnotatedMethodsInternal(concreteClass);
- }
- });
/**
* {@inheritDoc}
*
- * This implementation finds all methods marked with a {@link Subscribe} annotation.
+ * This implementation finds all methods marked with a {@link Subscribe}
+ * annotation.
*/
@Override
public Multimap<Class<?>, EventHandler> findAllHandlers(Object listener) {
- Multimap<Class<?>, EventHandler> methodsInListener = HashMultimap.create();
- Class<?> clazz = listener.getClass();
- for (Method method : getAnnotatedMethods(clazz)) {
- Class<?>[] parameterTypes = method.getParameterTypes();
- Class<?> eventType = parameterTypes[0];
- EventHandler handler = makeHandler(listener, method);
- methodsInListener.put(eventType, handler);
- }
- return methodsInListener;
- }
+ Multimap<Class<?>, EventHandler> methodsInListener =
+ HashMultimap.create();
+ Class clazz = listener.getClass();
+ while (clazz != null) {
+ for (Method method : clazz.getMethods()) {
+ Subscribe annotation = method.getAnnotation(Subscribe.class);
- private static ImmutableList<Method> getAnnotatedMethods(Class<?> clazz) {
- try {
- return handlerMethodsCache.getUnchecked(clazz);
- } catch (UncheckedExecutionException e) {
- throw Throwables.propagate(e.getCause());
- }
- }
-
- private static ImmutableList<Method> getAnnotatedMethodsInternal(Class<?> clazz) {
- Set<? extends Class<?>> supers = TypeToken.of(clazz).getTypes().rawTypes();
- ImmutableList.Builder<Method> result = ImmutableList.builder();
- for (Method method : clazz.getMethods()) {
- /*
- * Iterate over each distinct method of {@code clazz}, checking if it is annotated with
- * @Subscribe by any of the superclasses or superinterfaces that declare it.
- */
- for (Class<?> c : supers) {
- try {
- Method m = c.getMethod(method.getName(), method.getParameterTypes());
- if (m.isAnnotationPresent(Subscribe.class)) {
- Class<?>[] parameterTypes = method.getParameterTypes();
- if (parameterTypes.length != 1) {
- throw new IllegalArgumentException("Method " + method
- + " has @Subscribe annotation, but requires " + parameterTypes.length
- + " arguments. Event handler methods must require a single argument.");
- }
- Class<?> eventType = parameterTypes[0];
- result.add(method);
- break;
+ if (annotation != null) {
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length != 1) {
+ throw new IllegalArgumentException(
+ "Method " + method + " has @Subscribe annotation, but requires " +
+ parameterTypes.length + " arguments. Event handler methods " +
+ "must require a single argument.");
}
- } catch (NoSuchMethodException ignored) {
- // Move on.
+ Class<?> eventType = parameterTypes[0];
+ EventHandler handler = makeHandler(listener, method);
+
+ methodsInListener.put(eventType, handler);
}
}
+ clazz = clazz.getSuperclass();
}
- return result.build();
+ return methodsInListener;
}
/**
diff --git a/guava/src/com/google/common/eventbus/AsyncEventBus.java b/guava/src/com/google/common/eventbus/AsyncEventBus.java
index eb57aba..8018cee 100644
--- a/guava/src/com/google/common/eventbus/AsyncEventBus.java
+++ b/guava/src/com/google/common/eventbus/AsyncEventBus.java
@@ -16,10 +16,7 @@
package com.google.common.eventbus;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
-
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
@@ -49,7 +46,7 @@ public class AsyncEventBus extends EventBus {
*/
public AsyncEventBus(String identifier, Executor executor) {
super(identifier);
- this.executor = checkNotNull(executor);
+ this.executor = executor;
}
/**
@@ -61,11 +58,11 @@ public class AsyncEventBus extends EventBus {
* been posted to this event bus.
*/
public AsyncEventBus(Executor executor) {
- this.executor = checkNotNull(executor);
+ this.executor = executor;
}
@Override
- void enqueueEvent(Object event, EventHandler handler) {
+ protected void enqueueEvent(Object event, EventHandler handler) {
eventsToDispatch.offer(new EventWithHandler(event, handler));
}
@@ -73,7 +70,6 @@ public class AsyncEventBus extends EventBus {
* Dispatch {@code events} in the order they were posted, regardless of
* the posting thread.
*/
- @SuppressWarnings("deprecation") // only deprecated for external subclasses
@Override
protected void dispatchQueuedEvents() {
while (true) {
@@ -90,15 +86,14 @@ public class AsyncEventBus extends EventBus {
* Calls the {@link #executor} to dispatch {@code event} to {@code handler}.
*/
@Override
- void dispatch(final Object event, final EventHandler handler) {
- checkNotNull(event);
- checkNotNull(handler);
- executor.execute(
- new Runnable() {
+ protected void dispatch(final Object event, final EventHandler handler) {
+ executor.execute(new Runnable() {
@Override
+ @SuppressWarnings("synthetic-access")
public void run() {
AsyncEventBus.super.dispatch(event, handler);
}
});
}
+
}
diff --git a/guava/src/com/google/common/eventbus/DeadEvent.java b/guava/src/com/google/common/eventbus/DeadEvent.java
index 03b4a2e..8265d5a 100644
--- a/guava/src/com/google/common/eventbus/DeadEvent.java
+++ b/guava/src/com/google/common/eventbus/DeadEvent.java
@@ -16,8 +16,6 @@
package com.google.common.eventbus;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
/**
@@ -44,8 +42,8 @@ public class DeadEvent {
* @param event the event that could not be delivered.
*/
public DeadEvent(Object source, Object event) {
- this.source = checkNotNull(source);
- this.event = checkNotNull(event);
+ this.source = source;
+ this.event = event;
}
/**
diff --git a/guava/src/com/google/common/eventbus/EventBus.java b/guava/src/com/google/common/eventbus/EventBus.java
index 94cf2e9..a962fa8 100644
--- a/guava/src/com/google/common/eventbus/EventBus.java
+++ b/guava/src/com/google/common/eventbus/EventBus.java
@@ -16,28 +16,28 @@
package com.google.common.eventbus;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
-import com.google.common.reflect.TypeToken;
-import com.google.common.util.concurrent.UncheckedExecutionException;
+import com.google.common.collect.Sets;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
import java.util.Map.Entry;
-import java.util.Queue;
import java.util.Set;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -101,10 +101,6 @@ import java.util.logging.Logger;
* receive any Object will never receive a DeadEvent.
*
* <p>This class is safe for concurrent use.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/EventBusExplained">
- * {@code EventBus}</a>.
*
* @author Cliff Biffle
* @since 10.0
@@ -113,32 +109,18 @@ import java.util.logging.Logger;
public class EventBus {
/**
- * A thread-safe cache for flattenHierarchy(). The Class class is immutable. This cache is shared
- * across all EventBus instances, which greatly improves performance if multiple such instances
- * are created and objects of the same class are posted on all of them.
+ * All registered event handlers, indexed by event type.
*/
- private static final LoadingCache<Class<?>, Set<Class<?>>> flattenHierarchyCache =
- CacheBuilder.newBuilder()
- .weakKeys()
- .build(new CacheLoader<Class<?>, Set<Class<?>>>() {
- @SuppressWarnings({"unchecked", "rawtypes"}) // safe cast
+ private final SetMultimap<Class<?>, EventHandler> handlersByType =
+ Multimaps.newSetMultimap(new ConcurrentHashMap<Class<?>, Collection<EventHandler>>(),
+ new Supplier<Set<EventHandler>>() {
@Override
- public Set<Class<?>> load(Class<?> concreteClass) {
- return (Set) TypeToken.of(concreteClass).getTypes().rawTypes();
+ public Set<EventHandler> get() {
+ return new CopyOnWriteArraySet<EventHandler>();
}
});
/**
- * All registered event handlers, indexed by event type.
- *
- * <p>This SetMultimap is NOT safe for concurrent use; all access should be
- * made after acquiring a read or write lock via {@link #handlersByTypeLock}.
- */
- private final SetMultimap<Class<?>, EventHandler> handlersByType =
- HashMultimap.create();
- private final ReadWriteLock handlersByTypeLock = new ReentrantReadWriteLock();
-
- /**
* Logger for event dispatch failures. Named by the fully-qualified name of
* this class, followed by the identifier provided at construction.
*/
@@ -152,10 +134,11 @@ public class EventBus {
private final HandlerFindingStrategy finder = new AnnotatedHandlerFinder();
/** queues of events for the current thread to dispatch */
- private final ThreadLocal<Queue<EventWithHandler>> eventsToDispatch =
- new ThreadLocal<Queue<EventWithHandler>>() {
- @Override protected Queue<EventWithHandler> initialValue() {
- return new LinkedList<EventWithHandler>();
+ private final ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>
+ eventsToDispatch =
+ new ThreadLocal<ConcurrentLinkedQueue<EventWithHandler>>() {
+ @Override protected ConcurrentLinkedQueue<EventWithHandler> initialValue() {
+ return new ConcurrentLinkedQueue<EventWithHandler>();
}
};
@@ -168,6 +151,38 @@ public class EventBus {
};
/**
+ * A thread-safe cache for flattenHierarch(). The Class class is immutable.
+ */
+ private LoadingCache<Class<?>, Set<Class<?>>> flattenHierarchyCache =
+ CacheBuilder.newBuilder()
+ .weakKeys()
+ .build(new CacheLoader<Class<?>, Set<Class<?>>>() {
+ @Override
+ public Set<Class<?>> load(Class<?> concreteClass) throws Exception {
+ List<Class<?>> parents = Lists.newLinkedList();
+ Set<Class<?>> classes = Sets.newHashSet();
+
+ parents.add(concreteClass);
+
+ while (!parents.isEmpty()) {
+ Class<?> clazz = parents.remove(0);
+ classes.add(clazz);
+
+ Class<?> parent = clazz.getSuperclass();
+ if (parent != null) {
+ parents.add(parent);
+ }
+
+ for (Class<?> iface : clazz.getInterfaces()) {
+ parents.add(iface);
+ }
+ }
+
+ return classes;
+ }
+ });
+
+ /**
* Creates a new EventBus named "default".
*/
public EventBus() {
@@ -181,7 +196,7 @@ public class EventBus {
* be a valid Java identifier.
*/
public EventBus(String identifier) {
- logger = Logger.getLogger(EventBus.class.getName() + "." + checkNotNull(identifier));
+ logger = Logger.getLogger(EventBus.class.getName() + "." + identifier);
}
/**
@@ -193,14 +208,7 @@ public class EventBus {
* @param object object whose handler methods should be registered.
*/
public void register(Object object) {
- Multimap<Class<?>, EventHandler> methodsInListener =
- finder.findAllHandlers(object);
- handlersByTypeLock.writeLock().lock();
- try {
- handlersByType.putAll(methodsInListener);
- } finally {
- handlersByTypeLock.writeLock().unlock();
- }
+ handlersByType.putAll(finder.findAllHandlers(object));
}
/**
@@ -212,20 +220,14 @@ public class EventBus {
public void unregister(Object object) {
Multimap<Class<?>, EventHandler> methodsInListener = finder.findAllHandlers(object);
for (Entry<Class<?>, Collection<EventHandler>> entry : methodsInListener.asMap().entrySet()) {
- Class<?> eventType = entry.getKey();
+ Set<EventHandler> currentHandlers = getHandlersForEventType(entry.getKey());
Collection<EventHandler> eventMethodsInListener = entry.getValue();
-
- handlersByTypeLock.writeLock().lock();
- try {
- Set<EventHandler> currentHandlers = handlersByType.get(eventType);
- if (!currentHandlers.containsAll(eventMethodsInListener)) {
- throw new IllegalArgumentException(
- "missing event handler for an annotated method. Is " + object + " registered?");
- }
- currentHandlers.removeAll(eventMethodsInListener);
- } finally {
- handlersByTypeLock.writeLock().unlock();
+
+ if (currentHandlers == null || !currentHandlers.containsAll(entry.getValue())) {
+ throw new IllegalArgumentException(
+ "missing event handler for an annotated method. Is " + object + " registered?");
}
+ currentHandlers.removeAll(eventMethodsInListener);
}
}
@@ -245,18 +247,13 @@ public class EventBus {
boolean dispatched = false;
for (Class<?> eventType : dispatchTypes) {
- handlersByTypeLock.readLock().lock();
- try {
- Set<EventHandler> wrappers = handlersByType.get(eventType);
-
- if (!wrappers.isEmpty()) {
- dispatched = true;
- for (EventHandler wrapper : wrappers) {
- enqueueEvent(event, wrapper);
- }
+ Set<EventHandler> wrappers = getHandlersForEventType(eventType);
+
+ if (wrappers != null && !wrappers.isEmpty()) {
+ dispatched = true;
+ for (EventHandler wrapper : wrappers) {
+ enqueueEvent(event, wrapper);
}
- } finally {
- handlersByTypeLock.readLock().unlock();
}
}
@@ -272,7 +269,7 @@ public class EventBus {
* {@link #dispatchQueuedEvents()}. Events are queued in-order of occurrence
* so they can be dispatched in the same order.
*/
- void enqueueEvent(Object event, EventHandler handler) {
+ protected void enqueueEvent(Object event, EventHandler handler) {
eventsToDispatch.get().offer(new EventWithHandler(event, handler));
}
@@ -280,7 +277,7 @@ public class EventBus {
* Drain the queue of events to be dispatched. As the queue is being drained,
* new events may be posted to the end of the queue.
*/
- void dispatchQueuedEvents() {
+ protected void dispatchQueuedEvents() {
// don't dispatch if we're already dispatching, that would allow reentrancy
// and out-of-order events. Instead, leave the events to be dispatched
// after the in-progress dispatch is complete.
@@ -290,14 +287,16 @@ public class EventBus {
isDispatching.set(true);
try {
- Queue<EventWithHandler> events = eventsToDispatch.get();
- EventWithHandler eventWithHandler;
- while ((eventWithHandler = events.poll()) != null) {
+ while (true) {
+ EventWithHandler eventWithHandler = eventsToDispatch.get().poll();
+ if (eventWithHandler == null) {
+ break;
+ }
+
dispatch(eventWithHandler.event, eventWithHandler.handler);
}
} finally {
- isDispatching.remove();
- eventsToDispatch.remove();
+ isDispatching.set(false);
}
}
@@ -309,7 +308,7 @@ public class EventBus {
* @param event event to dispatch.
* @param wrapper wrapper that will call the handler.
*/
- void dispatch(Object event, EventHandler wrapper) {
+ protected void dispatch(Object event, EventHandler wrapper) {
try {
wrapper.handleEvent(event);
} catch (InvocationTargetException e) {
@@ -319,6 +318,29 @@ public class EventBus {
}
/**
+ * Retrieves a mutable set of the currently registered handlers for
+ * {@code type}. If no handlers are currently registered for {@code type},
+ * this method may either return {@code null} or an empty set.
+ *
+ * @param type type of handlers to retrieve.
+ * @return currently registered handlers, or {@code null}.
+ */
+ Set<EventHandler> getHandlersForEventType(Class<?> type) {
+ return handlersByType.get(type);
+ }
+
+ /**
+ * Creates a new Set for insertion into the handler map. This is provided
+ * as an override point for subclasses. The returned set should support
+ * concurrent access.
+ *
+ * @return a new, mutable set for handlers.
+ */
+ protected Set<EventHandler> newHandlerSet() {
+ return new CopyOnWriteArraySet<EventHandler>();
+ }
+
+ /**
* Flattens a class's type hierarchy into a set of Class objects. The set
* will include all superclasses (transitively), and all interfaces
* implemented by these superclasses.
@@ -329,8 +351,8 @@ public class EventBus {
@VisibleForTesting
Set<Class<?>> flattenHierarchy(Class<?> concreteClass) {
try {
- return flattenHierarchyCache.getUnchecked(concreteClass);
- } catch (UncheckedExecutionException e) {
+ return flattenHierarchyCache.get(concreteClass);
+ } catch (ExecutionException e) {
throw Throwables.propagate(e.getCause());
}
}
@@ -340,8 +362,8 @@ public class EventBus {
final Object event;
final EventHandler handler;
public EventWithHandler(Object event, EventHandler handler) {
- this.event = checkNotNull(event);
- this.handler = checkNotNull(handler);
+ this.event = event;
+ this.handler = handler;
}
}
}
diff --git a/guava/src/com/google/common/eventbus/EventHandler.java b/guava/src/com/google/common/eventbus/EventHandler.java
index 45efa80..be89973 100644
--- a/guava/src/com/google/common/eventbus/EventHandler.java
+++ b/guava/src/com/google/common/eventbus/EventHandler.java
@@ -16,15 +16,10 @@
package com.google.common.eventbus;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.base.Preconditions;
-
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import javax.annotation.Nullable;
-
/**
* Wraps a single-argument 'handler' method on a specific object.
*
@@ -65,11 +60,10 @@ class EventHandler {
*
* @param event event to handle
* @throws InvocationTargetException if the wrapped method throws any
- * {@link Throwable} that is not an {@link Error} ({@code Error} instances are
+ * {@link Throwable} that is not an {@link Error} ({@code Error}s are
* propagated as-is).
*/
public void handleEvent(Object event) throws InvocationTargetException {
- checkNotNull(event);
try {
method.invoke(target, new Object[] { event });
} catch (IllegalArgumentException e) {
@@ -90,18 +84,25 @@ class EventHandler {
@Override public int hashCode() {
final int PRIME = 31;
- return (PRIME + method.hashCode()) * PRIME
- + System.identityHashCode(target);
+ return (PRIME + method.hashCode()) * PRIME + target.hashCode();
}
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof EventHandler) {
- EventHandler that = (EventHandler) obj;
- // Use == so that different equal instances will still receive events.
- // We only guard against the case that the same object is registered
- // multiple times
- return target == that.target && method.equals(that.method);
+ @Override public boolean equals(Object obj) {
+ if(this == obj) {
+ return true;
+ }
+
+ if(obj == null) {
+ return false;
}
- return false;
+
+ if(getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final EventHandler other = (EventHandler) obj;
+
+ return method.equals(other.method) && target == other.target;
}
+
}
diff --git a/guava/src/com/google/common/eventbus/HandlerFindingStrategy.java b/guava/src/com/google/common/eventbus/HandlerFindingStrategy.java
index 3f62cae..7144203 100644
--- a/guava/src/com/google/common/eventbus/HandlerFindingStrategy.java
+++ b/guava/src/com/google/common/eventbus/HandlerFindingStrategy.java
@@ -28,7 +28,7 @@ interface HandlerFindingStrategy {
/**
* Finds all suitable event handler methods in {@code source}, organizes them
- * by the type of event they handle, and wraps them in {@link EventHandler} instances.
+ * by the type of event they handle, and wraps them in {@link EventHandler}s.
*
* @param source object whose handlers are desired.
* @return EventHandler objects for each handler method, organized by event
diff --git a/guava/src/com/google/common/eventbus/Subscribe.java b/guava/src/com/google/common/eventbus/Subscribe.java
index 34cb587..568c1c0 100644
--- a/guava/src/com/google/common/eventbus/Subscribe.java
+++ b/guava/src/com/google/common/eventbus/Subscribe.java
@@ -17,7 +17,6 @@
package com.google.common.eventbus;
import com.google.common.annotations.Beta;
-
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/guava/src/com/google/common/eventbus/package-info.java b/guava/src/com/google/common/eventbus/package-info.java
index 28637cd..0c83104 100644
--- a/guava/src/com/google/common/eventbus/package-info.java
+++ b/guava/src/com/google/common/eventbus/package-info.java
@@ -21,10 +21,6 @@
* traditional Java in-process event distribution using explicit registration.
* It is <em>not</em> a general-purpose publish-subscribe system, nor is it
* intended for interprocess communication.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/EventBusExplained">
- * {@code EventBus}</a>.
*
* <h2>One-Minute Guide</h2>
*
@@ -123,6 +119,20 @@
* <p>In short, the EventBus is not a singleton because we'd rather not make
* that decision for you. Use it how you like.
*
+ * <h3>Can I unregister a listener from the Event Bus?</h3>
+ * Currently, no -- a listener registered with an EventBus instance will
+ * continue to receive events until the EventBus itself is disposed.
+ *
+ * <p>In the apps using EventBus so far, this has not been a problem:
+ * <ul>
+ * <li>Most listeners are registered on startup or lazy initialization, and
+ * persist for the life of the application.
+ * <li>Scope-specific EventBus instances can handle temporary event
+ * distribution (e.g. distributing events among request-scoped objects)
+ * <li>For testing, EventBus instances can be easily created and thrown away,
+ * removing the need for explicit unregistration.
+ * </ul>
+ *
* <h3>Why use an annotation to mark handler methods, rather than requiring the
* listener to implement an interface?</h3>
* We feel that the Event Bus's {@code @Subscribe} annotation conveys your
diff --git a/guava/src/com/google/common/hash/AbstractByteHasher.java b/guava/src/com/google/common/hash/AbstractByteHasher.java
deleted file mode 100644
index 90210df..0000000
--- a/guava/src/com/google/common/hash/AbstractByteHasher.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.hash;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-
-import com.google.common.primitives.Chars;
-import com.google.common.primitives.Ints;
-import com.google.common.primitives.Longs;
-import com.google.common.primitives.Shorts;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Abstract {@link Hasher} that handles converting primitives to bytes using a scratch {@code
- * ByteBuffer} and streams all bytes to a sink to compute the hash.
- *
- * @author Colin Decker
- */
-abstract class AbstractByteHasher extends AbstractHasher {
-
- private final ByteBuffer scratch = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);
-
- /**
- * Updates this hasher with the given byte.
- */
- protected abstract void update(byte b);
-
- /**
- * Updates this hasher with the given bytes.
- */
- protected void update(byte[] b) {
- update(b, 0, b.length);
- }
-
- /**
- * Updates this hasher with {@code len} bytes starting at {@code off} in the given buffer.
- */
- protected void update(byte[] b, int off, int len) {
- for (int i = off; i < off + len; i++) {
- update(b[i]);
- }
- }
-
- @Override
- public Hasher putByte(byte b) {
- update(b);
- return this;
- }
-
- @Override
- public Hasher putBytes(byte[] bytes) {
- checkNotNull(bytes);
- update(bytes);
- return this;
- }
-
- @Override
- public Hasher putBytes(byte[] bytes, int off, int len) {
- checkPositionIndexes(off, off + len, bytes.length);
- update(bytes, off, len);
- return this;
- }
-
- /**
- * Updates the sink with the given number of bytes from the buffer.
- */
- private Hasher update(int bytes) {
- try {
- update(scratch.array(), 0, bytes);
- } finally {
- scratch.clear();
- }
- return this;
- }
-
- @Override
- public Hasher putShort(short s) {
- scratch.putShort(s);
- return update(Shorts.BYTES);
- }
-
- @Override
- public Hasher putInt(int i) {
- scratch.putInt(i);
- return update(Ints.BYTES);
- }
-
- @Override
- public Hasher putLong(long l) {
- scratch.putLong(l);
- return update(Longs.BYTES);
- }
-
- @Override
- public Hasher putChar(char c) {
- scratch.putChar(c);
- return update(Chars.BYTES);
- }
-
- @Override
- public <T> Hasher putObject(T instance, Funnel<? super T> funnel) {
- funnel.funnel(instance, this);
- return this;
- }
-}
diff --git a/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java b/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java
index 6a0f452..41c4836 100644
--- a/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java
+++ b/guava/src/com/google/common/hash/AbstractCompositeHashFunction.java
@@ -1,42 +1,23 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.nio.charset.Charset;
/**
* An abstract composition of multiple hash functions. {@linkplain #newHasher()} delegates to the
* {@code Hasher} objects of the delegate hash functions, and in the end, they are used by
* {@linkplain #makeHash(Hasher[])} that constructs the final {@code HashCode}.
- *
- * @author Dimitris Andreou
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
abstract class AbstractCompositeHashFunction extends AbstractStreamingHashFunction {
final HashFunction[] functions;
-
+
AbstractCompositeHashFunction(HashFunction... functions) {
- for (HashFunction function : functions) {
- checkNotNull(function);
- }
this.functions = functions;
}
-
+
/**
* Constructs a {@code HashCode} from the {@code Hasher} objects of the functions. Each of them
* has consumed the entire input and they are ready to output a {@code HashCode}. The order of
@@ -44,7 +25,7 @@ abstract class AbstractCompositeHashFunction extends AbstractStreamingHashFuncti
*/
// this could be cleaner if it passed HashCode[], but that would create yet another array...
/* protected */ abstract HashCode makeHash(Hasher[] hashers);
-
+
@Override
public Hasher newHasher() {
final Hasher[] hashers = new Hasher[functions.length];
@@ -148,6 +129,6 @@ abstract class AbstractCompositeHashFunction extends AbstractStreamingHashFuncti
}
};
}
-
+
private static final long serialVersionUID = 0L;
}
diff --git a/guava/src/com/google/common/hash/AbstractHasher.java b/guava/src/com/google/common/hash/AbstractHasher.java
index f60f928..4abc6a3 100644
--- a/guava/src/com/google/common/hash/AbstractHasher.java
+++ b/guava/src/com/google/common/hash/AbstractHasher.java
@@ -14,6 +14,8 @@
package com.google.common.hash;
+import com.google.common.base.Charsets;
+
import java.nio.charset.Charset;
/**
@@ -21,7 +23,7 @@ import java.nio.charset.Charset;
* {@link #putFloat(float)}, {@link #putString(CharSequence)}, and
* {@link #putString(CharSequence, Charset)} as prescribed by {@link Hasher}.
*
- * @author Dimitris Andreou
+ * @author andreou@google.com (Dimitris Andreou)
*/
abstract class AbstractHasher implements Hasher {
@Override public final Hasher putBoolean(boolean b) {
@@ -37,13 +39,15 @@ abstract class AbstractHasher implements Hasher {
}
@Override public Hasher putString(CharSequence charSequence) {
- for (int i = 0, len = charSequence.length(); i < len; i++) {
- putChar(charSequence.charAt(i));
- }
- return this;
+ // TODO(user): Should we instead loop over the CharSequence and call #putChar?
+ return putString(charSequence, Charsets.UTF_16LE);
}
@Override public Hasher putString(CharSequence charSequence, Charset charset) {
- return putBytes(charSequence.toString().getBytes(charset));
+ try {
+ return putBytes(charSequence.toString().getBytes(charset.name()));
+ } catch (java.io.UnsupportedEncodingException impossible) {
+ throw new AssertionError(impossible);
+ }
}
}
diff --git a/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java b/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java
index 0025d3c..68e9ace 100644
--- a/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java
+++ b/guava/src/com/google/common/hash/AbstractNonStreamingHashFunction.java
@@ -1,18 +1,4 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
@@ -21,14 +7,13 @@ import com.google.common.base.Throwables;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.nio.charset.Charset;
/**
* Skeleton implementation of {@link HashFunction}, appropriate for non-streaming algorithms.
- * All the hash computation done using {@linkplain #newHasher()} are delegated to the {@linkplain
- * #hashBytes(byte[], int, int)} method.
- *
- * @author Dimitris Andreou
+ * All the hash computation done using {@linkplain #newHasher()} are delegated to the {@linkplain
+ * #hashBytes(byte[], int, int)} method.
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
abstract class AbstractNonStreamingHashFunction implements HashFunction {
@Override
@@ -41,43 +26,14 @@ abstract class AbstractNonStreamingHashFunction implements HashFunction {
Preconditions.checkArgument(expectedInputSize >= 0);
return new BufferingHasher(expectedInputSize);
}
-
- @Override public <T> HashCode hashObject(T instance, Funnel<? super T> funnel) {
- return newHasher().putObject(instance, funnel).hash();
- }
-
- @Override public HashCode hashString(CharSequence input) {
- int len = input.length();
- Hasher hasher = newHasher(len * 2);
- for (int i = 0; i < len; i++) {
- hasher.putChar(input.charAt(i));
- }
- return hasher.hash();
- }
-
- @Override public HashCode hashString(CharSequence input, Charset charset) {
- return hashBytes(input.toString().getBytes(charset));
- }
-
- @Override public HashCode hashInt(int input) {
- return newHasher(4).putInt(input).hash();
- }
-
- @Override public HashCode hashLong(long input) {
- return newHasher(8).putLong(input).hash();
- }
-
- @Override public HashCode hashBytes(byte[] input) {
- return hashBytes(input, 0, input.length);
- }
-
+
/**
- * In-memory stream-based implementation of Hasher.
+ * In-memory stream-based implementation of Hasher.
*/
private final class BufferingHasher extends AbstractHasher {
final ExposedByteArrayOutputStream stream;
static final int BOTTOM_BYTE = 0xFF;
-
+
BufferingHasher(int expectedInputSize) {
this.stream = new ExposedByteArrayOutputStream(expectedInputSize);
}
@@ -97,7 +53,7 @@ abstract class AbstractNonStreamingHashFunction implements HashFunction {
}
return this;
}
-
+
@Override
public Hasher putBytes(byte[] bytes, int off, int len) {
stream.write(bytes, off, len);
@@ -146,7 +102,7 @@ abstract class AbstractNonStreamingHashFunction implements HashFunction {
return hashBytes(stream.byteArray(), 0, stream.length());
}
}
-
+
// Just to access the byte[] without introducing an unnecessary copy
private static final class ExposedByteArrayOutputStream extends ByteArrayOutputStream {
ExposedByteArrayOutputStream(int expectedInputSize) {
diff --git a/guava/src/com/google/common/hash/AbstractStreamingHashFunction.java b/guava/src/com/google/common/hash/AbstractStreamingHashFunction.java
index ea6f692..de7748f 100644
--- a/guava/src/com/google/common/hash/AbstractStreamingHashFunction.java
+++ b/guava/src/com/google/common/hash/AbstractStreamingHashFunction.java
@@ -33,10 +33,6 @@ import java.nio.charset.Charset;
* @author Kevin Bourrillion
*/
abstract class AbstractStreamingHashFunction implements HashFunction {
- @Override public <T> HashCode hashObject(T instance, Funnel<? super T> funnel) {
- return newHasher().putObject(instance, funnel).hash();
- }
-
@Override public HashCode hashString(CharSequence input) {
return newHasher().putString(input).hash();
}
@@ -45,10 +41,6 @@ abstract class AbstractStreamingHashFunction implements HashFunction {
return newHasher().putString(input, charset).hash();
}
- @Override public HashCode hashInt(int input) {
- return newHasher().putInt(input).hash();
- }
-
@Override public HashCode hashLong(long input) {
return newHasher().putLong(input).hash();
}
@@ -70,8 +62,8 @@ abstract class AbstractStreamingHashFunction implements HashFunction {
* A convenience base class for implementors of {@code Hasher}; handles accumulating data
* until an entire "chunk" (of implementation-dependent length) is ready to be hashed.
*
- * @author Kevin Bourrillion
- * @author Dimitris Andreou
+ * @author kevinb@google.com (Kevin Bourrillion)
+ * @author andreou@google.com (Dimitris Andreou)
*/
// TODO(kevinb): this class still needs some design-and-document-for-inheritance love
protected static abstract class AbstractStreamingHasher extends AbstractHasher {
@@ -150,7 +142,7 @@ abstract class AbstractStreamingHashFunction implements HashFunction {
return putBytes(ByteBuffer.wrap(bytes, off, len).order(ByteOrder.LITTLE_ENDIAN));
}
- private Hasher putBytes(ByteBuffer readBuffer) {
+ private final Hasher putBytes(ByteBuffer readBuffer) {
// If we have room for all of it, this is easy
if (readBuffer.remaining() <= buffer.remaining()) {
buffer.put(readBuffer);
diff --git a/guava/src/com/google/common/hash/BloomFilter.java b/guava/src/com/google/common/hash/BloomFilter.java
index 4f78bb9..04bba08 100644
--- a/guava/src/com/google/common/hash/BloomFilter.java
+++ b/guava/src/com/google/common/hash/BloomFilter.java
@@ -19,305 +19,206 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
+import com.google.common.base.Preconditions;
import com.google.common.hash.BloomFilterStrategies.BitArray;
import java.io.Serializable;
-import javax.annotation.Nullable;
-
/**
* A Bloom filter for instances of {@code T}. A Bloom filter offers an approximate containment test
- * with one-sided error: if it claims that an element is contained in it, this might be in error,
+ * with one-sided error: if it claims that an element is contained in it, this might be in error,
* but if it claims that an element is <i>not</i> contained in it, then this is definitely true.
- *
- * <p>If you are unfamiliar with Bloom filters, this nice
- * <a href="http://llimllib.github.com/bloomfilter-tutorial/">tutorial</a> may help you understand
+ *
+ * <p>If you are unfamiliar with Bloom filters, this nice
+ * <a href="http://llimllib.github.com/bloomfilter-tutorial/">tutorial</a> may help you understand
* how they work.
- *
- * <p>The false positive probability ({@code FPP}) of a bloom filter is defined as the probability
- * that {@linkplain #mightContain(Object)} will erroneously return {@code true} for an object that
- * has not actually been put in the {@code BloomFilter}.
- *
- *
+ *
* @param <T> the type of instances that the {@code BloomFilter} accepts
- * @author Dimitris Andreou
* @author Kevin Bourrillion
+ * @author Dimitris Andreou
* @since 11.0
*/
@Beta
-public final class BloomFilter<T> implements Predicate<T>, Serializable {
+public final class BloomFilter<T> implements Serializable {
/**
* A strategy to translate T instances, to {@code numHashFunctions} bit indexes.
- *
- * <p>Implementations should be collections of pure functions (i.e. stateless).
*/
interface Strategy extends java.io.Serializable {
-
/**
- * Sets {@code numHashFunctions} bits of the given bit array, by hashing a user element.
- *
- * <p>Returns whether any bits changed as a result of this operation.
+ * Sets {@code numHashFunctions} bits of the given bit array, by hashing a user element.
*/
- <T> boolean put(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits);
-
+ <T> void put(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits);
+
/**
* Queries {@code numHashFunctions} bits of the given bit array, by hashing a user element;
- * returns {@code true} if and only if all selected bits are set.
+ * returns {@code true} if and only if all selected bits are set.
*/
<T> boolean mightContain(
T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits);
-
- /**
- * Identifier used to encode this strategy, when marshalled as part of a BloomFilter.
- * Only values in the [-128, 127] range are valid for the compact serial form.
- * Non-negative values are reserved for enums defined in BloomFilterStrategies;
- * negative values are reserved for any custom, stateful strategy we may define
- * (e.g. any kind of strategy that would depend on user input).
- */
- int ordinal();
}
-
+
/** The bit set of the BloomFilter (not necessarily power of 2!)*/
private final BitArray bits;
-
- /** Number of hashes per element */
+
+ /** Number of hashes per element */
private final int numHashFunctions;
-
+
/** The funnel to translate Ts to bytes */
private final Funnel<T> funnel;
-
+
/**
* The strategy we employ to map an element T to {@code numHashFunctions} bit indexes.
*/
private final Strategy strategy;
-
+
/**
- * Creates a BloomFilter.
+ * Creates a BloomFilter.
*/
private BloomFilter(BitArray bits, int numHashFunctions, Funnel<T> funnel,
Strategy strategy) {
- checkArgument(numHashFunctions > 0,
- "numHashFunctions (%s) must be > 0", numHashFunctions);
- checkArgument(numHashFunctions <= 255,
- "numHashFunctions (%s) must be <= 255", numHashFunctions);
+ Preconditions.checkArgument(numHashFunctions > 0, "numHashFunctions zero or negative");
this.bits = checkNotNull(bits);
this.numHashFunctions = numHashFunctions;
this.funnel = checkNotNull(funnel);
- this.strategy = checkNotNull(strategy);
- }
-
- /**
- * Creates a new {@code BloomFilter} that's a copy of this instance. The new instance is equal to
- * this instance but shares no mutable state.
- *
- * @since 12.0
- */
- public BloomFilter<T> copy() {
- return new BloomFilter<T>(bits.copy(), numHashFunctions, funnel, strategy);
+ this.strategy = strategy;
}
-
+
/**
- * Returns {@code true} if the element <i>might</i> have been put in this Bloom filter,
- * {@code false} if this is <i>definitely</i> not the case.
+ * Returns {@code true} if the element <i>might</i> have been put in this Bloom filter,
+ * {@code false} if this is <i>definitely</i> not the case.
*/
public boolean mightContain(T object) {
return strategy.mightContain(object, funnel, numHashFunctions, bits);
}
/**
- * Equivalent to {@link #mightContain}; provided only to satisfy the {@link Predicate} interface.
- * When using a reference of type {@code BloomFilter}, always invoke {@link #mightContain}
- * directly instead.
- */
- @Override public boolean apply(T input) {
- return mightContain(input);
- }
-
- /**
- * Puts an element into this {@code BloomFilter}. Ensures that subsequent invocations of
+ * Puts an element into this {@code BloomFilter}. Ensures that subsequent invocations of
* {@link #mightContain(Object)} with the same element will always return {@code true}.
- *
- * @return true if the bloom filter's bits changed as a result of this operation. If the bits
- * changed, this is <i>definitely</i> the first time {@code object} has been added to the
- * filter. If the bits haven't changed, this <i>might</i> be the first time {@code object}
- * has been added to the filter. Note that {@code put(t)} always returns the
- * <i>opposite</i> result to what {@code mightContain(t)} would have returned at the time
- * it is called."
- * @since 12.0 (present in 11.0 with {@code void} return type})
- */
- public boolean put(T object) {
- return strategy.put(object, funnel, numHashFunctions, bits);
- }
-
- /**
- * Returns the probability that {@linkplain #mightContain(Object)} will erroneously return
- * {@code true} for an object that has not actually been put in the {@code BloomFilter}.
- *
- * <p>Ideally, this number should be close to the {@code fpp} parameter
- * passed in {@linkplain #create(Funnel, int, double)}, or smaller. If it is
- * significantly higher, it is usually the case that too many elements (more than
- * expected) have been put in the {@code BloomFilter}, degenerating it.
- *
- * @since 14.0 (since 11.0 as expectedFalsePositiveProbability())
- */
- public double expectedFpp() {
- // You down with FPP? (Yeah you know me!) Who's down with FPP? (Every last homie!)
- return Math.pow((double) bits.bitCount() / bits.size(), numHashFunctions);
- }
-
- /**
- * @deprecated Use {@link #expectedFpp} instead.
*/
- @Deprecated
- public double expectedFalsePositiveProbability() {
- return expectedFpp();
+ public void put(T object) {
+ strategy.put(object, funnel, numHashFunctions, bits);
}
-
- @Override
- public boolean equals(@Nullable Object object) {
- if (object == this) {
- return true;
- }
- if (object instanceof BloomFilter) {
- BloomFilter<?> that = (BloomFilter<?>) object;
- return this.numHashFunctions == that.numHashFunctions
- && this.funnel.equals(that.funnel)
- && this.bits.equals(that.bits)
- && this.strategy.equals(that.strategy);
- }
- return false;
+
+ @VisibleForTesting int getHashCount() {
+ return numHashFunctions;
}
-
- @Override
- public int hashCode() {
- return Objects.hashCode(numHashFunctions, funnel, strategy, bits);
+
+ @VisibleForTesting double computeExpectedFalsePositiveRate(int insertions) {
+ return Math.pow(
+ 1 - Math.exp(-numHashFunctions * ((double) insertions / (bits.size()))),
+ numHashFunctions);
}
-
+
/**
- * Creates a {@code Builder} of a {@link BloomFilter BloomFilter<T>}, with the expected number
+ * Creates a {@code Builder} of a {@link BloomFilter BloomFilter<T>}, with the expected number
* of insertions and expected false positive probability.
- *
- * <p>Note that overflowing a {@code BloomFilter} with significantly more elements
+ *
+ * <p>Note that overflowing a {@code BloomFilter} with significantly more elements
* than specified, will result in its saturation, and a sharp deterioration of its
* false positive probability.
- *
- * <p>The constructed {@code BloomFilter<T>} will be serializable if the provided
+ *
+ * <p>The constructed {@code BloomFilter<T>} will be serializable if the provided
* {@code Funnel<T>} is.
- *
- * <p>It is recommended the funnel is implemented as a Java enum. This has the benefit of ensuring
- * proper serialization and deserialization, which is important since {@link #equals} also relies
- * on object identity of funnels.
- *
+ *
* @param funnel the funnel of T's that the constructed {@code BloomFilter<T>} will use
- * @param expectedInsertions the number of expected insertions to the constructed
- * {@code BloomFilter<T>}; must be positive
- * @param fpp the desired false positive probability (must be positive and less than 1.0)
- * @return a {@code BloomFilter}
+ * @param expectedInsertions the number of expected insertions to the constructed
+ * {@code BloomFilter<T>}; must be positive
+ * @param falsePositiveProbability the desired false positive probability (must be positive and
+ * less than 1.0)
+ * @return a {@code Builder}
*/
- public static <T> BloomFilter<T> create(
- Funnel<T> funnel, int expectedInsertions /* n */, double fpp) {
+ public static <T> BloomFilter<T> create(Funnel<T> funnel, int expectedInsertions /* n */,
+ double falsePositiveProbability) {
checkNotNull(funnel);
- checkArgument(expectedInsertions >= 0, "Expected insertions (%s) must be >= 0",
- expectedInsertions);
- checkArgument(fpp > 0.0, "False positive probability (%s) must be > 0.0", fpp);
- checkArgument(fpp < 1.0, "False positive probability (%s) must be < 1.0", fpp);
- if (expectedInsertions == 0) {
- expectedInsertions = 1;
- }
- /*
- * TODO(user): Put a warning in the javadoc about tiny fpp values,
+ checkArgument(expectedInsertions > 0, "Expected insertions must be positive");
+ checkArgument(falsePositiveProbability > 0.0 & falsePositiveProbability < 1.0,
+ "False positive probability in (0.0, 1.0)");
+ /*
+ * andreou: I wanted to put a warning in the javadoc about tiny fpp values,
* since the resulting size is proportional to -log(p), but there is not
* much of a point after all, e.g. optimalM(1000, 0.0000000000000001) = 76680
* which is less that 10kb. Who cares!
*/
- long numBits = optimalNumOfBits(expectedInsertions, fpp);
+ int numBits = optimalNumOfBits(expectedInsertions, falsePositiveProbability);
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits);
- try {
- return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel,
- BloomFilterStrategies.MURMUR128_MITZ_32);
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Could not create BloomFilter of " + numBits + " bits", e);
- }
+ return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel,
+ BloomFilterStrategies.MURMUR128_MITZ_32);
}
-
+
/**
- * Creates a {@code Builder} of a {@link BloomFilter BloomFilter<T>}, with the expected number
+ * Creates a {@code Builder} of a {@link BloomFilter BloomFilter<T>}, with the expected number
* of insertions, and a default expected false positive probability of 3%.
- *
- * <p>Note that overflowing a {@code BloomFilter} with significantly more elements
+ *
+ * <p>Note that overflowing a {@code BloomFilter} with significantly more elements
* than specified, will result in its saturation, and a sharp deterioration of its
* false positive probability.
- *
- * <p>The constructed {@code BloomFilter<T>} will be serializable if the provided
+ *
+ * <p>The constructed {@code BloomFilter<T>} will be serializable if the provided
* {@code Funnel<T>} is.
- *
+ *
* @param funnel the funnel of T's that the constructed {@code BloomFilter<T>} will use
- * @param expectedInsertions the number of expected insertions to the constructed
- * {@code BloomFilter<T>}; must be positive
- * @return a {@code BloomFilter}
+ * @param expectedInsertions the number of expected insertions to the constructed
+ * {@code BloomFilter<T>}; must be positive
+ * @return a {@code Builder}
*/
public static <T> BloomFilter<T> create(Funnel<T> funnel, int expectedInsertions /* n */) {
- return create(funnel, expectedInsertions, 0.03); // FYI, for 3%, we always get 5 hash functions
+ return create(funnel, expectedInsertions, 0.03); // FYI, for 3%, we always get 5 hash functions
}
-
+
/*
* Cheat sheet:
- *
+ *
* m: total bits
* n: expected insertions
* b: m/n, bits per insertion
* p: expected false positive probability
- *
+ *
* 1) Optimal k = b * ln2
* 2) p = (1 - e ^ (-kn/m))^k
* 3) For optimal k: p = 2 ^ (-k) ~= 0.6185^b
* 4) For optimal k: m = -nlnp / ((ln2) ^ 2)
*/
-
+
+ private static final double LN2 = Math.log(2);
+ private static final double LN2_SQUARED = LN2 * LN2;
+
/**
- * Computes the optimal k (number of hashes per element inserted in Bloom filter), given the
+ * Computes the optimal k (number of hashes per element inserted in Bloom filter), given the
* expected insertions and total number of bits in the Bloom filter.
- *
+ *
* See http://en.wikipedia.org/wiki/File:Bloom_filter_fp_probability.svg for the formula.
- *
+ *
* @param n expected insertions (must be positive)
* @param m total number of bits in Bloom filter (must be positive)
*/
- @VisibleForTesting
- static int optimalNumOfHashFunctions(long n, long m) {
- return Math.max(1, (int) Math.round(m / n * Math.log(2)));
+ @VisibleForTesting static int optimalNumOfHashFunctions(int n, int m) {
+ return Math.max(1, (int) Math.round(m / n * LN2));
}
-
+
/**
- * Computes m (total bits of Bloom filter) which is expected to achieve, for the specified
+ * Computes m (total bits of Bloom filter) which is expected to achieve, for the specified
* expected insertions, the required false positive probability.
- *
+ *
* See http://en.wikipedia.org/wiki/Bloom_filter#Probability_of_false_positives for the formula.
- *
+ *
* @param n expected insertions (must be positive)
* @param p false positive rate (must be 0 < p < 1)
*/
- @VisibleForTesting
- static long optimalNumOfBits(long n, double p) {
- if (p == 0) {
- p = Double.MIN_VALUE;
- }
- return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));
+ @VisibleForTesting static int optimalNumOfBits(int n, double p) {
+ return (int) (-n * Math.log(p) / LN2_SQUARED);
}
-
+
private Object writeReplace() {
return new SerialForm<T>(this);
}
-
+
private static class SerialForm<T> implements Serializable {
final long[] data;
final int numHashFunctions;
final Funnel<T> funnel;
final Strategy strategy;
-
+
SerialForm(BloomFilter<T> bf) {
this.data = bf.bits.data;
this.numHashFunctions = bf.numHashFunctions;
diff --git a/guava/src/com/google/common/hash/BloomFilterStrategies.java b/guava/src/com/google/common/hash/BloomFilterStrategies.java
index 0a4fa79..8c215e5 100644
--- a/guava/src/com/google/common/hash/BloomFilterStrategies.java
+++ b/guava/src/com/google/common/hash/BloomFilterStrategies.java
@@ -1,37 +1,20 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.hash;
import static com.google.common.base.Preconditions.checkArgument;
-import com.google.common.math.LongMath;
-import com.google.common.primitives.Ints;
+import com.google.common.math.IntMath;
import java.math.RoundingMode;
-import java.util.Arrays;
/**
- * Collections of strategies of generating the k * log(M) bits required for an element to
- * be mapped to a BloomFilter of M bits and k hash functions. These
+ * Collections of strategies of generating the {@code k * log(M)} bits required for an element to
+ * be mapped to a {@link BloomFilter} of {@code M} bits and {@code k} hash functions. These
* strategies are part of the serialized form of the Bloom filters that use them, thus they must be
* preserved as is (no updates allowed, only introduction of new versions).
*
- * Important: the order of the constants cannot change, and they cannot be deleted - we depend
- * on their ordinal for BloomFilter serialization.
- *
- * @author Dimitris Andreou
+ * @author andreou@google.com (Dimitris Andreou)
*/
enum BloomFilterStrategies implements BloomFilter.Strategy {
/**
@@ -40,25 +23,25 @@ enum BloomFilterStrategies implements BloomFilter.Strategy {
* performance of a Bloom filter (yet only needs two 32bit hash functions).
*/
MURMUR128_MITZ_32() {
- @Override public <T> boolean put(T object, Funnel<? super T> funnel,
+ @Override public <T> void put(T object, Funnel<? super T> funnel,
int numHashFunctions, BitArray bits) {
- long hash64 = Hashing.murmur3_128().hashObject(object, funnel).asLong();
+ // TODO(user): when the murmur's shortcuts are implemented, update this code
+ long hash64 = Hashing.murmur3_128().newHasher().putObject(object, funnel).hash().asLong();
int hash1 = (int) hash64;
int hash2 = (int) (hash64 >>> 32);
- boolean bitsChanged = false;
for (int i = 1; i <= numHashFunctions; i++) {
int nextHash = hash1 + i * hash2;
if (nextHash < 0) {
nextHash = ~nextHash;
}
- bitsChanged |= bits.set(nextHash % bits.size());
+ // up to here, the code is identical with the next method
+ bits.set(nextHash % bits.size());
}
- return bitsChanged;
}
@Override public <T> boolean mightContain(T object, Funnel<? super T> funnel,
int numHashFunctions, BitArray bits) {
- long hash64 = Hashing.murmur3_128().hashObject(object, funnel).asLong();
+ long hash64 = Hashing.murmur3_128().newHasher().putObject(object, funnel).hash().asLong();
int hash1 = (int) hash64;
int hash2 = (int) (hash64 >>> 32);
for (int i = 1; i <= numHashFunctions; i++) {
@@ -66,6 +49,7 @@ enum BloomFilterStrategies implements BloomFilter.Strategy {
if (nextHash < 0) {
nextHash = ~nextHash;
}
+ // up to here, the code is identical with the previous method
if (!bits.get(nextHash % bits.size())) {
return false;
}
@@ -74,34 +58,21 @@ enum BloomFilterStrategies implements BloomFilter.Strategy {
}
};
- // Note: We use this instead of java.util.BitSet because we need access to the long[] data field
static class BitArray {
final long[] data;
- int bitCount;
- BitArray(long bits) {
- this(new long[Ints.checkedCast(LongMath.divide(bits, 64, RoundingMode.CEILING))]);
+ BitArray(int bits) {
+ this(new long[IntMath.divide(bits, 64, RoundingMode.CEILING)]);
}
// Used by serialization
BitArray(long[] data) {
checkArgument(data.length > 0, "data length is zero!");
this.data = data;
- int bitCount = 0;
- for (long value : data) {
- bitCount += Long.bitCount(value);
- }
- this.bitCount = bitCount;
}
- /** Returns true if the bit changed value. */
- boolean set(int index) {
- if (!get(index)) {
- data[index >> 6] |= (1L << index);
- bitCount++;
- return true;
- }
- return false;
+ void set(int index) {
+ data[index >> 6] |= (1L << index);
}
boolean get(int index) {
@@ -112,26 +83,5 @@ enum BloomFilterStrategies implements BloomFilter.Strategy {
int size() {
return data.length * Long.SIZE;
}
-
- /** Number of set bits (1s) */
- int bitCount() {
- return bitCount;
- }
-
- BitArray copy() {
- return new BitArray(data.clone());
- }
-
- @Override public boolean equals(Object o) {
- if (o instanceof BitArray) {
- BitArray bitArray = (BitArray) o;
- return Arrays.equals(data, bitArray.data);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return Arrays.hashCode(data);
- }
}
}
diff --git a/guava/src/com/google/common/hash/ChecksumHashFunction.java b/guava/src/com/google/common/hash/ChecksumHashFunction.java
deleted file mode 100644
index bbcc00f..0000000
--- a/guava/src/com/google/common/hash/ChecksumHashFunction.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.hash;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.base.Supplier;
-
-import java.io.Serializable;
-import java.util.zip.Checksum;
-
-/**
- * {@link HashFunction} adapter for {@link Checksum} instances.
- *
- * @author Colin Decker
- */
-final class ChecksumHashFunction extends AbstractStreamingHashFunction implements Serializable {
-
- private final Supplier<? extends Checksum> checksumSupplier;
- private final int bits;
- private final String toString;
-
- ChecksumHashFunction(Supplier<? extends Checksum> checksumSupplier, int bits, String toString) {
- this.checksumSupplier = checkNotNull(checksumSupplier);
- checkArgument(bits == 32 || bits == 64, "bits (%s) must be either 32 or 64", bits);
- this.bits = bits;
- this.toString = checkNotNull(toString);
- }
-
- @Override
- public int bits() {
- return bits;
- }
-
- @Override
- public Hasher newHasher() {
- return new ChecksumHasher(checksumSupplier.get());
- }
-
- @Override
- public String toString() {
- return toString;
- }
-
- /**
- * Hasher that updates a checksum.
- */
- private final class ChecksumHasher extends AbstractByteHasher {
-
- private final Checksum checksum;
-
- private ChecksumHasher(Checksum checksum) {
- this.checksum = checkNotNull(checksum);
- }
-
- @Override
- protected void update(byte b) {
- checksum.update(b);
- }
-
- @Override
- protected void update(byte[] bytes, int off, int len) {
- checksum.update(bytes, off, len);
- }
-
- @Override
- public HashCode hash() {
- long value = checksum.getValue();
- if (bits == 32) {
- /*
- * The long returned from a 32-bit Checksum will have all 0s for its second word, so the
- * cast won't lose any information and is necessary to return a HashCode of the correct
- * size.
- */
- return HashCodes.fromInt((int) value);
- } else {
- return HashCodes.fromLong(value);
- }
- }
- }
-
- private static final long serialVersionUID = 0L;
-}
diff --git a/guava/src/com/google/common/hash/Funnel.java b/guava/src/com/google/common/hash/Funnel.java
index 6d62648..61cff7b 100644
--- a/guava/src/com/google/common/hash/Funnel.java
+++ b/guava/src/com/google/common/hash/Funnel.java
@@ -16,37 +16,18 @@ package com.google.common.hash;
import com.google.common.annotations.Beta;
-import java.io.Serializable;
-
/**
- * An object which can send data from an object of type {@code T} into a {@code PrimitiveSink}.
- *
- * <p>Note that serialization of {@linkplain BloomFilter bloom filters} requires the proper
- * serialization of funnels. When possible, it is recommended that funnels be implemented as a
- * single-element enum to maintain serialization guarantees. See Effective Java (2nd Edition),
- * Item 3: "Enforce the singleton property with a private constructor or an enum type". For example:
- * <pre> {@code
- * public enum PersonFunnel implements Funnel<Person> {
- * INSTANCE;
- * public void funnel(Person person, PrimitiveSink into) {
- * into.putString(person.getFirstName())
- * .putString(person.getLastName())
- * .putInt(person.getAge());
- * }
- * }}</pre>
+ * An object which can send data from an object of type {@code T} into a {@code Sink}.
*
* @author Dimitris Andreou
* @since 11.0
*/
@Beta
-public interface Funnel<T> extends Serializable {
-
+public interface Funnel<T> {
/**
* Sends a stream of data from the {@code from} object into the sink {@code into}. There
* is no requirement that this data be complete enough to fully reconstitute the object
* later.
- *
- * @since 12.0 (in Guava 11.0, {@code PrimitiveSink} was named {@code Sink})
*/
- void funnel(T from, PrimitiveSink into);
+ void funnel(T from, Sink into);
}
diff --git a/guava/src/com/google/common/hash/Funnels.java b/guava/src/com/google/common/hash/Funnels.java
index 7f76202..2cb04f4 100644
--- a/guava/src/com/google/common/hash/Funnels.java
+++ b/guava/src/com/google/common/hash/Funnels.java
@@ -15,13 +15,10 @@
package com.google.common.hash;
import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-import java.io.OutputStream;
/**
* Funnels for common types. All implementations are serializable.
- *
+ *
* @author Dimitris Andreou
* @since 11.0
*/
@@ -39,7 +36,7 @@ public final class Funnels {
private enum ByteArrayFunnel implements Funnel<byte[]> {
INSTANCE;
- public void funnel(byte[] from, PrimitiveSink into) {
+ public void funnel(byte[] from, Sink into) {
into.putBytes(from);
}
@@ -58,7 +55,7 @@ public final class Funnels {
private enum StringFunnel implements Funnel<CharSequence> {
INSTANCE;
- public void funnel(CharSequence from, PrimitiveSink into) {
+ public void funnel(CharSequence from, Sink into) {
into.putString(from);
}
@@ -66,83 +63,4 @@ public final class Funnels {
return "Funnels.stringFunnel()";
}
}
-
- /**
- * Returns a funnel for integers.
- *
- * @since 13.0
- */
- public static Funnel<Integer> integerFunnel() {
- return IntegerFunnel.INSTANCE;
- }
-
- private enum IntegerFunnel implements Funnel<Integer> {
- INSTANCE;
-
- public void funnel(Integer from, PrimitiveSink into) {
- into.putInt(from);
- }
-
- @Override public String toString() {
- return "Funnels.integerFunnel()";
- }
- }
-
- /**
- * Returns a funnel for longs.
- *
- * @since 13.0
- */
- public static Funnel<Long> longFunnel() {
- return LongFunnel.INSTANCE;
- }
-
- private enum LongFunnel implements Funnel<Long> {
- INSTANCE;
-
- public void funnel(Long from, PrimitiveSink into) {
- into.putLong(from);
- }
-
- @Override public String toString() {
- return "Funnels.longFunnel()";
- }
- }
-
- /**
- * Wraps a {@code PrimitiveSink} as an {@link OutputStream}, so it is easy to
- * {@link Funnel#funnel funnel} an object to a {@code PrimitiveSink}
- * if there is already a way to write the contents of the object to an {@code OutputStream}.
- *
- * <p>The {@code close} and {@code flush} methods of the returned {@code OutputStream}
- * do nothing, and no method throws {@code IOException}.
- *
- * @since 13.0
- */
- public static OutputStream asOutputStream(PrimitiveSink sink) {
- return new SinkAsStream(sink);
- }
-
- private static class SinkAsStream extends OutputStream {
- final PrimitiveSink sink;
- SinkAsStream(PrimitiveSink sink) {
- this.sink = Preconditions.checkNotNull(sink);
- }
-
- @Override public void write(int b) {
- sink.putByte((byte) b);
- }
-
- @Override public void write(byte[] bytes) {
- sink.putBytes(bytes);
- }
-
- @Override public void write(byte[] bytes, int off, int len) {
- sink.putBytes(bytes, off, len);
- }
-
- @Override public String toString() {
- return "Funnels.asOutputStream(" + sink + ")";
- }
- }
}
diff --git a/guava/src/com/google/common/hash/HashCode.java b/guava/src/com/google/common/hash/HashCode.java
index f955699..ecd8706 100644
--- a/guava/src/com/google/common/hash/HashCode.java
+++ b/guava/src/com/google/common/hash/HashCode.java
@@ -20,8 +20,6 @@ import com.google.common.primitives.Ints;
import java.security.MessageDigest;
-import javax.annotation.Nullable;
-
/**
* An immutable hash code of arbitrary bit length.
*
@@ -35,8 +33,6 @@ public abstract class HashCode {
/**
* Returns the first four bytes of {@linkplain #asBytes() this hashcode's bytes}, converted to
* an {@code int} value in little-endian order.
- *
- * @throws IllegalStateException if {@code bits() < 32}
*/
public abstract int asInt();
@@ -49,15 +45,6 @@ public abstract class HashCode {
public abstract long asLong();
/**
- * If this hashcode has enough bits, returns {@code asLong()}, otherwise returns a {@code long}
- * value with {@code asInt()} as the least-significant four bytes and {@code 0x00} as
- * each of the most-significant four bytes.
- *
- * @since 14.0 (since 11.0 as {@code Hashing.padToLong(HashCode)})
- */
- public abstract long padToLong();
-
- /**
* Returns the value of this hash code as a byte array. The caller may modify the byte array;
* changes to it will <i>not</i> be reflected in this {@code HashCode} object or any other arrays
* returned by this method.
@@ -83,11 +70,11 @@ public abstract class HashCode {
}
/**
- * Returns the number of bits in this hash code; a positive multiple of 8.
+ * Returns the number of bits in this hash code; a positive multiple of 32.
*/
public abstract int bits();
- @Override public boolean equals(@Nullable Object object) {
+ @Override public boolean equals(Object object) {
if (object instanceof HashCode) {
HashCode that = (HashCode) object;
// Undocumented: this is a non-short-circuiting equals(), in case this is a cryptographic
@@ -121,6 +108,7 @@ public abstract class HashCode {
*/
@Override public String toString() {
byte[] bytes = asBytes();
+ // TODO(user): Use c.g.common.base.ByteArrays once it is open sourced.
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]);
diff --git a/guava/src/com/google/common/hash/HashCodes.java b/guava/src/com/google/common/hash/HashCodes.java
index b911c28..b6101a5 100644
--- a/guava/src/com/google/common/hash/HashCodes.java
+++ b/guava/src/com/google/common/hash/HashCodes.java
@@ -14,35 +14,23 @@
package com.google.common.hash;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.Beta;
-import com.google.common.primitives.UnsignedInts;
-
-import java.io.Serializable;
-
/**
- * Static factories for creating {@link HashCode} instances; most users should never have to use
- * this. All returned instances are {@link Serializable}.
- *
- * @author Dimitris Andreou
- * @since 12.0
+ * Static factories for {@link HashCode} instances.
+ *
+ * @author andreou@google.com (Dimitris Andreou)
*/
-@Beta
-public final class HashCodes {
- private HashCodes() {}
-
+final class HashCodes {
+ private HashCodes() { }
+
/**
* Creates a 32-bit {@code HashCode}, of which the bytes will form the passed int, interpreted
* in little endian order.
*/
- public static HashCode fromInt(int hash) {
+ static HashCode fromInt(int hash) {
return new IntHashCode(hash);
}
- private static final class IntHashCode extends HashCode implements Serializable {
+ private static class IntHashCode extends HashCode {
final int hash;
IntHashCode(int hash) {
@@ -68,24 +56,17 @@ public final class HashCodes {
@Override public long asLong() {
throw new IllegalStateException("this HashCode only has 32 bits; cannot create a long");
}
-
- @Override
- public long padToLong() {
- return UnsignedInts.toLong(hash);
- }
-
- private static final long serialVersionUID = 0;
}
/**
* Creates a 64-bit {@code HashCode}, of which the bytes will form the passed long, interpreted
* in little endian order.
*/
- public static HashCode fromLong(long hash) {
+ static HashCode fromLong(long hash) {
return new LongHashCode(hash);
}
- private static final class LongHashCode extends HashCode implements Serializable {
+ private static class LongHashCode extends HashCode {
final long hash;
LongHashCode(long hash) {
@@ -115,37 +96,22 @@ public final class HashCodes {
@Override public long asLong() {
return hash;
}
-
- @Override
- public long padToLong() {
- return hash;
- }
-
- private static final long serialVersionUID = 0;
}
-
- /**
- * Creates a {@code HashCode} from a byte array. The array is defensively copied to preserve
- * the immutability contract of {@code HashCode}. The array cannot be empty.
- */
- public static HashCode fromBytes(byte[] bytes) {
- checkArgument(bytes.length >= 1, "A HashCode must contain at least 1 byte.");
- return fromBytesNoCopy(bytes.clone());
- }
-
+
/**
* Creates a {@code HashCode} from a byte array. The array is <i>not</i> copied defensively,
* so it must be handed-off so as to preserve the immutability contract of {@code HashCode}.
+ * The array must be at least of length 4 (not checked).
*/
- static HashCode fromBytesNoCopy(byte[] bytes) {
+ static HashCode fromBytes(byte[] bytes) {
return new BytesHashCode(bytes);
}
- private static final class BytesHashCode extends HashCode implements Serializable {
+ private static class BytesHashCode extends HashCode {
final byte[] bytes;
BytesHashCode(byte[] bytes) {
- this.bytes = checkNotNull(bytes);
+ this.bytes = bytes;
}
@Override public int bits() {
@@ -157,8 +123,6 @@ public final class HashCodes {
}
@Override public int asInt() {
- checkState(bytes.length >= 4,
- "HashCode#asInt() requires >= 4 bytes (it only has %s bytes).", bytes.length);
return (bytes[0] & 0xFF)
| ((bytes[1] & 0xFF) << 8)
| ((bytes[2] & 0xFF) << 16)
@@ -166,8 +130,10 @@ public final class HashCodes {
}
@Override public long asLong() {
- checkState(bytes.length >= 8,
- "HashCode#asLong() requires >= 8 bytes (it only has %s bytes).", bytes.length);
+ if (bytes.length < 8) {
+ // Checking this to throw the correct type of exception
+ throw new IllegalStateException("Not enough bytes");
+ }
return (bytes[0] & 0xFFL)
| ((bytes[1] & 0xFFL) << 8)
| ((bytes[2] & 0xFFL) << 16)
@@ -177,25 +143,5 @@ public final class HashCodes {
| ((bytes[6] & 0xFFL) << 48)
| ((bytes[7] & 0xFFL) << 56);
}
-
- @Override
- public long padToLong() {
- return (bytes.length < 8) ? UnsignedInts.toLong(asInt()) : asLong();
- }
-
- @Override
- public int hashCode() {
- if (bytes.length >= 4) {
- return asInt();
- } else {
- int val = (bytes[0] & 0xFF);
- for (int i = 1; i < bytes.length; i++) {
- val |= ((bytes[i] & 0xFF) << (i * 8));
- }
- return val;
- }
- }
-
- private static final long serialVersionUID = 0;
}
}
diff --git a/guava/src/com/google/common/hash/HashFunction.java b/guava/src/com/google/common/hash/HashFunction.java
index 0386261..ba3c992 100644
--- a/guava/src/com/google/common/hash/HashFunction.java
+++ b/guava/src/com/google/common/hash/HashFunction.java
@@ -40,8 +40,7 @@ import java.nio.charset.Charset;
* represents a hash code as an instance of {@link HashCode}.
*
* <li><b>pure function:</b> the value produced must depend only on the input bytes, in
- * the order they appear. Input data is never modified. {@link HashFunction} instances
- * should always be stateless, and therefore thread-safe.
+ * the order they appear. Input data is never modified.
*
* <li><b>collision-averse:</b> while it can't be helped that a hash function will
* sometimes produce the same hash code for distinct inputs (a "collision"), every
@@ -143,21 +142,12 @@ public interface HashFunction {
Hasher newHasher();
/**
- * Begins a new hash code computation as {@link #newHasher()}, but provides a hint of the
+ * Begins a new hash code computation as {@link #newHasher()}, but provides a hint of the
* expected size of the input (in bytes). This is only important for non-streaming hash
- * functions (hash functions that need to buffer their whole input before processing any
- * of it).
+ * functions (hash functions that need to buffer their whole input before processing any
+ * of it).
*/
- Hasher newHasher(int expectedInputSize);
-
- /**
- * Shortcut for {@code newHasher().putInt(input).hash()}; returns the hash code for the given
- * {@code int} value, interpreted in little-endian byte order. The implementation <i>might</i>
- * perform better than its longhand equivalent, but should not perform worse.
- *
- * @since 12.0
- */
- HashCode hashInt(int input);
+ Hasher newHasher(int expectedInputSize);
/**
* Shortcut for {@code newHasher().putLong(input).hash()}; returns the hash code for the
@@ -175,9 +165,9 @@ public interface HashFunction {
/**
* Shortcut for {@code newHasher().putBytes(input, off, len).hash()}. The implementation
- * <i>might</i> perform better than its longhand equivalent, but should not perform
- * worse.
- *
+ * <i>might</i> perform better than its longhand equivalent, but should not perform
+ * worse.
+ *
* @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > bytes.length}
* or {@code len < 0}
*/
@@ -200,14 +190,6 @@ public interface HashFunction {
HashCode hashString(CharSequence input, Charset charset);
/**
- * Shortcut for {@code newHasher().putObject(instance, funnel).hash()}. The implementation
- * <i>might</i> perform better than its longhand equivalent, but should not perform worse.
- *
- * @since 14.0
- */
- <T> HashCode hashObject(T instance, Funnel<? super T> funnel);
-
- /**
* Returns the number of bits (a multiple of 32) that each hash code produced by this
* hash function has.
*/
diff --git a/guava/src/com/google/common/hash/Hasher.java b/guava/src/com/google/common/hash/Hasher.java
index e7adc82..b10d536 100644
--- a/guava/src/com/google/common/hash/Hasher.java
+++ b/guava/src/com/google/common/hash/Hasher.java
@@ -19,62 +19,40 @@ import com.google.common.annotations.Beta;
import java.nio.charset.Charset;
/**
- * A {@link PrimitiveSink} that can compute a hash code after reading the input. Each hasher should
- * translate all multibyte values ({@link #putInt(int)}, {@link #putLong(long)}, etc) to bytes
+ * A {@link Sink} that can compute a hash code after reading the input. Each hasher should
+ * translate all multibyte values ({@link #putInt(int)}, {@link #putLong(long)}, etc) to bytes
* in little-endian order.
*
- * <p>The result of calling any methods after calling {@link #hash} is undefined.
- *
- * <p><b>Warning:</b> Chunks of data that are put into the {@link Hasher} are not delimited.
- * The resulting {@link HashCode} is dependent only on the bytes inserted, and the order in which
- * they were inserted, not how those bytes were chunked into discrete put() operations. For example,
- * the following three expressions all generate colliding hash codes: <pre> {@code
- *
- * newHasher().putString("ab").putString("c").hash()
- * newHasher().putString("a").putString("bc").hash()
- * newHasher().putChar('a').putChar('b').putChar('c').hash()}</pre>
- *
- * If you wish to avoid this, you should either prepend or append the size of each chunk.
- * For example:
- * <pre> {@code
- * newHasher().putInt(s1.length()).putString(s1).putInt(s2.length()).putString(s2).hash()}</pre>
- *
* @author Kevin Bourrillion
* @since 11.0
*/
@Beta
-public interface Hasher extends PrimitiveSink {
+public interface Hasher extends Sink {
@Override Hasher putByte(byte b);
@Override Hasher putBytes(byte[] bytes);
@Override Hasher putBytes(byte[] bytes, int off, int len);
@Override Hasher putShort(short s);
@Override Hasher putInt(int i);
@Override Hasher putLong(long l);
-
/**
* Equivalent to {@code putInt(Float.floatToRawIntBits(f))}.
*/
@Override Hasher putFloat(float f);
-
/**
* Equivalent to {@code putLong(Double.doubleToRawLongBits(d))}.
*/
@Override Hasher putDouble(double d);
-
/**
* Equivalent to {@code putByte(b ? (byte) 1 : (byte) 0)}.
*/
@Override Hasher putBoolean(boolean b);
@Override Hasher putChar(char c);
-
/**
- * Equivalent to processing each {@code char} value in the {@code CharSequence}, in order.
- * The input must not be updated while this method is in progress.
+ * Equivalent to {@code putBytes(charSequence.toString().getBytes(Charsets.UTF_16LE)}.
*/
@Override Hasher putString(CharSequence charSequence);
-
/**
- * Equivalent to {@code putBytes(charSequence.toString().getBytes(charset))}.
+ * Equivalent to {@code putBytes(charSequence.toString().getBytes(charset)}.
*/
@Override Hasher putString(CharSequence charSequence, Charset charset);
@@ -85,7 +63,7 @@ public interface Hasher extends PrimitiveSink {
/**
* Computes a hash code based on the data that have been provided to this hasher. The result is
- * unspecified if this method is called more than once on the same instance.
+ * unspecified if this method is called more than once on the same instance.
*/
HashCode hash();
}
diff --git a/guava/src/com/google/common/hash/Hashing.java b/guava/src/com/google/common/hash/Hashing.java
index 0e81d0e..f2582c7 100644
--- a/guava/src/com/google/common/hash/Hashing.java
+++ b/guava/src/com/google/common/hash/Hashing.java
@@ -17,19 +17,15 @@ package com.google.common.hash;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Supplier;
+import com.google.common.primitives.UnsignedInts;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.util.Iterator;
-import java.util.zip.Adler32;
-import java.util.zip.CRC32;
-import java.util.zip.Checksum;
/**
- * Static methods to obtain {@link HashFunction} instances, and other static hashing-related
- * utilities.
+ * Static methods to obtain {@link HashFunction} instances, and other static
+ * hashing-related utilities.
*
* @author Kevin Bourrillion
* @author Dimitris Andreou
@@ -41,27 +37,11 @@ public final class Hashing {
private Hashing() {}
/**
- * Used to randomize {@link #goodFastHash} instances, so that programs which persist anything
- * dependent on hashcodes of those, will fail sooner than later.
- */
- private static final int GOOD_FAST_HASH_SEED = (int) System.currentTimeMillis();
-
- // Used by goodFastHash when minimumBits == 32.
- private static final HashFunction GOOD_FAST_HASH_FUNCTION_32 = murmur3_32(GOOD_FAST_HASH_SEED);
-
- // Used by goodFastHash when 32 < minimumBits <= 128.
- private static final HashFunction GOOD_FAST_HASH_FUNCTION_128 = murmur3_128(GOOD_FAST_HASH_SEED);
-
- /**
* Returns a general-purpose, <b>non-cryptographic-strength</b>, streaming hash function that
* produces hash codes of length at least {@code minimumBits}. Users without specific
* compatibility requirements and who do not persist the hash codes are encouraged to
* choose this hash function.
*
- * <p>Repeated calls to {@link #goodFastHash} with the same {@code minimumBits} value will
- * return {@link HashFunction} instances with identical behavior (but not necessarily the
- * same instance) for the duration of the current virtual machine.
- *
* <p><b>Warning: the implementation is unspecified and is subject to change.</b>
*
* @throws IllegalArgumentException if {@code minimumBits} is not positive
@@ -70,31 +50,24 @@ public final class Hashing {
int bits = checkPositiveAndMakeMultipleOf32(minimumBits);
if (bits == 32) {
- return GOOD_FAST_HASH_FUNCTION_32;
- }
- if (bits <= 128) {
- return GOOD_FAST_HASH_FUNCTION_128;
- }
-
- // Otherwise, join together some 128-bit murmur3s
- int hashFunctionsNeeded = (bits + 127) / 128;
- HashFunction[] hashFunctions = new HashFunction[hashFunctionsNeeded];
- hashFunctions[0] = GOOD_FAST_HASH_FUNCTION_128;
- int seed = GOOD_FAST_HASH_SEED;
- for (int i = 1; i < hashFunctionsNeeded; i++) {
- seed += 1500450271; // a prime; shouldn't matter
- hashFunctions[i] = murmur3_128(seed);
+ return murmur3_32();
+ } else if (bits <= 128) {
+ return murmur3_128();
+ } else {
+ // Join some 128-bit murmur3s
+ int hashFunctionsNeeded = (bits + 127) / 128;
+ HashFunction[] hashFunctions = new HashFunction[hashFunctionsNeeded];
+ for (int i = 0; i < hashFunctionsNeeded; i++) {
+ hashFunctions[i] = murmur3_128(i * 1500450271 /* a prime; shouldn't matter */);
+ }
+ return new ConcatenatedHashFunction(hashFunctions);
}
- return new ConcatenatedHashFunction(hashFunctions);
}
/**
* Returns a hash function implementing the
- * <a href="http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp">
- * 32-bit murmur3 algorithm, x86 variant</a> (little-endian variant),
- * using the given seed value.
- *
- * <p>The exact C++ equivalent is the MurmurHash3_x86_32 function (Murmur3A).
+ * <a href="http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp">32-bit murmur3
+ * algorithm</a> (little-endian variant), using the given seed value.
*/
public static HashFunction murmur3_32(int seed) {
return new Murmur3_32HashFunction(seed);
@@ -102,25 +75,20 @@ public final class Hashing {
/**
* Returns a hash function implementing the
- * <a href="http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp">
- * 32-bit murmur3 algorithm, x86 variant</a> (little-endian variant),
- * using a seed value of zero.
- *
- * <p>The exact C++ equivalent is the MurmurHash3_x86_32 function (Murmur3A).
+ * <a href="http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp">32-bit murmur3
+ * algorithm</a> (little-endian variant), using a seed value of zero.
*/
public static HashFunction murmur3_32() {
return MURMUR3_32;
}
- private static final HashFunction MURMUR3_32 = new Murmur3_32HashFunction(0);
+ private static final Murmur3_32HashFunction MURMUR3_32 = new Murmur3_32HashFunction(0);
/**
* Returns a hash function implementing the
* <a href="http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp">
- * 128-bit murmur3 algorithm, x64 variant</a> (little-endian variant),
- * using the given seed value.
- *
- * <p>The exact C++ equivalent is the MurmurHash3_x64_128 function (Murmur3F).
+ * 128-bit murmur3 algorithm, x64 variant</a> (little-endian variant), using the given seed
+ * value.
*/
public static HashFunction murmur3_128(int seed) {
return new Murmur3_128HashFunction(seed);
@@ -129,133 +97,62 @@ public final class Hashing {
/**
* Returns a hash function implementing the
* <a href="http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp">
- * 128-bit murmur3 algorithm, x64 variant</a> (little-endian variant),
- * using a seed value of zero.
- *
- * <p>The exact C++ equivalent is the MurmurHash3_x64_128 function (Murmur3F).
+ * 128-bit murmur3 algorithm, x64 variant</a> (little-endian variant), using a seed value
+ * of zero.
*/
public static HashFunction murmur3_128() {
return MURMUR3_128;
}
- private static final HashFunction MURMUR3_128 = new Murmur3_128HashFunction(0);
+ private static final Murmur3_128HashFunction MURMUR3_128 = new Murmur3_128HashFunction(0);
/**
- * Returns a hash function implementing the MD5 hash algorithm (128 hash bits) by delegating to
- * the MD5 {@link MessageDigest}.
+ * Returns a hash function implementing the MD5 hash algorithm by delegating to the MD5
+ * {@link MessageDigest}.
*/
public static HashFunction md5() {
return MD5;
}
- private static final HashFunction MD5 = new MessageDigestHashFunction("MD5", "Hashing.md5()");
+ private static final HashFunction MD5 = new MessageDigestHashFunction("MD5");
/**
- * Returns a hash function implementing the SHA-1 algorithm (160 hash bits) by delegating to the
- * SHA-1 {@link MessageDigest}.
+ * Returns a hash function implementing the SHA-1 algorithm by delegating to the SHA-1
+ * {@link MessageDigest}.
*/
public static HashFunction sha1() {
return SHA_1;
}
- private static final HashFunction SHA_1 =
- new MessageDigestHashFunction("SHA-1", "Hashing.sha1()");
+ private static final HashFunction SHA_1 = new MessageDigestHashFunction("SHA-1");
/**
- * Returns a hash function implementing the SHA-256 algorithm (256 hash bits) by delegating to
- * the SHA-256 {@link MessageDigest}.
+ * Returns a hash function implementing the SHA-256 algorithm by delegating to the SHA-256
+ * {@link MessageDigest}.
*/
public static HashFunction sha256() {
return SHA_256;
}
- private static final HashFunction SHA_256 =
- new MessageDigestHashFunction("SHA-256", "Hashing.sha256()");
+ private static final HashFunction SHA_256 = new MessageDigestHashFunction("SHA-256");
/**
- * Returns a hash function implementing the SHA-512 algorithm (512 hash bits) by delegating to the
- * SHA-512 {@link MessageDigest}.
+ * Returns a hash function implementing the SHA-512 algorithm by delegating to the SHA-512
+ * {@link MessageDigest}.
*/
public static HashFunction sha512() {
return SHA_512;
}
- private static final HashFunction SHA_512 =
- new MessageDigestHashFunction("SHA-512", "Hashing.sha512()");
-
- /**
- * Returns a hash function implementing the CRC-32 checksum algorithm (32 hash bits) by delegating
- * to the {@link CRC32} {@link Checksum}.
- *
- * <p>To get the {@code long} value equivalent to {@link Checksum#getValue()} for a
- * {@code HashCode} produced by this function, use {@link HashCode#padToLong()}.
- *
- * @since 14.0
- */
- public static HashFunction crc32() {
- return CRC_32;
- }
-
- private static final HashFunction CRC_32 =
- checksumHashFunction(ChecksumType.CRC_32, "Hashing.crc32()");
-
- /**
- * Returns a hash function implementing the Adler-32 checksum algorithm (32 hash bits) by
- * delegating to the {@link Adler32} {@link Checksum}.
- *
- * <p>To get the {@code long} value equivalent to {@link Checksum#getValue()} for a
- * {@code HashCode} produced by this function, use {@link HashCode#padToLong()}.
- *
- * @since 14.0
- */
- public static HashFunction adler32() {
- return ADLER_32;
- }
-
- private static final HashFunction ADLER_32 =
- checksumHashFunction(ChecksumType.ADLER_32, "Hashing.adler32()");
-
- private static HashFunction checksumHashFunction(ChecksumType type, String toString) {
- return new ChecksumHashFunction(type, type.bits, toString);
- }
-
- enum ChecksumType implements Supplier<Checksum> {
- CRC_32(32) {
- @Override
- public Checksum get() {
- return new CRC32();
- }
- },
- ADLER_32(32) {
- @Override
- public Checksum get() {
- return new Adler32();
- }
- };
-
- private final int bits;
-
- ChecksumType(int bits) {
- this.bits = bits;
- }
-
- @Override
- public abstract Checksum get();
- }
-
- // Lazy initialization holder class idiom.
+ private static final HashFunction SHA_512 = new MessageDigestHashFunction("SHA-512");
/**
* If {@code hashCode} has enough bits, returns {@code hashCode.asLong()}, otherwise
* returns a {@code long} value with {@code hashCode.asInt()} as the least-significant
* four bytes and {@code 0x00} as each of the most-significant four bytes.
- *
- * @deprecated Use {@code HashCode.padToLong()} instead. This method is scheduled to be
- * removed in Guava 15.0.
*/
- @Deprecated
public static long padToLong(HashCode hashCode) {
- return hashCode.padToLong();
+ return (hashCode.bits() < 64) ? UnsignedInts.toLong(hashCode.asInt()) : hashCode.asLong();
}
/**
@@ -270,12 +167,9 @@ public final class Hashing {
*
* <p>See the <a href="http://en.wikipedia.org/wiki/Consistent_hashing">wikipedia
* article on consistent hashing</a> for more information.
- * <p>
- * If you might want to have weights for the buckets in the future, take a look at
- * {@code weightedConsistentHash}.
*/
public static int consistentHash(HashCode hashCode, int buckets) {
- return consistentHash(hashCode.padToLong(), buckets);
+ return consistentHash(padToLong(hashCode), buckets);
}
/**
@@ -290,19 +184,21 @@ public final class Hashing {
*
* <p>See the <a href="http://en.wikipedia.org/wiki/Consistent_hashing">wikipedia
* article on consistent hashing</a> for more information.
- * <p>
- * If you might want to have weights for the buckets in the future, take a look at
- * {@code weightedConsistentHash}.
*/
public static int consistentHash(long input, int buckets) {
checkArgument(buckets > 0, "buckets must be positive: %s", buckets);
- LinearCongruentialGenerator generator = new LinearCongruentialGenerator(input);
+ long h = input;
int candidate = 0;
int next;
// Jump from bucket to bucket until we go out of range
while (true) {
- next = (int) ((candidate + 1) / generator.nextDouble());
+ // See http://en.wikipedia.org/wiki/Linear_congruential_generator
+ // These values for a and m come from the C++ version of this function.
+ h = 2862933555777941757L * h + 1;
+ double inv = 0x1.0p31 / ((int) (h >>> 33) + 1);
+ next = (int) ((candidate + 1) * inv);
+
if (next >= 0 && next < buckets) {
candidate = next;
} else {
@@ -334,7 +230,7 @@ public final class Hashing {
resultBytes[i] = (byte) (resultBytes[i] * 37 ^ nextBytes[i]);
}
}
- return HashCodes.fromBytesNoCopy(resultBytes);
+ return HashCodes.fromBytes(resultBytes);
}
/**
@@ -359,7 +255,7 @@ public final class Hashing {
resultBytes[i] += nextBytes[i];
}
}
- return HashCodes.fromBytesNoCopy(resultBytes);
+ return HashCodes.fromBytes(resultBytes);
}
/**
@@ -370,29 +266,27 @@ public final class Hashing {
return (bits + 31) & ~31;
}
- // TODO(kevinb): Maybe expose this class via a static Hashing method?
- @VisibleForTesting
- static final class ConcatenatedHashFunction extends AbstractCompositeHashFunction {
- private final int bits;
+ // TODO(kevinb): probably expose this via a Hashing method at some point?
+ private static class ConcatenatedHashFunction extends AbstractCompositeHashFunction {
+ final int bits;
- ConcatenatedHashFunction(HashFunction... functions) {
+ ConcatenatedHashFunction(HashFunction[] functions) {
super(functions);
int bitSum = 0;
- for (HashFunction function : functions) {
- bitSum += function.bits();
+ for (HashFunction f : this.functions) {
+ bitSum += f.bits();
}
this.bits = bitSum;
}
@Override
HashCode makeHash(Hasher[] hashers) {
- // TODO(user): Get rid of the ByteBuffer here?
byte[] bytes = new byte[bits / 8];
ByteBuffer buffer = ByteBuffer.wrap(bytes);
for (Hasher hasher : hashers) {
buffer.put(hasher.hash().asBytes());
}
- return HashCodes.fromBytesNoCopy(bytes);
+ return HashCodes.fromBytes(bytes);
}
@Override
@@ -400,21 +294,4 @@ public final class Hashing {
return bits;
}
}
-
- /**
- * Linear CongruentialGenerator to use for consistent hashing.
- * See http://en.wikipedia.org/wiki/Linear_congruential_generator
- */
- private static final class LinearCongruentialGenerator {
- private long state;
-
- public LinearCongruentialGenerator(long seed) {
- this.state = seed;
- }
-
- public double nextDouble() {
- state = 2862933555777941757L * state + 1;
- return ((double) ((int) (state >>> 33) + 1)) / (0x1.0p31);
- }
- }
}
diff --git a/guava/src/com/google/common/hash/MessageDigestHashFunction.java b/guava/src/com/google/common/hash/MessageDigestHashFunction.java
index 029a494..03c6471 100644
--- a/guava/src/com/google/common/hash/MessageDigestHashFunction.java
+++ b/guava/src/com/google/common/hash/MessageDigestHashFunction.java
@@ -14,60 +14,37 @@
package com.google.common.hash;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Preconditions.checkPositionIndexes;
-import java.io.Serializable;
+import com.google.common.primitives.Chars;
+import com.google.common.primitives.Ints;
+import com.google.common.primitives.Longs;
+import com.google.common.primitives.Shorts;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
/**
- * {@link HashFunction} adapter for {@link MessageDigest} instances.
+ * {@link HashFunction} adapter for {@link MessageDigest}s.
*
- * @author Kevin Bourrillion
- * @author Dimitris Andreou
+ * @author kevinb@google.com (Kevin Bourrillion)
+ * @author andreou@google.com (Dimitris Andreou)
*/
-final class MessageDigestHashFunction extends AbstractStreamingHashFunction
- implements Serializable {
- private final MessageDigest prototype;
- private final int bytes;
- private final boolean supportsClone;
- private final String toString;
-
- MessageDigestHashFunction(String algorithmName, String toString) {
- this.prototype = getMessageDigest(algorithmName);
- this.bytes = prototype.getDigestLength();
- this.toString = checkNotNull(toString);
- this.supportsClone = supportsClone();
- }
-
- MessageDigestHashFunction(String algorithmName, int bytes, String toString) {
- this.toString = checkNotNull(toString);
- this.prototype = getMessageDigest(algorithmName);
- int maxLength = prototype.getDigestLength();
- checkArgument(bytes >= 4 && bytes <= maxLength,
- "bytes (%s) must be >= 4 and < %s", bytes, maxLength);
- this.bytes = bytes;
- this.supportsClone = supportsClone();
- }
+final class MessageDigestHashFunction extends AbstractStreamingHashFunction {
+ private final String algorithmName;
+ private final int bits;
- private boolean supportsClone() {
- try {
- prototype.clone();
- return true;
- } catch (CloneNotSupportedException e) {
- return false;
- }
+ MessageDigestHashFunction(String algorithmName) {
+ this.algorithmName = algorithmName;
+ this.bits = getMessageDigest(algorithmName).getDigestLength() * 8;
}
- @Override public int bits() {
- return bytes * Byte.SIZE;
- }
-
- @Override public String toString() {
- return toString;
+ public int bits() {
+ return bits;
}
private static MessageDigest getMessageDigest(String algorithmName) {
@@ -79,80 +56,118 @@ final class MessageDigestHashFunction extends AbstractStreamingHashFunction
}
@Override public Hasher newHasher() {
- if (supportsClone) {
- try {
- return new MessageDigestHasher((MessageDigest) prototype.clone(), bytes);
- } catch (CloneNotSupportedException e) {
- // falls through
- }
- }
- return new MessageDigestHasher(getMessageDigest(prototype.getAlgorithm()), bytes);
+ return new MessageDigestHasher(getMessageDigest(algorithmName));
}
- private static final class SerializedForm implements Serializable {
- private final String algorithmName;
- private final int bytes;
- private final String toString;
+ private static class MessageDigestHasher implements Hasher {
+ private final MessageDigest digest;
+ private final ByteBuffer scratch; // lazy convenience
+ private boolean done;
- private SerializedForm(String algorithmName, int bytes, String toString) {
- this.algorithmName = algorithmName;
- this.bytes = bytes;
- this.toString = toString;
+ private MessageDigestHasher(MessageDigest digest) {
+ this.digest = digest;
+ this.scratch = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);
}
- private Object readResolve() {
- return new MessageDigestHashFunction(algorithmName, bytes, toString);
+ @Override public Hasher putByte(byte b) {
+ checkNotDone();
+ digest.update(b);
+ return this;
}
- private static final long serialVersionUID = 0;
- }
+ @Override public Hasher putBytes(byte[] bytes) {
+ checkNotDone();
+ digest.update(bytes);
+ return this;
+ }
- Object writeReplace() {
- return new SerializedForm(prototype.getAlgorithm(), bytes, toString);
- }
+ @Override public Hasher putBytes(byte[] bytes, int off, int len) {
+ checkNotDone();
+ checkPositionIndexes(off, off + len, bytes.length);
+ digest.update(bytes, off, len);
+ return this;
+ }
- /**
- * Hasher that updates a message digest.
- */
- private static final class MessageDigestHasher extends AbstractByteHasher {
+ @Override public Hasher putShort(short s) {
+ checkNotDone();
+ scratch.putShort(s);
+ digest.update(scratch.array(), 0, Shorts.BYTES);
+ scratch.clear();
+ return this;
+ }
- private final MessageDigest digest;
- private final int bytes;
- private boolean done;
+ @Override public Hasher putInt(int i) {
+ checkNotDone();
+ scratch.putInt(i);
+ digest.update(scratch.array(), 0, Ints.BYTES);
+ scratch.clear();
+ return this;
+ }
- private MessageDigestHasher(MessageDigest digest, int bytes) {
- this.digest = digest;
- this.bytes = bytes;
+ @Override public Hasher putLong(long l) {
+ checkNotDone();
+ scratch.putLong(l);
+ digest.update(scratch.array(), 0, Longs.BYTES);
+ scratch.clear();
+ return this;
}
- @Override
- protected void update(byte b) {
+ @Override public Hasher putFloat(float f) {
checkNotDone();
- digest.update(b);
+ scratch.putFloat(f);
+ digest.update(scratch.array(), 0, 4);
+ scratch.clear();
+ return this;
}
- @Override
- protected void update(byte[] b) {
+ @Override public Hasher putDouble(double d) {
checkNotDone();
- digest.update(b);
+ scratch.putDouble(d);
+ digest.update(scratch.array(), 0, 8);
+ scratch.clear();
+ return this;
+ }
+
+ @Override public Hasher putBoolean(boolean b) {
+ return putByte(b ? (byte) 1 : (byte) 0);
+ }
+
+ @Override public Hasher putChar(char c) {
+ checkNotDone();
+ scratch.putChar(c);
+ digest.update(scratch.array(), 0, Chars.BYTES);
+ scratch.clear();
+ return this;
+ }
+
+ @Override public Hasher putString(CharSequence charSequence) {
+ for (int i = 0; i < charSequence.length(); i++) {
+ putChar(charSequence.charAt(i));
+ }
+ return this;
+ }
+
+ @Override public Hasher putString(CharSequence charSequence, Charset charset) {
+ try {
+ return putBytes(charSequence.toString().getBytes(charset.name()));
+ } catch (java.io.UnsupportedEncodingException impossible) {
+ throw new AssertionError(impossible);
+ }
}
- @Override
- protected void update(byte[] b, int off, int len) {
+ @Override public <T> Hasher putObject(T instance, Funnel<? super T> funnel) {
checkNotDone();
- digest.update(b, off, len);
+ funnel.funnel(instance, this);
+ return this;
}
private void checkNotDone() {
checkState(!done, "Cannot use Hasher after calling #hash() on it");
}
- @Override
public HashCode hash() {
done = true;
- return (bytes == digest.getDigestLength())
- ? HashCodes.fromBytesNoCopy(digest.digest())
- : HashCodes.fromBytesNoCopy(Arrays.copyOf(digest.digest(), bytes));
+ return HashCodes.fromBytes(digest.digest());
}
}
}
diff --git a/guava/src/com/google/common/hash/Murmur3_128HashFunction.java b/guava/src/com/google/common/hash/Murmur3_128HashFunction.java
index aab08a3..cd49f87 100644
--- a/guava/src/com/google/common/hash/Murmur3_128HashFunction.java
+++ b/guava/src/com/google/common/hash/Murmur3_128HashFunction.java
@@ -12,17 +12,6 @@
* the License.
*/
-/*
- * MurmurHash3 was written by Austin Appleby, and is placed in the public
- * domain. The author hereby disclaims copyright to this source code.
- */
-
-/*
- * Source:
- * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
- * (Modified to adapt to Guava coding conventions and to use the HashFunction interface)
- */
-
package com.google.common.hash;
import static com.google.common.primitives.UnsignedBytes.toInt;
@@ -35,8 +24,8 @@ import java.nio.ByteOrder;
* See http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp
* MurmurHash3_x64_128
*
- * @author Austin Appleby
- * @author Dimitris Andreou
+ * @author aappleby@google.com (Austin Appleby)
+ * @author andreou@google.com (Dimitris Andreou)
*/
final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implements Serializable {
// TODO(user): when the shortcuts are implemented, update BloomFilterStrategies
@@ -54,41 +43,40 @@ final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implem
return new Murmur3_128Hasher(seed);
}
- @Override
- public String toString() {
- return "Hashing.murmur3_128(" + seed + ")";
- }
-
private static final class Murmur3_128Hasher extends AbstractStreamingHasher {
- private static final int CHUNK_SIZE = 16;
- private static final long C1 = 0x87c37b91114253d5L;
- private static final long C2 = 0x4cf5ad432745937fL;
- private long h1;
- private long h2;
- private int length;
+ long h1;
+ long h2;
+ long c1 = 0x87c37b91114253d5L;
+ long c2 = 0x4cf5ad432745937fL;
+ int len;
Murmur3_128Hasher(int seed) {
- super(CHUNK_SIZE);
- this.h1 = seed;
- this.h2 = seed;
- this.length = 0;
+ super(16);
+ h1 = seed;
+ h2 = seed;
}
@Override protected void process(ByteBuffer bb) {
long k1 = bb.getLong();
long k2 = bb.getLong();
+ len += 16;
bmix64(k1, k2);
- length += CHUNK_SIZE;
}
private void bmix64(long k1, long k2) {
- h1 ^= mixK1(k1);
+ k1 *= c1;
+ k1 = Long.rotateLeft(k1, 31);
+ k1 *= c2;
+ h1 ^= k1;
h1 = Long.rotateLeft(h1, 27);
h1 += h2;
h1 = h1 * 5 + 0x52dce729;
- h2 ^= mixK2(k2);
+ k2 *= c2;
+ k2 = Long.rotateLeft(k2, 33);
+ k2 *= c1;
+ h2 ^= k2;
h2 = Long.rotateLeft(h2, 31);
h2 += h1;
@@ -98,7 +86,7 @@ final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implem
@Override protected void processRemaining(ByteBuffer bb) {
long k1 = 0;
long k2 = 0;
- length += bb.remaining();
+ len += bb.remaining();
switch (bb.remaining()) {
case 15:
k2 ^= (long) toInt(bb.get(14)) << 48; // fall through
@@ -113,10 +101,14 @@ final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implem
case 10:
k2 ^= (long) toInt(bb.get(9)) << 8; // fall through
case 9:
- k2 ^= (long) toInt(bb.get(8)); // fall through
+ k2 ^= (long) toInt(bb.get(8)) << 0;
+ k2 *= c2;
+ k2 = Long.rotateLeft(k2, 33);
+ k2 *= c1;
+ h2 ^= k2;
+ // fall through
case 8:
- k1 ^= bb.getLong();
- break;
+ k1 ^= (long) toInt(bb.get(7)) << 56; // fall through
case 7:
k1 ^= (long) toInt(bb.get(6)) << 48; // fall through
case 6:
@@ -130,18 +122,19 @@ final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implem
case 2:
k1 ^= (long) toInt(bb.get(1)) << 8; // fall through
case 1:
- k1 ^= (long) toInt(bb.get(0));
- break;
+ k1 ^= (long) toInt(bb.get(0)) << 0;
+ k1 *= c1;
+ k1 = Long.rotateLeft(k1, 31);
+ k1 *= c2;
+ h1 ^= k1;
+ // fall through
default:
- throw new AssertionError("Should never get here.");
}
- h1 ^= mixK1(k1);
- h2 ^= mixK2(k2);
}
@Override public HashCode makeHash() {
- h1 ^= length;
- h2 ^= length;
+ h1 ^= len;
+ h2 ^= len;
h1 += h2;
h2 += h1;
@@ -152,15 +145,13 @@ final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implem
h1 += h2;
h2 += h1;
- return HashCodes.fromBytesNoCopy(ByteBuffer
- .wrap(new byte[CHUNK_SIZE])
- .order(ByteOrder.LITTLE_ENDIAN)
- .putLong(h1)
- .putLong(h2)
- .array());
+ ByteBuffer bb = ByteBuffer.wrap(new byte[16]).order(ByteOrder.LITTLE_ENDIAN);
+ bb.putLong(h1);
+ bb.putLong(h2);
+ return HashCodes.fromBytes(bb.array());
}
- private static long fmix64(long k) {
+ private long fmix64(long k) {
k ^= k >>> 33;
k *= 0xff51afd7ed558ccdL;
k ^= k >>> 33;
@@ -168,20 +159,6 @@ final class Murmur3_128HashFunction extends AbstractStreamingHashFunction implem
k ^= k >>> 33;
return k;
}
-
- private static long mixK1(long k1) {
- k1 *= C1;
- k1 = Long.rotateLeft(k1, 31);
- k1 *= C2;
- return k1;
- }
-
- private static long mixK2(long k2) {
- k2 *= C2;
- k2 = Long.rotateLeft(k2, 33);
- k2 *= C1;
- return k2;
- }
}
private static final long serialVersionUID = 0L;
diff --git a/guava/src/com/google/common/hash/Murmur3_32HashFunction.java b/guava/src/com/google/common/hash/Murmur3_32HashFunction.java
index c6637de..5c03b92 100644
--- a/guava/src/com/google/common/hash/Murmur3_32HashFunction.java
+++ b/guava/src/com/google/common/hash/Murmur3_32HashFunction.java
@@ -12,42 +12,23 @@
* the License.
*/
-/*
- * MurmurHash3 was written by Austin Appleby, and is placed in the public
- * domain. The author hereby disclaims copyright to this source code.
- */
-
-/*
- * Source:
- * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
- * (Modified to adapt to Guava coding conventions and to use the HashFunction interface)
- */
-
package com.google.common.hash;
import static com.google.common.primitives.UnsignedBytes.toInt;
-import com.google.common.primitives.Chars;
-import com.google.common.primitives.Ints;
-import com.google.common.primitives.Longs;
-
import java.io.Serializable;
import java.nio.ByteBuffer;
/**
* See http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp
* MurmurHash3_x86_32
- *
- * @author Austin Appleby
- * @author Dimitris Andreou
- * @author Kurt Alfred Kluever
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ * @author andreou@google.com (Dimitris Andreou)
*/
final class Murmur3_32HashFunction extends AbstractStreamingHashFunction implements Serializable {
- private static final int C1 = 0xcc9e2d51;
- private static final int C2 = 0x1b873593;
-
private final int seed;
-
+
Murmur3_32HashFunction(int seed) {
this.seed = seed;
}
@@ -60,107 +41,63 @@ final class Murmur3_32HashFunction extends AbstractStreamingHashFunction impleme
return new Murmur3_32Hasher(seed);
}
- @Override
- public String toString() {
- return "Hashing.murmur3_32(" + seed + ")";
- }
-
- @Override public HashCode hashInt(int input) {
- int k1 = mixK1(input);
- int h1 = mixH1(seed, k1);
-
- return fmix(h1, Ints.BYTES);
- }
-
- @Override public HashCode hashLong(long input) {
- int low = (int) input;
- int high = (int) (input >>> 32);
-
- int k1 = mixK1(low);
- int h1 = mixH1(seed, k1);
-
- k1 = mixK1(high);
- h1 = mixH1(h1, k1);
-
- return fmix(h1, Longs.BYTES);
- }
-
- // TODO(user): Maybe implement #hashBytes instead?
- @Override public HashCode hashString(CharSequence input) {
- int h1 = seed;
-
- // step through the CharSequence 2 chars at a time
- for (int i = 1; i < input.length(); i += 2) {
- int k1 = input.charAt(i - 1) | (input.charAt(i) << 16);
- k1 = mixK1(k1);
- h1 = mixH1(h1, k1);
- }
-
- // deal with any remaining characters
- if ((input.length() & 1) == 1) {
- int k1 = input.charAt(input.length() - 1);
- k1 = mixK1(k1);
- h1 ^= k1;
- }
-
- return fmix(h1, Chars.BYTES * input.length());
- }
-
- private static int mixK1(int k1) {
- k1 *= C1;
- k1 = Integer.rotateLeft(k1, 15);
- k1 *= C2;
- return k1;
- }
-
- private static int mixH1(int h1, int k1) {
- h1 ^= k1;
- h1 = Integer.rotateLeft(h1, 13);
- h1 = h1 * 5 + 0xe6546b64;
- return h1;
- }
-
- // Finalization mix - force all bits of a hash block to avalanche
- private static HashCode fmix(int h1, int length) {
- h1 ^= length;
- h1 ^= h1 >>> 16;
- h1 *= 0x85ebca6b;
- h1 ^= h1 >>> 13;
- h1 *= 0xc2b2ae35;
- h1 ^= h1 >>> 16;
- return HashCodes.fromInt(h1);
- }
-
private static final class Murmur3_32Hasher extends AbstractStreamingHasher {
- private static final int CHUNK_SIZE = 4;
- private int h1;
- private int length;
+ int h1;
+ int c1 = 0xcc9e2d51;
+ int c2 = 0x1b873593;
+ int len;
Murmur3_32Hasher(int seed) {
- super(CHUNK_SIZE);
- this.h1 = seed;
- this.length = 0;
+ super(4);
+ h1 = seed;
}
@Override protected void process(ByteBuffer bb) {
- int k1 = Murmur3_32HashFunction.mixK1(bb.getInt());
- h1 = Murmur3_32HashFunction.mixH1(h1, k1);
- length += CHUNK_SIZE;
+ int k1 = bb.getInt();
+ len += 4;
+
+ k1 *= c1;
+ k1 = Integer.rotateLeft(k1, 15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = Integer.rotateLeft(h1, 13);
+ h1 = h1 * 5 + 0xe6546b64;
}
-
+
@Override protected void processRemaining(ByteBuffer bb) {
- length += bb.remaining();
+ len += bb.remaining();
int k1 = 0;
- for (int i = 0; bb.hasRemaining(); i += 8) {
- k1 ^= toInt(bb.get()) << i;
+ switch (bb.remaining()) {
+ case 3:
+ k1 ^= toInt(bb.get(2)) << 16;
+ // fall through
+ case 2:
+ k1 ^= toInt(bb.get(1)) << 8;
+ // fall through
+ case 1:
+ k1 ^= toInt(bb.get(0));
+ // fall through
+ default:
+ k1 *= c1;
+ k1 = Integer.rotateLeft(k1, 15);
+ k1 *= c2;
+ h1 ^= k1;
}
- h1 ^= Murmur3_32HashFunction.mixK1(k1);
}
-
+
@Override public HashCode makeHash() {
- return Murmur3_32HashFunction.fmix(h1, length);
+ h1 ^= len;
+
+ h1 ^= h1 >>> 16;
+ h1 *= 0x85ebca6b;
+ h1 ^= h1 >>> 13;
+ h1 *= 0xc2b2ae35;
+ h1 ^= h1 >>> 16;
+
+ return HashCodes.fromInt(h1);
}
}
-
+
private static final long serialVersionUID = 0L;
}
diff --git a/guava/src/com/google/common/hash/PrimitiveSink.java b/guava/src/com/google/common/hash/Sink.java
index c851a1e..37167fc 100644
--- a/guava/src/com/google/common/hash/PrimitiveSink.java
+++ b/guava/src/com/google/common/hash/Sink.java
@@ -22,17 +22,17 @@ import java.nio.charset.Charset;
* An object which can receive a stream of primitive values.
*
* @author Kevin Bourrillion
- * @since 12.0 (in 11.0 as {@code Sink})
+ * @since 11.0
*/
@Beta
-public interface PrimitiveSink {
+public interface Sink {
/**
* Puts a byte into this sink.
*
* @param b a byte
* @return this instance
*/
- PrimitiveSink putByte(byte b);
+ Sink putByte(byte b);
/**
* Puts an array of bytes into this sink.
@@ -40,7 +40,7 @@ public interface PrimitiveSink {
* @param bytes a byte array
* @return this instance
*/
- PrimitiveSink putBytes(byte[] bytes);
+ Sink putBytes(byte[] bytes);
/**
* Puts a chunk of an array of bytes into this sink. {@code bytes[off]} is the first byte written,
@@ -53,50 +53,50 @@ public interface PrimitiveSink {
* @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > bytes.length} or
* {@code len < 0}
*/
- PrimitiveSink putBytes(byte[] bytes, int off, int len);
+ Sink putBytes(byte[] bytes, int off, int len);
/**
* Puts a short into this sink.
*/
- PrimitiveSink putShort(short s);
+ Sink putShort(short s);
/**
* Puts an int into this sink.
*/
- PrimitiveSink putInt(int i);
+ Sink putInt(int i);
/**
* Puts a long into this sink.
*/
- PrimitiveSink putLong(long l);
+ Sink putLong(long l);
/**
* Puts a float into this sink.
*/
- PrimitiveSink putFloat(float f);
+ Sink putFloat(float f);
/**
* Puts a double into this sink.
*/
- PrimitiveSink putDouble(double d);
+ Sink putDouble(double d);
/**
* Puts a boolean into this sink.
*/
- PrimitiveSink putBoolean(boolean b);
+ Sink putBoolean(boolean b);
/**
* Puts a character into this sink.
*/
- PrimitiveSink putChar(char c);
+ Sink putChar(char c);
/**
* Puts a string into this sink.
*/
- PrimitiveSink putString(CharSequence charSequence);
+ Sink putString(CharSequence charSequence);
/**
* Puts a string into this sink using the given charset.
*/
- PrimitiveSink putString(CharSequence charSequence, Charset charset);
+ Sink putString(CharSequence charSequence, Charset charset);
}
diff --git a/guava/src/com/google/common/hash/package-info.java b/guava/src/com/google/common/hash/package-info.java
index 7df4e73..4acc096 100644
--- a/guava/src/com/google/common/hash/package-info.java
+++ b/guava/src/com/google/common/hash/package-info.java
@@ -15,10 +15,6 @@
// TODO(user): when things stabilize, flesh this out
/**
* Hash functions and related structures.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/HashingExplained">
- * hashing</a>.
*/
@ParametersAreNonnullByDefault
package com.google.common.hash;
diff --git a/guava/src/com/google/common/io/AppendableWriter.java b/guava/src/com/google/common/io/AppendableWriter.java
index 7705183..8033e46 100644
--- a/guava/src/com/google/common/io/AppendableWriter.java
+++ b/guava/src/com/google/common/io/AppendableWriter.java
@@ -16,15 +16,11 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.Writer;
-import javax.annotation.Nullable;
-
/**
* Writer that places all output on an {@link Appendable} target. If the target
* is {@link Flushable} or {@link Closeable}, flush()es and close()s will also
@@ -44,7 +40,7 @@ class AppendableWriter extends Writer {
* @param target target to which to append output
*/
AppendableWriter(Appendable target) {
- this.target = checkNotNull(target);
+ this.target = target;
}
/*
@@ -83,12 +79,12 @@ class AppendableWriter extends Writer {
target.append((char) c);
}
- @Override public void write(@Nullable String str) throws IOException {
+ @Override public void write(String str) throws IOException {
checkNotClosed();
target.append(str);
}
- @Override public void write(@Nullable String str, int off, int len) throws IOException {
+ @Override public void write(String str, int off, int len) throws IOException {
checkNotClosed();
// tricky: append takes start, end pair...
target.append(str, off, off + len);
@@ -100,13 +96,13 @@ class AppendableWriter extends Writer {
return this;
}
- @Override public Writer append(@Nullable CharSequence charSeq) throws IOException {
+ @Override public Writer append(CharSequence charSeq) throws IOException {
checkNotClosed();
target.append(charSeq);
return this;
}
- @Override public Writer append(@Nullable CharSequence charSeq, int start, int end)
+ @Override public Writer append(CharSequence charSeq, int start, int end)
throws IOException {
checkNotClosed();
target.append(charSeq, start, end);
diff --git a/guava/src/com/google/common/io/BaseEncoding.java b/guava/src/com/google/common/io/BaseEncoding.java
deleted file mode 100644
index 4af0719..0000000
--- a/guava/src/com/google/common/io/BaseEncoding.java
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.io.GwtWorkarounds.asCharInput;
-import static com.google.common.io.GwtWorkarounds.asCharOutput;
-import static com.google.common.io.GwtWorkarounds.asInputStream;
-import static com.google.common.io.GwtWorkarounds.asOutputStream;
-import static com.google.common.io.GwtWorkarounds.stringBuilderOutput;
-import static com.google.common.math.IntMath.divide;
-import static com.google.common.math.IntMath.log2;
-import static java.math.RoundingMode.CEILING;
-import static java.math.RoundingMode.FLOOR;
-import static java.math.RoundingMode.UNNECESSARY;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Ascii;
-import com.google.common.base.CharMatcher;
-import com.google.common.io.GwtWorkarounds.ByteInput;
-import com.google.common.io.GwtWorkarounds.ByteOutput;
-import com.google.common.io.GwtWorkarounds.CharInput;
-import com.google.common.io.GwtWorkarounds.CharOutput;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.Arrays;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nullable;
-
-/**
- * A binary encoding scheme for reversibly translating between byte sequences and printable ASCII
- * strings. This class includes several constants for encoding schemes specified by <a
- * href="http://tools.ietf.org/html/rfc4648">RFC 4648</a>. For example, the expression:
- * <pre> {@code
- *
- * BaseEncoding.base32().encode("foo".getBytes(Charsets.US_ASCII))
- * }</pre>
- * returns the string {@code "MZXW6==="}, and <pre> {@code
- *
- * byte[] decoded = BaseEncoding.base32().decode("MZXW6===");
- * }</pre>
- *
- * ...returns the ASCII bytes of the string {@code "foo"}.
- *
- * <p>By default, {@code BaseEncoding}'s behavior is relatively strict and in accordance with
- * RFC 4648. Decoding rejects characters in the wrong case, though padding is optional.
- * To modify encoding and decoding behavior, use configuration methods to obtain a new encoding
- * with modified behavior: <pre> {@code
- *
- * BaseEncoding.base16().lowerCase().decode("deadbeef");
- * }</pre>
- *
- * <p>Warning: BaseEncoding instances are immutable. Invoking a configuration method has no effect
- * on the receiving instance; you must store and use the new encoding instance it returns, instead.
- * <pre> {@code
- *
- * // Do NOT do this
- * BaseEncoding hex = BaseEncoding.base16();
- * hex.lowerCase(); // does nothing!
- * return hex.decode("deadbeef"); // throws an IllegalArgumentException
- * }</pre>
- *
- * <p>It is guaranteed that {@code encoding.decode(encoding.encode(x))} is always equal to
- * {@code x}, but the reverse does not necessarily hold.
- *
- * <p>
- * <table>
- * <tr>
- * <th>Encoding
- * <th>Alphabet
- * <th>{@code char:byte} ratio
- * <th>Default padding
- * <th>Comments
- * <tr>
- * <td>{@link #base16()}
- * <td>0-9 A-F
- * <td>2.00
- * <td>N/A
- * <td>Traditional hexadecimal. Defaults to upper case.
- * <tr>
- * <td>{@link #base32()}
- * <td>A-Z 2-7
- * <td>1.60
- * <td>=
- * <td>Human-readable; no possibility of mixing up 0/O or 1/I. Defaults to upper case.
- * <tr>
- * <td>{@link #base32Hex()}
- * <td>0-9 A-V
- * <td>1.60
- * <td>=
- * <td>"Numerical" base 32; extended from the traditional hex alphabet. Defaults to upper case.
- * <tr>
- * <td>{@link #base64()}
- * <td>A-Z a-z 0-9 + /
- * <td>1.33
- * <td>=
- * <td>
- * <tr>
- * <td>{@link #base64Url()}
- * <td>A-Z a-z 0-9 - _
- * <td>1.33
- * <td>=
- * <td>Safe to use as filenames, or to pass in URLs without escaping
- * </table>
- *
- * <p>
- * All instances of this class are immutable, so they may be stored safely as static constants.
- *
- * @author Louis Wasserman
- * @since 14.0
- */
-@Beta
-@GwtCompatible(emulated = true)
-public abstract class BaseEncoding {
- // TODO(user): consider adding encodeTo(Appendable, byte[], [int, int])
-
- BaseEncoding() {}
-
- /**
- * Encodes the specified byte array, and returns the encoded {@code String}.
- */
- public String encode(byte[] bytes) {
- return encode(checkNotNull(bytes), 0, bytes.length);
- }
-
- /**
- * Encodes the specified range of the specified byte array, and returns the encoded
- * {@code String}.
- */
- public final String encode(byte[] bytes, int off, int len) {
- checkNotNull(bytes);
- checkPositionIndexes(off, off + len, bytes.length);
- CharOutput result = stringBuilderOutput(maxEncodedSize(len));
- ByteOutput byteOutput = encodingStream(result);
- try {
- for (int i = 0; i < len; i++) {
- byteOutput.write(bytes[off + i]);
- }
- byteOutput.close();
- } catch (IOException impossible) {
- throw new AssertionError("impossible");
- }
- return result.toString();
- }
-
- /**
- * Returns an {@code OutputStream} that encodes bytes using this encoding into the specified
- * {@code Writer}. When the returned {@code OutputStream} is closed, so is the backing
- * {@code Writer}.
- */
- @GwtIncompatible("Writer,OutputStream")
- public final OutputStream encodingStream(Writer writer) {
- return asOutputStream(encodingStream(asCharOutput(writer)));
- }
-
- /**
- * Returns an {@code OutputSupplier} that supplies streams that encode bytes using this encoding
- * into writers from the specified {@code OutputSupplier}.
- */
- @GwtIncompatible("Writer,OutputStream")
- public final OutputSupplier<OutputStream> encodingStream(
- final OutputSupplier<? extends Writer> writerSupplier) {
- checkNotNull(writerSupplier);
- return new OutputSupplier<OutputStream>() {
- @Override
- public OutputStream getOutput() throws IOException {
- return encodingStream(writerSupplier.getOutput());
- }
- };
- }
-
- /**
- * Returns a {@code ByteSink} that writes base-encoded bytes to the specified {@code CharSink}.
- */
- @GwtIncompatible("ByteSink,CharSink")
- public final ByteSink encodingSink(final CharSink encodedSink) {
- checkNotNull(encodedSink);
- return new ByteSink() {
- @Override
- public OutputStream openStream() throws IOException {
- return encodingStream(encodedSink.openStream());
- }
- };
- }
-
- // TODO(user): document the extent of leniency, probably after adding ignore(CharMatcher)
-
- private static byte[] extract(byte[] result, int length) {
- if (length == result.length) {
- return result;
- } else {
- byte[] trunc = new byte[length];
- System.arraycopy(result, 0, trunc, 0, length);
- return trunc;
- }
- }
-
- /**
- * Decodes the specified character sequence, and returns the resulting {@code byte[]}.
- * This is the inverse operation to {@link #encode(byte[])}.
- *
- * @throws IllegalArgumentException if the input is not a valid encoded string according to this
- * encoding.
- */
- public final byte[] decode(CharSequence chars) {
- chars = padding().trimTrailingFrom(chars);
- ByteInput decodedInput = decodingStream(asCharInput(chars));
- byte[] tmp = new byte[maxDecodedSize(chars.length())];
- int index = 0;
- try {
- for (int i = decodedInput.read(); i != -1; i = decodedInput.read()) {
- tmp[index++] = (byte) i;
- }
- } catch (IOException badInput) {
- throw new IllegalArgumentException(badInput);
- }
- return extract(tmp, index);
- }
-
- /**
- * Returns an {@code InputStream} that decodes base-encoded input from the specified
- * {@code Reader}.
- */
- @GwtIncompatible("Reader,InputStream")
- public final InputStream decodingStream(Reader reader) {
- return asInputStream(decodingStream(asCharInput(reader)));
- }
-
- /**
- * Returns an {@code InputSupplier} that supplies input streams that decode base-encoded input
- * from readers from the specified supplier.
- */
- @GwtIncompatible("Reader,InputStream")
- public final InputSupplier<InputStream> decodingStream(
- final InputSupplier<? extends Reader> readerSupplier) {
- checkNotNull(readerSupplier);
- return new InputSupplier<InputStream>() {
- @Override
- public InputStream getInput() throws IOException {
- return decodingStream(readerSupplier.getInput());
- }
- };
- }
-
- /**
- * Returns a {@code ByteSource} that reads base-encoded bytes from the specified
- * {@code CharSource}.
- */
- @GwtIncompatible("ByteSource,CharSource")
- public final ByteSource decodingSource(final CharSource encodedSource) {
- checkNotNull(encodedSource);
- return new ByteSource() {
- @Override
- public InputStream openStream() throws IOException {
- return decodingStream(encodedSource.openStream());
- }
- };
- }
-
- // Implementations for encoding/decoding
-
- abstract int maxEncodedSize(int bytes);
-
- abstract ByteOutput encodingStream(CharOutput charOutput);
-
- abstract int maxDecodedSize(int chars);
-
- abstract ByteInput decodingStream(CharInput charInput);
-
- abstract CharMatcher padding();
-
- // Modified encoding generators
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but omits any padding
- * characters as specified by <a href="http://tools.ietf.org/html/rfc4648#section-3.2">RFC 4648
- * section 3.2</a>, Padding of Encoded Data.
- */
- @CheckReturnValue
- public abstract BaseEncoding omitPadding();
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but uses an alternate character
- * for padding.
- *
- * @throws IllegalArgumentException if this padding character is already used in the alphabet or a
- * separator
- */
- @CheckReturnValue
- public abstract BaseEncoding withPadChar(char padChar);
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but adds a separator string
- * after every {@code n} characters. Any occurrences of any characters that occur in the separator
- * are skipped over in decoding.
- *
- * @throws IllegalArgumentException if any alphabet or padding characters appear in the separator
- * string, or if {@code n <= 0}
- * @throws UnsupportedOperationException if this encoding already uses a separator
- */
- @CheckReturnValue
- public abstract BaseEncoding withSeparator(String separator, int n);
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but encodes and decodes with
- * uppercase letters. Padding and separator characters remain in their original case.
- *
- * @throws IllegalStateException if the alphabet used by this encoding contains mixed upper- and
- * lower-case characters
- */
- @CheckReturnValue
- public abstract BaseEncoding upperCase();
-
- /**
- * Returns an encoding that behaves equivalently to this encoding, but encodes and decodes with
- * lowercase letters. Padding and separator characters remain in their original case.
- *
- * @throws IllegalStateException if the alphabet used by this encoding contains mixed upper- and
- * lower-case characters
- */
- @CheckReturnValue
- public abstract BaseEncoding lowerCase();
-
- private static final BaseEncoding BASE64 = new StandardBaseEncoding(
- "base64()", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", '=');
-
- /**
- * The "base64" base encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-4">RFC 4648 section 4</a>, Base 64 Encoding.
- * (This is the same as the base 64 encoding from <a
- * href="http://tools.ietf.org/html/rfc3548#section-3">RFC 3548</a>.)
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base64() {
- return BASE64;
- }
-
- private static final BaseEncoding BASE64_URL = new StandardBaseEncoding(
- "base64Url()", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", '=');
-
- /**
- * The "base64url" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-5">RFC 4648 section 5</a>, Base 64 Encoding
- * with URL and Filename Safe Alphabet, also sometimes referred to as the "web safe Base64."
- * (This is the same as the base 64 encoding with URL and filename safe alphabet from <a
- * href="http://tools.ietf.org/html/rfc3548#section-4">RFC 3548</a>.)
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base64Url() {
- return BASE64_URL;
- }
-
- private static final BaseEncoding BASE32 =
- new StandardBaseEncoding("base32()", "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", '=');
-
- /**
- * The "base32" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-6">RFC 4648 section 6</a>, Base 32 Encoding.
- * (This is the same as the base 32 encoding from <a
- * href="http://tools.ietf.org/html/rfc3548#section-5">RFC 3548</a>.)
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base32() {
- return BASE32;
- }
-
- private static final BaseEncoding BASE32_HEX =
- new StandardBaseEncoding("base32Hex()", "0123456789ABCDEFGHIJKLMNOPQRSTUV", '=');
-
- /**
- * The "base32hex" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-7">RFC 4648 section 7</a>, Base 32 Encoding
- * with Extended Hex Alphabet. There is no corresponding encoding in RFC 3548.
- *
- * <p>The character {@code '='} is used for padding, but can be {@linkplain #omitPadding()
- * omitted} or {@linkplain #withPadChar(char) replaced}.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base32Hex() {
- return BASE32_HEX;
- }
-
- private static final BaseEncoding BASE16 =
- new StandardBaseEncoding("base16()", "0123456789ABCDEF", null);
-
- /**
- * The "base16" encoding specified by <a
- * href="http://tools.ietf.org/html/rfc4648#section-8">RFC 4648 section 8</a>, Base 16 Encoding.
- * (This is the same as the base 16 encoding from <a
- * href="http://tools.ietf.org/html/rfc3548#section-6">RFC 3548</a>.) This is commonly known as
- * "hexadecimal" format.
- *
- * <p>No padding is necessary in base 16, so {@link #withPadChar(char)} and
- * {@link #omitPadding()} have no effect.
- *
- * <p>No line feeds are added by default, as per <a
- * href="http://tools.ietf.org/html/rfc4648#section-3.1"> RFC 4648 section 3.1</a>, Line Feeds in
- * Encoded Data. Line feeds may be added using {@link #withSeparator(String, int)}.
- */
- public static BaseEncoding base16() {
- return BASE16;
- }
-
- private static final class Alphabet extends CharMatcher {
- private final String name;
- // this is meant to be immutable -- don't modify it!
- private final char[] chars;
- final int mask;
- final int bitsPerChar;
- final int charsPerChunk;
- final int bytesPerChunk;
- private final byte[] decodabet;
- private final boolean[] validPadding;
-
- Alphabet(String name, char[] chars) {
- this.name = checkNotNull(name);
- this.chars = checkNotNull(chars);
- try {
- this.bitsPerChar = log2(chars.length, UNNECESSARY);
- } catch (ArithmeticException e) {
- throw new IllegalArgumentException("Illegal alphabet length " + chars.length, e);
- }
-
- /*
- * e.g. for base64, bitsPerChar == 6, charsPerChunk == 4, and bytesPerChunk == 3. This makes
- * for the smallest chunk size that still has charsPerChunk * bitsPerChar be a multiple of 8.
- */
- int gcd = Math.min(8, Integer.lowestOneBit(bitsPerChar));
- this.charsPerChunk = 8 / gcd;
- this.bytesPerChunk = bitsPerChar / gcd;
-
- this.mask = chars.length - 1;
-
- byte[] decodabet = new byte[Ascii.MAX + 1];
- Arrays.fill(decodabet, (byte) -1);
- for (int i = 0; i < chars.length; i++) {
- char c = chars[i];
- checkArgument(CharMatcher.ASCII.matches(c), "Non-ASCII character: %s", c);
- checkArgument(decodabet[c] == -1, "Duplicate character: %s", c);
- decodabet[c] = (byte) i;
- }
- this.decodabet = decodabet;
-
- boolean[] validPadding = new boolean[charsPerChunk];
- for (int i = 0; i < bytesPerChunk; i++) {
- validPadding[divide(i * 8, bitsPerChar, CEILING)] = true;
- }
- this.validPadding = validPadding;
- }
-
- char encode(int bits) {
- return chars[bits];
- }
-
- boolean isValidPaddingStartPosition(int index) {
- return validPadding[index % charsPerChunk];
- }
-
- int decode(char ch) throws IOException {
- if (ch > Ascii.MAX || decodabet[ch] == -1) {
- throw new IOException("Unrecognized character: " + ch);
- }
- return decodabet[ch];
- }
-
- private boolean hasLowerCase() {
- for (char c : chars) {
- if (Ascii.isLowerCase(c)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean hasUpperCase() {
- for (char c : chars) {
- if (Ascii.isUpperCase(c)) {
- return true;
- }
- }
- return false;
- }
-
- Alphabet upperCase() {
- if (!hasLowerCase()) {
- return this;
- } else {
- checkState(!hasUpperCase(), "Cannot call upperCase() on a mixed-case alphabet");
- char[] upperCased = new char[chars.length];
- for (int i = 0; i < chars.length; i++) {
- upperCased[i] = Ascii.toUpperCase(chars[i]);
- }
- return new Alphabet(name + ".upperCase()", upperCased);
- }
- }
-
- Alphabet lowerCase() {
- if (!hasUpperCase()) {
- return this;
- } else {
- checkState(!hasLowerCase(), "Cannot call lowerCase() on a mixed-case alphabet");
- char[] lowerCased = new char[chars.length];
- for (int i = 0; i < chars.length; i++) {
- lowerCased[i] = Ascii.toLowerCase(chars[i]);
- }
- return new Alphabet(name + ".lowerCase()", lowerCased);
- }
- }
-
- @Override
- public boolean matches(char c) {
- return CharMatcher.ASCII.matches(c) && decodabet[c] != -1;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- static final class StandardBaseEncoding extends BaseEncoding {
- // TODO(user): provide a useful toString
- private final Alphabet alphabet;
-
- @Nullable
- private final Character paddingChar;
-
- StandardBaseEncoding(String name, String alphabetChars, @Nullable Character paddingChar) {
- this(new Alphabet(name, alphabetChars.toCharArray()), paddingChar);
- }
-
- StandardBaseEncoding(Alphabet alphabet, Character paddingChar) {
- this.alphabet = checkNotNull(alphabet);
- checkArgument(paddingChar == null || !alphabet.matches(paddingChar),
- "Padding character %s was already in alphabet", paddingChar);
- this.paddingChar = paddingChar;
- }
-
- @Override
- CharMatcher padding() {
- return (paddingChar == null) ? CharMatcher.NONE : CharMatcher.is(paddingChar.charValue());
- }
-
- @Override
- int maxEncodedSize(int bytes) {
- return alphabet.charsPerChunk * divide(bytes, alphabet.bytesPerChunk, CEILING);
- }
-
- @Override
- ByteOutput encodingStream(final CharOutput out) {
- checkNotNull(out);
- return new ByteOutput() {
- int bitBuffer = 0;
- int bitBufferLength = 0;
- int writtenChars = 0;
-
- @Override
- public void write(byte b) throws IOException {
- bitBuffer <<= 8;
- bitBuffer |= b & 0xFF;
- bitBufferLength += 8;
- while (bitBufferLength >= alphabet.bitsPerChar) {
- int charIndex = (bitBuffer >> (bitBufferLength - alphabet.bitsPerChar))
- & alphabet.mask;
- out.write(alphabet.encode(charIndex));
- writtenChars++;
- bitBufferLength -= alphabet.bitsPerChar;
- }
- }
-
- @Override
- public void flush() throws IOException {
- out.flush();
- }
-
- @Override
- public void close() throws IOException {
- if (bitBufferLength > 0) {
- int charIndex = (bitBuffer << (alphabet.bitsPerChar - bitBufferLength))
- & alphabet.mask;
- out.write(alphabet.encode(charIndex));
- writtenChars++;
- if (paddingChar != null) {
- while (writtenChars % alphabet.charsPerChunk != 0) {
- out.write(paddingChar.charValue());
- writtenChars++;
- }
- }
- }
- out.close();
- }
- };
- }
-
- @Override
- int maxDecodedSize(int chars) {
- return (int) ((alphabet.bitsPerChar * (long) chars + 7L) / 8L);
- }
-
- @Override
- ByteInput decodingStream(final CharInput reader) {
- checkNotNull(reader);
- return new ByteInput() {
- int bitBuffer = 0;
- int bitBufferLength = 0;
- int readChars = 0;
- boolean hitPadding = false;
- final CharMatcher paddingMatcher = padding();
-
- @Override
- public int read() throws IOException {
- while (true) {
- int readChar = reader.read();
- if (readChar == -1) {
- if (!hitPadding && !alphabet.isValidPaddingStartPosition(readChars)) {
- throw new IOException("Invalid input length " + readChars);
- }
- return -1;
- }
- readChars++;
- char ch = (char) readChar;
- if (paddingMatcher.matches(ch)) {
- if (!hitPadding
- && (readChars == 1 || !alphabet.isValidPaddingStartPosition(readChars - 1))) {
- throw new IOException("Padding cannot start at index " + readChars);
- }
- hitPadding = true;
- } else if (hitPadding) {
- throw new IOException(
- "Expected padding character but found '" + ch + "' at index " + readChars);
- } else {
- bitBuffer <<= alphabet.bitsPerChar;
- bitBuffer |= alphabet.decode(ch);
- bitBufferLength += alphabet.bitsPerChar;
-
- if (bitBufferLength >= 8) {
- bitBufferLength -= 8;
- return (bitBuffer >> bitBufferLength) & 0xFF;
- }
- }
- }
- }
-
- @Override
- public void close() throws IOException {
- reader.close();
- }
- };
- }
-
- @Override
- public BaseEncoding omitPadding() {
- return (paddingChar == null) ? this : new StandardBaseEncoding(alphabet, null);
- }
-
- @Override
- public BaseEncoding withPadChar(char padChar) {
- if (8 % alphabet.bitsPerChar == 0 ||
- (paddingChar != null && paddingChar.charValue() == padChar)) {
- return this;
- } else {
- return new StandardBaseEncoding(alphabet, padChar);
- }
- }
-
- @Override
- public BaseEncoding withSeparator(String separator, int afterEveryChars) {
- checkNotNull(separator);
- checkArgument(padding().or(alphabet).matchesNoneOf(separator),
- "Separator cannot contain alphabet or padding characters");
- return new SeparatedBaseEncoding(this, separator, afterEveryChars);
- }
-
- private transient BaseEncoding upperCase;
- private transient BaseEncoding lowerCase;
-
- @Override
- public BaseEncoding upperCase() {
- BaseEncoding result = upperCase;
- if (result == null) {
- Alphabet upper = alphabet.upperCase();
- result = upperCase =
- (upper == alphabet) ? this : new StandardBaseEncoding(upper, paddingChar);
- }
- return result;
- }
-
- @Override
- public BaseEncoding lowerCase() {
- BaseEncoding result = lowerCase;
- if (result == null) {
- Alphabet lower = alphabet.lowerCase();
- result = lowerCase =
- (lower == alphabet) ? this : new StandardBaseEncoding(lower, paddingChar);
- }
- return result;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder("BaseEncoding.");
- builder.append(alphabet.toString());
- if (8 % alphabet.bitsPerChar != 0) {
- if (paddingChar == null) {
- builder.append(".omitPadding()");
- } else {
- builder.append(".withPadChar(").append(paddingChar).append(')');
- }
- }
- return builder.toString();
- }
- }
-
- static CharInput ignoringInput(final CharInput delegate, final CharMatcher toIgnore) {
- checkNotNull(delegate);
- checkNotNull(toIgnore);
- return new CharInput() {
- @Override
- public int read() throws IOException {
- int readChar;
- do {
- readChar = delegate.read();
- } while (readChar != -1 && toIgnore.matches((char) readChar));
- return readChar;
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
- };
- }
-
- static CharOutput separatingOutput(
- final CharOutput delegate, final String separator, final int afterEveryChars) {
- checkNotNull(delegate);
- checkNotNull(separator);
- checkArgument(afterEveryChars > 0);
- return new CharOutput() {
- int charsUntilSeparator = afterEveryChars;
-
- @Override
- public void write(char c) throws IOException {
- if (charsUntilSeparator == 0) {
- for (int i = 0; i < separator.length(); i++) {
- delegate.write(separator.charAt(i));
- }
- charsUntilSeparator = afterEveryChars;
- }
- delegate.write(c);
- charsUntilSeparator--;
- }
-
- @Override
- public void flush() throws IOException {
- delegate.flush();
- }
-
- @Override
- public void close() throws IOException {
- delegate.close();
- }
- };
- }
-
- static final class SeparatedBaseEncoding extends BaseEncoding {
- private final BaseEncoding delegate;
- private final String separator;
- private final int afterEveryChars;
- private final CharMatcher separatorChars;
-
- SeparatedBaseEncoding(BaseEncoding delegate, String separator, int afterEveryChars) {
- this.delegate = checkNotNull(delegate);
- this.separator = checkNotNull(separator);
- this.afterEveryChars = afterEveryChars;
- checkArgument(
- afterEveryChars > 0, "Cannot add a separator after every %s chars", afterEveryChars);
- this.separatorChars = CharMatcher.anyOf(separator).precomputed();
- }
-
- @Override
- CharMatcher padding() {
- return delegate.padding();
- }
-
- @Override
- int maxEncodedSize(int bytes) {
- int unseparatedSize = delegate.maxEncodedSize(bytes);
- return unseparatedSize + separator.length()
- * divide(Math.max(0, unseparatedSize - 1), afterEveryChars, FLOOR);
- }
-
- @Override
- ByteOutput encodingStream(final CharOutput output) {
- return delegate.encodingStream(separatingOutput(output, separator, afterEveryChars));
- }
-
- @Override
- int maxDecodedSize(int chars) {
- return delegate.maxDecodedSize(chars);
- }
-
- @Override
- ByteInput decodingStream(final CharInput input) {
- return delegate.decodingStream(ignoringInput(input, separatorChars));
- }
-
- @Override
- public BaseEncoding omitPadding() {
- return delegate.omitPadding().withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public BaseEncoding withPadChar(char padChar) {
- return delegate.withPadChar(padChar).withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public BaseEncoding withSeparator(String separator, int afterEveryChars) {
- throw new UnsupportedOperationException("Already have a separator");
- }
-
- @Override
- public BaseEncoding upperCase() {
- return delegate.upperCase().withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public BaseEncoding lowerCase() {
- return delegate.lowerCase().withSeparator(separator, afterEveryChars);
- }
-
- @Override
- public String toString() {
- return delegate.toString() +
- ".withSeparator(\"" + separator + "\", " + afterEveryChars + ")";
- }
- }
-}
diff --git a/guava/src/com/google/common/io/ByteArrayDataInput.java b/guava/src/com/google/common/io/ByteArrayDataInput.java
index 3f4a467..f374b4e 100644
--- a/guava/src/com/google/common/io/ByteArrayDataInput.java
+++ b/guava/src/com/google/common/io/ByteArrayDataInput.java
@@ -22,44 +22,26 @@ import java.io.IOException;
/**
* An extension of {@code DataInput} for reading from in-memory byte arrays; its
* methods offer identical functionality but do not throw {@link IOException}.
- *
- * <p><b>Warning:<b> The caller is responsible for not attempting to read past
- * the end of the array. If any method encounters the end of the array
- * prematurely, it throws {@link IllegalStateException} to signify <i>programmer
- * error</i>. This behavior is a technical violation of the supertype's
- * contract, which specifies a checked exception.
+ * If any method encounters the end of the array prematurely, it throws {@link
+ * IllegalStateException}.
*
* @author Kevin Bourrillion
* @since 1.0
*/
public interface ByteArrayDataInput extends DataInput {
@Override void readFully(byte b[]);
-
@Override void readFully(byte b[], int off, int len);
-
@Override int skipBytes(int n);
-
@Override boolean readBoolean();
-
@Override byte readByte();
-
@Override int readUnsignedByte();
-
@Override short readShort();
-
@Override int readUnsignedShort();
-
@Override char readChar();
-
@Override int readInt();
-
@Override long readLong();
-
@Override float readFloat();
-
@Override double readDouble();
-
@Override String readLine();
-
@Override String readUTF();
}
diff --git a/guava/src/com/google/common/io/ByteSink.java b/guava/src/com/google/common/io/ByteSink.java
deleted file mode 100644
index 781b2c3..0000000
--- a/guava/src/com/google/common/io/ByteSink.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.Charset;
-
-/**
- * A destination to which bytes can be written, such as a file. Unlike an {@link OutputStream}, a
- * {@code ByteSink} is not an open, stateful stream that can be written to and closed. Instead, it
- * is an immutable <i>supplier</i> of {@code OutputStream} instances.
- *
- * <p>{@code ByteSink} provides two kinds of methods:
- * <ul>
- * <li><b>Methods that return a stream:</b> These methods should return a <i>new</i>, independent
- * instance each time they are called. The caller is responsible for ensuring that the returned
- * stream is closed.
- * <li><b>Convenience methods:</b> These are implementations of common operations that are
- * typically implemented by opening a stream using one of the methods in the first category, doing
- * something and finally closing the stream or channel that was opened.
- * </ul>
- *
- * @since 14.0
- * @author Colin Decker
- */
-public abstract class ByteSink {
-
- /**
- * Returns a {@link CharSink} view of this {@code ByteSink} that writes characters to this sink
- * as bytes encoded with the given {@link Charset charset}.
- */
- public CharSink asCharSink(Charset charset) {
- return new AsCharSink(charset);
- }
-
- /**
- * Opens a new {@link OutputStream} for writing to this sink. This method should return a new,
- * independent stream each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned stream is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the stream
- */
- public abstract OutputStream openStream() throws IOException;
-
- /**
- * Opens a new {@link BufferedOutputStream} for writing to this sink. This method should return a
- * new, independent stream each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned stream is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the stream
- */
- public BufferedOutputStream openBufferedStream() throws IOException {
- OutputStream out = openStream();
- return (out instanceof BufferedOutputStream)
- ? (BufferedOutputStream) out
- : new BufferedOutputStream(out);
- }
-
- /**
- * Writes all the given bytes to this sink.
- *
- * @throws IOException if an I/O occurs in the process of writing to this sink
- */
- public void write(byte[] bytes) throws IOException {
- checkNotNull(bytes);
-
- Closer closer = Closer.create();
- try {
- OutputStream out = closer.register(openStream());
- out.write(bytes);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Writes all the bytes from the given {@code InputStream} to this sink. Does not close
- * {@code input}.
- *
- * @throws IOException if an I/O occurs in the process of reading from {@code input} or writing to
- * this sink
- */
- public long writeFrom(InputStream input) throws IOException {
- checkNotNull(input);
-
- Closer closer = Closer.create();
- try {
- OutputStream out = closer.register(openStream());
- return ByteStreams.copy(input, out);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * A char sink that encodes written characters with a charset and writes resulting bytes to this
- * byte sink.
- */
- private final class AsCharSink extends CharSink {
-
- private final Charset charset;
-
- private AsCharSink(Charset charset) {
- this.charset = checkNotNull(charset);
- }
-
- @Override
- public Writer openStream() throws IOException {
- return new OutputStreamWriter(ByteSink.this.openStream(), charset);
- }
-
- @Override
- public String toString() {
- return ByteSink.this.toString() + ".asCharSink(" + charset + ")";
- }
- }
-}
diff --git a/guava/src/com/google/common/io/ByteSource.java b/guava/src/com/google/common/io/ByteSource.java
deleted file mode 100644
index 44bb6ff..0000000
--- a/guava/src/com/google/common/io/ByteSource.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.hash.Funnels;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
-import com.google.common.hash.Hasher;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-
-/**
- * A readable source of bytes, such as a file. Unlike an {@link InputStream}, a
- * {@code ByteSource} is not an open, stateful stream for input that can be read and closed.
- * Instead, it is an immutable <i>supplier</i> of {@code InputStream} instances.
- *
- * <p>{@code ByteSource} provides two kinds of methods:
- * <ul>
- * <li><b>Methods that return a stream:</b> These methods should return a <i>new</i>, independent
- * instance each time they are called. The caller is responsible for ensuring that the returned
- * stream is closed.
- * <li><b>Convenience methods:</b> These are implementations of common operations that are
- * typically implemented by opening a stream using one of the methods in the first category, doing
- * something and finally closing the stream that was opened.
- * </ul>
- *
- * @since 14.0
- * @author Colin Decker
- */
-public abstract class ByteSource {
-
- private static final int BUF_SIZE = 0x1000; // 4K
-
- /**
- * Returns a {@link CharSource} view of this byte source that decodes bytes read from this source
- * as characters using the given {@link Charset}.
- */
- public CharSource asCharSource(Charset charset) {
- return new AsCharSource(charset);
- }
-
- /**
- * Opens a new {@link InputStream} for reading from this source. This method should return a new,
- * independent stream each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned stream is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the stream
- */
- public abstract InputStream openStream() throws IOException;
-
- /**
- * Opens a new {@link BufferedInputStream} for reading from this source. This method should return
- * a new, independent stream each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned stream is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the stream
- */
- public BufferedInputStream openBufferedStream() throws IOException {
- InputStream in = openStream();
- return (in instanceof BufferedInputStream)
- ? (BufferedInputStream) in
- : new BufferedInputStream(in);
- }
-
- /**
- * Returns a view of a slice of this byte source that is at most {@code length} bytes long
- * starting at the given {@code offset}.
- *
- * @throws IllegalArgumentException if {@code offset} or {@code length} is negative
- */
- public ByteSource slice(long offset, long length) {
- return new SlicedByteSource(offset, length);
- }
-
- /**
- * Returns the size of this source in bytes. For most implementations, this is a heavyweight
- * operation that will open a stream, read (or {@link InputStream#skip(long) skip}, if possible)
- * to the end of the stream and return the total number of bytes that were read.
- *
- * <p>For some sources, such as a file, this method may use a more efficient implementation. Note
- * that in such cases, it is <i>possible</i> that this method will return a different number of
- * bytes than would be returned by reading all of the bytes (for example, some special files may
- * return a size of 0 despite actually having content when read).
- *
- * <p>In either case, if this is a mutable source such as a file, the size it returns may not be
- * the same number of bytes a subsequent read would return.
- *
- * @throws IOException if an I/O error occurs in the process of reading the size of this source
- */
- public long size() throws IOException {
- Closer closer = Closer.create();
- try {
- InputStream in = closer.register(openStream());
- return countBySkipping(in);
- } catch (IOException e) {
- // skip may not be supported... at any rate, try reading
- } finally {
- closer.close();
- }
-
- closer = Closer.create();
- try {
- InputStream in = closer.register(openStream());
- return countByReading(in);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Counts the bytes in the given input stream using skip if possible. Returns SKIP_FAILED if the
- * first call to skip threw, in which case skip may just not be supported.
- */
- private long countBySkipping(InputStream in) throws IOException {
- long count = 0;
- while (true) {
- // don't try to skip more than available()
- // things may work really wrong with FileInputStream otherwise
- long skipped = in.skip(Math.min(in.available(), Integer.MAX_VALUE));
- if (skipped <= 0) {
- if (in.read() == -1) {
- return count;
- }
- count++;
- } else {
- count += skipped;
- }
- }
- }
-
- private static final byte[] countBuffer = new byte[BUF_SIZE];
-
- private long countByReading(InputStream in) throws IOException {
- long count = 0;
- long read;
- while ((read = in.read(countBuffer)) != -1) {
- count += read;
- }
- return count;
- }
-
- /**
- * Copies the contents of this byte source to the given {@code OutputStream}. Does not close
- * {@code output}.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source or
- * writing to {@code output}
- */
- public long copyTo(OutputStream output) throws IOException {
- checkNotNull(output);
-
- Closer closer = Closer.create();
- try {
- InputStream in = closer.register(openStream());
- return ByteStreams.copy(in, output);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Copies the contents of this byte source to the given {@code ByteSink}.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source or
- * writing to {@code sink}
- */
- public long copyTo(ByteSink sink) throws IOException {
- checkNotNull(sink);
-
- Closer closer = Closer.create();
- try {
- InputStream in = closer.register(openStream());
- OutputStream out = closer.register(sink.openStream());
- return ByteStreams.copy(in, out);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Reads the full contents of this byte source as a byte array.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source
- */
- public byte[] read() throws IOException {
- Closer closer = Closer.create();
- try {
- InputStream in = closer.register(openStream());
- return ByteStreams.toByteArray(in);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Hashes the contents of this byte source using the given hash function.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source
- */
- public HashCode hash(HashFunction hashFunction) throws IOException {
- Hasher hasher = hashFunction.newHasher();
- copyTo(Funnels.asOutputStream(hasher));
- return hasher.hash();
- }
-
- /**
- * Checks that the contents of this byte source are equal to the contents of the given byte
- * source.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source or
- * {@code other}
- */
- public boolean contentEquals(ByteSource other) throws IOException {
- checkNotNull(other);
-
- byte[] buf1 = new byte[BUF_SIZE];
- byte[] buf2 = new byte[BUF_SIZE];
-
- Closer closer = Closer.create();
- try {
- InputStream in1 = closer.register(openStream());
- InputStream in2 = closer.register(other.openStream());
- while (true) {
- int read1 = ByteStreams.read(in1, buf1, 0, BUF_SIZE);
- int read2 = ByteStreams.read(in2, buf2, 0, BUF_SIZE);
- if (read1 != read2 || !Arrays.equals(buf1, buf2)) {
- return false;
- } else if (read1 != BUF_SIZE) {
- return true;
- }
- }
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * A char source that reads bytes from this source and decodes them as characters using a
- * charset.
- */
- private final class AsCharSource extends CharSource {
-
- private final Charset charset;
-
- private AsCharSource(Charset charset) {
- this.charset = checkNotNull(charset);
- }
-
- @Override
- public Reader openStream() throws IOException {
- return new InputStreamReader(ByteSource.this.openStream(), charset);
- }
-
- @Override
- public String toString() {
- return ByteSource.this.toString() + ".asCharSource(" + charset + ")";
- }
- }
-
- /**
- * A view of a subsection of the containing byte source.
- */
- private final class SlicedByteSource extends ByteSource {
-
- private final long offset;
- private final long length;
-
- private SlicedByteSource(long offset, long length) {
- checkArgument(offset >= 0, "offset (%s) may not be negative", offset);
- checkArgument(length >= 0, "length (%s) may not be negative", length);
- this.offset = offset;
- this.length = length;
- }
-
- @Override
- public InputStream openStream() throws IOException {
- InputStream in = ByteSource.this.openStream();
- if (offset > 0) {
- try {
- ByteStreams.skipFully(in, offset);
- } catch (Throwable e) {
- Closer closer = Closer.create();
- closer.register(in);
- try {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
- }
- return ByteStreams.limit(in, length);
- }
-
- @Override
- public ByteSource slice(long offset, long length) {
- checkArgument(offset >= 0, "offset (%s) may not be negative", offset);
- checkArgument(length >= 0, "length (%s) may not be negative", length);
- long maxLength = this.length - offset;
- return ByteSource.this.slice(this.offset + offset, Math.min(length, maxLength));
- }
-
- @Override
- public String toString() {
- return ByteSource.this.toString() + ".slice(" + offset + ", " + length + ")";
- }
- }
-}
diff --git a/guava/src/com/google/common/io/ByteStreams.java b/guava/src/com/google/common/io/ByteStreams.java
index 4259d2b..78e63c5 100644
--- a/guava/src/com/google/common/io/ByteStreams.java
+++ b/guava/src/com/google/common/io/ByteStreams.java
@@ -16,13 +16,8 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndex;
-
import com.google.common.annotations.Beta;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
+import com.google.common.base.Preconditions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -31,21 +26,22 @@ import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.EOFException;
-import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
+import java.security.MessageDigest;
import java.util.Arrays;
import java.util.zip.Checksum;
/**
* Provides utility methods for working with byte arrays and I/O streams.
*
+ * <p>All method parameters must be non-null unless documented otherwise.
+ *
* @author Chris Nokleberg
- * @author Colin Decker
* @since 1.0
*/
@Beta
@@ -63,7 +59,7 @@ public final class ByteStreams {
*/
public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier(
byte[] b) {
- return ByteStreams.asInputSupplier(asByteSource(b));
+ return newInputStreamSupplier(b, 0, b.length);
}
/**
@@ -77,58 +73,12 @@ public final class ByteStreams {
*/
public static InputSupplier<ByteArrayInputStream> newInputStreamSupplier(
final byte[] b, final int off, final int len) {
- return ByteStreams.asInputSupplier(asByteSource(b).slice(off, len));
- }
-
- /**
- * Returns a new {@link ByteSource} that reads bytes from the given byte array.
- *
- * @since 14.0
- */
- public static ByteSource asByteSource(byte[] b) {
- return new ByteArrayByteSource(b);
- }
-
- private static final class ByteArrayByteSource extends ByteSource {
-
- private final byte[] bytes;
-
- private ByteArrayByteSource(byte[] bytes) {
- this.bytes = checkNotNull(bytes);
- }
-
- @Override
- public InputStream openStream() throws IOException {
- return new ByteArrayInputStream(bytes);
- }
-
- @Override
- public long size() throws IOException {
- return bytes.length;
- }
-
- @Override
- public byte[] read() throws IOException {
- return bytes.clone();
- }
-
- @Override
- public long copyTo(OutputStream output) throws IOException {
- output.write(bytes);
- return bytes.length;
- }
-
- @Override
- public HashCode hash(HashFunction hashFunction) throws IOException {
- return hashFunction.hashBytes(bytes);
- }
-
- // TODO(user): Possibly override slice()
-
- @Override
- public String toString() {
- return "ByteStreams.asByteSource(" + BaseEncoding.base16().encode(bytes) + ")";
- }
+ return new InputSupplier<ByteArrayInputStream>() {
+ @Override
+ public ByteArrayInputStream getInput() {
+ return new ByteArrayInputStream(b, off, len);
+ }
+ };
}
/**
@@ -140,7 +90,15 @@ public final class ByteStreams {
*/
public static void write(byte[] from,
OutputSupplier<? extends OutputStream> to) throws IOException {
- asByteSink(to).write(from);
+ Preconditions.checkNotNull(from);
+ boolean threw = true;
+ OutputStream out = to.getOutput();
+ try {
+ out.write(from);
+ threw = false;
+ } finally {
+ Closeables.close(out, threw);
+ }
}
/**
@@ -154,7 +112,21 @@ public final class ByteStreams {
*/
public static long copy(InputSupplier<? extends InputStream> from,
OutputSupplier<? extends OutputStream> to) throws IOException {
- return asByteSource(from).copyTo(asByteSink(to));
+ int successfulOps = 0;
+ InputStream in = from.getInput();
+ try {
+ OutputStream out = to.getOutput();
+ try {
+ long count = copy(in, out);
+ successfulOps++;
+ return count;
+ } finally {
+ Closeables.close(out, successfulOps < 1);
+ successfulOps++;
+ }
+ } finally {
+ Closeables.close(in, successfulOps < 2);
+ }
}
/**
@@ -169,13 +141,21 @@ public final class ByteStreams {
*/
public static long copy(InputSupplier<? extends InputStream> from,
OutputStream to) throws IOException {
- return asByteSource(from).copyTo(to);
+ boolean threw = true;
+ InputStream in = from.getInput();
+ try {
+ long count = copy(in, to);
+ threw = false;
+ return count;
+ } finally {
+ Closeables.close(in, threw);
+ }
}
/**
* Opens an output stream from the supplier, copies all bytes from the input
* to the output, and closes the output stream. Does not close or flush the
- * input stream.
+ * output stream.
*
* @param from the input stream to read from
* @param to the output factory
@@ -185,7 +165,15 @@ public final class ByteStreams {
*/
public static long copy(InputStream from,
OutputSupplier<? extends OutputStream> to) throws IOException {
- return asByteSink(to).writeFrom(from);
+ boolean threw = true;
+ OutputStream out = to.getOutput();
+ try {
+ long count = copy(from, out);
+ threw = false;
+ return count;
+ } finally {
+ Closeables.close(out, threw);
+ }
}
/**
@@ -199,8 +187,6 @@ public final class ByteStreams {
*/
public static long copy(InputStream from, OutputStream to)
throws IOException {
- checkNotNull(from);
- checkNotNull(to);
byte[] buf = new byte[BUF_SIZE];
long total = 0;
while (true) {
@@ -225,8 +211,6 @@ public final class ByteStreams {
*/
public static long copy(ReadableByteChannel from,
WritableByteChannel to) throws IOException {
- checkNotNull(from);
- checkNotNull(to);
ByteBuffer buf = ByteBuffer.allocate(BUF_SIZE);
long total = 0;
while (from.read(buf) != -1) {
@@ -261,7 +245,15 @@ public final class ByteStreams {
*/
public static byte[] toByteArray(
InputSupplier<? extends InputStream> supplier) throws IOException {
- return asByteSource(supplier).read();
+ boolean threw = true;
+ InputStream in = supplier.getInput();
+ try {
+ byte[] result = toByteArray(in);
+ threw = false;
+ return result;
+ } finally {
+ Closeables.close(in, threw);
+ }
}
/**
@@ -280,7 +272,7 @@ public final class ByteStreams {
* than the length of the array
*/
public static ByteArrayDataInput newDataInput(byte[] bytes, int start) {
- checkPositionIndex(start, bytes.length);
+ Preconditions.checkPositionIndex(start, bytes.length);
return new ByteArrayDataInputStream(bytes, start);
}
@@ -433,7 +425,7 @@ public final class ByteStreams {
* @throws IllegalArgumentException if {@code size} is negative
*/
public static ByteArrayDataOutput newDataOutput(int size) {
- checkArgument(size >= 0, "Invalid size: %s", size);
+ Preconditions.checkArgument(size >= 0, "Invalid size: %s", size);
return new ByteArrayDataOutputStream(size);
}
@@ -572,123 +564,35 @@ public final class ByteStreams {
@Override public byte[] toByteArray() {
return byteArrayOutputSteam.toByteArray();
}
- }
-
- private static final OutputStream NULL_OUTPUT_STREAM =
- new OutputStream() {
- /** Discards the specified byte. */
- @Override public void write(int b) {
- }
- /** Discards the specified byte array. */
- @Override public void write(byte[] b) {
- checkNotNull(b);
- }
- /** Discards the specified byte array. */
- @Override public void write(byte[] b, int off, int len) {
- checkNotNull(b);
- }
-
- @Override
- public String toString() {
- return "ByteStreams.nullOutputStream()";
- }
- };
-
- /**
- * Returns an {@link OutputStream} that simply discards written bytes.
- *
- * @since 14.0 (since 1.0 as com.google.common.io.NullOutputStream)
- */
- public static OutputStream nullOutputStream() {
- return NULL_OUTPUT_STREAM;
- }
- /**
- * Wraps a {@link InputStream}, limiting the number of bytes which can be
- * read.
- *
- * @param in the input stream to be wrapped
- * @param limit the maximum number of bytes to be read
- * @return a length-limited {@link InputStream}
- * @since 14.0 (since 1.0 as com.google.common.io.LimitInputStream)
- */
- public static InputStream limit(InputStream in, long limit) {
- return new LimitedInputStream(in, limit);
}
- private static final class LimitedInputStream extends FilterInputStream {
-
- private long left;
- private long mark = -1;
-
- LimitedInputStream(InputStream in, long limit) {
- super(in);
- checkNotNull(in);
- checkArgument(limit >= 0, "limit must be non-negative");
- left = limit;
- }
-
- @Override public int available() throws IOException {
- return (int) Math.min(in.available(), left);
- }
-
- // it's okay to mark even if mark isn't supported, as reset won't work
- @Override public synchronized void mark(int readLimit) {
- in.mark(readLimit);
- mark = left;
- }
-
- @Override public int read() throws IOException {
- if (left == 0) {
- return -1;
- }
-
- int result = in.read();
- if (result != -1) {
- --left;
- }
- return result;
- }
-
- @Override public int read(byte[] b, int off, int len) throws IOException {
- if (left == 0) {
- return -1;
- }
-
- len = (int) Math.min(len, left);
- int result = in.read(b, off, len);
- if (result != -1) {
- left -= result;
- }
- return result;
- }
-
- @Override public synchronized void reset() throws IOException {
- if (!in.markSupported()) {
- throw new IOException("Mark not supported");
- }
- if (mark == -1) {
- throw new IOException("Mark not set");
+ // TODO(chrisn): Not all streams support skipping.
+ /** Returns the length of a supplied input stream, in bytes. */
+ public static long length(InputSupplier<? extends InputStream> supplier)
+ throws IOException {
+ long count = 0;
+ boolean threw = true;
+ InputStream in = supplier.getInput();
+ try {
+ while (true) {
+ // We skip only Integer.MAX_VALUE due to JDK overflow bugs.
+ long amt = in.skip(Integer.MAX_VALUE);
+ if (amt == 0) {
+ if (in.read() == -1) {
+ threw = false;
+ return count;
+ }
+ count++;
+ } else {
+ count += amt;
+ }
}
-
- in.reset();
- left = mark;
- }
-
- @Override public long skip(long n) throws IOException {
- n = Math.min(n, left);
- long skipped = in.skip(n);
- left -= skipped;
- return skipped;
+ } finally {
+ Closeables.close(in, threw);
}
}
- /** Returns the length of a supplied input stream, in bytes. */
- public static long length(
- InputSupplier<? extends InputStream> supplier) throws IOException {
- return asByteSource(supplier).size();
- }
-
/**
* Returns true if the supplied input streams contain the same bytes.
*
@@ -696,7 +600,31 @@ public final class ByteStreams {
*/
public static boolean equal(InputSupplier<? extends InputStream> supplier1,
InputSupplier<? extends InputStream> supplier2) throws IOException {
- return asByteSource(supplier1).contentEquals(asByteSource(supplier2));
+ byte[] buf1 = new byte[BUF_SIZE];
+ byte[] buf2 = new byte[BUF_SIZE];
+
+ boolean threw = true;
+ InputStream in1 = supplier1.getInput();
+ try {
+ InputStream in2 = supplier2.getInput();
+ try {
+ while (true) {
+ int read1 = read(in1, buf1, 0, BUF_SIZE);
+ int read2 = read(in2, buf2, 0, BUF_SIZE);
+ if (read1 != read2 || !Arrays.equals(buf1, buf2)) {
+ threw = false;
+ return false;
+ } else if (read1 != BUF_SIZE) {
+ threw = false;
+ return true;
+ }
+ }
+ } finally {
+ Closeables.close(in2, threw);
+ }
+ } finally {
+ Closeables.close(in1, threw);
+ }
}
/**
@@ -728,12 +656,10 @@ public final class ByteStreams {
* the bytes.
* @throws IOException if an I/O error occurs.
*/
- public static void readFully(
- InputStream in, byte[] b, int off, int len) throws IOException {
- int read = read(in, b, off, len);
- if (read != len) {
- throw new EOFException("reached end of stream after reading "
- + read + " bytes; " + len + " bytes expected");
+ public static void readFully(InputStream in, byte[] b, int off, int len)
+ throws IOException {
+ if (read(in, b, off, len) != len) {
+ throw new EOFException();
}
}
@@ -750,15 +676,12 @@ public final class ByteStreams {
* support skipping
*/
public static void skipFully(InputStream in, long n) throws IOException {
- long toSkip = n;
while (n > 0) {
long amt = in.skip(n);
if (amt == 0) {
// Force a blocking read to avoid infinite loop
if (in.read() == -1) {
- long skipped = toSkip - n;
- throw new EOFException("reached end of stream after skipping "
- + skipped + " bytes; " + toSkip + " bytes expected");
+ throw new EOFException();
}
n--;
} else {
@@ -775,46 +698,27 @@ public final class ByteStreams {
* @return the result of the byte processor
* @throws IOException if an I/O error occurs
*/
- public static <T> T readBytes(
- InputSupplier<? extends InputStream> supplier,
+ public static <T> T readBytes(InputSupplier<? extends InputStream> supplier,
ByteProcessor<T> processor) throws IOException {
- checkNotNull(supplier);
- checkNotNull(processor);
-
- Closer closer = Closer.create();
+ byte[] buf = new byte[BUF_SIZE];
+ boolean threw = true;
+ InputStream in = supplier.getInput();
try {
- InputStream in = closer.register(supplier.getInput());
- return readBytes(in, processor);
- } catch (Throwable e) {
- throw closer.rethrow(e);
+ int amt;
+ do {
+ amt = in.read(buf);
+ if (amt == -1) {
+ threw = false;
+ break;
+ }
+ } while (processor.processBytes(buf, 0, amt));
+ return processor.getResult();
} finally {
- closer.close();
+ Closeables.close(in, threw);
}
}
/**
- * Process the bytes of the given input stream using the given processor.
- *
- * @param input the input stream to process
- * @param processor the object to which to pass the bytes of the stream
- * @return the result of the byte processor
- * @throws IOException if an I/O error occurs
- * @since 14.0
- */
- public static <T> T readBytes(
- InputStream input, ByteProcessor<T> processor) throws IOException {
- checkNotNull(input);
- checkNotNull(processor);
-
- byte[] buf = new byte[BUF_SIZE];
- int read;
- do {
- read = input.read(buf);
- } while (read != -1 && processor.processBytes(buf, 0, read));
- return processor.getResult();
- }
-
- /**
* Computes and returns the checksum value for a supplied input stream.
* The checksum object is reset when this method returns successfully.
*
@@ -823,21 +727,16 @@ public final class ByteStreams {
* @return the result of {@link Checksum#getValue} after updating the
* checksum object with all of the bytes in the stream
* @throws IOException if an I/O error occurs
- * @deprecated Use {@code hash} with the {@code Hashing.crc32()} or
- * {@code Hashing.adler32()} hash functions instead. This method is
- * scheduled to be removed in Guava 15.0.
*/
- @Deprecated
- public static long getChecksum(
- InputSupplier<? extends InputStream> supplier, final Checksum checksum)
- throws IOException {
- checkNotNull(checksum);
+ public static long getChecksum(InputSupplier<? extends InputStream> supplier,
+ final Checksum checksum) throws IOException {
return readBytes(supplier, new ByteProcessor<Long>() {
@Override
public boolean processBytes(byte[] buf, int off, int len) {
checksum.update(buf, off, len);
return true;
}
+
@Override
public Long getResult() {
long result = checksum.getValue();
@@ -848,19 +747,29 @@ public final class ByteStreams {
}
/**
- * Computes the hash code of the data supplied by {@code supplier} using {@code
- * hashFunction}.
+ * Computes and returns the digest value for a supplied input stream.
+ * The digest object is reset when this method returns successfully.
*
* @param supplier the input stream factory
- * @param hashFunction the hash function to use to hash the data
- * @return the {@link HashCode} of all of the bytes in the input stream
+ * @param md the digest object
+ * @return the result of {@link MessageDigest#digest()} after updating the
+ * digest object with all of the bytes in the stream
* @throws IOException if an I/O error occurs
- * @since 12.0
*/
- public static HashCode hash(
- InputSupplier<? extends InputStream> supplier, HashFunction hashFunction)
- throws IOException {
- return asByteSource(supplier).hash(hashFunction);
+ public static byte[] getDigest(InputSupplier<? extends InputStream> supplier,
+ final MessageDigest md) throws IOException {
+ return readBytes(supplier, new ByteProcessor<byte[]>() {
+ @Override
+ public boolean processBytes(byte[] buf, int off, int len) {
+ md.update(buf, off, len);
+ return true;
+ }
+
+ @Override
+ public byte[] getResult() {
+ return md.digest();
+ }
+ });
}
/**
@@ -889,8 +798,6 @@ public final class ByteStreams {
*/
public static int read(InputStream in, byte[] b, int off, int len)
throws IOException {
- checkNotNull(in);
- checkNotNull(b);
if (len < 0) {
throw new IndexOutOfBoundsException("len is negative");
}
@@ -920,7 +827,23 @@ public final class ByteStreams {
final InputSupplier<? extends InputStream> supplier,
final long offset,
final long length) {
- return asInputSupplier(asByteSource(supplier).slice(offset, length));
+ Preconditions.checkNotNull(supplier);
+ Preconditions.checkArgument(offset >= 0, "offset is negative");
+ Preconditions.checkArgument(length >= 0, "length is negative");
+ return new InputSupplier<InputStream>() {
+ @Override public InputStream getInput() throws IOException {
+ InputStream in = supplier.getInput();
+ if (offset > 0) {
+ try {
+ skipFully(in, offset);
+ } catch (IOException e) {
+ Closeables.closeQuietly(in);
+ throw e;
+ }
+ }
+ return new LimitInputStream(in, length);
+ }
+ };
}
/**
@@ -940,7 +863,6 @@ public final class ByteStreams {
*/
public static InputSupplier<InputStream> join(
final Iterable<? extends InputSupplier<? extends InputStream>> suppliers) {
- checkNotNull(suppliers);
return new InputSupplier<InputStream>() {
@Override public InputStream getInput() throws IOException {
return new MultiInputStream(suppliers.iterator());
@@ -953,52 +875,4 @@ public final class ByteStreams {
InputSupplier<? extends InputStream>... suppliers) {
return join(Arrays.asList(suppliers));
}
-
- // TODO(user): Remove these once Input/OutputSupplier methods are removed
-
- static <S extends InputStream> InputSupplier<S> asInputSupplier(
- final ByteSource source) {
- checkNotNull(source);
- return new InputSupplier<S>() {
- @SuppressWarnings("unchecked") // used internally where known to be safe
- @Override
- public S getInput() throws IOException {
- return (S) source.openStream();
- }
- };
- }
-
- static <S extends OutputStream> OutputSupplier<S> asOutputSupplier(
- final ByteSink sink) {
- checkNotNull(sink);
- return new OutputSupplier<S>() {
- @SuppressWarnings("unchecked") // used internally where known to be safe
- @Override
- public S getOutput() throws IOException {
- return (S) sink.openStream();
- }
- };
- }
-
- static ByteSource asByteSource(
- final InputSupplier<? extends InputStream> supplier) {
- checkNotNull(supplier);
- return new ByteSource() {
- @Override
- public InputStream openStream() throws IOException {
- return supplier.getInput();
- }
- };
- }
-
- static ByteSink asByteSink(
- final OutputSupplier<? extends OutputStream> supplier) {
- checkNotNull(supplier);
- return new ByteSink() {
- @Override
- public OutputStream openStream() throws IOException {
- return supplier.getOutput();
- }
- };
- }
}
diff --git a/guava/src/com/google/common/io/CharSink.java b/guava/src/com/google/common/io/CharSink.java
deleted file mode 100644
index 064adcd..0000000
--- a/guava/src/com/google/common/io/CharSink.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.charset.Charset;
-
-/**
- * A destination to which characters can be written, such as a text file. Unlike a {@link Writer}, a
- * {@code CharSink} is not an open, stateful stream that can be written to and closed. Instead, it
- * is an immutable <i>supplier</i> of {@code Writer} instances.
- *
- * <p>{@code CharSink} provides two kinds of methods:
- * <ul>
- * <li><b>Methods that return a writer:</b> These methods should return a <i>new</i>,
- * independent instance each time they are called. The caller is responsible for ensuring that the
- * returned writer is closed.
- * <li><b>Convenience methods:</b> These are implementations of common operations that are
- * typically implemented by opening a writer using one of the methods in the first category,
- * doing something and finally closing the writer that was opened.
- * </ul>
- *
- * <p>Any {@link ByteSink} may be viewed as a {@code CharSink} with a specific {@linkplain Charset
- * character encoding} using {@link ByteSink#asCharSink(Charset)}. Characters written to the
- * resulting {@code CharSink} will written to the {@code ByteSink} as encoded bytes.
- *
- * @since 14.0
- * @author Colin Decker
- */
-public abstract class CharSink {
-
- /**
- * Opens a new {@link Writer} for writing to this sink. This method should return a new,
- * independent writer each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned writer is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the writer
- */
- public abstract Writer openStream() throws IOException;
-
- /**
- * Opens a new {@link BufferedWriter} for writing to this sink. This method should return a new,
- * independent writer each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned writer is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the writer
- */
- public BufferedWriter openBufferedStream() throws IOException {
- Writer writer = openStream();
- return (writer instanceof BufferedWriter)
- ? (BufferedWriter) writer
- : new BufferedWriter(writer);
- }
-
- /**
- * Writes the given character sequence to this sink.
- *
- * @throws IOException if an I/O error in the process of writing to this sink
- */
- public void write(CharSequence charSequence) throws IOException {
- checkNotNull(charSequence);
-
- Closer closer = Closer.create();
- try {
- Writer out = closer.register(openStream());
- out.append(charSequence);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Writes the given lines of text to this sink with each line (including the last) terminated with
- * the operating system's default line separator. This method is equivalent to
- * {@code writeLines(lines, System.getProperty("line.separator"))}.
- *
- * @throws IOException if an I/O error occurs in the process of writing to this sink
- */
- public void writeLines(Iterable<? extends CharSequence> lines) throws IOException {
- writeLines(lines, System.getProperty("line.separator"));
- }
-
- /**
- * Writes the given lines of text to this sink with each line (including the last) terminated with
- * the given line separator.
- *
- * @throws IOException if an I/O error occurs in the process of writing to this sink
- */
- public void writeLines(Iterable<? extends CharSequence> lines, String lineSeparator)
- throws IOException {
- checkNotNull(lines);
- checkNotNull(lineSeparator);
-
- Closer closer = Closer.create();
- try {
- BufferedWriter out = closer.register(openBufferedStream());
- for (CharSequence line : lines) {
- out.append(line).append(lineSeparator);
- }
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Writes all the text from the given {@link Readable} (such as a {@link Reader}) to this sink.
- * Does not close {@code readable} if it is {@code Closeable}.
- *
- * @throws IOException if an I/O error occurs in the process of reading from {@code readable} or
- * writing to this sink
- */
- public long writeFrom(Readable readable) throws IOException {
- checkNotNull(readable);
-
- Closer closer = Closer.create();
- try {
- Writer out = closer.register(openStream());
- return CharStreams.copy(readable, out);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-}
diff --git a/guava/src/com/google/common/io/CharSource.java b/guava/src/com/google/common/io/CharSource.java
deleted file mode 100644
index 057deaf..0000000
--- a/guava/src/com/google/common/io/CharSource.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.nio.charset.Charset;
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-/**
- * A readable source of characters, such as a text file. Unlike a {@link Reader}, a
- * {@code CharSource} is not an open, stateful stream of characters that can be read and closed.
- * Instead, it is an immutable <i>supplier</i> of {@code InputStream} instances.
- *
- * <p>{@code CharSource} provides two kinds of methods:
- * <ul>
- * <li><b>Methods that return a reader:</b> These methods should return a <i>new</i>, independent
- * instance each time they are called. The caller is responsible for ensuring that the returned
- * reader is closed.
- * <li><b>Convenience methods:</b> These are implementations of common operations that are
- * typically implemented by opening a reader using one of the methods in the first category,
- * doing something and finally closing the reader that was opened.
- * </ul>
- *
- * <p>Several methods in this class, such as {@link #readLines()}, break the contents of the
- * source into lines. Like {@link BufferedReader}, these methods break lines on any of {@code \n},
- * {@code \r} or {@code \r\n}, do not include the line separator in each line and do not consider
- * there to be an empty line at the end if the contents are terminated with a line separator.
- *
- * <p>Any {@link ByteSource} containing text encoded with a specific {@linkplain Charset character
- * encoding} may be viewed as a {@code CharSource} using {@link ByteSource#asCharSource(Charset)}.
- *
- * @since 14.0
- * @author Colin Decker
- */
-public abstract class CharSource {
-
- /**
- * Opens a new {@link Reader} for reading from this source. This method should return a new,
- * independent reader each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned reader is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the reader
- */
- public abstract Reader openStream() throws IOException;
-
- /**
- * Opens a new {@link BufferedReader} for reading from this source. This method should return a
- * new, independent reader each time it is called.
- *
- * <p>The caller is responsible for ensuring that the returned reader is closed.
- *
- * @throws IOException if an I/O error occurs in the process of opening the reader
- */
- public BufferedReader openBufferedStream() throws IOException {
- Reader reader = openStream();
- return (reader instanceof BufferedReader)
- ? (BufferedReader) reader
- : new BufferedReader(reader);
- }
-
- /**
- * Appends the contents of this source to the given {@link Appendable} (such as a {@link Writer}).
- * Does not close {@code appendable} if it is {@code Closeable}.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source or
- * writing to {@code appendable}
- */
- public long copyTo(Appendable appendable) throws IOException {
- checkNotNull(appendable);
-
- Closer closer = Closer.create();
- try {
- Reader reader = closer.register(openStream());
- return CharStreams.copy(reader, appendable);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Copies the contents of this source to the given sink.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source or
- * writing to {@code sink}
- */
- public long copyTo(CharSink sink) throws IOException {
- checkNotNull(sink);
-
- Closer closer = Closer.create();
- try {
- Reader reader = closer.register(openStream());
- Writer writer = closer.register(sink.openStream());
- return CharStreams.copy(reader, writer);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Reads the contents of this source as a string.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source
- */
- public String read() throws IOException {
- Closer closer = Closer.create();
- try {
- Reader reader = closer.register(openStream());
- return CharStreams.toString(reader);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Reads the first link of this source as a string. Returns {@code null} if this source is empty.
- *
- * <p>Like {@link BufferedReader}, this method breaks lines on any of {@code \n}, {@code \r} or
- * {@code \r\n}, does not include the line separator in the returned line and does not consider
- * there to be an extra empty line at the end if the content is terminated with a line separator.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source
- */
- public @Nullable String readFirstLine() throws IOException {
- Closer closer = Closer.create();
- try {
- BufferedReader reader = closer.register(openBufferedStream());
- return reader.readLine();
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- /**
- * Reads all the lines of this source as a list of strings. The returned list will be empty if
- * this source is empty.
- *
- * <p>Like {@link BufferedReader}, this method breaks lines on any of {@code \n}, {@code \r} or
- * {@code \r\n}, does not include the line separator in the returned lines and does not consider
- * there to be an extra empty line at the end if the content is terminated with a line separator.
- *
- * @throws IOException if an I/O error occurs in the process of reading from this source
- */
- public ImmutableList<String> readLines() throws IOException {
- Closer closer = Closer.create();
- try {
- BufferedReader reader = closer.register(openBufferedStream());
- List<String> result = Lists.newArrayList();
- String line;
- while ((line = reader.readLine()) != null) {
- result.add(line);
- }
- return ImmutableList.copyOf(result);
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-}
diff --git a/guava/src/com/google/common/io/CharStreams.java b/guava/src/com/google/common/io/CharStreams.java
index 6d9999d..0d53d90 100644
--- a/guava/src/com/google/common/io/CharStreams.java
+++ b/guava/src/com/google/common/io/CharStreams.java
@@ -16,13 +16,8 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
-import com.google.common.base.Charsets;
-import com.google.common.base.Splitter;
-import com.google.common.collect.AbstractIterator;
-import com.google.common.collect.ImmutableList;
+import com.google.common.base.Preconditions;
import java.io.Closeable;
import java.io.EOFException;
@@ -38,9 +33,7 @@ import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.List;
-import java.util.regex.Pattern;
/**
* Provides utility methods for working with character streams.
@@ -54,7 +47,6 @@ import java.util.regex.Pattern;
*
* @author Chris Nokleberg
* @author Bin Zhu
- * @author Colin Decker
* @since 1.0
*/
@Beta
@@ -72,85 +64,13 @@ public final class CharStreams {
*/
public static InputSupplier<StringReader> newReaderSupplier(
final String value) {
- return CharStreams.asInputSupplier(asCharSource(value));
- }
-
- /**
- * Returns a {@link CharSource} that reads the given string value.
- *
- * @since 14.0
- */
- public static CharSource asCharSource(String string) {
- return new StringCharSource(string);
- }
-
- private static final class StringCharSource extends CharSource {
-
- private static final Splitter LINE_SPLITTER
- = Splitter.on(Pattern.compile("\r\n|\n|\r"));
-
- private final String string;
-
- private StringCharSource(String string) {
- this.string = checkNotNull(string);
- }
-
- @Override
- public Reader openStream() {
- return new StringReader(string);
- }
-
- @Override
- public String read() {
- return string;
- }
-
- /**
- * Returns an iterable over the lines in the string. If the string ends in
- * a newline, a final empty string is not included to match the behavior of
- * BufferedReader/LineReader.readLine().
- */
- private Iterable<String> lines() {
- return new Iterable<String>() {
- @Override
- public Iterator<String> iterator() {
- return new AbstractIterator<String>() {
- Iterator<String> lines = LINE_SPLITTER.split(string).iterator();
-
- @Override
- protected String computeNext() {
- if (lines.hasNext()) {
- String next = lines.next();
- // skip last line if it's empty
- if (lines.hasNext() || !next.isEmpty()) {
- return next;
- }
- }
- return endOfData();
- }
- };
- }
- };
- }
-
- @Override
- public String readFirstLine() {
- Iterator<String> lines = lines().iterator();
- return lines.hasNext() ? lines.next() : null;
- }
-
- @Override
- public ImmutableList<String> readLines() {
- return ImmutableList.copyOf(lines());
- }
-
- @Override
- public String toString() {
- String limited = (string.length() <= 15)
- ? string
- : string.substring(0, 12) + "...";
- return "CharStreams.asCharSource(" + limited + ")";
- }
+ Preconditions.checkNotNull(value);
+ return new InputSupplier<StringReader>() {
+ @Override
+ public StringReader getInput() {
+ return new StringReader(value);
+ }
+ };
}
/**
@@ -158,14 +78,19 @@ public final class CharStreams {
* using the given {@link InputStream} factory and character set.
*
* @param in the factory that will be used to open input streams
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used to decode the input stream
* @return the factory
*/
public static InputSupplier<InputStreamReader> newReaderSupplier(
final InputSupplier<? extends InputStream> in, final Charset charset) {
- return CharStreams.asInputSupplier(
- ByteStreams.asByteSource(in).asCharSource(charset));
+ Preconditions.checkNotNull(in);
+ Preconditions.checkNotNull(charset);
+ return new InputSupplier<InputStreamReader>() {
+ @Override
+ public InputStreamReader getInput() throws IOException {
+ return new InputStreamReader(in.getInput(), charset);
+ }
+ };
}
/**
@@ -173,14 +98,19 @@ public final class CharStreams {
* using the given {@link OutputStream} factory and character set.
*
* @param out the factory that will be used to open output streams
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used to encode the output stream
* @return the factory
*/
public static OutputSupplier<OutputStreamWriter> newWriterSupplier(
final OutputSupplier<? extends OutputStream> out, final Charset charset) {
- return CharStreams.asOutputSupplier(
- ByteStreams.asByteSink(out).asCharSink(charset));
+ Preconditions.checkNotNull(out);
+ Preconditions.checkNotNull(charset);
+ return new OutputSupplier<OutputStreamWriter>() {
+ @Override
+ public OutputStreamWriter getOutput() throws IOException {
+ return new OutputStreamWriter(out.getOutput(), charset);
+ }
+ };
}
/**
@@ -193,7 +123,15 @@ public final class CharStreams {
*/
public static <W extends Appendable & Closeable> void write(CharSequence from,
OutputSupplier<W> to) throws IOException {
- asCharSink(to).write(from);
+ Preconditions.checkNotNull(from);
+ boolean threw = true;
+ W out = to.getOutput();
+ try {
+ out.append(from);
+ threw = false;
+ } finally {
+ Closeables.close(out, threw);
+ }
}
/**
@@ -209,7 +147,21 @@ public final class CharStreams {
public static <R extends Readable & Closeable,
W extends Appendable & Closeable> long copy(InputSupplier<R> from,
OutputSupplier<W> to) throws IOException {
- return asCharSource(from).copyTo(asCharSink(to));
+ int successfulOps = 0;
+ R in = from.getInput();
+ try {
+ W out = to.getOutput();
+ try {
+ long count = copy(in, out);
+ successfulOps++;
+ return count;
+ } finally {
+ Closeables.close(out, successfulOps < 1);
+ successfulOps++;
+ }
+ } finally {
+ Closeables.close(in, successfulOps < 2);
+ }
}
/**
@@ -224,7 +176,15 @@ public final class CharStreams {
*/
public static <R extends Readable & Closeable> long copy(
InputSupplier<R> from, Appendable to) throws IOException {
- return asCharSource(from).copyTo(to);
+ boolean threw = true;
+ R in = from.getInput();
+ try {
+ long count = copy(in, to);
+ threw = false;
+ return count;
+ } finally {
+ Closeables.close(in, threw);
+ }
}
/**
@@ -237,15 +197,16 @@ public final class CharStreams {
* @throws IOException if an I/O error occurs
*/
public static long copy(Readable from, Appendable to) throws IOException {
- checkNotNull(from);
- checkNotNull(to);
CharBuffer buf = CharBuffer.allocate(BUF_SIZE);
long total = 0;
- while (from.read(buf) != -1) {
+ while (true) {
+ int r = from.read(buf);
+ if (r == -1) {
+ break;
+ }
buf.flip();
- to.append(buf);
- total += buf.remaining();
- buf.clear();
+ to.append(buf, 0, r);
+ total += r;
}
return total;
}
@@ -272,7 +233,7 @@ public final class CharStreams {
*/
public static <R extends Readable & Closeable> String toString(
InputSupplier<R> supplier) throws IOException {
- return asCharSource(supplier).read();
+ return toStringBuilder(supplier).toString();
}
/**
@@ -290,6 +251,26 @@ public final class CharStreams {
}
/**
+ * Returns the characters from a {@link Readable} & {@link Closeable} object
+ * supplied by a factory as a new {@link StringBuilder} instance.
+ *
+ * @param supplier the factory to read from
+ * @throws IOException if an I/O error occurs
+ */
+ private static <R extends Readable & Closeable> StringBuilder toStringBuilder(
+ InputSupplier<R> supplier) throws IOException {
+ boolean threw = true;
+ R r = supplier.getInput();
+ try {
+ StringBuilder result = toStringBuilder(r);
+ threw = false;
+ return result;
+ } finally {
+ Closeables.close(r, threw);
+ }
+ }
+
+ /**
* Reads the first line from a {@link Readable} & {@link Closeable} object
* supplied by a factory. The line does not include line-termination
* characters, but does include other leading and trailing whitespace.
@@ -300,7 +281,15 @@ public final class CharStreams {
*/
public static <R extends Readable & Closeable> String readFirstLine(
InputSupplier<R> supplier) throws IOException {
- return asCharSource(supplier).readFirstLine();
+ boolean threw = true;
+ R r = supplier.getInput();
+ try {
+ String line = new LineReader(r).readLine();
+ threw = false;
+ return line;
+ } finally {
+ Closeables.close(r, threw);
+ }
}
/**
@@ -314,14 +303,14 @@ public final class CharStreams {
*/
public static <R extends Readable & Closeable> List<String> readLines(
InputSupplier<R> supplier) throws IOException {
- Closer closer = Closer.create();
+ boolean threw = true;
+ R r = supplier.getInput();
try {
- R r = closer.register(supplier.getInput());
- return readLines(r);
- } catch (Throwable e) {
- throw closer.rethrow(e);
+ List<String> result = readLines(r);
+ threw = false;
+ return result;
} finally {
- closer.close();
+ Closeables.close(r, threw);
}
}
@@ -349,31 +338,6 @@ public final class CharStreams {
}
/**
- * Streams lines from a {@link Readable} object, stopping when the processor
- * returns {@code false} or all lines have been read and returning the result
- * produced by the processor. Does not close {@code readable}. Note that this
- * method may not fully consume the contents of {@code readable} if the
- * processor stops processing early.
- *
- * @throws IOException if an I/O error occurs
- * @since 14.0
- */
- public static <T> T readLines(
- Readable readable, LineProcessor<T> processor) throws IOException {
- checkNotNull(readable);
- checkNotNull(processor);
-
- LineReader lineReader = new LineReader(readable);
- String line;
- while ((line = lineReader.readLine()) != null) {
- if (!processor.processLine(line)) {
- break;
- }
- }
- return processor.getResult();
- }
-
- /**
* Streams lines from a {@link Readable} and {@link Closeable} object
* supplied by a factory, stopping when our callback returns false, or we
* have read all of the lines.
@@ -385,18 +349,21 @@ public final class CharStreams {
*/
public static <R extends Readable & Closeable, T> T readLines(
InputSupplier<R> supplier, LineProcessor<T> callback) throws IOException {
- checkNotNull(supplier);
- checkNotNull(callback);
-
- Closer closer = Closer.create();
+ boolean threw = true;
+ R r = supplier.getInput();
try {
- R r = closer.register(supplier.getInput());
- return readLines(r, callback);
- } catch (Throwable e) {
- throw closer.rethrow(e);
+ LineReader lineReader = new LineReader(r);
+ String line;
+ while ((line = lineReader.readLine()) != null) {
+ if (!callback.processLine(line)) {
+ break;
+ }
+ }
+ threw = false;
} finally {
- closer.close();
+ Closeables.close(r, threw);
}
+ return callback.getResult();
}
/**
@@ -416,7 +383,6 @@ public final class CharStreams {
*/
public static InputSupplier<Reader> join(
final Iterable<? extends InputSupplier<? extends Reader>> suppliers) {
- checkNotNull(suppliers);
return new InputSupplier<Reader>() {
@Override public Reader getInput() throws IOException {
return new MultiReader(suppliers.iterator());
@@ -442,7 +408,6 @@ public final class CharStreams {
* @throws IOException if an I/O error occurs
*/
public static void skipFully(Reader reader, long n) throws IOException {
- checkNotNull(reader);
while (n > 0) {
long amt = reader.skip(n);
if (amt == 0) {
@@ -473,73 +438,4 @@ public final class CharStreams {
}
return new AppendableWriter(target);
}
-
- // TODO(user): Remove these once Input/OutputSupplier methods are removed
-
- static <R extends Readable & Closeable> Reader asReader(final R readable) {
- checkNotNull(readable);
- if (readable instanceof Reader) {
- return (Reader) readable;
- }
- return new Reader() {
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- return read(CharBuffer.wrap(cbuf, off, len));
- }
-
- @Override
- public int read(CharBuffer target) throws IOException {
- return readable.read(target);
- }
-
- @Override
- public void close() throws IOException {
- readable.close();
- }
- };
- }
-
- static <R extends Reader> InputSupplier<R> asInputSupplier(
- final CharSource source) {
- checkNotNull(source);
- return new InputSupplier<R>() {
- @Override
- public R getInput() throws IOException {
- return (R) source.openStream();
- }
- };
- }
-
- static <W extends Writer> OutputSupplier<W> asOutputSupplier(
- final CharSink sink) {
- checkNotNull(sink);
- return new OutputSupplier<W>() {
- @Override
- public W getOutput() throws IOException {
- return (W) sink.openStream();
- }
- };
- }
-
- static <R extends Readable & Closeable> CharSource asCharSource(
- final InputSupplier<R> supplier) {
- checkNotNull(supplier);
- return new CharSource() {
- @Override
- public Reader openStream() throws IOException {
- return asReader(supplier.getInput());
- }
- };
- }
-
- static <W extends Appendable & Closeable> CharSink asCharSink(
- final OutputSupplier<W> supplier) {
- checkNotNull(supplier);
- return new CharSink() {
- @Override
- public Writer openStream() throws IOException {
- return asWriter(supplier.getOutput());
- }
- };
- }
}
diff --git a/guava/src/com/google/common/io/Closeables.java b/guava/src/com/google/common/io/Closeables.java
index d312184..e619887 100644
--- a/guava/src/com/google/common/io/Closeables.java
+++ b/guava/src/com/google/common/io/Closeables.java
@@ -40,33 +40,36 @@ public final class Closeables {
private Closeables() {}
/**
- * Closes a {@link Closeable}, with control over whether an {@code IOException} may be thrown.
- * This is primarily useful in a finally block, where a thrown exception needs to be logged but
- * not propagated (otherwise the original exception will be lost).
+ * Closes a {@link Closeable}, with control over whether an
+ * {@code IOException} may be thrown. This is primarily useful in a
+ * finally block, where a thrown exception needs to be logged but not
+ * propagated (otherwise the original exception will be lost).
*
- * <p>If {@code swallowIOException} is true then we never throw {@code IOException} but merely log
- * it.
+ * <p>If {@code swallowIOException} is true then we never throw
+ * {@code IOException} but merely log it.
*
- * <p>Example: <pre> {@code
+ * <p>Example:
*
- * public void useStreamNicely() throws IOException {
- * SomeStream stream = new SomeStream("foo");
- * boolean threw = true;
- * try {
- * // ... code which does something with the stream ...
- * threw = false;
- * } finally {
- * // If an exception occurs, rethrow it only if threw==false:
- * Closeables.close(stream, threw);
- * }
- * }}</pre>
+ * <p><pre>public void useStreamNicely() throws IOException {
+ * SomeStream stream = new SomeStream("foo");
+ * boolean threw = true;
+ * try {
+ * // Some code which does something with the Stream. May throw a
+ * // Throwable.
+ * threw = false; // No throwable thrown.
+ * } finally {
+ * // Close the stream.
+ * // If an exception occurs, only rethrow it if (threw==false).
+ * Closeables.close(stream, threw);
+ * }
+ * </pre>
*
- * @param closeable the {@code Closeable} object to be closed, or null, in which case this method
- * does nothing
- * @param swallowIOException if true, don't propagate IO exceptions thrown by the {@code close}
- * methods
- * @throws IOException if {@code swallowIOException} is false and {@code close} throws an
- * {@code IOException}.
+ * @param closeable the {@code Closeable} object to be closed, or null,
+ * in which case this method does nothing
+ * @param swallowIOException if true, don't propagate IO exceptions
+ * thrown by the {@code close} methods
+ * @throws IOException if {@code swallowIOException} is false and
+ * {@code close} throws an {@code IOException}.
*/
public static void close(@Nullable Closeable closeable,
boolean swallowIOException) throws IOException {
@@ -86,23 +89,11 @@ public final class Closeables {
}
/**
- * Equivalent to calling {@code close(closeable, true)}, but with no IOException in the signature.
- *
- * @param closeable the {@code Closeable} object to be closed, or null, in which case this method
- * does nothing
- * @deprecated Where possible, use the
- * <a href="http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html">
- * try-with-resources</a> statement if using JDK7 or {@link Closer} on JDK6 to close one or
- * more {@code Closeable} objects. This method is deprecated because it is easy to misuse and
- * may swallow IO exceptions that really should be thrown and handled. See
- * <a href="https://code.google.com/p/guava-libraries/issues/detail?id=1118">Guava issue
- * 1118</a> for a more detailed explanation of the reasons for deprecation and see
- * <a href="https://code.google.com/p/guava-libraries/wiki/ClosingResourcesExplained">
- * Closing Resources</a> for more information on the problems with closing {@code Closeable}
- * objects and some of the preferred solutions for handling it correctly. This method is
- * scheduled to be removed in Guava 16.0.
+ * Equivalent to calling {@code close(closeable, true)}, but with no
+ * IOException in the signature.
+ * @param closeable the {@code Closeable} object to be closed, or null, in
+ * which case this method does nothing
*/
- @Deprecated
public static void closeQuietly(@Nullable Closeable closeable) {
try {
close(closeable, true);
diff --git a/guava/src/com/google/common/io/Closer.java b/guava/src/com/google/common/io/Closer.java
deleted file mode 100644
index 49141c2..0000000
--- a/guava/src/com/google/common/io/Closer.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Throwables;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.logging.Level;
-
-/**
- * A {@link Closeable} that collects {@code Closeable} resources and closes them all when it is
- * {@linkplain #close closed}. This is intended to approximately emulate the behavior of Java 7's
- * <a href="http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html">
- * try-with-resources</a> statement in JDK6-compatible code. Running on Java 7, code using this
- * should be approximately equivalent in behavior to the same code written with try-with-resources.
- * Running on Java 6, exceptions that cannot be thrown must be logged rather than being added to the
- * thrown exception as a suppressed exception.
- *
- * <p>This class is intended to to be used in the following pattern:
- *
- * <pre>{@code
- * Closer closer = Closer.create();
- * try {
- * InputStream in = closer.register(openInputStream());
- * OutputStream out = closer.register(openOutputStream());
- * // do stuff
- * } catch (Throwable e) {
- * // ensure that any checked exception types other than IOException that could be thrown are
- * // provided here, e.g. throw closer.rethrow(e, CheckedException.class);
- * throw closer.rethrow(e);
- * } finally {
- * closer.close();
- * }
- * }</pre>
- *
- * <p>Note that this try-catch-finally block is not equivalent to a try-catch-finally block using
- * try-with-resources. To get the equivalent of that, you must wrap the above code in <i>another</i>
- * try block in order to catch any exception that may be thrown (including from the call to
- * {@code close()}).
- *
- * <p>This pattern ensures the following:
- * <ul>
- * <li>Each {@code Closeable} resource that is successfully registered will be closed later.</li>
- * <li>If a {@code Throwable} is thrown in the try block, no exceptions that occur when attempting
- * to close resources will be thrown from the finally block. The throwable from the try block will
- * be thrown.</li>
- * <li>If no exceptions or errors were thrown in the try block, the <i>first</i> exception thrown
- * by an attempt to close a resource will be thrown.</li>
- * <li>Any exception caught when attempting to close a resource that is <i>not</i> thrown
- * (because another exception is already being thrown) is <i>suppressed</i>.</li>
- * </ul>
- *
- * An exception that is suppressed is not thrown. The method of suppression used depends on the
- * version of Java the code is running on:
- *
- * <ul>
- * <li><b>Java 7+:</b> Exceptions are suppressed by adding them to the exception that <i>will</i>
- * be thrown using {@code Throwable.addSuppressed(Throwable)}.</li>
- * <li><b>Java 6:</b> Exceptions are suppressed by logging them instead.</li>
- * </ul>
- *
- * @author Colin Decker
- * @since 14.0
- */
-// Coffee's for {@link Closer closers} only.
-@Beta
-public final class Closer implements Closeable {
-
- /**
- * The suppressor implementation to use for the current Java version.
- */
- private static final Suppressor SUPPRESSOR = SuppressingSuppressor.isAvailable()
- ? SuppressingSuppressor.INSTANCE
- : LoggingSuppressor.INSTANCE;
-
- /**
- * Creates a new {@link Closer}.
- */
- public static Closer create() {
- return new Closer(SUPPRESSOR);
- }
-
- @VisibleForTesting final Suppressor suppressor;
-
- // only need space for 2 elements in most cases, so try to use the smallest array possible
- private final Deque<Closeable> stack = new ArrayDeque<Closeable>(4);
- private Throwable thrown;
-
- @VisibleForTesting Closer(Suppressor suppressor) {
- this.suppressor = checkNotNull(suppressor); // checkNotNull to satisfy null tests
- }
-
- /**
- * Registers the given {@code closeable} to be closed when this {@code Closer} is
- * {@linkplain #close closed}.
- *
- * @return the given {@code closeable}
- */
- // close. this word no longer has any meaning to me.
- public <C extends Closeable> C register(C closeable) {
- stack.push(closeable);
- return closeable;
- }
-
- /**
- * Stores the given throwable and rethrows it. It will be rethrown as is if it is an
- * {@code IOException}, {@code RuntimeException} or {@code Error}. Otherwise, it will be rethrown
- * wrapped in a {@code RuntimeException}. <b>Note:</b> Be sure to declare all of the checked
- * exception types your try block can throw when calling an overload of this method so as to avoid
- * losing the original exception type.
- *
- * <p>This method always throws, and as such should be called as
- * {@code throw closer.rethrow(e);} to ensure the compiler knows that it will throw.
- *
- * @return this method does not return; it always throws
- * @throws IOException when the given throwable is an IOException
- */
- public RuntimeException rethrow(Throwable e) throws IOException {
- thrown = e;
- Throwables.propagateIfPossible(e, IOException.class);
- throw Throwables.propagate(e);
- }
-
- /**
- * Stores the given throwable and rethrows it. It will be rethrown as is if it is an
- * {@code IOException}, {@code RuntimeException}, {@code Error} or a checked exception of the
- * given type. Otherwise, it will be rethrown wrapped in a {@code RuntimeException}. <b>Note:</b>
- * Be sure to declare all of the checked exception types your try block can throw when calling an
- * overload of this method so as to avoid losing the original exception type.
- *
- * <p>This method always throws, and as such should be called as
- * {@code throw closer.rethrow(e, ...);} to ensure the compiler knows that it will throw.
- *
- * @return this method does not return; it always throws
- * @throws IOException when the given throwable is an IOException
- * @throws X when the given throwable is of the declared type X
- */
- public <X extends Exception> RuntimeException rethrow(Throwable e,
- Class<X> declaredType) throws IOException, X {
- thrown = e;
- Throwables.propagateIfPossible(e, IOException.class);
- Throwables.propagateIfPossible(e, declaredType);
- throw Throwables.propagate(e);
- }
-
- /**
- * Stores the given throwable and rethrows it. It will be rethrown as is if it is an
- * {@code IOException}, {@code RuntimeException}, {@code Error} or a checked exception of either
- * of the given types. Otherwise, it will be rethrown wrapped in a {@code RuntimeException}.
- * <b>Note:</b> Be sure to declare all of the checked exception types your try block can throw
- * when calling an overload of this method so as to avoid losing the original exception type.
- *
- * <p>This method always throws, and as such should be called as
- * {@code throw closer.rethrow(e, ...);} to ensure the compiler knows that it will throw.
- *
- * @return this method does not return; it always throws
- * @throws IOException when the given throwable is an IOException
- * @throws X1 when the given throwable is of the declared type X1
- * @throws X2 when the given throwable is of the declared type X2
- */
- public <X1 extends Exception, X2 extends Exception> RuntimeException rethrow(
- Throwable e, Class<X1> declaredType1, Class<X2> declaredType2) throws IOException, X1, X2 {
- thrown = e;
- Throwables.propagateIfPossible(e, IOException.class);
- Throwables.propagateIfPossible(e, declaredType1, declaredType2);
- throw Throwables.propagate(e);
- }
-
- /**
- * Closes all {@code Closeable} instances that have been added to this {@code Closer}. If an
- * exception was thrown in the try block and passed to one of the {@code exceptionThrown} methods,
- * any exceptions thrown when attempting to close a closeable will be suppressed. Otherwise, the
- * <i>first</i> exception to be thrown from an attempt to close a closeable will be thrown and any
- * additional exceptions that are thrown after that will be suppressed.
- */
- @Override
- public void close() throws IOException {
- Throwable throwable = thrown;
-
- // close closeables in LIFO order
- while (!stack.isEmpty()) {
- Closeable closeable = stack.pop();
- try {
- closeable.close();
- } catch (Throwable e) {
- if (throwable == null) {
- throwable = e;
- } else {
- suppressor.suppress(closeable, throwable, e);
- }
- }
- }
-
- if (thrown == null && throwable != null) {
- Throwables.propagateIfPossible(throwable, IOException.class);
- throw new AssertionError(throwable); // not possible
- }
- }
-
- /**
- * Suppression strategy interface.
- */
- @VisibleForTesting interface Suppressor {
- /**
- * Suppresses the given exception ({@code suppressed}) which was thrown when attempting to close
- * the given closeable. {@code thrown} is the exception that is actually being thrown from the
- * method. Implementations of this method should not throw under any circumstances.
- */
- void suppress(Closeable closeable, Throwable thrown, Throwable suppressed);
- }
-
- /**
- * Suppresses exceptions by logging them.
- */
- @VisibleForTesting static final class LoggingSuppressor implements Suppressor {
-
- static final LoggingSuppressor INSTANCE = new LoggingSuppressor();
-
- @Override
- public void suppress(Closeable closeable, Throwable thrown, Throwable suppressed) {
- // log to the same place as Closeables
- Closeables.logger.log(Level.WARNING,
- "Suppressing exception thrown when closing " + closeable, suppressed);
- }
- }
-
- /**
- * Suppresses exceptions by adding them to the exception that will be thrown using JDK7's
- * addSuppressed(Throwable) mechanism.
- */
- @VisibleForTesting static final class SuppressingSuppressor implements Suppressor {
-
- static final SuppressingSuppressor INSTANCE = new SuppressingSuppressor();
-
- static boolean isAvailable() {
- return addSuppressed != null;
- }
-
- static final Method addSuppressed = getAddSuppressed();
-
- private static Method getAddSuppressed() {
- try {
- return Throwable.class.getMethod("addSuppressed", Throwable.class);
- } catch (Throwable e) {
- return null;
- }
- }
-
- @Override
- public void suppress(Closeable closeable, Throwable thrown, Throwable suppressed) {
- // ensure no exceptions from addSuppressed
- if (thrown == suppressed) {
- return;
- }
- try {
- addSuppressed.invoke(thrown, suppressed);
- } catch (Throwable e) {
- // if, somehow, IllegalAccessException or another exception is thrown, fall back to logging
- LoggingSuppressor.INSTANCE.suppress(closeable, thrown, suppressed);
- }
- }
- }
-}
diff --git a/guava/src/com/google/common/io/CountingInputStream.java b/guava/src/com/google/common/io/CountingInputStream.java
index 573099a..d11c8ec 100644
--- a/guava/src/com/google/common/io/CountingInputStream.java
+++ b/guava/src/com/google/common/io/CountingInputStream.java
@@ -22,8 +22,6 @@ import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
-import javax.annotation.Nullable;
-
/**
* An {@link InputStream} that counts the number of bytes read.
*
@@ -41,7 +39,7 @@ public final class CountingInputStream extends FilterInputStream {
*
* @param in the input stream to be wrapped
*/
- public CountingInputStream(@Nullable InputStream in) {
+ public CountingInputStream(InputStream in) {
super(in);
}
diff --git a/guava/src/com/google/common/io/CountingOutputStream.java b/guava/src/com/google/common/io/CountingOutputStream.java
index 4013f9c..5f57714 100644
--- a/guava/src/com/google/common/io/CountingOutputStream.java
+++ b/guava/src/com/google/common/io/CountingOutputStream.java
@@ -22,8 +22,6 @@ import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import javax.annotation.Nullable;
-
/**
* An OutputStream that counts the number of bytes written.
*
@@ -40,7 +38,7 @@ public final class CountingOutputStream extends FilterOutputStream {
*
* @param out the output stream to be wrapped
*/
- public CountingOutputStream(@Nullable OutputStream out) {
+ public CountingOutputStream(OutputStream out) {
super(out);
}
diff --git a/guava/src/com/google/common/io/FileWriteMode.java b/guava/src/com/google/common/io/FileWriteMode.java
deleted file mode 100644
index d246740..0000000
--- a/guava/src/com/google/common/io/FileWriteMode.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.io;
-
-/**
- * Modes for opening a file for writing. The default when mode when none is specified is to
- * truncate the file before writing.
- *
- * @author Colin Decker
- */
-public enum FileWriteMode {
- /** Specifies that writes to the opened file should append to the end of the file. */
- APPEND
-}
diff --git a/guava/src/com/google/common/io/Files.java b/guava/src/com/google/common/io/Files.java
index c3dd506..1d3ce1a 100644
--- a/guava/src/com/google/common/io/Files.java
+++ b/guava/src/com/google/common/io/Files.java
@@ -16,21 +16,15 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.io.FileWriteMode.APPEND;
import com.google.common.annotations.Beta;
-import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.HashFunction;
import java.io.BufferedReader;
import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
@@ -46,8 +40,8 @@ import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.charset.Charset;
+import java.security.MessageDigest;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.zip.Checksum;
@@ -57,7 +51,6 @@ import java.util.zip.Checksum;
* <p>All method parameters must be non-null unless documented otherwise.
*
* @author Chris Nokleberg
- * @author Colin Decker
* @since 1.0
*/
@Beta
@@ -73,14 +66,11 @@ public final class Files {
* character set.
*
* @param file the file to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @return the buffered reader
*/
public static BufferedReader newReader(File file, Charset charset)
throws FileNotFoundException {
- checkNotNull(file);
- checkNotNull(charset);
return new BufferedReader(
new InputStreamReader(new FileInputStream(file), charset));
}
@@ -90,171 +80,16 @@ public final class Files {
* character set.
*
* @param file the file to write to
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @return the buffered writer
*/
public static BufferedWriter newWriter(File file, Charset charset)
throws FileNotFoundException {
- checkNotNull(file);
- checkNotNull(charset);
return new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file), charset));
}
/**
- * Returns a new {@link ByteSource} for reading bytes from the given file.
- *
- * @since 14.0
- */
- public static ByteSource asByteSource(File file) {
- return new FileByteSource(file);
- }
-
- private static final class FileByteSource extends ByteSource {
-
- private final File file;
-
- private FileByteSource(File file) {
- this.file = checkNotNull(file);
- }
-
- @Override
- public FileInputStream openStream() throws IOException {
- return new FileInputStream(file);
- }
-
- @Override
- public long size() throws IOException {
- if (!file.isFile()) {
- throw new FileNotFoundException(file.toString());
- }
- return file.length();
- }
-
- @Override
- public byte[] read() throws IOException {
- long size = file.length();
- // some special files may return size 0 but have content
- // read normally to be sure
- if (size == 0) {
- return super.read();
- }
-
- // can't initialize a large enough array
- // technically, this could probably be Integer.MAX_VALUE - 5
- if (size > Integer.MAX_VALUE) {
- // OOME is what would be thrown if we tried to initialize the array
- throw new OutOfMemoryError("file is too large to fit in a byte array: "
- + size + " bytes");
- }
-
- // initialize the array to the current size of the file
- byte[] bytes = new byte[(int) size];
-
- Closer closer = Closer.create();
- try {
- InputStream in = closer.register(openStream());
- int off = 0;
- int read = 0;
-
- // read until we've read size bytes or reached EOF
- while (off < size
- && ((read = in.read(bytes, off, (int) size - off)) != -1)) {
- off += read;
- }
-
- byte[] result = bytes;
-
- if (off < size) {
- // encountered EOF early; truncate the result
- result = Arrays.copyOf(bytes, off);
- } else if (read != -1) {
- // we read size bytes... if the last read didn't return -1, the file got larger
- // so we just read the rest normally and then create a new array
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ByteStreams.copy(in, out);
- byte[] moreBytes = out.toByteArray();
- result = new byte[bytes.length + moreBytes.length];
- System.arraycopy(bytes, 0, result, 0, bytes.length);
- System.arraycopy(moreBytes, 0, result, bytes.length, moreBytes.length);
- }
- // normally, off should == size and read should == -1
- // in that case, the array is just returned as is
- return result;
- } catch (Throwable e) {
- throw closer.rethrow(e);
- } finally {
- closer.close();
- }
- }
-
- @Override
- public String toString() {
- return "Files.asByteSource(" + file + ")";
- }
- }
-
- /**
- * Returns a new {@link ByteSink} for writing bytes to the given file. The
- * given {@code modes} control how the file is opened for writing. When no
- * mode is provided, the file will be truncated before writing. When the
- * {@link FileWriteMode#APPEND APPEND} mode is provided, writes will
- * append to the end of the file without truncating it.
- *
- * @since 14.0
- */
- public static ByteSink asByteSink(File file, FileWriteMode... modes) {
- return new FileByteSink(file, modes);
- }
-
- private static final class FileByteSink extends ByteSink {
-
- private final File file;
- private final ImmutableSet<FileWriteMode> modes;
-
- private FileByteSink(File file, FileWriteMode... modes) {
- this.file = checkNotNull(file);
- this.modes = ImmutableSet.copyOf(modes);
- }
-
- @Override
- public FileOutputStream openStream() throws IOException {
- return new FileOutputStream(file, modes.contains(APPEND));
- }
-
- @Override
- public String toString() {
- return "Files.asByteSink(" + file + ", " + modes + ")";
- }
- }
-
- /**
- * Returns a new {@link CharSource} for reading character data from the given
- * file using the given character set.
- *
- * @since 14.0
- */
- public static CharSource asCharSource(File file, Charset charset) {
- return asByteSource(file).asCharSource(charset);
- }
-
- /**
- * Returns a new {@link CharSink} for writing character data to the given
- * file using the given character set. The given {@code modes} control how
- * the file is opened for writing. When no mode is provided, the file
- * will be truncated before writing. When the
- * {@link FileWriteMode#APPEND APPEND} mode is provided, writes will
- * append to the end of the file without truncating it.
- *
- * @since 14.0
- */
- public static CharSink asCharSink(File file, Charset charset,
- FileWriteMode... modes) {
- return asByteSink(file, modes).asCharSink(charset);
- }
-
- /**
* Returns a factory that will supply instances of {@link FileInputStream}
* that read from a file.
*
@@ -263,7 +98,13 @@ public final class Files {
*/
public static InputSupplier<FileInputStream> newInputStreamSupplier(
final File file) {
- return ByteStreams.asInputSupplier(asByteSource(file));
+ Preconditions.checkNotNull(file);
+ return new InputSupplier<FileInputStream>() {
+ @Override
+ public FileInputStream getInput() throws IOException {
+ return new FileInputStream(file);
+ }
+ };
}
/**
@@ -289,13 +130,13 @@ public final class Files {
*/
public static OutputSupplier<FileOutputStream> newOutputStreamSupplier(
final File file, final boolean append) {
- return ByteStreams.asOutputSupplier(asByteSink(file, modes(append)));
- }
-
- private static FileWriteMode[] modes(boolean append) {
- return append
- ? new FileWriteMode[]{ FileWriteMode.APPEND }
- : new FileWriteMode[0];
+ Preconditions.checkNotNull(file);
+ return new OutputSupplier<FileOutputStream>() {
+ @Override
+ public FileOutputStream getOutput() throws IOException {
+ return new FileOutputStream(file, append);
+ }
+ };
}
/**
@@ -303,13 +144,12 @@ public final class Files {
* {@link InputStreamReader} that read a file using the given character set.
*
* @param file the file to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the file
* @return the factory
*/
public static InputSupplier<InputStreamReader> newReaderSupplier(File file,
Charset charset) {
- return CharStreams.asInputSupplier(asCharSource(file, charset));
+ return CharStreams.newReaderSupplier(newInputStreamSupplier(file), charset);
}
/**
@@ -317,8 +157,7 @@ public final class Files {
* that write to a file using the given character set.
*
* @param file the file to write to
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @return the factory
*/
public static OutputSupplier<OutputStreamWriter> newWriterSupplier(File file,
@@ -331,15 +170,15 @@ public final class Files {
* that write to or append to a file using the given character set.
*
* @param file the file to write to
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @param append if true, the encoded characters will be appended to the file;
* otherwise the file is overwritten
* @return the factory
*/
public static OutputSupplier<OutputStreamWriter> newWriterSupplier(File file,
Charset charset, boolean append) {
- return CharStreams.asOutputSupplier(asCharSink(file, charset, modes(append)));
+ return CharStreams.newWriterSupplier(newOutputStreamSupplier(file, append),
+ charset);
}
/**
@@ -352,7 +191,23 @@ public final class Files {
* @throws IOException if an I/O error occurs
*/
public static byte[] toByteArray(File file) throws IOException {
- return asByteSource(file).read();
+ Preconditions.checkArgument(file.length() <= Integer.MAX_VALUE);
+ if (file.length() == 0) {
+ // Some special files are length 0 but have content nonetheless.
+ return ByteStreams.toByteArray(newInputStreamSupplier(file));
+ } else {
+ // Avoid an extra allocation and copy.
+ byte[] b = new byte[(int) file.length()];
+ boolean threw = true;
+ InputStream in = new FileInputStream(file);
+ try {
+ ByteStreams.readFully(in, b);
+ threw = false;
+ } finally {
+ Closeables.close(in, threw);
+ }
+ return b;
+ }
}
/**
@@ -360,13 +215,12 @@ public final class Files {
* character set.
*
* @param file the file to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the file
* @return a string containing all the characters from the file
* @throws IOException if an I/O error occurs
*/
public static String toString(File file, Charset charset) throws IOException {
- return asCharSource(file, charset).read();
+ return new String(toByteArray(file), charset.name());
}
/**
@@ -379,7 +233,7 @@ public final class Files {
*/
public static void copy(InputSupplier<? extends InputStream> from, File to)
throws IOException {
- ByteStreams.asByteSource(from).copyTo(asByteSink(to));
+ ByteStreams.copy(from, newOutputStreamSupplier(to));
}
/**
@@ -390,7 +244,7 @@ public final class Files {
* @throws IOException if an I/O error occurs
*/
public static void write(byte[] from, File to) throws IOException {
- asByteSink(to).write(from);
+ ByteStreams.write(from, newOutputStreamSupplier(to));
}
/**
@@ -403,7 +257,7 @@ public final class Files {
*/
public static void copy(File from, OutputSupplier<? extends OutputStream> to)
throws IOException {
- asByteSource(from).copyTo(ByteStreams.asByteSink(to));
+ ByteStreams.copy(newInputStreamSupplier(from), to);
}
/**
@@ -414,26 +268,21 @@ public final class Files {
* @throws IOException if an I/O error occurs
*/
public static void copy(File from, OutputStream to) throws IOException {
- asByteSource(from).copyTo(to);
+ ByteStreams.copy(newInputStreamSupplier(from), to);
}
/**
* Copies all the bytes from one file to another.
- *
- * <p><b>Warning:</b> If {@code to} represents an existing file, that file
- * will be overwritten with the contents of {@code from}. If {@code to} and
- * {@code from} refer to the <i>same</i> file, the contents of that file
- * will be deleted.
- *
+ *.
* @param from the source file
* @param to the destination file
* @throws IOException if an I/O error occurs
* @throws IllegalArgumentException if {@code from.equals(to)}
*/
public static void copy(File from, File to) throws IOException {
- checkArgument(!from.equals(to),
+ Preconditions.checkArgument(!from.equals(to),
"Source %s and destination %s must be different", from, to);
- asByteSource(from).copyTo(asByteSink(to));
+ copy(newInputStreamSupplier(from), to);
}
/**
@@ -443,13 +292,12 @@ public final class Files {
*
* @param from the readable supplier
* @param to the destination file
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @throws IOException if an I/O error occurs
*/
public static <R extends Readable & Closeable> void copy(
InputSupplier<R> from, File to, Charset charset) throws IOException {
- CharStreams.asCharSource(from).copyTo(asCharSink(to, charset));
+ CharStreams.copy(from, newWriterSupplier(to, charset));
}
/**
@@ -458,13 +306,12 @@ public final class Files {
*
* @param from the character sequence to write
* @param to the destination file
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @throws IOException if an I/O error occurs
*/
public static void write(CharSequence from, File to, Charset charset)
throws IOException {
- asCharSink(to, charset).write(from);
+ write(from, to, charset, false);
}
/**
@@ -473,8 +320,7 @@ public final class Files {
*
* @param from the character sequence to append
* @param to the destination file
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @throws IOException if an I/O error occurs
*/
public static void append(CharSequence from, File to, Charset charset)
@@ -488,14 +334,13 @@ public final class Files {
*
* @param from the character sequence to append
* @param to the destination file
- * @param charset the charset used to encode the output stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @param append true to append, false to overwrite
* @throws IOException if an I/O error occurs
*/
private static void write(CharSequence from, File to, Charset charset,
boolean append) throws IOException {
- asCharSink(to, charset, modes(append)).write(from);
+ CharStreams.write(from, newWriterSupplier(to, charset, append));
}
/**
@@ -504,14 +349,13 @@ public final class Files {
* character set.
*
* @param from the source file
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the file
* @param to the appendable supplier
* @throws IOException if an I/O error occurs
*/
public static <W extends Appendable & Closeable> void copy(File from,
Charset charset, OutputSupplier<W> to) throws IOException {
- asCharSource(from, charset).copyTo(CharStreams.asCharSink(to));
+ CharStreams.copy(newReaderSupplier(from, charset), to);
}
/**
@@ -519,14 +363,13 @@ public final class Files {
* using the given character set.
*
* @param from the source file
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the file
* @param to the appendable object
* @throws IOException if an I/O error occurs
*/
public static void copy(File from, Charset charset, Appendable to)
throws IOException {
- asCharSource(from, charset).copyTo(to);
+ CharStreams.copy(newReaderSupplier(from, charset), to);
}
/**
@@ -535,8 +378,6 @@ public final class Files {
* @throws IOException if an I/O error occurs
*/
public static boolean equal(File file1, File file2) throws IOException {
- checkNotNull(file1);
- checkNotNull(file2);
if (file1 == file2 || file1.equals(file2)) {
return true;
}
@@ -551,7 +392,8 @@ public final class Files {
if (len1 != 0 && len2 != 0 && len1 != len2) {
return false;
}
- return asByteSource(file1).contentEquals(asByteSource(file2));
+ return ByteStreams.equal(newInputStreamSupplier(file1),
+ newInputStreamSupplier(file2));
}
/**
@@ -596,7 +438,6 @@ public final class Files {
* @throws IOException if an I/O error occurs
*/
public static void touch(File file) throws IOException {
- checkNotNull(file);
if (!file.createNewFile()
&& !file.setLastModified(System.currentTimeMillis())) {
throw new IOException("Unable to update modification time of " + file);
@@ -614,7 +455,6 @@ public final class Files {
* @since 4.0
*/
public static void createParentDirs(File file) throws IOException {
- checkNotNull(file);
File parent = file.getCanonicalFile().getParentFile();
if (parent == null) {
/*
@@ -642,9 +482,8 @@ public final class Files {
* @throws IllegalArgumentException if {@code from.equals(to)}
*/
public static void move(File from, File to) throws IOException {
- checkNotNull(from);
- checkNotNull(to);
- checkArgument(!from.equals(to),
+ Preconditions.checkNotNull(to);
+ Preconditions.checkArgument(!from.equals(to),
"Source %s and destination %s must be different", from, to);
if (!from.renameTo(to)) {
@@ -664,14 +503,13 @@ public final class Files {
* trailing whitespace.
*
* @param file the file to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @return the first line, or null if the file is empty
* @throws IOException if an I/O error occurs
*/
public static String readFirstLine(File file, Charset charset)
throws IOException {
- return asCharSource(file, charset).readFirstLine();
+ return CharStreams.readFirstLine(Files.newReaderSupplier(file, charset));
}
/**
@@ -680,8 +518,7 @@ public final class Files {
* trailing whitespace.
*
* @param file the file to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @return a mutable {@link List} containing all the lines
* @throws IOException if an I/O error occurs
*/
@@ -695,15 +532,15 @@ public final class Files {
* false, or we have read all of the lines.
*
* @param file the file to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @param callback the {@link LineProcessor} to use to handle the lines
* @return the output of processing the lines
* @throws IOException if an I/O error occurs
*/
public static <T> T readLines(File file, Charset charset,
LineProcessor<T> callback) throws IOException {
- return CharStreams.readLines(newReaderSupplier(file, charset), callback);
+ return CharStreams.readLines(Files.newReaderSupplier(file, charset),
+ callback);
}
/**
@@ -731,28 +568,25 @@ public final class Files {
* @return the result of {@link Checksum#getValue} after updating the
* checksum object with all of the bytes in the file
* @throws IOException if an I/O error occurs
- * @deprecated Use {@code hash} with the {@code Hashing.crc32()} or
- * {@code Hashing.adler32()} hash functions. This method is scheduled
- * to be removed in Guava 15.0.
*/
- @Deprecated
public static long getChecksum(File file, Checksum checksum)
throws IOException {
return ByteStreams.getChecksum(newInputStreamSupplier(file), checksum);
}
/**
- * Computes the hash code of the {@code file} using {@code hashFunction}.
+ * Computes and returns the digest value for a file.
+ * The digest object is reset when this method returns successfully.
*
* @param file the file to read
- * @param hashFunction the hash function to use to hash the data
- * @return the {@link HashCode} of all of the bytes in the file
+ * @param md the digest object
+ * @return the result of {@link MessageDigest#digest()} after updating the
+ * digest object with all of the bytes in this file
* @throws IOException if an I/O error occurs
- * @since 12.0
*/
- public static HashCode hash(File file, HashFunction hashFunction)
+ public static byte[] getDigest(File file, MessageDigest md)
throws IOException {
- return asByteSource(file).hash(hashFunction);
+ return ByteStreams.getDigest(newInputStreamSupplier(file), md);
}
/**
@@ -772,7 +606,6 @@ public final class Files {
* @since 2.0
*/
public static MappedByteBuffer map(File file) throws IOException {
- checkNotNull(file);
return map(file, MapMode.READ_ONLY);
}
@@ -796,8 +629,6 @@ public final class Files {
*/
public static MappedByteBuffer map(File file, MapMode mode)
throws IOException {
- checkNotNull(file);
- checkNotNull(mode);
if (!file.exists()) {
throw new FileNotFoundException(file.toString());
}
@@ -827,31 +658,30 @@ public final class Files {
*/
public static MappedByteBuffer map(File file, MapMode mode, long size)
throws FileNotFoundException, IOException {
- checkNotNull(file);
- checkNotNull(mode);
+ RandomAccessFile raf =
+ new RandomAccessFile(file, mode == MapMode.READ_ONLY ? "r" : "rw");
- Closer closer = Closer.create();
+ boolean threw = true;
try {
- RandomAccessFile raf = closer.register(
- new RandomAccessFile(file, mode == MapMode.READ_ONLY ? "r" : "rw"));
- return map(raf, mode, size);
- } catch (Throwable e) {
- throw closer.rethrow(e);
+ MappedByteBuffer mbb = map(raf, mode, size);
+ threw = false;
+ return mbb;
} finally {
- closer.close();
+ Closeables.close(raf, threw);
}
}
private static MappedByteBuffer map(RandomAccessFile raf, MapMode mode,
long size) throws IOException {
- Closer closer = Closer.create();
+ FileChannel channel = raf.getChannel();
+
+ boolean threw = true;
try {
- FileChannel channel = closer.register(raf.getChannel());
- return channel.map(mode, 0, size);
- } catch (Throwable e) {
- throw closer.rethrow(e);
+ MappedByteBuffer mbb = channel.map(mode, 0, size);
+ threw = false;
+ return mbb;
} finally {
- closer.close();
+ Closeables.close(channel, threw);
}
}
@@ -877,7 +707,6 @@ public final class Files {
* @since 11.0
*/
public static String simplifyPath(String pathname) {
- checkNotNull(pathname);
if (pathname.length() == 0) {
return ".";
}
@@ -927,27 +756,9 @@ public final class Files {
*
* @since 11.0
*/
- public static String getFileExtension(String fullName) {
- checkNotNull(fullName);
- String fileName = new File(fullName).getName();
+ public static String getFileExtension(String fileName) {
+ checkNotNull(fileName);
int dotIndex = fileName.lastIndexOf('.');
return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
}
-
- /**
- * Returns the file name without its
- * <a href="http://en.wikipedia.org/wiki/Filename_extension">file extension</a> or path. This is
- * similar to the {@code basename} unix command. The result does not include the '{@code .}'.
- *
- * @param file The name of the file to trim the extension from. This can be either a fully
- * qualified file name (including a path) or just a file name.
- * @return The file name without its path or extension.
- * @since 14.0
- */
- public static String getNameWithoutExtension(String file) {
- checkNotNull(file);
- String fileName = new File(file).getName();
- int dotIndex = fileName.lastIndexOf('.');
- return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
- }
}
diff --git a/guava/src/com/google/common/io/GwtWorkarounds.java b/guava/src/com/google/common/io/GwtWorkarounds.java
deleted file mode 100644
index 285df59..0000000
--- a/guava/src/com/google/common/io/GwtWorkarounds.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.io;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkPositionIndexes;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Writer;
-
-/**
- * Provides simple GWT-compatible substitutes for {@code InputStream}, {@code OutputStream},
- * {@code Reader}, and {@code Writer} so that {@code BaseEncoding} can use streaming implementations
- * while remaining GWT-compatible.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-final class GwtWorkarounds {
- private GwtWorkarounds() {}
-
- /**
- * A GWT-compatible substitute for a {@code Reader}.
- */
- interface CharInput {
- int read() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * Views a {@code Reader} as a {@code CharInput}.
- */
- @GwtIncompatible("Reader")
- static CharInput asCharInput(final Reader reader) {
- checkNotNull(reader);
- return new CharInput() {
- @Override
- public int read() throws IOException {
- return reader.read();
- }
-
- @Override
- public void close() throws IOException {
- reader.close();
- }
- };
- }
-
- /**
- * Views a {@code CharSequence} as a {@code CharInput}.
- */
- static CharInput asCharInput(final CharSequence chars) {
- checkNotNull(chars);
- return new CharInput() {
- int index = 0;
-
- @Override
- public int read() {
- if (index < chars.length()) {
- return chars.charAt(index++);
- } else {
- return -1;
- }
- }
-
- @Override
- public void close() {
- index = chars.length();
- }
- };
- }
-
- /**
- * A GWT-compatible substitute for an {@code InputStream}.
- */
- interface ByteInput {
- int read() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * Views a {@code ByteInput} as an {@code InputStream}.
- */
- @GwtIncompatible("InputStream")
- static InputStream asInputStream(final ByteInput input) {
- checkNotNull(input);
- return new InputStream() {
- @Override
- public int read() throws IOException {
- return input.read();
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- checkNotNull(b);
- checkPositionIndexes(off, off + len, b.length);
- if (len == 0) {
- return 0;
- }
- int firstByte = read();
- if (firstByte == -1) {
- return -1;
- }
- b[off] = (byte) firstByte;
- for (int dst = 1; dst < len; dst++) {
- int readByte = read();
- if (readByte == -1) {
- return dst;
- }
- b[off + dst] = (byte) readByte;
- }
- return len;
- }
-
- @Override
- public void close() throws IOException {
- input.close();
- }
- };
- }
-
- /**
- * A GWT-compatible substitute for an {@code OutputStream}.
- */
- interface ByteOutput {
- void write(byte b) throws IOException;
- void flush() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * Views a {@code ByteOutput} as an {@code OutputStream}.
- */
- @GwtIncompatible("OutputStream")
- static OutputStream asOutputStream(final ByteOutput output) {
- checkNotNull(output);
- return new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- output.write((byte) b);
- }
-
- @Override
- public void flush() throws IOException {
- output.flush();
- }
-
- @Override
- public void close() throws IOException {
- output.close();
- }
- };
- }
-
- /**
- * A GWT-compatible substitute for a {@code Writer}.
- */
- interface CharOutput {
- void write(char c) throws IOException;
- void flush() throws IOException;
- void close() throws IOException;
- }
-
- /**
- * Views a {@code Writer} as a {@code CharOutput}.
- */
- @GwtIncompatible("Writer")
- static CharOutput asCharOutput(final Writer writer) {
- checkNotNull(writer);
- return new CharOutput() {
- @Override
- public void write(char c) throws IOException {
- writer.append(c);
- }
-
- @Override
- public void flush() throws IOException {
- writer.flush();
- }
-
- @Override
- public void close() throws IOException {
- writer.close();
- }
- };
- }
-
- /**
- * Returns a {@code CharOutput} whose {@code toString()} method can be used
- * to get the combined output.
- */
- static CharOutput stringBuilderOutput(int initialSize) {
- final StringBuilder builder = new StringBuilder(initialSize);
- return new CharOutput() {
-
- @Override
- public void write(char c) {
- builder.append(c);
- }
-
- @Override
- public void flush() {}
-
- @Override
- public void close() {}
-
- @Override
- public String toString() {
- return builder.toString();
- }
- };
- }
-}
diff --git a/guava/src/com/google/common/io/LimitInputStream.java b/guava/src/com/google/common/io/LimitInputStream.java
index c8bd6cf..e9d963d 100644
--- a/guava/src/com/google/common/io/LimitInputStream.java
+++ b/guava/src/com/google/common/io/LimitInputStream.java
@@ -28,11 +28,8 @@ import java.io.InputStream;
*
* @author Charles Fry
* @since 1.0
- * @deprecated Use {@link ByteStreams#limit} instead. This class is scheduled
- * to be removed in Guava release 15.0.
*/
@Beta
-@Deprecated
public final class LimitInputStream extends FilterInputStream {
private long left;
diff --git a/guava/src/com/google/common/io/LineBuffer.java b/guava/src/com/google/common/io/LineBuffer.java
index 119516b..1f1c8dc 100644
--- a/guava/src/com/google/common/io/LineBuffer.java
+++ b/guava/src/com/google/common/io/LineBuffer.java
@@ -75,9 +75,6 @@ abstract class LineBuffer {
finishLine(true);
start = pos + 1;
break;
-
- default:
- // do nothing
}
}
line.append(cbuf, start, off + len - start);
diff --git a/guava/src/com/google/common/io/MultiInputStream.java b/guava/src/com/google/common/io/MultiInputStream.java
index 1902baf..f8f1a0b 100644
--- a/guava/src/com/google/common/io/MultiInputStream.java
+++ b/guava/src/com/google/common/io/MultiInputStream.java
@@ -16,14 +16,10 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
-import javax.annotation.Nullable;
-
/**
* An {@link InputStream} that concatenates multiple substreams. At most
* one stream will be open at a time.
@@ -44,7 +40,7 @@ final class MultiInputStream extends InputStream {
public MultiInputStream(
Iterator<? extends InputSupplier<? extends InputStream>> it)
throws IOException {
- this.it = checkNotNull(it);
+ this.it = it;
advance();
}
@@ -91,7 +87,7 @@ final class MultiInputStream extends InputStream {
return result;
}
- @Override public int read(@Nullable byte[] b, int off, int len) throws IOException {
+ @Override public int read(byte[] b, int off, int len) throws IOException {
if (in == null) {
return -1;
}
diff --git a/guava/src/com/google/common/io/MultiReader.java b/guava/src/com/google/common/io/MultiReader.java
index fc0e7fb..6757a26 100644
--- a/guava/src/com/google/common/io/MultiReader.java
+++ b/guava/src/com/google/common/io/MultiReader.java
@@ -22,8 +22,6 @@ import java.io.IOException;
import java.io.Reader;
import java.util.Iterator;
-import javax.annotation.Nullable;
-
/**
* A {@link Reader} that concatenates multiple readers.
*
@@ -50,7 +48,7 @@ class MultiReader extends Reader {
}
}
- @Override public int read(@Nullable char cbuf[], int off, int len) throws IOException {
+ @Override public int read(char cbuf[], int off, int len) throws IOException {
if (current == null) {
return -1;
}
diff --git a/guava/src/com/google/common/io/NullOutputStream.java b/guava/src/com/google/common/io/NullOutputStream.java
index d1dda67..1c1e98e 100644
--- a/guava/src/com/google/common/io/NullOutputStream.java
+++ b/guava/src/com/google/common/io/NullOutputStream.java
@@ -16,8 +16,6 @@
package com.google.common.io;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
import java.io.OutputStream;
@@ -27,11 +25,8 @@ import java.io.OutputStream;
*
* @author Spencer Kimball
* @since 1.0
- * @deprecated Use {@link ByteStreams#nullOutputStream} instead. This class is
- * scheduled to be removed in Guava release 15.0.
*/
@Beta
-@Deprecated
public final class NullOutputStream extends OutputStream {
/** Discards the specified byte. */
@Override public void write(int b) {
@@ -39,6 +34,5 @@ public final class NullOutputStream extends OutputStream {
/** Discards the specified byte array. */
@Override public void write(byte[] b, int off, int len) {
- checkNotNull(b);
}
}
diff --git a/guava/src/com/google/common/io/PatternFilenameFilter.java b/guava/src/com/google/common/io/PatternFilenameFilter.java
index 2859277..065566f 100644
--- a/guava/src/com/google/common/io/PatternFilenameFilter.java
+++ b/guava/src/com/google/common/io/PatternFilenameFilter.java
@@ -27,8 +27,8 @@ import java.util.regex.PatternSyntaxException;
import javax.annotation.Nullable;
/**
- * File name filter that only accepts files matching a regular expression. This
- * class is thread-safe and immutable.
+ * File name filter that only accepts files matching a regular expression. This class is thread-safe
+ * and immutable.
*
* @author Apple Chow
* @since 1.0
diff --git a/guava/src/com/google/common/io/Resources.java b/guava/src/com/google/common/io/Resources.java
index 3d81491..c57a95f 100644
--- a/guava/src/com/google/common/io/Resources.java
+++ b/guava/src/com/google/common/io/Resources.java
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
-import com.google.common.base.Charsets;
import java.io.IOException;
import java.io.InputStream;
@@ -39,7 +38,6 @@ import java.util.List;
*
* @author Chris Nokleberg
* @author Ben Yu
- * @author Colin Decker
* @since 1.0
*/
@Beta
@@ -53,39 +51,15 @@ public final class Resources {
* @param url the URL to read from
* @return the factory
*/
- public static InputSupplier<InputStream> newInputStreamSupplier(URL url) {
- return ByteStreams.asInputSupplier(asByteSource(url));
- }
-
- /**
- * Returns a {@link ByteSource} that reads from the given URL.
- *
- * @since 14.0
- */
- public static ByteSource asByteSource(URL url) {
- return new UrlByteSource(url);
- }
-
- /**
- * A byte source that reads from a URL using {@link URL#openStream()}.
- */
- private static final class UrlByteSource extends ByteSource {
-
- private final URL url;
-
- private UrlByteSource(URL url) {
- this.url = checkNotNull(url);
- }
-
- @Override
- public InputStream openStream() throws IOException {
- return url.openStream();
- }
-
- @Override
- public String toString() {
- return "Resources.newByteSource(" + url + ")";
- }
+ public static InputSupplier<InputStream> newInputStreamSupplier(
+ final URL url) {
+ checkNotNull(url);
+ return new InputSupplier<InputStream>() {
+ @Override
+ public InputStream getInput() throws IOException {
+ return url.openStream();
+ }
+ };
}
/**
@@ -93,22 +67,12 @@ public final class Resources {
* {@link InputStreamReader} that read a URL using the given character set.
*
* @param url the URL to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the URL contents
* @return the factory
*/
public static InputSupplier<InputStreamReader> newReaderSupplier(
URL url, Charset charset) {
- return CharStreams.asInputSupplier(asCharSource(url, charset));
- }
-
- /**
- * Returns a {@link CharSource} that reads from the given URL using the given character set.
- *
- * @since 14.0
- */
- public static CharSource asCharSource(URL url, Charset charset) {
- return asByteSource(url).asCharSource(charset);
+ return CharStreams.newReaderSupplier(newInputStreamSupplier(url), charset);
}
/**
@@ -119,7 +83,7 @@ public final class Resources {
* @throws IOException if an I/O error occurs
*/
public static byte[] toByteArray(URL url) throws IOException {
- return asByteSource(url).read();
+ return ByteStreams.toByteArray(newInputStreamSupplier(url));
}
/**
@@ -127,13 +91,12 @@ public final class Resources {
* character set.
*
* @param url the URL to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the URL
* @return a string containing all the characters from the URL
* @throws IOException if an I/O error occurs.
*/
public static String toString(URL url, Charset charset) throws IOException {
- return asCharSource(url, charset).read();
+ return CharStreams.toString(newReaderSupplier(url, charset));
}
/**
@@ -141,8 +104,7 @@ public final class Resources {
* have read all of the lines.
*
* @param url the URL to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when reading the URL
* @param callback the LineProcessor to use to handle the lines
* @return the output of processing the lines
* @throws IOException if an I/O error occurs
@@ -158,8 +120,7 @@ public final class Resources {
* whitespace.
*
* @param url the URL to read from
- * @param charset the charset used to decode the input stream; see {@link
- * Charsets} for helpful predefined constants
+ * @param charset the character set used when writing the file
* @return a mutable {@link List} containing all the lines
* @throws IOException if an I/O error occurs
*/
@@ -176,7 +137,7 @@ public final class Resources {
* @throws IOException if an I/O error occurs
*/
public static void copy(URL from, OutputStream to) throws IOException {
- asByteSource(from).copyTo(to);
+ ByteStreams.copy(newInputStreamSupplier(from), to);
}
/**
diff --git a/guava/src/com/google/common/io/package-info.java b/guava/src/com/google/common/io/package-info.java
index f5f83ad..9f08e64 100644
--- a/guava/src/com/google/common/io/package-info.java
+++ b/guava/src/com/google/common/io/package-info.java
@@ -38,4 +38,3 @@
package com.google.common.io;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/guava/src/com/google/common/math/BigIntegerMath.java b/guava/src/com/google/common/math/BigIntegerMath.java
index 6b40b6b..99e69fe 100644
--- a/guava/src/com/google/common/math/BigIntegerMath.java
+++ b/guava/src/com/google/common/math/BigIntegerMath.java
@@ -25,8 +25,7 @@ import static java.math.RoundingMode.CEILING;
import static java.math.RoundingMode.FLOOR;
import static java.math.RoundingMode.HALF_EVEN;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import java.math.BigDecimal;
@@ -47,7 +46,7 @@ import java.util.List;
* @author Louis Wasserman
* @since 11.0
*/
-@GwtCompatible(emulated = true)
+@Beta
public final class BigIntegerMath {
/**
* Returns {@code true} if {@code x} represents a power of two.
@@ -65,7 +64,6 @@ public final class BigIntegerMath {
* is not a power of two
*/
@SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
public static int log2(BigInteger x, RoundingMode mode) {
checkPositive("x", checkNotNull(x));
int logFloor = x.bitLength() - 1;
@@ -124,7 +122,6 @@ public final class BigIntegerMath {
* @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
* is not a power of ten
*/
- @GwtIncompatible("TODO")
@SuppressWarnings("fallthrough")
public static int log10(BigInteger x, RoundingMode mode) {
checkPositive("x", x);
@@ -132,45 +129,27 @@ public final class BigIntegerMath {
return LongMath.log10(x.longValue(), mode);
}
- int approxLog10 = (int) (log2(x, FLOOR) * LN_2 / LN_10);
- BigInteger approxPow = BigInteger.TEN.pow(approxLog10);
- int approxCmp = approxPow.compareTo(x);
-
- /*
- * We adjust approxLog10 and approxPow until they're equal to floor(log10(x)) and
- * 10^floor(log10(x)).
- */
-
- if (approxCmp > 0) {
- /*
- * The code is written so that even completely incorrect approximations will still yield the
- * correct answer eventually, but in practice this branch should almost never be entered,
- * and even then the loop should not run more than once.
- */
- do {
- approxLog10--;
- approxPow = approxPow.divide(BigInteger.TEN);
- approxCmp = approxPow.compareTo(x);
- } while (approxCmp > 0);
- } else {
- BigInteger nextPow = BigInteger.TEN.multiply(approxPow);
- int nextCmp = nextPow.compareTo(x);
- while (nextCmp <= 0) {
- approxLog10++;
- approxPow = nextPow;
- approxCmp = nextCmp;
- nextPow = BigInteger.TEN.multiply(approxPow);
- nextCmp = nextPow.compareTo(x);
+ // capacity of 10 suffices for all x <= 10^(2^10).
+ List<BigInteger> powersOf10 = new ArrayList<BigInteger>(10);
+ BigInteger powerOf10 = BigInteger.TEN;
+ while (x.compareTo(powerOf10) >= 0) {
+ powersOf10.add(powerOf10);
+ powerOf10 = powerOf10.pow(2);
+ }
+ BigInteger floorPow = BigInteger.ONE;
+ int floorLog = 0;
+ for (int i = powersOf10.size() - 1; i >= 0; i--) {
+ BigInteger powOf10 = powersOf10.get(i);
+ floorLog *= 2;
+ BigInteger tenPow = powOf10.multiply(floorPow);
+ if (x.compareTo(tenPow) >= 0) {
+ floorPow = tenPow;
+ floorLog++;
}
}
-
- int floorLog = approxLog10;
- BigInteger floorPow = approxPow;
- int floorCmp = approxCmp;
-
switch (mode) {
case UNNECESSARY:
- checkRoundingUnnecessary(floorCmp == 0);
+ checkRoundingUnnecessary(floorPow.equals(x));
// fall through
case FLOOR:
case DOWN:
@@ -192,9 +171,6 @@ public final class BigIntegerMath {
}
}
- private static final double LN_10 = Math.log(10);
- private static final double LN_2 = Math.log(2);
-
/**
* Returns the square root of {@code x}, rounded with the specified rounding mode.
*
@@ -202,7 +178,6 @@ public final class BigIntegerMath {
* @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and
* {@code sqrt(x)} is not an integer
*/
- @GwtIncompatible("TODO")
@SuppressWarnings("fallthrough")
public static BigInteger sqrt(BigInteger x, RoundingMode mode) {
checkNonNegative("x", x);
@@ -234,7 +209,6 @@ public final class BigIntegerMath {
}
}
- @GwtIncompatible("TODO")
private static BigInteger sqrtFloor(BigInteger x) {
/*
* Adapted from Hacker's Delight, Figure 11-1.
@@ -257,7 +231,7 @@ public final class BigIntegerMath {
*/
BigInteger sqrt0;
int log2 = log2(x, FLOOR);
- if(log2 < Double.MAX_EXPONENT) {
+ if(log2 < DoubleUtils.MAX_DOUBLE_EXPONENT) {
sqrt0 = sqrtApproxWithDoubles(x);
} else {
int shift = (log2 - DoubleUtils.SIGNIFICAND_BITS) & ~1; // even!
@@ -278,7 +252,6 @@ public final class BigIntegerMath {
return sqrt0;
}
- @GwtIncompatible("TODO")
private static BigInteger sqrtApproxWithDoubles(BigInteger x) {
return DoubleMath.roundToBigInteger(Math.sqrt(DoubleUtils.bigToDouble(x)), HALF_EVEN);
}
@@ -290,7 +263,6 @@ public final class BigIntegerMath {
* @throws ArithmeticException if {@code q == 0}, or if {@code mode == UNNECESSARY} and {@code a}
* is not an integer multiple of {@code b}
*/
- @GwtIncompatible("TODO")
public static BigInteger divide(BigInteger p, BigInteger q, RoundingMode mode){
BigDecimal pDec = new BigDecimal(p);
BigDecimal qDec = new BigDecimal(q);
@@ -313,8 +285,8 @@ public final class BigIntegerMath {
checkNonNegative("n", n);
// If the factorial is small enough, just use LongMath to do it.
- if (n < LongMath.factorials.length) {
- return BigInteger.valueOf(LongMath.factorials[n]);
+ if (n < LongMath.FACTORIALS.length) {
+ return BigInteger.valueOf(LongMath.FACTORIALS[n]);
}
// Pre-allocate space for our list of intermediate BigIntegers.
@@ -322,8 +294,8 @@ public final class BigIntegerMath {
ArrayList<BigInteger> bignums = new ArrayList<BigInteger>(approxSize);
// Start from the pre-computed maximum long factorial.
- int startingNumber = LongMath.factorials.length;
- long product = LongMath.factorials[startingNumber - 1];
+ int startingNumber = LongMath.FACTORIALS.length;
+ long product = LongMath.FACTORIALS[startingNumber - 1];
// Strip off 2s from this value.
int shift = Long.numberOfTrailingZeros(product);
product >>= shift;
@@ -400,48 +372,18 @@ public final class BigIntegerMath {
if (k > (n >> 1)) {
k = n - k;
}
- if (k < LongMath.biggestBinomials.length && n <= LongMath.biggestBinomials[k]) {
+ if (k < LongMath.BIGGEST_BINOMIALS.length && n <= LongMath.BIGGEST_BINOMIALS[k]) {
return BigInteger.valueOf(LongMath.binomial(n, k));
}
-
- BigInteger accum = BigInteger.ONE;
-
- long numeratorAccum = n;
- long denominatorAccum = 1;
-
- int bits = LongMath.log2(n, RoundingMode.CEILING);
-
- int numeratorBits = bits;
-
- for (int i = 1; i < k; i++) {
- int p = n - i;
- int q = i + 1;
-
- // log2(p) >= bits - 1, because p >= n/2
-
- if (numeratorBits + bits >= Long.SIZE - 1) {
- // The numerator is as big as it can get without risking overflow.
- // Multiply numeratorAccum / denominatorAccum into accum.
- accum = accum
- .multiply(BigInteger.valueOf(numeratorAccum))
- .divide(BigInteger.valueOf(denominatorAccum));
- numeratorAccum = p;
- denominatorAccum = q;
- numeratorBits = bits;
- } else {
- // We can definitely multiply into the long accumulators without overflowing them.
- numeratorAccum *= p;
- denominatorAccum *= q;
- numeratorBits += bits;
- }
+ BigInteger result = BigInteger.ONE;
+ for (int i = 0; i < k; i++) {
+ result = result.multiply(BigInteger.valueOf(n - i));
+ result = result.divide(BigInteger.valueOf(i + 1));
}
- return accum
- .multiply(BigInteger.valueOf(numeratorAccum))
- .divide(BigInteger.valueOf(denominatorAccum));
+ return result;
}
// Returns true if BigInteger.valueOf(x.longValue()).equals(x).
- @GwtIncompatible("TODO")
static boolean fitsInLong(BigInteger x) {
return x.bitLength() <= Long.SIZE - 1;
}
diff --git a/guava/src/com/google/common/math/DoubleMath.java b/guava/src/com/google/common/math/DoubleMath.java
index ded38b2..35365a7 100644
--- a/guava/src/com/google/common/math/DoubleMath.java
+++ b/guava/src/com/google/common/math/DoubleMath.java
@@ -19,31 +19,29 @@ package com.google.common.math;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.math.DoubleUtils.IMPLICIT_BIT;
import static com.google.common.math.DoubleUtils.SIGNIFICAND_BITS;
+import static com.google.common.math.DoubleUtils.getExponent;
import static com.google.common.math.DoubleUtils.getSignificand;
import static com.google.common.math.DoubleUtils.isFinite;
import static com.google.common.math.DoubleUtils.isNormal;
+import static com.google.common.math.DoubleUtils.next;
import static com.google.common.math.DoubleUtils.scaleNormalize;
import static com.google.common.math.MathPreconditions.checkInRange;
import static com.google.common.math.MathPreconditions.checkNonNegative;
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
-import static java.lang.Math.abs;
-import static java.lang.Math.copySign;
-import static java.lang.Math.getExponent;
-import static java.lang.Math.log;
-import static java.lang.Math.rint;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.primitives.Booleans;
import java.math.BigInteger;
import java.math.RoundingMode;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.annotations.Beta;
+
/**
* A class for arithmetic on doubles that is not covered by {@link java.lang.Math}.
*
* @author Louis Wasserman
* @since 11.0
*/
+@Beta
public final class DoubleMath {
/*
* This method returns a value y such that rounding y DOWN (towards zero) gives the same result
@@ -59,55 +57,43 @@ public final class DoubleMath {
return x;
case FLOOR:
- if (x >= 0.0 || isMathematicalInteger(x)) {
- return x;
- } else {
- return x - 1.0;
- }
+ return (x >= 0.0) ? x : Math.floor(x);
case CEILING:
- if (x <= 0.0 || isMathematicalInteger(x)) {
- return x;
- } else {
- return x + 1.0;
- }
+ return (x >= 0.0) ? Math.ceil(x) : x;
case DOWN:
return x;
case UP:
- if (isMathematicalInteger(x)) {
- return x;
- } else {
- return x + Math.copySign(1.0, x);
- }
+ return (x >= 0.0) ? Math.ceil(x) : Math.floor(x);
case HALF_EVEN:
- return rint(x);
+ return Math.rint(x);
- case HALF_UP: {
- double z = rint(x);
- if (abs(x - z) == 0.5) {
- return x + copySign(0.5, x);
+ case HALF_UP:
+ if (isMathematicalInteger(x)) {
+ return x;
} else {
- return z;
+ return (x >= 0.0) ? x + 0.5 : x - 0.5;
}
- }
- case HALF_DOWN: {
- double z = rint(x);
- if (abs(x - z) == 0.5) {
+ case HALF_DOWN:
+ if (isMathematicalInteger(x)) {
return x;
+ } else if (x >= 0.0) {
+ double z = x + 0.5;
+ return (z == x) ? x : next(z, false); // x + 0.5 - epsilon
} else {
- return z;
+ double z = x - 0.5;
+ return (z == x) ? x : next(z, true); // x - 0.5 + epsilon
}
- }
default:
throw new AssertionError();
}
}
-
+
/**
* Returns the {@code int} value that is equal to {@code x} rounded with the specified rounding
* mode, if possible.
@@ -175,6 +161,9 @@ public final class DoubleMath {
return BigInteger.valueOf((long) x);
}
int exponent = getExponent(x);
+ if (exponent < 0) {
+ return BigInteger.ZERO;
+ }
long significand = getSignificand(x);
BigInteger result = BigInteger.valueOf(significand).shiftLeft(exponent - SIGNIFICAND_BITS);
return (x < 0) ? result.negate() : result;
@@ -198,16 +187,16 @@ public final class DoubleMath {
* <li>If {@code x} is positive or negative zero, the result is negative infinity.
* </ul>
*
- * <p>The computed result is within 1 ulp of the exact result.
+ * <p>The computed result must be within 1 ulp of the exact result.
*
* <p>If the result of this method will be immediately rounded to an {@code int},
* {@link #log2(double, RoundingMode)} is faster.
*/
public static double log2(double x) {
- return log(x) / LN_2; // surprisingly within 1 ulp according to tests
+ return Math.log(x) / LN_2; // surprisingly within 1 ulp according to tests
}
- private static final double LN_2 = log(2);
+ private static final double LN_2 = Math.log(2);
/**
* Returns the base 2 logarithm of a double value, rounded with the specified rounding mode to an
@@ -260,14 +249,14 @@ public final class DoubleMath {
/**
* Returns {@code true} if {@code x} represents a mathematical integer.
- *
+ *
* <p>This is equivalent to, but not necessarily implemented as, the expression {@code
* !Double.isNaN(x) && !Double.isInfinite(x) && x == Math.rint(x)}.
*/
public static boolean isMathematicalInteger(double x) {
return isFinite(x)
- && (x == 0.0 ||
- SIGNIFICAND_BITS - Long.numberOfTrailingZeros(getSignificand(x)) <= getExponent(x));
+ && (x == 0.0 || SIGNIFICAND_BITS
+ - Long.numberOfTrailingZeros(getSignificand(x)) <= getExponent(x));
}
/**
@@ -285,12 +274,12 @@ public final class DoubleMath {
return Double.POSITIVE_INFINITY;
} else {
// Multiplying the last (n & 0xf) values into their own accumulator gives a more accurate
- // result than multiplying by everySixteenthFactorial[n >> 4] directly.
+ // result than multiplying by EVERY_SIXTEENTH_FACTORIAL[n >> 4] directly.
double accum = 1.0;
for (int i = 1 + (n & ~0xf); i <= n; i++) {
accum *= i;
}
- return accum * everySixteenthFactorial[n >> 4];
+ return accum * EVERY_SIXTEENTH_FACTORIAL[n >> 4];
}
}
@@ -298,7 +287,7 @@ public final class DoubleMath {
static final int MAX_FACTORIAL = 170;
@VisibleForTesting
- static final double[] everySixteenthFactorial = {
+ static final double[] EVERY_SIXTEENTH_FACTORIAL = {
0x1.0p0,
0x1.30777758p44,
0x1.956ad0aae33a4p117,
@@ -310,66 +299,4 @@ public final class DoubleMath {
0x1.1e5dfc140e1e5p716,
0x1.8ce85fadb707ep829,
0x1.95d5f3d928edep945};
-
- /**
- * Returns {@code true} if {@code a} and {@code b} are within {@code tolerance} of each other.
- *
- * <p>Technically speaking, this is equivalent to
- * {@code Math.abs(a - b) <= tolerance || Double.valueOf(a).equals(Double.valueOf(b))}.
- *
- * <p>Notable special cases include:
- * <ul>
- * <li>All NaNs are fuzzily equal.
- * <li>If {@code a == b}, then {@code a} and {@code b} are always fuzzily equal.
- * <li>Positive and negative zero are always fuzzily equal.
- * <li>If {@code tolerance} is zero, and neither {@code a} nor {@code b} is NaN, then
- * {@code a} and {@code b} are fuzzily equal if and only if {@code a == b}.
- * <li>With {@link Double#POSITIVE_INFINITY} tolerance, all non-NaN values are fuzzily equal.
- * <li>With finite tolerance, {@code Double.POSITIVE_INFINITY} and {@code
- * Double.NEGATIVE_INFINITY} are fuzzily equal only to themselves.
- * </li>
- *
- * <p>This is reflexive and symmetric, but <em>not</em> transitive, so it is <em>not</em> an
- * equivalence relation and <em>not</em> suitable for use in {@link Object#equals}
- * implementations.
- *
- * @throws IllegalArgumentException if {@code tolerance} is {@code < 0} or NaN
- * @since 13.0
- */
- public static boolean fuzzyEquals(double a, double b, double tolerance) {
- MathPreconditions.checkNonNegative("tolerance", tolerance);
- return
- Math.copySign(a - b, 1.0) <= tolerance
- // copySign(x, 1.0) is a branch-free version of abs(x), but with different NaN semantics
- || (a == b) // needed to ensure that infinities equal themselves
- || ((a != a) && (b != b)); // x != x is equivalent to Double.isNaN(x), but faster
- }
-
- /**
- * Compares {@code a} and {@code b} "fuzzily," with a tolerance for nearly-equal values.
- *
- * <p>This method is equivalent to
- * {@code fuzzyEquals(a, b, tolerance) ? 0 : Double.compare(a, b)}. In particular, like
- * {@link Double#compare(double, double)}, it treats all NaN values as equal and greater than all
- * other values (including {@link Double#POSITIVE_INFINITY}).
- *
- * <p>This is <em>not</em> a total ordering and is <em>not</em> suitable for use in
- * {@link Comparable#compareTo} implementations. In particular, it is not transitive.
- *
- * @throws IllegalArgumentException if {@code tolerance} is {@code < 0} or NaN
- * @since 13.0
- */
- public static int fuzzyCompare(double a, double b, double tolerance) {
- if (fuzzyEquals(a, b, tolerance)) {
- return 0;
- } else if (a < b) {
- return -1;
- } else if (a > b) {
- return 1;
- } else {
- return Booleans.compare(Double.isNaN(a), Double.isNaN(b));
- }
- }
-
- private DoubleMath() {}
}
diff --git a/guava/src/com/google/common/math/DoubleUtils.java b/guava/src/com/google/common/math/DoubleUtils.java
index 6cd94e3..5a6fb3e 100644
--- a/guava/src/com/google/common/math/DoubleUtils.java
+++ b/guava/src/com/google/common/math/DoubleUtils.java
@@ -17,27 +17,35 @@
package com.google.common.math;
import static com.google.common.base.Preconditions.checkArgument;
-import static java.lang.Double.MAX_EXPONENT;
-import static java.lang.Double.MIN_EXPONENT;
-import static java.lang.Double.POSITIVE_INFINITY;
-import static java.lang.Double.doubleToRawLongBits;
-import static java.lang.Double.isNaN;
-import static java.lang.Double.longBitsToDouble;
-import static java.lang.Math.getExponent;
import java.math.BigInteger;
+import com.google.common.annotations.VisibleForTesting;
+
/**
- * Utilities for {@code double} primitives.
+ * Utilities for {@code double} primitives. Some of these are exposed in JDK 6,
+ * but we can't depend on them there.
*
* @author Louis Wasserman
*/
final class DoubleUtils {
+ // TODO(user): replace with appropriate calls when we move to JDK 6
+
private DoubleUtils() {
}
- static double nextDown(double d) {
- return -Math.nextUp(-d);
+ static double next(double x, boolean up) {
+ // Math.nextAfter is JDK 6.
+ if (x == 0.0) {
+ return up ? Double.MIN_VALUE : -Double.MIN_VALUE;
+ }
+ long bits = Double.doubleToRawLongBits(x);
+ if ((x < 0.0) == up) {
+ bits--;
+ } else {
+ bits++;
+ }
+ return Double.longBitsToDouble(bits);
}
// The mask for the significand, according to the {@link
@@ -56,27 +64,64 @@ final class DoubleUtils {
static final int EXPONENT_BIAS = 1023;
+ static final int MIN_DOUBLE_EXPONENT = -1022;
+
+ static final int MAX_DOUBLE_EXPONENT = 1023;
+
/**
* The implicit 1 bit that is omitted in significands of normal doubles.
*/
static final long IMPLICIT_BIT = SIGNIFICAND_MASK + 1;
+ @VisibleForTesting
+ static int getExponent(double d) {
+ // TODO: replace with Math.getExponent in JDK 6
+ long bits = Double.doubleToRawLongBits(d);
+ int exponent = (int) ((bits & EXPONENT_MASK) >> SIGNIFICAND_BITS);
+ exponent -= EXPONENT_BIAS;
+ return exponent;
+ }
+
+ /**
+ * Returns {@code d * 2^scale}.
+ */
+ static strictfp double scalb(double d, int scale) {
+ // TODO: replace with Math.scalb in JDK 6
+ int exponent = getExponent(d);
+ switch (exponent) {
+ case MAX_DOUBLE_EXPONENT + 1: // NaN, infinity
+ return d;
+ case MIN_DOUBLE_EXPONENT - 1:
+ return d * StrictMath.pow(2.0, scale);
+ default:
+ int newExponent = exponent + scale;
+ if (MIN_DOUBLE_EXPONENT <= newExponent
+ & newExponent <= MAX_DOUBLE_EXPONENT) {
+ long bits = Double.doubleToRawLongBits(d);
+ bits &= ~EXPONENT_MASK;
+ bits |= ((long) (newExponent + EXPONENT_BIAS)) << SIGNIFICAND_BITS;
+ return Double.longBitsToDouble(bits);
+ }
+ return d * StrictMath.pow(2.0, scale);
+ }
+ }
+
static long getSignificand(double d) {
checkArgument(isFinite(d), "not a normal value");
int exponent = getExponent(d);
- long bits = doubleToRawLongBits(d);
+ long bits = Double.doubleToRawLongBits(d);
bits &= SIGNIFICAND_MASK;
- return (exponent == MIN_EXPONENT - 1)
+ return (exponent == MIN_DOUBLE_EXPONENT - 1)
? bits << 1
: bits | IMPLICIT_BIT;
}
static boolean isFinite(double d) {
- return getExponent(d) <= MAX_EXPONENT;
+ return getExponent(d) <= MAX_DOUBLE_EXPONENT;
}
static boolean isNormal(double d) {
- return getExponent(d) >= MIN_EXPONENT;
+ return getExponent(d) >= MIN_DOUBLE_EXPONENT;
}
/*
@@ -84,8 +129,8 @@ final class DoubleUtils {
* normal, and finite.
*/
static double scaleNormalize(double x) {
- long significand = doubleToRawLongBits(x) & SIGNIFICAND_MASK;
- return longBitsToDouble(significand | ONE_BITS);
+ long significand = Double.doubleToRawLongBits(x) & SIGNIFICAND_MASK;
+ return Double.longBitsToDouble(significand | ONE_BITS);
}
static double bigToDouble(BigInteger x) {
@@ -95,8 +140,8 @@ final class DoubleUtils {
// exponent == floor(log2(abs(x)))
if (exponent < Long.SIZE - 1) {
return x.longValue();
- } else if (exponent > MAX_EXPONENT) {
- return x.signum() * POSITIVE_INFINITY;
+ } else if (exponent > MAX_DOUBLE_EXPONENT) {
+ return x.signum() * Double.POSITIVE_INFINITY;
}
/*
@@ -129,20 +174,8 @@ final class DoubleUtils {
* Double.POSITIVE_INFINITY.
*/
bits |= x.signum() & SIGN_MASK;
- return longBitsToDouble(bits);
- }
-
- /**
- * Returns its argument if it is non-negative, zero if it is negative.
- */
- static double ensureNonNegative(double value) {
- checkArgument(!isNaN(value));
- if (value > 0.0) {
- return value;
- } else {
- return 0.0;
- }
+ return Double.longBitsToDouble(bits);
}
- private static final long ONE_BITS = doubleToRawLongBits(1.0);
+ private static final long ONE_BITS = Double.doubleToRawLongBits(1.0);
}
diff --git a/guava/src/com/google/common/math/IntMath.java b/guava/src/com/google/common/math/IntMath.java
index 33ed400..8fc7cd8 100644
--- a/guava/src/com/google/common/math/IntMath.java
+++ b/guava/src/com/google/common/math/IntMath.java
@@ -23,10 +23,10 @@ import static com.google.common.math.MathPreconditions.checkNonNegative;
import static com.google.common.math.MathPreconditions.checkPositive;
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;
import static java.lang.Math.abs;
-import static java.lang.Math.min;
import static java.math.RoundingMode.HALF_EVEN;
import static java.math.RoundingMode.HALF_UP;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
@@ -48,6 +48,7 @@ import java.math.RoundingMode;
* @author Louis Wasserman
* @since 11.0
*/
+@Beta
@GwtCompatible(emulated = true)
public final class IntMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@@ -70,8 +71,8 @@ public final class IntMath {
* @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
* is not a power of two
*/
+ @GwtIncompatible("need BigIntegerMath to adequately test")
@SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
public static int log2(int x, RoundingMode mode) {
checkPositive("x", x);
switch (mode) {
@@ -116,7 +117,7 @@ public final class IntMath {
public static int log10(int x, RoundingMode mode) {
checkPositive("x", x);
int logFloor = log10Floor(x);
- int floorPow = powersOf10[logFloor];
+ int floorPow = POWERS_OF_10[logFloor];
switch (mode) {
case UNNECESSARY:
checkRoundingUnnecessary(x == floorPow);
@@ -131,40 +132,26 @@ public final class IntMath {
case HALF_UP:
case HALF_EVEN:
// sqrt(10) is irrational, so log10(x) - logFloor is never exactly 0.5
- return (x <= halfPowersOf10[logFloor]) ? logFloor : logFloor + 1;
+ return (x <= HALF_POWERS_OF_10[logFloor]) ? logFloor : logFloor + 1;
default:
throw new AssertionError();
}
}
private static int log10Floor(int x) {
- /*
- * Based on Hacker's Delight Fig. 11-5, the two-table-lookup, branch-free implementation.
- *
- * The key idea is that based on the number of leading zeros (equivalently, floor(log2(x))),
- * we can narrow the possible floor(log10(x)) values to two. For example, if floor(log2(x))
- * is 6, then 64 <= x < 128, so floor(log10(x)) is either 1 or 2.
- */
- int y = maxLog10ForLeadingZeros[Integer.numberOfLeadingZeros(x)];
- // y is the higher of the two possible values of floor(log10(x))
-
- int sgn = (x - powersOf10[y]) >>> (Integer.SIZE - 1);
- /*
- * sgn is the sign bit of x - 10^y; it is 1 if x < 10^y, and 0 otherwise. If x < 10^y, then we
- * want the lower of the two possible values, or y - 1, otherwise, we want y.
- */
- return y - sgn;
+ for (int i = 1; i < POWERS_OF_10.length; i++) {
+ if (x < POWERS_OF_10[i]) {
+ return i - 1;
+ }
+ }
+ return POWERS_OF_10.length - 1;
}
- // maxLog10ForLeadingZeros[i] == floor(log10(2^(Long.SIZE - i)))
- @VisibleForTesting static final byte[] maxLog10ForLeadingZeros = {9, 9, 9, 8, 8, 8,
- 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0};
+ @VisibleForTesting static final int[] POWERS_OF_10 =
+ {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
- @VisibleForTesting static final int[] powersOf10 = {1, 10, 100, 1000, 10000,
- 100000, 1000000, 10000000, 100000000, 1000000000};
-
- // halfPowersOf10[i] = largest int less than 10^(i + 0.5)
- @VisibleForTesting static final int[] halfPowersOf10 =
+ // HALF_POWERS_OF_10[i] = largest int less than 10^(i + 0.5)
+ @VisibleForTesting static final int[] HALF_POWERS_OF_10 =
{3, 31, 316, 3162, 31622, 316227, 3162277, 31622776, 316227766, Integer.MAX_VALUE};
/**
@@ -194,8 +181,6 @@ public final class IntMath {
} else {
return 0;
}
- default:
- // continue below to handle the general case
}
for (int accum = 1;; k >>= 1) {
switch (k) {
@@ -259,6 +244,7 @@ public final class IntMath {
* @throws ArithmeticException if {@code q == 0}, or if {@code mode == UNNECESSARY} and {@code a}
* is not an integer multiple of {@code b}
*/
+ @GwtIncompatible("failing tests")
@SuppressWarnings("fallthrough")
public static int divide(int p, int q, RoundingMode mode) {
checkNotNull(mode);
@@ -352,41 +338,13 @@ public final class IntMath {
*/
checkNonNegative("a", a);
checkNonNegative("b", b);
- if (a == 0) {
- // 0 % b == 0, so b divides a, but the converse doesn't hold.
- // BigInteger.gcd is consistent with this decision.
- return b;
- } else if (b == 0) {
- return a; // similar logic
- }
- /*
- * Uses the binary GCD algorithm; see http://en.wikipedia.org/wiki/Binary_GCD_algorithm.
- * This is >40% faster than the Euclidean algorithm in benchmarks.
- */
- int aTwos = Integer.numberOfTrailingZeros(a);
- a >>= aTwos; // divide out all 2s
- int bTwos = Integer.numberOfTrailingZeros(b);
- b >>= bTwos; // divide out all 2s
- while (a != b) { // both a, b are odd
- // The key to the binary GCD algorithm is as follows:
- // Both a and b are odd. Assume a > b; then gcd(a - b, b) = gcd(a, b).
- // But in gcd(a - b, b), a - b is even and b is odd, so we can divide out powers of two.
-
- // We bend over backwards to avoid branching, adapting a technique from
- // http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
-
- int delta = a - b; // can't overflow, since a and b are nonnegative
-
- int minDeltaOrZero = delta & (delta >> (Integer.SIZE - 1));
- // equivalent to Math.min(delta, 0)
-
- a = delta - minDeltaOrZero - minDeltaOrZero; // sets a to Math.abs(a - b)
- // a is now nonnegative and even
-
- b += minDeltaOrZero; // sets b to min(old a, b)
- a >>= Integer.numberOfTrailingZeros(a); // divide out all 2s, since 2 doesn't divide b
+ // The simple Euclidean algorithm is the fastest for ints, and is easily the most readable.
+ while (b != 0) {
+ int t = b;
+ b = a % b;
+ a = t;
}
- return a << min(aTwos, bTwos);
+ return a;
}
/**
@@ -430,6 +388,7 @@ public final class IntMath {
* @throws ArithmeticException if {@code b} to the {@code k}th power overflows in signed
* {@code int} arithmetic
*/
+ @GwtIncompatible("failing tests")
public static int checkedPow(int b, int k) {
checkNonNegative("exponent", k);
switch (b) {
@@ -445,8 +404,6 @@ public final class IntMath {
case (-2):
checkNoOverflow(k < Integer.SIZE);
return ((k & 1) == 0) ? 1 << k : -1 << k;
- default:
- // continue below to handle the general case
}
int accum = 1;
while (true) {
@@ -477,12 +434,13 @@ public final class IntMath {
*
* @throws IllegalArgumentException if {@code n < 0}
*/
+ @GwtIncompatible("need BigIntegerMath to adequately test")
public static int factorial(int n) {
checkNonNegative("n", n);
- return (n < factorials.length) ? factorials[n] : Integer.MAX_VALUE;
+ return (n < FACTORIALS.length) ? FACTORIALS[n] : Integer.MAX_VALUE;
}
- private static final int[] factorials = {
+ static final int[] FACTORIALS = {
1,
1,
1 * 2,
@@ -511,7 +469,7 @@ public final class IntMath {
if (k > (n >> 1)) {
k = n - k;
}
- if (k >= biggestBinomials.length || n > biggestBinomials[k]) {
+ if (k >= BIGGEST_BINOMIALS.length || n > BIGGEST_BINOMIALS[k]) {
return Integer.MAX_VALUE;
}
switch (k) {
@@ -529,8 +487,8 @@ public final class IntMath {
}
}
- // binomial(biggestBinomials[k], k) fits in an int, but not binomial(biggestBinomials[k]+1,k).
- @VisibleForTesting static int[] biggestBinomials = {
+ // binomial(BIGGEST_BINOMIALS[k], k) fits in an int, but not binomial(BIGGEST_BINOMIALS[k]+1,k).
+ @VisibleForTesting static int[] BIGGEST_BINOMIALS = {
Integer.MAX_VALUE,
Integer.MAX_VALUE,
65536,
@@ -550,18 +508,5 @@ public final class IntMath {
33
};
- /**
- * Returns the arithmetic mean of {@code x} and {@code y}, rounded towards
- * negative infinity. This method is overflow resilient.
- *
- * @since 14.0
- */
- public static int mean(int x, int y) {
- // Efficient method for computing the arithmetic mean.
- // The alternative (x + y) / 2 fails for large values.
- // The alternative (x + y) >>> 1 fails for negative values.
- return (x & y) + ((x ^ y) >> 1);
- }
-
private IntMath() {}
}
diff --git a/guava/src/com/google/common/math/LongMath.java b/guava/src/com/google/common/math/LongMath.java
index 6e00e61..07bd534 100644
--- a/guava/src/com/google/common/math/LongMath.java
+++ b/guava/src/com/google/common/math/LongMath.java
@@ -27,8 +27,7 @@ import static java.lang.Math.min;
import static java.math.RoundingMode.HALF_EVEN;
import static java.math.RoundingMode.HALF_UP;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import java.math.BigInteger;
@@ -48,7 +47,7 @@ import java.math.RoundingMode;
* @author Louis Wasserman
* @since 11.0
*/
-@GwtCompatible(emulated = true)
+@Beta
public final class LongMath {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||
@@ -70,7 +69,6 @@ public final class LongMath {
* is not a power of two
*/
@SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
public static int log2(long x, RoundingMode mode) {
checkPositive("x", x);
switch (mode) {
@@ -110,16 +108,14 @@ public final class LongMath {
* @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
* is not a power of ten
*/
- @GwtIncompatible("TODO")
@SuppressWarnings("fallthrough")
- // TODO(kevinb): remove after this warning is disabled globally
public static int log10(long x, RoundingMode mode) {
checkPositive("x", x);
if (fitsInInt(x)) {
return IntMath.log10((int) x, mode);
}
int logFloor = log10Floor(x);
- long floorPow = powersOf10[logFloor];
+ long floorPow = POWERS_OF_10[logFloor];
switch (mode) {
case UNNECESSARY:
checkRoundingUnnecessary(x == floorPow);
@@ -134,41 +130,23 @@ public final class LongMath {
case HALF_UP:
case HALF_EVEN:
// sqrt(10) is irrational, so log10(x)-logFloor is never exactly 0.5
- return (x <= halfPowersOf10[logFloor]) ? logFloor : logFloor + 1;
+ return (x <= HALF_POWERS_OF_10[logFloor]) ? logFloor : logFloor + 1;
default:
throw new AssertionError();
}
}
- @GwtIncompatible("TODO")
static int log10Floor(long x) {
- /*
- * Based on Hacker's Delight Fig. 11-5, the two-table-lookup, branch-free implementation.
- *
- * The key idea is that based on the number of leading zeros (equivalently, floor(log2(x))),
- * we can narrow the possible floor(log10(x)) values to two. For example, if floor(log2(x))
- * is 6, then 64 <= x < 128, so floor(log10(x)) is either 1 or 2.
- */
- int y = maxLog10ForLeadingZeros[Long.numberOfLeadingZeros(x)];
- // y is the higher of the two possible values of floor(log10(x))
-
- long sgn = (x - powersOf10[y]) >>> (Long.SIZE - 1);
- /*
- * sgn is the sign bit of x - 10^y; it is 1 if x < 10^y, and 0 otherwise. If x < 10^y, then we
- * want the lower of the two possible values, or y - 1, otherwise, we want y.
- */
- return y - (int) sgn;
+ for (int i = 1; i < POWERS_OF_10.length; i++) {
+ if (x < POWERS_OF_10[i]) {
+ return i - 1;
+ }
+ }
+ return POWERS_OF_10.length - 1;
}
- // maxLog10ForLeadingZeros[i] == floor(log10(2^(Long.SIZE - i)))
- @VisibleForTesting static final byte[] maxLog10ForLeadingZeros = {
- 19, 18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12,
- 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4,
- 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0 };
-
- @GwtIncompatible("TODO")
@VisibleForTesting
- static final long[] powersOf10 = {
+ static final long[] POWERS_OF_10 = {
1L,
10L,
100L,
@@ -190,10 +168,9 @@ public final class LongMath {
1000000000000000000L
};
- // halfPowersOf10[i] = largest long less than 10^(i + 0.5)
- @GwtIncompatible("TODO")
+ // HALF_POWERS_OF_10[i] = largest long less than 10^(i + 0.5)
@VisibleForTesting
- static final long[] halfPowersOf10 = {
+ static final long[] HALF_POWERS_OF_10 = {
3L,
31L,
316L,
@@ -222,7 +199,6 @@ public final class LongMath {
*
* @throws IllegalArgumentException if {@code k < 0}
*/
- @GwtIncompatible("TODO")
public static long pow(long b, int k) {
checkNonNegative("exponent", k);
if (-2 <= b && b <= 2) {
@@ -241,8 +217,6 @@ public final class LongMath {
} else {
return 0;
}
- default:
- throw new AssertionError();
}
}
for (long accum = 1;; k >>= 1) {
@@ -265,7 +239,6 @@ public final class LongMath {
* @throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and
* {@code sqrt(x)} is not an integer
*/
- @GwtIncompatible("TODO")
@SuppressWarnings("fallthrough")
public static long sqrt(long x, RoundingMode mode) {
checkNonNegative("x", x);
@@ -297,60 +270,19 @@ public final class LongMath {
}
}
- @GwtIncompatible("TODO")
private static long sqrtFloor(long x) {
- long guess = (long) Math.sqrt(x);
- /*
- * Lemma: For all a, b, if |a - b| <= 1, then |floor(a) - floor(b)| <= 1.
- *
- * Proof:
- * -1 <= a - b <= 1
- * b - 1 <= a <= b + 1
- * floor(b - 1) <= floor(a) <= floor(b + 1)
- * floor(b) - 1 <= floor(a) <= floor(b) + 1
- * -1 <= floor(a) - floor(b) <= 1
- *
- * Theorem: |floor(sqrt(x)) - guess| <= 1.
- *
- * Proof: By the lemma, it suffices to show that |sqrt(x) - Math.sqrt(x)| <= 1.
- * We consider two cases: x <= 2^53 and x > 2^53.
- *
- * If x <= 2^53, then x is exactly representable as a double, so the only error is in rounding
- * sqrt(x) to a double, which introduces at most 2^-52 relative error. Since sqrt(x) < 2^27,
- * the absolute error is at most 2^(27-52) = 2^-25 < 1.
- *
- * Otherwise, x > 2^53. The rounding error introduced by casting x to a double is at most
- * 2^63 * 2^-52 = 2^11. Noting that sqrt(x) > 2^26,
- *
- * sqrt(x) - 0.5 = sqrt((sqrt(x) - 0.5)^2)
- * = sqrt(x - sqrt(x) + 0.25)
- * < sqrt(x - 2^26 + 0.25)
- * < sqrt(x - 2^11)
- * <= sqrt((double) x)
- * sqrt(x) + 0.5 = sqrt((sqrt(x) + 0.5)^2)
- * = sqrt(x + sqrt(x) + 0.25)
- * > sqrt(x + 2^26 + 0.25)
- * > sqrt(x + 2^11)
- * >= sqrt((double) x)
- * sqrt(x) - 0.5 < sqrt((double) x) < sqrt(x) + 0.5
- *
- * Math.sqrt((double) x) is obtained by rounding sqrt((double) x) to a double, increasing the
- * error by at most 2^-52 * sqrt(x) <= 2^(32 - 52) <= 2^-20, so clearly
- *
- * sqrt(x) - 0.5 - 2^-20 <= Math.sqrt((double) x) <= sqrt(x) + 0.5 + 2^-20
- *
- * Therefore, |sqrt(x) - Math.sqrt((double) x)| <= 1, so
- * |floor(sqrt(x)) - (long) Math.sqrt((double) x)| <= 1
- * as desired.
- */
- long guessSquared = guess * guess;
- if (x - guessSquared >= guess + guess + 1) {
- // The condition is equivalent to x >= (guess + 1) * (guess + 1), but doesn't overflow.
- guess++;
- } else if (x < guessSquared) {
- guess--;
+ // Hackers's Delight, Figure 11-1
+ long sqrt0 = (long) Math.sqrt(x);
+ // Precision can be lost in the cast to double, so we use this as a starting estimate.
+ long sqrt1 = (sqrt0 + (x / sqrt0)) >> 1;
+ if (sqrt1 == sqrt0) {
+ return sqrt0;
}
- return guess;
+ do {
+ sqrt0 = sqrt1;
+ sqrt1 = (sqrt0 + (x / sqrt0)) >> 1;
+ } while (sqrt1 < sqrt0);
+ return sqrt0;
}
/**
@@ -360,7 +292,6 @@ public final class LongMath {
* @throws ArithmeticException if {@code q == 0}, or if {@code mode == UNNECESSARY} and {@code a}
* is not an integer multiple of {@code b}
*/
- @GwtIncompatible("TODO")
@SuppressWarnings("fallthrough")
public static long divide(long p, long q, RoundingMode mode) {
checkNotNull(mode);
@@ -431,7 +362,6 @@ public final class LongMath {
*
* @throws ArithmeticException if {@code m <= 0}
*/
- @GwtIncompatible("TODO")
public static int mod(long x, int m) {
// Cast is safe because the result is guaranteed in the range [0, m)
return (int) mod(x, (long) m);
@@ -453,7 +383,6 @@ public final class LongMath {
*
* @throws ArithmeticException if {@code m <= 0}
*/
- @GwtIncompatible("TODO")
public static long mod(long x, long m) {
if (m <= 0) {
throw new ArithmeticException("Modulus " + m + " must be > 0");
@@ -476,38 +405,24 @@ public final class LongMath {
*/
checkNonNegative("a", a);
checkNonNegative("b", b);
- if (a == 0) {
- // 0 % b == 0, so b divides a, but the converse doesn't hold.
- // BigInteger.gcd is consistent with this decision.
- return b;
- } else if (b == 0) {
- return a; // similar logic
+ if (a == 0 | b == 0) {
+ return a | b;
}
/*
* Uses the binary GCD algorithm; see http://en.wikipedia.org/wiki/Binary_GCD_algorithm.
- * This is >60% faster than the Euclidean algorithm in benchmarks.
+ * This is over 40% faster than the Euclidean algorithm in benchmarks.
*/
int aTwos = Long.numberOfTrailingZeros(a);
a >>= aTwos; // divide out all 2s
int bTwos = Long.numberOfTrailingZeros(b);
b >>= bTwos; // divide out all 2s
while (a != b) { // both a, b are odd
- // The key to the binary GCD algorithm is as follows:
- // Both a and b are odd. Assume a > b; then gcd(a - b, b) = gcd(a, b).
- // But in gcd(a - b, b), a - b is even and b is odd, so we can divide out powers of two.
-
- // We bend over backwards to avoid branching, adapting a technique from
- // http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
-
- long delta = a - b; // can't overflow, since a and b are nonnegative
-
- long minDeltaOrZero = delta & (delta >> (Long.SIZE - 1));
- // equivalent to Math.min(delta, 0)
-
- a = delta - minDeltaOrZero - minDeltaOrZero; // sets a to Math.abs(a - b)
- // a is now nonnegative and even
-
- b += minDeltaOrZero; // sets b to min(old a, b)
+ if (a < b) { // swap a, b
+ long t = b;
+ b = a;
+ a = t;
+ }
+ a -= b; // a is now positive and even
a >>= Long.numberOfTrailingZeros(a); // divide out all 2s, since 2 doesn't divide b
}
return a << min(aTwos, bTwos);
@@ -518,7 +433,6 @@ public final class LongMath {
*
* @throws ArithmeticException if {@code a + b} overflows in signed {@code long} arithmetic
*/
- @GwtIncompatible("TODO")
public static long checkedAdd(long a, long b) {
long result = a + b;
checkNoOverflow((a ^ b) < 0 | (a ^ result) >= 0);
@@ -530,7 +444,6 @@ public final class LongMath {
*
* @throws ArithmeticException if {@code a - b} overflows in signed {@code long} arithmetic
*/
- @GwtIncompatible("TODO")
public static long checkedSubtract(long a, long b) {
long result = a - b;
checkNoOverflow((a ^ b) >= 0 | (a ^ result) >= 0);
@@ -542,7 +455,6 @@ public final class LongMath {
*
* @throws ArithmeticException if {@code a * b} overflows in signed {@code long} arithmetic
*/
- @GwtIncompatible("TODO")
public static long checkedMultiply(long a, long b) {
// Hacker's Delight, Section 2-12
int leadingZeros = Long.numberOfLeadingZeros(a) + Long.numberOfLeadingZeros(~a)
@@ -573,7 +485,6 @@ public final class LongMath {
* @throws ArithmeticException if {@code b} to the {@code k}th power overflows in signed
* {@code long} arithmetic
*/
- @GwtIncompatible("TODO")
public static long checkedPow(long b, int k) {
checkNonNegative("exponent", k);
if (b >= -2 & b <= 2) {
@@ -590,8 +501,6 @@ public final class LongMath {
case (-2):
checkNoOverflow(k < Long.SIZE);
return ((k & 1) == 0) ? (1L << k) : (-1L << k);
- default:
- throw new AssertionError();
}
}
long accum = 1;
@@ -614,7 +523,6 @@ public final class LongMath {
}
}
- @GwtIncompatible("TODO")
@VisibleForTesting static final long FLOOR_SQRT_MAX_LONG = 3037000499L;
/**
@@ -624,13 +532,12 @@ public final class LongMath {
*
* @throws IllegalArgumentException if {@code n < 0}
*/
- @GwtIncompatible("TODO")
public static long factorial(int n) {
checkNonNegative("n", n);
- return (n < factorials.length) ? factorials[n] : Long.MAX_VALUE;
+ return (n < FACTORIALS.length) ? FACTORIALS[n] : Long.MAX_VALUE;
}
- static final long[] factorials = {
+ static final long[] FACTORIALS = {
1L,
1L,
1L * 2,
@@ -667,111 +574,51 @@ public final class LongMath {
if (k > (n >> 1)) {
k = n - k;
}
- switch (k) {
- case 0:
- return 1;
- case 1:
- return n;
- default:
- if (n < factorials.length) {
- return factorials[n] / (factorials[k] * factorials[n - k]);
- } else if (k >= biggestBinomials.length || n > biggestBinomials[k]) {
- return Long.MAX_VALUE;
- } else if (k < biggestSimpleBinomials.length && n <= biggestSimpleBinomials[k]) {
- // guaranteed not to overflow
- long result = n--;
- for (int i = 2; i <= k; n--, i++) {
- result *= n;
- result /= i;
- }
- return result;
- } else {
- int nBits = LongMath.log2(n, RoundingMode.CEILING);
-
- long result = 1;
- long numerator = n--;
- long denominator = 1;
-
- int numeratorBits = nBits;
- // This is an upper bound on log2(numerator, ceiling).
-
- /*
- * We want to do this in long math for speed, but want to avoid overflow. We adapt the
- * technique previously used by BigIntegerMath: maintain separate numerator and
- * denominator accumulators, multiplying the fraction into result when near overflow.
- */
- for (int i = 2; i <= k; i++, n--) {
- if (numeratorBits + nBits < Long.SIZE - 1) {
- // It's definitely safe to multiply into numerator and denominator.
- numerator *= n;
- denominator *= i;
- numeratorBits += nBits;
- } else {
- // It might not be safe to multiply into numerator and denominator,
- // so multiply (numerator / denominator) into result.
- result = multiplyFraction(result, numerator, denominator);
- numerator = n;
- denominator = i;
- numeratorBits = nBits;
- }
- }
- return multiplyFraction(result, numerator, denominator);
- }
+ if (k >= BIGGEST_BINOMIALS.length || n > BIGGEST_BINOMIALS[k]) {
+ return Long.MAX_VALUE;
}
- }
-
- /**
- * Returns (x * numerator / denominator), which is assumed to come out to an integral value.
- */
- static long multiplyFraction(long x, long numerator, long denominator) {
- if (x == 1) {
- return numerator / denominator;
+ long result = 1;
+ if (k < BIGGEST_SIMPLE_BINOMIALS.length && n <= BIGGEST_SIMPLE_BINOMIALS[k]) {
+ // guaranteed not to overflow
+ for (int i = 0; i < k; i++) {
+ result *= n - i;
+ result /= i + 1;
+ }
+ } else {
+ // We want to do this in long math for speed, but want to avoid overflow.
+ // Dividing by the GCD suffices to avoid overflow in all the remaining cases.
+ for (int i = 1; i <= k; i++, n--) {
+ int d = IntMath.gcd(n, i);
+ result /= i / d; // (i/d) is guaranteed to divide result
+ result *= n / d;
+ }
}
- long commonDivisor = gcd(x, denominator);
- x /= commonDivisor;
- denominator /= commonDivisor;
- // We know gcd(x, denominator) = 1, and x * numerator / denominator is exact,
- // so denominator must be a divisor of numerator.
- return x * (numerator / denominator);
+ return result;
}
/*
- * binomial(biggestBinomials[k], k) fits in a long, but not
- * binomial(biggestBinomials[k] + 1, k).
+ * binomial(BIGGEST_BINOMIALS[k], k) fits in a long, but not
+ * binomial(BIGGEST_BINOMIALS[k] + 1, k).
*/
- static final int[] biggestBinomials =
+ static final int[] BIGGEST_BINOMIALS =
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 3810779, 121977, 16175, 4337, 1733,
887, 534, 361, 265, 206, 169, 143, 125, 111, 101, 94, 88, 83, 79, 76, 74, 72, 70, 69, 68,
67, 67, 66, 66, 66, 66};
/*
- * binomial(biggestSimpleBinomials[k], k) doesn't need to use the slower GCD-based impl,
- * but binomial(biggestSimpleBinomials[k] + 1, k) does.
+ * binomial(BIGGEST_SIMPLE_BINOMIALS[k], k) doesn't need to use the slower GCD-based impl,
+ * but binomial(BIGGEST_SIMPLE_BINOMIALS[k] + 1, k) does.
*/
- @VisibleForTesting static final int[] biggestSimpleBinomials =
+ @VisibleForTesting static final int[] BIGGEST_SIMPLE_BINOMIALS =
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 2642246, 86251, 11724, 3218, 1313,
684, 419, 287, 214, 169, 139, 119, 105, 95, 87, 81, 76, 73, 70, 68, 66, 64, 63, 62, 62,
61, 61, 61};
// These values were generated by using checkedMultiply to see when the simple multiply/divide
// algorithm would lead to an overflow.
- @GwtIncompatible("TODO")
static boolean fitsInInt(long x) {
return (int) x == x;
}
- /**
- * Returns the arithmetic mean of {@code x} and {@code y}, rounded toward
- * negative infinity. This method is resilient to overflow.
- *
- * @since 14.0
- */
- public static long mean(long x, long y) {
- // Efficient method for computing the arithmetic mean.
- // The alternative (x + y) / 2 fails for large values.
- // The alternative (x + y) >>> 1 fails for negative values.
- return (x & y) + ((x ^ y) >> 1);
- }
-
private LongMath() {}
}
diff --git a/guava/src/com/google/common/math/MathPreconditions.java b/guava/src/com/google/common/math/MathPreconditions.java
index afaee3b..98a6d38 100644
--- a/guava/src/com/google/common/math/MathPreconditions.java
+++ b/guava/src/com/google/common/math/MathPreconditions.java
@@ -1,76 +1,71 @@
/*
* Copyright (C) 2011 The Guava Authors
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations
- * under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.google.common.math;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.annotations.GwtCompatible;
import java.math.BigInteger;
-import javax.annotation.Nullable;
-
/**
* A collection of preconditions for math functions.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible
final class MathPreconditions {
- static int checkPositive(@Nullable String role, int x) {
+ static int checkPositive(String role, int x) {
if (x <= 0) {
throw new IllegalArgumentException(role + " (" + x + ") must be > 0");
}
return x;
}
- static long checkPositive(@Nullable String role, long x) {
+ static long checkPositive(String role, long x) {
if (x <= 0) {
throw new IllegalArgumentException(role + " (" + x + ") must be > 0");
}
return x;
}
- static BigInteger checkPositive(@Nullable String role, BigInteger x) {
+ static BigInteger checkPositive(String role, BigInteger x) {
if (x.signum() <= 0) {
throw new IllegalArgumentException(role + " (" + x + ") must be > 0");
}
return x;
}
- static int checkNonNegative(@Nullable String role, int x) {
+ static int checkNonNegative(String role, int x) {
if (x < 0) {
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
}
return x;
}
- static long checkNonNegative(@Nullable String role, long x) {
+ static long checkNonNegative(String role, long x) {
if (x < 0) {
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
}
return x;
}
- static BigInteger checkNonNegative(@Nullable String role, BigInteger x) {
- if (x.signum() < 0) {
- throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
- }
- return x;
- }
-
- static double checkNonNegative(@Nullable String role, double x) {
- if (!(x >= 0)) { // not x < 0, to work with NaN.
+ static BigInteger checkNonNegative(String role, BigInteger x) {
+ if (checkNotNull(x).signum() < 0) {
throw new IllegalArgumentException(role + " (" + x + ") must be >= 0");
}
return x;
diff --git a/guava/src/com/google/common/math/package-info.java b/guava/src/com/google/common/math/package-info.java
index bd17e52..6bbd4f2 100644
--- a/guava/src/com/google/common/math/package-info.java
+++ b/guava/src/com/google/common/math/package-info.java
@@ -19,13 +19,8 @@
*
* <p>This package is a part of the open-source
* <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/MathExplained">
- * math utilities</a>.
*/
@ParametersAreNonnullByDefault
package com.google.common.math;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/guava/src/com/google/common/net/HostAndPort.java b/guava/src/com/google/common/net/HostAndPort.java
index a0cd3bf..eacc858 100644
--- a/guava/src/com/google/common/net/HostAndPort.java
+++ b/guava/src/com/google/common/net/HostAndPort.java
@@ -22,13 +22,10 @@ import static com.google.common.base.Preconditions.checkState;
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
-import com.google.common.base.Strings;
-import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
@@ -63,7 +60,7 @@ import javax.annotation.concurrent.Immutable;
* @since 10.0
*/
@Beta @Immutable
-public final class HostAndPort implements Serializable {
+public final class HostAndPort {
/** Magic value indicating the absence of a port number. */
private static final int NO_PORT = -1;
@@ -86,7 +83,7 @@ public final class HostAndPort implements Serializable {
* Returns the portion of this {@code HostAndPort} instance that should
* represent the hostname or IPv4/IPv6 literal.
*
- * <p>A successful parse does not imply any degree of sanity in this field.
+ * A successful parse does not imply any degree of sanity in this field.
* For additional validation, see the {@link HostSpecifier} class.
*/
public String getHostText() {
@@ -174,7 +171,7 @@ public final class HostAndPort implements Serializable {
}
int port = NO_PORT;
- if (!Strings.isNullOrEmpty(portString)) {
+ if (portString != null) {
// Try to parse the whole port string as a number.
// JDK7 accepts leading plus signs. We don't want to.
checkArgument(!portString.startsWith("+"), "Unparseable port number: %s", hostPortString);
@@ -228,7 +225,7 @@ public final class HostAndPort implements Serializable {
}
@Override
- public boolean equals(@Nullable Object other) {
+ public boolean equals(Object other) {
if (this == other) {
return true;
}
@@ -265,6 +262,4 @@ public final class HostAndPort implements Serializable {
private static boolean isValidPort(int port) {
return port >= 0 && port <= 65535;
}
-
- private static final long serialVersionUID = 0;
}
diff --git a/guava/src/com/google/common/net/HttpHeaders.java b/guava/src/com/google/common/net/HttpHeaders.java
index ace1773..4bb6f9f 100644
--- a/guava/src/com/google/common/net/HttpHeaders.java
+++ b/guava/src/com/google/common/net/HttpHeaders.java
@@ -16,6 +16,7 @@
package com.google.common.net;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
/**
@@ -31,6 +32,7 @@ import com.google.common.annotations.GwtCompatible;
* @author Kurt Alfred Kluever
* @since 11.0
*/
+@Beta
@GwtCompatible
public final class HttpHeaders {
private HttpHeaders() {}
diff --git a/guava/src/com/google/common/net/InetAddresses.java b/guava/src/com/google/common/net/InetAddresses.java
index 8eddd0d..2cd9472 100644
--- a/guava/src/com/google/common/net/InetAddresses.java
+++ b/guava/src/com/google/common/net/InetAddresses.java
@@ -17,9 +17,8 @@
package com.google.common.net;
import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
-import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.common.primitives.Ints;
@@ -42,6 +41,12 @@ import javax.annotation.Nullable;
* IP address string literals -- there is no blocking DNS penalty for a
* malformed string.
*
+ * <p>This class hooks into the {@code sun.net.util.IPAddressUtil} class
+ * to make use of the {@code textToNumericFormatV4} and
+ * {@code textToNumericFormatV6} methods directly as a means to avoid
+ * accidentally traversing all nameservices (it can be vitally important
+ * to avoid, say, blocking on DNS at times).
+ *
* <p>When dealing with {@link Inet4Address} and {@link Inet6Address}
* objects as byte arrays (vis. {@code InetAddress.getAddress()}) they
* are 4 and 16 bytes in length, respectively, and represent the address
@@ -114,36 +119,68 @@ import javax.annotation.Nullable;
public final class InetAddresses {
private static final int IPV4_PART_COUNT = 4;
private static final int IPV6_PART_COUNT = 8;
- private static final Inet4Address LOOPBACK4 = (Inet4Address) forString("127.0.0.1");
- private static final Inet4Address ANY4 = (Inet4Address) forString("0.0.0.0");
+ private static final Inet4Address LOOPBACK4 =
+ (Inet4Address) forString("127.0.0.1");
+ private static final Inet4Address ANY4 =
+ (Inet4Address) forString("0.0.0.0");
private InetAddresses() {}
/**
- * Returns an {@link Inet4Address}, given a byte array representation of the IPv4 address.
+ * Returns an {@link Inet4Address}, given a byte array representation
+ * of the IPv4 address.
*
- * @param bytes byte array representing an IPv4 address (should be of length 4)
- * @return {@link Inet4Address} corresponding to the supplied byte array
- * @throws IllegalArgumentException if a valid {@link Inet4Address} can not be created
+ * @param bytes byte array representing an IPv4 address (should be
+ * of length 4).
+ * @return {@link Inet4Address} corresponding to the supplied byte
+ * array.
+ * @throws IllegalArgumentException if a valid {@link Inet4Address}
+ * can not be created.
*/
private static Inet4Address getInet4Address(byte[] bytes) {
Preconditions.checkArgument(bytes.length == 4,
"Byte array has invalid length for an IPv4 address: %s != 4.",
bytes.length);
- // Given a 4-byte array, this cast should always succeed.
- return (Inet4Address) bytesToInetAddress(bytes);
+ try {
+ InetAddress ipv4 = InetAddress.getByAddress(bytes);
+ if (!(ipv4 instanceof Inet4Address)) {
+ throw new UnknownHostException(
+ String.format("'%s' is not an IPv4 address.",
+ ipv4.getHostAddress()));
+ }
+
+ return (Inet4Address) ipv4;
+ } catch (UnknownHostException e) {
+
+ /*
+ * This really shouldn't happen in practice since all our byte
+ * sequences should be valid IP addresses.
+ *
+ * However {@link InetAddress#getByAddress} is documented as
+ * potentially throwing this "if IP address is of illegal length".
+ *
+ * This is mapped to IllegalArgumentException since, presumably,
+ * the argument triggered some bizarre processing bug.
+ */
+ throw new IllegalArgumentException(
+ String.format("Host address '%s' is not a valid IPv4 address.",
+ Arrays.toString(bytes)),
+ e);
+ }
}
/**
- * Returns the {@link InetAddress} having the given string representation.
+ * Returns the {@link InetAddress} having the given string
+ * representation.
*
* <p>This deliberately avoids all nameservice lookups (e.g. no DNS).
*
- * @param ipString {@code String} containing an IPv4 or IPv6 string literal, e.g.
- * {@code "192.168.0.1"} or {@code "2001:db8::1"}
+ * @param ipString {@code String} containing an IPv4 or IPv6 string literal,
+ * e.g. {@code "192.168.0.1"} or {@code "2001:db8::1"}
* @return {@link InetAddress} representing the argument
- * @throws IllegalArgumentException if the argument is not a valid IP string literal
+ * @throws IllegalArgumentException if the argument is not a valid
+ * IP string literal
*/
public static InetAddress forString(String ipString) {
byte[] addr = ipStringToBytes(ipString);
@@ -154,7 +191,25 @@ public final class InetAddresses {
String.format("'%s' is not an IP string literal.", ipString));
}
- return bytesToInetAddress(addr);
+ try {
+ return InetAddress.getByAddress(addr);
+ } catch (UnknownHostException e) {
+
+ /*
+ * This really shouldn't happen in practice since all our byte
+ * sequences should be valid IP addresses.
+ *
+ * However {@link InetAddress#getByAddress} is documented as
+ * potentially throwing this "if IP address is of illegal length".
+ *
+ * This is mapped to IllegalArgumentException since, presumably,
+ * the argument triggered some processing bug in either
+ * {@link IPAddressUtil#textToNumericFormatV4} or
+ * {@link IPAddressUtil#textToNumericFormatV6}.
+ */
+ throw new IllegalArgumentException(
+ String.format("'%s' is extremely broken.", ipString), e);
+ }
}
/**
@@ -316,25 +371,6 @@ public final class InetAddresses {
}
/**
- * Convert a byte array into an InetAddress.
- *
- * {@link InetAddress#getByAddress} is documented as throwing a checked
- * exception "if IP address if of illegal length." We replace it with
- * an unchecked exception, for use by callers who already know that addr
- * is an array of length 4 or 16.
- *
- * @param addr the raw 4-byte or 16-byte IP address in big-endian order
- * @return an InetAddress object created from the raw IP address
- */
- private static InetAddress bytesToInetAddress(byte[] addr) {
- try {
- return InetAddress.getByAddress(addr);
- } catch (UnknownHostException e) {
- throw new AssertionError(e);
- }
- }
-
- /**
* Returns the string representation of an {@link InetAddress}.
*
* <p>For IPv4 addresses, this is identical to
@@ -375,7 +411,7 @@ public final class InetAddresses {
* leftmost run wins. If a qualifying run is found, its hextets are replaced
* by the sentinel value -1.
*
- * @param hextets {@code int[]} mutable array of eight 16-bit hextets
+ * @param hextets {@code int[]} mutable array of eight 16-bit hextets.
*/
private static void compressLongestRunOfZeroes(int[] hextets) {
int bestRunStart = -1;
@@ -400,13 +436,13 @@ public final class InetAddresses {
}
}
- /**
+ /**
* Convert a list of hextets into a human-readable IPv6 address.
*
* <p>In order for "::" compression to work, the input should contain negative
* sentinel values in place of the elided zeroes.
*
- * @param hextets {@code int[]} array of eight 16-bit hextets, or -1s
+ * @param hextets {@code int[]} array of eight 16-bit hextets, or -1s.
*/
private static String hextetsToIPv6String(int[] hextets) {
/*
@@ -483,26 +519,30 @@ public final class InetAddresses {
*/
public static InetAddress forUriString(String hostAddr) {
Preconditions.checkNotNull(hostAddr);
+ Preconditions.checkArgument(hostAddr.length() > 0, "host string is empty");
+ InetAddress retval = null;
- // Decide if this should be an IPv6 or IPv4 address.
- String ipString;
- int expectBytes;
- if (hostAddr.startsWith("[") && hostAddr.endsWith("]")) {
- ipString = hostAddr.substring(1, hostAddr.length() - 1);
- expectBytes = 16;
- } else {
- ipString = hostAddr;
- expectBytes = 4;
+ // IPv4 address?
+ try {
+ retval = forString(hostAddr);
+ if (retval instanceof Inet4Address) {
+ return retval;
+ }
+ } catch (IllegalArgumentException e) {
+ // Not a valid IP address, fall through.
}
- // Parse the address, and make sure the length/version is correct.
- byte[] addr = ipStringToBytes(ipString);
- if (addr == null || addr.length != expectBytes) {
- throw new IllegalArgumentException(
- String.format("Not a valid URI IP literal: '%s'", hostAddr));
+ // IPv6 address
+ if (!(hostAddr.startsWith("[") && hostAddr.endsWith("]"))) {
+ throw new IllegalArgumentException("Not a valid address: \"" + hostAddr + '"');
+ }
+
+ retval = forString(hostAddr.substring(1, hostAddr.length() - 1));
+ if (retval instanceof Inet6Address) {
+ return retval;
}
- return bytesToInetAddress(addr);
+ throw new IllegalArgumentException("Not a valid address: \"" + hostAddr + '"');
}
/**
@@ -542,7 +582,8 @@ public final class InetAddresses {
* proper IPv6 addresses (which they are), NOT IPv4 compatible
* addresses (which they are generally NOT considered to be).
*
- * @param ip {@link Inet6Address} to be examined for embedded IPv4 compatible address format
+ * @param ip {@link Inet6Address} to be examined for embedded IPv4
+ * compatible address format
* @return {@code true} if the argument is a valid "compat" address
*/
public static boolean isCompatIPv4Address(Inet6Address ip) {
@@ -552,7 +593,7 @@ public final class InetAddresses {
byte[] bytes = ip.getAddress();
if ((bytes[12] == 0) && (bytes[13] == 0) && (bytes[14] == 0)
- && ((bytes[15] == 0) || (bytes[15] == 1))) {
+ && ((bytes[15] == 0) || (bytes[15] == 1))) {
return false;
}
@@ -562,15 +603,17 @@ public final class InetAddresses {
/**
* Returns the IPv4 address embedded in an IPv4 compatible address.
*
- * @param ip {@link Inet6Address} to be examined for an embedded IPv4 address
+ * @param ip {@link Inet6Address} to be examined for an embedded
+ * IPv4 address
* @return {@link Inet4Address} of the embedded IPv4 address
- * @throws IllegalArgumentException if the argument is not a valid IPv4 compatible address
+ * @throws IllegalArgumentException if the argument is not a valid
+ * IPv4 compatible address
*/
public static Inet4Address getCompatIPv4Address(Inet6Address ip) {
Preconditions.checkArgument(isCompatIPv4Address(ip),
"Address '%s' is not IPv4-compatible.", toAddrString(ip));
- return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16));
+ return getInet4Address(copyOfRange(ip.getAddress(), 12, 16));
}
/**
@@ -584,7 +627,8 @@ public final class InetAddresses {
* <a target="_parent" href="http://tools.ietf.org/html/rfc3056#section-2"
* >http://tools.ietf.org/html/rfc3056</a>
*
- * @param ip {@link Inet6Address} to be examined for 6to4 address format
+ * @param ip {@link Inet6Address} to be examined for 6to4 address
+ * format
* @return {@code true} if the argument is a 6to4 address
*/
public static boolean is6to4Address(Inet6Address ip) {
@@ -595,19 +639,21 @@ public final class InetAddresses {
/**
* Returns the IPv4 address embedded in a 6to4 address.
*
- * @param ip {@link Inet6Address} to be examined for embedded IPv4 in 6to4 address
- * @return {@link Inet4Address} of embedded IPv4 in 6to4 address
- * @throws IllegalArgumentException if the argument is not a valid IPv6 6to4 address
+ * @param ip {@link Inet6Address} to be examined for embedded IPv4
+ * in 6to4 address.
+ * @return {@link Inet4Address} of embedded IPv4 in 6to4 address.
+ * @throws IllegalArgumentException if the argument is not a valid
+ * IPv6 6to4 address.
*/
public static Inet4Address get6to4IPv4Address(Inet6Address ip) {
Preconditions.checkArgument(is6to4Address(ip),
"Address '%s' is not a 6to4 address.", toAddrString(ip));
- return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 2, 6));
+ return getInet4Address(copyOfRange(ip.getAddress(), 2, 6));
}
/**
- * A simple immutable data class to encapsulate the information to be found in a
+ * A simple data class to encapsulate the information to be found in a
* Teredo address.
*
* <p>All of the fields in this class are encoded in various portions
@@ -635,19 +681,31 @@ public final class InetAddresses {
* <p>Both server and client can be {@code null}, in which case the
* value {@code "0.0.0.0"} will be assumed.
*
- * @throws IllegalArgumentException if either of the {@code port} or the {@code flags}
- * arguments are out of range of an unsigned short
+ * @throws IllegalArgumentException if either of the {@code port}
+ * or the {@code flags} arguments are out of range of an
+ * unsigned short
*/
// TODO: why is this public?
- public TeredoInfo(
- @Nullable Inet4Address server, @Nullable Inet4Address client, int port, int flags) {
+ public TeredoInfo(@Nullable Inet4Address server,
+ @Nullable Inet4Address client,
+ int port, int flags) {
Preconditions.checkArgument((port >= 0) && (port <= 0xffff),
"port '%s' is out of range (0 <= port <= 0xffff)", port);
Preconditions.checkArgument((flags >= 0) && (flags <= 0xffff),
"flags '%s' is out of range (0 <= flags <= 0xffff)", flags);
-
- this.server = Objects.firstNonNull(server, ANY4);
- this.client = Objects.firstNonNull(client, ANY4);
+
+ if (server != null) {
+ this.server = server;
+ } else {
+ this.server = ANY4;
+ }
+
+ if (client != null) {
+ this.client = client;
+ } else {
+ this.client = ANY4;
+ }
+
this.port = port;
this.flags = flags;
}
@@ -674,7 +732,8 @@ public final class InetAddresses {
*
* <p>Teredo addresses begin with the {@code "2001::/32"} prefix.
*
- * @param ip {@link Inet6Address} to be examined for Teredo address format
+ * @param ip {@link Inet6Address} to be examined for Teredo address
+ * format.
* @return {@code true} if the argument is a Teredo address
*/
public static boolean isTeredoAddress(Inet6Address ip) {
@@ -686,23 +745,25 @@ public final class InetAddresses {
/**
* Returns the Teredo information embedded in a Teredo address.
*
- * @param ip {@link Inet6Address} to be examined for embedded Teredo information
+ * @param ip {@link Inet6Address} to be examined for embedded Teredo
+ * information
* @return extracted {@code TeredoInfo}
- * @throws IllegalArgumentException if the argument is not a valid IPv6 Teredo address
+ * @throws IllegalArgumentException if the argument is not a valid
+ * IPv6 Teredo address
*/
public static TeredoInfo getTeredoInfo(Inet6Address ip) {
Preconditions.checkArgument(isTeredoAddress(ip),
"Address '%s' is not a Teredo address.", toAddrString(ip));
byte[] bytes = ip.getAddress();
- Inet4Address server = getInet4Address(Arrays.copyOfRange(bytes, 4, 8));
+ Inet4Address server = getInet4Address(copyOfRange(bytes, 4, 8));
int flags = ByteStreams.newDataInput(bytes, 8).readShort() & 0xffff;
// Teredo obfuscates the mapped client port, per section 4 of the RFC.
int port = ~ByteStreams.newDataInput(bytes, 10).readShort() & 0xffff;
- byte[] clientBytes = Arrays.copyOfRange(bytes, 12, 16);
+ byte[] clientBytes = copyOfRange(bytes, 12, 16);
for (int i = 0; i < clientBytes.length; i++) {
// Teredo obfuscates the mapped client IP, per section 4 of the RFC.
clientBytes[i] = (byte) ~clientBytes[i];
@@ -724,7 +785,8 @@ public final class InetAddresses {
* <a target="_parent" href="http://tools.ietf.org/html/rfc5214#section-6.1"
* >http://tools.ietf.org/html/rfc5214</a>
*
- * @param ip {@link Inet6Address} to be examined for ISATAP address format
+ * @param ip {@link Inet6Address} to be examined for ISATAP address
+ * format.
* @return {@code true} if the argument is an ISATAP address
*/
public static boolean isIsatapAddress(Inet6Address ip) {
@@ -751,15 +813,17 @@ public final class InetAddresses {
/**
* Returns the IPv4 address embedded in an ISATAP address.
*
- * @param ip {@link Inet6Address} to be examined for embedded IPv4 in ISATAP address
+ * @param ip {@link Inet6Address} to be examined for embedded IPv4
+ * in ISATAP address
* @return {@link Inet4Address} of embedded IPv4 in an ISATAP address
- * @throws IllegalArgumentException if the argument is not a valid IPv6 ISATAP address
+ * @throws IllegalArgumentException if the argument is not a valid
+ * IPv6 ISATAP address
*/
public static Inet4Address getIsatapIPv4Address(Inet6Address ip) {
Preconditions.checkArgument(isIsatapAddress(ip),
"Address '%s' is not an ISATAP address.", toAddrString(ip));
- return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16));
+ return getInet4Address(copyOfRange(ip.getAddress(), 12, 16));
}
/**
@@ -770,12 +834,14 @@ public final class InetAddresses {
* due to their trivial spoofability. With other transition addresses
* spoofing involves (at least) infection of one's BGP routing table.
*
- * @param ip {@link Inet6Address} to be examined for embedded IPv4 client address
- * @return {@code true} if there is an embedded IPv4 client address
+ * @param ip {@link Inet6Address} to be examined for embedded IPv4
+ * client address.
+ * @return {@code true} if there is an embedded IPv4 client address.
* @since 7.0
*/
public static boolean hasEmbeddedIPv4ClientAddress(Inet6Address ip) {
- return isCompatIPv4Address(ip) || is6to4Address(ip) || isTeredoAddress(ip);
+ return isCompatIPv4Address(ip) || is6to4Address(ip) ||
+ isTeredoAddress(ip);
}
/**
@@ -787,9 +853,11 @@ public final class InetAddresses {
* due to their trivial spoofability. With other transition addresses
* spoofing involves (at least) infection of one's BGP routing table.
*
- * @param ip {@link Inet6Address} to be examined for embedded IPv4 client address
- * @return {@link Inet4Address} of embedded IPv4 client address
- * @throws IllegalArgumentException if the argument does not have a valid embedded IPv4 address
+ * @param ip {@link Inet6Address} to be examined for embedded IPv4
+ * client address.
+ * @return {@link Inet4Address} of embedded IPv4 client address.
+ * @throws IllegalArgumentException if the argument does not have a valid
+ * embedded IPv4 address.
*/
public static Inet4Address getEmbeddedIPv4ClientAddress(Inet6Address ip) {
if (isCompatIPv4Address(ip)) {
@@ -805,7 +873,8 @@ public final class InetAddresses {
}
throw new IllegalArgumentException(
- String.format("'%s' has no embedded IPv4 address.", toAddrString(ip)));
+ String.format("'%s' has no embedded IPv4 address.",
+ toAddrString(ip)));
}
/**
@@ -826,7 +895,8 @@ public final class InetAddresses {
* {@link Inet6Address} methods, but it would be unwise to depend on such
* a poorly-documented feature.)
*
- * @param ipString {@code String} to be examined for embedded IPv4-mapped IPv6 address format
+ * @param ipString {@code String} to be examined for embedded IPv4-mapped
+ * IPv6 address format
* @return {@code true} if the argument is a valid "mapped" address
* @since 10.0
*/
@@ -899,7 +969,7 @@ public final class InetAddresses {
}
// Many strategies for hashing are possible. This might suffice for now.
- int coercedHash = Hashing.murmur3_32().hashLong(addressAsLong).asInt();
+ int coercedHash = hash64To32(addressAsLong);
// Squash into 224/4 Multicast and 240/4 Reserved space (i.e. 224/3).
coercedHash |= 0xe0000000;
@@ -914,6 +984,27 @@ public final class InetAddresses {
}
/**
+ * Returns an {@code int} hash of a 64-bit long.
+ *
+ * This comes from http://www.concentric.net/~ttwang/tech/inthash.htm
+ *
+ * This hash gives no guarantees on the cryptographic suitability nor the
+ * quality of randomness produced, and the mapping may change in the future.
+ *
+ * @param key A 64-bit number to hash
+ * @return {@code int} the input hashed into 32 bits
+ */
+ @VisibleForTesting static int hash64To32(long key) {
+ key = (~key) + (key << 18);
+ key = key ^ (key >>> 31);
+ key = key * 21;
+ key = key ^ (key >>> 11);
+ key = key + (key << 6);
+ key = key ^ (key >>> 22);
+ return (int) key;
+ }
+
+ /**
* Returns an integer representing an IPv4 address regardless of
* whether the supplied argument is an IPv4 address or not.
*
@@ -960,7 +1051,8 @@ public final class InetAddresses {
* @return an InetAddress object created from the raw IP address
* @throws UnknownHostException if IP address is of illegal length
*/
- public static InetAddress fromLittleEndianByteArray(byte[] addr) throws UnknownHostException {
+ public static InetAddress fromLittleEndianByteArray(byte[] addr)
+ throws UnknownHostException {
byte[] reversed = new byte[addr.length];
for (int i = 0; i < addr.length; i++) {
reversed[i] = addr[addr.length - i - 1];
@@ -973,8 +1065,9 @@ public final class InetAddresses {
* This method works for both IPv4 and IPv6 addresses.
*
* @param address the InetAddress to increment
- * @return a new InetAddress that is one more than the passed in address
- * @throws IllegalArgumentException if InetAddress is at the end of its range
+ * @return a new InetAddress that is one more than the passed in address.
+ * @throws IllegalArgumentException if InetAddress is at the end of its
+ * range.
* @since 10.0
*/
public static InetAddress increment(InetAddress address) {
@@ -988,7 +1081,11 @@ public final class InetAddresses {
Preconditions.checkArgument(i >= 0, "Incrementing %s would wrap.", address);
addr[i]++;
- return bytesToInetAddress(addr);
+ try {
+ return InetAddress.getByAddress(addr);
+ } catch (UnknownHostException e) {
+ throw new AssertionError(e);
+ }
}
/**
@@ -996,7 +1093,7 @@ public final class InetAddresses {
* ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff for IPv6.
*
* @return true if the InetAddress is either 255.255.255.255 for IPv4 or
- * ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff for IPv6
+ * ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff for IPv6.
* @since 10.0
*/
public static boolean isMaximum(InetAddress address) {
@@ -1008,4 +1105,19 @@ public final class InetAddresses {
}
return true;
}
+
+ /**
+ * This method emulates the Java 6 method
+ * {@code Arrays.copyOfRange(byte, int, int)}, which is not available in
+ * Java 5, and thus cannot be used in Guava code.
+ */
+ private static byte[] copyOfRange(byte[] original, int from, int to) {
+ Preconditions.checkNotNull(original);
+
+ int end = Math.min(to, original.length);
+ byte[] result = new byte[to - from];
+
+ System.arraycopy(original, from, result, 0, end - from);
+ return result;
+ }
}
diff --git a/guava/src/com/google/common/net/InternetDomainName.java b/guava/src/com/google/common/net/InternetDomainName.java
index 4ca6581..7537271 100644
--- a/guava/src/com/google/common/net/InternetDomainName.java
+++ b/guava/src/com/google/common/net/InternetDomainName.java
@@ -73,7 +73,7 @@ import javax.annotation.Nullable;
* @since 5.0
*/
@Beta
-@GwtCompatible
+@GwtCompatible(emulated = true)
public final class InternetDomainName {
private static final CharMatcher DOTS_MATCHER =
@@ -146,13 +146,11 @@ public final class InternetDomainName {
name = name.substring(0, name.length() - 1);
}
- checkArgument(name.length() <= MAX_LENGTH,
- "Domain name too long: '%s':", name);
+ checkArgument(name.length() <= MAX_LENGTH, "Domain name too long: '%s':", name);
this.name = name;
this.parts = ImmutableList.copyOf(DOT_SPLITTER.split(name));
- checkArgument(parts.size() <= MAX_PARTS,
- "Domain has too many parts: '%s'", name);
+ checkArgument(parts.size() <= MAX_PARTS, "Domain has too many parts: '%s'", name);
checkArgument(validateSyntax(parts), "Not a valid domain name: '%s'", name);
this.publicSuffixIndex = findPublicSuffix();
@@ -194,7 +192,7 @@ public final class InternetDomainName {
*
* @param domain A domain name (not IP address)
* @throws IllegalArgumentException if {@code name} is not syntactically valid
- * according to {@link #isValid}
+ * according to {@link #isValidLenient}
* @since 8.0 (previously named {@code from})
* @deprecated Use {@link #from(String)}
*/
diff --git a/guava/src/com/google/common/net/MediaType.java b/guava/src/com/google/common/net/MediaType.java
deleted file mode 100644
index bef306c..0000000
--- a/guava/src/com/google/common/net/MediaType.java
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.net;
-
-import static com.google.common.base.CharMatcher.ASCII;
-import static com.google.common.base.CharMatcher.JAVA_ISO_CONTROL;
-import static com.google.common.base.Charsets.UTF_8;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Ascii;
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Joiner.MapJoiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultiset;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-
-import java.nio.charset.Charset;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * Represents an <a href="http://en.wikipedia.org/wiki/Internet_media_type">Internet Media Type</a>
- * (also known as a MIME Type or Content Type). This class also supports the concept of media ranges
- * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1">defined by HTTP/1.1</a>.
- * As such, the {@code *} character is treated as a wildcard and is used to represent any acceptable
- * type or subtype value. A media type may not have wildcard type with a declared subtype. The
- * {@code *} character has no special meaning as part of a parameter. All values for type, subtype,
- * parameter attributes or parameter values must be valid according to RFCs
- * <a href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and
- * <a href="http://www.ietf.org/rfc/rfc2046.txt">2046</a>.
- *
- * <p>All portions of the media type that are case-insensitive (type, subtype, parameter attributes)
- * are normalized to lowercase. The value of the {@code charset} parameter is normalized to
- * lowercase, but all others are left as-is.
- *
- * <p>Note that this specifically does <strong>not</strong> represent the value of the MIME
- * {@code Content-Type} header and as such has no support for header-specific considerations such as
- * line folding and comments.
- *
- * <p>For media types that take a charset the predefined constants default to UTF-8 and have a
- * "_UTF_8" suffix. To get a version without a character set, use {@link #withoutParameters}.
- *
- * @since 12.0
- *
- * @author Gregory Kick
- */
-@Beta
-@GwtCompatible
-@Immutable
-public final class MediaType {
- private static final String CHARSET_ATTRIBUTE = "charset";
- private static final ImmutableListMultimap<String, String> UTF_8_CONSTANT_PARAMETERS =
- ImmutableListMultimap.of(CHARSET_ATTRIBUTE, Ascii.toLowerCase(UTF_8.name()));
-
- /** Matcher for type, subtype and attributes. */
- private static final CharMatcher TOKEN_MATCHER = ASCII.and(JAVA_ISO_CONTROL.negate())
- .and(CharMatcher.isNot(' '))
- .and(CharMatcher.noneOf("()<>@,;:\\\"/[]?="));
- private static final CharMatcher QUOTED_TEXT_MATCHER = ASCII
- .and(CharMatcher.noneOf("\"\\\r"));
- /*
- * This matches the same characters as linear-white-space from RFC 822, but we make no effort to
- * enforce any particular rules with regards to line folding as stated in the class docs.
- */
- private static final CharMatcher LINEAR_WHITE_SPACE = CharMatcher.anyOf(" \t\r\n");
-
- // TODO(gak): make these public?
- private static final String APPLICATION_TYPE = "application";
- private static final String AUDIO_TYPE = "audio";
- private static final String IMAGE_TYPE = "image";
- private static final String TEXT_TYPE = "text";
- private static final String VIDEO_TYPE = "video";
-
- private static final String WILDCARD = "*";
-
- /*
- * The following constants are grouped by their type and ordered alphabetically by the constant
- * name within that type. The constant name should be a sensible identifier that is closest to the
- * "common name" of the media. This is often, but not necessarily the same as the subtype.
- *
- * Be sure to declare all constants with the type and subtype in all lowercase.
- *
- * When adding constants, be sure to add an entry into the KNOWN_TYPES map. For types that
- * take a charset (e.g. all text/* types), default to UTF-8 and suffix with "_UTF_8".
- */
-
- public static final MediaType ANY_TYPE = createConstant(WILDCARD, WILDCARD);
- public static final MediaType ANY_TEXT_TYPE = createConstant(TEXT_TYPE, WILDCARD);
- public static final MediaType ANY_IMAGE_TYPE = createConstant(IMAGE_TYPE, WILDCARD);
- public static final MediaType ANY_AUDIO_TYPE = createConstant(AUDIO_TYPE, WILDCARD);
- public static final MediaType ANY_VIDEO_TYPE = createConstant(VIDEO_TYPE, WILDCARD);
- public static final MediaType ANY_APPLICATION_TYPE = createConstant(APPLICATION_TYPE, WILDCARD);
-
- /* text types */
- public static final MediaType CACHE_MANIFEST_UTF_8 =
- createConstantUtf8(TEXT_TYPE, "cache-manifest");
- public static final MediaType CSS_UTF_8 = createConstantUtf8(TEXT_TYPE, "css");
- public static final MediaType CSV_UTF_8 = createConstantUtf8(TEXT_TYPE, "csv");
- public static final MediaType HTML_UTF_8 = createConstantUtf8(TEXT_TYPE, "html");
- public static final MediaType I_CALENDAR_UTF_8 = createConstantUtf8(TEXT_TYPE, "calendar");
- public static final MediaType PLAIN_TEXT_UTF_8 = createConstantUtf8(TEXT_TYPE, "plain");
- /**
- * <a href="http://www.rfc-editor.org/rfc/rfc4329.txt">RFC 4329</a> declares
- * {@link #JAVASCRIPT_UTF_8 application/javascript} to be the correct media type for JavaScript,
- * but this may be necessary in certain situations for compatibility.
- */
- public static final MediaType TEXT_JAVASCRIPT_UTF_8 = createConstantUtf8(TEXT_TYPE, "javascript");
- public static final MediaType VCARD_UTF_8 = createConstantUtf8(TEXT_TYPE, "vcard");
- public static final MediaType WML_UTF_8 = createConstantUtf8(TEXT_TYPE, "vnd.wap.wml");
- /**
- * As described in <a href="http://www.ietf.org/rfc/rfc3023.txt">RFC 3023</a>, this constant
- * ({@code text/xml}) is used for XML documents that are "readable by casual users."
- * {@link #APPLICATION_XML_UTF_8} is provided for documents that are intended for applications.
- */
- public static final MediaType XML_UTF_8 = createConstantUtf8(TEXT_TYPE, "xml");
-
- /* image types */
- public static final MediaType BMP = createConstant(IMAGE_TYPE, "bmp");
- public static final MediaType GIF = createConstant(IMAGE_TYPE, "gif");
- public static final MediaType ICO = createConstant(IMAGE_TYPE, "vnd.microsoft.icon");
- public static final MediaType JPEG = createConstant(IMAGE_TYPE, "jpeg");
- public static final MediaType PNG = createConstant(IMAGE_TYPE, "png");
- public static final MediaType SVG_UTF_8 = createConstantUtf8(IMAGE_TYPE, "svg+xml");
- public static final MediaType TIFF = createConstant(IMAGE_TYPE, "tiff");
- public static final MediaType WEBP = createConstant(IMAGE_TYPE, "webp");
-
- /* audio types */
- public static final MediaType MP4_AUDIO = createConstant(AUDIO_TYPE, "mp4");
- public static final MediaType MPEG_AUDIO = createConstant(AUDIO_TYPE, "mpeg");
- public static final MediaType OGG_AUDIO = createConstant(AUDIO_TYPE, "ogg");
- public static final MediaType WEBM_AUDIO = createConstant(AUDIO_TYPE, "webm");
-
- /* video types */
- public static final MediaType MP4_VIDEO = createConstant(VIDEO_TYPE, "mp4");
- public static final MediaType MPEG_VIDEO = createConstant(VIDEO_TYPE, "mpeg");
- public static final MediaType OGG_VIDEO = createConstant(VIDEO_TYPE, "ogg");
- public static final MediaType QUICKTIME = createConstant(VIDEO_TYPE, "quicktime");
- public static final MediaType WEBM_VIDEO = createConstant(VIDEO_TYPE, "webm");
- public static final MediaType WMV = createConstant(VIDEO_TYPE, "x-ms-wmv");
-
- /* application types */
- /**
- * As described in <a href="http://www.ietf.org/rfc/rfc3023.txt">RFC 3023</a>, this constant
- * ({@code application/xml}) is used for XML documents that are "unreadable by casual users."
- * {@link #XML_UTF_8} is provided for documents that may be read by users.
- */
- public static final MediaType APPLICATION_XML_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "xml");
- public static final MediaType ATOM_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "atom+xml");
- public static final MediaType BZIP2 = createConstant(APPLICATION_TYPE, "x-bzip2");
- public static final MediaType FORM_DATA = createConstant(APPLICATION_TYPE,
- "x-www-form-urlencoded");
- /**
- * This is a non-standard media type, but is commonly used in serving hosted binary files as it is
- * <a href="http://code.google.com/p/browsersec/wiki/Part2#Survey_of_content_sniffing_behaviors">
- * known not to trigger content sniffing in current browsers</a>. It <i>should not</i> be used in
- * other situations as it is not specified by any RFC and does not appear in the <a href=
- * "http://www.iana.org/assignments/media-types">/IANA MIME Media Types</a> list. Consider
- * {@link #OCTET_STREAM} for binary data that is not being served to a browser.
- *
- *
- * @since 14.0
- */
- public static final MediaType APPLICATION_BINARY = createConstant(APPLICATION_TYPE, "binary");
- public static final MediaType GZIP = createConstant(APPLICATION_TYPE, "x-gzip");
- /**
- * <a href="http://www.rfc-editor.org/rfc/rfc4329.txt">RFC 4329</a> declares this to be the
- * correct media type for JavaScript, but {@link #TEXT_JAVASCRIPT_UTF_8 text/javascript} may be
- * necessary in certain situations for compatibility.
- */
- public static final MediaType JAVASCRIPT_UTF_8 =
- createConstantUtf8(APPLICATION_TYPE, "javascript");
- public static final MediaType JSON_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "json");
- public static final MediaType KML = createConstant(APPLICATION_TYPE, "vnd.google-earth.kml+xml");
- public static final MediaType KMZ = createConstant(APPLICATION_TYPE, "vnd.google-earth.kmz");
- public static final MediaType MBOX = createConstant(APPLICATION_TYPE, "mbox");
- public static final MediaType MICROSOFT_EXCEL = createConstant(APPLICATION_TYPE, "vnd.ms-excel");
- public static final MediaType MICROSOFT_POWERPOINT =
- createConstant(APPLICATION_TYPE, "vnd.ms-powerpoint");
- public static final MediaType MICROSOFT_WORD = createConstant(APPLICATION_TYPE, "msword");
- public static final MediaType OCTET_STREAM = createConstant(APPLICATION_TYPE, "octet-stream");
- public static final MediaType OGG_CONTAINER = createConstant(APPLICATION_TYPE, "ogg");
- public static final MediaType OOXML_DOCUMENT = createConstant(APPLICATION_TYPE,
- "vnd.openxmlformats-officedocument.wordprocessingml.document");
- public static final MediaType OOXML_PRESENTATION = createConstant(APPLICATION_TYPE,
- "vnd.openxmlformats-officedocument.presentationml.presentation");
- public static final MediaType OOXML_SHEET =
- createConstant(APPLICATION_TYPE, "vnd.openxmlformats-officedocument.spreadsheetml.sheet");
- public static final MediaType OPENDOCUMENT_GRAPHICS =
- createConstant(APPLICATION_TYPE, "vnd.oasis.opendocument.graphics");
- public static final MediaType OPENDOCUMENT_PRESENTATION =
- createConstant(APPLICATION_TYPE, "vnd.oasis.opendocument.presentation");
- public static final MediaType OPENDOCUMENT_SPREADSHEET =
- createConstant(APPLICATION_TYPE, "vnd.oasis.opendocument.spreadsheet");
- public static final MediaType OPENDOCUMENT_TEXT =
- createConstant(APPLICATION_TYPE, "vnd.oasis.opendocument.text");
- public static final MediaType PDF = createConstant(APPLICATION_TYPE, "pdf");
- public static final MediaType POSTSCRIPT = createConstant(APPLICATION_TYPE, "postscript");
- public static final MediaType RDF_XML_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "rdf+xml");
- public static final MediaType RTF_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "rtf");
- public static final MediaType SHOCKWAVE_FLASH = createConstant(APPLICATION_TYPE,
- "x-shockwave-flash");
- public static final MediaType SKETCHUP = createConstant(APPLICATION_TYPE, "vnd.sketchup.skp");
- public static final MediaType TAR = createConstant(APPLICATION_TYPE, "x-tar");
- public static final MediaType XHTML_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "xhtml+xml");
- /**
- * Media type for Extensible Resource Descriptors. This is not yet registered with the IANA, but
- * it is specified by OASIS in the
- * <a href="http://docs.oasis-open.org/xri/xrd/v1.0/cd02/xrd-1.0-cd02.html"> XRD definition</a>
- * and implemented in projects such as
- * <a href="http://code.google.com/p/webfinger/">WebFinger</a>.
- */
- public static final MediaType XRD_UTF_8 = createConstantUtf8(APPLICATION_TYPE, "xrd+xml");
- public static final MediaType ZIP = createConstant(APPLICATION_TYPE, "zip");
-
- private static final ImmutableMap<MediaType, MediaType> KNOWN_TYPES =
- new ImmutableMap.Builder<MediaType, MediaType>()
- .put(ANY_TYPE, ANY_TYPE)
- .put(ANY_TEXT_TYPE, ANY_TEXT_TYPE)
- .put(ANY_IMAGE_TYPE, ANY_IMAGE_TYPE)
- .put(ANY_AUDIO_TYPE, ANY_AUDIO_TYPE)
- .put(ANY_VIDEO_TYPE, ANY_VIDEO_TYPE)
- .put(ANY_APPLICATION_TYPE, ANY_APPLICATION_TYPE)
- /* text types */
- .put(CACHE_MANIFEST_UTF_8, CACHE_MANIFEST_UTF_8)
- .put(CSS_UTF_8, CSS_UTF_8)
- .put(CSV_UTF_8, CSV_UTF_8)
- .put(HTML_UTF_8, HTML_UTF_8)
- .put(I_CALENDAR_UTF_8, I_CALENDAR_UTF_8)
- .put(PLAIN_TEXT_UTF_8, PLAIN_TEXT_UTF_8)
- .put(TEXT_JAVASCRIPT_UTF_8, TEXT_JAVASCRIPT_UTF_8)
- .put(VCARD_UTF_8, VCARD_UTF_8)
- .put(WML_UTF_8, WML_UTF_8)
- .put(XML_UTF_8, XML_UTF_8)
- /* image types */
- .put(BMP, BMP)
- .put(GIF, GIF)
- .put(ICO, ICO)
- .put(JPEG, JPEG)
- .put(PNG, PNG)
- .put(SVG_UTF_8, SVG_UTF_8)
- .put(TIFF, TIFF)
- .put(WEBP, WEBP)
- /* audio types */
- .put(MP4_AUDIO, MP4_AUDIO)
- .put(MPEG_AUDIO, MPEG_AUDIO)
- .put(OGG_AUDIO, OGG_AUDIO)
- .put(WEBM_AUDIO, WEBM_AUDIO)
- /* video types */
- .put(MP4_VIDEO, MP4_VIDEO)
- .put(MPEG_VIDEO, MPEG_VIDEO)
- .put(OGG_VIDEO, OGG_VIDEO)
- .put(QUICKTIME, QUICKTIME)
- .put(WEBM_VIDEO, WEBM_VIDEO)
- .put(WMV, WMV)
- /* application types */
- .put(APPLICATION_XML_UTF_8, APPLICATION_XML_UTF_8)
- .put(ATOM_UTF_8, ATOM_UTF_8)
- .put(BZIP2, BZIP2)
- .put(FORM_DATA, FORM_DATA)
- .put(APPLICATION_BINARY, APPLICATION_BINARY)
- .put(GZIP, GZIP)
- .put(JAVASCRIPT_UTF_8, JAVASCRIPT_UTF_8)
- .put(JSON_UTF_8, JSON_UTF_8)
- .put(KML, KML)
- .put(KMZ, KMZ)
- .put(MBOX, MBOX)
- .put(MICROSOFT_EXCEL, MICROSOFT_EXCEL)
- .put(MICROSOFT_POWERPOINT, MICROSOFT_POWERPOINT)
- .put(MICROSOFT_WORD, MICROSOFT_WORD)
- .put(OCTET_STREAM, OCTET_STREAM)
- .put(OGG_CONTAINER, OGG_CONTAINER)
- .put(OOXML_DOCUMENT, OOXML_DOCUMENT)
- .put(OOXML_PRESENTATION, OOXML_PRESENTATION)
- .put(OOXML_SHEET, OOXML_SHEET)
- .put(OPENDOCUMENT_GRAPHICS, OPENDOCUMENT_GRAPHICS)
- .put(OPENDOCUMENT_PRESENTATION, OPENDOCUMENT_PRESENTATION)
- .put(OPENDOCUMENT_SPREADSHEET, OPENDOCUMENT_SPREADSHEET)
- .put(OPENDOCUMENT_TEXT, OPENDOCUMENT_TEXT)
- .put(PDF, PDF)
- .put(POSTSCRIPT, POSTSCRIPT)
- .put(RDF_XML_UTF_8, RDF_XML_UTF_8)
- .put(RTF_UTF_8, RTF_UTF_8)
- .put(SHOCKWAVE_FLASH, SHOCKWAVE_FLASH)
- .put(SKETCHUP, SKETCHUP)
- .put(TAR, TAR)
- .put(XHTML_UTF_8, XHTML_UTF_8)
- .put(XRD_UTF_8, XRD_UTF_8)
- .put(ZIP, ZIP)
- .build();
-
- private final String type;
- private final String subtype;
- private final ImmutableListMultimap<String, String> parameters;
-
- private MediaType(String type, String subtype,
- ImmutableListMultimap<String, String> parameters) {
- this.type = type;
- this.subtype = subtype;
- this.parameters = parameters;
- }
-
- private static MediaType createConstant(String type, String subtype) {
- return new MediaType(type, subtype, ImmutableListMultimap.<String, String>of());
- }
-
- private static MediaType createConstantUtf8(String type, String subtype) {
- return new MediaType(type, subtype, UTF_8_CONSTANT_PARAMETERS);
- }
-
- /** Returns the top-level media type. For example, {@code "text"} in {@code "text/plain"}. */
- public String type() {
- return type;
- }
-
- /** Returns the media subtype. For example, {@code "plain"} in {@code "text/plain"}. */
- public String subtype() {
- return subtype;
- }
-
- /** Returns a multimap containing the parameters of this media type. */
- public ImmutableListMultimap<String, String> parameters() {
- return parameters;
- }
-
- private Map<String, ImmutableMultiset<String>> parametersAsMap() {
- return Maps.transformValues(parameters.asMap(),
- new Function<Collection<String>, ImmutableMultiset<String>>() {
- @Override public ImmutableMultiset<String> apply(Collection<String> input) {
- return ImmutableMultiset.copyOf(input);
- }
- });
- }
-
- /**
- * Returns an optional charset for the value of the charset parameter if it is specified.
- *
- * @throws IllegalStateException if multiple charset values have been set for this media type
- * @throws IllegalCharsetNameException if a charset value is present, but illegal
- * @throws UnsupportedCharsetException if a charset value is present, but no support is available
- * in this instance of the Java virtual machine
- */
- public Optional<Charset> charset() {
- ImmutableSet<String> charsetValues = ImmutableSet.copyOf(parameters.get(CHARSET_ATTRIBUTE));
- switch (charsetValues.size()) {
- case 0:
- return Optional.absent();
- case 1:
- return Optional.of(Charset.forName(Iterables.getOnlyElement(charsetValues)));
- default:
- throw new IllegalStateException("Multiple charset values defined: " + charsetValues);
- }
- }
-
- /**
- * Returns a new instance with the same type and subtype as this instance, but without any
- * parameters.
- */
- public MediaType withoutParameters() {
- return parameters.isEmpty() ? this : create(type, subtype);
- }
-
- /**
- * <em>Replaces</em> all parameters with the given parameters.
- *
- * @throws IllegalArgumentException if any parameter or value is invalid
- */
- public MediaType withParameters(Multimap<String, String> parameters) {
- return create(type, subtype, parameters);
- }
-
- /**
- * <em>Replaces</em> all parameters with the given attribute with a single parameter with the
- * given value. If multiple parameters with the same attributes are necessary use
- * {@link #withParameters}. Prefer {@link #withCharset} for setting the {@code charset} parameter
- * when using a {@link Charset} object.
- *
- * @throws IllegalArgumentException if either {@code attribute} or {@code value} is invalid
- */
- public MediaType withParameter(String attribute, String value) {
- checkNotNull(attribute);
- checkNotNull(value);
- String normalizedAttribute = normalizeToken(attribute);
- ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
- for (Entry<String, String> entry : parameters.entries()) {
- String key = entry.getKey();
- if (!normalizedAttribute.equals(key)) {
- builder.put(key, entry.getValue());
- }
- }
- builder.put(normalizedAttribute, normalizeParameterValue(normalizedAttribute, value));
- MediaType mediaType = new MediaType(type, subtype, builder.build());
- // Return one of the constants if the media type is a known type.
- return Objects.firstNonNull(KNOWN_TYPES.get(mediaType), mediaType);
- }
-
- /**
- * Returns a new instance with the same type and subtype as this instance, with the
- * {@code charset} parameter set to the {@link Charset#name name} of the given charset. Only one
- * {@code charset} parameter will be present on the new instance regardless of the number set on
- * this one.
- *
- * <p>If a charset must be specified that is not supported on this JVM (and thus is not
- * representable as a {@link Charset} instance, use {@link #withParameter}.
- */
- public MediaType withCharset(Charset charset) {
- checkNotNull(charset);
- return withParameter(CHARSET_ATTRIBUTE, charset.name());
- }
-
- /** Returns true if either the type or subtype is the wildcard. */
- public boolean hasWildcard() {
- return WILDCARD.equals(type) || WILDCARD.equals(subtype);
- }
-
- /**
- * Returns {@code true} if this instance falls within the range (as defined by
- * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">the HTTP Accept header</a>)
- * given by the argument according to three criteria:
- *
- * <ol>
- * <li>The type of the argument is the wildcard or equal to the type of this instance.
- * <li>The subtype of the argument is the wildcard or equal to the subtype of this instance.
- * <li>All of the parameters present in the argument are present in this instance.
- * </ol>
- *
- * For example: <pre> {@code
- * PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8) // true
- * PLAIN_TEXT_UTF_8.is(HTML_UTF_8) // false
- * PLAIN_TEXT_UTF_8.is(ANY_TYPE) // true
- * PLAIN_TEXT_UTF_8.is(ANY_TEXT_TYPE) // true
- * PLAIN_TEXT_UTF_8.is(ANY_IMAGE_TYPE) // false
- * PLAIN_TEXT_UTF_8.is(ANY_TEXT_TYPE.withCharset(UTF_8)) // true
- * PLAIN_TEXT_UTF_8.withoutParameters().is(ANY_TEXT_TYPE.withCharset(UTF_8)) // false
- * PLAIN_TEXT_UTF_8.is(ANY_TEXT_TYPE.withCharset(UTF_16)) // false}</pre>
- *
- * <p>Note that while it is possible to have the same parameter declared multiple times within a
- * media type this method does not consider the number of occurrences of a parameter. For
- * example, {@code "text/plain; charset=UTF-8"} satisfies
- * {@code "text/plain; charset=UTF-8; charset=UTF-8"}.
- */
- public boolean is(MediaType mediaTypeRange) {
- return (mediaTypeRange.type.equals(WILDCARD) || mediaTypeRange.type.equals(this.type))
- && (mediaTypeRange.subtype.equals(WILDCARD) || mediaTypeRange.subtype.equals(this.subtype))
- && this.parameters.entries().containsAll(mediaTypeRange.parameters.entries());
- }
-
- /**
- * Creates a new media type with the given type and subtype.
- *
- * @throws IllegalArgumentException if type or subtype is invalid or if a wildcard is used for the
- * type, but not the subtype.
- */
- public static MediaType create(String type, String subtype) {
- return create(type, subtype, ImmutableListMultimap.<String, String>of());
- }
-
- /**
- * Creates a media type with the "application" type and the given subtype.
- *
- * @throws IllegalArgumentException if subtype is invalid
- */
- static MediaType createApplicationType(String subtype) {
- return create(APPLICATION_TYPE, subtype);
- }
-
- /**
- * Creates a media type with the "audio" type and the given subtype.
- *
- * @throws IllegalArgumentException if subtype is invalid
- */
- static MediaType createAudioType(String subtype) {
- return create(AUDIO_TYPE, subtype);
- }
-
- /**
- * Creates a media type with the "image" type and the given subtype.
- *
- * @throws IllegalArgumentException if subtype is invalid
- */
- static MediaType createImageType(String subtype) {
- return create(IMAGE_TYPE, subtype);
- }
-
- /**
- * Creates a media type with the "text" type and the given subtype.
- *
- * @throws IllegalArgumentException if subtype is invalid
- */
- static MediaType createTextType(String subtype) {
- return create(TEXT_TYPE, subtype);
- }
-
- /**
- * Creates a media type with the "video" type and the given subtype.
- *
- * @throws IllegalArgumentException if subtype is invalid
- */
- static MediaType createVideoType(String subtype) {
- return create(VIDEO_TYPE, subtype);
- }
-
- private static MediaType create(String type, String subtype,
- Multimap<String, String> parameters) {
- checkNotNull(type);
- checkNotNull(subtype);
- checkNotNull(parameters);
- String normalizedType = normalizeToken(type);
- String normalizedSubtype = normalizeToken(subtype);
- checkArgument(!WILDCARD.equals(normalizedType) || WILDCARD.equals(normalizedSubtype),
- "A wildcard type cannot be used with a non-wildcard subtype");
- ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
- for (Entry<String, String> entry : parameters.entries()) {
- String attribute = normalizeToken(entry.getKey());
- builder.put(attribute, normalizeParameterValue(attribute, entry.getValue()));
- }
- MediaType mediaType = new MediaType(normalizedType, normalizedSubtype, builder.build());
- // Return one of the constants if the media type is a known type.
- return Objects.firstNonNull(KNOWN_TYPES.get(mediaType), mediaType);
- }
-
- private static String normalizeToken(String token) {
- checkArgument(TOKEN_MATCHER.matchesAllOf(token));
- return Ascii.toLowerCase(token);
- }
-
- private static String normalizeParameterValue(String attribute, String value) {
- return CHARSET_ATTRIBUTE.equals(attribute) ? Ascii.toLowerCase(value) : value;
- }
-
- /**
- * Parses a media type from its string representation.
- *
- * @throws IllegalArgumentException if the input is not parsable
- */
- public static MediaType parse(String input) {
- checkNotNull(input);
- Tokenizer tokenizer = new Tokenizer(input);
- try {
- String type = tokenizer.consumeToken(TOKEN_MATCHER);
- tokenizer.consumeCharacter('/');
- String subtype = tokenizer.consumeToken(TOKEN_MATCHER);
- ImmutableListMultimap.Builder<String, String> parameters = ImmutableListMultimap.builder();
- while (tokenizer.hasMore()) {
- tokenizer.consumeCharacter(';');
- tokenizer.consumeTokenIfPresent(LINEAR_WHITE_SPACE);
- String attribute = tokenizer.consumeToken(TOKEN_MATCHER);
- tokenizer.consumeCharacter('=');
- final String value;
- if ('"' == tokenizer.previewChar()) {
- tokenizer.consumeCharacter('"');
- StringBuilder valueBuilder = new StringBuilder();
- while ('"' != tokenizer.previewChar()) {
- if ('\\' == tokenizer.previewChar()) {
- tokenizer.consumeCharacter('\\');
- valueBuilder.append(tokenizer.consumeCharacter(ASCII));
- } else {
- valueBuilder.append(tokenizer.consumeToken(QUOTED_TEXT_MATCHER));
- }
- }
- value = valueBuilder.toString();
- tokenizer.consumeCharacter('"');
- } else {
- value = tokenizer.consumeToken(TOKEN_MATCHER);
- }
- parameters.put(attribute, value);
- }
- return create(type, subtype, parameters.build());
- } catch (IllegalStateException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private static final class Tokenizer {
- final String input;
- int position = 0;
-
- Tokenizer(String input) {
- this.input = input;
- }
-
- String consumeTokenIfPresent(CharMatcher matcher) {
- checkState(hasMore());
- int startPosition = position;
- position = matcher.negate().indexIn(input, startPosition);
- return hasMore() ? input.substring(startPosition, position) : input.substring(startPosition);
- }
-
- String consumeToken(CharMatcher matcher) {
- int startPosition = position;
- String token = consumeTokenIfPresent(matcher);
- checkState(position != startPosition);
- return token;
- }
-
- char consumeCharacter(CharMatcher matcher) {
- checkState(hasMore());
- char c = previewChar();
- checkState(matcher.matches(c));
- position++;
- return c;
- }
-
- char consumeCharacter(char c) {
- checkState(hasMore());
- checkState(previewChar() == c);
- position++;
- return c;
- }
-
- char previewChar() {
- checkState(hasMore());
- return input.charAt(position);
- }
-
- boolean hasMore() {
- return (position >= 0) && (position < input.length());
- }
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj == this) {
- return true;
- } else if (obj instanceof MediaType) {
- MediaType that = (MediaType) obj;
- return this.type.equals(that.type)
- && this.subtype.equals(that.subtype)
- // compare parameters regardless of order
- && this.parametersAsMap().equals(that.parametersAsMap());
- } else {
- return false;
- }
- }
-
- @Override public int hashCode() {
- return Objects.hashCode(type, subtype, parametersAsMap());
- }
-
- private static final MapJoiner PARAMETER_JOINER = Joiner.on("; ").withKeyValueSeparator("=");
-
- /**
- * Returns the string representation of this media type in the format described in <a
- * href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
- */
- @Override public String toString() {
- StringBuilder builder = new StringBuilder().append(type).append('/').append(subtype);
- if (!parameters.isEmpty()) {
- builder.append("; ");
- Multimap<String, String> quotedParameters = Multimaps.transformValues(parameters,
- new Function<String, String>() {
- @Override public String apply(String value) {
- return TOKEN_MATCHER.matchesAllOf(value) ? value : escapeAndQuote(value);
- }
- });
- PARAMETER_JOINER.appendTo(builder, quotedParameters.entries());
- }
- return builder.toString();
- }
-
- private static String escapeAndQuote(String value) {
- StringBuilder escaped = new StringBuilder(value.length() + 16).append('"');
- for (char ch : value.toCharArray()) {
- if (ch == '\r' || ch == '\\' || ch == '"') {
- escaped.append('\\');
- }
- escaped.append(ch);
- }
- return escaped.append('"').toString();
- }
-
-}
diff --git a/guava/src/com/google/common/net/TldPatterns.java b/guava/src/com/google/common/net/TldPatterns.java
index 6bc5bb2..879b34d 100644
--- a/guava/src/com/google/common/net/TldPatterns.java
+++ b/guava/src/com/google/common/net/TldPatterns.java
@@ -1,26 +1,11 @@
// GENERATED FILE - DO NOT EDIT
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
package com.google.common.net;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableSet;
+import java.util.Set;
/**
* A generated static class containing public members which provide domain
@@ -28,13 +13,15 @@ import com.google.common.collect.ImmutableSet;
* effective top-level domain (TLD).
*/
@GwtCompatible
-final class TldPatterns {
- private TldPatterns() {}
+class TldPatterns {
+ private TldPatterns() {
+ // Prevent instantiation.
+ }
/**
* If a hostname is contained in this set, it is a TLD.
*/
- static final ImmutableSet<String> EXACT = ImmutableSet.of(
+ static final Set<String> EXACT = ImmutableSet.of(
"ac",
"com.ac",
"edu.ac",
@@ -194,25 +181,9 @@ final class TldPatterns {
"co.at",
"gv.at",
"or.at",
- "com.au",
- "net.au",
- "org.au",
- "edu.au",
- "gov.au",
- "csiro.au",
- "asn.au",
- "id.au",
- "info.au",
- "conf.au",
- "oz.au",
- "act.au",
- "nsw.au",
- "nt.au",
- "qld.au",
- "sa.au",
- "tas.au",
- "vic.au",
- "wa.au",
+ "biz.at",
+ "info.at",
+ "priv.at",
"act.edu.au",
"nsw.edu.au",
"nt.edu.au",
@@ -228,6 +199,14 @@ final class TldPatterns {
"tas.gov.au",
"vic.gov.au",
"wa.gov.au",
+ "act.au",
+ "nsw.au",
+ "nt.au",
+ "qld.au",
+ "sa.au",
+ "tas.au",
+ "vic.au",
+ "wa.au",
"aw",
"com.aw",
"ax",
@@ -350,13 +329,13 @@ final class TldPatterns {
"bio.br",
"blog.br",
"bmd.br",
+ "can.br",
"cim.br",
"cng.br",
"cnt.br",
"com.br",
"coop.br",
"ecn.br",
- "eco.br",
"edu.br",
"emp.br",
"eng.br",
@@ -377,7 +356,6 @@ final class TldPatterns {
"inf.br",
"jor.br",
"jus.br",
- "leg.br",
"lel.br",
"mat.br",
"med.br",
@@ -477,8 +455,6 @@ final class TldPatterns {
"cl",
"gov.cl",
"gob.cl",
- "co.cl",
- "mil.cl",
"cm",
"gov.cm",
"cn",
@@ -544,6 +520,26 @@ final class TldPatterns {
"rec.co",
"web.co",
"com",
+ "ar.com",
+ "br.com",
+ "cn.com",
+ "de.com",
+ "eu.com",
+ "gb.com",
+ "hu.com",
+ "jpn.com",
+ "kr.com",
+ "no.com",
+ "qc.com",
+ "ru.com",
+ "sa.com",
+ "se.com",
+ "uk.com",
+ "us.com",
+ "uy.com",
+ "za.com",
+ "operaunite.com",
+ "appspot.com",
"coop",
"cr",
"ac.cr",
@@ -637,6 +633,7 @@ final class TldPatterns {
"eu",
"fi",
"aland.fi",
+ "iki.fi",
"fm",
"fo",
"fr",
@@ -1190,1732 +1187,6 @@ final class TldPatterns {
"lg.jp",
"ne.jp",
"or.jp",
- "aichi.jp",
- "akita.jp",
- "aomori.jp",
- "chiba.jp",
- "ehime.jp",
- "fukui.jp",
- "fukuoka.jp",
- "fukushima.jp",
- "gifu.jp",
- "gunma.jp",
- "hiroshima.jp",
- "hokkaido.jp",
- "hyogo.jp",
- "ibaraki.jp",
- "ishikawa.jp",
- "iwate.jp",
- "kagawa.jp",
- "kagoshima.jp",
- "kanagawa.jp",
- "kochi.jp",
- "kumamoto.jp",
- "kyoto.jp",
- "mie.jp",
- "miyagi.jp",
- "miyazaki.jp",
- "nagano.jp",
- "nagasaki.jp",
- "nara.jp",
- "niigata.jp",
- "oita.jp",
- "okayama.jp",
- "okinawa.jp",
- "osaka.jp",
- "saga.jp",
- "saitama.jp",
- "shiga.jp",
- "shimane.jp",
- "shizuoka.jp",
- "tochigi.jp",
- "tokushima.jp",
- "tokyo.jp",
- "tottori.jp",
- "toyama.jp",
- "wakayama.jp",
- "yamagata.jp",
- "yamaguchi.jp",
- "yamanashi.jp",
- "aisai.aichi.jp",
- "ama.aichi.jp",
- "anjo.aichi.jp",
- "asuke.aichi.jp",
- "chiryu.aichi.jp",
- "chita.aichi.jp",
- "fuso.aichi.jp",
- "gamagori.aichi.jp",
- "handa.aichi.jp",
- "hazu.aichi.jp",
- "hekinan.aichi.jp",
- "higashiura.aichi.jp",
- "ichinomiya.aichi.jp",
- "inazawa.aichi.jp",
- "inuyama.aichi.jp",
- "isshiki.aichi.jp",
- "iwakura.aichi.jp",
- "kanie.aichi.jp",
- "kariya.aichi.jp",
- "kasugai.aichi.jp",
- "kira.aichi.jp",
- "kiyosu.aichi.jp",
- "komaki.aichi.jp",
- "konan.aichi.jp",
- "kota.aichi.jp",
- "mihama.aichi.jp",
- "miyoshi.aichi.jp",
- "nagakute.aichi.jp",
- "nishio.aichi.jp",
- "nisshin.aichi.jp",
- "obu.aichi.jp",
- "oguchi.aichi.jp",
- "oharu.aichi.jp",
- "okazaki.aichi.jp",
- "owariasahi.aichi.jp",
- "seto.aichi.jp",
- "shikatsu.aichi.jp",
- "shinshiro.aichi.jp",
- "shitara.aichi.jp",
- "tahara.aichi.jp",
- "takahama.aichi.jp",
- "tobishima.aichi.jp",
- "toei.aichi.jp",
- "togo.aichi.jp",
- "tokai.aichi.jp",
- "tokoname.aichi.jp",
- "toyoake.aichi.jp",
- "toyohashi.aichi.jp",
- "toyokawa.aichi.jp",
- "toyone.aichi.jp",
- "toyota.aichi.jp",
- "tsushima.aichi.jp",
- "yatomi.aichi.jp",
- "akita.akita.jp",
- "daisen.akita.jp",
- "fujisato.akita.jp",
- "gojome.akita.jp",
- "hachirogata.akita.jp",
- "happou.akita.jp",
- "higashinaruse.akita.jp",
- "honjo.akita.jp",
- "honjyo.akita.jp",
- "ikawa.akita.jp",
- "kamikoani.akita.jp",
- "kamioka.akita.jp",
- "katagami.akita.jp",
- "kazuno.akita.jp",
- "kitaakita.akita.jp",
- "kosaka.akita.jp",
- "kyowa.akita.jp",
- "misato.akita.jp",
- "mitane.akita.jp",
- "moriyoshi.akita.jp",
- "nikaho.akita.jp",
- "noshiro.akita.jp",
- "odate.akita.jp",
- "oga.akita.jp",
- "ogata.akita.jp",
- "semboku.akita.jp",
- "yokote.akita.jp",
- "yurihonjo.akita.jp",
- "aomori.aomori.jp",
- "gonohe.aomori.jp",
- "hachinohe.aomori.jp",
- "hashikami.aomori.jp",
- "hiranai.aomori.jp",
- "hirosaki.aomori.jp",
- "itayanagi.aomori.jp",
- "kuroishi.aomori.jp",
- "misawa.aomori.jp",
- "mutsu.aomori.jp",
- "nakadomari.aomori.jp",
- "noheji.aomori.jp",
- "oirase.aomori.jp",
- "owani.aomori.jp",
- "rokunohe.aomori.jp",
- "sannohe.aomori.jp",
- "shichinohe.aomori.jp",
- "shingo.aomori.jp",
- "takko.aomori.jp",
- "towada.aomori.jp",
- "tsugaru.aomori.jp",
- "tsuruta.aomori.jp",
- "abiko.chiba.jp",
- "asahi.chiba.jp",
- "chonan.chiba.jp",
- "chosei.chiba.jp",
- "choshi.chiba.jp",
- "chuo.chiba.jp",
- "funabashi.chiba.jp",
- "futtsu.chiba.jp",
- "hanamigawa.chiba.jp",
- "ichihara.chiba.jp",
- "ichikawa.chiba.jp",
- "ichinomiya.chiba.jp",
- "inzai.chiba.jp",
- "isumi.chiba.jp",
- "kamagaya.chiba.jp",
- "kamogawa.chiba.jp",
- "kashiwa.chiba.jp",
- "katori.chiba.jp",
- "katsuura.chiba.jp",
- "kimitsu.chiba.jp",
- "kisarazu.chiba.jp",
- "kozaki.chiba.jp",
- "kujukuri.chiba.jp",
- "kyonan.chiba.jp",
- "matsudo.chiba.jp",
- "midori.chiba.jp",
- "mihama.chiba.jp",
- "minamiboso.chiba.jp",
- "mobara.chiba.jp",
- "mutsuzawa.chiba.jp",
- "nagara.chiba.jp",
- "nagareyama.chiba.jp",
- "narashino.chiba.jp",
- "narita.chiba.jp",
- "noda.chiba.jp",
- "oamishirasato.chiba.jp",
- "omigawa.chiba.jp",
- "onjuku.chiba.jp",
- "otaki.chiba.jp",
- "sakae.chiba.jp",
- "sakura.chiba.jp",
- "shimofusa.chiba.jp",
- "shirako.chiba.jp",
- "shiroi.chiba.jp",
- "shisui.chiba.jp",
- "sodegaura.chiba.jp",
- "sosa.chiba.jp",
- "tako.chiba.jp",
- "tateyama.chiba.jp",
- "togane.chiba.jp",
- "tohnosho.chiba.jp",
- "tomisato.chiba.jp",
- "urayasu.chiba.jp",
- "yachimata.chiba.jp",
- "yachiyo.chiba.jp",
- "yokaichiba.chiba.jp",
- "yokoshibahikari.chiba.jp",
- "yotsukaido.chiba.jp",
- "ainan.ehime.jp",
- "honai.ehime.jp",
- "ikata.ehime.jp",
- "imabari.ehime.jp",
- "iyo.ehime.jp",
- "kamijima.ehime.jp",
- "kihoku.ehime.jp",
- "kumakogen.ehime.jp",
- "masaki.ehime.jp",
- "matsuno.ehime.jp",
- "matsuyama.ehime.jp",
- "namikata.ehime.jp",
- "niihama.ehime.jp",
- "ozu.ehime.jp",
- "saijo.ehime.jp",
- "seiyo.ehime.jp",
- "shikokuchuo.ehime.jp",
- "tobe.ehime.jp",
- "toon.ehime.jp",
- "uchiko.ehime.jp",
- "uwajima.ehime.jp",
- "yawatahama.ehime.jp",
- "echizen.fukui.jp",
- "eiheiji.fukui.jp",
- "fukui.fukui.jp",
- "ikeda.fukui.jp",
- "katsuyama.fukui.jp",
- "mihama.fukui.jp",
- "minamiechizen.fukui.jp",
- "obama.fukui.jp",
- "ohi.fukui.jp",
- "ono.fukui.jp",
- "sabae.fukui.jp",
- "sakai.fukui.jp",
- "takahama.fukui.jp",
- "tsuruga.fukui.jp",
- "wakasa.fukui.jp",
- "ashiya.fukuoka.jp",
- "buzen.fukuoka.jp",
- "chikugo.fukuoka.jp",
- "chikuho.fukuoka.jp",
- "chikujo.fukuoka.jp",
- "chikushino.fukuoka.jp",
- "chikuzen.fukuoka.jp",
- "chuo.fukuoka.jp",
- "dazaifu.fukuoka.jp",
- "fukuchi.fukuoka.jp",
- "hakata.fukuoka.jp",
- "higashi.fukuoka.jp",
- "hirokawa.fukuoka.jp",
- "hisayama.fukuoka.jp",
- "iizuka.fukuoka.jp",
- "inatsuki.fukuoka.jp",
- "kaho.fukuoka.jp",
- "kasuga.fukuoka.jp",
- "kasuya.fukuoka.jp",
- "kawara.fukuoka.jp",
- "keisen.fukuoka.jp",
- "koga.fukuoka.jp",
- "kurate.fukuoka.jp",
- "kurogi.fukuoka.jp",
- "kurume.fukuoka.jp",
- "minami.fukuoka.jp",
- "miyako.fukuoka.jp",
- "miyama.fukuoka.jp",
- "miyawaka.fukuoka.jp",
- "mizumaki.fukuoka.jp",
- "munakata.fukuoka.jp",
- "nakagawa.fukuoka.jp",
- "nakama.fukuoka.jp",
- "nishi.fukuoka.jp",
- "nogata.fukuoka.jp",
- "ogori.fukuoka.jp",
- "okagaki.fukuoka.jp",
- "okawa.fukuoka.jp",
- "oki.fukuoka.jp",
- "omuta.fukuoka.jp",
- "onga.fukuoka.jp",
- "onojo.fukuoka.jp",
- "oto.fukuoka.jp",
- "saigawa.fukuoka.jp",
- "sasaguri.fukuoka.jp",
- "shingu.fukuoka.jp",
- "shinyoshitomi.fukuoka.jp",
- "shonai.fukuoka.jp",
- "soeda.fukuoka.jp",
- "sue.fukuoka.jp",
- "tachiarai.fukuoka.jp",
- "tagawa.fukuoka.jp",
- "takata.fukuoka.jp",
- "toho.fukuoka.jp",
- "toyotsu.fukuoka.jp",
- "tsuiki.fukuoka.jp",
- "ukiha.fukuoka.jp",
- "umi.fukuoka.jp",
- "usui.fukuoka.jp",
- "yamada.fukuoka.jp",
- "yame.fukuoka.jp",
- "yanagawa.fukuoka.jp",
- "yukuhashi.fukuoka.jp",
- "aizubange.fukushima.jp",
- "aizumisato.fukushima.jp",
- "aizuwakamatsu.fukushima.jp",
- "asakawa.fukushima.jp",
- "bandai.fukushima.jp",
- "date.fukushima.jp",
- "fukushima.fukushima.jp",
- "furudono.fukushima.jp",
- "futaba.fukushima.jp",
- "hanawa.fukushima.jp",
- "higashi.fukushima.jp",
- "hirata.fukushima.jp",
- "hirono.fukushima.jp",
- "iitate.fukushima.jp",
- "inawashiro.fukushima.jp",
- "ishikawa.fukushima.jp",
- "iwaki.fukushima.jp",
- "izumizaki.fukushima.jp",
- "kagamiishi.fukushima.jp",
- "kaneyama.fukushima.jp",
- "kawamata.fukushima.jp",
- "kitakata.fukushima.jp",
- "kitashiobara.fukushima.jp",
- "koori.fukushima.jp",
- "koriyama.fukushima.jp",
- "kunimi.fukushima.jp",
- "miharu.fukushima.jp",
- "mishima.fukushima.jp",
- "namie.fukushima.jp",
- "nango.fukushima.jp",
- "nishiaizu.fukushima.jp",
- "nishigo.fukushima.jp",
- "okuma.fukushima.jp",
- "omotego.fukushima.jp",
- "ono.fukushima.jp",
- "otama.fukushima.jp",
- "samegawa.fukushima.jp",
- "shimogo.fukushima.jp",
- "shirakawa.fukushima.jp",
- "showa.fukushima.jp",
- "soma.fukushima.jp",
- "sukagawa.fukushima.jp",
- "taishin.fukushima.jp",
- "tamakawa.fukushima.jp",
- "tanagura.fukushima.jp",
- "tenei.fukushima.jp",
- "yabuki.fukushima.jp",
- "yamato.fukushima.jp",
- "yamatsuri.fukushima.jp",
- "yanaizu.fukushima.jp",
- "yugawa.fukushima.jp",
- "anpachi.gifu.jp",
- "ena.gifu.jp",
- "gifu.gifu.jp",
- "ginan.gifu.jp",
- "godo.gifu.jp",
- "gujo.gifu.jp",
- "hashima.gifu.jp",
- "hichiso.gifu.jp",
- "hida.gifu.jp",
- "higashishirakawa.gifu.jp",
- "ibigawa.gifu.jp",
- "ikeda.gifu.jp",
- "kakamigahara.gifu.jp",
- "kani.gifu.jp",
- "kasahara.gifu.jp",
- "kasamatsu.gifu.jp",
- "kawaue.gifu.jp",
- "kitagata.gifu.jp",
- "mino.gifu.jp",
- "minokamo.gifu.jp",
- "mitake.gifu.jp",
- "mizunami.gifu.jp",
- "motosu.gifu.jp",
- "nakatsugawa.gifu.jp",
- "ogaki.gifu.jp",
- "sakahogi.gifu.jp",
- "seki.gifu.jp",
- "sekigahara.gifu.jp",
- "shirakawa.gifu.jp",
- "tajimi.gifu.jp",
- "takayama.gifu.jp",
- "tarui.gifu.jp",
- "toki.gifu.jp",
- "tomika.gifu.jp",
- "wanouchi.gifu.jp",
- "yamagata.gifu.jp",
- "yaotsu.gifu.jp",
- "yoro.gifu.jp",
- "annaka.gunma.jp",
- "chiyoda.gunma.jp",
- "fujioka.gunma.jp",
- "higashiagatsuma.gunma.jp",
- "isesaki.gunma.jp",
- "itakura.gunma.jp",
- "kanna.gunma.jp",
- "kanra.gunma.jp",
- "katashina.gunma.jp",
- "kawaba.gunma.jp",
- "kiryu.gunma.jp",
- "kusatsu.gunma.jp",
- "maebashi.gunma.jp",
- "meiwa.gunma.jp",
- "midori.gunma.jp",
- "minakami.gunma.jp",
- "naganohara.gunma.jp",
- "nakanojo.gunma.jp",
- "nanmoku.gunma.jp",
- "numata.gunma.jp",
- "oizumi.gunma.jp",
- "ora.gunma.jp",
- "ota.gunma.jp",
- "shibukawa.gunma.jp",
- "shimonita.gunma.jp",
- "shinto.gunma.jp",
- "showa.gunma.jp",
- "takasaki.gunma.jp",
- "takayama.gunma.jp",
- "tamamura.gunma.jp",
- "tatebayashi.gunma.jp",
- "tomioka.gunma.jp",
- "tsukiyono.gunma.jp",
- "tsumagoi.gunma.jp",
- "ueno.gunma.jp",
- "yoshioka.gunma.jp",
- "asaminami.hiroshima.jp",
- "daiwa.hiroshima.jp",
- "etajima.hiroshima.jp",
- "fuchu.hiroshima.jp",
- "fukuyama.hiroshima.jp",
- "hatsukaichi.hiroshima.jp",
- "higashihiroshima.hiroshima.jp",
- "hongo.hiroshima.jp",
- "jinsekikogen.hiroshima.jp",
- "kaita.hiroshima.jp",
- "kui.hiroshima.jp",
- "kumano.hiroshima.jp",
- "kure.hiroshima.jp",
- "mihara.hiroshima.jp",
- "miyoshi.hiroshima.jp",
- "naka.hiroshima.jp",
- "onomichi.hiroshima.jp",
- "osakikamijima.hiroshima.jp",
- "otake.hiroshima.jp",
- "saka.hiroshima.jp",
- "sera.hiroshima.jp",
- "seranishi.hiroshima.jp",
- "shinichi.hiroshima.jp",
- "shobara.hiroshima.jp",
- "takehara.hiroshima.jp",
- "abashiri.hokkaido.jp",
- "abira.hokkaido.jp",
- "aibetsu.hokkaido.jp",
- "akabira.hokkaido.jp",
- "akkeshi.hokkaido.jp",
- "asahikawa.hokkaido.jp",
- "ashibetsu.hokkaido.jp",
- "ashoro.hokkaido.jp",
- "assabu.hokkaido.jp",
- "atsuma.hokkaido.jp",
- "bibai.hokkaido.jp",
- "biei.hokkaido.jp",
- "bifuka.hokkaido.jp",
- "bihoro.hokkaido.jp",
- "biratori.hokkaido.jp",
- "chippubetsu.hokkaido.jp",
- "chitose.hokkaido.jp",
- "date.hokkaido.jp",
- "ebetsu.hokkaido.jp",
- "embetsu.hokkaido.jp",
- "eniwa.hokkaido.jp",
- "erimo.hokkaido.jp",
- "esan.hokkaido.jp",
- "esashi.hokkaido.jp",
- "fukagawa.hokkaido.jp",
- "fukushima.hokkaido.jp",
- "furano.hokkaido.jp",
- "furubira.hokkaido.jp",
- "haboro.hokkaido.jp",
- "hakodate.hokkaido.jp",
- "hamatonbetsu.hokkaido.jp",
- "hidaka.hokkaido.jp",
- "higashikagura.hokkaido.jp",
- "higashikawa.hokkaido.jp",
- "hiroo.hokkaido.jp",
- "hokuryu.hokkaido.jp",
- "hokuto.hokkaido.jp",
- "honbetsu.hokkaido.jp",
- "horokanai.hokkaido.jp",
- "horonobe.hokkaido.jp",
- "ikeda.hokkaido.jp",
- "imakane.hokkaido.jp",
- "ishikari.hokkaido.jp",
- "iwamizawa.hokkaido.jp",
- "iwanai.hokkaido.jp",
- "kamifurano.hokkaido.jp",
- "kamikawa.hokkaido.jp",
- "kamishihoro.hokkaido.jp",
- "kamisunagawa.hokkaido.jp",
- "kamoenai.hokkaido.jp",
- "kayabe.hokkaido.jp",
- "kembuchi.hokkaido.jp",
- "kikonai.hokkaido.jp",
- "kimobetsu.hokkaido.jp",
- "kitahiroshima.hokkaido.jp",
- "kitami.hokkaido.jp",
- "kiyosato.hokkaido.jp",
- "koshimizu.hokkaido.jp",
- "kunneppu.hokkaido.jp",
- "kuriyama.hokkaido.jp",
- "kuromatsunai.hokkaido.jp",
- "kushiro.hokkaido.jp",
- "kutchan.hokkaido.jp",
- "kyowa.hokkaido.jp",
- "mashike.hokkaido.jp",
- "matsumae.hokkaido.jp",
- "mikasa.hokkaido.jp",
- "minamifurano.hokkaido.jp",
- "mombetsu.hokkaido.jp",
- "moseushi.hokkaido.jp",
- "mukawa.hokkaido.jp",
- "muroran.hokkaido.jp",
- "naie.hokkaido.jp",
- "nakagawa.hokkaido.jp",
- "nakasatsunai.hokkaido.jp",
- "nakatombetsu.hokkaido.jp",
- "nanae.hokkaido.jp",
- "nanporo.hokkaido.jp",
- "nayoro.hokkaido.jp",
- "nemuro.hokkaido.jp",
- "niikappu.hokkaido.jp",
- "niki.hokkaido.jp",
- "nishiokoppe.hokkaido.jp",
- "noboribetsu.hokkaido.jp",
- "numata.hokkaido.jp",
- "obihiro.hokkaido.jp",
- "obira.hokkaido.jp",
- "oketo.hokkaido.jp",
- "okoppe.hokkaido.jp",
- "otaru.hokkaido.jp",
- "otobe.hokkaido.jp",
- "otofuke.hokkaido.jp",
- "otoineppu.hokkaido.jp",
- "oumu.hokkaido.jp",
- "ozora.hokkaido.jp",
- "pippu.hokkaido.jp",
- "rankoshi.hokkaido.jp",
- "rebun.hokkaido.jp",
- "rikubetsu.hokkaido.jp",
- "rishiri.hokkaido.jp",
- "rishirifuji.hokkaido.jp",
- "saroma.hokkaido.jp",
- "sarufutsu.hokkaido.jp",
- "shakotan.hokkaido.jp",
- "shari.hokkaido.jp",
- "shibecha.hokkaido.jp",
- "shibetsu.hokkaido.jp",
- "shikabe.hokkaido.jp",
- "shikaoi.hokkaido.jp",
- "shimamaki.hokkaido.jp",
- "shimizu.hokkaido.jp",
- "shimokawa.hokkaido.jp",
- "shinshinotsu.hokkaido.jp",
- "shintoku.hokkaido.jp",
- "shiranuka.hokkaido.jp",
- "shiraoi.hokkaido.jp",
- "shiriuchi.hokkaido.jp",
- "sobetsu.hokkaido.jp",
- "sunagawa.hokkaido.jp",
- "taiki.hokkaido.jp",
- "takasu.hokkaido.jp",
- "takikawa.hokkaido.jp",
- "takinoue.hokkaido.jp",
- "teshikaga.hokkaido.jp",
- "tobetsu.hokkaido.jp",
- "tohma.hokkaido.jp",
- "tomakomai.hokkaido.jp",
- "tomari.hokkaido.jp",
- "toya.hokkaido.jp",
- "toyako.hokkaido.jp",
- "toyotomi.hokkaido.jp",
- "toyoura.hokkaido.jp",
- "tsubetsu.hokkaido.jp",
- "tsukigata.hokkaido.jp",
- "urakawa.hokkaido.jp",
- "urausu.hokkaido.jp",
- "uryu.hokkaido.jp",
- "utashinai.hokkaido.jp",
- "wakkanai.hokkaido.jp",
- "wassamu.hokkaido.jp",
- "yakumo.hokkaido.jp",
- "yoichi.hokkaido.jp",
- "aioi.hyogo.jp",
- "akashi.hyogo.jp",
- "ako.hyogo.jp",
- "amagasaki.hyogo.jp",
- "aogaki.hyogo.jp",
- "asago.hyogo.jp",
- "ashiya.hyogo.jp",
- "awaji.hyogo.jp",
- "fukusaki.hyogo.jp",
- "goshiki.hyogo.jp",
- "harima.hyogo.jp",
- "himeji.hyogo.jp",
- "ichikawa.hyogo.jp",
- "inagawa.hyogo.jp",
- "itami.hyogo.jp",
- "kakogawa.hyogo.jp",
- "kamigori.hyogo.jp",
- "kamikawa.hyogo.jp",
- "kasai.hyogo.jp",
- "kasuga.hyogo.jp",
- "kawanishi.hyogo.jp",
- "miki.hyogo.jp",
- "minamiawaji.hyogo.jp",
- "nishinomiya.hyogo.jp",
- "nishiwaki.hyogo.jp",
- "ono.hyogo.jp",
- "sanda.hyogo.jp",
- "sannan.hyogo.jp",
- "sasayama.hyogo.jp",
- "sayo.hyogo.jp",
- "shingu.hyogo.jp",
- "shinonsen.hyogo.jp",
- "shiso.hyogo.jp",
- "sumoto.hyogo.jp",
- "taishi.hyogo.jp",
- "taka.hyogo.jp",
- "takarazuka.hyogo.jp",
- "takasago.hyogo.jp",
- "takino.hyogo.jp",
- "tamba.hyogo.jp",
- "tatsuno.hyogo.jp",
- "toyooka.hyogo.jp",
- "yabu.hyogo.jp",
- "yashiro.hyogo.jp",
- "yoka.hyogo.jp",
- "yokawa.hyogo.jp",
- "ami.ibaraki.jp",
- "asahi.ibaraki.jp",
- "bando.ibaraki.jp",
- "chikusei.ibaraki.jp",
- "daigo.ibaraki.jp",
- "fujishiro.ibaraki.jp",
- "hitachi.ibaraki.jp",
- "hitachinaka.ibaraki.jp",
- "hitachiomiya.ibaraki.jp",
- "hitachiota.ibaraki.jp",
- "ibaraki.ibaraki.jp",
- "ina.ibaraki.jp",
- "inashiki.ibaraki.jp",
- "itako.ibaraki.jp",
- "iwama.ibaraki.jp",
- "joso.ibaraki.jp",
- "kamisu.ibaraki.jp",
- "kasama.ibaraki.jp",
- "kashima.ibaraki.jp",
- "kasumigaura.ibaraki.jp",
- "koga.ibaraki.jp",
- "miho.ibaraki.jp",
- "mito.ibaraki.jp",
- "moriya.ibaraki.jp",
- "naka.ibaraki.jp",
- "namegata.ibaraki.jp",
- "oarai.ibaraki.jp",
- "ogawa.ibaraki.jp",
- "omitama.ibaraki.jp",
- "ryugasaki.ibaraki.jp",
- "sakai.ibaraki.jp",
- "sakuragawa.ibaraki.jp",
- "shimodate.ibaraki.jp",
- "shimotsuma.ibaraki.jp",
- "shirosato.ibaraki.jp",
- "sowa.ibaraki.jp",
- "suifu.ibaraki.jp",
- "takahagi.ibaraki.jp",
- "tamatsukuri.ibaraki.jp",
- "tokai.ibaraki.jp",
- "tomobe.ibaraki.jp",
- "tone.ibaraki.jp",
- "toride.ibaraki.jp",
- "tsuchiura.ibaraki.jp",
- "tsukuba.ibaraki.jp",
- "uchihara.ibaraki.jp",
- "ushiku.ibaraki.jp",
- "yachiyo.ibaraki.jp",
- "yamagata.ibaraki.jp",
- "yawara.ibaraki.jp",
- "yuki.ibaraki.jp",
- "anamizu.ishikawa.jp",
- "hakui.ishikawa.jp",
- "hakusan.ishikawa.jp",
- "kaga.ishikawa.jp",
- "kahoku.ishikawa.jp",
- "kanazawa.ishikawa.jp",
- "kawakita.ishikawa.jp",
- "komatsu.ishikawa.jp",
- "nakanoto.ishikawa.jp",
- "nanao.ishikawa.jp",
- "nomi.ishikawa.jp",
- "nonoichi.ishikawa.jp",
- "noto.ishikawa.jp",
- "shika.ishikawa.jp",
- "suzu.ishikawa.jp",
- "tsubata.ishikawa.jp",
- "tsurugi.ishikawa.jp",
- "uchinada.ishikawa.jp",
- "wajima.ishikawa.jp",
- "fudai.iwate.jp",
- "fujisawa.iwate.jp",
- "hanamaki.iwate.jp",
- "hiraizumi.iwate.jp",
- "hirono.iwate.jp",
- "ichinohe.iwate.jp",
- "ichinoseki.iwate.jp",
- "iwaizumi.iwate.jp",
- "iwate.iwate.jp",
- "joboji.iwate.jp",
- "kamaishi.iwate.jp",
- "kanegasaki.iwate.jp",
- "karumai.iwate.jp",
- "kawai.iwate.jp",
- "kitakami.iwate.jp",
- "kuji.iwate.jp",
- "kunohe.iwate.jp",
- "kuzumaki.iwate.jp",
- "miyako.iwate.jp",
- "mizusawa.iwate.jp",
- "morioka.iwate.jp",
- "ninohe.iwate.jp",
- "noda.iwate.jp",
- "ofunato.iwate.jp",
- "oshu.iwate.jp",
- "otsuchi.iwate.jp",
- "rikuzentakata.iwate.jp",
- "shiwa.iwate.jp",
- "shizukuishi.iwate.jp",
- "sumita.iwate.jp",
- "takizawa.iwate.jp",
- "tanohata.iwate.jp",
- "tono.iwate.jp",
- "yahaba.iwate.jp",
- "yamada.iwate.jp",
- "ayagawa.kagawa.jp",
- "higashikagawa.kagawa.jp",
- "kanonji.kagawa.jp",
- "kotohira.kagawa.jp",
- "manno.kagawa.jp",
- "marugame.kagawa.jp",
- "mitoyo.kagawa.jp",
- "naoshima.kagawa.jp",
- "sanuki.kagawa.jp",
- "tadotsu.kagawa.jp",
- "takamatsu.kagawa.jp",
- "tonosho.kagawa.jp",
- "uchinomi.kagawa.jp",
- "utazu.kagawa.jp",
- "zentsuji.kagawa.jp",
- "akune.kagoshima.jp",
- "amami.kagoshima.jp",
- "hioki.kagoshima.jp",
- "isa.kagoshima.jp",
- "isen.kagoshima.jp",
- "izumi.kagoshima.jp",
- "kagoshima.kagoshima.jp",
- "kanoya.kagoshima.jp",
- "kawanabe.kagoshima.jp",
- "kinko.kagoshima.jp",
- "kouyama.kagoshima.jp",
- "makurazaki.kagoshima.jp",
- "matsumoto.kagoshima.jp",
- "minamitane.kagoshima.jp",
- "nakatane.kagoshima.jp",
- "nishinoomote.kagoshima.jp",
- "satsumasendai.kagoshima.jp",
- "soo.kagoshima.jp",
- "tarumizu.kagoshima.jp",
- "yusui.kagoshima.jp",
- "aikawa.kanagawa.jp",
- "atsugi.kanagawa.jp",
- "ayase.kanagawa.jp",
- "chigasaki.kanagawa.jp",
- "ebina.kanagawa.jp",
- "fujisawa.kanagawa.jp",
- "hadano.kanagawa.jp",
- "hakone.kanagawa.jp",
- "hiratsuka.kanagawa.jp",
- "isehara.kanagawa.jp",
- "kaisei.kanagawa.jp",
- "kamakura.kanagawa.jp",
- "kiyokawa.kanagawa.jp",
- "matsuda.kanagawa.jp",
- "minamiashigara.kanagawa.jp",
- "miura.kanagawa.jp",
- "nakai.kanagawa.jp",
- "ninomiya.kanagawa.jp",
- "odawara.kanagawa.jp",
- "oi.kanagawa.jp",
- "oiso.kanagawa.jp",
- "sagamihara.kanagawa.jp",
- "samukawa.kanagawa.jp",
- "tsukui.kanagawa.jp",
- "yamakita.kanagawa.jp",
- "yamato.kanagawa.jp",
- "yokosuka.kanagawa.jp",
- "yugawara.kanagawa.jp",
- "zama.kanagawa.jp",
- "zushi.kanagawa.jp",
- "aki.kochi.jp",
- "geisei.kochi.jp",
- "hidaka.kochi.jp",
- "higashitsuno.kochi.jp",
- "ino.kochi.jp",
- "kagami.kochi.jp",
- "kami.kochi.jp",
- "kitagawa.kochi.jp",
- "kochi.kochi.jp",
- "mihara.kochi.jp",
- "motoyama.kochi.jp",
- "muroto.kochi.jp",
- "nahari.kochi.jp",
- "nakamura.kochi.jp",
- "nankoku.kochi.jp",
- "nishitosa.kochi.jp",
- "niyodogawa.kochi.jp",
- "ochi.kochi.jp",
- "okawa.kochi.jp",
- "otoyo.kochi.jp",
- "otsuki.kochi.jp",
- "sakawa.kochi.jp",
- "sukumo.kochi.jp",
- "susaki.kochi.jp",
- "tosa.kochi.jp",
- "tosashimizu.kochi.jp",
- "toyo.kochi.jp",
- "tsuno.kochi.jp",
- "umaji.kochi.jp",
- "yasuda.kochi.jp",
- "yusuhara.kochi.jp",
- "amakusa.kumamoto.jp",
- "arao.kumamoto.jp",
- "aso.kumamoto.jp",
- "choyo.kumamoto.jp",
- "gyokuto.kumamoto.jp",
- "hitoyoshi.kumamoto.jp",
- "kamiamakusa.kumamoto.jp",
- "kashima.kumamoto.jp",
- "kikuchi.kumamoto.jp",
- "kosa.kumamoto.jp",
- "kumamoto.kumamoto.jp",
- "mashiki.kumamoto.jp",
- "mifune.kumamoto.jp",
- "minamata.kumamoto.jp",
- "minamioguni.kumamoto.jp",
- "nagasu.kumamoto.jp",
- "nishihara.kumamoto.jp",
- "oguni.kumamoto.jp",
- "ozu.kumamoto.jp",
- "sumoto.kumamoto.jp",
- "takamori.kumamoto.jp",
- "uki.kumamoto.jp",
- "uto.kumamoto.jp",
- "yamaga.kumamoto.jp",
- "yamato.kumamoto.jp",
- "yatsushiro.kumamoto.jp",
- "ayabe.kyoto.jp",
- "fukuchiyama.kyoto.jp",
- "higashiyama.kyoto.jp",
- "ide.kyoto.jp",
- "ine.kyoto.jp",
- "joyo.kyoto.jp",
- "kameoka.kyoto.jp",
- "kamo.kyoto.jp",
- "kita.kyoto.jp",
- "kizu.kyoto.jp",
- "kumiyama.kyoto.jp",
- "kyotamba.kyoto.jp",
- "kyotanabe.kyoto.jp",
- "kyotango.kyoto.jp",
- "maizuru.kyoto.jp",
- "minami.kyoto.jp",
- "minamiyamashiro.kyoto.jp",
- "miyazu.kyoto.jp",
- "muko.kyoto.jp",
- "nagaokakyo.kyoto.jp",
- "nakagyo.kyoto.jp",
- "nantan.kyoto.jp",
- "oyamazaki.kyoto.jp",
- "sakyo.kyoto.jp",
- "seika.kyoto.jp",
- "tanabe.kyoto.jp",
- "uji.kyoto.jp",
- "ujitawara.kyoto.jp",
- "wazuka.kyoto.jp",
- "yamashina.kyoto.jp",
- "yawata.kyoto.jp",
- "asahi.mie.jp",
- "inabe.mie.jp",
- "ise.mie.jp",
- "kameyama.mie.jp",
- "kawagoe.mie.jp",
- "kiho.mie.jp",
- "kisosaki.mie.jp",
- "kiwa.mie.jp",
- "komono.mie.jp",
- "kumano.mie.jp",
- "kuwana.mie.jp",
- "matsusaka.mie.jp",
- "meiwa.mie.jp",
- "mihama.mie.jp",
- "minamiise.mie.jp",
- "misugi.mie.jp",
- "miyama.mie.jp",
- "nabari.mie.jp",
- "shima.mie.jp",
- "suzuka.mie.jp",
- "tado.mie.jp",
- "taiki.mie.jp",
- "taki.mie.jp",
- "tamaki.mie.jp",
- "toba.mie.jp",
- "tsu.mie.jp",
- "udono.mie.jp",
- "ureshino.mie.jp",
- "watarai.mie.jp",
- "yokkaichi.mie.jp",
- "furukawa.miyagi.jp",
- "higashimatsushima.miyagi.jp",
- "ishinomaki.miyagi.jp",
- "iwanuma.miyagi.jp",
- "kakuda.miyagi.jp",
- "kami.miyagi.jp",
- "kawasaki.miyagi.jp",
- "kesennuma.miyagi.jp",
- "marumori.miyagi.jp",
- "matsushima.miyagi.jp",
- "minamisanriku.miyagi.jp",
- "misato.miyagi.jp",
- "murata.miyagi.jp",
- "natori.miyagi.jp",
- "ogawara.miyagi.jp",
- "ohira.miyagi.jp",
- "onagawa.miyagi.jp",
- "osaki.miyagi.jp",
- "rifu.miyagi.jp",
- "semine.miyagi.jp",
- "shibata.miyagi.jp",
- "shichikashuku.miyagi.jp",
- "shikama.miyagi.jp",
- "shiogama.miyagi.jp",
- "shiroishi.miyagi.jp",
- "tagajo.miyagi.jp",
- "taiwa.miyagi.jp",
- "tome.miyagi.jp",
- "tomiya.miyagi.jp",
- "wakuya.miyagi.jp",
- "watari.miyagi.jp",
- "yamamoto.miyagi.jp",
- "zao.miyagi.jp",
- "aya.miyazaki.jp",
- "ebino.miyazaki.jp",
- "gokase.miyazaki.jp",
- "hyuga.miyazaki.jp",
- "kadogawa.miyazaki.jp",
- "kawaminami.miyazaki.jp",
- "kijo.miyazaki.jp",
- "kitagawa.miyazaki.jp",
- "kitakata.miyazaki.jp",
- "kitaura.miyazaki.jp",
- "kobayashi.miyazaki.jp",
- "kunitomi.miyazaki.jp",
- "kushima.miyazaki.jp",
- "mimata.miyazaki.jp",
- "miyakonojo.miyazaki.jp",
- "miyazaki.miyazaki.jp",
- "morotsuka.miyazaki.jp",
- "nichinan.miyazaki.jp",
- "nishimera.miyazaki.jp",
- "nobeoka.miyazaki.jp",
- "saito.miyazaki.jp",
- "shiiba.miyazaki.jp",
- "shintomi.miyazaki.jp",
- "takaharu.miyazaki.jp",
- "takanabe.miyazaki.jp",
- "takazaki.miyazaki.jp",
- "tsuno.miyazaki.jp",
- "achi.nagano.jp",
- "agematsu.nagano.jp",
- "anan.nagano.jp",
- "aoki.nagano.jp",
- "asahi.nagano.jp",
- "azumino.nagano.jp",
- "chikuhoku.nagano.jp",
- "chikuma.nagano.jp",
- "chino.nagano.jp",
- "fujimi.nagano.jp",
- "hakuba.nagano.jp",
- "hara.nagano.jp",
- "hiraya.nagano.jp",
- "iida.nagano.jp",
- "iijima.nagano.jp",
- "iiyama.nagano.jp",
- "iizuna.nagano.jp",
- "ikeda.nagano.jp",
- "ikusaka.nagano.jp",
- "ina.nagano.jp",
- "karuizawa.nagano.jp",
- "kawakami.nagano.jp",
- "kiso.nagano.jp",
- "kisofukushima.nagano.jp",
- "kitaaiki.nagano.jp",
- "komagane.nagano.jp",
- "komoro.nagano.jp",
- "matsukawa.nagano.jp",
- "matsumoto.nagano.jp",
- "miasa.nagano.jp",
- "minamiaiki.nagano.jp",
- "minamimaki.nagano.jp",
- "minamiminowa.nagano.jp",
- "minowa.nagano.jp",
- "miyada.nagano.jp",
- "miyota.nagano.jp",
- "mochizuki.nagano.jp",
- "nagano.nagano.jp",
- "nagawa.nagano.jp",
- "nagiso.nagano.jp",
- "nakagawa.nagano.jp",
- "nakano.nagano.jp",
- "nozawaonsen.nagano.jp",
- "obuse.nagano.jp",
- "ogawa.nagano.jp",
- "okaya.nagano.jp",
- "omachi.nagano.jp",
- "omi.nagano.jp",
- "ookuwa.nagano.jp",
- "ooshika.nagano.jp",
- "otaki.nagano.jp",
- "otari.nagano.jp",
- "sakae.nagano.jp",
- "sakaki.nagano.jp",
- "saku.nagano.jp",
- "sakuho.nagano.jp",
- "shimosuwa.nagano.jp",
- "shinanomachi.nagano.jp",
- "shiojiri.nagano.jp",
- "suwa.nagano.jp",
- "suzaka.nagano.jp",
- "takagi.nagano.jp",
- "takamori.nagano.jp",
- "takayama.nagano.jp",
- "tateshina.nagano.jp",
- "tatsuno.nagano.jp",
- "togakushi.nagano.jp",
- "togura.nagano.jp",
- "tomi.nagano.jp",
- "ueda.nagano.jp",
- "wada.nagano.jp",
- "yamagata.nagano.jp",
- "yamanouchi.nagano.jp",
- "yasaka.nagano.jp",
- "yasuoka.nagano.jp",
- "chijiwa.nagasaki.jp",
- "futsu.nagasaki.jp",
- "goto.nagasaki.jp",
- "hasami.nagasaki.jp",
- "hirado.nagasaki.jp",
- "iki.nagasaki.jp",
- "isahaya.nagasaki.jp",
- "kawatana.nagasaki.jp",
- "kuchinotsu.nagasaki.jp",
- "matsuura.nagasaki.jp",
- "nagasaki.nagasaki.jp",
- "obama.nagasaki.jp",
- "omura.nagasaki.jp",
- "oseto.nagasaki.jp",
- "saikai.nagasaki.jp",
- "sasebo.nagasaki.jp",
- "seihi.nagasaki.jp",
- "shimabara.nagasaki.jp",
- "shinkamigoto.nagasaki.jp",
- "togitsu.nagasaki.jp",
- "tsushima.nagasaki.jp",
- "unzen.nagasaki.jp",
- "ando.nara.jp",
- "gose.nara.jp",
- "heguri.nara.jp",
- "higashiyoshino.nara.jp",
- "ikaruga.nara.jp",
- "ikoma.nara.jp",
- "kamikitayama.nara.jp",
- "kanmaki.nara.jp",
- "kashiba.nara.jp",
- "kashihara.nara.jp",
- "katsuragi.nara.jp",
- "kawai.nara.jp",
- "kawakami.nara.jp",
- "kawanishi.nara.jp",
- "koryo.nara.jp",
- "kurotaki.nara.jp",
- "mitsue.nara.jp",
- "miyake.nara.jp",
- "nara.nara.jp",
- "nosegawa.nara.jp",
- "oji.nara.jp",
- "ouda.nara.jp",
- "oyodo.nara.jp",
- "sakurai.nara.jp",
- "sango.nara.jp",
- "shimoichi.nara.jp",
- "shimokitayama.nara.jp",
- "shinjo.nara.jp",
- "soni.nara.jp",
- "takatori.nara.jp",
- "tawaramoto.nara.jp",
- "tenkawa.nara.jp",
- "tenri.nara.jp",
- "uda.nara.jp",
- "yamatokoriyama.nara.jp",
- "yamatotakada.nara.jp",
- "yamazoe.nara.jp",
- "yoshino.nara.jp",
- "aga.niigata.jp",
- "agano.niigata.jp",
- "gosen.niigata.jp",
- "itoigawa.niigata.jp",
- "izumozaki.niigata.jp",
- "joetsu.niigata.jp",
- "kamo.niigata.jp",
- "kariwa.niigata.jp",
- "kashiwazaki.niigata.jp",
- "minamiuonuma.niigata.jp",
- "mitsuke.niigata.jp",
- "muika.niigata.jp",
- "murakami.niigata.jp",
- "myoko.niigata.jp",
- "nagaoka.niigata.jp",
- "niigata.niigata.jp",
- "ojiya.niigata.jp",
- "omi.niigata.jp",
- "sado.niigata.jp",
- "sanjo.niigata.jp",
- "seiro.niigata.jp",
- "seirou.niigata.jp",
- "sekikawa.niigata.jp",
- "shibata.niigata.jp",
- "tagami.niigata.jp",
- "tainai.niigata.jp",
- "tochio.niigata.jp",
- "tokamachi.niigata.jp",
- "tsubame.niigata.jp",
- "tsunan.niigata.jp",
- "uonuma.niigata.jp",
- "yahiko.niigata.jp",
- "yoita.niigata.jp",
- "yuzawa.niigata.jp",
- "beppu.oita.jp",
- "bungoono.oita.jp",
- "bungotakada.oita.jp",
- "hasama.oita.jp",
- "hiji.oita.jp",
- "himeshima.oita.jp",
- "hita.oita.jp",
- "kamitsue.oita.jp",
- "kokonoe.oita.jp",
- "kuju.oita.jp",
- "kunisaki.oita.jp",
- "kusu.oita.jp",
- "oita.oita.jp",
- "saiki.oita.jp",
- "taketa.oita.jp",
- "tsukumi.oita.jp",
- "usa.oita.jp",
- "usuki.oita.jp",
- "yufu.oita.jp",
- "akaiwa.okayama.jp",
- "asakuchi.okayama.jp",
- "bizen.okayama.jp",
- "hayashima.okayama.jp",
- "ibara.okayama.jp",
- "kagamino.okayama.jp",
- "kasaoka.okayama.jp",
- "kibichuo.okayama.jp",
- "kumenan.okayama.jp",
- "kurashiki.okayama.jp",
- "maniwa.okayama.jp",
- "misaki.okayama.jp",
- "nagi.okayama.jp",
- "niimi.okayama.jp",
- "nishiawakura.okayama.jp",
- "okayama.okayama.jp",
- "satosho.okayama.jp",
- "setouchi.okayama.jp",
- "shinjo.okayama.jp",
- "shoo.okayama.jp",
- "soja.okayama.jp",
- "takahashi.okayama.jp",
- "tamano.okayama.jp",
- "tsuyama.okayama.jp",
- "wake.okayama.jp",
- "yakage.okayama.jp",
- "aguni.okinawa.jp",
- "ginowan.okinawa.jp",
- "ginoza.okinawa.jp",
- "gushikami.okinawa.jp",
- "haebaru.okinawa.jp",
- "higashi.okinawa.jp",
- "hirara.okinawa.jp",
- "iheya.okinawa.jp",
- "ishigaki.okinawa.jp",
- "ishikawa.okinawa.jp",
- "itoman.okinawa.jp",
- "izena.okinawa.jp",
- "kadena.okinawa.jp",
- "kin.okinawa.jp",
- "kitadaito.okinawa.jp",
- "kitanakagusuku.okinawa.jp",
- "kumejima.okinawa.jp",
- "kunigami.okinawa.jp",
- "minamidaito.okinawa.jp",
- "motobu.okinawa.jp",
- "nago.okinawa.jp",
- "naha.okinawa.jp",
- "nakagusuku.okinawa.jp",
- "nakijin.okinawa.jp",
- "nanjo.okinawa.jp",
- "nishihara.okinawa.jp",
- "ogimi.okinawa.jp",
- "okinawa.okinawa.jp",
- "onna.okinawa.jp",
- "shimoji.okinawa.jp",
- "taketomi.okinawa.jp",
- "tarama.okinawa.jp",
- "tokashiki.okinawa.jp",
- "tomigusuku.okinawa.jp",
- "tonaki.okinawa.jp",
- "urasoe.okinawa.jp",
- "uruma.okinawa.jp",
- "yaese.okinawa.jp",
- "yomitan.okinawa.jp",
- "yonabaru.okinawa.jp",
- "yonaguni.okinawa.jp",
- "zamami.okinawa.jp",
- "abeno.osaka.jp",
- "chihayaakasaka.osaka.jp",
- "chuo.osaka.jp",
- "daito.osaka.jp",
- "fujiidera.osaka.jp",
- "habikino.osaka.jp",
- "hannan.osaka.jp",
- "higashiosaka.osaka.jp",
- "higashisumiyoshi.osaka.jp",
- "higashiyodogawa.osaka.jp",
- "hirakata.osaka.jp",
- "ibaraki.osaka.jp",
- "ikeda.osaka.jp",
- "izumi.osaka.jp",
- "izumiotsu.osaka.jp",
- "izumisano.osaka.jp",
- "kadoma.osaka.jp",
- "kaizuka.osaka.jp",
- "kanan.osaka.jp",
- "kashiwara.osaka.jp",
- "katano.osaka.jp",
- "kawachinagano.osaka.jp",
- "kishiwada.osaka.jp",
- "kita.osaka.jp",
- "kumatori.osaka.jp",
- "matsubara.osaka.jp",
- "minato.osaka.jp",
- "minoh.osaka.jp",
- "misaki.osaka.jp",
- "moriguchi.osaka.jp",
- "neyagawa.osaka.jp",
- "nishi.osaka.jp",
- "nose.osaka.jp",
- "osakasayama.osaka.jp",
- "sakai.osaka.jp",
- "sayama.osaka.jp",
- "sennan.osaka.jp",
- "settsu.osaka.jp",
- "shijonawate.osaka.jp",
- "shimamoto.osaka.jp",
- "suita.osaka.jp",
- "tadaoka.osaka.jp",
- "taishi.osaka.jp",
- "tajiri.osaka.jp",
- "takaishi.osaka.jp",
- "takatsuki.osaka.jp",
- "tondabayashi.osaka.jp",
- "toyonaka.osaka.jp",
- "toyono.osaka.jp",
- "yao.osaka.jp",
- "ariake.saga.jp",
- "arita.saga.jp",
- "fukudomi.saga.jp",
- "genkai.saga.jp",
- "hamatama.saga.jp",
- "hizen.saga.jp",
- "imari.saga.jp",
- "kamimine.saga.jp",
- "kanzaki.saga.jp",
- "karatsu.saga.jp",
- "kashima.saga.jp",
- "kitagata.saga.jp",
- "kitahata.saga.jp",
- "kiyama.saga.jp",
- "kouhoku.saga.jp",
- "kyuragi.saga.jp",
- "nishiarita.saga.jp",
- "ogi.saga.jp",
- "omachi.saga.jp",
- "ouchi.saga.jp",
- "saga.saga.jp",
- "shiroishi.saga.jp",
- "taku.saga.jp",
- "tara.saga.jp",
- "tosu.saga.jp",
- "yoshinogari.saga.jp",
- "arakawa.saitama.jp",
- "asaka.saitama.jp",
- "chichibu.saitama.jp",
- "fujimi.saitama.jp",
- "fujimino.saitama.jp",
- "fukaya.saitama.jp",
- "hanno.saitama.jp",
- "hanyu.saitama.jp",
- "hasuda.saitama.jp",
- "hatogaya.saitama.jp",
- "hatoyama.saitama.jp",
- "hidaka.saitama.jp",
- "higashichichibu.saitama.jp",
- "higashimatsuyama.saitama.jp",
- "honjo.saitama.jp",
- "ina.saitama.jp",
- "iruma.saitama.jp",
- "iwatsuki.saitama.jp",
- "kamiizumi.saitama.jp",
- "kamikawa.saitama.jp",
- "kamisato.saitama.jp",
- "kasukabe.saitama.jp",
- "kawagoe.saitama.jp",
- "kawaguchi.saitama.jp",
- "kawajima.saitama.jp",
- "kazo.saitama.jp",
- "kitamoto.saitama.jp",
- "koshigaya.saitama.jp",
- "kounosu.saitama.jp",
- "kuki.saitama.jp",
- "kumagaya.saitama.jp",
- "matsubushi.saitama.jp",
- "minano.saitama.jp",
- "misato.saitama.jp",
- "miyashiro.saitama.jp",
- "miyoshi.saitama.jp",
- "moroyama.saitama.jp",
- "nagatoro.saitama.jp",
- "namegawa.saitama.jp",
- "niiza.saitama.jp",
- "ogano.saitama.jp",
- "ogawa.saitama.jp",
- "ogose.saitama.jp",
- "okegawa.saitama.jp",
- "omiya.saitama.jp",
- "otaki.saitama.jp",
- "ranzan.saitama.jp",
- "ryokami.saitama.jp",
- "saitama.saitama.jp",
- "sakado.saitama.jp",
- "satte.saitama.jp",
- "sayama.saitama.jp",
- "shiki.saitama.jp",
- "shiraoka.saitama.jp",
- "soka.saitama.jp",
- "sugito.saitama.jp",
- "toda.saitama.jp",
- "tokigawa.saitama.jp",
- "tokorozawa.saitama.jp",
- "tsurugashima.saitama.jp",
- "urawa.saitama.jp",
- "warabi.saitama.jp",
- "yashio.saitama.jp",
- "yokoze.saitama.jp",
- "yono.saitama.jp",
- "yorii.saitama.jp",
- "yoshida.saitama.jp",
- "yoshikawa.saitama.jp",
- "yoshimi.saitama.jp",
- "aisho.shiga.jp",
- "gamo.shiga.jp",
- "higashiomi.shiga.jp",
- "hikone.shiga.jp",
- "koka.shiga.jp",
- "konan.shiga.jp",
- "kosei.shiga.jp",
- "koto.shiga.jp",
- "kusatsu.shiga.jp",
- "maibara.shiga.jp",
- "moriyama.shiga.jp",
- "nagahama.shiga.jp",
- "nishiazai.shiga.jp",
- "notogawa.shiga.jp",
- "omihachiman.shiga.jp",
- "otsu.shiga.jp",
- "ritto.shiga.jp",
- "ryuoh.shiga.jp",
- "takashima.shiga.jp",
- "takatsuki.shiga.jp",
- "torahime.shiga.jp",
- "toyosato.shiga.jp",
- "yasu.shiga.jp",
- "akagi.shimane.jp",
- "ama.shimane.jp",
- "gotsu.shimane.jp",
- "hamada.shimane.jp",
- "higashiizumo.shimane.jp",
- "hikawa.shimane.jp",
- "hikimi.shimane.jp",
- "izumo.shimane.jp",
- "kakinoki.shimane.jp",
- "masuda.shimane.jp",
- "matsue.shimane.jp",
- "misato.shimane.jp",
- "nishinoshima.shimane.jp",
- "ohda.shimane.jp",
- "okinoshima.shimane.jp",
- "okuizumo.shimane.jp",
- "shimane.shimane.jp",
- "tamayu.shimane.jp",
- "tsuwano.shimane.jp",
- "unnan.shimane.jp",
- "yakumo.shimane.jp",
- "yasugi.shimane.jp",
- "yatsuka.shimane.jp",
- "arai.shizuoka.jp",
- "atami.shizuoka.jp",
- "fuji.shizuoka.jp",
- "fujieda.shizuoka.jp",
- "fujikawa.shizuoka.jp",
- "fujinomiya.shizuoka.jp",
- "fukuroi.shizuoka.jp",
- "gotemba.shizuoka.jp",
- "haibara.shizuoka.jp",
- "hamamatsu.shizuoka.jp",
- "higashiizu.shizuoka.jp",
- "ito.shizuoka.jp",
- "iwata.shizuoka.jp",
- "izu.shizuoka.jp",
- "izunokuni.shizuoka.jp",
- "kakegawa.shizuoka.jp",
- "kannami.shizuoka.jp",
- "kawanehon.shizuoka.jp",
- "kawazu.shizuoka.jp",
- "kikugawa.shizuoka.jp",
- "kosai.shizuoka.jp",
- "makinohara.shizuoka.jp",
- "matsuzaki.shizuoka.jp",
- "minamiizu.shizuoka.jp",
- "mishima.shizuoka.jp",
- "morimachi.shizuoka.jp",
- "nishiizu.shizuoka.jp",
- "numazu.shizuoka.jp",
- "omaezaki.shizuoka.jp",
- "shimada.shizuoka.jp",
- "shimizu.shizuoka.jp",
- "shimoda.shizuoka.jp",
- "shizuoka.shizuoka.jp",
- "susono.shizuoka.jp",
- "yaizu.shizuoka.jp",
- "yoshida.shizuoka.jp",
- "ashikaga.tochigi.jp",
- "bato.tochigi.jp",
- "haga.tochigi.jp",
- "ichikai.tochigi.jp",
- "iwafune.tochigi.jp",
- "kaminokawa.tochigi.jp",
- "kanuma.tochigi.jp",
- "karasuyama.tochigi.jp",
- "kuroiso.tochigi.jp",
- "mashiko.tochigi.jp",
- "mibu.tochigi.jp",
- "moka.tochigi.jp",
- "motegi.tochigi.jp",
- "nasu.tochigi.jp",
- "nasushiobara.tochigi.jp",
- "nikko.tochigi.jp",
- "nishikata.tochigi.jp",
- "nogi.tochigi.jp",
- "ohira.tochigi.jp",
- "ohtawara.tochigi.jp",
- "oyama.tochigi.jp",
- "sakura.tochigi.jp",
- "sano.tochigi.jp",
- "shimotsuke.tochigi.jp",
- "shioya.tochigi.jp",
- "takanezawa.tochigi.jp",
- "tochigi.tochigi.jp",
- "tsuga.tochigi.jp",
- "ujiie.tochigi.jp",
- "utsunomiya.tochigi.jp",
- "yaita.tochigi.jp",
- "aizumi.tokushima.jp",
- "anan.tokushima.jp",
- "ichiba.tokushima.jp",
- "itano.tokushima.jp",
- "kainan.tokushima.jp",
- "komatsushima.tokushima.jp",
- "matsushige.tokushima.jp",
- "mima.tokushima.jp",
- "minami.tokushima.jp",
- "miyoshi.tokushima.jp",
- "mugi.tokushima.jp",
- "nakagawa.tokushima.jp",
- "naruto.tokushima.jp",
- "sanagochi.tokushima.jp",
- "shishikui.tokushima.jp",
- "tokushima.tokushima.jp",
- "wajiki.tokushima.jp",
- "adachi.tokyo.jp",
- "akiruno.tokyo.jp",
- "akishima.tokyo.jp",
- "aogashima.tokyo.jp",
- "arakawa.tokyo.jp",
- "bunkyo.tokyo.jp",
- "chiyoda.tokyo.jp",
- "chofu.tokyo.jp",
- "chuo.tokyo.jp",
- "edogawa.tokyo.jp",
- "fuchu.tokyo.jp",
- "fussa.tokyo.jp",
- "hachijo.tokyo.jp",
- "hachioji.tokyo.jp",
- "hamura.tokyo.jp",
- "higashikurume.tokyo.jp",
- "higashimurayama.tokyo.jp",
- "higashiyamato.tokyo.jp",
- "hino.tokyo.jp",
- "hinode.tokyo.jp",
- "hinohara.tokyo.jp",
- "inagi.tokyo.jp",
- "itabashi.tokyo.jp",
- "katsushika.tokyo.jp",
- "kita.tokyo.jp",
- "kiyose.tokyo.jp",
- "kodaira.tokyo.jp",
- "koganei.tokyo.jp",
- "kokubunji.tokyo.jp",
- "komae.tokyo.jp",
- "koto.tokyo.jp",
- "kouzushima.tokyo.jp",
- "kunitachi.tokyo.jp",
- "machida.tokyo.jp",
- "meguro.tokyo.jp",
- "minato.tokyo.jp",
- "mitaka.tokyo.jp",
- "mizuho.tokyo.jp",
- "musashimurayama.tokyo.jp",
- "musashino.tokyo.jp",
- "nakano.tokyo.jp",
- "nerima.tokyo.jp",
- "ogasawara.tokyo.jp",
- "okutama.tokyo.jp",
- "ome.tokyo.jp",
- "oshima.tokyo.jp",
- "ota.tokyo.jp",
- "setagaya.tokyo.jp",
- "shibuya.tokyo.jp",
- "shinagawa.tokyo.jp",
- "shinjuku.tokyo.jp",
- "suginami.tokyo.jp",
- "sumida.tokyo.jp",
- "tachikawa.tokyo.jp",
- "taito.tokyo.jp",
- "tama.tokyo.jp",
- "toshima.tokyo.jp",
- "chizu.tottori.jp",
- "hino.tottori.jp",
- "kawahara.tottori.jp",
- "koge.tottori.jp",
- "kotoura.tottori.jp",
- "misasa.tottori.jp",
- "nanbu.tottori.jp",
- "nichinan.tottori.jp",
- "sakaiminato.tottori.jp",
- "tottori.tottori.jp",
- "wakasa.tottori.jp",
- "yazu.tottori.jp",
- "yonago.tottori.jp",
- "asahi.toyama.jp",
- "fuchu.toyama.jp",
- "fukumitsu.toyama.jp",
- "funahashi.toyama.jp",
- "himi.toyama.jp",
- "imizu.toyama.jp",
- "inami.toyama.jp",
- "johana.toyama.jp",
- "kamiichi.toyama.jp",
- "kurobe.toyama.jp",
- "nakaniikawa.toyama.jp",
- "namerikawa.toyama.jp",
- "nanto.toyama.jp",
- "nyuzen.toyama.jp",
- "oyabe.toyama.jp",
- "taira.toyama.jp",
- "takaoka.toyama.jp",
- "tateyama.toyama.jp",
- "toga.toyama.jp",
- "tonami.toyama.jp",
- "toyama.toyama.jp",
- "unazuki.toyama.jp",
- "uozu.toyama.jp",
- "yamada.toyama.jp",
- "arida.wakayama.jp",
- "aridagawa.wakayama.jp",
- "gobo.wakayama.jp",
- "hashimoto.wakayama.jp",
- "hidaka.wakayama.jp",
- "hirogawa.wakayama.jp",
- "inami.wakayama.jp",
- "iwade.wakayama.jp",
- "kainan.wakayama.jp",
- "kamitonda.wakayama.jp",
- "katsuragi.wakayama.jp",
- "kimino.wakayama.jp",
- "kinokawa.wakayama.jp",
- "kitayama.wakayama.jp",
- "koya.wakayama.jp",
- "koza.wakayama.jp",
- "kozagawa.wakayama.jp",
- "kudoyama.wakayama.jp",
- "kushimoto.wakayama.jp",
- "mihama.wakayama.jp",
- "misato.wakayama.jp",
- "nachikatsuura.wakayama.jp",
- "shingu.wakayama.jp",
- "shirahama.wakayama.jp",
- "taiji.wakayama.jp",
- "tanabe.wakayama.jp",
- "wakayama.wakayama.jp",
- "yuasa.wakayama.jp",
- "yura.wakayama.jp",
- "asahi.yamagata.jp",
- "funagata.yamagata.jp",
- "higashine.yamagata.jp",
- "iide.yamagata.jp",
- "kahoku.yamagata.jp",
- "kaminoyama.yamagata.jp",
- "kaneyama.yamagata.jp",
- "kawanishi.yamagata.jp",
- "mamurogawa.yamagata.jp",
- "mikawa.yamagata.jp",
- "murayama.yamagata.jp",
- "nagai.yamagata.jp",
- "nakayama.yamagata.jp",
- "nanyo.yamagata.jp",
- "nishikawa.yamagata.jp",
- "obanazawa.yamagata.jp",
- "oe.yamagata.jp",
- "oguni.yamagata.jp",
- "ohkura.yamagata.jp",
- "oishida.yamagata.jp",
- "sagae.yamagata.jp",
- "sakata.yamagata.jp",
- "sakegawa.yamagata.jp",
- "shinjo.yamagata.jp",
- "shirataka.yamagata.jp",
- "shonai.yamagata.jp",
- "takahata.yamagata.jp",
- "tendo.yamagata.jp",
- "tozawa.yamagata.jp",
- "tsuruoka.yamagata.jp",
- "yamagata.yamagata.jp",
- "yamanobe.yamagata.jp",
- "yonezawa.yamagata.jp",
- "yuza.yamagata.jp",
- "abu.yamaguchi.jp",
- "hagi.yamaguchi.jp",
- "hikari.yamaguchi.jp",
- "hofu.yamaguchi.jp",
- "iwakuni.yamaguchi.jp",
- "kudamatsu.yamaguchi.jp",
- "mitou.yamaguchi.jp",
- "nagato.yamaguchi.jp",
- "oshima.yamaguchi.jp",
- "shimonoseki.yamaguchi.jp",
- "shunan.yamaguchi.jp",
- "tabuse.yamaguchi.jp",
- "tokuyama.yamaguchi.jp",
- "toyota.yamaguchi.jp",
- "ube.yamaguchi.jp",
- "yuu.yamaguchi.jp",
- "chuo.yamanashi.jp",
- "doshi.yamanashi.jp",
- "fuefuki.yamanashi.jp",
- "fujikawa.yamanashi.jp",
- "fujikawaguchiko.yamanashi.jp",
- "fujiyoshida.yamanashi.jp",
- "hayakawa.yamanashi.jp",
- "hokuto.yamanashi.jp",
- "ichikawamisato.yamanashi.jp",
- "kai.yamanashi.jp",
- "kofu.yamanashi.jp",
- "koshu.yamanashi.jp",
- "kosuge.yamanashi.jp",
- "minami-alps.yamanashi.jp",
- "minobu.yamanashi.jp",
- "nakamichi.yamanashi.jp",
- "nanbu.yamanashi.jp",
- "narusawa.yamanashi.jp",
- "nirasaki.yamanashi.jp",
- "nishikatsura.yamanashi.jp",
- "oshino.yamanashi.jp",
- "otsuki.yamanashi.jp",
- "showa.yamanashi.jp",
- "tabayama.yamanashi.jp",
- "tsuru.yamanashi.jp",
- "uenohara.yamanashi.jp",
- "yamanakako.yamanashi.jp",
- "yamanashi.yamanashi.jp",
"kg",
"org.kg",
"net.kg",
@@ -3012,6 +1283,7 @@ final class TldPatterns {
"per.la",
"com.la",
"org.la",
+ "c.la",
"com.lb",
"edu.lb",
"gov.lb",
@@ -3040,6 +1312,7 @@ final class TldPatterns {
"assn.lk",
"grp.lk",
"hotel.lk",
+ "local",
"com.lr",
"edu.lr",
"gov.lr",
@@ -3760,6 +2033,10 @@ final class TldPatterns {
"asso.nc",
"ne",
"net",
+ "gb.net",
+ "se.net",
+ "uk.net",
+ "za.net",
"nf",
"com.nf",
"net.nf",
@@ -4716,6 +2993,8 @@ final class TldPatterns {
"com.nr",
"nu",
"org",
+ "ae.org",
+ "za.org",
"pa",
"ac.pa",
"gob.pa",
@@ -4944,7 +3223,7 @@ final class TldPatterns {
"poznan.pl",
"wroc.pl",
"zakopane.pl",
- "pm",
+ "co.pl",
"pn",
"gov.pn",
"co.pn",
@@ -4997,15 +3276,6 @@ final class TldPatterns {
"ed.pw",
"go.pw",
"belau.pw",
- "qa",
- "com.qa",
- "edu.qa",
- "gov.qa",
- "mil.qa",
- "name.qa",
- "net.qa",
- "org.qa",
- "sch.qa",
"re",
"com.re",
"asso.re",
@@ -5200,7 +3470,6 @@ final class TldPatterns {
"org.sd",
"edu.sd",
"med.sd",
- "tv.sd",
"gov.sd",
"info.sd",
"se",
@@ -5252,11 +3521,6 @@ final class TldPatterns {
"edu.sg",
"per.sg",
"sh",
- "com.sh",
- "net.sh",
- "gov.sh",
- "org.sh",
- "mil.sh",
"si",
"sk",
"sl",
@@ -5293,8 +3557,6 @@ final class TldPatterns {
"saotome.st",
"store.st",
"su",
- "sx",
- "gov.sx",
"sy",
"edu.sy",
"gov.sy",
@@ -5339,14 +3601,6 @@ final class TldPatterns {
"tl",
"gov.tl",
"tm",
- "com.tm",
- "co.tm",
- "org.tm",
- "net.tm",
- "nom.tm",
- "gov.tm",
- "mil.tm",
- "edu.tm",
"tn",
"com.tn",
"ens.tn",
@@ -5428,86 +3682,58 @@ final class TldPatterns {
"net.ua",
"org.ua",
"cherkassy.ua",
- "cherkasy.ua",
"chernigov.ua",
- "chernihiv.ua",
- "chernivtsi.ua",
"chernovtsy.ua",
"ck.ua",
"cn.ua",
- "cr.ua",
"crimea.ua",
"cv.ua",
"dn.ua",
"dnepropetrovsk.ua",
- "dnipropetrovsk.ua",
- "dominic.ua",
"donetsk.ua",
"dp.ua",
"if.ua",
"ivano-frankivsk.ua",
"kh.ua",
- "kharkiv.ua",
"kharkov.ua",
"kherson.ua",
"khmelnitskiy.ua",
- "khmelnytskyi.ua",
"kiev.ua",
"kirovograd.ua",
"km.ua",
"kr.ua",
- "krym.ua",
"ks.ua",
"kv.ua",
- "kyiv.ua",
"lg.ua",
- "lt.ua",
"lugansk.ua",
"lutsk.ua",
- "lv.ua",
"lviv.ua",
"mk.ua",
- "mykolaiv.ua",
"nikolaev.ua",
"od.ua",
- "odesa.ua",
"odessa.ua",
"pl.ua",
"poltava.ua",
- "rivne.ua",
"rovno.ua",
"rv.ua",
- "sb.ua",
"sebastopol.ua",
- "sevastopol.ua",
- "sm.ua",
"sumy.ua",
"te.ua",
"ternopil.ua",
- "uz.ua",
"uzhgorod.ua",
"vinnica.ua",
- "vinnytsia.ua",
"vn.ua",
- "volyn.ua",
- "yalta.ua",
"zaporizhzhe.ua",
- "zaporizhzhia.ua",
- "zhitomir.ua",
- "zhytomyr.ua",
"zp.ua",
+ "zhitomir.ua",
"zt.ua",
- "co.ua",
- "pp.ua",
"ug",
"co.ug",
- "or.ug",
"ac.ug",
"sc.ug",
"go.ug",
"ne.ug",
- "com.ug",
- "org.ug",
+ "or.ug",
"us",
"dni.us",
"fed.us",
@@ -5736,18 +3962,9 @@ final class TldPatterns {
"pvt.k12.ma.us",
"chtr.k12.ma.us",
"paroch.k12.ma.us",
- "uy",
- "com.uy",
- "edu.uy",
- "gub.uy",
- "mil.uy",
- "net.uy",
- "org.uy",
"uz",
- "co.uz",
"com.uz",
- "net.uz",
- "org.uz",
+ "co.uz",
"va",
"vc",
"com.vc",
@@ -5756,17 +3973,6 @@ final class TldPatterns {
"gov.vc",
"mil.vc",
"edu.vc",
- "ve",
- "co.ve",
- "com.ve",
- "e12.ve",
- "edu.ve",
- "gov.ve",
- "info.ve",
- "mil.ve",
- "net.ve",
- "org.ve",
- "web.ve",
"vg",
"vi",
"co.vi",
@@ -5788,14 +3994,12 @@ final class TldPatterns {
"pro.vn",
"health.vn",
"vu",
- "wf",
"ws",
"com.ws",
"net.ws",
"org.ws",
"gov.ws",
"edu.ws",
- "yt",
"\u0627\u0645\u0627\u0631\u0627\u062a",
"xn--mgbaam7a8h",
"\u09ac\u09be\u0982\u09b2\u09be",
@@ -5881,330 +4085,9 @@ final class TldPatterns {
"\u0627\u0644\u064a\u0645\u0646",
"xn--mgb2ddes",
"xxx",
- "biz.at",
- "info.at",
- "priv.at",
- "co.ca",
- "ae.org",
- "ar.com",
- "br.com",
- "cn.com",
- "com.de",
- "de.com",
- "eu.com",
- "gb.com",
- "gb.net",
- "gr.com",
- "hu.com",
- "hu.net",
- "jp.net",
- "jpn.com",
- "kr.com",
- "no.com",
- "qc.com",
- "ru.com",
- "sa.com",
- "se.com",
- "se.net",
- "uk.com",
- "uk.net",
- "us.com",
- "us.org",
- "uy.com",
- "za.com",
- "operaunite.com",
- "appspot.com",
- "dreamhosters.com",
- "iki.fi",
- "c.la",
- "za.net",
- "za.org",
- "co.nl",
- "co.no",
- "co.pl",
- "dyndns-at-home.com",
- "dyndns-at-work.com",
- "dyndns-blog.com",
- "dyndns-free.com",
- "dyndns-home.com",
- "dyndns-ip.com",
- "dyndns-mail.com",
- "dyndns-office.com",
- "dyndns-pics.com",
- "dyndns-remote.com",
- "dyndns-server.com",
- "dyndns-web.com",
- "dyndns-wiki.com",
- "dyndns-work.com",
- "dyndns.biz",
- "dyndns.info",
- "dyndns.org",
- "dyndns.tv",
- "at-band-camp.net",
- "ath.cx",
- "barrel-of-knowledge.info",
- "barrell-of-knowledge.info",
- "better-than.tv",
- "blogdns.com",
- "blogdns.net",
- "blogdns.org",
- "blogsite.org",
- "boldlygoingnowhere.org",
- "broke-it.net",
- "buyshouses.net",
- "cechire.com",
- "dnsalias.com",
- "dnsalias.net",
- "dnsalias.org",
- "dnsdojo.com",
- "dnsdojo.net",
- "dnsdojo.org",
- "does-it.net",
- "doesntexist.com",
- "doesntexist.org",
- "dontexist.com",
- "dontexist.net",
- "dontexist.org",
- "doomdns.com",
- "doomdns.org",
- "dvrdns.org",
- "dyn-o-saur.com",
- "dynalias.com",
- "dynalias.net",
- "dynalias.org",
- "dynathome.net",
- "dyndns.ws",
- "endofinternet.net",
- "endofinternet.org",
- "endoftheinternet.org",
- "est-a-la-maison.com",
- "est-a-la-masion.com",
- "est-le-patron.com",
- "est-mon-blogueur.com",
- "for-better.biz",
- "for-more.biz",
- "for-our.info",
- "for-some.biz",
- "for-the.biz",
- "forgot.her.name",
- "forgot.his.name",
- "from-ak.com",
- "from-al.com",
- "from-ar.com",
- "from-az.net",
- "from-ca.com",
- "from-co.net",
- "from-ct.com",
- "from-dc.com",
- "from-de.com",
- "from-fl.com",
- "from-ga.com",
- "from-hi.com",
- "from-ia.com",
- "from-id.com",
- "from-il.com",
- "from-in.com",
- "from-ks.com",
- "from-ky.com",
- "from-la.net",
- "from-ma.com",
- "from-md.com",
- "from-me.org",
- "from-mi.com",
- "from-mn.com",
- "from-mo.com",
- "from-ms.com",
- "from-mt.com",
- "from-nc.com",
- "from-nd.com",
- "from-ne.com",
- "from-nh.com",
- "from-nj.com",
- "from-nm.com",
- "from-nv.com",
- "from-ny.net",
- "from-oh.com",
- "from-ok.com",
- "from-or.com",
- "from-pa.com",
- "from-pr.com",
- "from-ri.com",
- "from-sc.com",
- "from-sd.com",
- "from-tn.com",
- "from-tx.com",
- "from-ut.com",
- "from-va.com",
- "from-vt.com",
- "from-wa.com",
- "from-wi.com",
- "from-wv.com",
- "from-wy.com",
- "ftpaccess.cc",
- "fuettertdasnetz.de",
- "game-host.org",
- "game-server.cc",
- "getmyip.com",
- "gets-it.net",
- "go.dyndns.org",
- "gotdns.com",
- "gotdns.org",
- "groks-the.info",
- "groks-this.info",
- "ham-radio-op.net",
- "here-for-more.info",
- "hobby-site.com",
- "hobby-site.org",
- "home.dyndns.org",
- "homedns.org",
- "homeftp.net",
- "homeftp.org",
- "homeip.net",
- "homelinux.com",
- "homelinux.net",
- "homelinux.org",
- "homeunix.com",
- "homeunix.net",
- "homeunix.org",
- "iamallama.com",
- "in-the-band.net",
- "is-a-anarchist.com",
- "is-a-blogger.com",
- "is-a-bookkeeper.com",
- "is-a-bruinsfan.org",
- "is-a-bulls-fan.com",
- "is-a-candidate.org",
- "is-a-caterer.com",
- "is-a-celticsfan.org",
- "is-a-chef.com",
- "is-a-chef.net",
- "is-a-chef.org",
- "is-a-conservative.com",
- "is-a-cpa.com",
- "is-a-cubicle-slave.com",
- "is-a-democrat.com",
- "is-a-designer.com",
- "is-a-doctor.com",
- "is-a-financialadvisor.com",
- "is-a-geek.com",
- "is-a-geek.net",
- "is-a-geek.org",
- "is-a-green.com",
- "is-a-guru.com",
- "is-a-hard-worker.com",
- "is-a-hunter.com",
- "is-a-knight.org",
- "is-a-landscaper.com",
- "is-a-lawyer.com",
- "is-a-liberal.com",
- "is-a-libertarian.com",
- "is-a-linux-user.org",
- "is-a-llama.com",
- "is-a-musician.com",
- "is-a-nascarfan.com",
- "is-a-nurse.com",
- "is-a-painter.com",
- "is-a-patsfan.org",
- "is-a-personaltrainer.com",
- "is-a-photographer.com",
- "is-a-player.com",
- "is-a-republican.com",
- "is-a-rockstar.com",
- "is-a-socialist.com",
- "is-a-soxfan.org",
- "is-a-student.com",
- "is-a-teacher.com",
- "is-a-techie.com",
- "is-a-therapist.com",
- "is-an-accountant.com",
- "is-an-actor.com",
- "is-an-actress.com",
- "is-an-anarchist.com",
- "is-an-artist.com",
- "is-an-engineer.com",
- "is-an-entertainer.com",
- "is-by.us",
- "is-certified.com",
- "is-found.org",
- "is-gone.com",
- "is-into-anime.com",
- "is-into-cars.com",
- "is-into-cartoons.com",
- "is-into-games.com",
- "is-leet.com",
- "is-lost.org",
- "is-not-certified.com",
- "is-saved.org",
- "is-slick.com",
- "is-uberleet.com",
- "is-very-bad.org",
- "is-very-evil.org",
- "is-very-good.org",
- "is-very-nice.org",
- "is-very-sweet.org",
- "is-with-theband.com",
- "isa-geek.com",
- "isa-geek.net",
- "isa-geek.org",
- "isa-hockeynut.com",
- "issmarterthanyou.com",
- "isteingeek.de",
- "istmein.de",
- "kicks-ass.net",
- "kicks-ass.org",
- "knowsitall.info",
- "land-4-sale.us",
- "lebtimnetz.de",
- "leitungsen.de",
- "likes-pie.com",
- "likescandy.com",
- "merseine.nu",
- "mine.nu",
- "misconfused.org",
- "mypets.ws",
- "myphotos.cc",
- "neat-url.com",
- "office-on-the.net",
- "on-the-web.tv",
- "podzone.net",
- "podzone.org",
- "readmyblog.org",
- "saves-the-whales.com",
- "scrapper-site.net",
- "scrapping.cc",
- "selfip.biz",
- "selfip.com",
- "selfip.info",
- "selfip.net",
- "selfip.org",
- "sells-for-less.com",
- "sells-for-u.com",
- "sells-it.net",
- "sellsyourhome.org",
- "servebbs.com",
- "servebbs.net",
- "servebbs.org",
- "serveftp.net",
- "serveftp.org",
- "servegame.org",
- "shacknet.nu",
- "simple-url.com",
- "space-to-rent.com",
- "stuff-4-sale.org",
- "stuff-4-sale.us",
- "teaches-yoga.com",
- "thruhere.net",
- "traeumtgerade.de",
- "webhop.biz",
- "webhop.info",
- "webhop.net",
- "webhop.org",
- "worse-than.tv",
- "writesthisblog.com",
"tp",
- "ng",
- "\u049b\u0430\u0437",
- "xn--80ao21a"
+ "yt",
+ "ng"
);
/**
@@ -6212,8 +4095,9 @@ final class TldPatterns {
* leftmost component results in a name which is contained in this
* set, it is a TLD.
*/
- static final ImmutableSet<String> UNDER = ImmutableSet.of(
+ static final Set<String> UNDER = ImmutableSet.of(
"ar",
+ "au",
"bd",
"bn",
"ck",
@@ -6226,12 +4110,59 @@ final class TldPatterns {
"gu",
"il",
"jm",
+ "aichi.jp",
+ "akita.jp",
+ "aomori.jp",
+ "chiba.jp",
+ "ehime.jp",
+ "fukui.jp",
+ "fukuoka.jp",
+ "fukushima.jp",
+ "gifu.jp",
+ "gunma.jp",
+ "hiroshima.jp",
+ "hokkaido.jp",
+ "hyogo.jp",
+ "ibaraki.jp",
+ "ishikawa.jp",
+ "iwate.jp",
+ "kagawa.jp",
+ "kagoshima.jp",
+ "kanagawa.jp",
"kawasaki.jp",
"kitakyushu.jp",
"kobe.jp",
+ "kochi.jp",
+ "kumamoto.jp",
+ "kyoto.jp",
+ "mie.jp",
+ "miyagi.jp",
+ "miyazaki.jp",
+ "nagano.jp",
+ "nagasaki.jp",
"nagoya.jp",
+ "nara.jp",
+ "niigata.jp",
+ "oita.jp",
+ "okayama.jp",
+ "okinawa.jp",
+ "osaka.jp",
+ "saga.jp",
+ "saitama.jp",
"sapporo.jp",
"sendai.jp",
+ "shiga.jp",
+ "shimane.jp",
+ "shizuoka.jp",
+ "tochigi.jp",
+ "tokushima.jp",
+ "tokyo.jp",
+ "tottori.jp",
+ "toyama.jp",
+ "wakayama.jp",
+ "yamagata.jp",
+ "yamaguchi.jp",
+ "yamanashi.jp",
"yokohama.jp",
"ke",
"kh",
@@ -6245,13 +4176,15 @@ final class TldPatterns {
"om",
"pg",
"py",
+ "qa",
"sv",
"tr",
"uk",
- "nhs.uk",
- "police.uk",
"sch.uk",
+ "uy",
+ "ve",
"ye",
+ "yu",
"za",
"zm",
"zw"
@@ -6261,7 +4194,7 @@ final class TldPatterns {
* The elements in this set would pass the UNDER test, but are
* known not to be TLDs and are thus excluded from consideration.
*/
- static final ImmutableSet<String> EXCLUDED = ImmutableSet.of(
+ static final Set<String> EXCLUDED = ImmutableSet.of(
"congresodelalengua3.ar",
"educ.ar",
"gobiernoelectronico.ar",
@@ -6271,14 +4204,68 @@ final class TldPatterns {
"promocion.ar",
"retina.ar",
"uba.ar",
- "www.ck",
- "www.gt",
+ "metro.tokyo.jp",
+ "pref.aichi.jp",
+ "pref.akita.jp",
+ "pref.aomori.jp",
+ "pref.chiba.jp",
+ "pref.ehime.jp",
+ "pref.fukui.jp",
+ "pref.fukuoka.jp",
+ "pref.fukushima.jp",
+ "pref.gifu.jp",
+ "pref.gunma.jp",
+ "pref.hiroshima.jp",
+ "pref.hokkaido.jp",
+ "pref.hyogo.jp",
+ "pref.ibaraki.jp",
+ "pref.ishikawa.jp",
+ "pref.iwate.jp",
+ "pref.kagawa.jp",
+ "pref.kagoshima.jp",
+ "pref.kanagawa.jp",
+ "pref.kochi.jp",
+ "pref.kumamoto.jp",
+ "pref.kyoto.jp",
+ "pref.mie.jp",
+ "pref.miyagi.jp",
+ "pref.miyazaki.jp",
+ "pref.nagano.jp",
+ "pref.nagasaki.jp",
+ "pref.nara.jp",
+ "pref.niigata.jp",
+ "pref.oita.jp",
+ "pref.okayama.jp",
+ "pref.okinawa.jp",
+ "pref.osaka.jp",
+ "pref.saga.jp",
+ "pref.saitama.jp",
+ "pref.shiga.jp",
+ "pref.shimane.jp",
+ "pref.shizuoka.jp",
+ "pref.tochigi.jp",
+ "pref.tokushima.jp",
+ "pref.tottori.jp",
+ "pref.toyama.jp",
+ "pref.wakayama.jp",
+ "pref.yamagata.jp",
+ "pref.yamaguchi.jp",
+ "pref.yamanashi.jp",
+ "city.chiba.jp",
+ "city.fukuoka.jp",
+ "city.hiroshima.jp",
"city.kawasaki.jp",
"city.kitakyushu.jp",
"city.kobe.jp",
+ "city.kyoto.jp",
"city.nagoya.jp",
+ "city.niigata.jp",
+ "city.okayama.jp",
+ "city.osaka.jp",
+ "city.saitama.jp",
"city.sapporo.jp",
"city.sendai.jp",
+ "city.shizuoka.jp",
"city.yokohama.jp",
"mediaphone.om",
"nawrastelecom.om",
@@ -6291,15 +4278,17 @@ final class TldPatterns {
"songfest.om",
"statecouncil.om",
"nic.tr",
+ "tsk.tr",
"bl.uk",
"british-library.uk",
+ "icnet.uk",
"jet.uk",
- "mod.uk",
- "national-library-scotland.uk",
"nel.uk",
- "nic.uk",
+ "nhs.uk",
"nls.uk",
- "parliament.uk"
+ "national-library-scotland.uk",
+ "parliament.uk",
+ "police.uk"
);
}
diff --git a/guava/src/com/google/common/net/package-info.java b/guava/src/com/google/common/net/package-info.java
index 090a231..1cb9958 100644
--- a/guava/src/com/google/common/net/package-info.java
+++ b/guava/src/com/google/common/net/package-info.java
@@ -27,4 +27,3 @@
package com.google.common.net;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/guava/src/com/google/common/primitives/Booleans.java b/guava/src/com/google/common/primitives/Booleans.java
index 3601a8a..ab333f1 100644
--- a/guava/src/com/google/common/primitives/Booleans.java
+++ b/guava/src/com/google/common/primitives/Booleans.java
@@ -37,10 +37,6 @@ import java.util.RandomAccess;
* Static utility methods pertaining to {@code boolean} primitives, that are not
* already found in either {@link Boolean} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -407,8 +403,7 @@ public final class Booleans {
@Override public Boolean set(int index, Boolean element) {
checkElementIndex(index, size());
boolean oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -459,7 +454,7 @@ public final class Booleans {
}
boolean[] toBooleanArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
boolean[] result = new boolean[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava/src/com/google/common/primitives/Bytes.java b/guava/src/com/google/common/primitives/Bytes.java
index d9c5e1f..92f7805 100644
--- a/guava/src/com/google/common/primitives/Bytes.java
+++ b/guava/src/com/google/common/primitives/Bytes.java
@@ -38,10 +38,6 @@ import java.util.RandomAccess;
* treat bytes as signed or unsigned are found in {@link SignedBytes} and {@link
* UnsignedBytes}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -214,21 +210,20 @@ public final class Bytes {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code byte} value in the manner of {@link Number#byteValue}.
+ * Copies a collection of {@code Byte} instances into a new array of
+ * primitive {@code byte} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Byte} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Byte>} before 12.0)
*/
- public static byte[] toArray(Collection<? extends Number> collection) {
+ public static byte[] toArray(Collection<Byte> collection) {
if (collection instanceof ByteArrayAsList) {
return ((ByteArrayAsList) collection).toByteArray();
}
@@ -238,7 +233,7 @@ public final class Bytes {
byte[] array = new byte[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).byteValue();
+ array[i] = (Byte) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -325,8 +320,7 @@ public final class Bytes {
@Override public Byte set(int index, Byte element) {
checkElementIndex(index, size());
byte oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -377,7 +371,7 @@ public final class Bytes {
}
byte[] toByteArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
byte[] result = new byte[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava/src/com/google/common/primitives/Chars.java b/guava/src/com/google/common/primitives/Chars.java
index 241814a..5ac57d1 100644
--- a/guava/src/com/google/common/primitives/Chars.java
+++ b/guava/src/com/google/common/primitives/Chars.java
@@ -40,10 +40,6 @@ import java.util.RandomAccess;
* <p>All the operations in this class treat {@code char} values strictly
* numerically; they are neither Unicode-aware nor locale-dependent.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -523,8 +519,7 @@ public final class Chars {
@Override public Character set(int index, Character element) {
checkElementIndex(index, size());
char oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -575,7 +570,7 @@ public final class Chars {
}
char[] toCharArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
char[] result = new char[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava/src/com/google/common/primitives/Doubles.java b/guava/src/com/google/common/primitives/Doubles.java
index 068fc9d..dc3ea64 100644
--- a/guava/src/com/google/common/primitives/Doubles.java
+++ b/guava/src/com/google/common/primitives/Doubles.java
@@ -23,9 +23,7 @@ import static com.google.common.base.Preconditions.checkPositionIndexes;
import static java.lang.Double.NEGATIVE_INFINITY;
import static java.lang.Double.POSITIVE_INFINITY;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
import java.util.AbstractList;
@@ -35,22 +33,15 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.RandomAccess;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
/**
* Static utility methods pertaining to {@code double} primitives, that are not
* already found in either {@link Double} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public final class Doubles {
private Doubles() {}
@@ -302,8 +293,8 @@ public final class Doubles {
* the string {@code "1.0-2.0-3.0"}.
*
* <p>Note that {@link Double#toString(double)} formats {@code double}
- * differently in GWT sometimes. In the previous example, it returns the
- * string {@code "1-2-3"}.
+ * differently in GWT sometimes. In the previous example, it returns the string
+ * {@code "1-2-3"}.
*
* @param separator the text that should appear between consecutive values in
* the resulting string (but not at the start or end)
@@ -361,21 +352,20 @@ public final class Doubles {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code double} value in the manner of {@link Number#doubleValue}.
+ * Copies a collection of {@code Double} instances into a new array of
+ * primitive {@code double} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Double} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Double>} before 12.0)
*/
- public static double[] toArray(Collection<? extends Number> collection) {
+ public static double[] toArray(Collection<Double> collection) {
if (collection instanceof DoubleArrayAsList) {
return ((DoubleArrayAsList) collection).toDoubleArray();
}
@@ -385,7 +375,7 @@ public final class Doubles {
double[] array = new double[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).doubleValue();
+ array[i] = (Double) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -475,8 +465,7 @@ public final class Doubles {
@Override public Double set(int index, Double element) {
checkElementIndex(index, size());
double oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -527,7 +516,7 @@ public final class Doubles {
}
double[] toDoubleArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
double[] result = new double[size];
System.arraycopy(array, start, result, 0, size);
@@ -536,59 +525,4 @@ public final class Doubles {
private static final long serialVersionUID = 0;
}
-
- /**
- * This is adapted from the regex suggested by {@link Double#valueOf(String)}
- * for prevalidating inputs. All valid inputs must pass this regex, but it's
- * semantically fine if not all inputs that pass this regex are valid --
- * only a performance hit is incurred, not a semantics bug.
- */
- @GwtIncompatible("regular expressions")
- static final Pattern FLOATING_POINT_PATTERN = fpPattern();
-
- @GwtIncompatible("regular expressions")
- private static Pattern fpPattern() {
- String decimal = "(?:\\d++(?:\\.\\d*+)?|\\.\\d++)";
- String completeDec = decimal + "(?:[eE][+-]?\\d++)?[fFdD]?";
- String hex = "(?:\\p{XDigit}++(?:\\.\\p{XDigit}*+)?|\\.\\p{XDigit}++)";
- String completeHex = "0[xX]" + hex + "[pP][+-]?\\d++[fFdD]?";
- String fpPattern = "[+-]?(?:NaN|Infinity|" + completeDec + "|" + completeHex + ")";
- return Pattern.compile(fpPattern);
- }
-
- /**
- * Parses the specified string as a double-precision floating point value.
- * The ASCII character {@code '-'} (<code>'&#92;u002D'</code>) is recognized
- * as the minus sign.
- *
- * <p>Unlike {@link Double#parseDouble(String)}, this method returns
- * {@code null} instead of throwing an exception if parsing fails.
- * Valid inputs are exactly those accepted by {@link Double#valueOf(String)},
- * except that leading and trailing whitespace is not permitted.
- *
- * <p>This implementation is likely to be faster than {@code
- * Double.parseDouble} if many failures are expected.
- *
- * @param string the string representation of a {@code double} value
- * @return the floating point value represented by {@code string}, or
- * {@code null} if {@code string} has a length of zero or cannot be
- * parsed as a {@code double} value
- * @since 14.0
- */
- @GwtIncompatible("regular expressions")
- @Nullable
- @Beta
- public static Double tryParse(String string) {
- if (FLOATING_POINT_PATTERN.matcher(string).matches()) {
- // TODO(user): could be potentially optimized, but only with
- // extensive testing
- try {
- return Double.parseDouble(string);
- } catch (NumberFormatException e) {
- // Double.parseDouble has changed specs several times, so fall through
- // gracefully
- }
- }
- return null;
- }
}
diff --git a/guava/src/com/google/common/primitives/Floats.java b/guava/src/com/google/common/primitives/Floats.java
index 03a1ed1..ffc932f 100644
--- a/guava/src/com/google/common/primitives/Floats.java
+++ b/guava/src/com/google/common/primitives/Floats.java
@@ -23,9 +23,7 @@ import static com.google.common.base.Preconditions.checkPositionIndexes;
import static java.lang.Float.NEGATIVE_INFINITY;
import static java.lang.Float.POSITIVE_INFINITY;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
import java.util.AbstractList;
@@ -36,20 +34,14 @@ import java.util.Comparator;
import java.util.List;
import java.util.RandomAccess;
-import javax.annotation.Nullable;
-
/**
* Static utility methods pertaining to {@code float} primitives, that are not
* already found in either {@link Float} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
-@GwtCompatible(emulated = true)
+@GwtCompatible
public final class Floats {
private Floats() {}
@@ -357,21 +349,20 @@ public final class Floats {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code float} value in the manner of {@link Number#floatValue}.
+ * Copies a collection of {@code Float} instances into a new array of
+ * primitive {@code float} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Float} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Float>} before 12.0)
*/
- public static float[] toArray(Collection<? extends Number> collection) {
+ public static float[] toArray(Collection<Float> collection) {
if (collection instanceof FloatArrayAsList) {
return ((FloatArrayAsList) collection).toFloatArray();
}
@@ -381,7 +372,7 @@ public final class Floats {
float[] array = new float[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).floatValue();
+ array[i] = (Float) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -471,8 +462,7 @@ public final class Floats {
@Override public Float set(int index, Float element) {
checkElementIndex(index, size());
float oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -523,7 +513,7 @@ public final class Floats {
}
float[] toFloatArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
float[] result = new float[size];
System.arraycopy(array, start, result, 0, size);
@@ -532,40 +522,4 @@ public final class Floats {
private static final long serialVersionUID = 0;
}
-
- /**
- * Parses the specified string as a single-precision floating point value.
- * The ASCII character {@code '-'} (<code>'&#92;u002D'</code>) is recognized
- * as the minus sign.
- *
- * <p>Unlike {@link Float#parseFloat(String)}, this method returns
- * {@code null} instead of throwing an exception if parsing fails.
- * Valid inputs are exactly those accepted by {@link Float#valueOf(String)},
- * except that leading and trailing whitespace is not permitted.
- *
- * <p>This implementation is likely to be faster than {@code
- * Float.parseFloat} if many failures are expected.
- *
- * @param string the string representation of a {@code float} value
- * @return the floating point value represented by {@code string}, or
- * {@code null} if {@code string} has a length of zero or cannot be
- * parsed as a {@code float} value
- * @since 14.0
- */
- @GwtIncompatible("regular expressions")
- @Nullable
- @Beta
- public static Float tryParse(String string) {
- if (Doubles.FLOATING_POINT_PATTERN.matcher(string).matches()) {
- // TODO(user): could be potentially optimized, but only with
- // extensive testing
- try {
- return Float.parseFloat(string);
- } catch (NumberFormatException e) {
- // Float.parseFloat has changed specs several times, so fall through
- // gracefully
- }
- }
- return null;
- }
}
diff --git a/guava/src/com/google/common/primitives/Ints.java b/guava/src/com/google/common/primitives/Ints.java
index 966066d..bc7acb8 100644
--- a/guava/src/com/google/common/primitives/Ints.java
+++ b/guava/src/com/google/common/primitives/Ints.java
@@ -40,10 +40,6 @@ import javax.annotation.CheckForNull;
* Static utility methods pertaining to {@code int} primitives, that are not
* already found in either {@link Integer} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -420,21 +416,20 @@ public final class Ints {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code int} value in the manner of {@link Number#intValue}.
+ * Copies a collection of {@code Integer} instances into a new array of
+ * primitive {@code int} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Integer} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Integer>} before 12.0)
*/
- public static int[] toArray(Collection<? extends Number> collection) {
+ public static int[] toArray(Collection<Integer> collection) {
if (collection instanceof IntArrayAsList) {
return ((IntArrayAsList) collection).toIntArray();
}
@@ -444,7 +439,7 @@ public final class Ints {
int[] array = new int[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).intValue();
+ array[i] = (Integer) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -531,8 +526,7 @@ public final class Ints {
@Override public Integer set(int index, Integer element) {
checkElementIndex(index, size());
int oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -583,7 +577,7 @@ public final class Ints {
}
int[] toIntArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
int[] result = new int[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava/src/com/google/common/primitives/Longs.java b/guava/src/com/google/common/primitives/Longs.java
index 9460316..99c7033 100644
--- a/guava/src/com/google/common/primitives/Longs.java
+++ b/guava/src/com/google/common/primitives/Longs.java
@@ -21,8 +21,8 @@ import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndexes;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
import java.util.AbstractList;
@@ -37,14 +37,10 @@ import java.util.RandomAccess;
* Static utility methods pertaining to {@code long} primitives, that are not
* already found in either {@link Long} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public final class Longs {
private Longs() {}
@@ -258,15 +254,17 @@ public final class Longs {
* {@link com.google.common.io.ByteStreams#newDataOutput()} to get a growable
* buffer.
*/
+ @GwtIncompatible("doesn't work")
public static byte[] toByteArray(long value) {
- // Note that this code needs to stay compatible with GWT, which has known
- // bugs when narrowing byte casts of long values occur.
- byte[] result = new byte[8];
- for (int i = 7; i >= 0; i--) {
- result[i] = (byte) (value & 0xffL);
- value >>= 8;
- }
- return result;
+ return new byte[] {
+ (byte) (value >> 56),
+ (byte) (value >> 48),
+ (byte) (value >> 40),
+ (byte) (value >> 32),
+ (byte) (value >> 24),
+ (byte) (value >> 16),
+ (byte) (value >> 8),
+ (byte) value};
}
/**
@@ -282,6 +280,7 @@ public final class Longs {
* @throws IllegalArgumentException if {@code bytes} has fewer than 8
* elements
*/
+ @GwtIncompatible("doesn't work")
public static long fromByteArray(byte[] bytes) {
checkArgument(bytes.length >= BYTES,
"array too small: %s < %s", bytes.length, BYTES);
@@ -296,6 +295,7 @@ public final class Longs {
*
* @since 7.0
*/
+ @GwtIncompatible("doesn't work")
public static long fromBytes(byte b1, byte b2, byte b3, byte b4,
byte b5, byte b6, byte b7, byte b8) {
return (b1 & 0xFFL) << 56
@@ -309,60 +309,6 @@ public final class Longs {
}
/**
- * Parses the specified string as a signed decimal long value. The ASCII
- * character {@code '-'} (<code>'&#92;u002D'</code>) is recognized as the
- * minus sign.
- *
- * <p>Unlike {@link Long#parseLong(String)}, this method returns
- * {@code null} instead of throwing an exception if parsing fails.
- *
- * <p>Note that strings prefixed with ASCII {@code '+'} are rejected, even
- * under JDK 7, despite the change to {@link Long#parseLong(String)} for
- * that version.
- *
- * @param string the string representation of a long value
- * @return the long value represented by {@code string}, or {@code null} if
- * {@code string} has a length of zero or cannot be parsed as a long
- * value
- * @since 14.0
- */
- @Beta
- public static Long tryParse(String string) {
- if (checkNotNull(string).isEmpty()) {
- return null;
- }
- boolean negative = string.charAt(0) == '-';
- int index = negative ? 1 : 0;
- if (index == string.length()) {
- return null;
- }
- int digit = string.charAt(index++) - '0';
- if (digit < 0 || digit > 9) {
- return null;
- }
- long accum = -digit;
- while (index < string.length()) {
- digit = string.charAt(index++) - '0';
- if (digit < 0 || digit > 9 || accum < Long.MIN_VALUE / 10) {
- return null;
- }
- accum *= 10;
- if (accum < Long.MIN_VALUE + digit) {
- return null;
- }
- accum -= digit;
- }
-
- if (negative) {
- return accum;
- } else if (accum == Long.MIN_VALUE) {
- return null;
- } else {
- return -accum;
- }
- }
-
- /**
* Returns an array containing the same values as {@code array}, but
* guaranteed to be of a specified minimum length. If {@code array} already
* has a length of at least {@code minLength}, it is returned directly.
@@ -455,21 +401,20 @@ public final class Longs {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code long} value in the manner of {@link Number#longValue}.
+ * Copies a collection of {@code Long} instances into a new array of
+ * primitive {@code long} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Long} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Long>} before 12.0)
*/
- public static long[] toArray(Collection<? extends Number> collection) {
+ public static long[] toArray(Collection<Long> collection) {
if (collection instanceof LongArrayAsList) {
return ((LongArrayAsList) collection).toLongArray();
}
@@ -479,7 +424,7 @@ public final class Longs {
long[] array = new long[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).longValue();
+ array[i] = (Long) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -566,8 +511,7 @@ public final class Longs {
@Override public Long set(int index, Long element) {
checkElementIndex(index, size());
long oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -618,7 +562,7 @@ public final class Longs {
}
long[] toLongArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
long[] result = new long[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava/src/com/google/common/primitives/ParseRequest.java b/guava/src/com/google/common/primitives/ParseRequest.java
deleted file mode 100644
index 98f29b4..0000000
--- a/guava/src/com/google/common/primitives/ParseRequest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.primitives;
-
-import com.google.common.annotations.GwtCompatible;
-
-/**
- * A string to be parsed as a number and the radix to interpret it in.
- */
-@GwtCompatible
-final class ParseRequest {
- final String rawValue;
- final int radix;
-
- private ParseRequest(String rawValue, int radix) {
- this.rawValue = rawValue;
- this.radix = radix;
- }
-
- static ParseRequest fromString(String stringValue) {
- if (stringValue.length() == 0) {
- throw new NumberFormatException("empty string");
- }
-
- // Handle radix specifier if present
- String rawValue;
- int radix;
- char firstChar = stringValue.charAt(0);
- if (stringValue.startsWith("0x") || stringValue.startsWith("0X")) {
- rawValue = stringValue.substring(2);
- radix = 16;
- } else if (firstChar == '#') {
- rawValue = stringValue.substring(1);
- radix = 16;
- } else if (firstChar == '0' && stringValue.length() > 1) {
- rawValue = stringValue.substring(1);
- radix = 8;
- } else {
- rawValue = stringValue;
- radix = 10;
- }
-
- return new ParseRequest(rawValue, radix);
- }
-}
diff --git a/guava/src/com/google/common/primitives/Shorts.java b/guava/src/com/google/common/primitives/Shorts.java
index db3d206..d5859b3 100644
--- a/guava/src/com/google/common/primitives/Shorts.java
+++ b/guava/src/com/google/common/primitives/Shorts.java
@@ -37,10 +37,6 @@ import java.util.RandomAccess;
* Static utility methods pertaining to {@code short} primitives, that are not
* already found in either {@link Short} or {@link Arrays}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @since 1.0
*/
@@ -418,21 +414,20 @@ public final class Shorts {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code short} value in the manner of {@link Number#shortValue}.
+ * Copies a collection of {@code Short} instances into a new array of
+ * primitive {@code short} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code Short} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Short>} before 12.0)
*/
- public static short[] toArray(Collection<? extends Number> collection) {
+ public static short[] toArray(Collection<Short> collection) {
if (collection instanceof ShortArrayAsList) {
return ((ShortArrayAsList) collection).toShortArray();
}
@@ -442,7 +437,7 @@ public final class Shorts {
short[] array = new short[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).shortValue();
+ array[i] = (Short) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -529,8 +524,7 @@ public final class Shorts {
@Override public Short set(int index, Short element) {
checkElementIndex(index, size());
short oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
@@ -581,7 +575,7 @@ public final class Shorts {
}
short[] toShortArray() {
- // Arrays.copyOfRange() is not available under GWT
+ // Arrays.copyOfRange() requires Java 6
int size = size();
short[] result = new short[size];
System.arraycopy(array, start, result, 0, size);
diff --git a/guava/src/com/google/common/primitives/SignedBytes.java b/guava/src/com/google/common/primitives/SignedBytes.java
index 07e3bda..00a36d8 100644
--- a/guava/src/com/google/common/primitives/SignedBytes.java
+++ b/guava/src/com/google/common/primitives/SignedBytes.java
@@ -28,10 +28,6 @@ import java.util.Comparator;
* interpret values as signed. The corresponding methods that treat the values
* as unsigned are found in {@link UnsignedBytes}, and the methods for which
* signedness is not an issue are in {@link Bytes}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
*
* @author Kevin Bourrillion
* @since 1.0
diff --git a/guava/src/com/google/common/primitives/UnsignedBytes.java b/guava/src/com/google/common/primitives/UnsignedBytes.java
index c503f99..1651295 100644
--- a/guava/src/com/google/common/primitives/UnsignedBytes.java
+++ b/guava/src/com/google/common/primitives/UnsignedBytes.java
@@ -19,12 +19,16 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
-import sun.misc.Unsafe;
+// BEGIN android-changed
+//import sun.misc.Unsafe;
+// END android-changed
+import java.lang.reflect.Field;
import java.nio.ByteOrder;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Comparator;
/**
@@ -34,35 +38,20 @@ import java.util.Comparator;
* the values as signed are found in {@link SignedBytes}, and the methods for
* which signedness is not an issue are in {@link Bytes}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
- *
* @author Kevin Bourrillion
* @author Martin Buchholz
* @author Hiroshi Yamauchi
- * @author Louis Wasserman
* @since 1.0
*/
public final class UnsignedBytes {
private UnsignedBytes() {}
/**
- * The largest power of two that can be represented as an unsigned {@code
- * byte}.
+ * The largest power of two that can be represented as an unsigned {@code byte}.
*
* @since 10.0
*/
- public static final byte MAX_POWER_OF_TWO = (byte) 0x80;
-
- /**
- * The largest value that fits into an unsigned byte.
- *
- * @since 13.0
- */
- public static final byte MAX_VALUE = (byte) 0xFF;
-
- private static final int UNSIGNED_MASK = 0xFF;
+ public static final byte MAX_POWER_OF_TWO = (byte) (1 << 7);
/**
* Returns the value of the given byte as an integer, when treated as
@@ -72,7 +61,7 @@ public final class UnsignedBytes {
* @since 6.0
*/
public static int toInt(byte value) {
- return value & UNSIGNED_MASK;
+ return value & 0xFF;
}
/**
@@ -86,7 +75,7 @@ public final class UnsignedBytes {
* than 255
*/
public static byte checkedCast(long value) {
- checkArgument(value >> Byte.SIZE == 0, "out of range: %s", value);
+ checkArgument(value >> 8 == 0, "out of range: %s", value);
return (byte) value;
}
@@ -99,8 +88,8 @@ public final class UnsignedBytes {
* {@code value <= 0}, and {@code value} cast to {@code byte} otherwise
*/
public static byte saturatedCast(long value) {
- if (value > toInt(MAX_VALUE)) {
- return MAX_VALUE; // -1
+ if (value > 255) {
+ return (byte) 255; // -1
}
if (value < 0) {
return (byte) 0;
@@ -164,71 +153,6 @@ public final class UnsignedBytes {
}
/**
- * Returns a string representation of x, where x is treated as unsigned.
- *
- * @since 13.0
- */
- @Beta
- public static String toString(byte x) {
- return toString(x, 10);
- }
-
- /**
- * Returns a string representation of {@code x} for the given radix, where {@code x} is treated
- * as unsigned.
- *
- * @param x the value to convert to a string.
- * @param radix the radix to use while working with {@code x}
- * @throws IllegalArgumentException if {@code radix} is not between {@link Character#MIN_RADIX}
- * and {@link Character#MAX_RADIX}.
- * @since 13.0
- */
- @Beta
- public static String toString(byte x, int radix) {
- checkArgument(radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX,
- "radix (%s) must be between Character.MIN_RADIX and Character.MAX_RADIX", radix);
- // Benchmarks indicate this is probably not worth optimizing.
- return Integer.toString(toInt(x), radix);
- }
-
- /**
- * Returns the unsigned {@code byte} value represented by the given decimal string.
- *
- * @throws NumberFormatException if the string does not contain a valid unsigned {@code byte}
- * value
- * @throws NullPointerException if {@code s} is null
- * (in contrast to {@link Byte#parseByte(String)})
- * @since 13.0
- */
- @Beta
- public static byte parseUnsignedByte(String string) {
- return parseUnsignedByte(string, 10);
- }
-
- /**
- * Returns the unsigned {@code byte} value represented by a string with the given radix.
- *
- * @param string the string containing the unsigned {@code byte} representation to be parsed.
- * @param radix the radix to use while parsing {@code string}
- * @throws NumberFormatException if the string does not contain a valid unsigned {@code byte}
- * with the given radix, or if {@code radix} is not between {@link Character#MIN_RADIX}
- * and {@link Character#MAX_RADIX}.
- * @throws NullPointerException if {@code s} is null
- * (in contrast to {@link Byte#parseByte(String)})
- * @since 13.0
- */
- @Beta
- public static byte parseUnsignedByte(String string, int radix) {
- int parse = Integer.parseInt(checkNotNull(string), radix);
- // We need to throw a NumberFormatException, so we have to duplicate checkedCast. =(
- if (parse >> Byte.SIZE == 0) {
- return (byte) parse;
- } else {
- throw new NumberFormatException("out of range: " + parse);
- }
- }
-
- /**
* Returns a string containing the supplied {@code byte} values separated by
* {@code separator}. For example, {@code join(":", (byte) 1, (byte) 2,
* (byte) 255)} returns the string {@code "1:2:255"}.
@@ -244,10 +168,10 @@ public final class UnsignedBytes {
}
// For pre-sizing a builder, just get the right order of magnitude
- StringBuilder builder = new StringBuilder(array.length * (3 + separator.length()));
+ StringBuilder builder = new StringBuilder(array.length * 5);
builder.append(toInt(array[0]));
for (int i = 1; i < array.length; i++) {
- builder.append(separator).append(toString(array[i]));
+ builder.append(separator).append(toInt(array[i]));
}
return builder.toString();
}
@@ -289,133 +213,123 @@ public final class UnsignedBytes {
static final String UNSAFE_COMPARATOR_NAME =
LexicographicalComparatorHolder.class.getName() + "$UnsafeComparator";
- static final Comparator<byte[]> BEST_COMPARATOR = getBestComparator();
-
- @VisibleForTesting
- enum UnsafeComparator implements Comparator<byte[]> {
- INSTANCE;
-
- static final boolean littleEndian =
- ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
-
- /*
- * The following static final fields exist for performance reasons.
- *
- * In UnsignedBytesBenchmark, accessing the following objects via static
- * final fields is the fastest (more than twice as fast as the Java
- * implementation, vs ~1.5x with non-final static fields, on x86_32)
- * under the Hotspot server compiler. The reason is obviously that the
- * non-final fields need to be reloaded inside the loop.
- *
- * And, no, defining (final or not) local variables out of the loop still
- * isn't as good because the null check on the theUnsafe object remains
- * inside the loop and BYTE_ARRAY_BASE_OFFSET doesn't get
- * constant-folded.
- *
- * The compiler can treat static final fields as compile-time constants
- * and can constant-fold them while (final or not) local variables are
- * run time values.
- */
-
- static final Unsafe theUnsafe;
-
- /** The offset to the first element in a byte array. */
- static final int BYTE_ARRAY_BASE_OFFSET;
-
- static {
- theUnsafe = getUnsafe();
-
- BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
-
- // sanity check - this should never fail
- if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
- throw new AssertionError();
- }
- }
-
- /**
- * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
- * Replace with a simple call to Unsafe.getUnsafe when integrating
- * into a jdk.
- *
- * @return a sun.misc.Unsafe
- */
- private static sun.misc.Unsafe getUnsafe() {
- try {
- return sun.misc.Unsafe.getUnsafe();
- } catch (SecurityException tryReflectionInstead) {}
- try {
- return java.security.AccessController.doPrivileged
- (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
- public sun.misc.Unsafe run() throws Exception {
- Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
- for (java.lang.reflect.Field f : k.getDeclaredFields()) {
- f.setAccessible(true);
- Object x = f.get(null);
- if (k.isInstance(x))
- return k.cast(x);
- }
- throw new NoSuchFieldError("the Unsafe");
- }});
- } catch (java.security.PrivilegedActionException e) {
- throw new RuntimeException("Could not initialize intrinsics",
- e.getCause());
- }
- }
-
- @Override public int compare(byte[] left, byte[] right) {
- int minLength = Math.min(left.length, right.length);
- int minWords = minLength / Longs.BYTES;
-
- /*
- * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a
- * time is no slower than comparing 4 bytes at a time even on 32-bit.
- * On the other hand, it is substantially faster on 64-bit.
- */
- for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) {
- long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
- long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
- long diff = lw ^ rw;
-
- if (diff != 0) {
- if (!littleEndian) {
- return UnsignedLongs.compare(lw, rw);
- }
-
- // Use binary search
- int n = 0;
- int y;
- int x = (int) diff;
- if (x == 0) {
- x = (int) (diff >>> 32);
- n = 32;
- }
-
- y = x << 16;
- if (y == 0) {
- n += 16;
- } else {
- x = y;
- }
-
- y = x << 8;
- if (y == 0) {
- n += 8;
- }
- return (int) (((lw >>> n) & UNSIGNED_MASK) - ((rw >>> n) & UNSIGNED_MASK));
- }
- }
-
- // The epilogue to cover the last (minLength % 8) elements.
- for (int i = minWords * Longs.BYTES; i < minLength; i++) {
- int result = UnsignedBytes.compare(left[i], right[i]);
- if (result != 0) {
- return result;
- }
- }
- return left.length - right.length;
- }
- }
+ // BEGIN android-changed
+
+ static final Comparator<byte[]> BEST_COMPARATOR = lexicographicalComparatorJavaImpl();
+
+ // @VisibleForTesting
+ // enum UnsafeComparator implements Comparator<byte[]> {
+ // INSTANCE;
+
+ // static final boolean littleEndian =
+ // ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
+
+ // /*
+ // * The following static final fields exist for performance reasons.
+ // *
+ // * In UnsignedBytesBenchmark, accessing the following objects via static
+ // * final fields is the fastest (more than twice as fast as the Java
+ // * implementation, vs ~1.5x with non-final static fields, on x86_32)
+ // * under the Hotspot server compiler. The reason is obviously that the
+ // * non-final fields need to be reloaded inside the loop.
+ // *
+ // * And, no, defining (final or not) local variables out of the loop still
+ // * isn't as good because the null check on the theUnsafe object remains
+ // * inside the loop and BYTE_ARRAY_BASE_OFFSET doesn't get
+ // * constant-folded.
+ // *
+ // * The compiler can treat static final fields as compile-time constants
+ // * and can constant-fold them while (final or not) local variables are
+ // * run time values.
+ // */
+
+ // static final Unsafe theUnsafe;
+
+ // /** The offset to the first element in a byte array. */
+ // static final int BYTE_ARRAY_BASE_OFFSET;
+
+ // static {
+ // theUnsafe = (Unsafe) AccessController.doPrivileged(
+ // new PrivilegedAction<Object>() {
+ // @Override
+ // public Object run() {
+ // try {
+ // Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ // f.setAccessible(true);
+ // return f.get(null);
+ // } catch (NoSuchFieldException e) {
+ // // It doesn't matter what we throw;
+ // // it's swallowed in getBestComparator().
+ // throw new Error();
+ // } catch (IllegalAccessException e) {
+ // throw new Error();
+ // }
+ // }
+ // });
+
+ // BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
+
+ // // sanity check - this should never fail
+ // if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
+ // throw new AssertionError();
+ // }
+ // }
+
+ // @Override public int compare(byte[] left, byte[] right) {
+ // int minLength = Math.min(left.length, right.length);
+ // int minWords = minLength / Longs.BYTES;
+
+ // /*
+ // * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a
+ // * time is no slower than comparing 4 bytes at a time even on 32-bit.
+ // * On the other hand, it is substantially faster on 64-bit.
+ // */
+ // for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) {
+ // long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
+ // long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
+ // long diff = lw ^ rw;
+
+ // if (diff != 0) {
+ // if (!littleEndian) {
+ // return UnsignedLongs.compare(lw, rw);
+ // }
+
+ // // Use binary search
+ // int n = 0;
+ // int y;
+ // int x = (int) diff;
+ // if (x == 0) {
+ // x = (int) (diff >>> 32);
+ // n = 32;
+ // }
+
+ // y = x << 16;
+ // if (y == 0) {
+ // n += 16;
+ // } else {
+ // x = y;
+ // }
+
+ // y = x << 8;
+ // if (y == 0) {
+ // n += 8;
+ // }
+ // return (int) (((lw >>> n) & 0xFFL) - ((rw >>> n) & 0xFFL));
+ // }
+ // }
+
+ // // The epilogue to cover the last (minLength % 8) elements.
+ // for (int i = minWords * Longs.BYTES; i < minLength; i++) {
+ // int result = UnsignedBytes.compare(left[i], right[i]);
+ // if (result != 0) {
+ // return result;
+ // }
+ // }
+ // return left.length - right.length;
+ // }
+ // }
+
+ // END android-changed
enum PureJavaComparator implements Comparator<byte[]> {
INSTANCE;
@@ -432,22 +346,28 @@ public final class UnsignedBytes {
}
}
- /**
- * Returns the Unsafe-using Comparator, or falls back to the pure-Java
- * implementation if unable to do so.
- */
- static Comparator<byte[]> getBestComparator() {
- try {
- Class<?> theClass = Class.forName(UNSAFE_COMPARATOR_NAME);
-
- // yes, UnsafeComparator does implement Comparator<byte[]>
- @SuppressWarnings("unchecked")
- Comparator<byte[]> comparator =
- (Comparator<byte[]>) theClass.getEnumConstants()[0];
- return comparator;
- } catch (Throwable t) { // ensure we really catch *everything*
- return lexicographicalComparatorJavaImpl();
- }
- }
+ // BEGIN android-changed
+
+ // /**
+ // * Returns the Unsafe-using Comparator, or falls back to the pure-Java
+ // * implementation if unable to do so.
+ // */
+ // static Comparator<byte[]> getBestComparator() {
+ // try {
+ // Class<?> theClass = Class.forName(UNSAFE_COMPARATOR_NAME);
+
+ // // yes, UnsafeComparator does implement Comparator<byte[]>
+ // @SuppressWarnings("unchecked")
+ // Comparator<byte[]> comparator =
+ // (Comparator<byte[]>) theClass.getEnumConstants()[0];
+ // return comparator;
+ // } catch (Throwable t) { // ensure we really catch *everything*
+ // return lexicographicalComparatorJavaImpl();
+ // }
+ // }
+
+ // END android-changed
+
}
}
+
diff --git a/guava/src/com/google/common/primitives/UnsignedInteger.java b/guava/src/com/google/common/primitives/UnsignedInteger.java
index 88d89b5..d64ff88 100644
--- a/guava/src/com/google/common/primitives/UnsignedInteger.java
+++ b/guava/src/com/google/common/primitives/UnsignedInteger.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -20,28 +20,24 @@ import static com.google.common.primitives.UnsignedInts.INT_MASK;
import static com.google.common.primitives.UnsignedInts.compare;
import static com.google.common.primitives.UnsignedInts.toLong;
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
import java.math.BigInteger;
-import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
/**
* A wrapper class for unsigned {@code int} values, supporting arithmetic operations.
- *
+ *
* <p>In some cases, when speed is more important than code readability, it may be faster simply to
* treat primitive {@code int} values as unsigned, using the methods from {@link UnsignedInts}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
- * unsigned primitive utilities</a>.
- *
+ *
* @author Louis Wasserman
* @since 11.0
*/
+@Beta
@GwtCompatible(emulated = true)
public final class UnsignedInteger extends Number implements Comparable<UnsignedInteger> {
public static final UnsignedInteger ZERO = asUnsigned(0);
@@ -51,37 +47,15 @@ public final class UnsignedInteger extends Number implements Comparable<Unsigned
private final int value;
private UnsignedInteger(int value) {
- // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
this.value = value & 0xffffffff;
}
/**
* Returns an {@code UnsignedInteger} that, when treated as signed, is
* equal to {@code value}.
- *
- * @deprecated Use {@link #fromIntBits(int)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public static UnsignedInteger asUnsigned(int value) {
- return fromIntBits(value);
- }
-
- /**
- * Returns an {@code UnsignedInteger} corresponding to a given bit representation.
- * The argument is interpreted as an unsigned 32-bit value. Specifically, the sign bit
- * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual.
- *
- * <p>If the argument is nonnegative, the returned result will be equal to {@code bits},
- * otherwise, the result will be equal to {@code 2^32 + bits}.
- *
- * <p>To represent unsigned decimal constants, consider {@link #valueOf(long)} instead.
- *
- * @since 14.0
- */
- public static UnsignedInteger fromIntBits(int bits) {
- return new UnsignedInteger(bits);
+ return new UnsignedInteger(value);
}
/**
@@ -91,26 +65,26 @@ public final class UnsignedInteger extends Number implements Comparable<Unsigned
public static UnsignedInteger valueOf(long value) {
checkArgument((value & INT_MASK) == value,
"value (%s) is outside the range for an unsigned integer value", value);
- return fromIntBits((int) value);
+ return asUnsigned((int) value);
}
/**
* Returns a {@code UnsignedInteger} representing the same value as the specified
* {@link BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
- *
+ *
* @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^32}
*/
public static UnsignedInteger valueOf(BigInteger value) {
checkNotNull(value);
checkArgument(value.signum() >= 0 && value.bitLength() <= Integer.SIZE,
"value (%s) is outside the range for an unsigned integer value", value);
- return fromIntBits(value.intValue());
+ return asUnsigned(value.intValue());
}
/**
* Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
* as an unsigned {@code int} value.
- *
+ *
* @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
* value
*/
@@ -121,139 +95,62 @@ public final class UnsignedInteger extends Number implements Comparable<Unsigned
/**
* Returns an {@code UnsignedInteger} holding the value of the specified {@code String}, parsed
* as an unsigned {@code int} value in the specified radix.
- *
+ *
* @throws NumberFormatException if the string does not contain a parsable unsigned {@code int}
* value
*/
public static UnsignedInteger valueOf(String string, int radix) {
- return fromIntBits(UnsignedInts.parseUnsignedInt(string, radix));
+ return asUnsigned(UnsignedInts.parseUnsignedInt(string, radix));
}
/**
* Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
* returns the low 32 bits of the result.
- *
- * @deprecated Use {@link #plus(UnsignedInteger)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedInteger add(UnsignedInteger val) {
- return plus(val);
- }
-
- /**
- * Returns the result of adding this and {@code val}. If the result would have more than 32 bits,
- * returns the low 32 bits of the result.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger plus(UnsignedInteger val) {
- return fromIntBits(this.value + checkNotNull(val).value);
+ checkNotNull(val);
+ return asUnsigned(this.value + val.value);
}
/**
* Returns the result of subtracting this and {@code val}. If the result would be negative,
* returns the low 32 bits of the result.
- *
- * @deprecated Use {@link #minus(UnsignedInteger)}. This method is scheduled to be removed in
- * Guava release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedInteger subtract(UnsignedInteger val) {
- return minus(val);
- }
-
- /**
- * Returns the result of subtracting this and {@code val}. If the result would be negative,
- * returns the low 32 bits of the result.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger minus(UnsignedInteger val) {
- return fromIntBits(value - checkNotNull(val).value);
+ checkNotNull(val);
+ return asUnsigned(this.value - val.value);
}
/**
* Returns the result of multiplying this and {@code val}. If the result would have more than 32
* bits, returns the low 32 bits of the result.
- *
- * @deprecated Use {@link #times(UnsignedInteger)}. This method is scheduled to be removed in
- * Guava release 15.0.
*/
- @Deprecated
- @Beta
@GwtIncompatible("Does not truncate correctly")
public UnsignedInteger multiply(UnsignedInteger val) {
- return times(val);
- }
-
- /**
- * Returns the result of multiplying this and {@code val}. If the result would have more than 32
- * bits, returns the low 32 bits of the result.
- *
- * @since 14.0
- */
- @CheckReturnValue
- @GwtIncompatible("Does not truncate correctly")
- public UnsignedInteger times(UnsignedInteger val) {
- // TODO(user): make this GWT-compatible
- return fromIntBits(value * checkNotNull(val).value);
+ checkNotNull(val);
+ return asUnsigned(value * val.value);
}
/**
* Returns the result of dividing this by {@code val}.
- *
- * @deprecated Use {@link #dividedBy(UnsignedInteger)}. This method is scheduled to be removed in
- * Guava release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedInteger divide(UnsignedInteger val) {
- return dividedBy(val);
- }
-
- /**
- * Returns the result of dividing this by {@code val}.
- *
- * @throws ArithmeticException if {@code val} is zero
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger dividedBy(UnsignedInteger val) {
- return fromIntBits(UnsignedInts.divide(value, checkNotNull(val).value));
+ checkNotNull(val);
+ return asUnsigned(UnsignedInts.divide(value, val.value));
}
/**
* Returns the remainder of dividing this by {@code val}.
- *
- * @deprecated Use {@link #mod(UnsignedInteger)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedInteger remainder(UnsignedInteger val) {
- return mod(val);
- }
-
- /**
- * Returns this mod {@code val}.
- *
- * @throws ArithmeticException if {@code val} is zero
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedInteger mod(UnsignedInteger val) {
- return fromIntBits(UnsignedInts.remainder(value, checkNotNull(val).value));
+ checkNotNull(val);
+ return asUnsigned(UnsignedInts.remainder(value, val.value));
}
/**
* Returns the value of this {@code UnsignedInteger} as an {@code int}. This is an inverse
- * operation to {@link #fromIntBits}.
- *
+ * operation to {@link #asUnsigned}.
+ *
* <p>Note that if this {@code UnsignedInteger} holds a value {@code >= 2^31}, the returned value
* will be equal to {@code this - 2^32}.
*/
diff --git a/guava/src/com/google/common/primitives/UnsignedInts.java b/guava/src/com/google/common/primitives/UnsignedInts.java
index 762b841..222d9f3 100644
--- a/guava/src/com/google/common/primitives/UnsignedInts.java
+++ b/guava/src/com/google/common/primitives/UnsignedInts.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -17,30 +17,26 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
import java.util.Arrays;
import java.util.Comparator;
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
/**
* Static utility methods pertaining to {@code int} primitives that interpret values as
* <i>unsigned</i> (that is, any negative value {@code x} is treated as the positive value
* {@code 2^32 + x}). The methods for which signedness is not an issue are in {@link Ints}, as well
* as signed versions of methods for which signedness is an issue.
- *
+ *
* <p>In addition, this class provides several static methods for converting an {@code int} to a
* {@code String} and a {@code String} to an {@code int} that treat the {@code int} as an unsigned
* number.
- *
+ *
* <p>Users of these utilities must be <i>extremely careful</i> not to mix up signed and unsigned
* {@code int} values. When possible, it is recommended that the {@link UnsignedInteger} wrapper
* class be used, at a small efficiency penalty, to enforce the distinction in the type system.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
- * unsigned primitive utilities</a>.
- *
+ *
* @author Louis Wasserman
* @since 11.0
*/
@@ -58,7 +54,7 @@ public final class UnsignedInts {
/**
* Compares the two specified {@code int} values, treating them as unsigned values between
* {@code 0} and {@code 2^32 - 1} inclusive.
- *
+ *
* @param a the first unsigned {@code int} to compare
* @param b the second unsigned {@code int} to compare
* @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is
@@ -77,7 +73,7 @@ public final class UnsignedInts {
/**
* Returns the least value present in {@code array}, treating values as unsigned.
- *
+ *
* @param array a <i>nonempty</i> array of unsigned {@code int} values
* @return the value present in {@code array} that is less than or equal to every other value in
* the array according to {@link #compare}
@@ -97,7 +93,7 @@ public final class UnsignedInts {
/**
* Returns the greatest value present in {@code array}, treating values as unsigned.
- *
+ *
* @param array a <i>nonempty</i> array of unsigned {@code int} values
* @return the value present in {@code array} that is greater than or equal to every other value
* in the array according to {@link #compare}
@@ -118,7 +114,7 @@ public final class UnsignedInts {
/**
* Returns a string containing the supplied unsigned {@code int} values separated by
* {@code separator}. For example, {@code join("-", 1, 2, 3)} returns the string {@code "1-2-3"}.
- *
+ *
* @param separator the text that should appear between consecutive values in the resulting
* string (but not at the start or end)
* @param array an array of unsigned {@code int} values, possibly empty
@@ -131,7 +127,7 @@ public final class UnsignedInts {
// For pre-sizing a builder, just get the right order of magnitude
StringBuilder builder = new StringBuilder(array.length * 5);
- builder.append(toString(array[0]));
+ builder.append(array[0]);
for (int i = 1; i < array.length; i++) {
builder.append(separator).append(toString(array[i]));
}
@@ -143,10 +139,10 @@ public final class UnsignedInts {
* That is, it compares, using {@link #compare(int, int)}), the first pair of values that follow
* any common prefix, or when one array is a prefix of the other, treats the shorter array as the
* lesser. For example, {@code [] < [1] < [1, 2] < [2] < [1 << 31]}.
- *
+ *
* <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays
* support only identity equality), but it is consistent with {@link Arrays#equals(int[], int[])}.
- *
+ *
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order"> Lexicographical order
* article at Wikipedia</a>
*/
@@ -172,7 +168,7 @@ public final class UnsignedInts {
/**
* Returns dividend / divisor, where the dividend and divisor are treated as unsigned 32-bit
* quantities.
- *
+ *
* @param dividend the dividend (numerator)
* @param divisor the divisor (denominator)
* @throws ArithmeticException if divisor is 0
@@ -184,7 +180,7 @@ public final class UnsignedInts {
/**
* Returns dividend % divisor, where the dividend and divisor are treated as unsigned 32-bit
* quantities.
- *
+ *
* @param dividend the dividend (numerator)
* @param divisor the divisor (denominator)
* @throws ArithmeticException if divisor is 0
@@ -194,39 +190,11 @@ public final class UnsignedInts {
}
/**
- * Returns the unsigned {@code int} value represented by the given string.
- *
- * Accepts a decimal, hexadecimal, or octal number given by specifying the following prefix:
- *
- * <ul>
- * <li>{@code 0x}<i>HexDigits</i>
- * <li>{@code 0X}<i>HexDigits</i>
- * <li>{@code #}<i>HexDigits</i>
- * <li>{@code 0}<i>OctalDigits</i>
- * </ul>
- *
- * @throws NumberFormatException if the string does not contain a valid unsigned {@code int} value
- * @since 13.0
- */
- public static int decode(String stringValue) {
- ParseRequest request = ParseRequest.fromString(stringValue);
-
- try {
- return parseUnsignedInt(request.rawValue, request.radix);
- } catch (NumberFormatException e) {
- NumberFormatException decodeException =
- new NumberFormatException("Error parsing value: " + stringValue);
- decodeException.initCause(e);
- throw decodeException;
- }
- }
-
- /**
* Returns the unsigned {@code int} value represented by the given decimal string.
- *
- * @throws NumberFormatException if the string does not contain a valid unsigned {@code int} value
- * @throws NullPointerException if {@code s} is null
- * (in contrast to {@link Integer#parseInt(String)})
+ *
+ * @throws NumberFormatException if the string does not contain a valid unsigned integer, or if
+ * the value represented is too large to fit in an unsigned {@code int}.
+ * @throws NullPointerException if {@code s} is null
*/
public static int parseUnsignedInt(String s) {
return parseUnsignedInt(s, 10);
@@ -234,14 +202,12 @@ public final class UnsignedInts {
/**
* Returns the unsigned {@code int} value represented by a string with the given radix.
- *
+ *
* @param string the string containing the unsigned integer representation to be parsed.
* @param radix the radix to use while parsing {@code s}; must be between
* {@link Character#MIN_RADIX} and {@link Character#MAX_RADIX}.
* @throws NumberFormatException if the string does not contain a valid unsigned {@code int}, or
* if supplied radix is invalid.
- * @throws NullPointerException if {@code s} is null
- * (in contrast to {@link Integer#parseInt(String)})
*/
public static int parseUnsignedInt(String string, int radix) {
checkNotNull(string);
@@ -263,7 +229,7 @@ public final class UnsignedInts {
/**
* Returns a string representation of {@code x} for the given radix, where {@code x} is treated
* as unsigned.
- *
+ *
* @param x the value to convert to a string.
* @param radix the radix to use while working with {@code x}
* @throws IllegalArgumentException if {@code radix} is not between {@link Character#MIN_RADIX}
diff --git a/guava/src/com/google/common/primitives/UnsignedLong.java b/guava/src/com/google/common/primitives/UnsignedLong.java
index a48de6b..62f7f81 100644
--- a/guava/src/com/google/common/primitives/UnsignedLong.java
+++ b/guava/src/com/google/common/primitives/UnsignedLong.java
@@ -17,31 +17,30 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
import java.io.Serializable;
import java.math.BigInteger;
-import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
/**
* A wrapper class for unsigned {@code long} values, supporting arithmetic operations.
*
* <p>In some cases, when speed is more important than code readability, it may be faster simply to
* treat primitive {@code long} values as unsigned, using the methods from {@link UnsignedLongs}.
*
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
- * unsigned primitive utilities</a>.
+ * <p><b>Please do not extend this class; it will be made final in the near future.</b>
*
* @author Louis Wasserman
* @author Colin Evans
* @since 11.0
*/
+@Beta
@GwtCompatible(serializable = true)
-public final class UnsignedLong extends Number implements Comparable<UnsignedLong>, Serializable {
+public class UnsignedLong extends Number implements Comparable<UnsignedLong>, Serializable {
+ // TODO(user): make final as soon as util.UnsignedLong is migrated over
private static final long UNSIGNED_MASK = 0x7fffffffffffffffL;
@@ -51,7 +50,7 @@ public final class UnsignedLong extends Number implements Comparable<UnsignedLon
private final long value;
- private UnsignedLong(long value) {
+ protected UnsignedLong(long value) {
this.value = value;
}
@@ -61,49 +60,14 @@ public final class UnsignedLong extends Number implements Comparable<UnsignedLon
*
* <p>Put another way, if {@code value} is negative, the returned result will be equal to
* {@code 2^64 + value}; otherwise, the returned result will be equal to {@code value}.
- *
- * @deprecated Use {@link #fromLongBits(long)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public static UnsignedLong asUnsigned(long value) {
- return fromLongBits(value);
- }
-
- /**
- * Returns an {@code UnsignedLong} corresponding to a given bit representation.
- * The argument is interpreted as an unsigned 64-bit value. Specifically, the sign bit
- * of {@code bits} is interpreted as a normal bit, and all other bits are treated as usual.
- *
- * <p>If the argument is nonnegative, the returned result will be equal to {@code bits},
- * otherwise, the result will be equal to {@code 2^64 + bits}.
- *
- * <p>To represent decimal constants less than {@code 2^63}, consider {@link #valueOf(long)}
- * instead.
- *
- * @since 14.0
- */
- public static UnsignedLong fromLongBits(long bits) {
- // TODO(user): consider caching small values, like Long.valueOf
- return new UnsignedLong(bits);
+ return new UnsignedLong(value);
}
/**
- * Returns an {@code UnsignedLong} representing the same value as the specified {@code long}.
- *
- * @throws IllegalArgumentException if {@code value} is negative
- * @since 14.0
- */
- public static UnsignedLong valueOf(long value) {
- checkArgument(value >= 0,
- "value (%s) is outside the range for an unsigned long value", value);
- return fromLongBits(value);
- }
-
- /**
- * Returns a {@code UnsignedLong} representing the same value as the specified
- * {@code BigInteger}. This is the inverse operation of {@link #bigIntegerValue()}.
+ * Returns a {@code UnsignedLong} representing the same value as the specified {@code BigInteger}
+ * . This is the inverse operation of {@link #bigIntegerValue()}.
*
* @throws IllegalArgumentException if {@code value} is negative or {@code value >= 2^64}
*/
@@ -111,7 +75,7 @@ public final class UnsignedLong extends Number implements Comparable<UnsignedLon
checkNotNull(value);
checkArgument(value.signum() >= 0 && value.bitLength() <= Long.SIZE,
"value (%s) is outside the range for an unsigned long value", value);
- return fromLongBits(value.longValue());
+ return asUnsigned(value.longValue());
}
/**
@@ -134,121 +98,50 @@ public final class UnsignedLong extends Number implements Comparable<UnsignedLon
* {@link Character#MAX_RADIX}
*/
public static UnsignedLong valueOf(String string, int radix) {
- return fromLongBits(UnsignedLongs.parseUnsignedLong(string, radix));
+ return asUnsigned(UnsignedLongs.parseUnsignedLong(string, radix));
}
/**
* Returns the result of adding this and {@code val}. If the result would have more than 64 bits,
* returns the low 64 bits of the result.
- *
- * @deprecated Use {@link #plus(UnsignedLong)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedLong add(UnsignedLong val) {
- return plus(val);
- }
-
- /**
- * Returns the result of adding this and {@code val}. If the result would have more than 64 bits,
- * returns the low 64 bits of the result.
- *
- * @since 14.0
- */
- public UnsignedLong plus(UnsignedLong val) {
- return fromLongBits(this.value + checkNotNull(val).value);
+ checkNotNull(val);
+ return asUnsigned(this.value + val.value);
}
/**
* Returns the result of subtracting this and {@code val}. If the result would be negative,
* returns the low 64 bits of the result.
- *
- * @deprecated Use {@link #minus(UnsignedLong)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedLong subtract(UnsignedLong val) {
- return minus(val);
- }
-
- /**
- * Returns the result of subtracting this and {@code val}. If the result would have more than 64
- * bits, returns the low 64 bits of the result.
- *
- * @since 14.0
- */
- public UnsignedLong minus(UnsignedLong val) {
- return fromLongBits(this.value - checkNotNull(val).value);
+ checkNotNull(val);
+ return asUnsigned(this.value - val.value);
}
/**
* Returns the result of multiplying this and {@code val}. If the result would have more than 64
* bits, returns the low 64 bits of the result.
- *
- * @deprecated Use {@link #times(UnsignedLong)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedLong multiply(UnsignedLong val) {
- return times(val);
- }
-
- /**
- * Returns the result of multiplying this and {@code val}. If the result would have more than 64
- * bits, returns the low 64 bits of the result.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedLong times(UnsignedLong val) {
- return fromLongBits(value * checkNotNull(val).value);
+ checkNotNull(val);
+ return asUnsigned(value * val.value);
}
/**
* Returns the result of dividing this by {@code val}.
- *
- * @deprecated Use {@link #dividedBy(UnsignedLong)}. This method is scheduled to be removed in
- * Guava release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedLong divide(UnsignedLong val) {
- return dividedBy(val);
- }
-
- /**
- * Returns the result of dividing this by {@code val}.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedLong dividedBy(UnsignedLong val) {
- return fromLongBits(UnsignedLongs.divide(value, checkNotNull(val).value));
+ checkNotNull(val);
+ return asUnsigned(UnsignedLongs.divide(value, val.value));
}
/**
* Returns the remainder of dividing this by {@code val}.
- *
- * @deprecated Use {@link #mod(UnsignedLong)}. This method is scheduled to be removed in Guava
- * release 15.0.
*/
- @Deprecated
- @Beta
public UnsignedLong remainder(UnsignedLong val) {
- return mod(val);
- }
-
- /**
- * Returns this modulo {@code val}.
- *
- * @since 14.0
- */
- @CheckReturnValue
- public UnsignedLong mod(UnsignedLong val) {
- return fromLongBits(UnsignedLongs.remainder(value, checkNotNull(val).value));
+ checkNotNull(val);
+ return asUnsigned(UnsignedLongs.remainder(value, val.value));
}
/**
diff --git a/guava/src/com/google/common/primitives/UnsignedLongs.java b/guava/src/com/google/common/primitives/UnsignedLongs.java
index cb9923f..b723a1b 100644
--- a/guava/src/com/google/common/primitives/UnsignedLongs.java
+++ b/guava/src/com/google/common/primitives/UnsignedLongs.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -17,31 +17,27 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.GwtCompatible;
-
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Comparator;
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+
/**
* Static utility methods pertaining to {@code long} primitives that interpret values as
* <i>unsigned</i> (that is, any negative value {@code x} is treated as the positive value
* {@code 2^64 + x}). The methods for which signedness is not an issue are in {@link Longs}, as
* well as signed versions of methods for which signedness is an issue.
- *
+ *
* <p>In addition, this class provides several static methods for converting a {@code long} to a
* {@code String} and a {@code String} to a {@code long} that treat the {@code long} as an unsigned
* number.
- *
+ *
* <p>Users of these utilities must be <i>extremely careful</i> not to mix up signed and unsigned
- * {@code long} values. When possible, it is recommended that the {@link UnsignedLong} wrapper
+ * {@code long} values. When possible, it is recommended that the {@link UnsignedLong} wrapper
* class be used, at a small efficiency penalty, to enforce the distinction in the type system.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained#Unsigned_support">
- * unsigned primitive utilities</a>.
- *
+ *
* @author Louis Wasserman
* @author Brian Milch
* @author Colin Evans
@@ -56,7 +52,7 @@ public final class UnsignedLongs {
/**
* A (self-inverse) bijection which converts the ordering on unsigned longs to the ordering on
- * longs, that is, {@code a <= b} as unsigned longs if and only if {@code flip(a) <= flip(b)}
+ * longs, that is, {@code a <= b} as unsigned longs if and only if {@code rotate(a) <= rotate(b)}
* as signed longs.
*/
private static long flip(long a) {
@@ -66,7 +62,7 @@ public final class UnsignedLongs {
/**
* Compares the two specified {@code long} values, treating them as unsigned values between
* {@code 0} and {@code 2^64 - 1} inclusive.
- *
+ *
* @param a the first unsigned {@code long} to compare
* @param b the second unsigned {@code long} to compare
* @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is
@@ -78,7 +74,7 @@ public final class UnsignedLongs {
/**
* Returns the least value present in {@code array}, treating values as unsigned.
- *
+ *
* @param array a <i>nonempty</i> array of unsigned {@code long} values
* @return the value present in {@code array} that is less than or equal to every other value in
* the array according to {@link #compare}
@@ -98,7 +94,7 @@ public final class UnsignedLongs {
/**
* Returns the greatest value present in {@code array}, treating values as unsigned.
- *
+ *
* @param array a <i>nonempty</i> array of unsigned {@code long} values
* @return the value present in {@code array} that is greater than or equal to every other value
* in the array according to {@link #compare}
@@ -119,7 +115,7 @@ public final class UnsignedLongs {
/**
* Returns a string containing the supplied unsigned {@code long} values separated by
* {@code separator}. For example, {@code join("-", 1, 2, 3)} returns the string {@code "1-2-3"}.
- *
+ *
* @param separator the text that should appear between consecutive values in the resulting
* string (but not at the start or end)
* @param array an array of unsigned {@code long} values, possibly empty
@@ -132,7 +128,7 @@ public final class UnsignedLongs {
// For pre-sizing a builder, just get the right order of magnitude
StringBuilder builder = new StringBuilder(array.length * 5);
- builder.append(toString(array[0]));
+ builder.append(array[0]);
for (int i = 1; i < array.length; i++) {
builder.append(separator).append(toString(array[i]));
}
@@ -144,11 +140,11 @@ public final class UnsignedLongs {
* lexicographically. That is, it compares, using {@link #compare(long, long)}), the first pair of
* values that follow any common prefix, or when one array is a prefix of the other, treats the
* shorter array as the lesser. For example, {@code [] < [1L] < [1L, 2L] < [2L] < [1L << 63]}.
- *
+ *
* <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays
* support only identity equality), but it is consistent with
* {@link Arrays#equals(long[], long[])}.
- *
+ *
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">Lexicographical order
* article at Wikipedia</a>
*/
@@ -174,7 +170,7 @@ public final class UnsignedLongs {
/**
* Returns dividend / divisor, where the dividend and divisor are treated as unsigned 64-bit
* quantities.
- *
+ *
* @param dividend the dividend (numerator)
* @param divisor the divisor (denominator)
* @throws ArithmeticException if divisor is 0
@@ -207,7 +203,7 @@ public final class UnsignedLongs {
/**
* Returns dividend % divisor, where the dividend and divisor are treated as unsigned 64-bit
* quantities.
- *
+ *
* @param dividend the dividend (numerator)
* @param divisor the divisor (denominator)
* @throws ArithmeticException if divisor is 0
@@ -240,55 +236,22 @@ public final class UnsignedLongs {
/**
* Returns the unsigned {@code long} value represented by the given decimal string.
- *
+ *
* @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
* value
- * @throws NullPointerException if {@code s} is null
- * (in contrast to {@link Long#parseLong(String)})
*/
public static long parseUnsignedLong(String s) {
return parseUnsignedLong(s, 10);
}
/**
- * Returns the unsigned {@code long} value represented by the given string.
- *
- * Accepts a decimal, hexadecimal, or octal number given by specifying the following prefix:
- *
- * <ul>
- * <li>{@code 0x}<i>HexDigits</i>
- * <li>{@code 0X}<i>HexDigits</i>
- * <li>{@code #}<i>HexDigits</i>
- * <li>{@code 0}<i>OctalDigits</i>
- * </ul>
- *
- * @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
- * value
- * @since 13.0
- */
- public static long decode(String stringValue) {
- ParseRequest request = ParseRequest.fromString(stringValue);
-
- try {
- return parseUnsignedLong(request.rawValue, request.radix);
- } catch (NumberFormatException e) {
- NumberFormatException decodeException =
- new NumberFormatException("Error parsing value: " + stringValue);
- decodeException.initCause(e);
- throw decodeException;
- }
- }
-
- /**
* Returns the unsigned {@code long} value represented by a string with the given radix.
- *
+ *
* @param s the string containing the unsigned {@code long} representation to be parsed.
* @param radix the radix to use while parsing {@code s}
* @throws NumberFormatException if the string does not contain a valid unsigned {@code long}
* with the given radix, or if {@code radix} is not between {@link Character#MIN_RADIX}
* and {@link Character#MAX_RADIX}.
- * @throws NullPointerException if {@code s} is null
- * (in contrast to {@link Long#parseLong(String)})
*/
public static long parseUnsignedLong(String s, int radix) {
checkNotNull(s);
@@ -296,7 +259,7 @@ public final class UnsignedLongs {
throw new NumberFormatException("empty string");
}
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
- throw new NumberFormatException("illegal radix: " + radix);
+ throw new NumberFormatException("illegal radix:" + radix);
}
int max_safe_pos = maxSafeDigits[radix] - 1;
@@ -347,7 +310,7 @@ public final class UnsignedLongs {
/**
* Returns a string representation of {@code x} for the given radix, where {@code x} is treated
* as unsigned.
- *
+ *
* @param x the value to convert to a string.
* @param radix the radix to use while working with {@code x}
* @throws IllegalArgumentException if {@code radix} is not between {@link Character#MIN_RADIX}
@@ -363,17 +326,23 @@ public final class UnsignedLongs {
char[] buf = new char[64];
int i = buf.length;
if (x < 0) {
- // Separate off the last digit using unsigned division. That will leave
- // a number that is nonnegative as a signed integer.
- long quotient = divide(x, radix);
- long rem = x - quotient * radix;
- buf[--i] = Character.forDigit((int) rem, radix);
- x = quotient;
- }
- // Simple modulo/division approach
- while (x > 0) {
- buf[--i] = Character.forDigit((int) (x % radix), radix);
- x /= radix;
+ // Split x into high-order and low-order halves.
+ // Individual digits are generated from the bottom half into which
+ // bits are moved continously from the top half.
+ long top = x >>> 32;
+ long bot = (x & 0xffffffffl) + ((top % radix) << 32);
+ top /= radix;
+ while ((bot > 0) || (top > 0)) {
+ buf[--i] = Character.forDigit((int) (bot % radix), radix);
+ bot = (bot / radix) + ((top % radix) << 32);
+ top /= radix;
+ }
+ } else {
+ // Simple modulo/division approach
+ while (x > 0) {
+ buf[--i] = Character.forDigit((int) (x % radix), radix);
+ x /= radix;
+ }
}
// Generate string
return new String(buf, i, buf.length - i);
diff --git a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Floats.java b/guava/src/com/google/common/primitives/generate.sh
index 8e4eaf7..5d594a2 100644
--- a/guava-gwt/src-super/com/google/common/primitives/super/com/google/common/primitives/Floats.java
+++ b/guava/src/com/google/common/primitives/generate.sh
@@ -1,3 +1,27 @@
+#!/bin/sh
+#
+# Usage example: ./generate.sh int Int Integer"
+# Args are: primitive type, capitalized primitive type, wrapper type
+#
+# To make changes to the .java files in this package,
+# 1. run this script to generate the templates, move the .gen files
+# somewhere else
+# 2. modify the template with your intended changes, then rerun the
+# script
+# 3. use any three-way merge tool to edit the checked-in source files,
+# using the before-and-after generated files as the bases.
+#
+
+if [ "$#" -ne "3" ]
+then
+ echo "Usage example: ./generate.sh int Int Integer"
+ exit 1
+fi
+
+# Note: using the strange strings 'primtyp' and 'WrapperCl' so that they match
+# the maximum length of the real strings ('boolean' and 'Character').
+
+perl -pe "s/primtyp/$1/g; s/PrimTyp/$2/g; s/WrapperCl/$3/g" << "--EOF--" > $2s.java.gen
/*
* Copyright (C) 2008 The Guava Authors
*
@@ -20,13 +44,13 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndexes;
-import static java.lang.Float.NEGATIVE_INFINITY;
-import static java.lang.Float.POSITIVE_INFINITY;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import java.io.Serializable;
import java.util.AbstractList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -34,77 +58,90 @@ import java.util.List;
import java.util.RandomAccess;
/**
- * Static utility methods pertaining to {@code float} primitives, that are not
- * already found in either {@link Float} or {@link Arrays}.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
+ * Static utility methods pertaining to {@code primtyp} primitives, that are not
+ * already found in either {@link WrapperCl} or {@link Arrays}.
*
* @author Kevin Bourrillion
* @since 1.0
*/
-@GwtCompatible(emulated = true)
-public final class Floats {
- private Floats() {}
+@GwtCompatible
+public final class PrimTyps {
+ private PrimTyps() {}
/**
- * The number of bytes required to represent a primitive {@code float}
+ * The number of bytes required to represent a primitive {@code primtyp}
* value.
- *
- * @since 10.0
*/
- public static final int BYTES = Float.SIZE / Byte.SIZE;
+ public static final int BYTES = WrapperCl.SIZE / Byte.SIZE;
/**
* Returns a hash code for {@code value}; equal to the result of invoking
- * {@code ((Float) value).hashCode()}.
+ * {@code ((WrapperCl) value).hashCode()}.
*
- * @param value a primitive {@code float} value
+ * @param value a primitive {@code primtyp} value
* @return a hash code for the value
*/
- public static int hashCode(float value) {
- // TODO(kevinb): is there a better way, that's still gwt-safe?
- return ((Float) value).hashCode();
+ public static int hashCode(primtyp value) {
+ return ??
}
/**
- * Compares the two specified {@code float} values using {@link
- * Float#compare(float, float)}. You may prefer to invoke that method
- * directly; this method exists only for consistency with the other utilities
- * in this package.
+ * Returns the {@code primtyp} value that is equal to {@code value}, if
+ * possible.
*
- * @param a the first {@code float} to compare
- * @param b the second {@code float} to compare
- * @return the result of invoking {@link Float#compare(float, float)}
+ * @param value any value in the range of the {@code primtyp} type
+ * @return the {@code primtyp} value that equals {@code value}
+ * @throws IllegalArgumentException if {@code value} is greater than {@link
+ * WrapperCl#MAX_VALUE} or less than {@link WrapperCl#MIN_VALUE}
*/
- public static int compare(float a, float b) {
- return Float.compare(a, b);
+ public static primtyp checkedCast(long value) {
+ primtyp result = (primtyp) value;
+ checkArgument(result == value, "Out of range: %s", value);
+ return result;
}
/**
- * Returns {@code true} if {@code value} represents a real number. This is
- * equivalent to, but not necessarily implemented as,
- * {@code !(Float.isInfinite(value) || Float.isNaN(value))}.
+ * Returns the {@code primtyp} nearest in value to {@code value}.
*
- * @since 10.0
+ * @param value any {@code long} value
+ * @return the same value cast to {@code primtyp} if it is in the range of the
+ * {@code primtyp} type, {@link WrapperCl#MAX_VALUE} if it is too large,
+ * or {@link WrapperCl#MIN_VALUE} if it is too small
*/
- public static boolean isFinite(float value) {
- return NEGATIVE_INFINITY < value & value < POSITIVE_INFINITY;
+ public static primtyp saturatedCast(long value) {
+ if (value > WrapperCl.MAX_VALUE) {
+ return WrapperCl.MAX_VALUE;
+ }
+ if (value < WrapperCl.MIN_VALUE) {
+ return WrapperCl.MIN_VALUE;
+ }
+ return (primtyp) value;
+ }
+
+ /**
+ * Compares the two specified {@code primtyp} values. The sign of the value
+ * returned is the same as that of {@code ((WrapperCl) a).compareTo(b)}.
+ *
+ * @param a the first {@code primtyp} to compare
+ * @param b the second {@code primtyp} to compare
+ * @return a negative value if {@code a} is less than {@code b}; a positive
+ * value if {@code a} is greater than {@code b}; or zero if they are equal
+ */
+ public static int compare(primtyp a, primtyp b) {
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
}
/**
* Returns {@code true} if {@code target} is present as an element anywhere in
- * {@code array}. Note that this always returns {@code false} when {@code
- * target} is {@code NaN}.
+ * {@code array}.
*
- * @param array an array of {@code float} values, possibly empty
- * @param target a primitive {@code float} value
+ * @param array an array of {@code primtyp} values, possibly empty
+ * @param target a primitive {@code primtyp} value
* @return {@code true} if {@code array[i] == target} for some value of {@code
* i}
*/
- public static boolean contains(float[] array, float target) {
- for (float value : array) {
+ public static boolean contains(primtyp[] array, primtyp target) {
+ for (primtyp value : array) {
if (value == target) {
return true;
}
@@ -114,21 +151,20 @@ public final class Floats {
/**
* Returns the index of the first appearance of the value {@code target} in
- * {@code array}. Note that this always returns {@code -1} when {@code target}
- * is {@code NaN}.
+ * {@code array}.
*
- * @param array an array of {@code float} values, possibly empty
- * @param target a primitive {@code float} value
+ * @param array an array of {@code primtyp} values, possibly empty
+ * @param target a primitive {@code primtyp} value
* @return the least index {@code i} for which {@code array[i] == target}, or
* {@code -1} if no such index exists.
*/
- public static int indexOf(float[] array, float target) {
+ public static int indexOf(primtyp[] array, primtyp target) {
return indexOf(array, target, 0, array.length);
}
// TODO(kevinb): consider making this public
private static int indexOf(
- float[] array, float target, int start, int end) {
+ primtyp[] array, primtyp target, int start, int end) {
for (int i = start; i < end; i++) {
if (array[i] == target) {
return i;
@@ -145,13 +181,10 @@ public final class Floats {
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
* the same elements as {@code target}.
*
- * <p>Note that this always returns {@code -1} when {@code target} contains
- * {@code NaN}.
- *
* @param array the array to search for the sequence {@code target}
* @param target the array to search for as a sub-sequence of {@code array}
*/
- public static int indexOf(float[] array, float[] target) {
+ public static int indexOf(primtyp[] array, primtyp[] target) {
checkNotNull(array, "array");
checkNotNull(target, "target");
if (target.length == 0) {
@@ -172,21 +205,20 @@ public final class Floats {
/**
* Returns the index of the last appearance of the value {@code target} in
- * {@code array}. Note that this always returns {@code -1} when {@code target}
- * is {@code NaN}.
+ * {@code array}.
*
- * @param array an array of {@code float} values, possibly empty
- * @param target a primitive {@code float} value
+ * @param array an array of {@code primtyp} values, possibly empty
+ * @param target a primitive {@code primtyp} value
* @return the greatest index {@code i} for which {@code array[i] == target},
* or {@code -1} if no such index exists.
*/
- public static int lastIndexOf(float[] array, float target) {
+ public static int lastIndexOf(primtyp[] array, primtyp target) {
return lastIndexOf(array, target, 0, array.length);
}
// TODO(kevinb): consider making this public
private static int lastIndexOf(
- float[] array, float target, int start, int end) {
+ primtyp[] array, primtyp target, int start, int end) {
for (int i = end - 1; i >= start; i--) {
if (array[i] == target) {
return i;
@@ -196,58 +228,60 @@ public final class Floats {
}
/**
- * Returns the least value present in {@code array}, using the same rules of
- * comparison as {@link Math#min(float, float)}.
+ * Returns the least value present in {@code array}.
*
- * @param array a <i>nonempty</i> array of {@code float} values
+ * @param array a <i>nonempty</i> array of {@code primtyp} values
* @return the value present in {@code array} that is less than or equal to
* every other value in the array
* @throws IllegalArgumentException if {@code array} is empty
*/
- public static float min(float... array) {
+ public static primtyp min(primtyp... array) {
checkArgument(array.length > 0);
- float min = array[0];
+ primtyp min = array[0];
for (int i = 1; i < array.length; i++) {
- min = Math.min(min, array[i]);
+ if (array[i] < min) {
+ min = array[i];
+ }
}
return min;
}
/**
- * Returns the greatest value present in {@code array}, using the same rules
- * of comparison as {@link Math#min(float, float)}.
+ * Returns the greatest value present in {@code array}.
*
- * @param array a <i>nonempty</i> array of {@code float} values
+ * @param array a <i>nonempty</i> array of {@code primtyp} values
* @return the value present in {@code array} that is greater than or equal to
* every other value in the array
* @throws IllegalArgumentException if {@code array} is empty
*/
- public static float max(float... array) {
+ public static primtyp max(primtyp... array) {
checkArgument(array.length > 0);
- float max = array[0];
+ primtyp max = array[0];
for (int i = 1; i < array.length; i++) {
- max = Math.max(max, array[i]);
+ if (array[i] > max) {
+ max = array[i];
+ }
}
return max;
}
/**
* Returns the values from each provided array combined into a single array.
- * For example, {@code concat(new float[] {a, b}, new float[] {}, new
- * float[] {c}} returns the array {@code {a, b, c}}.
+ * For example, {@code concat(new primtyp[] {a, b}, new primtyp[] {}, new
+ * primtyp[] {c}} returns the array {@code {a, b, c}}.
*
- * @param arrays zero or more {@code float} arrays
+ * @param arrays zero or more {@code primtyp} arrays
* @return a single array containing all the values from the source arrays, in
* order
*/
- public static float[] concat(float[]... arrays) {
+ public static primtyp[] concat(primtyp[]... arrays) {
int length = 0;
- for (float[] array : arrays) {
+ for (primtyp[] array : arrays) {
length += array.length;
}
- float[] result = new float[length];
+ primtyp[] result = new primtyp[length];
int pos = 0;
- for (float[] array : arrays) {
+ for (primtyp[] array : arrays) {
System.arraycopy(array, 0, result, pos, array.length);
pos += array.length;
}
@@ -255,6 +289,55 @@ public final class Floats {
}
/**
+ * Returns a big-endian representation of {@code value} in a ?-element byte
+ * array; equivalent to {@code
+ * ByteBuffer.allocate(?).putPrimTyp(value).array()}. For example, the input
+ * value {@code ?} would yield the byte array {@code {?}}.
+ *
+ * <p>If you need to convert and concatenate several values (possibly even of
+ * different types), use a shared {@link java.nio.ByteBuffer} instance, or use
+ * {@link com.google.common.io.ByteStreams#newDataOutput()} to get a growable
+ * buffer.
+ */
+ @GwtIncompatible("doesn't work")
+ public static byte[] toByteArray(primtyp value) {
+ return new byte[] {
+ ?
+ };
+ }
+
+ /**
+ * Returns the {@code primtyp} value whose big-endian representation is
+ * stored in the first ? bytes of {@code bytes}; equivalent to {@code
+ * ByteBuffer.wrap(bytes).getPrimTyp()}. For example, the input byte array
+ * {@code {?}} would yield the {@code primtyp} value {@code ?}.
+ *
+ * <p>Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that
+ * library exposes much more flexibility at little cost in readability.
+ *
+ * @throws IllegalArgumentException if {@code bytes} has fewer than ?
+ * elements
+ */
+ @GwtIncompatible("doesn't work")
+ public static primtyp fromByteArray(byte[] bytes) {
+ checkArgument(bytes.length >= BYTES,
+ "array too small: %s < %s", bytes.length, BYTES);
+ return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);
+ }
+
+ /**
+ * Returns the {@code primtyp} value whose byte representation is the given ?
+ * bytes, in big-endian order; equivalent to {@code
+ * PrimTyps.fromByteArray(new byte[] { ? })}.
+ *
+ * @since 7.0
+ */
+ @GwtIncompatible("doesn't work")
+ public static primtyp fromBytes(byte b1, byte b2, byte b3, byte b4) {
+ return ?
+ }
+
+ /**
* Returns an array containing the same values as {@code array}, but
* guaranteed to be of a specified minimum length. If {@code array} already
* has a length of at least {@code minLength}, it is returned directly.
@@ -270,8 +353,8 @@ public final class Floats {
* @return an array containing the values of {@code array}, with guaranteed
* minimum length {@code minLength}
*/
- public static float[] ensureCapacity(
- float[] array, int minLength, int padding) {
+ public static primtyp[] ensureCapacity(
+ primtyp[] array, int minLength, int padding) {
checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
checkArgument(padding >= 0, "Invalid padding: %s", padding);
return (array.length < minLength)
@@ -280,34 +363,29 @@ public final class Floats {
}
// Arrays.copyOf() requires Java 6
- private static float[] copyOf(float[] original, int length) {
- float[] copy = new float[length];
+ private static primtyp[] copyOf(primtyp[] original, int length) {
+ primtyp[] copy = new primtyp[length];
System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
return copy;
}
/**
- * Returns a string containing the supplied {@code float} values, converted
- * to strings as specified by {@link Float#toString(float)}, and separated by
- * {@code separator}. For example, {@code join("-", 1.0f, 2.0f, 3.0f)}
- * returns the string {@code "1.0-2.0-3.0"}.
- *
- * <p>Note that {@link Float#toString(float)} formats {@code float}
- * differently in GWT. In the previous example, it returns the string {@code
- * "1-2-3"}.
+ * Returns a string containing the supplied {@code primtyp} values separated
+ * by {@code separator}. For example, {@code join("-", 1?, 2?, 3?)} returns
+ * the string {@code "1-2-3"}.
*
* @param separator the text that should appear between consecutive values in
* the resulting string (but not at the start or end)
- * @param array an array of {@code float} values, possibly empty
+ * @param array an array of {@code primtyp} values, possibly empty
*/
- public static String join(String separator, float... array) {
+ public static String join(String separator, primtyp... array) {
checkNotNull(separator);
if (array.length == 0) {
return "";
}
// For pre-sizing a builder, just get the right order of magnitude
- StringBuilder builder = new StringBuilder(array.length * 12);
+ StringBuilder builder = new StringBuilder(array.length * ??);
builder.append(array[0]);
for (int i = 1; i < array.length; i++) {
builder.append(separator).append(array[i]);
@@ -316,33 +394,32 @@ public final class Floats {
}
/**
- * Returns a comparator that compares two {@code float} arrays
+ * Returns a comparator that compares two {@code primtyp} arrays
* lexicographically. That is, it compares, using {@link
- * #compare(float, float)}), the first pair of values that follow any
+ * #compare(primtyp, primtyp)}), the first pair of values that follow any
* common prefix, or when one array is a prefix of the other, treats the
- * shorter array as the lesser. For example, {@code [] < [1.0f] < [1.0f, 2.0f]
- * < [2.0f]}.
+ * shorter array as the lesser. For example, {@code [] < [1] < [1, 2] < [2]}.
*
* <p>The returned comparator is inconsistent with {@link
* Object#equals(Object)} (since arrays support only identity equality), but
- * it is consistent with {@link Arrays#equals(float[], float[])}.
+ * it is consistent with {@link Arrays#equals(primtyp[], primtyp[])}.
*
* @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
* Lexicographical order article at Wikipedia</a>
* @since 2.0
*/
- public static Comparator<float[]> lexicographicalComparator() {
+ public static Comparator<primtyp[]> lexicographicalComparator() {
return LexicographicalComparator.INSTANCE;
}
- private enum LexicographicalComparator implements Comparator<float[]> {
+ private enum LexicographicalComparator implements Comparator<primtyp[]> {
INSTANCE;
@Override
- public int compare(float[] left, float[] right) {
+ public int compare(primtyp[] left, primtyp[] right) {
int minLength = Math.min(left.length, right.length);
for (int i = 0; i < minLength; i++) {
- int result = Floats.compare(left[i], right[i]);
+ int result = PrimTyps.compare(left[i], right[i]);
if (result != 0) {
return result;
}
@@ -352,31 +429,30 @@ public final class Floats {
}
/**
- * Returns an array containing each value of {@code collection}, converted to
- * a {@code float} value in the manner of {@link Number#floatValue}.
+ * Copies a collection of {@code WrapperCl} instances into a new array of
+ * primitive {@code primtyp} values.
*
* <p>Elements are copied from the argument collection as if by {@code
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
- * @param collection a collection of {@code Number} instances
+ * @param collection a collection of {@code WrapperCl} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
* @throws NullPointerException if {@code collection} or any of its elements
* is null
- * @since 1.0 (parameter was {@code Collection<Float>} before 12.0)
*/
- public static float[] toArray(Collection<? extends Number> collection) {
- if (collection instanceof FloatArrayAsList) {
- return ((FloatArrayAsList) collection).toFloatArray();
+ public static primtyp[] toArray(Collection<WrapperCl> collection) {
+ if (collection instanceof PrimTypArrayAsList) {
+ return ((PrimTypArrayAsList) collection).toPrimTypArray();
}
Object[] boxedArray = collection.toArray();
int len = boxedArray.length;
- float[] array = new float[len];
+ primtyp[] array = new primtyp[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
- array[i] = ((Number) checkNotNull(boxedArray[i])).floatValue();
+ array[i] = (WrapperCl) checkNotNull(boxedArray[i]);
}
return array;
}
@@ -388,35 +464,32 @@ public final class Floats {
* NullPointerException}.
*
* <p>The returned list maintains the values, but not the identities, of
- * {@code Float} objects written to or read from it. For example, whether
+ * {@code WrapperCl} objects written to or read from it. For example, whether
* {@code list.get(0) == list.get(0)} is true for the returned list is
* unspecified.
*
- * <p>The returned list may have unexpected behavior if it contains {@code
- * NaN}, or if {@code NaN} is used as a parameter to any of its methods.
- *
* @param backingArray the array to back the list
* @return a list view of the array
*/
- public static List<Float> asList(float... backingArray) {
+ public static List<WrapperCl> asList(primtyp... backingArray) {
if (backingArray.length == 0) {
return Collections.emptyList();
}
- return new FloatArrayAsList(backingArray);
+ return new PrimTypArrayAsList(backingArray);
}
@GwtCompatible
- private static class FloatArrayAsList extends AbstractList<Float>
+ private static class PrimTypArrayAsList extends AbstractList<WrapperCl>
implements RandomAccess, Serializable {
- final float[] array;
+ final primtyp[] array;
final int start;
final int end;
- FloatArrayAsList(float[] array) {
+ PrimTypArrayAsList(primtyp[] array) {
this(array, 0, array.length);
}
- FloatArrayAsList(float[] array, int start, int end) {
+ PrimTypArrayAsList(primtyp[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
@@ -430,21 +503,21 @@ public final class Floats {
return false;
}
- @Override public Float get(int index) {
+ @Override public WrapperCl get(int index) {
checkElementIndex(index, size());
return array[start + index];
}
@Override public boolean contains(Object target) {
// Overridden to prevent a ton of boxing
- return (target instanceof Float)
- && Floats.indexOf(array, (Float) target, start, end) != -1;
+ return (target instanceof WrapperCl)
+ && PrimTyps.indexOf(array, (WrapperCl) target, start, end) != -1;
}
@Override public int indexOf(Object target) {
// Overridden to prevent a ton of boxing
- if (target instanceof Float) {
- int i = Floats.indexOf(array, (Float) target, start, end);
+ if (target instanceof WrapperCl) {
+ int i = PrimTyps.indexOf(array, (WrapperCl) target, start, end);
if (i >= 0) {
return i - start;
}
@@ -454,8 +527,8 @@ public final class Floats {
@Override public int lastIndexOf(Object target) {
// Overridden to prevent a ton of boxing
- if (target instanceof Float) {
- int i = Floats.lastIndexOf(array, (Float) target, start, end);
+ if (target instanceof WrapperCl) {
+ int i = PrimTyps.lastIndexOf(array, (WrapperCl) target, start, end);
if (i >= 0) {
return i - start;
}
@@ -463,29 +536,28 @@ public final class Floats {
return -1;
}
- @Override public Float set(int index, Float element) {
+ @Override public WrapperCl set(int index, WrapperCl element) {
checkElementIndex(index, size());
- float oldValue = array[start + index];
- // checkNotNull for GWT (do not optimize)
- array[start + index] = checkNotNull(element);
+ primtyp oldValue = array[start + index];
+ array[start + index] = checkNotNull(element); // checkNotNull for GWT (do not optimize)
return oldValue;
}
- @Override public List<Float> subList(int fromIndex, int toIndex) {
+ @Override public List<WrapperCl> subList(int fromIndex, int toIndex) {
int size = size();
checkPositionIndexes(fromIndex, toIndex, size);
if (fromIndex == toIndex) {
return Collections.emptyList();
}
- return new FloatArrayAsList(array, start + fromIndex, start + toIndex);
+ return new PrimTypArrayAsList(array, start + fromIndex, start + toIndex);
}
@Override public boolean equals(Object object) {
if (object == this) {
return true;
}
- if (object instanceof FloatArrayAsList) {
- FloatArrayAsList that = (FloatArrayAsList) object;
+ if (object instanceof PrimTypArrayAsList) {
+ PrimTypArrayAsList that = (PrimTypArrayAsList) object;
int size = size();
if (that.size() != size) {
return false;
@@ -503,13 +575,13 @@ public final class Floats {
@Override public int hashCode() {
int result = 1;
for (int i = start; i < end; i++) {
- result = 31 * result + Floats.hashCode(array[i]);
+ result = 31 * result + PrimTyps.hashCode(array[i]);
}
return result;
}
@Override public String toString() {
- StringBuilder builder = new StringBuilder(size() * 12);
+ StringBuilder builder = new StringBuilder(size() * ??);
builder.append('[').append(array[start]);
for (int i = start + 1; i < end; i++) {
builder.append(", ").append(array[i]);
@@ -517,10 +589,10 @@ public final class Floats {
return builder.append(']').toString();
}
- float[] toFloatArray() {
- // Arrays.copyOfRange() is not available under GWT
+ primtyp[] toPrimTypArray() {
+ // Arrays.copyOfRange() requires Java 6
int size = size();
- float[] result = new float[size];
+ primtyp[] result = new primtyp[size];
System.arraycopy(array, start, result, 0, size);
return result;
}
@@ -528,3 +600,5 @@ public final class Floats {
private static final long serialVersionUID = 0;
}
}
+--EOF--
+
diff --git a/guava/src/com/google/common/primitives/package-info.java b/guava/src/com/google/common/primitives/package-info.java
index 205183f..a3b3a01 100644
--- a/guava/src/com/google/common/primitives/package-info.java
+++ b/guava/src/com/google/common/primitives/package-info.java
@@ -15,15 +15,10 @@
*/
/**
- * Static utilities for working with the eight primitive types and {@code void},
- * and value types for treating them as unsigned.
+ * Static utilities for working with the eight primitive types and {@code void}.
*
* <p>This package is a part of the open-source
* <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained">
- * primitive utilities</a>.
*
* <h2>Contents</h2>
*
@@ -66,4 +61,3 @@
package com.google.common.primitives;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/guava/src/com/google/common/reflect/AbstractInvocationHandler.java b/guava/src/com/google/common/reflect/AbstractInvocationHandler.java
deleted file mode 100644
index 489dcff..0000000
--- a/guava/src/com/google/common/reflect/AbstractInvocationHandler.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.annotations.Beta;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-import javax.annotation.Nullable;
-
-/**
- * Abstract implementation of {@link InvocationHandler} that handles {@link Object#equals},
- * {@link Object#hashCode} and {@link Object#toString}.
- *
- * @author Ben Yu
- * @since 12.0
- */
-@Beta
-public abstract class AbstractInvocationHandler implements InvocationHandler {
-
- private static final Object[] NO_ARGS = {};
-
- /**
- * {@inheritDoc}
- *
- * <p><ul>
- * <li>{@code proxy.hashCode()} delegates to {@link AbstractInvocationHandler#hashCode}
- * <li>{@code proxy.toString()} delegates to {@link AbstractInvocationHandler#toString}
- * <li>{@code proxy.equals(argument)} returns true if: <ul>
- * <li>{@code proxy} and {@code argument} are of the same type
- * <li>and {@link AbstractInvocationHandler#equals} returns true for the {@link
- * InvocationHandler} of {@code argument}
- * </ul>
- * <li>other method calls are dispatched to {@link #handleInvocation}.
- * </ul>
- */
- @Override public final Object invoke(Object proxy, Method method, @Nullable Object[] args)
- throws Throwable {
- if (args == null) {
- args = NO_ARGS;
- }
- if (args.length == 0 && method.getName().equals("hashCode")) {
- return hashCode();
- }
- if (args.length == 1
- && method.getName().equals("equals")
- && method.getParameterTypes()[0] == Object.class) {
- Object arg = args[0];
- return proxy.getClass().isInstance(arg) && equals(Proxy.getInvocationHandler(arg));
- }
- if (args.length == 0 && method.getName().equals("toString")) {
- return toString();
- }
- return handleInvocation(proxy, method, args);
- }
-
- /**
- * {@link #invoke} delegates to this method upon any method invocation on the proxy instance,
- * except {@link Object#equals}, {@link Object#hashCode} and {@link Object#toString}. The result
- * will be returned as the proxied method's return value.
- *
- * <p>Unlike {@link #invoke}, {@code args} will never be null. When the method has no parameter,
- * an empty array is passed in.
- */
- protected abstract Object handleInvocation(Object proxy, Method method, Object[] args)
- throws Throwable;
-
- /**
- * By default delegates to {@link Object#equals} so instances are only equal if they are
- * identical. {@code proxy.equals(argument)} returns true if: <ul>
- * <li>{@code proxy} and {@code argument} are of the same type
- * <li>and this method returns true for the {@link InvocationHandler} of {@code argument}
- * </ul>
- * Subclasses can override this method to provide custom equality.
- */
- @Override public boolean equals(Object obj) {
- return super.equals(obj);
- }
-
- /**
- * By default delegates to {@link Object#hashCode}. The dynamic proxies' {@code hashCode()} will
- * delegate to this method. Subclasses can override this method to provide custom equality.
- */
- @Override public int hashCode() {
- return super.hashCode();
- }
-
- /**
- * By default delegates to {@link Object#toString}. The dynamic proxies' {@code toString()} will
- * delegate to this method. Subclasses can override this method to provide custom string
- * representation for the proxies.
- */
- @Override public String toString() {
- return super.toString();
- }
-}
diff --git a/guava/src/com/google/common/reflect/ClassPath.java b/guava/src/com/google/common/reflect/ClassPath.java
deleted file mode 100644
index cfbc479..0000000
--- a/guava/src/com/google/common/reflect/ClassPath.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Enumeration;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.logging.Logger;
-
-import javax.annotation.Nullable;
-
-/**
- * Scans the source of a {@link ClassLoader} and finds all the classes loadable.
- *
- * @author Ben Yu
- * @since 14.0
- */
-@Beta
-public final class ClassPath {
-
- private static final Logger logger = Logger.getLogger(ClassPath.class.getName());
-
- /** Separator for the Class-Path manifest attribute value in jar files. */
- private static final Splitter CLASS_PATH_ATTRIBUTE_SEPARATOR =
- Splitter.on(" ").omitEmptyStrings();
-
- private static final String CLASS_FILE_NAME_EXTENSION = ".class";
-
- private final ImmutableSet<ResourceInfo> resources;
-
- private ClassPath(ImmutableSet<ResourceInfo> resources) {
- this.resources = resources;
- }
-
- /**
- * Returns a {@code ClassPath} representing all classes and resources loadable from {@code
- * classloader} and its parent class loaders.
- *
- * <p>Currently only {@link URLClassLoader} and only {@code file://} urls are supported.
- *
- * @throws IOException if the attempt to read class path resources (jar files or directories)
- * failed.
- */
- public static ClassPath from(ClassLoader classloader) throws IOException {
- ImmutableSortedSet.Builder<ResourceInfo> resources =
- new ImmutableSortedSet.Builder<ResourceInfo>(Ordering.usingToString());
- for (Map.Entry<URI, ClassLoader> entry : getClassPathEntries(classloader).entrySet()) {
- browse(entry.getKey(), entry.getValue(), resources);
- }
- return new ClassPath(resources.build());
- }
-
- /**
- * Returns all resources loadable from the current class path, including the class files of all
- * loadable classes.
- */
- public ImmutableSet<ResourceInfo> getResources() {
- return resources;
- }
-
- /** Returns all top level classes loadable from the current class path. */
- public ImmutableSet<ClassInfo> getTopLevelClasses() {
- ImmutableSet.Builder<ClassInfo> builder = ImmutableSet.builder();
- for (ResourceInfo resource : resources) {
- if (resource instanceof ClassInfo) {
- builder.add((ClassInfo) resource);
- }
- }
- return builder.build();
- }
-
- /** Returns all top level classes whose package name is {@code packageName}. */
- public ImmutableSet<ClassInfo> getTopLevelClasses(String packageName) {
- checkNotNull(packageName);
- ImmutableSet.Builder<ClassInfo> builder = ImmutableSet.builder();
- for (ClassInfo classInfo : getTopLevelClasses()) {
- if (classInfo.getPackageName().equals(packageName)) {
- builder.add(classInfo);
- }
- }
- return builder.build();
- }
-
- /**
- * Returns all top level classes whose package name is {@code packageName} or starts with
- * {@code packageName} followed by a '.'.
- */
- public ImmutableSet<ClassInfo> getTopLevelClassesRecursive(String packageName) {
- checkNotNull(packageName);
- String packagePrefix = packageName + '.';
- ImmutableSet.Builder<ClassInfo> builder = ImmutableSet.builder();
- for (ClassInfo classInfo : getTopLevelClasses()) {
- if (classInfo.getName().startsWith(packagePrefix)) {
- builder.add(classInfo);
- }
- }
- return builder.build();
- }
-
- /**
- * Represents a class path resource that can be either a class file or any other resource file
- * loadable from the class path.
- *
- * @since 14.0
- */
- @Beta
- public static class ResourceInfo {
- private final String resourceName;
- final ClassLoader loader;
-
- static ResourceInfo of(String resourceName, ClassLoader loader) {
- if (resourceName.endsWith(CLASS_FILE_NAME_EXTENSION) && !resourceName.contains("$")) {
- return new ClassInfo(resourceName, loader);
- } else {
- return new ResourceInfo(resourceName, loader);
- }
- }
-
- ResourceInfo(String resourceName, ClassLoader loader) {
- this.resourceName = checkNotNull(resourceName);
- this.loader = checkNotNull(loader);
- }
-
- /** Returns the url identifying the resource. */
- public final URL url() {
- return checkNotNull(loader.getResource(resourceName),
- "Failed to load resource: %s", resourceName);
- }
-
- /** Returns the fully qualified name of the resource. Such as "com/mycomp/foo/bar.txt". */
- public final String getResourceName() {
- return resourceName;
- }
-
- @Override public int hashCode() {
- return resourceName.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof ResourceInfo) {
- ResourceInfo that = (ResourceInfo) obj;
- return resourceName.equals(that.resourceName)
- && loader == that.loader;
- }
- return false;
- }
-
- @Override public String toString() {
- return resourceName;
- }
- }
-
- /**
- * Represents a class that can be loaded through {@link #load}.
- *
- * @since 14.0
- */
- @Beta
- public static final class ClassInfo extends ResourceInfo {
- private final String className;
-
- ClassInfo(String resourceName, ClassLoader loader) {
- super(resourceName, loader);
- this.className = getClassName(resourceName);
- }
-
- /** Returns the package name of the class, without attempting to load the class. */
- public String getPackageName() {
- return Reflection.getPackageName(className);
- }
-
- /** Returns the simple name of the underlying class as given in the source code. */
- public String getSimpleName() {
- String packageName = getPackageName();
- if (packageName.isEmpty()) {
- return className;
- }
- // Since this is a top level class, its simple name is always the part after package name.
- return className.substring(packageName.length() + 1);
- }
-
- /** Returns the fully qualified name of the class. */
- public String getName() {
- return className;
- }
-
- /** Loads (but doesn't link or initialize) the class. */
- public Class<?> load() {
- try {
- return loader.loadClass(className);
- } catch (ClassNotFoundException e) {
- // Shouldn't happen, since the class name is read from the class path.
- throw new IllegalStateException(e);
- }
- }
-
- @Override public String toString() {
- return className;
- }
- }
-
- @VisibleForTesting static ImmutableMap<URI, ClassLoader> getClassPathEntries(
- ClassLoader classloader) {
- LinkedHashMap<URI, ClassLoader> entries = Maps.newLinkedHashMap();
- // Search parent first, since it's the order ClassLoader#loadClass() uses.
- ClassLoader parent = classloader.getParent();
- if (parent != null) {
- entries.putAll(getClassPathEntries(parent));
- }
- if (classloader instanceof URLClassLoader) {
- URLClassLoader urlClassLoader = (URLClassLoader) classloader;
- for (URL entry : urlClassLoader.getURLs()) {
- URI uri;
- try {
- uri = entry.toURI();
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(e);
- }
- if (!entries.containsKey(uri)) {
- entries.put(uri, classloader);
- }
- }
- }
- return ImmutableMap.copyOf(entries);
- }
-
- private static void browse(
- URI uri, ClassLoader classloader, ImmutableSet.Builder<ResourceInfo> resources)
- throws IOException {
- if (uri.getScheme().equals("file")) {
- browseFrom(new File(uri), classloader, resources);
- }
- }
-
- @VisibleForTesting static void browseFrom(
- File file, ClassLoader classloader, ImmutableSet.Builder<ResourceInfo> resources)
- throws IOException {
- if (!file.exists()) {
- return;
- }
- if (file.isDirectory()) {
- browseDirectory(file, classloader, resources);
- } else {
- browseJar(file, classloader, resources);
- }
- }
-
- private static void browseDirectory(
- File directory, ClassLoader classloader, ImmutableSet.Builder<ResourceInfo> resources) {
- browseDirectory(directory, classloader, "", resources);
- }
-
- private static void browseDirectory(
- File directory, ClassLoader classloader, String packagePrefix,
- ImmutableSet.Builder<ResourceInfo> resources) {
- for (File f : directory.listFiles()) {
- String name = f.getName();
- if (f.isDirectory()) {
- browseDirectory(f, classloader, packagePrefix + name + "/", resources);
- } else {
- String resourceName = packagePrefix + name;
- resources.add(ResourceInfo.of(resourceName, classloader));
- }
- }
- }
-
- private static void browseJar(
- File file, ClassLoader classloader, ImmutableSet.Builder<ResourceInfo> resources)
- throws IOException {
- JarFile jarFile;
- try {
- jarFile = new JarFile(file);
- } catch (IOException e) {
- // Not a jar file
- return;
- }
- try {
- for (URI uri : getClassPathFromManifest(file, jarFile.getManifest())) {
- browse(uri, classloader, resources);
- }
- Enumeration<JarEntry> entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- if (entry.isDirectory() || entry.getName().startsWith("META-INF/")) {
- continue;
- }
- resources.add(ResourceInfo.of(entry.getName(), classloader));
- }
- } finally {
- try {
- jarFile.close();
- } catch (IOException ignored) {}
- }
- }
-
- /**
- * Returns the class path URIs specified by the {@code Class-Path} manifest attribute, according
- * to <a href="http://docs.oracle.com/javase/1.4.2/docs/guide/jar/jar.html#Main%20Attributes">
- * JAR File Specification</a>. If {@code manifest} is null, it means the jar file has no manifest,
- * and an empty set will be returned.
- */
- @VisibleForTesting static ImmutableSet<URI> getClassPathFromManifest(
- File jarFile, @Nullable Manifest manifest) {
- if (manifest == null) {
- return ImmutableSet.of();
- }
- ImmutableSet.Builder<URI> builder = ImmutableSet.builder();
- String classpathAttribute = manifest.getMainAttributes().getValue("Class-Path");
- if (classpathAttribute != null) {
- for (String path : CLASS_PATH_ATTRIBUTE_SEPARATOR.split(classpathAttribute)) {
- URI uri;
- try {
- uri = getClassPathEntry(jarFile, path);
- } catch (URISyntaxException e) {
- // Ignore bad entry
- logger.warning("Invalid Class-Path entry: " + path);
- continue;
- }
- builder.add(uri);
- }
- }
- return builder.build();
- }
-
- /**
- * Returns the absolute uri of the Class-Path entry value as specified in
- * <a href="http://docs.oracle.com/javase/1.4.2/docs/guide/jar/jar.html#Main%20Attributes">
- * JAR File Specification</a>. Even though the specification only talks about relative urls,
- * absolute urls are actually supported too (for example, in Maven surefire plugin).
- */
- @VisibleForTesting static URI getClassPathEntry(File jarFile, String path)
- throws URISyntaxException {
- URI uri = new URI(path);
- if (uri.isAbsolute()) {
- return uri;
- } else {
- return new File(jarFile.getParentFile(), path.replace('/', File.separatorChar)).toURI();
- }
- }
-
- @VisibleForTesting static String getClassName(String filename) {
- int classNameEnd = filename.length() - CLASS_FILE_NAME_EXTENSION.length();
- return filename.substring(0, classNameEnd).replace('/', '.');
- }
-}
diff --git a/guava/src/com/google/common/reflect/Element.java b/guava/src/com/google/common/reflect/Element.java
deleted file mode 100644
index 14962b6..0000000
--- a/guava/src/com/google/common/reflect/Element.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import javax.annotation.Nullable;
-
-/**
- * Represents either a {@link Field}, a {@link Method} or a {@link Constructor}.
- * Provides convenience methods such as {@link #isPublic} and {@link #isPackagePrivate}.
- *
- * @author Ben Yu
- */
-class Element extends AccessibleObject implements Member {
-
- private final AccessibleObject accessibleObject;
- private final Member member;
-
- <M extends AccessibleObject & Member> Element(M member) {
- checkNotNull(member);
- this.accessibleObject = member;
- this.member = member;
- }
-
- @Override public final boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
- return accessibleObject.isAnnotationPresent(annotationClass);
- }
-
- @Override public final <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
- return accessibleObject.getAnnotation(annotationClass);
- }
-
- @Override public final Annotation[] getAnnotations() {
- return accessibleObject.getAnnotations();
- }
-
- @Override public final Annotation[] getDeclaredAnnotations() {
- return accessibleObject.getDeclaredAnnotations();
- }
-
- @Override public final void setAccessible(boolean flag) throws SecurityException {
- accessibleObject.setAccessible(flag);
- }
-
- @Override public final boolean isAccessible() {
- return accessibleObject.isAccessible();
- }
-
- @Override public Class<?> getDeclaringClass() {
- return member.getDeclaringClass();
- }
-
- @Override public final String getName() {
- return member.getName();
- }
-
- @Override public final int getModifiers() {
- return member.getModifiers();
- }
-
- @Override public final boolean isSynthetic() {
- return member.isSynthetic();
- }
-
- /** Returns true if the element is public. */
- public final boolean isPublic() {
- return Modifier.isPublic(getModifiers());
- }
-
- /** Returns true if the element is protected. */
- public final boolean isProtected() {
- return Modifier.isProtected(getModifiers());
- }
-
- /** Returns true if the element is package-private. */
- public final boolean isPackagePrivate() {
- return !isPrivate() && !isPublic() && !isProtected();
- }
-
- /** Returns true if the element is private. */
- public final boolean isPrivate() {
- return Modifier.isPrivate(getModifiers());
- }
-
- /** Returns true if the element is static. */
- public final boolean isStatic() {
- return Modifier.isStatic(getModifiers());
- }
-
- /**
- * Returns {@code true} if this method is final, per {@code Modifier.isFinal(getModifiers())}.
- *
- * <p>Note that a method may still be effectively "final", or non-overridable when it has no
- * {@code final} keyword. For example, it could be private, or it could be declared by a final
- * class. To tell whether a method is overridable, use {@link Invokable#isOverridable}.
- */
- public final boolean isFinal() {
- return Modifier.isFinal(getModifiers());
- }
-
- /** Returns true if the method is abstract. */
- public final boolean isAbstract() {
- return Modifier.isAbstract(getModifiers());
- }
-
- /** Returns true if the element is native. */
- public final boolean isNative() {
- return Modifier.isNative(getModifiers());
- }
-
- /** Returns true if the method is synchronized. */
- public final boolean isSynchronized() {
- return Modifier.isSynchronized(getModifiers());
- }
-
- /** Returns true if the field is volatile. */
- final boolean isVolatile() {
- return Modifier.isVolatile(getModifiers());
- }
-
- /** Returns true if the field is transient. */
- final boolean isTransient() {
- return Modifier.isTransient(getModifiers());
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof Element) {
- Element that = (Element) obj;
- return member.equals(that.member);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return member.hashCode();
- }
-
- @Override public String toString() {
- return member.toString();
- }
-}
diff --git a/guava/src/com/google/common/reflect/ImmutableTypeToInstanceMap.java b/guava/src/com/google/common/reflect/ImmutableTypeToInstanceMap.java
deleted file mode 100644
index 43e5e1e..0000000
--- a/guava/src/com/google/common/reflect/ImmutableTypeToInstanceMap.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ForwardingMap;
-import com.google.common.collect.ImmutableMap;
-
-import java.util.Map;
-
-/**
- * A type-to-instance map backed by an {@link ImmutableMap}. See also {@link
- * MutableTypeToInstanceMap}.
- *
- * @author Ben Yu
- * @since 13.0
- */
-@Beta
-public final class ImmutableTypeToInstanceMap<B> extends ForwardingMap<TypeToken<? extends B>, B>
- implements TypeToInstanceMap<B> {
-
- /** Returns an empty type to instance map. */
- public static <B> ImmutableTypeToInstanceMap<B> of() {
- return new ImmutableTypeToInstanceMap<B>(ImmutableMap.<TypeToken<? extends B>, B>of());
- }
-
- /** Returns a new builder. */
- public static <B> Builder<B> builder() {
- return new Builder<B>();
- }
-
- /**
- * A builder for creating immutable type-to-instance maps. Example:
- * <pre> {@code
- *
- * static final ImmutableTypeToInstanceMap<Handler<?>> HANDLERS =
- * ImmutableTypeToInstanceMap.<Handler<?>>builder()
- * .put(new TypeToken<Handler<Foo>>() {}, new FooHandler())
- * .put(new TypeToken<Handler<Bar>>() {}, new SubBarHandler())
- * .build();}</pre>
- *
- * After invoking {@link #build()} it is still possible to add more entries
- * and build again. Thus each map generated by this builder will be a superset
- * of any map generated before it.
- *
- * @since 13.0
- */
- @Beta
- public static final class Builder<B> {
- private final ImmutableMap.Builder<TypeToken<? extends B>, B> mapBuilder
- = ImmutableMap.builder();
-
- private Builder() {}
-
- /**
- * Associates {@code key} with {@code value} in the built map. Duplicate
- * keys are not allowed, and will cause {@link #build} to fail.
- */
- public <T extends B> Builder<B> put(Class<T> key, T value) {
- mapBuilder.put(TypeToken.of(key), value);
- return this;
- }
-
- /**
- * Associates {@code key} with {@code value} in the built map. Duplicate
- * keys are not allowed, and will cause {@link #build} to fail.
- */
- public <T extends B> Builder<B> put(TypeToken<T> key, T value) {
- mapBuilder.put(key.rejectTypeVariables(), value);
- return this;
- }
-
- /**
- * Returns a new immutable type-to-instance map containing the entries
- * provided to this builder.
- *
- * @throws IllegalArgumentException if duplicate keys were added
- */
- public ImmutableTypeToInstanceMap<B> build() {
- return new ImmutableTypeToInstanceMap<B>(mapBuilder.build());
- }
- }
-
- private final ImmutableMap<TypeToken<? extends B>, B> delegate;
-
- private ImmutableTypeToInstanceMap(ImmutableMap<TypeToken<? extends B>, B> delegate) {
- this.delegate = delegate;
- }
-
- @Override public <T extends B> T getInstance(TypeToken<T> type) {
- return trustedGet(type.rejectTypeVariables());
- }
-
- /**
- * Guaranteed to throw an exception and leave the map unmodified.
- *
- * @throws UnsupportedOperationException always
- */
- @Override public <T extends B> T putInstance(TypeToken<T> type, T value) {
- throw new UnsupportedOperationException();
- }
-
- @Override public <T extends B> T getInstance(Class<T> type) {
- return trustedGet(TypeToken.of(type));
- }
-
- /**
- * Guaranteed to throw an exception and leave the map unmodified.
- *
- * @throws UnsupportedOperationException always
- */
- @Override public <T extends B> T putInstance(Class<T> type, T value) {
- throw new UnsupportedOperationException();
- }
-
- @Override protected Map<TypeToken<? extends B>, B> delegate() {
- return delegate;
- }
-
- @SuppressWarnings("unchecked") // value could not get in if not a T
- private <T extends B> T trustedGet(TypeToken<T> type) {
- return (T) delegate.get(type);
- }
-}
diff --git a/guava/src/com/google/common/reflect/Invokable.java b/guava/src/com/google/common/reflect/Invokable.java
deleted file mode 100644
index a8f9b77..0000000
--- a/guava/src/com/google/common/reflect/Invokable.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.Arrays;
-
-import javax.annotation.Nullable;
-
-/**
- * Wrapper around either a {@link Method} or a {@link Constructor}.
- * Convenience API is provided to make common reflective operation easier to deal with,
- * such as {@link #isPublic}, {@link #getParameters} etc.
- *
- * <p>In addition to convenience methods, {@link TypeToken#method} and {@link
- * TypeToken#constructor} will resolve the type parameters of the method or constructor in the
- * context of the owner type, which may be a subtype of the declaring class. For example:
- * <pre> {@code
- *
- * Method getMethod = List.class.getMethod("get", int.class);
- * Invokable<List<String>, ?> invokable = new TypeToken<List<String>>() {}.method(getMethod);
- * assertEquals(TypeToken.of(String.class), invokable.getReturnType()); // Not Object.class!
- * assertEquals(new TypeToken<List<String>>() {}, invokable.getOwnerType());}</pre>
- *
- * @param <T> the type that owns this method or constructor.
- * @param <R> the return type of (or supertype thereof) the method or the declaring type of the
- * constructor.
- * @author Ben Yu
- * @since 14.0
- */
-@Beta
-public abstract class Invokable<T, R> extends Element implements GenericDeclaration {
-
- <M extends AccessibleObject & Member> Invokable(M member) {
- super(member);
- }
-
- /** Returns {@link Invokable} of {@code method}. */
- public static Invokable<?, Object> from(Method method) {
- return new MethodInvokable<Object>(method);
- }
-
- /** Returns {@link Invokable} of {@code constructor}. */
- public static <T> Invokable<T, T> from(Constructor<T> constructor) {
- return new ConstructorInvokable<T>(constructor);
- }
-
- /**
- * Returns {@code true} if this is an overridable method. Constructors, private, static or final
- * methods, or methods declared by final classes are not overridable.
- */
- public abstract boolean isOverridable();
-
- /** Returns {@code true} if this was declared to take a variable number of arguments. */
- public abstract boolean isVarArgs();
-
- /**
- * Invokes with {@code receiver} as 'this' and {@code args} passed to the underlying method
- * and returns the return value; or calls the underlying constructor with {@code args} and returns
- * the constructed instance.
- *
- * @throws IllegalAccessException if this {@code Constructor} object enforces Java language
- * access control and the underlying method or constructor is inaccessible.
- * @throws IllegalArgumentException if the number of actual and formal parameters differ;
- * if an unwrapping conversion for primitive arguments fails; or if, after possible
- * unwrapping, a parameter value cannot be converted to the corresponding formal
- * parameter type by a method invocation conversion.
- * @throws InvocationTargetException if the underlying method or constructor throws an exception.
- */
- // All subclasses are owned by us and we'll make sure to get the R type right.
- @SuppressWarnings("unchecked")
- public final R invoke(@Nullable T receiver, Object... args)
- throws InvocationTargetException, IllegalAccessException {
- return (R) invokeInternal(receiver, checkNotNull(args));
- }
-
- /** Returns the return type of this {@code Invokable}. */
- // All subclasses are owned by us and we'll make sure to get the R type right.
- @SuppressWarnings("unchecked")
- public final TypeToken<? extends R> getReturnType() {
- return (TypeToken<? extends R>) TypeToken.of(getGenericReturnType());
- }
-
- /**
- * Returns all declared parameters of this {@code Invokable}. Note that if this is a constructor
- * of a non-static inner class, unlike {@link Constructor#getParameterTypes}, the hidden
- * {@code this} parameter of the enclosing class is excluded from the returned parameters.
- */
- public final ImmutableList<Parameter> getParameters() {
- Type[] parameterTypes = getGenericParameterTypes();
- Annotation[][] annotations = getParameterAnnotations();
- ImmutableList.Builder<Parameter> builder = ImmutableList.builder();
- for (int i = 0; i < parameterTypes.length; i++) {
- builder.add(new Parameter(
- this, i, TypeToken.of(parameterTypes[i]), annotations[i]));
- }
- return builder.build();
- }
-
- /** Returns all declared exception types of this {@code Invokable}. */
- public final ImmutableList<TypeToken<? extends Throwable>> getExceptionTypes() {
- ImmutableList.Builder<TypeToken<? extends Throwable>> builder = ImmutableList.builder();
- for (Type type : getGenericExceptionTypes()) {
- // getGenericExceptionTypes() will never return a type that's not exception
- @SuppressWarnings("unchecked")
- TypeToken<? extends Throwable> exceptionType = (TypeToken<? extends Throwable>)
- TypeToken.of(type);
- builder.add(exceptionType);
- }
- return builder.build();
- }
-
- /**
- * Explicitly specifies the return type of this {@code Invokable}. For example:
- * <pre> {@code
- * Method factoryMethod = Person.class.getMethod("create");
- * Invokable<?, Person> factory = Invokable.of(getNameMethod).returning(Person.class);
- * }</pre>
- */
- public final <R1 extends R> Invokable<T, R1> returning(Class<R1> returnType) {
- return returning(TypeToken.of(returnType));
- }
-
- /** Explicitly specifies the return type of this {@code Invokable}. */
- public final <R1 extends R> Invokable<T, R1> returning(TypeToken<R1> returnType) {
- if (!returnType.isAssignableFrom(getReturnType())) {
- throw new IllegalArgumentException(
- "Invokable is known to return " + getReturnType() + ", not " + returnType);
- }
- @SuppressWarnings("unchecked") // guarded by previous check
- Invokable<T, R1> specialized = (Invokable<T, R1>) this;
- return specialized;
- }
-
- @SuppressWarnings("unchecked") // The declaring class is T's raw class, or one of its supertypes.
- @Override public final Class<? super T> getDeclaringClass() {
- return (Class<? super T>) super.getDeclaringClass();
- }
-
- /** Returns the type of {@code T}. */
- // Overridden in TypeToken#method() and TypeToken#constructor()
- @SuppressWarnings("unchecked") // The declaring class is T.
- public TypeToken<T> getOwnerType() {
- return (TypeToken<T>) TypeToken.of(getDeclaringClass());
- }
-
- abstract Object invokeInternal(@Nullable Object receiver, Object[] args)
- throws InvocationTargetException, IllegalAccessException;
-
- abstract Type[] getGenericParameterTypes();
-
- /** This should never return a type that's not a subtype of Throwable. */
- abstract Type[] getGenericExceptionTypes();
-
- abstract Annotation[][] getParameterAnnotations();
-
- abstract Type getGenericReturnType();
-
- static class MethodInvokable<T> extends Invokable<T, Object> {
-
- private final Method method;
-
- MethodInvokable(Method method) {
- super(method);
- this.method = method;
- }
-
- @Override final Object invokeInternal(@Nullable Object receiver, Object[] args)
- throws InvocationTargetException, IllegalAccessException {
- return method.invoke(receiver, args);
- }
-
- @Override Type getGenericReturnType() {
- return method.getGenericReturnType();
- }
-
- @Override Type[] getGenericParameterTypes() {
- return method.getGenericParameterTypes();
- }
-
- @Override Type[] getGenericExceptionTypes() {
- return method.getGenericExceptionTypes();
- }
-
- @Override final Annotation[][] getParameterAnnotations() {
- return method.getParameterAnnotations();
- }
-
- @Override public final TypeVariable<?>[] getTypeParameters() {
- return method.getTypeParameters();
- }
-
- @Override public final boolean isOverridable() {
- return !(isFinal() || isPrivate() || isStatic()
- || Modifier.isFinal(getDeclaringClass().getModifiers()));
- }
-
- @Override public final boolean isVarArgs() {
- return method.isVarArgs();
- }
- }
-
- static class ConstructorInvokable<T> extends Invokable<T, T> {
-
- private final Constructor<?> constructor;
-
- ConstructorInvokable(Constructor<?> constructor) {
- super(constructor);
- this.constructor = constructor;
- }
-
- @Override final Object invokeInternal(@Nullable Object receiver, Object[] args)
- throws InvocationTargetException, IllegalAccessException {
- try {
- return constructor.newInstance(args);
- } catch (InstantiationException e) {
- throw new RuntimeException(constructor + " failed.", e);
- }
- }
-
- @Override Type getGenericReturnType() {
- return constructor.getDeclaringClass();
- }
-
- @Override Type[] getGenericParameterTypes() {
- Type[] types = constructor.getGenericParameterTypes();
- Class<?> declaringClass = constructor.getDeclaringClass();
- if (!Modifier.isStatic(declaringClass.getModifiers())
- && declaringClass.getEnclosingClass() != null) {
- if (types.length == constructor.getParameterTypes().length) {
- // first parameter is the hidden 'this'
- return Arrays.copyOfRange(types, 1, types.length);
- }
- }
- return types;
- }
-
- @Override Type[] getGenericExceptionTypes() {
- return constructor.getGenericExceptionTypes();
- }
-
- @Override final Annotation[][] getParameterAnnotations() {
- return constructor.getParameterAnnotations();
- }
-
- @Override public final TypeVariable<?>[] getTypeParameters() {
- return constructor.getTypeParameters();
- }
-
- @Override public final boolean isOverridable() {
- return false;
- }
-
- @Override public final boolean isVarArgs() {
- return constructor.isVarArgs();
- }
- }
-}
diff --git a/guava/src/com/google/common/reflect/MutableTypeToInstanceMap.java b/guava/src/com/google/common/reflect/MutableTypeToInstanceMap.java
deleted file mode 100644
index 5f1249d..0000000
--- a/guava/src/com/google/common/reflect/MutableTypeToInstanceMap.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ForwardingMap;
-import com.google.common.collect.Maps;
-
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-/**
- * A mutable type-to-instance map.
- * See also {@link ImmutableTypeToInstanceMap}.
- *
- * @author Ben Yu
- * @since 13.0
- */
-@Beta
-public final class MutableTypeToInstanceMap<B> extends ForwardingMap<TypeToken<? extends B>, B>
- implements TypeToInstanceMap<B> {
-
- private final Map<TypeToken<? extends B>, B> backingMap = Maps.newHashMap();
-
- @Nullable
- @Override
- public <T extends B> T getInstance(Class<T> type) {
- return trustedGet(TypeToken.of(type));
- }
-
- @Nullable
- @Override
- public <T extends B> T putInstance(Class<T> type, @Nullable T value) {
- return trustedPut(TypeToken.of(type), value);
- }
-
- @Nullable
- @Override
- public <T extends B> T getInstance(TypeToken<T> type) {
- return trustedGet(type.rejectTypeVariables());
- }
-
- @Nullable
- @Override
- public <T extends B> T putInstance(TypeToken<T> type, @Nullable T value) {
- return trustedPut(type.rejectTypeVariables(), value);
- }
-
- /** Not supported. Use {@link #putInstance} instead. */
- @Override public B put(TypeToken<? extends B> key, B value) {
- throw new UnsupportedOperationException("Please use putInstance() instead.");
- }
-
- /** Not supported. Use {@link #putInstance} instead. */
- @Override public void putAll(Map<? extends TypeToken<? extends B>, ? extends B> map) {
- throw new UnsupportedOperationException("Please use putInstance() instead.");
- }
-
- @Override protected Map<TypeToken<? extends B>, B> delegate() {
- return backingMap;
- }
-
- @SuppressWarnings("unchecked") // value could not get in if not a T
- @Nullable
- private <T extends B> T trustedPut(TypeToken<T> type, @Nullable T value) {
- return (T) backingMap.put(type, value);
- }
-
- @SuppressWarnings("unchecked") // value could not get in if not a T
- @Nullable
- private <T extends B> T trustedGet(TypeToken<T> type) {
- return (T) backingMap.get(type);
- }
-}
diff --git a/guava/src/com/google/common/reflect/Parameter.java b/guava/src/com/google/common/reflect/Parameter.java
deleted file mode 100644
index 977bc8d..0000000
--- a/guava/src/com/google/common/reflect/Parameter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableList;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AnnotatedElement;
-
-import javax.annotation.Nullable;
-
-/**
- * Represents a method or constructor parameter.
- *
- * @author Ben Yu
- * @since 14.0
- */
-@Beta
-public final class Parameter implements AnnotatedElement {
-
- private final Invokable<?, ?> declaration;
- private final int position;
- private final TypeToken<?> type;
- private final ImmutableList<Annotation> annotations;
-
- Parameter(
- Invokable<?, ?> declaration,
- int position,
- TypeToken<?> type,
- Annotation[] annotations) {
- this.declaration = declaration;
- this.position = position;
- this.type = type;
- this.annotations = ImmutableList.copyOf(annotations);
- }
-
- /** Returns the type of the parameter. */
- public TypeToken<?> getType() {
- return type;
- }
-
- /** Returns the {@link Invokable} that declares this parameter. */
- public Invokable<?, ?> getDeclaringInvokable() {
- return declaration;
- }
-
- @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
- return getAnnotation(annotationType) != null;
- }
-
- @Override
- @Nullable
- public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
- checkNotNull(annotationType);
- for (Annotation annotation : annotations) {
- if (annotationType.isInstance(annotation)) {
- return annotationType.cast(annotation);
- }
- }
- return null;
- }
-
- @Override public Annotation[] getAnnotations() {
- return getDeclaredAnnotations();
- }
-
- @Override public Annotation[] getDeclaredAnnotations() {
- return annotations.toArray(new Annotation[annotations.size()]);
- }
-
- @Override public boolean equals(@Nullable Object obj) {
- if (obj instanceof Parameter) {
- Parameter that = (Parameter) obj;
- return position == that.position && declaration.equals(that.declaration);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return position;
- }
-
- @Override public String toString() {
- return type + " arg" + position;
- }
-}
diff --git a/guava/src/com/google/common/reflect/Reflection.java b/guava/src/com/google/common/reflect/Reflection.java
deleted file mode 100644
index 028c8a9..0000000
--- a/guava/src/com/google/common/reflect/Reflection.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2005 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-/**
- * Static utilities relating to Java reflection.
- *
- * @since 12.0
- */
-@Beta
-public final class Reflection {
-
- /**
- * Returns the package name of {@code clazz} according to the Java Language Specification (section
- * 6.7). Unlike {@link Class#getPackage}, this method only parses the class name, without
- * attempting to define the {@link Package} and hence load files.
- */
- public static String getPackageName(Class<?> clazz) {
- return getPackageName(clazz.getName());
- }
-
- /**
- * Returns the package name of {@code classFullName} according to the Java Language Specification
- * (section 6.7). Unlike {@link Class#getPackage}, this method only parses the class name, without
- * attempting to define the {@link Package} and hence load files.
- */
- public static String getPackageName(String classFullName) {
- int lastDot = classFullName.lastIndexOf('.');
- return (lastDot < 0) ? "" : classFullName.substring(0, lastDot);
- }
-
- /**
- * Ensures that the given classes are initialized, as described in
- * <a href="http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.4.2">
- * JLS Section 12.4.2</a>.
- *
- * <p>WARNING: Normally it's a smell if a class needs to be explicitly initialized, because static
- * state hurts system maintainability and testability. In cases when you have no choice while
- * inter-operating with a legacy framework, this method helps to keep the code less ugly.
- *
- * @throws ExceptionInInitializerError if an exception is thrown during
- * initialization of a class
- */
- public static void initialize(Class<?>... classes) {
- for (Class<?> clazz : classes) {
- try {
- Class.forName(clazz.getName(), true, clazz.getClassLoader());
- } catch (ClassNotFoundException e) {
- throw new AssertionError(e);
- }
- }
- }
-
- /**
- * Returns a proxy instance that implements {@code interfaceType} by
- * dispatching method invocations to {@code handler}. The class loader of
- * {@code interfaceType} will be used to define the proxy class. To implement
- * multiple interfaces or specify a class loader, use
- * {@link Proxy#newProxyInstance}.
- *
- * @throws IllegalArgumentException if {@code interfaceType} does not specify
- * the type of a Java interface
- */
- public static <T> T newProxy(
- Class<T> interfaceType, InvocationHandler handler) {
- checkNotNull(handler);
- checkArgument(interfaceType.isInterface(), "%s is not an interface", interfaceType);
- Object object = Proxy.newProxyInstance(
- interfaceType.getClassLoader(),
- new Class<?>[] { interfaceType },
- handler);
- return interfaceType.cast(object);
- }
-
- private Reflection() {}
-}
diff --git a/guava/src/com/google/common/reflect/TypeCapture.java b/guava/src/com/google/common/reflect/TypeCapture.java
deleted file mode 100644
index c686661..0000000
--- a/guava/src/com/google/common/reflect/TypeCapture.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-
-/**
- * Captures the actual type of {@code T}.
- *
- * @author Ben Yu
- */
-abstract class TypeCapture<T> {
-
- /** Returns the captured type. */
- final Type capture() {
- Type superclass = getClass().getGenericSuperclass();
- checkArgument(superclass instanceof ParameterizedType,
- "%s isn't parameterized", superclass);
- return ((ParameterizedType) superclass).getActualTypeArguments()[0];
- }
-}
diff --git a/guava/src/com/google/common/reflect/TypeParameter.java b/guava/src/com/google/common/reflect/TypeParameter.java
deleted file mode 100644
index 79bf076..0000000
--- a/guava/src/com/google/common/reflect/TypeParameter.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.Beta;
-
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-
-import javax.annotation.Nullable;
-
-/**
- * Captures a free type variable that can be used in {@link TypeToken#where}.
- * For example: <pre> {@code
- *
- * static <T> TypeToken<List<T>> listOf(Class<T> elementType) {
- * return new TypeToken<List<T>>() {}
- * .where(new TypeParameter<T>() {}, elementType);
- * }
- * }</pre>
- *
- * @author Ben Yu
- * @since 12.0
- */
-@Beta
-public abstract class TypeParameter<T> extends TypeCapture<T> {
-
- final TypeVariable<?> typeVariable;
-
- protected TypeParameter() {
- Type type = capture();
- checkArgument(type instanceof TypeVariable, "%s should be a type variable.", type);
- this.typeVariable = (TypeVariable<?>) type;
- }
-
- @Override public final int hashCode() {
- return typeVariable.hashCode();
- }
-
- @Override public final boolean equals(@Nullable Object o) {
- if (o instanceof TypeParameter) {
- TypeParameter<?> that = (TypeParameter<?>) o;
- return typeVariable.equals(that.typeVariable);
- }
- return false;
- }
-
- @Override public String toString() {
- return typeVariable.toString();
- }
-}
diff --git a/guava/src/com/google/common/reflect/TypeResolver.java b/guava/src/com/google/common/reflect/TypeResolver.java
deleted file mode 100644
index 8c2d582..0000000
--- a/guava/src/com/google/common/reflect/TypeResolver.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.Nullable;
-
-/**
- * An object of this class encapsulates type mappings from type variables. Mappings are established
- * with {@link #where} and types are resolved using {@link #resolveType}.
- *
- * <p>Note that usually type mappings are already implied by the static type hierarchy (for example,
- * the {@code E} type variable declared by class {@code List} naturally maps to {@code String} in
- * the context of {@code class MyStringList implements List<String>}. In such case, prefer to use
- * {@link TypeToken#resolveType} since it's simpler and more type safe. This class should only be
- * used when the type mapping isn't implied by the static type hierarchy, but provided through other
- * means such as an annotation or external configuration file.
- *
- * @author Ben Yu
- */
-class TypeResolver {
-
- private final ImmutableMap<TypeVariable<?>, Type> typeTable;
-
- public TypeResolver() {
- this.typeTable = ImmutableMap.of();
- }
-
- private TypeResolver(ImmutableMap<TypeVariable<?>, Type> typeTable) {
- this.typeTable = typeTable;
- }
-
- static TypeResolver accordingTo(Type type) {
- return new TypeResolver().where(TypeMappingIntrospector.getTypeMappings(type));
- }
-
- /**
- * Returns a new {@code TypeResolver} with type variables in {@code formal} mapping to types in
- * {@code actual}.
- *
- * <p>For example, if {@code formal} is a {@code TypeVariable T}, and {@code actual} is {@code
- * String.class}, then {@code new TypeResolver().where(formal, actual)} will {@linkplain
- * #resolveType resolve} {@code ParameterizedType List<T>} to {@code List<String>}, and resolve
- * {@code Map<T, Something>} to {@code Map<String, Something>} etc. Similarly, {@code formal} and
- * {@code actual} can be {@code Map<K, V>} and {@code Map<String, Integer>} respectively, or they
- * can be {@code E[]} and {@code String[]} respectively, or even any arbitrary combination
- * thereof.
- *
- * @param formal The type whose type variables or itself is mapped to other type(s). It's almost
- * always a bug if {@code formal} isn't a type variable and contains no type variable. Make
- * sure you are passing the two parameters in the right order.
- * @param actual The type that the formal type variable(s) are mapped to. It can be or contain yet
- * other type variables, in which case these type variables will be further resolved if
- * corresponding mappings exist in the current {@code TypeResolver} instance.
- */
- public final TypeResolver where(Type formal, Type actual) {
- Map<TypeVariable<?>, Type> mappings = Maps.newHashMap();
- populateTypeMappings(mappings, checkNotNull(formal), checkNotNull(actual));
- return where(mappings);
- }
-
- /** Returns a new {@code TypeResolver} with {@code variable} mapping to {@code type}. */
- final TypeResolver where(Map<? extends TypeVariable<?>, ? extends Type> mappings) {
- ImmutableMap.Builder<TypeVariable<?>, Type> builder = ImmutableMap.builder();
- builder.putAll(typeTable);
- for (Map.Entry<? extends TypeVariable<?>, ? extends Type> mapping : mappings.entrySet()) {
- TypeVariable<?> variable = mapping.getKey();
- Type type = mapping.getValue();
- checkArgument(!variable.equals(type), "Type variable %s bound to itself", variable);
- builder.put(variable, type);
- }
- return new TypeResolver(builder.build());
- }
-
- private static void populateTypeMappings(
- Map<TypeVariable<?>, Type> mappings, Type from, Type to) {
- if (from.equals(to)) {
- return;
- }
- if (from instanceof TypeVariable) {
- mappings.put((TypeVariable<?>) from, to);
- } else if (from instanceof GenericArrayType) {
- populateTypeMappings(mappings,
- ((GenericArrayType) from).getGenericComponentType(),
- checkNonNullArgument(Types.getComponentType(to), "%s is not an array type.", to));
- } else if (from instanceof ParameterizedType) {
- ParameterizedType fromParameterizedType = (ParameterizedType) from;
- ParameterizedType toParameterizedType = expectArgument(ParameterizedType.class, to);
- checkArgument(fromParameterizedType.getRawType().equals(toParameterizedType.getRawType()),
- "Inconsistent raw type: %s vs. %s", from, to);
- Type[] fromArgs = fromParameterizedType.getActualTypeArguments();
- Type[] toArgs = toParameterizedType.getActualTypeArguments();
- checkArgument(fromArgs.length == toArgs.length);
- for (int i = 0; i < fromArgs.length; i++) {
- populateTypeMappings(mappings, fromArgs[i], toArgs[i]);
- }
- } else if (from instanceof WildcardType) {
- WildcardType fromWildcardType = (WildcardType) from;
- WildcardType toWildcardType = expectArgument(WildcardType.class, to);
- Type[] fromUpperBounds = fromWildcardType.getUpperBounds();
- Type[] toUpperBounds = toWildcardType.getUpperBounds();
- Type[] fromLowerBounds = fromWildcardType.getLowerBounds();
- Type[] toLowerBounds = toWildcardType.getLowerBounds();
- checkArgument(
- fromUpperBounds.length == toUpperBounds.length
- && fromLowerBounds.length == toLowerBounds.length,
- "Incompatible type: %s vs. %s", from, to);
- for (int i = 0; i < fromUpperBounds.length; i++) {
- populateTypeMappings(mappings, fromUpperBounds[i], toUpperBounds[i]);
- }
- for (int i = 0; i < fromLowerBounds.length; i++) {
- populateTypeMappings(mappings, fromLowerBounds[i], toLowerBounds[i]);
- }
- } else {
- throw new IllegalArgumentException("No type mapping from " + from);
- }
- }
-
- /**
- * Resolves all type variables in {@code type} and all downstream types and
- * returns a corresponding type with type variables resolved.
- */
- public final Type resolveType(Type type) {
- checkNotNull(type);
- if (type instanceof TypeVariable) {
- return resolveTypeVariable((TypeVariable<?>) type);
- } else if (type instanceof ParameterizedType) {
- return resolveParameterizedType((ParameterizedType) type);
- } else if (type instanceof GenericArrayType) {
- return resolveGenericArrayType((GenericArrayType) type);
- } else if (type instanceof WildcardType) {
- WildcardType wildcardType = (WildcardType) type;
- return new Types.WildcardTypeImpl(
- resolveTypes(wildcardType.getLowerBounds()),
- resolveTypes(wildcardType.getUpperBounds()));
- } else {
- // if Class<?>, no resolution needed, we are done.
- return type;
- }
- }
-
- private Type[] resolveTypes(Type[] types) {
- Type[] result = new Type[types.length];
- for (int i = 0; i < types.length; i++) {
- result[i] = resolveType(types[i]);
- }
- return result;
- }
-
- private Type resolveGenericArrayType(GenericArrayType type) {
- Type componentType = resolveType(type.getGenericComponentType());
- return Types.newArrayType(componentType);
- }
-
- private Type resolveTypeVariable(final TypeVariable<?> var) {
- final TypeResolver unguarded = this;
- TypeResolver guarded = new TypeResolver(typeTable) {
- @Override Type resolveTypeVariable(
- TypeVariable<?> intermediateVar, TypeResolver guardedResolver) {
- if (intermediateVar.getGenericDeclaration().equals(var.getGenericDeclaration())) {
- return intermediateVar;
- }
- return unguarded.resolveTypeVariable(intermediateVar, guardedResolver);
- }
- };
- return resolveTypeVariable(var, guarded);
- }
-
- /**
- * Resolves {@code var} using the encapsulated type mapping. If it maps to yet another
- * non-reified type, {@code guardedResolver} is used to do further resolution, which doesn't try
- * to resolve any type variable on generic declarations that are already being resolved.
- */
- Type resolveTypeVariable(TypeVariable<?> var, TypeResolver guardedResolver) {
- checkNotNull(guardedResolver);
- Type type = typeTable.get(var);
- if (type == null) {
- Type[] bounds = var.getBounds();
- if (bounds.length == 0) {
- return var;
- }
- return Types.newTypeVariable(
- var.getGenericDeclaration(),
- var.getName(),
- guardedResolver.resolveTypes(bounds));
- }
- return guardedResolver.resolveType(type); // in case the type is yet another type variable.
- }
-
- private ParameterizedType resolveParameterizedType(ParameterizedType type) {
- Type owner = type.getOwnerType();
- Type resolvedOwner = (owner == null) ? null : resolveType(owner);
- Type resolvedRawType = resolveType(type.getRawType());
-
- Type[] vars = type.getActualTypeArguments();
- Type[] resolvedArgs = new Type[vars.length];
- for (int i = 0; i < vars.length; i++) {
- resolvedArgs[i] = resolveType(vars[i]);
- }
- return Types.newParameterizedTypeWithOwner(
- resolvedOwner, (Class<?>) resolvedRawType, resolvedArgs);
- }
-
- private static <T> T checkNonNullArgument(T arg, String format, Object... messageParams) {
- checkArgument(arg != null, format, messageParams);
- return arg;
- }
-
- private static <T> T expectArgument(Class<T> type, Object arg) {
- try {
- return type.cast(arg);
- } catch (ClassCastException e) {
- throw new IllegalArgumentException(arg + " is not a " + type.getSimpleName());
- }
- }
-
- private static final class TypeMappingIntrospector {
-
- private static final WildcardCapturer wildcardCapturer = new WildcardCapturer();
-
- private final Map<TypeVariable<?>, Type> mappings = Maps.newHashMap();
- private final Set<Type> introspectedTypes = Sets.newHashSet();
-
- /**
- * Returns type mappings using type parameters and type arguments found in
- * the generic superclass and the super interfaces of {@code contextClass}.
- */
- static ImmutableMap<TypeVariable<?>, Type> getTypeMappings(
- Type contextType) {
- TypeMappingIntrospector introspector = new TypeMappingIntrospector();
- introspector.introspect(wildcardCapturer.capture(contextType));
- return ImmutableMap.copyOf(introspector.mappings);
- }
-
- private void introspect(Type type) {
- if (!introspectedTypes.add(type)) {
- return;
- }
- if (type instanceof ParameterizedType) {
- introspectParameterizedType((ParameterizedType) type);
- } else if (type instanceof Class) {
- introspectClass((Class<?>) type);
- } else if (type instanceof TypeVariable) {
- for (Type bound : ((TypeVariable<?>) type).getBounds()) {
- introspect(bound);
- }
- } else if (type instanceof WildcardType) {
- for (Type bound : ((WildcardType) type).getUpperBounds()) {
- introspect(bound);
- }
- }
- }
-
- private void introspectClass(Class<?> clazz) {
- introspect(clazz.getGenericSuperclass());
- for (Type interfaceType : clazz.getGenericInterfaces()) {
- introspect(interfaceType);
- }
- }
-
- private void introspectParameterizedType(
- ParameterizedType parameterizedType) {
- Class<?> rawClass = (Class<?>) parameterizedType.getRawType();
- TypeVariable<?>[] vars = rawClass.getTypeParameters();
- Type[] typeArgs = parameterizedType.getActualTypeArguments();
- checkState(vars.length == typeArgs.length);
- for (int i = 0; i < vars.length; i++) {
- map(vars[i], typeArgs[i]);
- }
- introspectClass(rawClass);
- introspect(parameterizedType.getOwnerType());
- }
-
- private void map(final TypeVariable<?> var, final Type arg) {
- if (mappings.containsKey(var)) {
- // Mapping already established
- // This is possible when following both superClass -> enclosingClass
- // and enclosingclass -> superClass paths.
- // Since we follow the path of superclass first, enclosing second,
- // superclass mapping should take precedence.
- return;
- }
- // First, check whether var -> arg forms a cycle
- for (Type t = arg; t != null; t = mappings.get(t)) {
- if (var.equals(t)) {
- // cycle detected, remove the entire cycle from the mapping so that
- // each type variable resolves deterministically to itself.
- // Otherwise, a F -> T cycle will end up resolving both F and T
- // nondeterministically to either F or T.
- for (Type x = arg; x != null; x = mappings.remove(x)) {}
- return;
- }
- }
- mappings.put(var, arg);
- }
- }
-
- // This is needed when resolving types against a context with wildcards
- // For example:
- // class Holder<T> {
- // void set(T data) {...}
- // }
- // Holder<List<?>> should *not* resolve the set() method to set(List<?> data).
- // Instead, it should create a capture of the wildcard so that set() rejects any List<T>.
- private static final class WildcardCapturer {
-
- private final AtomicInteger id = new AtomicInteger();
-
- Type capture(Type type) {
- checkNotNull(type);
- if (type instanceof Class) {
- return type;
- }
- if (type instanceof TypeVariable) {
- return type;
- }
- if (type instanceof GenericArrayType) {
- GenericArrayType arrayType = (GenericArrayType) type;
- return Types.newArrayType(capture(arrayType.getGenericComponentType()));
- }
- if (type instanceof ParameterizedType) {
- ParameterizedType parameterizedType = (ParameterizedType) type;
- return Types.newParameterizedTypeWithOwner(
- captureNullable(parameterizedType.getOwnerType()),
- (Class<?>) parameterizedType.getRawType(),
- capture(parameterizedType.getActualTypeArguments()));
- }
- if (type instanceof WildcardType) {
- WildcardType wildcardType = (WildcardType) type;
- Type[] lowerBounds = wildcardType.getLowerBounds();
- if (lowerBounds.length == 0) { // ? extends something changes to capture-of
- Type[] upperBounds = wildcardType.getUpperBounds();
- String name = "capture#" + id.incrementAndGet() + "-of ? extends "
- + Joiner.on('&').join(upperBounds);
- return Types.newTypeVariable(
- WildcardCapturer.class, name, wildcardType.getUpperBounds());
- } else {
- // TODO(benyu): handle ? super T somehow.
- return type;
- }
- }
- throw new AssertionError("must have been one of the known types");
- }
-
- private Type captureNullable(@Nullable Type type) {
- if (type == null) {
- return null;
- }
- return capture(type);
- }
-
- private Type[] capture(Type[] types) {
- Type[] result = new Type[types.length];
- for (int i = 0; i < types.length; i++) {
- result[i] = capture(types[i]);
- }
- return result;
- }
- }
-}
diff --git a/guava/src/com/google/common/reflect/TypeToInstanceMap.java b/guava/src/com/google/common/reflect/TypeToInstanceMap.java
deleted file mode 100644
index 3b00820..0000000
--- a/guava/src/com/google/common/reflect/TypeToInstanceMap.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import com.google.common.annotations.Beta;
-
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-/**
- * A map, each entry of which maps a {@link TypeToken} to an instance of that type.
- * In addition to implementing {@code Map}, the additional type-safe operations
- * {@link #putInstance} and {@link #getInstance} are available.
- *
- * <p>Generally, implementations don't support {@link #put} and {@link #putAll}
- * because there is no way to check an object at runtime to be an instance of a
- * {@link TypeToken}. Instead, caller should use the type safe {@link #putInstance}.
- *
- * <p>Also, if caller suppresses unchecked warnings and passes in an {@code Iterable<String>}
- * for type {@code Iterable<Integer>}, the map won't be able to detect and throw type error.
- *
- * <p>Like any other {@code Map<Class, Object>}, this map may contain entries
- * for primitive types, and a primitive type and its corresponding wrapper type
- * may map to different values.
- *
- * @param <B> the common supertype that all entries must share; often this is
- * simply {@link Object}
- *
- * @author Ben Yu
- * @since 13.0
- */
-@Beta
-public interface TypeToInstanceMap<B> extends Map<TypeToken<? extends B>, B> {
-
- /**
- * Returns the value the specified class is mapped to, or {@code null} if no
- * entry for this class is present. This will only return a value that was
- * bound to this specific class, not a value that may have been bound to a
- * subtype.
- *
- * <p>{@code getInstance(Foo.class)} is equivalent to
- * {@code getInstance(TypeToken.of(Foo.class))}.
- */
- @Nullable
- <T extends B> T getInstance(Class<T> type);
-
- /**
- * Maps the specified class to the specified value. Does <i>not</i> associate
- * this value with any of the class's supertypes.
- *
- * <p>{@code putInstance(Foo.class, foo)} is equivalent to
- * {@code putInstance(TypeToken.of(Foo.class), foo)}.
- *
- * @return the value previously associated with this class (possibly {@code null}),
- * or {@code null} if there was no previous entry.
- */
- @Nullable
- <T extends B> T putInstance(Class<T> type, @Nullable T value);
-
- /**
- * Returns the value the specified type is mapped to, or {@code null} if no
- * entry for this type is present. This will only return a value that was
- * bound to this specific type, not a value that may have been bound to a subtype.
- */
- @Nullable
- <T extends B> T getInstance(TypeToken<T> type);
-
- /**
- * Maps the specified type to the specified value. Does <i>not</i> associate
- * this value with any of the type's supertypes.
- *
- * @return the value previously associated with this type (possibly {@code null}),
- * or {@code null} if there was no previous entry.
- */
- @Nullable
- <T extends B> T putInstance(TypeToken<T> type, @Nullable T value);
-}
diff --git a/guava/src/com/google/common/reflect/TypeToken.java b/guava/src/com/google/common/reflect/TypeToken.java
deleted file mode 100644
index 61469b5..0000000
--- a/guava/src/com/google/common/reflect/TypeToken.java
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*
- * Copyright (C) 2006 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ForwardingSet;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * A {@link Type} with generics.
- *
- * <p>Operations that are otherwise only available in {@link Class} are implemented to support
- * {@code Type}, for example {@link #isAssignableFrom}, {@link #isArray} and {@link
- * #getComponentType}. It also provides additional utilities such as {@link #getTypes} and {@link
- * #resolveType} etc.
- *
- * <p>There are three ways to get a {@code TypeToken} instance: <ul>
- * <li>Wrap a {@code Type} obtained via reflection. For example: {@code
- * TypeToken.of(method.getGenericReturnType())}.
- * <li>Capture a generic type with a (usually anonymous) subclass. For example: <pre> {@code
- *
- * new TypeToken<List<String>>() {}
- * }</pre>
- * Note that it's critical that the actual type argument is carried by a subclass.
- * The following code is wrong because it only captures the {@code <T>} type variable
- * of the {@code listType()} method signature; while {@code <String>} is lost in erasure:
- * <pre> {@code
- *
- * class Util {
- * static <T> TypeToken<List<T>> listType() {
- * return new TypeToken<List<T>>() {};
- * }
- * }
- *
- * TypeToken<List<String>> stringListType = Util.<String>listType();
- * }</pre>
- * <li>Capture a generic type with a (usually anonymous) subclass and resolve it against
- * a context class that knows what the type parameters are. For example: <pre> {@code
- * abstract class IKnowMyType<T> {
- * TypeToken<T> type = new TypeToken<T>(getClass()) {};
- * }
- * new IKnowMyType<String>() {}.type => String
- * }</pre>
- * </ul>
- *
- * <p>{@code TypeToken} is serializable when no type variable is contained in the type.
- *
- * <p>Note to Guice users: {@code} TypeToken is similar to Guice's {@code TypeLiteral} class,
- * but with one important difference: it supports non-reified types such as {@code T},
- * {@code List<T>} or even {@code List<? extends Number>}; while TypeLiteral does not.
- * TypeToken is also serializable and offers numerous additional utility methods.
- *
- * @author Bob Lee
- * @author Sven Mawson
- * @author Ben Yu
- * @since 12.0
- */
-@Beta
-@SuppressWarnings("serial") // SimpleTypeToken is the serialized form.
-public abstract class TypeToken<T> extends TypeCapture<T> implements Serializable {
-
- private final Type runtimeType;
-
- /** Resolver for resolving types with {@link #runtimeType} as context. */
- private transient TypeResolver typeResolver;
-
- /**
- * Constructs a new type token of {@code T}.
- *
- * <p>Clients create an empty anonymous subclass. Doing so embeds the type
- * parameter in the anonymous class's type hierarchy so we can reconstitute
- * it at runtime despite erasure.
- *
- * <p>For example: <pre> {@code
- *
- * TypeToken<List<String>> t = new TypeToken<List<String>>() {};
- * }</pre>
- */
- protected TypeToken() {
- this.runtimeType = capture();
- checkState(!(runtimeType instanceof TypeVariable),
- "Cannot construct a TypeToken for a type variable.\n" +
- "You probably meant to call new TypeToken<%s>(getClass()) " +
- "that can resolve the type variable for you.\n" +
- "If you do need to create a TypeToken of a type variable, " +
- "please use TypeToken.of() instead.", runtimeType);
- }
-
- /**
- * Constructs a new type token of {@code T} while resolving free type variables in the context of
- * {@code declaringClass}.
- *
- * <p>Clients create an empty anonymous subclass. Doing so embeds the type
- * parameter in the anonymous class's type hierarchy so we can reconstitute
- * it at runtime despite erasure.
- *
- * <p>For example: <pre> {@code
- *
- * abstract class IKnowMyType<T> {
- * TypeToken<T> getMyType() {
- * return new TypeToken<T>(getClass()) {};
- * }
- * }
- *
- * new IKnowMyType<String>() {}.getMyType() => String
- * }</pre>
- */
- protected TypeToken(Class<?> declaringClass) {
- Type captured = super.capture();
- if (captured instanceof Class) {
- this.runtimeType = captured;
- } else {
- this.runtimeType = of(declaringClass).resolveType(captured).runtimeType;
- }
- }
-
- private TypeToken(Type type) {
- this.runtimeType = checkNotNull(type);
- }
-
- /** Returns an instance of type token that wraps {@code type}. */
- public static <T> TypeToken<T> of(Class<T> type) {
- return new SimpleTypeToken<T>(type);
- }
-
- /** Returns an instance of type token that wraps {@code type}. */
- public static TypeToken<?> of(Type type) {
- return new SimpleTypeToken<Object>(type);
- }
-
- /**
- * Returns the raw type of {@code T}. Formally speaking, if {@code T} is returned by
- * {@link java.lang.reflect.Method#getGenericReturnType}, the raw type is what's returned by
- * {@link java.lang.reflect.Method#getReturnType} of the same method object. Specifically:
- * <ul>
- * <li>If {@code T} is a {@code Class} itself, {@code T} itself is returned.
- * <li>If {@code T} is a {@link ParameterizedType}, the raw type of the parameterized type is
- * returned.
- * <li>If {@code T} is a {@link GenericArrayType}, the returned type is the corresponding array
- * class. For example: {@code List<Integer>[] => List[]}.
- * <li>If {@code T} is a type variable or a wildcard type, the raw type of the first upper bound
- * is returned. For example: {@code <X extends Foo> => Foo}.
- * </ul>
- */
- public final Class<? super T> getRawType() {
- Class<?> rawType = getRawType(runtimeType);
- @SuppressWarnings("unchecked") // raw type is |T|
- Class<? super T> result = (Class<? super T>) rawType;
- return result;
- }
-
- /**
- * Returns the raw type of the class or parameterized type; if {@code T} is type variable or
- * wildcard type, the raw types of all its upper bounds are returned.
- */
- private ImmutableSet<Class<? super T>> getImmediateRawTypes() {
- // Cast from ImmutableSet<Class<?>> to ImmutableSet<Class<? super T>>
- @SuppressWarnings({"unchecked", "rawtypes"})
- ImmutableSet<Class<? super T>> result = (ImmutableSet) getRawTypes(runtimeType);
- return result;
- }
-
- /** Returns the represented type. */
- public final Type getType() {
- return runtimeType;
- }
-
- /**
- * Returns a new {@code TypeToken} where type variables represented by {@code typeParam}
- * are substituted by {@code typeArg}. For example, it can be used to construct
- * {@code Map<K, V>} for any {@code K} and {@code V} type: <pre> {@code
- *
- * static <K, V> TypeToken<Map<K, V>> mapOf(
- * TypeToken<K> keyType, TypeToken<V> valueType) {
- * return new TypeToken<Map<K, V>>() {}
- * .where(new TypeParameter<K>() {}, keyType)
- * .where(new TypeParameter<V>() {}, valueType);
- * }
- * }</pre>
- *
- * @param <X> The parameter type
- * @param typeParam the parameter type variable
- * @param typeArg the actual type to substitute
- */
- public final <X> TypeToken<T> where(TypeParameter<X> typeParam, TypeToken<X> typeArg) {
- TypeResolver resolver = new TypeResolver()
- .where(ImmutableMap.of(typeParam.typeVariable, typeArg.runtimeType));
- // If there's any type error, we'd report now rather than later.
- return new SimpleTypeToken<T>(resolver.resolveType(runtimeType));
- }
-
- /**
- * Returns a new {@code TypeToken} where type variables represented by {@code typeParam}
- * are substituted by {@code typeArg}. For example, it can be used to construct
- * {@code Map<K, V>} for any {@code K} and {@code V} type: <pre> {@code
- *
- * static <K, V> TypeToken<Map<K, V>> mapOf(
- * Class<K> keyType, Class<V> valueType) {
- * return new TypeToken<Map<K, V>>() {}
- * .where(new TypeParameter<K>() {}, keyType)
- * .where(new TypeParameter<V>() {}, valueType);
- * }
- * }</pre>
- *
- * @param <X> The parameter type
- * @param typeParam the parameter type variable
- * @param typeArg the actual type to substitute
- */
- public final <X> TypeToken<T> where(TypeParameter<X> typeParam, Class<X> typeArg) {
- return where(typeParam, of(typeArg));
- }
-
- /**
- * Resolves the given {@code type} against the type context represented by this type.
- * For example: <pre> {@code
- *
- * new TypeToken<List<String>>() {}.resolveType(
- * List.class.getMethod("get", int.class).getGenericReturnType())
- * => String.class
- * }</pre>
- */
- public final TypeToken<?> resolveType(Type type) {
- checkNotNull(type);
- TypeResolver resolver = typeResolver;
- if (resolver == null) {
- resolver = (typeResolver = TypeResolver.accordingTo(runtimeType));
- }
- return of(resolver.resolveType(type));
- }
-
- private Type[] resolveInPlace(Type[] types) {
- for (int i = 0; i < types.length; i++) {
- types[i] = resolveType(types[i]).getType();
- }
- return types;
- }
-
- private TypeToken<?> resolveSupertype(Type type) {
- TypeToken<?> supertype = resolveType(type);
- // super types' type mapping is a subset of type mapping of this type.
- supertype.typeResolver = typeResolver;
- return supertype;
- }
-
- /**
- * Returns the generic superclass of this type or {@code null} if the type represents
- * {@link Object} or an interface. This method is similar but different from {@link
- * Class#getGenericSuperclass}. For example, {@code
- * new TypeToken<StringArrayList>() {}.getGenericSuperclass()} will return {@code
- * new TypeToken<ArrayList<String>>() {}}; while {@code
- * StringArrayList.class.getGenericSuperclass()} will return {@code ArrayList<E>}, where {@code E}
- * is the type variable declared by class {@code ArrayList}.
- *
- * <p>If this type is a type variable or wildcard, its first upper bound is examined and returned
- * if the bound is a class or extends from a class. This means that the returned type could be a
- * type variable too.
- */
- @Nullable
- final TypeToken<? super T> getGenericSuperclass() {
- if (runtimeType instanceof TypeVariable) {
- // First bound is always the super class, if one exists.
- return boundAsSuperclass(((TypeVariable<?>) runtimeType).getBounds()[0]);
- }
- if (runtimeType instanceof WildcardType) {
- // wildcard has one and only one upper bound.
- return boundAsSuperclass(((WildcardType) runtimeType).getUpperBounds()[0]);
- }
- Type superclass = getRawType().getGenericSuperclass();
- if (superclass == null) {
- return null;
- }
- @SuppressWarnings("unchecked") // super class of T
- TypeToken<? super T> superToken = (TypeToken<? super T>) resolveSupertype(superclass);
- return superToken;
- }
-
- @Nullable private TypeToken<? super T> boundAsSuperclass(Type bound) {
- TypeToken<?> token = of(bound);
- if (token.getRawType().isInterface()) {
- return null;
- }
- @SuppressWarnings("unchecked") // only upper bound of T is passed in.
- TypeToken<? super T> superclass = (TypeToken<? super T>) token;
- return superclass;
- }
-
- /**
- * Returns the generic interfaces that this type directly {@code implements}. This method is
- * similar but different from {@link Class#getGenericInterfaces()}. For example, {@code
- * new TypeToken<List<String>>() {}.getGenericInterfaces()} will return a list that contains
- * {@code new TypeToken<Iterable<String>>() {}}; while {@code List.class.getGenericInterfaces()}
- * will return an array that contains {@code Iterable<T>}, where the {@code T} is the type
- * variable declared by interface {@code Iterable}.
- *
- * <p>If this type is a type variable or wildcard, its upper bounds are examined and those that
- * are either an interface or upper-bounded only by interfaces are returned. This means that the
- * returned types could include type variables too.
- */
- final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
- if (runtimeType instanceof TypeVariable) {
- return boundsAsInterfaces(((TypeVariable<?>) runtimeType).getBounds());
- }
- if (runtimeType instanceof WildcardType) {
- return boundsAsInterfaces(((WildcardType) runtimeType).getUpperBounds());
- }
- ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
- for (Type interfaceType : getRawType().getGenericInterfaces()) {
- @SuppressWarnings("unchecked") // interface of T
- TypeToken<? super T> resolvedInterface = (TypeToken<? super T>)
- resolveSupertype(interfaceType);
- builder.add(resolvedInterface);
- }
- return builder.build();
- }
-
- private ImmutableList<TypeToken<? super T>> boundsAsInterfaces(Type[] bounds) {
- ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
- for (Type bound : bounds) {
- @SuppressWarnings("unchecked") // upper bound of T
- TypeToken<? super T> boundType = (TypeToken<? super T>) of(bound);
- if (boundType.getRawType().isInterface()) {
- builder.add(boundType);
- }
- }
- return builder.build();
- }
-
- /**
- * Returns the set of interfaces and classes that this type is or is a subtype of. The returned
- * types are parameterized with proper type arguments.
- *
- * <p>Subtypes are always listed before supertypes. But the reverse is not true. A type isn't
- * necessarily a subtype of all the types following. Order between types without subtype
- * relationship is arbitrary and not guaranteed.
- *
- * <p>If this type is a type variable or wildcard, upper bounds that are themselves type variables
- * aren't included (their super interfaces and superclasses are).
- */
- public final TypeSet getTypes() {
- return new TypeSet();
- }
-
- /**
- * Returns the generic form of {@code superclass}. For example, if this is
- * {@code ArrayList<String>}, {@code Iterable<String>} is returned given the
- * input {@code Iterable.class}.
- */
- public final TypeToken<? super T> getSupertype(Class<? super T> superclass) {
- checkArgument(superclass.isAssignableFrom(getRawType()),
- "%s is not a super class of %s", superclass, this);
- if (runtimeType instanceof TypeVariable) {
- return getSupertypeFromUpperBounds(superclass, ((TypeVariable<?>) runtimeType).getBounds());
- }
- if (runtimeType instanceof WildcardType) {
- return getSupertypeFromUpperBounds(superclass, ((WildcardType) runtimeType).getUpperBounds());
- }
- if (superclass.isArray()) {
- return getArraySupertype(superclass);
- }
- @SuppressWarnings("unchecked") // resolved supertype
- TypeToken<? super T> supertype = (TypeToken<? super T>)
- resolveSupertype(toGenericType(superclass).runtimeType);
- return supertype;
- }
-
- /**
- * Returns subtype of {@code this} with {@code subclass} as the raw class.
- * For example, if this is {@code Iterable<String>} and {@code subclass} is {@code List},
- * {@code List<String>} is returned.
- */
- public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
- checkArgument(!(runtimeType instanceof TypeVariable),
- "Cannot get subtype of type variable <%s>", this);
- if (runtimeType instanceof WildcardType) {
- return getSubtypeFromLowerBounds(subclass, ((WildcardType) runtimeType).getLowerBounds());
- }
- checkArgument(getRawType().isAssignableFrom(subclass),
- "%s isn't a subclass of %s", subclass, this);
- // unwrap array type if necessary
- if (isArray()) {
- return getArraySubtype(subclass);
- }
- @SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
- TypeToken<? extends T> subtype = (TypeToken<? extends T>)
- of(resolveTypeArgsForSubclass(subclass));
- return subtype;
- }
-
- /** Returns true if this type is assignable from the given {@code type}. */
- public final boolean isAssignableFrom(TypeToken<?> type) {
- return isAssignableFrom(type.runtimeType);
- }
-
- /** Check if this type is assignable from the given {@code type}. */
- public final boolean isAssignableFrom(Type type) {
- return isAssignable(checkNotNull(type), runtimeType);
- }
-
- /**
- * Returns true if this type is known to be an array type, such as {@code int[]}, {@code T[]},
- * {@code <? extends Map<String, Integer>[]>} etc.
- */
- public final boolean isArray() {
- return getComponentType() != null;
- }
-
- /**
- * Returns the array component type if this type represents an array ({@code int[]}, {@code T[]},
- * {@code <? extends Map<String, Integer>[]>} etc.), or else {@code null} is returned.
- */
- @Nullable public final TypeToken<?> getComponentType() {
- Type componentType = Types.getComponentType(runtimeType);
- if (componentType == null) {
- return null;
- }
- return of(componentType);
- }
-
- /**
- * Returns the {@link Invokable} for {@code method}, which must be a member of {@code T}.
- *
- * @since 14.0
- */
- public final Invokable<T, Object> method(Method method) {
- checkArgument(of(method.getDeclaringClass()).isAssignableFrom(this),
- "%s not declared by %s", method, this);
- return new Invokable.MethodInvokable<T>(method) {
- @Override Type getGenericReturnType() {
- return resolveType(super.getGenericReturnType()).getType();
- }
- @Override Type[] getGenericParameterTypes() {
- return resolveInPlace(super.getGenericParameterTypes());
- }
- @Override Type[] getGenericExceptionTypes() {
- return resolveInPlace(super.getGenericExceptionTypes());
- }
- @Override public TypeToken<T> getOwnerType() {
- return TypeToken.this;
- }
- };
- }
-
- /**
- * Returns the {@link Invokable} for {@code constructor}, which must be a member of {@code T}.
- *
- * @since 14.0
- */
- public final Invokable<T, T> constructor(Constructor<?> constructor) {
- checkArgument(constructor.getDeclaringClass() == getRawType(),
- "%s not declared by %s", constructor, getRawType());
- return new Invokable.ConstructorInvokable<T>(constructor) {
- @Override Type getGenericReturnType() {
- return resolveType(super.getGenericReturnType()).getType();
- }
- @Override Type[] getGenericParameterTypes() {
- return resolveInPlace(super.getGenericParameterTypes());
- }
- @Override Type[] getGenericExceptionTypes() {
- return resolveInPlace(super.getGenericExceptionTypes());
- }
- @Override public TypeToken<T> getOwnerType() {
- return TypeToken.this;
- }
- };
- }
-
- /**
- * The set of interfaces and classes that {@code T} is or is a subtype of. {@link Object} is not
- * included in the set if this type is an interface.
- */
- public class TypeSet extends ForwardingSet<TypeToken<? super T>> implements Serializable {
-
- private transient ImmutableSet<TypeToken<? super T>> types;
-
- TypeSet() {}
-
- /** Returns the types that are interfaces implemented by this type. */
- public TypeSet interfaces() {
- return new InterfaceSet(this);
- }
-
- /** Returns the types that are classes. */
- public TypeSet classes() {
- return new ClassSet();
- }
-
- @Override protected Set<TypeToken<? super T>> delegate() {
- ImmutableSet<TypeToken<? super T>> filteredTypes = types;
- if (filteredTypes == null) {
- // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
- @SuppressWarnings({"unchecked", "rawtypes"})
- ImmutableList<TypeToken<? super T>> collectedTypes = (ImmutableList)
- TypeCollector.FOR_GENERIC_TYPE.collectTypes(TypeToken.this);
- return (types = FluentIterable.from(collectedTypes)
- .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
- .toSet());
- } else {
- return filteredTypes;
- }
- }
-
- /** Returns the raw types of the types in this set, in the same order. */
- public Set<Class<? super T>> rawTypes() {
- // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
- @SuppressWarnings({"unchecked", "rawtypes"})
- ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
- TypeCollector.FOR_RAW_TYPE.collectTypes(getImmediateRawTypes());
- return ImmutableSet.copyOf(collectedTypes);
- }
-
- private static final long serialVersionUID = 0;
- }
-
- private final class InterfaceSet extends TypeSet {
-
- private transient final TypeSet allTypes;
- private transient ImmutableSet<TypeToken<? super T>> interfaces;
-
- InterfaceSet(TypeSet allTypes) {
- this.allTypes = allTypes;
- }
-
- @Override protected Set<TypeToken<? super T>> delegate() {
- ImmutableSet<TypeToken<? super T>> result = interfaces;
- if (result == null) {
- return (interfaces = FluentIterable.from(allTypes)
- .filter(TypeFilter.INTERFACE_ONLY)
- .toSet());
- } else {
- return result;
- }
- }
-
- @Override public TypeSet interfaces() {
- return this;
- }
-
- @Override public Set<Class<? super T>> rawTypes() {
- // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
- @SuppressWarnings({"unchecked", "rawtypes"})
- ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
- TypeCollector.FOR_RAW_TYPE.collectTypes(getImmediateRawTypes());
- return FluentIterable.from(collectedTypes)
- .filter(new Predicate<Class<?>>() {
- @Override public boolean apply(Class<?> type) {
- return type.isInterface();
- }
- })
- .toSet();
- }
-
- @Override public TypeSet classes() {
- throw new UnsupportedOperationException("interfaces().classes() not supported.");
- }
-
- private Object readResolve() {
- return getTypes().interfaces();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- private final class ClassSet extends TypeSet {
-
- private transient ImmutableSet<TypeToken<? super T>> classes;
-
- @Override protected Set<TypeToken<? super T>> delegate() {
- ImmutableSet<TypeToken<? super T>> result = classes;
- if (result == null) {
- @SuppressWarnings({"unchecked", "rawtypes"})
- ImmutableList<TypeToken<? super T>> collectedTypes = (ImmutableList)
- TypeCollector.FOR_GENERIC_TYPE.classesOnly().collectTypes(TypeToken.this);
- return (classes = FluentIterable.from(collectedTypes)
- .filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD)
- .toSet());
- } else {
- return result;
- }
- }
-
- @Override public TypeSet classes() {
- return this;
- }
-
- @Override public Set<Class<? super T>> rawTypes() {
- // Java has no way to express ? super T when we parameterize TypeToken vs. Class.
- @SuppressWarnings({"unchecked", "rawtypes"})
- ImmutableList<Class<? super T>> collectedTypes = (ImmutableList)
- TypeCollector.FOR_RAW_TYPE.classesOnly().collectTypes(getImmediateRawTypes());
- return ImmutableSet.copyOf(collectedTypes);
- }
-
- @Override public TypeSet interfaces() {
- throw new UnsupportedOperationException("classes().interfaces() not supported.");
- }
-
- private Object readResolve() {
- return getTypes().classes();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- private enum TypeFilter implements Predicate<TypeToken<?>> {
-
- IGNORE_TYPE_VARIABLE_OR_WILDCARD {
- @Override public boolean apply(TypeToken<?> type) {
- return !(type.runtimeType instanceof TypeVariable
- || type.runtimeType instanceof WildcardType);
- }
- },
- INTERFACE_ONLY {
- @Override public boolean apply(TypeToken<?> type) {
- return type.getRawType().isInterface();
- }
- }
- }
-
- /**
- * Returns true if {@code o} is another {@code TypeToken} that represents the same {@link Type}.
- */
- @Override public boolean equals(@Nullable Object o) {
- if (o instanceof TypeToken) {
- TypeToken<?> that = (TypeToken<?>) o;
- return runtimeType.equals(that.runtimeType);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return runtimeType.hashCode();
- }
-
- @Override public String toString() {
- return Types.toString(runtimeType);
- }
-
- /** Implemented to support serialization of subclasses. */
- protected Object writeReplace() {
- // TypeResolver just transforms the type to our own impls that are Serializable
- // except TypeVariable.
- return of(new TypeResolver().resolveType(runtimeType));
- }
-
- /**
- * Ensures that this type token doesn't contain type variables, which can cause unchecked type
- * errors for callers like {@link TypeToInstanceMap}.
- */
- final TypeToken<T> rejectTypeVariables() {
- checkArgument(!Types.containsTypeVariable(runtimeType),
- "%s contains a type variable and is not safe for the operation");
- return this;
- }
-
- private static boolean isAssignable(Type from, Type to) {
- if (to.equals(from)) {
- return true;
- }
- if (to instanceof WildcardType) {
- return isAssignableToWildcardType(from, (WildcardType) to);
- }
- // if "from" is type variable, it's assignable if any of its "extends"
- // bounds is assignable to "to".
- if (from instanceof TypeVariable) {
- return isAssignableFromAny(((TypeVariable<?>) from).getBounds(), to);
- }
- // if "from" is wildcard, it'a assignable to "to" if any of its "extends"
- // bounds is assignable to "to".
- if (from instanceof WildcardType) {
- return isAssignableFromAny(((WildcardType) from).getUpperBounds(), to);
- }
- if (from instanceof GenericArrayType) {
- return isAssignableFromGenericArrayType((GenericArrayType) from, to);
- }
- // Proceed to regular Type assignability check
- if (to instanceof Class) {
- return isAssignableToClass(from, (Class<?>) to);
- } else if (to instanceof ParameterizedType) {
- return isAssignableToParameterizedType(from, (ParameterizedType) to);
- } else if (to instanceof GenericArrayType) {
- return isAssignableToGenericArrayType(from, (GenericArrayType) to);
- } else { // to instanceof TypeVariable
- return false;
- }
- }
-
- private static boolean isAssignableFromAny(Type[] fromTypes, Type to) {
- for (Type from : fromTypes) {
- if (isAssignable(from, to)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isAssignableToClass(Type from, Class<?> to) {
- return to.isAssignableFrom(getRawType(from));
- }
-
- private static boolean isAssignableToWildcardType(
- Type from, WildcardType to) {
- // if "to" is <? extends Foo>, "from" can be:
- // Foo, SubFoo, <? extends Foo>, <? extends SubFoo>, <T extends Foo> or
- // <T extends SubFoo>.
- // if "to" is <? super Foo>, "from" can be:
- // Foo, SuperFoo, <? super Foo> or <? super SuperFoo>.
- return isAssignable(from, supertypeBound(to)) && isAssignableBySubtypeBound(from, to);
- }
-
- private static boolean isAssignableBySubtypeBound(Type from, WildcardType to) {
- Type toSubtypeBound = subtypeBound(to);
- if (toSubtypeBound == null) {
- return true;
- }
- Type fromSubtypeBound = subtypeBound(from);
- if (fromSubtypeBound == null) {
- return false;
- }
- return isAssignable(toSubtypeBound, fromSubtypeBound);
- }
-
- private static boolean isAssignableToParameterizedType(Type from, ParameterizedType to) {
- Class<?> matchedClass = getRawType(to);
- if (!matchedClass.isAssignableFrom(getRawType(from))) {
- return false;
- }
- Type[] typeParams = matchedClass.getTypeParameters();
- Type[] toTypeArgs = to.getActualTypeArguments();
- TypeToken<?> fromTypeToken = of(from);
- for (int i = 0; i < typeParams.length; i++) {
- // If "to" is "List<? extends CharSequence>"
- // and "from" is StringArrayList,
- // First step is to figure out StringArrayList "is-a" List<E> and <E> is
- // String.
- // typeParams[0] is E and fromTypeToken.get(typeParams[0]) will resolve to
- // String.
- // String is then matched against <? extends CharSequence>.
- Type fromTypeArg = fromTypeToken.resolveType(typeParams[i]).runtimeType;
- if (!matchTypeArgument(fromTypeArg, toTypeArgs[i])) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean isAssignableToGenericArrayType(Type from, GenericArrayType to) {
- if (from instanceof Class) {
- Class<?> fromClass = (Class<?>) from;
- if (!fromClass.isArray()) {
- return false;
- }
- return isAssignable(fromClass.getComponentType(), to.getGenericComponentType());
- } else if (from instanceof GenericArrayType) {
- GenericArrayType fromArrayType = (GenericArrayType) from;
- return isAssignable(fromArrayType.getGenericComponentType(), to.getGenericComponentType());
- } else {
- return false;
- }
- }
-
- private static boolean isAssignableFromGenericArrayType(GenericArrayType from, Type to) {
- if (to instanceof Class) {
- Class<?> toClass = (Class<?>) to;
- if (!toClass.isArray()) {
- return toClass == Object.class; // any T[] is assignable to Object
- }
- return isAssignable(from.getGenericComponentType(), toClass.getComponentType());
- } else if (to instanceof GenericArrayType) {
- GenericArrayType toArrayType = (GenericArrayType) to;
- return isAssignable(from.getGenericComponentType(), toArrayType.getGenericComponentType());
- } else {
- return false;
- }
- }
-
- private static boolean matchTypeArgument(Type from, Type to) {
- if (from.equals(to)) {
- return true;
- }
- if (to instanceof WildcardType) {
- return isAssignableToWildcardType(from, (WildcardType) to);
- }
- return false;
- }
-
- private static Type supertypeBound(Type type) {
- if (type instanceof WildcardType) {
- return supertypeBound((WildcardType) type);
- }
- return type;
- }
-
- private static Type supertypeBound(WildcardType type) {
- Type[] upperBounds = type.getUpperBounds();
- if (upperBounds.length == 1) {
- return supertypeBound(upperBounds[0]);
- } else if (upperBounds.length == 0) {
- return Object.class;
- } else {
- throw new AssertionError(
- "There should be at most one upper bound for wildcard type: " + type);
- }
- }
-
- @Nullable private static Type subtypeBound(Type type) {
- if (type instanceof WildcardType) {
- return subtypeBound((WildcardType) type);
- } else {
- return type;
- }
- }
-
- @Nullable private static Type subtypeBound(WildcardType type) {
- Type[] lowerBounds = type.getLowerBounds();
- if (lowerBounds.length == 1) {
- return subtypeBound(lowerBounds[0]);
- } else if (lowerBounds.length == 0) {
- return null;
- } else {
- throw new AssertionError(
- "Wildcard should have at most one lower bound: " + type);
- }
- }
-
- @VisibleForTesting static Class<?> getRawType(Type type) {
- // For wildcard or type variable, the first bound determines the runtime type.
- return getRawTypes(type).iterator().next();
- }
-
- @VisibleForTesting static ImmutableSet<Class<?>> getRawTypes(Type type) {
- if (type instanceof Class) {
- return ImmutableSet.<Class<?>>of((Class<?>) type);
- } else if (type instanceof ParameterizedType) {
- ParameterizedType parameterizedType = (ParameterizedType) type;
- // JDK implementation declares getRawType() to return Class<?>: http://goo.gl/YzaEd
- return ImmutableSet.<Class<?>>of((Class<?>) parameterizedType.getRawType());
- } else if (type instanceof GenericArrayType) {
- GenericArrayType genericArrayType = (GenericArrayType) type;
- return ImmutableSet.<Class<?>>of(Types.getArrayClass(
- getRawType(genericArrayType.getGenericComponentType())));
- } else if (type instanceof TypeVariable) {
- return getRawTypes(((TypeVariable<?>) type).getBounds());
- } else if (type instanceof WildcardType) {
- return getRawTypes(((WildcardType) type).getUpperBounds());
- } else {
- throw new AssertionError(type + " unsupported");
- }
- }
-
- private static ImmutableSet<Class<?>> getRawTypes(Type[] types) {
- ImmutableSet.Builder<Class<?>> builder = ImmutableSet.builder();
- for (Type type : types) {
- builder.addAll(getRawTypes(type));
- }
- return builder.build();
- }
-
- /**
- * Returns the type token representing the generic type declaration of {@code cls}. For example:
- * {@code TypeToken.getGenericType(Iterable.class)} returns {@code Iterable<T>}.
- *
- * <p>If {@code cls} isn't parameterized and isn't a generic array, the type token of the class is
- * returned.
- */
- @VisibleForTesting static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
- if (cls.isArray()) {
- Type arrayOfGenericType = Types.newArrayType(
- // If we are passed with int[].class, don't turn it to GenericArrayType
- toGenericType(cls.getComponentType()).runtimeType);
- @SuppressWarnings("unchecked") // array is covariant
- TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
- return result;
- }
- TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
- if (typeParams.length > 0) {
- @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
- TypeToken<? extends T> type = (TypeToken<? extends T>)
- of(Types.newParameterizedType(cls, typeParams));
- return type;
- } else {
- return of(cls);
- }
- }
-
- private TypeToken<? super T> getSupertypeFromUpperBounds(
- Class<? super T> supertype, Type[] upperBounds) {
- for (Type upperBound : upperBounds) {
- @SuppressWarnings("unchecked") // T's upperbound is <? super T>.
- TypeToken<? super T> bound = (TypeToken<? super T>) of(upperBound);
- if (of(supertype).isAssignableFrom(bound)) {
- @SuppressWarnings({"rawtypes", "unchecked"}) // guarded by the isAssignableFrom check.
- TypeToken<? super T> result = bound.getSupertype((Class) supertype);
- return result;
- }
- }
- throw new IllegalArgumentException(supertype + " isn't a super type of " + this);
- }
-
- private TypeToken<? extends T> getSubtypeFromLowerBounds(Class<?> subclass, Type[] lowerBounds) {
- for (Type lowerBound : lowerBounds) {
- @SuppressWarnings("unchecked") // T's lower bound is <? extends T>
- TypeToken<? extends T> bound = (TypeToken<? extends T>) of(lowerBound);
- // Java supports only one lowerbound anyway.
- return bound.getSubtype(subclass);
- }
- throw new IllegalArgumentException(subclass + " isn't a subclass of " + this);
- }
-
- private TypeToken<? super T> getArraySupertype(Class<? super T> supertype) {
- // with component type, we have lost generic type information
- // Use raw type so that compiler allows us to call getSupertype()
- @SuppressWarnings("rawtypes")
- TypeToken componentType = checkNotNull(getComponentType(),
- "%s isn't a super type of %s", supertype, this);
- // array is covariant. component type is super type, so is the array type.
- @SuppressWarnings("unchecked") // going from raw type back to generics
- TypeToken<?> componentSupertype = componentType.getSupertype(supertype.getComponentType());
- @SuppressWarnings("unchecked") // component type is super type, so is array type.
- TypeToken<? super T> result = (TypeToken<? super T>)
- // If we are passed with int[].class, don't turn it to GenericArrayType
- of(newArrayClassOrGenericArrayType(componentSupertype.runtimeType));
- return result;
- }
-
- private TypeToken<? extends T> getArraySubtype(Class<?> subclass) {
- // array is covariant. component type is subtype, so is the array type.
- TypeToken<?> componentSubtype = getComponentType()
- .getSubtype(subclass.getComponentType());
- @SuppressWarnings("unchecked") // component type is subtype, so is array type.
- TypeToken<? extends T> result = (TypeToken<? extends T>)
- // If we are passed with int[].class, don't turn it to GenericArrayType
- of(newArrayClassOrGenericArrayType(componentSubtype.runtimeType));
- return result;
- }
-
- private Type resolveTypeArgsForSubclass(Class<?> subclass) {
- if (runtimeType instanceof Class) {
- // no resolution needed
- return subclass;
- }
- // class Base<A, B> {}
- // class Sub<X, Y> extends Base<X, Y> {}
- // Base<String, Integer>.subtype(Sub.class):
-
- // Sub<X, Y>.getSupertype(Base.class) => Base<X, Y>
- // => X=String, Y=Integer
- // => Sub<X, Y>=Sub<String, Integer>
- TypeToken<?> genericSubtype = toGenericType(subclass);
- @SuppressWarnings({"rawtypes", "unchecked"}) // subclass isn't <? extends T>
- Type supertypeWithArgsFromSubtype = genericSubtype
- .getSupertype((Class) getRawType())
- .runtimeType;
- return new TypeResolver().where(supertypeWithArgsFromSubtype, runtimeType)
- .resolveType(genericSubtype.runtimeType);
- }
-
- /**
- * Creates an array class if {@code componentType} is a class, or else, a
- * {@link GenericArrayType}. This is what Java7 does for generic array type
- * parameters.
- */
- private static Type newArrayClassOrGenericArrayType(Type componentType) {
- return Types.JavaVersion.JAVA7.newArrayType(componentType);
- }
-
- private static final class SimpleTypeToken<T> extends TypeToken<T> {
-
- SimpleTypeToken(Type type) {
- super(type);
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Collects parent types from a sub type.
- *
- * @param <K> The type "kind". Either a TypeToken, or Class.
- */
- private abstract static class TypeCollector<K> {
-
- static final TypeCollector<TypeToken<?>> FOR_GENERIC_TYPE =
- new TypeCollector<TypeToken<?>>() {
- @Override Class<?> getRawType(TypeToken<?> type) {
- return type.getRawType();
- }
-
- @Override Iterable<? extends TypeToken<?>> getInterfaces(TypeToken<?> type) {
- return type.getGenericInterfaces();
- }
-
- @Nullable
- @Override TypeToken<?> getSuperclass(TypeToken<?> type) {
- return type.getGenericSuperclass();
- }
- };
-
- static final TypeCollector<Class<?>> FOR_RAW_TYPE =
- new TypeCollector<Class<?>>() {
- @Override Class<?> getRawType(Class<?> type) {
- return type;
- }
-
- @Override Iterable<? extends Class<?>> getInterfaces(Class<?> type) {
- return Arrays.asList(type.getInterfaces());
- }
-
- @Nullable
- @Override Class<?> getSuperclass(Class<?> type) {
- return type.getSuperclass();
- }
- };
-
- /** For just classes, we don't have to traverse interfaces. */
- final TypeCollector<K> classesOnly() {
- return new ForwardingTypeCollector<K>(this) {
- @Override Iterable<? extends K> getInterfaces(K type) {
- return ImmutableSet.of();
- }
- @Override ImmutableList<K> collectTypes(Iterable<? extends K> types) {
- ImmutableList.Builder<K> builder = ImmutableList.builder();
- for (K type : types) {
- if (!getRawType(type).isInterface()) {
- builder.add(type);
- }
- }
- return super.collectTypes(builder.build());
- }
- };
- }
-
- final ImmutableList<K> collectTypes(K type) {
- return collectTypes(ImmutableList.of(type));
- }
-
- ImmutableList<K> collectTypes(Iterable<? extends K> types) {
- // type -> order number. 1 for Object, 2 for anything directly below, so on so forth.
- Map<K, Integer> map = Maps.newHashMap();
- for (K type : types) {
- collectTypes(type, map);
- }
- return sortKeysByValue(map, Ordering.natural().reverse());
- }
-
- /** Collects all types to map, and returns the total depth from T up to Object. */
- private int collectTypes(K type, Map<? super K, Integer> map) {
- Integer existing = map.get(this);
- if (existing != null) {
- // short circuit: if set contains type it already contains its supertypes
- return existing;
- }
- int aboveMe = getRawType(type).isInterface()
- ? 1 // interfaces should be listed before Object
- : 0;
- for (K interfaceType : getInterfaces(type)) {
- aboveMe = Math.max(aboveMe, collectTypes(interfaceType, map));
- }
- K superclass = getSuperclass(type);
- if (superclass != null) {
- aboveMe = Math.max(aboveMe, collectTypes(superclass, map));
- }
- /*
- * TODO(benyu): should we include Object for interface?
- * Also, CharSequence[] and Object[] for String[]?
- *
- */
- map.put(type, aboveMe + 1);
- return aboveMe + 1;
- }
-
- private static <K, V> ImmutableList<K> sortKeysByValue(
- final Map<K, V> map, final Comparator<? super V> valueComparator) {
- Ordering<K> keyOrdering = new Ordering<K>() {
- @Override public int compare(K left, K right) {
- return valueComparator.compare(map.get(left), map.get(right));
- }
- };
- return keyOrdering.immutableSortedCopy(map.keySet());
- }
-
- abstract Class<?> getRawType(K type);
- abstract Iterable<? extends K> getInterfaces(K type);
- @Nullable abstract K getSuperclass(K type);
-
- private static class ForwardingTypeCollector<K> extends TypeCollector<K> {
-
- private final TypeCollector<K> delegate;
-
- ForwardingTypeCollector(TypeCollector<K> delegate) {
- this.delegate = delegate;
- }
-
- @Override Class<?> getRawType(K type) {
- return delegate.getRawType(type);
- }
-
- @Override Iterable<? extends K> getInterfaces(K type) {
- return delegate.getInterfaces(type);
- }
-
- @Override K getSuperclass(K type) {
- return delegate.getSuperclass(type);
- }
- }
- }
-}
diff --git a/guava/src/com/google/common/reflect/Types.java b/guava/src/com/google/common/reflect/Types.java
deleted file mode 100644
index c19f38e..0000000
--- a/guava/src/com/google/common/reflect/Types.java
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.reflect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.transform;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.GenericDeclaration;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.Arrays;
-import java.util.Collection;
-
-import javax.annotation.Nullable;
-
-/**
- * Utilities for working with {@link Type}.
- *
- * @author Ben Yu
- */
-final class Types {
-
- /** Class#toString without the "class " and "interface " prefixes */
- private static final Function<Type, String> TYPE_TO_STRING =
- new Function<Type, String>() {
- @Override public String apply(Type from) {
- return Types.toString(from);
- }
- };
-
- private static final Joiner COMMA_JOINER = Joiner.on(", ").useForNull("null");
-
- /** Returns the array type of {@code componentType}. */
- static Type newArrayType(Type componentType) {
- if (componentType instanceof WildcardType) {
- WildcardType wildcard = (WildcardType) componentType;
- Type[] lowerBounds = wildcard.getLowerBounds();
- checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds.");
- if (lowerBounds.length == 1) {
- return supertypeOf(newArrayType(lowerBounds[0]));
- } else {
- Type[] upperBounds = wildcard.getUpperBounds();
- checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound.");
- return subtypeOf(newArrayType(upperBounds[0]));
- }
- }
- return JavaVersion.CURRENT.newArrayType(componentType);
- }
-
- /**
- * Returns a type where {@code rawType} is parameterized by
- * {@code arguments} and is owned by {@code ownerType}.
- */
- static ParameterizedType newParameterizedTypeWithOwner(
- @Nullable Type ownerType, Class<?> rawType, Type... arguments) {
- if (ownerType == null) {
- return newParameterizedType(rawType, arguments);
- }
- // ParameterizedTypeImpl constructor already checks, but we want to throw NPE before IAE
- checkNotNull(arguments);
- checkArgument(rawType.getEnclosingClass() != null, "Owner type for unenclosed %s", rawType);
- return new ParameterizedTypeImpl(ownerType, rawType, arguments);
- }
-
- /**
- * Returns a type where {@code rawType} is parameterized by
- * {@code arguments}.
- */
- static ParameterizedType newParameterizedType(Class<?> rawType, Type... arguments) {
- return new ParameterizedTypeImpl(
- ClassOwnership.JVM_BEHAVIOR.getOwnerType(rawType), rawType, arguments);
- }
-
- /** Decides what owner type to use for constructing {@link ParameterizedType} from a raw class. */
- private enum ClassOwnership {
-
- OWNED_BY_ENCLOSING_CLASS {
- @Nullable
- @Override
- Class<?> getOwnerType(Class<?> rawType) {
- return rawType.getEnclosingClass();
- }
- },
- LOCAL_CLASS_HAS_NO_OWNER {
- @Nullable
- @Override
- Class<?> getOwnerType(Class<?> rawType) {
- if (rawType.isLocalClass()) {
- return null;
- } else {
- return rawType.getEnclosingClass();
- }
- }
- };
-
- @Nullable abstract Class<?> getOwnerType(Class<?> rawType);
-
- static final ClassOwnership JVM_BEHAVIOR = detectJvmBehavior();
-
- private static ClassOwnership detectJvmBehavior() {
- class LocalClass<T> {}
- Class<?> subclass = new LocalClass<String>() {}.getClass();
- ParameterizedType parameterizedType = (ParameterizedType)
- subclass.getGenericSuperclass();
- for (ClassOwnership behavior : ClassOwnership.values()) {
- if (behavior.getOwnerType(LocalClass.class) == parameterizedType.getOwnerType()) {
- return behavior;
- }
- }
- throw new AssertionError();
- }
- }
-
- /**
- * Returns a new {@link TypeVariable} that belongs to {@code declaration} with
- * {@code name} and {@code bounds}.
- */
- static <D extends GenericDeclaration> TypeVariable<D> newTypeVariable(
- D declaration, String name, Type... bounds) {
- return new TypeVariableImpl<D>(
- declaration,
- name,
- (bounds.length == 0)
- ? new Type[] { Object.class }
- : bounds);
- }
-
- /** Returns a new {@link WildcardType} with {@code upperBound}. */
- @VisibleForTesting static WildcardType subtypeOf(Type upperBound) {
- return new WildcardTypeImpl(new Type[0], new Type[] { upperBound });
- }
-
- /** Returns a new {@link WildcardType} with {@code lowerBound}. */
- @VisibleForTesting static WildcardType supertypeOf(Type lowerBound) {
- return new WildcardTypeImpl(new Type[] { lowerBound }, new Type[] { Object.class });
- }
-
- /**
- * Returns human readable string representation of {@code type}.
- * <ul>
- * <li> For array type {@code Foo[]}, {@code "com.mypackage.Foo[]"} are
- * returned.
- * <li> For any class, {@code theClass.getName()} are returned.
- * <li> For all other types, {@code type.toString()} are returned.
- * </ul>
- */
- static String toString(Type type) {
- return (type instanceof Class)
- ? ((Class<?>) type).getName()
- : type.toString();
- }
-
- @Nullable static Type getComponentType(Type type) {
- checkNotNull(type);
- if (type instanceof Class) {
- return ((Class<?>) type).getComponentType();
- } else if (type instanceof GenericArrayType) {
- return ((GenericArrayType) type).getGenericComponentType();
- } else if (type instanceof WildcardType) {
- return subtypeOfComponentType(((WildcardType) type).getUpperBounds());
- } else if (type instanceof TypeVariable) {
- return subtypeOfComponentType(((TypeVariable<?>) type).getBounds());
- } else {
- return null;
- }
- }
-
- /**
- * Returns {@code ? extends X} if any of {@code bounds} is a subtype of {@code X[]}; or null
- * otherwise.
- */
- @Nullable private static Type subtypeOfComponentType(Type[] bounds) {
- for (Type bound : bounds) {
- Type componentType = getComponentType(bound);
- if (componentType != null) {
- // Only the first bound can be a class or array.
- // Bounds after the first can only be interfaces.
- if (componentType instanceof Class) {
- Class<?> componentClass = (Class<?>) componentType;
- if (componentClass.isPrimitive()) {
- return componentClass;
- }
- }
- return subtypeOf(componentType);
- }
- }
- return null;
- }
-
- static boolean containsTypeVariable(@Nullable Type type) {
- if (type instanceof TypeVariable) {
- return true;
- }
- if (type instanceof GenericArrayType) {
- return containsTypeVariable(((GenericArrayType) type).getGenericComponentType());
- }
- if (type instanceof ParameterizedType) {
- return containsTypeVariable(((ParameterizedType) type).getActualTypeArguments());
- }
- if (type instanceof WildcardType) {
- WildcardType wildcard = (WildcardType) type;
- return containsTypeVariable(wildcard.getUpperBounds())
- || containsTypeVariable(wildcard.getLowerBounds());
- }
- return false;
- }
-
- private static boolean containsTypeVariable(Type[] types) {
- for (Type paramType : types) {
- if (containsTypeVariable(paramType)) {
- return true;
- }
- }
- return false;
- }
-
- private static final class GenericArrayTypeImpl
- implements GenericArrayType, Serializable {
-
- private final Type componentType;
-
- GenericArrayTypeImpl(Type componentType) {
- this.componentType = JavaVersion.CURRENT.usedInGenericType(componentType);
- }
-
- @Override public Type getGenericComponentType() {
- return componentType;
- }
-
- @Override public String toString() {
- return Types.toString(componentType) + "[]";
- }
-
- @Override public int hashCode() {
- return componentType.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof GenericArrayType) {
- GenericArrayType that = (GenericArrayType) obj;
- return Objects.equal(
- getGenericComponentType(), that.getGenericComponentType());
- }
- return false;
- }
-
- private static final long serialVersionUID = 0;
- }
-
- private static final class ParameterizedTypeImpl
- implements ParameterizedType, Serializable {
-
- private final Type ownerType;
- private final ImmutableList<Type> argumentsList;
- private final Class<?> rawType;
-
- ParameterizedTypeImpl(
- @Nullable Type ownerType, Class<?> rawType, Type[] typeArguments) {
- checkNotNull(rawType);
- checkArgument(typeArguments.length == rawType.getTypeParameters().length);
- disallowPrimitiveType(typeArguments, "type parameter");
- this.ownerType = ownerType;
- this.rawType = rawType;
- this.argumentsList = JavaVersion.CURRENT.usedInGenericType(typeArguments);
- }
-
- @Override public Type[] getActualTypeArguments() {
- return toArray(argumentsList);
- }
-
- @Override public Type getRawType() {
- return rawType;
- }
-
- @Override public Type getOwnerType() {
- return ownerType;
- }
-
- @Override public String toString() {
- StringBuilder builder = new StringBuilder();
- if (ownerType != null) {
- builder.append(Types.toString(ownerType)).append('.');
- }
- builder.append(rawType.getName())
- .append('<')
- .append(COMMA_JOINER.join(transform(argumentsList, TYPE_TO_STRING)))
- .append('>');
- return builder.toString();
- }
-
- @Override public int hashCode() {
- return (ownerType == null ? 0 : ownerType.hashCode())
- ^ argumentsList.hashCode() ^ rawType.hashCode();
- }
-
- @Override public boolean equals(Object other) {
- if (!(other instanceof ParameterizedType)) {
- return false;
- }
- ParameterizedType that = (ParameterizedType) other;
- return getRawType().equals(that.getRawType())
- && Objects.equal(getOwnerType(), that.getOwnerType())
- && Arrays.equals(
- getActualTypeArguments(), that.getActualTypeArguments());
- }
-
- private static final long serialVersionUID = 0;
- }
-
- private static final class TypeVariableImpl<D extends GenericDeclaration>
- implements TypeVariable<D> {
-
- private final D genericDeclaration;
- private final String name;
- private final ImmutableList<Type> bounds;
-
- TypeVariableImpl(D genericDeclaration, String name, Type[] bounds) {
- disallowPrimitiveType(bounds, "bound for type variable");
- this.genericDeclaration = checkNotNull(genericDeclaration);
- this.name = checkNotNull(name);
- this.bounds = ImmutableList.copyOf(bounds);
- }
-
- @Override public Type[] getBounds() {
- return toArray(bounds);
- }
-
- @Override public D getGenericDeclaration() {
- return genericDeclaration;
- }
-
- @Override public String getName() {
- return name;
- }
-
- @Override public String toString() {
- return name;
- }
-
- @Override public int hashCode() {
- return genericDeclaration.hashCode() ^ name.hashCode();
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof TypeVariable) {
- TypeVariable<?> that = (TypeVariable<?>) obj;
- return name.equals(that.getName())
- && genericDeclaration.equals(that.getGenericDeclaration());
- }
- return false;
- }
- }
-
- static final class WildcardTypeImpl implements WildcardType, Serializable {
-
- private final ImmutableList<Type> lowerBounds;
- private final ImmutableList<Type> upperBounds;
-
- WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) {
- disallowPrimitiveType(lowerBounds, "lower bound for wildcard");
- disallowPrimitiveType(upperBounds, "upper bound for wildcard");
- this.lowerBounds = JavaVersion.CURRENT.usedInGenericType(lowerBounds);
- this.upperBounds = JavaVersion.CURRENT.usedInGenericType(upperBounds);
- }
-
- @Override public Type[] getLowerBounds() {
- return toArray(lowerBounds);
- }
-
- @Override public Type[] getUpperBounds() {
- return toArray(upperBounds);
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof WildcardType) {
- WildcardType that = (WildcardType) obj;
- return lowerBounds.equals(Arrays.asList(that.getLowerBounds()))
- && upperBounds.equals(Arrays.asList(that.getUpperBounds()));
- }
- return false;
- }
-
- @Override public int hashCode() {
- return lowerBounds.hashCode() ^ upperBounds.hashCode();
- }
-
- @Override public String toString() {
- StringBuilder builder = new StringBuilder("?");
- for (Type lowerBound : lowerBounds) {
- builder.append(" super ").append(Types.toString(lowerBound));
- }
- for (Type upperBound : filterUpperBounds(upperBounds)) {
- builder.append(" extends ").append(Types.toString(upperBound));
- }
- return builder.toString();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- private static Type[] toArray(Collection<Type> types) {
- return types.toArray(new Type[types.size()]);
- }
-
- private static Iterable<Type> filterUpperBounds(Iterable<Type> bounds) {
- return Iterables.filter(
- bounds, Predicates.not(Predicates.<Type>equalTo(Object.class)));
- }
-
- private static void disallowPrimitiveType(Type[] types, String usedAs) {
- for (Type type : types) {
- if (type instanceof Class) {
- Class<?> cls = (Class<?>) type;
- checkArgument(!cls.isPrimitive(),
- "Primitive type '%s' used as %s", cls, usedAs);
- }
- }
- }
-
- /** Returns the {@code Class} object of arrays with {@code componentType}. */
- static Class<?> getArrayClass(Class<?> componentType) {
- // TODO(user): This is not the most efficient way to handle generic
- // arrays, but is there another way to extract the array class in a
- // non-hacky way (i.e. using String value class names- "[L...")?
- return Array.newInstance(componentType, 0).getClass();
- }
-
- // TODO(benyu): Once we are on Java 7, delete this abstraction
- enum JavaVersion {
-
- JAVA6 {
- @Override GenericArrayType newArrayType(Type componentType) {
- return new GenericArrayTypeImpl(componentType);
- }
- @Override Type usedInGenericType(Type type) {
- checkNotNull(type);
- if (type instanceof Class) {
- Class<?> cls = (Class<?>) type;
- if (cls.isArray()) {
- return new GenericArrayTypeImpl(cls.getComponentType());
- }
- }
- return type;
- }
- },
- JAVA7 {
- @Override Type newArrayType(Type componentType) {
- if (componentType instanceof Class) {
- return getArrayClass((Class<?>) componentType);
- } else {
- return new GenericArrayTypeImpl(componentType);
- }
- }
- @Override Type usedInGenericType(Type type) {
- return checkNotNull(type);
- }
- }
- ;
-
- static final JavaVersion CURRENT =
- (new TypeCapture<int[]>() {}.capture() instanceof Class)
- ? JAVA7 : JAVA6;
- abstract Type newArrayType(Type componentType);
- abstract Type usedInGenericType(Type type);
-
- final ImmutableList<Type> usedInGenericType(Type[] types) {
- ImmutableList.Builder<Type> builder = ImmutableList.builder();
- for (Type type : types) {
- builder.add(usedInGenericType(type));
- }
- return builder.build();
- }
- }
-
- private Types() {}
-}
diff --git a/guava/src/com/google/common/reflect/package-info.java b/guava/src/com/google/common/reflect/package-info.java
deleted file mode 100644
index e8ac02a..0000000
--- a/guava/src/com/google/common/reflect/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This package contains utilities to work with Java reflection.
- * It is a part of the open-source
- * <a href="http://guava-libraries.googlecode.com">Guava libraries</a>.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package com.google.common.reflect;
diff --git a/guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java b/guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java
index a1cb641..8136d23 100644
--- a/guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java
+++ b/guava/src/com/google/common/util/concurrent/AbstractExecutionThreadService.java
@@ -55,8 +55,7 @@ public abstract class AbstractExecutionThreadService implements Service {
shutDown();
} catch (Exception ignored) {
logger.log(Level.WARNING,
- "Error while attempting to shut down the service"
- + " after failure.", ignored);
+ "Error while attempting to shut down the service after failure.", ignored);
}
throw t;
}
@@ -78,14 +77,7 @@ public abstract class AbstractExecutionThreadService implements Service {
};
/**
- * Constructor for use by subclasses.
- */
- protected AbstractExecutionThreadService() {}
-
- /**
* Start the service. This method is invoked on the execution thread.
- *
- * <p>By default this method does nothing.
*/
protected void startUp() throws Exception {}
@@ -107,16 +99,12 @@ public abstract class AbstractExecutionThreadService implements Service {
/**
* Stop the service. This method is invoked on the execution thread.
- *
- * <p>By default this method does nothing.
*/
// TODO: consider supporting a TearDownTestCase-like API
protected void shutDown() throws Exception {}
/**
* Invoked to request the service to stop.
- *
- * <p>By default this method does nothing.
*/
protected void triggerShutdown() {}
@@ -129,19 +117,19 @@ public abstract class AbstractExecutionThreadService implements Service {
* promptly.
*
* <p>The default implementation returns a new {@link Executor} that sets the
- * name of its threads to the string returned by {@link #serviceName}
+ * name of its threads to the string returned by {@link #getServiceName}
*/
protected Executor executor() {
return new Executor() {
@Override
public void execute(Runnable command) {
- MoreExecutors.newThread(serviceName(), command).start();
+ new Thread(command, getServiceName()).start();
}
};
}
@Override public String toString() {
- return serviceName() + " [" + state() + "]";
+ return getServiceName() + " [" + state() + "]";
}
// We override instead of using ForwardingService so that these can be final.
@@ -171,28 +159,14 @@ public abstract class AbstractExecutionThreadService implements Service {
}
/**
- * @since 13.0
- */
- @Override public final void addListener(Listener listener, Executor executor) {
- delegate.addListener(listener, executor);
- }
-
- /**
- * @since 14.0
- */
- @Override public final Throwable failureCause() {
- return delegate.failureCause();
- }
-
- /**
- * Returns the name of this service. {@link AbstractExecutionThreadService}
- * may include the name in debugging output.
+ * Returns the name of this service. {@link AbstractExecutionThreadService} may include the name
+ * in debugging output.
*
* <p>Subclasses may override this method.
*
- * @since 14.0 (present in 10.0 as getServiceName)
+ * @since 10.0
*/
- protected String serviceName() {
+ protected String getServiceName() {
return getClass().getSimpleName();
}
}
diff --git a/guava/src/com/google/common/util/concurrent/AbstractFuture.java b/guava/src/com/google/common/util/concurrent/AbstractFuture.java
index e14a111..bef3d3d 100644
--- a/guava/src/com/google/common/util/concurrent/AbstractFuture.java
+++ b/guava/src/com/google/common/util/concurrent/AbstractFuture.java
@@ -70,11 +70,6 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
// The execution list to hold our executors.
private final ExecutionList executionList = new ExecutionList();
- /**
- * Constructor for use by subclasses.
- */
- protected AbstractFuture() {}
-
/*
* Improve the documentation of when InterruptedException is thrown. Our
* behavior matches the JDK's, but the JDK's documentation is misleading.
@@ -128,7 +123,7 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
- if (!sync.cancel(mayInterruptIfRunning)) {
+ if (!sync.cancel()) {
return false;
}
executionList.execute();
@@ -151,16 +146,6 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
}
/**
- * Returns true if this future was cancelled with {@code
- * mayInterruptIfRunning} set to {@code true}.
- *
- * @since 14.0
- */
- protected final boolean wasInterrupted() {
- return sync.wasInterrupted();
- }
-
- /**
* {@inheritDoc}
*
* @since 10.0
@@ -216,14 +201,13 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
* private subclass to hold the synchronizer. This synchronizer is used to
* implement the blocking and waiting calls as well as to handle state changes
* in a thread-safe manner. The current state of the future is held in the
- * Sync state, and the lock is released whenever the state changes to
- * {@link #COMPLETED}, {@link #CANCELLED}, or {@link #INTERRUPTED}
+ * Sync state, and the lock is released whenever the state changes to either
+ * {@link #COMPLETED} or {@link #CANCELLED}.
*
* <p>To avoid races between threads doing release and acquire, we transition
* to the final state in two steps. One thread will successfully CAS from
* RUNNING to COMPLETING, that thread will then set the result of the
- * computation, and only then transition to COMPLETED, CANCELLED, or
- * INTERRUPTED.
+ * computation, and only then transition to COMPLETED or CANCELLED.
*
* <p>We don't use the integer argument passed between acquire methods so we
* pass around a -1 everywhere.
@@ -237,7 +221,6 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
static final int COMPLETING = 1;
static final int COMPLETED = 2;
static final int CANCELLED = 4;
- static final int INTERRUPTED = 8;
private V value;
private Throwable exception;
@@ -309,9 +292,7 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
}
case CANCELLED:
- case INTERRUPTED:
- throw cancellationExceptionWithCause(
- "Task was cancelled.", exception);
+ throw new CancellationException("Task was cancelled.");
default:
throw new IllegalStateException(
@@ -320,25 +301,17 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
}
/**
- * Checks if the state is {@link #COMPLETED}, {@link #CANCELLED}, or {@link
- * INTERRUPTED}.
+ * Checks if the state is {@link #COMPLETED} or {@link #CANCELLED}.
*/
boolean isDone() {
- return (getState() & (COMPLETED | CANCELLED | INTERRUPTED)) != 0;
+ return (getState() & (COMPLETED | CANCELLED)) != 0;
}
/**
- * Checks if the state is {@link #CANCELLED} or {@link #INTERRUPTED}.
+ * Checks if the state is {@link #CANCELLED}.
*/
boolean isCancelled() {
- return (getState() & (CANCELLED | INTERRUPTED)) != 0;
- }
-
- /**
- * Checks if the state is {@link #INTERRUPTED}.
- */
- boolean wasInterrupted() {
- return getState() == INTERRUPTED;
+ return getState() == CANCELLED;
}
/**
@@ -356,10 +329,10 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
}
/**
- * Transition to the CANCELLED or INTERRUPTED state.
+ * Transition to the CANCELLED state.
*/
- boolean cancel(boolean interrupt) {
- return complete(null, null, interrupt ? INTERRUPTED : CANCELLED);
+ boolean cancel() {
+ return complete(null, null, CANCELLED);
}
/**
@@ -367,8 +340,7 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
* be set but not both. The {@code finalState} is the state to change to
* from {@link #RUNNING}. If the state is not in the RUNNING state we
* return {@code false} after waiting for the state to be set to a valid
- * final state ({@link #COMPLETED}, {@link #CANCELLED}, or {@link
- * #INTERRUPTED}).
+ * final state ({@link #COMPLETED} or {@link #CANCELLED}).
*
* @param v the value to set as the result of the computation.
* @param t the exception to set as the result of the computation.
@@ -381,9 +353,7 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
// If this thread successfully transitioned to COMPLETING, set the value
// and exception and then release to the final state.
this.value = v;
- // Don't actually construct a CancellationException until necessary.
- this.exception = ((finalState & (CANCELLED | INTERRUPTED)) != 0)
- ? new CancellationException("Future.cancel() was called.") : t;
+ this.exception = t;
releaseShared(finalState);
} else if (getState() == COMPLETING) {
// If some other thread is currently completing the future, block until
@@ -393,11 +363,4 @@ public abstract class AbstractFuture<V> implements ListenableFuture<V> {
return doCompletion;
}
}
-
- static final CancellationException cancellationExceptionWithCause(
- @Nullable String message, @Nullable Throwable cause) {
- CancellationException exception = new CancellationException(message);
- exception.initCause(cause);
- return exception;
- }
}
diff --git a/guava/src/com/google/common/util/concurrent/AbstractIdleService.java b/guava/src/com/google/common/util/concurrent/AbstractIdleService.java
index 96a6ff3..504a6bc 100644
--- a/guava/src/com/google/common/util/concurrent/AbstractIdleService.java
+++ b/guava/src/com/google/common/util/concurrent/AbstractIdleService.java
@@ -37,7 +37,7 @@ public abstract class AbstractIdleService implements Service {
/* use AbstractService for state management */
private final Service delegate = new AbstractService() {
@Override protected final void doStart() {
- executor().execute(new Runnable() {
+ executor(State.STARTING).execute(new Runnable() {
@Override public void run() {
try {
startUp();
@@ -51,7 +51,7 @@ public abstract class AbstractIdleService implements Service {
}
@Override protected final void doStop() {
- executor().execute(new Runnable() {
+ executor(State.STOPPING).execute(new Runnable() {
@Override public void run() {
try {
shutDown();
@@ -65,9 +65,6 @@ public abstract class AbstractIdleService implements Service {
}
};
- /** Constructor for use by subclasses. */
- protected AbstractIdleService() {}
-
/** Start the service. */
protected abstract void startUp() throws Exception;
@@ -81,19 +78,22 @@ public abstract class AbstractIdleService implements Service {
* priority. The returned executor's {@link Executor#execute(Runnable)
* execute()} method is called when this service is started and stopped,
* and should return promptly.
+ *
+ * @param state {@link Service.State#STARTING} or
+ * {@link Service.State#STOPPING}, used by the default implementation for
+ * naming the thread
*/
- protected Executor executor() {
- final State state = state();
+ protected Executor executor(final State state) {
return new Executor() {
@Override
public void execute(Runnable command) {
- MoreExecutors.newThread(serviceName() + " " + state, command).start();
+ new Thread(command, getServiceName() + " " + state).start();
}
};
}
@Override public String toString() {
- return serviceName() + " [" + state() + "]";
+ return getServiceName() + " [" + state() + "]";
}
// We override instead of using ForwardingService so that these can be final.
@@ -122,27 +122,7 @@ public abstract class AbstractIdleService implements Service {
return delegate.stopAndWait();
}
- /**
- * @since 13.0
- */
- @Override public final void addListener(Listener listener, Executor executor) {
- delegate.addListener(listener, executor);
- }
-
- /**
- * @since 14.0
- */
- @Override public final Throwable failureCause() {
- return delegate.failureCause();
- }
-
- /**
- * Returns the name of this service. {@link AbstractIdleService} may include the name in debugging
- * output.
- *
- * @since 14.0
- */
- protected String serviceName() {
+ private String getServiceName() {
return getClass().getSimpleName();
}
}
diff --git a/guava/src/com/google/common/util/concurrent/AbstractListeningExecutorService.java b/guava/src/com/google/common/util/concurrent/AbstractListeningExecutorService.java
index c3e33a5..24f596f 100644
--- a/guava/src/com/google/common/util/concurrent/AbstractListeningExecutorService.java
+++ b/guava/src/com/google/common/util/concurrent/AbstractListeningExecutorService.java
@@ -14,9 +14,7 @@
package com.google.common.util.concurrent;
-import static com.google.common.util.concurrent.MoreExecutors.invokeAnyImpl;
-
-import com.google.common.annotations.Beta;
+import static com.google.common.base.Preconditions.checkArgument;
import java.util.ArrayList;
import java.util.Collection;
@@ -25,12 +23,11 @@ import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import javax.annotation.Nullable;
-
/**
* Implements {@link ListeningExecutorService} execution methods atop the abstract {@link #execute}
* method. More concretely, the {@code submit}, {@code invokeAny} and {@code invokeAll} methods
@@ -40,17 +37,15 @@ import javax.annotation.Nullable;
* termination.
*
* @author Doug Lea
- * @since 14.0
*/
-@Beta
-public abstract class AbstractListeningExecutorService implements ListeningExecutorService {
+abstract class AbstractListeningExecutorService implements ListeningExecutorService {
@Override public ListenableFuture<?> submit(Runnable task) {
ListenableFutureTask<Void> ftask = ListenableFutureTask.create(task, null);
execute(ftask);
return ftask;
}
- @Override public <T> ListenableFuture<T> submit(Runnable task, @Nullable T result) {
+ @Override public <T> ListenableFuture<T> submit(Runnable task, T result) {
ListenableFutureTask<T> ftask = ListenableFutureTask.create(task, result);
execute(ftask);
return ftask;
@@ -62,10 +57,82 @@ public abstract class AbstractListeningExecutorService implements ListeningExecu
return ftask;
}
+ /**
+ * the main mechanics of invokeAny.
+ */
+ private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, boolean timed, long nanos)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ int ntasks = tasks.size();
+ checkArgument(ntasks > 0);
+ List<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
+ ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this);
+
+ // For efficiency, especially in executors with limited
+ // parallelism, check to see if previously submitted tasks are
+ // done before submitting more of them. This interleaving
+ // plus the exception mechanics account for messiness of main
+ // loop.
+
+ try {
+ // Record exceptions so that if we fail to obtain any
+ // result, we can throw the last exception we got.
+ ExecutionException ee = null;
+ long lastTime = timed ? System.nanoTime() : 0;
+ Iterator<? extends Callable<T>> it = tasks.iterator();
+
+ // Start one task for sure; the rest incrementally
+ futures.add(ecs.submit(it.next()));
+ --ntasks;
+ int active = 1;
+
+ for (;;) {
+ Future<T> f = ecs.poll();
+ if (f == null) {
+ if (ntasks > 0) {
+ --ntasks;
+ futures.add(ecs.submit(it.next()));
+ ++active;
+ } else if (active == 0) {
+ break;
+ } else if (timed) {
+ f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
+ if (f == null) {
+ throw new TimeoutException();
+ }
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ } else {
+ f = ecs.take();
+ }
+ }
+ if (f != null) {
+ --active;
+ try {
+ return f.get();
+ } catch (ExecutionException eex) {
+ ee = eex;
+ } catch (RuntimeException rex) {
+ ee = new ExecutionException(rex);
+ }
+ }
+ }
+
+ if (ee == null) {
+ ee = new ExecutionException(null);
+ }
+ throw ee;
+ } finally {
+ for (Future<T> f : futures) {
+ f.cancel(true);
+ }
+ }
+ }
+
@Override public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
try {
- return invokeAnyImpl(this, tasks, false, 0);
+ return doInvokeAny(tasks, false, 0);
} catch (TimeoutException cannotHappen) {
throw new AssertionError();
}
@@ -74,7 +141,7 @@ public abstract class AbstractListeningExecutorService implements ListeningExecu
@Override public <T> T invokeAny(
Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
- return invokeAnyImpl(this, tasks, true, unit.toNanos(timeout));
+ return doInvokeAny(tasks, true, unit.toNanos(timeout));
}
@Override public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
diff --git a/guava/src/com/google/common/util/concurrent/AbstractScheduledService.java b/guava/src/com/google/common/util/concurrent/AbstractScheduledService.java
index 949f76a..f847205 100644
--- a/guava/src/com/google/common/util/concurrent/AbstractScheduledService.java
+++ b/guava/src/com/google/common/util/concurrent/AbstractScheduledService.java
@@ -21,11 +21,9 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import java.util.concurrent.Callable;
-import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
@@ -98,8 +96,9 @@ public abstract class AbstractScheduledService implements Service {
*
* <p>Consider using the {@link #newFixedDelaySchedule} and {@link #newFixedRateSchedule} factory
* methods, these provide {@link Scheduler} instances for the common use case of running the
- * service with a fixed schedule. If more flexibility is needed then consider subclassing
- * {@link CustomScheduler}.
+ * service with a fixed schedule. If more flexibility is needed then consider subclassing the
+ * {@link CustomScheduler} abstract class in preference to creating your own {@link Scheduler}
+ * implementation.
*
* @author Luke Sandberg
* @since 11.0
@@ -230,9 +229,6 @@ public abstract class AbstractScheduledService implements Service {
}
};
- /** Constructor for use by subclasses. */
- protected AbstractScheduledService() {}
-
/**
* Run one iteration of the scheduled task. If any invocation of this method throws an exception,
* the service will transition to the {@link Service.State#FAILED} state and this method will no
@@ -240,19 +236,11 @@ public abstract class AbstractScheduledService implements Service {
*/
protected abstract void runOneIteration() throws Exception;
- /**
- * Start the service.
- *
- * <p>By default this method does nothing.
- */
- protected void startUp() throws Exception {}
+ /** Start the service. */
+ protected abstract void startUp() throws Exception;
- /**
- * Stop the service. This is guaranteed not to run concurrently with {@link #runOneIteration}.
- *
- * <p>By default this method does nothing.
- */
- protected void shutDown() throws Exception {}
+ /** Stop the service. This is guaranteed not to run concurrently with {@link #runOneIteration}. */
+ protected abstract void shutDown() throws Exception;
/**
* Returns the {@link Scheduler} object used to configure this service. This method will only be
@@ -262,56 +250,19 @@ public abstract class AbstractScheduledService implements Service {
/**
* Returns the {@link ScheduledExecutorService} that will be used to execute the {@link #startUp},
- * {@link #runOneIteration} and {@link #shutDown} methods. If this method is overridden the
- * executor will not be {@linkplain ScheduledExecutorService#shutdown shutdown} when this
- * service {@linkplain Service.State#TERMINATED terminates} or
- * {@linkplain Service.State#TERMINATED fails}. Subclasses may override this method to supply a
- * custom {@link ScheduledExecutorService} instance. This method is guaranteed to only be called
- * once.
+ * {@link #runOneIteration} and {@link #shutDown} methods. The executor will not be
+ * {@link ScheduledExecutorService#shutdown} when this service stops. Subclasses may override this
+ * method to use a custom {@link ScheduledExecutorService} instance.
*
* <p>By default this returns a new {@link ScheduledExecutorService} with a single thread thread
- * pool that sets the name of the thread to the {@linkplain #serviceName() service name}.
- * Also, the pool will be {@linkplain ScheduledExecutorService#shutdown() shut down} when the
- * service {@linkplain Service.State#TERMINATED terminates} or
- * {@linkplain Service.State#TERMINATED fails}.
+ * pool. This method will only be called once.
*/
protected ScheduledExecutorService executor() {
- final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
- new ThreadFactory() {
- @Override public Thread newThread(Runnable runnable) {
- return MoreExecutors.newThread(serviceName(), runnable);
- }
- });
- // Add a listener to shutdown the executor after the service is stopped. This ensures that the
- // JVM shutdown will not be prevented from exiting after this service has stopped or failed.
- // Technically this listener is added after start() was called so it is a little gross, but it
- // is called within doStart() so we know that the service cannot terminate or fail concurrently
- // with adding this listener so it is impossible to miss an event that we are interested in.
- addListener(new Listener() {
- @Override public void starting() {}
- @Override public void running() {}
- @Override public void stopping(State from) {}
- @Override public void terminated(State from) {
- executor.shutdown();
- }
- @Override public void failed(State from, Throwable failure) {
- executor.shutdown();
- }}, MoreExecutors.sameThreadExecutor());
- return executor;
+ return Executors.newSingleThreadScheduledExecutor();
}
- /**
- * Returns the name of this service. {@link AbstractScheduledService} may include the name in
- * debugging output.
- *
- * @since 14.0
- */
- protected String serviceName() {
- return getClass().getSimpleName();
- }
-
@Override public String toString() {
- return serviceName() + " [" + state() + "]";
+ return getClass().getSimpleName() + " [" + state() + "]";
}
// We override instead of using ForwardingService so that these can be final.
@@ -341,20 +292,6 @@ public abstract class AbstractScheduledService implements Service {
}
/**
- * @since 13.0
- */
- @Override public final void addListener(Listener listener, Executor executor) {
- delegate.addListener(listener, executor);
- }
-
- /**
- * @since 14.0
- */
- @Override public final Throwable failureCause() {
- return delegate.failureCause();
- }
-
- /**
* A {@link Scheduler} that provides a convenient way for the {@link AbstractScheduledService} to
* use a dynamically changing schedule. After every execution of the task, assuming it hasn't
* been cancelled, the {@link #getNextSchedule} method will be called.
diff --git a/guava/src/com/google/common/util/concurrent/AbstractService.java b/guava/src/com/google/common/util/concurrent/AbstractService.java
index f028a59..f84b374 100644
--- a/guava/src/com/google/common/util/concurrent/AbstractService.java
+++ b/guava/src/com/google/common/util/concurrent/AbstractService.java
@@ -16,148 +16,68 @@
package com.google.common.util.concurrent;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
import com.google.common.annotations.Beta;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Queues;
import com.google.common.util.concurrent.Service.State; // javadoc needs this
-import java.util.List;
-import java.util.Queue;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantLock;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.Immutable;
/**
- * Base class for implementing services that can handle {@link #doStart} and {@link #doStop}
- * requests, responding to them with {@link #notifyStarted()} and {@link #notifyStopped()}
- * callbacks. Its subclasses must manage threads manually; consider
- * {@link AbstractExecutionThreadService} if you need only a single execution thread.
+ * Base class for implementing services that can handle {@link #doStart} and
+ * {@link #doStop} requests, responding to them with {@link #notifyStarted()}
+ * and {@link #notifyStopped()} callbacks. Its subclasses must manage threads
+ * manually; consider {@link AbstractExecutionThreadService} if you need only a
+ * single execution thread.
*
* @author Jesse Wilson
- * @author Luke Sandberg
* @since 1.0
*/
@Beta
public abstract class AbstractService implements Service {
- private static final Logger logger = Logger.getLogger(AbstractService.class.getName());
+
private final ReentrantLock lock = new ReentrantLock();
private final Transition startup = new Transition();
private final Transition shutdown = new Transition();
/**
- * The listeners to notify during a state transition.
- */
- @GuardedBy("lock")
- private final List<ListenerExecutorPair> listeners = Lists.newArrayList();
-
- /**
- * The queue of listeners that are waiting to be executed.
- *
- * <p>Enqueue operations should be protected by {@link #lock} while dequeue operations should be
- * protected by the implicit lock on this object. Dequeue operations should be executed atomically
- * with the execution of the {@link Runnable} and additionally the {@link #lock} should not be
- * held when the listeners are being executed. Use {@link #executeListeners} for this operation.
- * This is necessary to ensure that elements on the queue are executed in the correct order.
- * Enqueue operations should be protected so that listeners are added in the correct order. We use
- * a concurrent queue implementation so that enqueues can be executed concurrently with dequeues.
+ * The internal state, which equals external state unless
+ * shutdownWhenStartupFinishes is true. Guarded by {@code lock}.
*/
- @GuardedBy("queuedListeners")
- private final Queue<Runnable> queuedListeners = Queues.newConcurrentLinkedQueue();
-
+ private State state = State.NEW;
+
/**
- * The current state of the service. This should be written with the lock held but can be read
- * without it because it is an immutable object in a volatile field. This is desirable so that
- * methods like {@link #state}, {@link #failureCause} and notably {@link #toString} can be run
- * without grabbing the lock.
- *
- * <p>To update this field correctly the lock must be held to guarantee that the state is
- * consistent.
+ * If true, the user requested a shutdown while the service was still starting
+ * up. Guarded by {@code lock}.
*/
- @GuardedBy("lock")
- private volatile StateSnapshot snapshot = new StateSnapshot(State.NEW);
+ private boolean shutdownWhenStartupFinishes = false;
- /** Constructor for use by subclasses. */
- protected AbstractService() {
- // Add a listener to update the futures. This needs to be added first so that it is executed
- // before the other listeners. This way the other listeners can access the completed futures.
- addListener(
- new Listener() {
- @Override public void starting() {}
-
- @Override public void running() {
- startup.set(State.RUNNING);
- }
-
- @Override public void stopping(State from) {
- if (from == State.STARTING) {
- startup.set(State.STOPPING);
- }
- }
-
- @Override public void terminated(State from) {
- if (from == State.NEW) {
- startup.set(State.TERMINATED);
- }
- shutdown.set(State.TERMINATED);
- }
-
- @Override public void failed(State from, Throwable failure) {
- switch (from) {
- case STARTING:
- startup.setException(failure);
- shutdown.setException(new Exception("Service failed to start.", failure));
- break;
- case RUNNING:
- shutdown.setException(new Exception("Service failed while running", failure));
- break;
- case STOPPING:
- shutdown.setException(failure);
- break;
- case TERMINATED: /* fall-through */
- case FAILED: /* fall-through */
- case NEW: /* fall-through */
- default:
- throw new AssertionError("Unexpected from state: " + from);
- }
- }
- },
- MoreExecutors.sameThreadExecutor());
- }
-
/**
- * This method is called by {@link #start} to initiate service startup. The invocation of this
- * method should cause a call to {@link #notifyStarted()}, either during this method's run, or
- * after it has returned. If startup fails, the invocation should cause a call to
- * {@link #notifyFailed(Throwable)} instead.
+ * This method is called by {@link #start} to initiate service startup. The
+ * invocation of this method should cause a call to {@link #notifyStarted()},
+ * either during this method's run, or after it has returned. If startup
+ * fails, the invocation should cause a call to {@link
+ * #notifyFailed(Throwable)} instead.
*
- * <p>This method should return promptly; prefer to do work on a different thread where it is
- * convenient. It is invoked exactly once on service startup, even when {@link #start} is called
- * multiple times.
+ * <p>This method should return promptly; prefer to do work on a different
+ * thread where it is convenient. It is invoked exactly once on service
+ * startup, even when {@link #start} is called multiple times.
*/
protected abstract void doStart();
/**
- * This method should be used to initiate service shutdown. The invocation of this method should
- * cause a call to {@link #notifyStopped()}, either during this method's run, or after it has
- * returned. If shutdown fails, the invocation should cause a call to
- * {@link #notifyFailed(Throwable)} instead.
+ * This method should be used to initiate service shutdown. The invocation
+ * of this method should cause a call to {@link #notifyStopped()}, either
+ * during this method's run, or after it has returned. If shutdown fails, the
+ * invocation should cause a call to {@link #notifyFailed(Throwable)} instead.
*
- * <p> This method should return promptly; prefer to do work on a different thread where it is
- * convenient. It is invoked exactly once on service shutdown, even when {@link #stop} is called
- * multiple times.
+ * <p>This method should return promptly; prefer to do work on a different
+ * thread where it is convenient. It is invoked exactly once on service
+ * shutdown, even when {@link #stop} is called multiple times.
*/
protected abstract void doStop();
@@ -165,16 +85,15 @@ public abstract class AbstractService implements Service {
public final ListenableFuture<State> start() {
lock.lock();
try {
- if (snapshot.state == State.NEW) {
- snapshot = new StateSnapshot(State.STARTING);
- starting();
+ if (state == State.NEW) {
+ state = State.STARTING;
doStart();
}
} catch (Throwable startupFailure) {
+ // put the exception in the future, the user can get it via Future.get()
notifyFailed(startupFailure);
} finally {
lock.unlock();
- executeListeners();
}
return startup;
@@ -184,33 +103,22 @@ public abstract class AbstractService implements Service {
public final ListenableFuture<State> stop() {
lock.lock();
try {
- switch (snapshot.state) {
- case NEW:
- snapshot = new StateSnapshot(State.TERMINATED);
- terminated(State.NEW);
- break;
- case STARTING:
- snapshot = new StateSnapshot(State.STARTING, true, null);
- stopping(State.STARTING);
- break;
- case RUNNING:
- snapshot = new StateSnapshot(State.STOPPING);
- stopping(State.RUNNING);
- doStop();
- break;
- case STOPPING:
- case TERMINATED:
- case FAILED:
- // do nothing
- break;
- default:
- throw new AssertionError("Unexpected state: " + snapshot.state);
+ if (state == State.NEW) {
+ state = State.TERMINATED;
+ startup.set(State.TERMINATED);
+ shutdown.set(State.TERMINATED);
+ } else if (state == State.STARTING) {
+ shutdownWhenStartupFinishes = true;
+ startup.set(State.STOPPING);
+ } else if (state == State.RUNNING) {
+ state = State.STOPPING;
+ doStop();
}
} catch (Throwable shutdownFailure) {
+ // put the exception in the future, the user can get it via Future.get()
notifyFailed(shutdownFailure);
} finally {
lock.unlock();
- executeListeners();
}
return shutdown;
@@ -227,91 +135,84 @@ public abstract class AbstractService implements Service {
}
/**
- * Implementing classes should invoke this method once their service has started. It will cause
- * the service to transition from {@link State#STARTING} to {@link State#RUNNING}.
+ * Implementing classes should invoke this method once their service has
+ * started. It will cause the service to transition from {@link
+ * State#STARTING} to {@link State#RUNNING}.
*
- * @throws IllegalStateException if the service is not {@link State#STARTING}.
+ * @throws IllegalStateException if the service is not
+ * {@link State#STARTING}.
*/
protected final void notifyStarted() {
lock.lock();
try {
- if (snapshot.state != State.STARTING) {
+ if (state != State.STARTING) {
IllegalStateException failure = new IllegalStateException(
- "Cannot notifyStarted() when the service is " + snapshot.state);
+ "Cannot notifyStarted() when the service is " + state);
notifyFailed(failure);
throw failure;
}
- if (snapshot.shutdownWhenStartupFinishes) {
- snapshot = new StateSnapshot(State.STOPPING);
- // We don't call listeners here because we already did that when we set the
- // shutdownWhenStartupFinishes flag.
- doStop();
+ state = State.RUNNING;
+ if (shutdownWhenStartupFinishes) {
+ stop();
} else {
- snapshot = new StateSnapshot(State.RUNNING);
- running();
+ startup.set(State.RUNNING);
}
} finally {
lock.unlock();
- executeListeners();
}
}
/**
- * Implementing classes should invoke this method once their service has stopped. It will cause
- * the service to transition from {@link State#STOPPING} to {@link State#TERMINATED}.
+ * Implementing classes should invoke this method once their service has
+ * stopped. It will cause the service to transition from {@link
+ * State#STOPPING} to {@link State#TERMINATED}.
*
- * @throws IllegalStateException if the service is neither {@link State#STOPPING} nor
- * {@link State#RUNNING}.
+ * @throws IllegalStateException if the service is neither {@link
+ * State#STOPPING} nor {@link State#RUNNING}.
*/
protected final void notifyStopped() {
lock.lock();
try {
- if (snapshot.state != State.STOPPING && snapshot.state != State.RUNNING) {
+ if (state != State.STOPPING && state != State.RUNNING) {
IllegalStateException failure = new IllegalStateException(
- "Cannot notifyStopped() when the service is " + snapshot.state);
+ "Cannot notifyStopped() when the service is " + state);
notifyFailed(failure);
throw failure;
}
- State previous = snapshot.state;
- snapshot = new StateSnapshot(State.TERMINATED);
- terminated(previous);
+
+ state = State.TERMINATED;
+ shutdown.set(State.TERMINATED);
} finally {
lock.unlock();
- executeListeners();
}
}
/**
- * Invoke this method to transition the service to the {@link State#FAILED}. The service will
- * <b>not be stopped</b> if it is running. Invoke this method when a service has failed critically
- * or otherwise cannot be started nor stopped.
+ * Invoke this method to transition the service to the
+ * {@link State#FAILED}. The service will <b>not be stopped</b> if it
+ * is running. Invoke this method when a service has failed critically or
+ * otherwise cannot be started nor stopped.
*/
protected final void notifyFailed(Throwable cause) {
checkNotNull(cause);
lock.lock();
try {
- switch (snapshot.state) {
- case NEW:
- case TERMINATED:
- throw new IllegalStateException("Failed while in state:" + snapshot.state, cause);
- case RUNNING:
- case STARTING:
- case STOPPING:
- State previous = snapshot.state;
- snapshot = new StateSnapshot(State.FAILED, false, cause);
- failed(previous, cause);
- break;
- case FAILED:
- // Do nothing
- break;
- default:
- throw new AssertionError("Unexpected state: " + snapshot.state);
+ if (state == State.STARTING) {
+ startup.setException(cause);
+ shutdown.setException(new Exception(
+ "Service failed to start.", cause));
+ } else if (state == State.STOPPING) {
+ shutdown.setException(cause);
+ } else if (state == State.RUNNING) {
+ shutdown.setException(new Exception("Service failed while running", cause));
+ } else if (state == State.NEW || state == State.TERMINATED) {
+ throw new IllegalStateException("Failed while in state:" + state, cause);
}
+ state = State.FAILED;
} finally {
lock.unlock();
- executeListeners();
}
}
@@ -322,28 +223,12 @@ public abstract class AbstractService implements Service {
@Override
public final State state() {
- return snapshot.externalState();
- }
-
- /**
- * @since 14.0
- */
- @Override
- public final Throwable failureCause() {
- return snapshot.failureCause();
- }
-
- /**
- * @since 13.0
- */
- @Override
- public final void addListener(Listener listener, Executor executor) {
- checkNotNull(listener, "listener");
- checkNotNull(executor, "executor");
lock.lock();
try {
- if (snapshot.state != State.TERMINATED && snapshot.state != State.FAILED) {
- listeners.add(new ListenerExecutorPair(listener, executor));
+ if (shutdownWhenStartupFinishes && state == State.STARTING) {
+ return State.STOPPING;
+ } else {
+ return state;
}
} finally {
lock.unlock();
@@ -368,182 +253,4 @@ public abstract class AbstractService implements Service {
}
}
}
-
- /**
- * Attempts to execute all the listeners in {@link #queuedListeners} while not holding the
- * {@link #lock}.
- */
- private void executeListeners() {
- if (!lock.isHeldByCurrentThread()) {
- synchronized (queuedListeners) {
- Runnable listener;
- while ((listener = queuedListeners.poll()) != null) {
- listener.run();
- }
- }
- }
- }
-
- @GuardedBy("lock")
- private void starting() {
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.starting();
- }
- });
- }
- });
- }
- }
-
- @GuardedBy("lock")
- private void running() {
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.running();
- }
- });
- }
- });
- }
- }
-
- @GuardedBy("lock")
- private void stopping(final State from) {
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.stopping(from);
- }
- });
- }
- });
- }
- }
-
- @GuardedBy("lock")
- private void terminated(final State from) {
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.terminated(from);
- }
- });
- }
- });
- }
- // There are no more state transitions so we can clear this out.
- listeners.clear();
- }
-
- @GuardedBy("lock")
- private void failed(final State from, final Throwable cause) {
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.failed(from, cause);
- }
- });
- }
- });
- }
- // There are no more state transitions so we can clear this out.
- listeners.clear();
- }
-
- /** A simple holder for a listener and its executor. */
- private static class ListenerExecutorPair {
- final Listener listener;
- final Executor executor;
-
- ListenerExecutorPair(Listener listener, Executor executor) {
- this.listener = listener;
- this.executor = executor;
- }
-
- /**
- * Executes the given {@link Runnable} on {@link #executor} logging and swallowing all
- * exceptions
- */
- void execute(Runnable runnable) {
- try {
- executor.execute(runnable);
- } catch (Exception e) {
- logger.log(Level.SEVERE, "Exception while executing listener " + listener
- + " with executor " + executor, e);
- }
- }
- }
-
- /**
- * An immutable snapshot of the current state of the service. This class represents a consistent
- * snapshot of the state and therefore it can be used to answer simple queries without needing to
- * grab a lock.
- */
- @Immutable
- private static final class StateSnapshot {
- /**
- * The internal state, which equals external state unless
- * shutdownWhenStartupFinishes is true.
- */
- final State state;
-
- /**
- * If true, the user requested a shutdown while the service was still starting
- * up.
- */
- final boolean shutdownWhenStartupFinishes;
-
- /**
- * The exception that caused this service to fail. This will be {@code null}
- * unless the service has failed.
- */
- @Nullable
- final Throwable failure;
-
- StateSnapshot(State internalState) {
- this(internalState, false, null);
- }
-
- StateSnapshot(
- State internalState, boolean shutdownWhenStartupFinishes, @Nullable Throwable failure) {
- checkArgument(!shutdownWhenStartupFinishes || internalState == State.STARTING,
- "shudownWhenStartupFinishes can only be set if state is STARTING. Got %s instead.",
- internalState);
- checkArgument(!(failure != null ^ internalState == State.FAILED),
- "A failure cause should be set if and only if the state is failed. Got %s and %s "
- + "instead.", internalState, failure);
- this.state = internalState;
- this.shutdownWhenStartupFinishes = shutdownWhenStartupFinishes;
- this.failure = failure;
- }
-
- /** @see Service#state() */
- State externalState() {
- if (shutdownWhenStartupFinishes && state == State.STARTING) {
- return State.STOPPING;
- } else {
- return state;
- }
- }
-
- /** @see Service#failureCause() */
- Throwable failureCause() {
- checkState(state == State.FAILED,
- "failureCause() is only valid if the service has failed, service is %s", state);
- return failure;
- }
- }
}
diff --git a/guava/src/com/google/common/util/concurrent/AsyncFunction.java b/guava/src/com/google/common/util/concurrent/AsyncFunction.java
index cdb1228..441c029 100644
--- a/guava/src/com/google/common/util/concurrent/AsyncFunction.java
+++ b/guava/src/com/google/common/util/concurrent/AsyncFunction.java
@@ -16,6 +16,8 @@
package com.google.common.util.concurrent;
+import com.google.common.annotations.Beta;
+
import java.util.concurrent.Future;
/**
@@ -25,6 +27,7 @@ import java.util.concurrent.Future;
* @author Chris Povirk
* @since 11.0
*/
+@Beta
public interface AsyncFunction<I, O> {
/**
* Returns an output {@code Future} to use in place of the given {@code
diff --git a/guava/src/com/google/common/util/concurrent/AtomicDouble.java b/guava/src/com/google/common/util/concurrent/AtomicDouble.java
index d007f45..0f38fb9 100644
--- a/guava/src/com/google/common/util/concurrent/AtomicDouble.java
+++ b/guava/src/com/google/common/util/concurrent/AtomicDouble.java
@@ -14,9 +14,10 @@
package com.google.common.util.concurrent;
+import com.google.common.annotations.Beta;
+
import static java.lang.Double.doubleToRawLongBits;
import static java.lang.Double.longBitsToDouble;
-
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
/**
@@ -42,16 +43,17 @@ import java.util.concurrent.atomic.AtomicLongFieldUpdater;
*
* <p>It is possible to write a more scalable updater, at the cost of
* giving up strict atomicity. See for example
- * <a href="http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166edocs/jsr166e/DoubleAdder.html">
- * DoubleAdder</a>
+ * <a href="http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166edocs/jsr166e/DoubleAdder.html"
+ * DoubleAdder>
* and
- * <a href="http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166edocs/jsr166e/DoubleMaxUpdater.html">
- * DoubleMaxUpdater</a>.
+ * <a href="http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166edocs/jsr166e/DoubleMaxUpdater.html"
+ * DoubleMaxUpdater>.
*
* @author Doug Lea
* @author Martin Buchholz
* @since 11.0
*/
+@Beta
public class AtomicDouble extends Number implements java.io.Serializable {
private static final long serialVersionUID = 0L;
diff --git a/guava/src/com/google/common/util/concurrent/AtomicDoubleArray.java b/guava/src/com/google/common/util/concurrent/AtomicDoubleArray.java
index 407cd7c..37f4c5c 100644
--- a/guava/src/com/google/common/util/concurrent/AtomicDoubleArray.java
+++ b/guava/src/com/google/common/util/concurrent/AtomicDoubleArray.java
@@ -13,9 +13,10 @@
package com.google.common.util.concurrent;
+import com.google.common.annotations.Beta;
+
import static java.lang.Double.doubleToRawLongBits;
import static java.lang.Double.longBitsToDouble;
-
import java.util.concurrent.atomic.AtomicLongArray;
/**
@@ -39,6 +40,7 @@ import java.util.concurrent.atomic.AtomicLongArray;
* @author Martin Buchholz
* @since 11.0
*/
+@Beta
public class AtomicDoubleArray implements java.io.Serializable {
private static final long serialVersionUID = 0L;
diff --git a/guava/src/com/google/common/util/concurrent/AtomicLongMap.java b/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
index d0af965..c49f84c 100644
--- a/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
+++ b/guava/src/com/google/common/util/concurrent/AtomicLongMap.java
@@ -1,24 +1,10 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// Copyright 2011 Google Inc. All Rights Reserved.
package com.google.common.util.concurrent;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
@@ -50,7 +36,7 @@ import java.util.concurrent.atomic.AtomicLong;
* @author Charles Fry
* @since 11.0
*/
-@GwtCompatible
+@Beta
public final class AtomicLongMap<K> {
private final ConcurrentHashMap<K, AtomicLong> map;
diff --git a/guava/src/com/google/common/util/concurrent/Atomics.java b/guava/src/com/google/common/util/concurrent/Atomics.java
index efb7946..fece83d 100644
--- a/guava/src/com/google/common/util/concurrent/Atomics.java
+++ b/guava/src/com/google/common/util/concurrent/Atomics.java
@@ -16,6 +16,8 @@
package com.google.common.util.concurrent;
+import com.google.common.annotations.Beta;
+
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
@@ -28,6 +30,7 @@ import javax.annotation.Nullable;
* @author Kurt Alfred Kluever
* @since 10.0
*/
+@Beta
public final class Atomics {
private Atomics() {}
diff --git a/guava/src/com/google/common/util/concurrent/CycleDetectingLockFactory.java b/guava/src/com/google/common/util/concurrent/CycleDetectingLockFactory.java
deleted file mode 100644
index 528fc8e..0000000
--- a/guava/src/com/google/common/util/concurrent/CycleDetectingLockFactory.java
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * The {@code CycleDetectingLockFactory} creates {@link ReentrantLock} instances and
- * {@link ReentrantReadWriteLock} instances that detect potential deadlock by checking
- * for cycles in lock acquisition order.
- * <p>
- * Potential deadlocks detected when calling the {@code lock()},
- * {@code lockInterruptibly()}, or {@code tryLock()} methods will result in the
- * execution of the {@link Policy} specified when creating the factory. The
- * currently available policies are:
- * <ul>
- * <li>DISABLED
- * <li>WARN
- * <li>THROW
- * </ul>
- * The locks created by a factory instance will detect lock acquisition cycles
- * with locks created by other {@code CycleDetectingLockFactory} instances
- * (except those with {@code Policy.DISABLED}). A lock's behavior when a cycle
- * is detected, however, is defined by the {@code Policy} of the factory that
- * created it. This allows detection of cycles across components while
- * delegating control over lock behavior to individual components.
- * <p>
- * Applications are encouraged to use a {@code CycleDetectingLockFactory} to
- * create any locks for which external/unmanaged code is executed while the lock
- * is held. (See caveats under <strong>Performance</strong>).
- * <p>
- * <strong>Cycle Detection</strong>
- * <p>
- * Deadlocks can arise when locks are acquired in an order that forms a cycle.
- * In a simple example involving two locks and two threads, deadlock occurs
- * when one thread acquires Lock A, and then Lock B, while another thread
- * acquires Lock B, and then Lock A:
- * <pre>
- * Thread1: acquire(LockA) --X acquire(LockB)
- * Thread2: acquire(LockB) --X acquire(LockA)
- * </pre>
- * Neither thread will progress because each is waiting for the other. In more
- * complex applications, cycles can arise from interactions among more than 2
- * locks:
- * <pre>
- * Thread1: acquire(LockA) --X acquire(LockB)
- * Thread2: acquire(LockB) --X acquire(LockC)
- * ...
- * ThreadN: acquire(LockN) --X acquire(LockA)
- * </pre>
- * The implementation detects cycles by constructing a directed graph in which
- * each lock represents a node and each edge represents an acquisition ordering
- * between two locks.
- * <ul>
- * <li>Each lock adds (and removes) itself to/from a ThreadLocal Set of acquired
- * locks when the Thread acquires its first hold (and releases its last
- * remaining hold).
- * <li>Before the lock is acquired, the lock is checked against the current set
- * of acquired locks---to each of the acquired locks, an edge from the
- * soon-to-be-acquired lock is either verified or created.
- * <li>If a new edge needs to be created, the outgoing edges of the acquired
- * locks are traversed to check for a cycle that reaches the lock to be
- * acquired. If no cycle is detected, a new "safe" edge is created.
- * <li>If a cycle is detected, an "unsafe" (cyclic) edge is created to represent
- * a potential deadlock situation, and the appropriate Policy is executed.
- * </ul>
- * Note that detection of potential deadlock does not necessarily indicate that
- * deadlock will happen, as it is possible that higher level application logic
- * prevents the cyclic lock acquisition from occurring. One example of a false
- * positive is:
- * <pre>
- * LockA -&gt; LockB -&gt; LockC
- * LockA -&gt; LockC -&gt; LockB
- * </pre>
- *
- * <strong>ReadWriteLocks</strong>
- * <p>
- * While {@code ReadWriteLock} instances have different properties and can form cycles
- * without potential deadlock, this class treats {@code ReadWriteLock} instances as
- * equivalent to traditional exclusive locks. Although this increases the false
- * positives that the locks detect (i.e. cycles that will not actually result in
- * deadlock), it simplifies the algorithm and implementation considerably. The
- * assumption is that a user of this factory wishes to eliminate any cyclic
- * acquisition ordering.
- * <p>
- * <strong>Explicit Lock Acquisition Ordering</strong>
- * <p>
- * The {@link CycleDetectingLockFactory.WithExplicitOrdering} class can be used
- * to enforce an application-specific ordering in addition to performing general
- * cycle detection.
- * <p>
- * <strong>Garbage Collection</strong>
- * <p>
- * In order to allow proper garbage collection of unused locks, the edges of
- * the lock graph are weak references.
- * <p>
- * <strong>Performance</strong>
- * <p>
- * The extra bookkeeping done by cycle detecting locks comes at some cost to
- * performance. Benchmarks (as of December 2011) show that:
- *
- * <ul>
- * <li>for an unnested {@code lock()} and {@code unlock()}, a cycle detecting
- * lock takes 38ns as opposed to the 24ns taken by a plain lock.
- * <li>for nested locking, the cost increases with the depth of the nesting:
- * <ul>
- * <li> 2 levels: average of 64ns per lock()/unlock()
- * <li> 3 levels: average of 77ns per lock()/unlock()
- * <li> 4 levels: average of 99ns per lock()/unlock()
- * <li> 5 levels: average of 103ns per lock()/unlock()
- * <li>10 levels: average of 184ns per lock()/unlock()
- * <li>20 levels: average of 393ns per lock()/unlock()
- * </ul>
- * </ul>
- *
- * As such, the CycleDetectingLockFactory may not be suitable for
- * performance-critical applications which involve tightly-looped or
- * deeply-nested locking algorithms.
- *
- * @author Darick Tong
- * @since 13.0
- */
-@Beta
-@ThreadSafe
-public class CycleDetectingLockFactory {
-
- /**
- * Encapsulates the action to be taken when a potential deadlock is
- * encountered. Clients can use one of the predefined {@link Policies} or
- * specify a custom implementation. Implementations must be thread-safe.
- *
- * @since 13.0
- */
- @Beta
- @ThreadSafe
- public interface Policy {
-
- /**
- * Called when a potential deadlock is encountered. Implementations can
- * throw the given {@code exception} and/or execute other desired logic.
- * <p>
- * Note that the method will be called even upon an invocation of
- * {@code tryLock()}. Although {@code tryLock()} technically recovers from
- * deadlock by eventually timing out, this behavior is chosen based on the
- * assumption that it is the application's wish to prohibit any cyclical
- * lock acquisitions.
- */
- void handlePotentialDeadlock(PotentialDeadlockException exception);
- }
-
- /**
- * Pre-defined {@link Policy} implementations.
- *
- * @since 13.0
- */
- @Beta
- public enum Policies implements Policy {
- /**
- * When potential deadlock is detected, this policy results in the throwing
- * of the {@code PotentialDeadlockException} indicating the potential
- * deadlock, which includes stack traces illustrating the cycle in lock
- * acquisition order.
- */
- THROW {
- @Override
- public void handlePotentialDeadlock(PotentialDeadlockException e) {
- throw e;
- }
- },
-
- /**
- * When potential deadlock is detected, this policy results in the logging
- * of a {@link Level#SEVERE} message indicating the potential deadlock,
- * which includes stack traces illustrating the cycle in lock acquisition
- * order.
- */
- WARN {
- @Override
- public void handlePotentialDeadlock(PotentialDeadlockException e) {
- logger.log(Level.SEVERE, "Detected potential deadlock", e);
- }
- },
-
- /**
- * Disables cycle detection. This option causes the factory to return
- * unmodified lock implementations provided by the JDK, and is provided to
- * allow applications to easily parameterize when cycle detection is
- * enabled.
- * <p>
- * Note that locks created by a factory with this policy will <em>not</em>
- * participate the cycle detection performed by locks created by other
- * factories.
- */
- DISABLED {
- @Override
- public void handlePotentialDeadlock(PotentialDeadlockException e) {
- }
- };
- }
-
- /**
- * Creates a new factory with the specified policy.
- */
- public static CycleDetectingLockFactory newInstance(Policy policy) {
- return new CycleDetectingLockFactory(policy);
- }
-
- /**
- * Equivalent to {@code newReentrantLock(lockName, false)}.
- */
- public ReentrantLock newReentrantLock(String lockName) {
- return newReentrantLock(lockName, false);
- }
-
- /**
- * Creates a {@link ReentrantLock} with the given fairness policy. The
- * {@code lockName} is used in the warning or exception output to help
- * identify the locks involved in the detected deadlock.
- */
- public ReentrantLock newReentrantLock(String lockName, boolean fair) {
- return policy == Policies.DISABLED ? new ReentrantLock(fair)
- : new CycleDetectingReentrantLock(
- new LockGraphNode(lockName), fair);
- }
-
- /**
- * Equivalent to {@code newReentrantReadWriteLock(lockName, false)}.
- */
- public ReentrantReadWriteLock newReentrantReadWriteLock(String lockName) {
- return newReentrantReadWriteLock(lockName, false);
- }
-
- /**
- * Creates a {@link ReentrantReadWriteLock} with the given fairness policy.
- * The {@code lockName} is used in the warning or exception output to help
- * identify the locks involved in the detected deadlock.
- */
- public ReentrantReadWriteLock newReentrantReadWriteLock(
- String lockName, boolean fair) {
- return policy == Policies.DISABLED ? new ReentrantReadWriteLock(fair)
- : new CycleDetectingReentrantReadWriteLock(
- new LockGraphNode(lockName), fair);
- }
-
- // A static mapping from an Enum type to its set of LockGraphNodes.
- private static final Map<Class<? extends Enum>,
- Map<? extends Enum, LockGraphNode>> lockGraphNodesPerType =
- new MapMaker().weakKeys().makeComputingMap(
- new OrderedLockGraphNodesCreator());
-
- /**
- * Creates a {@code CycleDetectingLockFactory.WithExplicitOrdering<E>}.
- */
- public static <E extends Enum<E>> WithExplicitOrdering<E>
- newInstanceWithExplicitOrdering(Class<E> enumClass, Policy policy) {
- // OrderedLockGraphNodesCreator maps each enumClass to a Map with the
- // corresponding enum key type.
- checkNotNull(enumClass);
- checkNotNull(policy);
- @SuppressWarnings("unchecked")
- Map<E, LockGraphNode> lockGraphNodes =
- (Map<E, LockGraphNode>) lockGraphNodesPerType.get(enumClass);
- return new WithExplicitOrdering<E>(policy, lockGraphNodes);
- }
-
- /**
- * A {@code CycleDetectingLockFactory.WithExplicitOrdering} provides the
- * additional enforcement of an application-specified ordering of lock
- * acquisitions. The application defines the allowed ordering with an
- * {@code Enum} whose values each correspond to a lock type. The order in
- * which the values are declared dictates the allowed order of lock
- * acquisition. In other words, locks corresponding to smaller values of
- * {@link Enum#ordinal()} should only be acquired before locks with larger
- * ordinals. Example:
- *
- * <pre> {@code
- * enum MyLockOrder {
- * FIRST, SECOND, THIRD;
- * }
- *
- * CycleDetectingLockFactory.WithExplicitOrdering<MyLockOrder> factory =
- * CycleDetectingLockFactory.newInstanceWithExplicitOrdering(Policies.THROW);
- *
- * Lock lock1 = factory.newReentrantLock(MyLockOrder.FIRST);
- * Lock lock2 = factory.newReentrantLock(MyLockOrder.SECOND);
- * Lock lock3 = factory.newReentrantLock(MyLockOrder.THIRD);
- *
- * lock1.lock();
- * lock3.lock();
- * lock2.lock(); // will throw an IllegalStateException
- * }</pre>
- *
- * As with all locks created by instances of {@code CycleDetectingLockFactory}
- * explicitly ordered locks participate in general cycle detection with all
- * other cycle detecting locks, and a lock's behavior when detecting a cyclic
- * lock acquisition is defined by the {@code Policy} of the factory that
- * created it.
- * <p>
- * Note, however, that although multiple locks can be created for a given Enum
- * value, whether it be through separate factory instances or through multiple
- * calls to the same factory, attempting to acquire multiple locks with the
- * same Enum value (within the same thread) will result in an
- * IllegalStateException regardless of the factory's policy. For example:
- *
- * <pre> {@code
- * CycleDetectingLockFactory.WithExplicitOrdering<MyLockOrder> factory1 =
- * CycleDetectingLockFactory.newInstanceWithExplicitOrdering(...);
- * CycleDetectingLockFactory.WithExplicitOrdering<MyLockOrder> factory2 =
- * CycleDetectingLockFactory.newInstanceWithExplicitOrdering(...);
- *
- * Lock lockA = factory1.newReentrantLock(MyLockOrder.FIRST);
- * Lock lockB = factory1.newReentrantLock(MyLockOrder.FIRST);
- * Lock lockC = factory2.newReentrantLock(MyLockOrder.FIRST);
- *
- * lockA.lock();
- *
- * lockB.lock(); // will throw an IllegalStateException
- * lockC.lock(); // will throw an IllegalStateException
- *
- * lockA.lock(); // reentrant acquisition is okay
- * }</pre>
- *
- * It is the responsibility of the application to ensure that multiple lock
- * instances with the same rank are never acquired in the same thread.
- *
- * @param <E> The Enum type representing the explicit lock ordering.
- * @since 13.0
- */
- @Beta
- public static final class WithExplicitOrdering<E extends Enum<E>>
- extends CycleDetectingLockFactory {
-
- private final Map<E, LockGraphNode> lockGraphNodes;
-
- @VisibleForTesting
- WithExplicitOrdering(
- Policy policy, Map<E, LockGraphNode> lockGraphNodes) {
- super(policy);
- this.lockGraphNodes = lockGraphNodes;
- }
-
- /**
- * Equivalent to {@code newReentrantLock(rank, false)}.
- */
- public ReentrantLock newReentrantLock(E rank) {
- return newReentrantLock(rank, false);
- }
-
- /**
- * Creates a {@link ReentrantLock} with the given fairness policy and rank.
- * The values returned by {@link Enum#getDeclaringClass()} and
- * {@link Enum#name()} are used to describe the lock in warning or
- * exception output.
- *
- * @throws IllegalStateException If the factory has already created a
- * {@code Lock} with the specified rank.
- */
- public ReentrantLock newReentrantLock(E rank, boolean fair) {
- return policy == Policies.DISABLED ? new ReentrantLock(fair)
- : new CycleDetectingReentrantLock(lockGraphNodes.get(rank), fair);
- }
-
- /**
- * Equivalent to {@code newReentrantReadWriteLock(rank, false)}.
- */
- public ReentrantReadWriteLock newReentrantReadWriteLock(E rank) {
- return newReentrantReadWriteLock(rank, false);
- }
-
- /**
- * Creates a {@link ReentrantReadWriteLock} with the given fairness policy
- * and rank. The values returned by {@link Enum#getDeclaringClass()} and
- * {@link Enum#name()} are used to describe the lock in warning or exception
- * output.
- *
- * @throws IllegalStateException If the factory has already created a
- * {@code Lock} with the specified rank.
- */
- public ReentrantReadWriteLock newReentrantReadWriteLock(
- E rank, boolean fair) {
- return policy == Policies.DISABLED ? new ReentrantReadWriteLock(fair)
- : new CycleDetectingReentrantReadWriteLock(
- lockGraphNodes.get(rank), fair);
- }
- }
-
- /**
- * For a given Enum type, creates an immutable map from each of the Enum's
- * values to a corresponding LockGraphNode, with the
- * {@code allowedPriorLocks} and {@code disallowedPriorLocks} prepopulated
- * with nodes according to the natural ordering of the associated Enum values.
- */
- @VisibleForTesting
- static class OrderedLockGraphNodesCreator
- implements Function<Class<? extends Enum>,
- Map<? extends Enum, LockGraphNode>> {
-
- @Override
- @SuppressWarnings("unchecked") // There's no way to properly express with
- // wildcards the recursive Enum type required by createNodesFor(), and the
- // Map/Function types must use wildcards since they accept any Enum class.
- public Map<? extends Enum, LockGraphNode> apply(
- Class<? extends Enum> clazz) {
- return createNodesFor(clazz);
- }
-
- <E extends Enum<E>> Map<E, LockGraphNode> createNodesFor(Class<E> clazz) {
- EnumMap<E, LockGraphNode> map = Maps.newEnumMap(clazz);
- E[] keys = clazz.getEnumConstants();
- final int numKeys = keys.length;
- ArrayList<LockGraphNode> nodes =
- Lists.newArrayListWithCapacity(numKeys);
- // Create a LockGraphNode for each enum value.
- for (E key : keys) {
- LockGraphNode node = new LockGraphNode(getLockName(key));
- nodes.add(node);
- map.put(key, node);
- }
- // Pre-populate all allowedPriorLocks with nodes of smaller ordinal.
- for (int i = 1; i < numKeys; i++) {
- nodes.get(i).checkAcquiredLocks(Policies.THROW, nodes.subList(0, i));
- }
- // Pre-populate all disallowedPriorLocks with nodes of larger ordinal.
- for (int i = 0; i < numKeys - 1; i++) {
- nodes.get(i).checkAcquiredLocks(
- Policies.DISABLED, nodes.subList(i + 1, numKeys));
- }
- return Collections.unmodifiableMap(map);
- }
-
- /**
- * For the given Enum value {@code rank}, returns the value's
- * {@code "EnumClass.name"}, which is used in exception and warning
- * output.
- */
- private String getLockName(Enum<?> rank) {
- return rank.getDeclaringClass().getSimpleName() + "." + rank.name();
- }
- }
-
- //////// Implementation /////////
-
- private static final Logger logger = Logger.getLogger(
- CycleDetectingLockFactory.class.getName());
-
- final Policy policy;
-
- private CycleDetectingLockFactory(Policy policy) {
- this.policy = checkNotNull(policy);
- }
-
- /**
- * Tracks the currently acquired locks for each Thread, kept up to date by
- * calls to {@link #aboutToAcquire(CycleDetectingLock)} and
- * {@link #lockStateChanged(CycleDetectingLock)}.
- */
- // This is logically a Set, but an ArrayList is used to minimize the amount
- // of allocation done on lock()/unlock().
- private static final ThreadLocal<ArrayList<LockGraphNode>>
- acquiredLocks = new ThreadLocal<ArrayList<LockGraphNode>>() {
- @Override
- protected ArrayList<LockGraphNode> initialValue() {
- return Lists.<LockGraphNode>newArrayListWithCapacity(3);
- }
- };
-
- /**
- * A Throwable used to record a stack trace that illustrates an example of
- * a specific lock acquisition ordering. The top of the stack trace is
- * truncated such that it starts with the acquisition of the lock in
- * question, e.g.
- *
- * <pre>
- * com...ExampleStackTrace: LockB -&gt; LockC
- * at com...CycleDetectingReentrantLock.lock(CycleDetectingLockFactory.java:443)
- * at ...
- * at ...
- * at com...MyClass.someMethodThatAcquiresLockB(MyClass.java:123)
- * </pre>
- */
- private static class ExampleStackTrace extends IllegalStateException {
-
- static final StackTraceElement[] EMPTY_STACK_TRACE =
- new StackTraceElement[0];
-
- static Set<String> EXCLUDED_CLASS_NAMES = ImmutableSet.of(
- CycleDetectingLockFactory.class.getName(),
- ExampleStackTrace.class.getName(),
- LockGraphNode.class.getName());
-
- ExampleStackTrace(LockGraphNode node1, LockGraphNode node2) {
- super(node1.getLockName() + " -> " + node2.getLockName());
- StackTraceElement[] origStackTrace = getStackTrace();
- for (int i = 0, n = origStackTrace.length; i < n; i++) {
- if (WithExplicitOrdering.class.getName().equals(
- origStackTrace[i].getClassName())) {
- // For pre-populated disallowedPriorLocks edges, omit the stack trace.
- setStackTrace(EMPTY_STACK_TRACE);
- break;
- }
- if (!EXCLUDED_CLASS_NAMES.contains(origStackTrace[i].getClassName())) {
- setStackTrace(Arrays.copyOfRange(origStackTrace, i, n));
- break;
- }
- }
- }
- }
-
- /**
- * Represents a detected cycle in lock acquisition ordering. The exception
- * includes a causal chain of {@code ExampleStackTrace} instances to illustrate the
- * cycle, e.g.
- *
- * <pre>
- * com....PotentialDeadlockException: Potential Deadlock from LockC -&gt; ReadWriteA
- * at ...
- * at ...
- * Caused by: com...ExampleStackTrace: LockB -&gt; LockC
- * at ...
- * at ...
- * Caused by: com...ExampleStackTrace: ReadWriteA -&gt; LockB
- * at ...
- * at ...
- * </pre>
- *
- * Instances are logged for the {@code Policies.WARN}, and thrown for
- * {@code Policies.THROW}.
- *
- * @since 13.0
- */
- @Beta
- public static final class PotentialDeadlockException
- extends ExampleStackTrace {
-
- private final ExampleStackTrace conflictingStackTrace;
-
- private PotentialDeadlockException(
- LockGraphNode node1,
- LockGraphNode node2,
- ExampleStackTrace conflictingStackTrace) {
- super(node1, node2);
- this.conflictingStackTrace = conflictingStackTrace;
- initCause(conflictingStackTrace);
- }
-
- public ExampleStackTrace getConflictingStackTrace() {
- return conflictingStackTrace;
- }
-
- /**
- * Appends the chain of messages from the {@code conflictingStackTrace} to
- * the original {@code message}.
- */
- @Override
- public String getMessage() {
- StringBuilder message = new StringBuilder(super.getMessage());
- for (Throwable t = conflictingStackTrace; t != null; t = t.getCause()) {
- message.append(", ").append(t.getMessage());
- }
- return message.toString();
- }
- }
-
- /**
- * Internal Lock implementations implement the {@code CycleDetectingLock}
- * interface, allowing the detection logic to treat all locks in the same
- * manner.
- */
- private interface CycleDetectingLock {
-
- /** @return the {@link LockGraphNode} associated with this lock. */
- LockGraphNode getLockGraphNode();
-
- /** @return {@code true} if the current thread has acquired this lock. */
- boolean isAcquiredByCurrentThread();
- }
-
- /**
- * A {@code LockGraphNode} associated with each lock instance keeps track of
- * the directed edges in the lock acquisition graph.
- */
- private static class LockGraphNode {
-
- /**
- * The map tracking the locks that are known to be acquired before this
- * lock, each associated with an example stack trace. Locks are weakly keyed
- * to allow proper garbage collection when they are no longer referenced.
- */
- final Map<LockGraphNode, ExampleStackTrace> allowedPriorLocks =
- new MapMaker().weakKeys().makeMap();
-
- /**
- * The map tracking lock nodes that can cause a lock acquisition cycle if
- * acquired before this node.
- */
- final Map<LockGraphNode, PotentialDeadlockException>
- disallowedPriorLocks = new MapMaker().weakKeys().makeMap();
-
- final String lockName;
-
- LockGraphNode(String lockName) {
- this.lockName = Preconditions.checkNotNull(lockName);
- }
-
- String getLockName() {
- return lockName;
- }
-
- void checkAcquiredLocks(
- Policy policy, List<LockGraphNode> acquiredLocks) {
- for (int i = 0, size = acquiredLocks.size(); i < size; i++) {
- checkAcquiredLock(policy, acquiredLocks.get(i));
- }
- }
-
- /**
- * Checks the acquisition-ordering between {@code this}, which is about to
- * be acquired, and the specified {@code acquiredLock}.
- * <p>
- * When this method returns, the {@code acquiredLock} should be in either
- * the {@code preAcquireLocks} map, for the case in which it is safe to
- * acquire {@code this} after the {@code acquiredLock}, or in the
- * {@code disallowedPriorLocks} map, in which case it is not safe.
- */
- void checkAcquiredLock(Policy policy, LockGraphNode acquiredLock) {
- // checkAcquiredLock() should never be invoked by a lock that has already
- // been acquired. For unordered locks, aboutToAcquire() ensures this by
- // checking isAcquiredByCurrentThread(). For ordered locks, however, this
- // can happen because multiple locks may share the same LockGraphNode. In
- // this situation, throw an IllegalStateException as defined by contract
- // described in the documentation of WithExplicitOrdering.
- Preconditions.checkState(
- this != acquiredLock,
- "Attempted to acquire multiple locks with the same rank " +
- acquiredLock.getLockName());
-
- if (allowedPriorLocks.containsKey(acquiredLock)) {
- // The acquisition ordering from "acquiredLock" to "this" has already
- // been verified as safe. In a properly written application, this is
- // the common case.
- return;
- }
- PotentialDeadlockException previousDeadlockException =
- disallowedPriorLocks.get(acquiredLock);
- if (previousDeadlockException != null) {
- // Previously determined to be an unsafe lock acquisition.
- // Create a new PotentialDeadlockException with the same causal chain
- // (the example cycle) as that of the cached exception.
- PotentialDeadlockException exception = new PotentialDeadlockException(
- acquiredLock, this,
- previousDeadlockException.getConflictingStackTrace());
- policy.handlePotentialDeadlock(exception);
- return;
- }
- // Otherwise, it's the first time seeing this lock relationship. Look for
- // a path from the acquiredLock to this.
- Set<LockGraphNode> seen = Sets.newIdentityHashSet();
- ExampleStackTrace path = acquiredLock.findPathTo(this, seen);
-
- if (path == null) {
- // this can be safely acquired after the acquiredLock.
- //
- // Note that there is a race condition here which can result in missing
- // a cyclic edge: it's possible for two threads to simultaneous find
- // "safe" edges which together form a cycle. Preventing this race
- // condition efficiently without _introducing_ deadlock is probably
- // tricky. For now, just accept the race condition---missing a warning
- // now and then is still better than having no deadlock detection.
- allowedPriorLocks.put(
- acquiredLock, new ExampleStackTrace(acquiredLock, this));
- } else {
- // Unsafe acquisition order detected. Create and cache a
- // PotentialDeadlockException.
- PotentialDeadlockException exception =
- new PotentialDeadlockException(acquiredLock, this, path);
- disallowedPriorLocks.put(acquiredLock, exception);
- policy.handlePotentialDeadlock(exception);
- }
- }
-
- /**
- * Performs a depth-first traversal of the graph edges defined by each
- * node's {@code allowedPriorLocks} to find a path between {@code this} and
- * the specified {@code lock}.
- *
- * @return If a path was found, a chained {@link ExampleStackTrace}
- * illustrating the path to the {@code lock}, or {@code null} if no path
- * was found.
- */
- @Nullable
- private ExampleStackTrace findPathTo(
- LockGraphNode node, Set<LockGraphNode> seen) {
- if (!seen.add(this)) {
- return null; // Already traversed this node.
- }
- ExampleStackTrace found = allowedPriorLocks.get(node);
- if (found != null) {
- return found; // Found a path ending at the node!
- }
- // Recurse the edges.
- for (Map.Entry<LockGraphNode, ExampleStackTrace> entry :
- allowedPriorLocks.entrySet()) {
- LockGraphNode preAcquiredLock = entry.getKey();
- found = preAcquiredLock.findPathTo(node, seen);
- if (found != null) {
- // One of this node's allowedPriorLocks found a path. Prepend an
- // ExampleStackTrace(preAcquiredLock, this) to the returned chain of
- // ExampleStackTraces.
- ExampleStackTrace path =
- new ExampleStackTrace(preAcquiredLock, this);
- path.setStackTrace(entry.getValue().getStackTrace());
- path.initCause(found);
- return path;
- }
- }
- return null;
- }
- }
-
- /**
- * CycleDetectingLock implementations must call this method before attempting
- * to acquire the lock.
- */
- private void aboutToAcquire(CycleDetectingLock lock) {
- if (!lock.isAcquiredByCurrentThread()) {
- ArrayList<LockGraphNode> acquiredLockList = acquiredLocks.get();
- LockGraphNode node = lock.getLockGraphNode();
- node.checkAcquiredLocks(policy, acquiredLockList);
- acquiredLockList.add(node);
- }
- }
-
- /**
- * CycleDetectingLock implementations must call this method in a
- * {@code finally} clause after any attempt to change the lock state,
- * including both lock and unlock attempts. Failure to do so can result in
- * corrupting the acquireLocks set.
- */
- private void lockStateChanged(CycleDetectingLock lock) {
- if (!lock.isAcquiredByCurrentThread()) {
- ArrayList<LockGraphNode> acquiredLockList = acquiredLocks.get();
- LockGraphNode node = lock.getLockGraphNode();
- // Iterate in reverse because locks are usually locked/unlocked in a
- // LIFO order.
- for (int i = acquiredLockList.size() - 1; i >=0; i--) {
- if (acquiredLockList.get(i) == node) {
- acquiredLockList.remove(i);
- break;
- }
- }
- }
- }
-
- final class CycleDetectingReentrantLock
- extends ReentrantLock implements CycleDetectingLock {
-
- private final LockGraphNode lockGraphNode;
-
- private CycleDetectingReentrantLock(
- LockGraphNode lockGraphNode, boolean fair) {
- super(fair);
- this.lockGraphNode = Preconditions.checkNotNull(lockGraphNode);
- }
-
- ///// CycleDetectingLock methods. /////
-
- @Override
- public LockGraphNode getLockGraphNode() {
- return lockGraphNode;
- }
-
- @Override
- public boolean isAcquiredByCurrentThread() {
- return isHeldByCurrentThread();
- }
-
- ///// Overridden ReentrantLock methods. /////
-
- @Override
- public void lock() {
- aboutToAcquire(this);
- try {
- super.lock();
- } finally {
- lockStateChanged(this);
- }
- }
-
- @Override
- public void lockInterruptibly() throws InterruptedException {
- aboutToAcquire(this);
- try {
- super.lockInterruptibly();
- } finally {
- lockStateChanged(this);
- }
- }
-
- @Override
- public boolean tryLock() {
- aboutToAcquire(this);
- try {
- return super.tryLock();
- } finally {
- lockStateChanged(this);
- }
- }
-
- @Override
- public boolean tryLock(long timeout, TimeUnit unit)
- throws InterruptedException {
- aboutToAcquire(this);
- try {
- return super.tryLock(timeout, unit);
- } finally {
- lockStateChanged(this);
- }
- }
-
- @Override
- public void unlock() {
- try {
- super.unlock();
- } finally {
- lockStateChanged(this);
- }
- }
- }
-
- final class CycleDetectingReentrantReadWriteLock
- extends ReentrantReadWriteLock implements CycleDetectingLock {
-
- // These ReadLock/WriteLock implementations shadow those in the
- // ReentrantReadWriteLock superclass. They are simply wrappers around the
- // internal Sync object, so this is safe since the shadowed locks are never
- // exposed or used.
- private final CycleDetectingReentrantReadLock readLock;
- private final CycleDetectingReentrantWriteLock writeLock;
-
- private final LockGraphNode lockGraphNode;
-
- private CycleDetectingReentrantReadWriteLock(
- LockGraphNode lockGraphNode, boolean fair) {
- super(fair);
- this.readLock = new CycleDetectingReentrantReadLock(this);
- this.writeLock = new CycleDetectingReentrantWriteLock(this);
- this.lockGraphNode = Preconditions.checkNotNull(lockGraphNode);
- }
-
- ///// Overridden ReentrantReadWriteLock methods. /////
-
- @Override
- public ReadLock readLock() {
- return readLock;
- }
-
- @Override
- public WriteLock writeLock() {
- return writeLock;
- }
-
- ///// CycleDetectingLock methods. /////
-
- @Override
- public LockGraphNode getLockGraphNode() {
- return lockGraphNode;
- }
-
- @Override
- public boolean isAcquiredByCurrentThread() {
- return isWriteLockedByCurrentThread() || getReadHoldCount() > 0;
- }
- }
-
- private class CycleDetectingReentrantReadLock
- extends ReentrantReadWriteLock.ReadLock {
-
- final CycleDetectingReentrantReadWriteLock readWriteLock;
-
- CycleDetectingReentrantReadLock(
- CycleDetectingReentrantReadWriteLock readWriteLock) {
- super(readWriteLock);
- this.readWriteLock = readWriteLock;
- }
-
- @Override
- public void lock() {
- aboutToAcquire(readWriteLock);
- try {
- super.lock();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public void lockInterruptibly() throws InterruptedException {
- aboutToAcquire(readWriteLock);
- try {
- super.lockInterruptibly();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public boolean tryLock() {
- aboutToAcquire(readWriteLock);
- try {
- return super.tryLock();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public boolean tryLock(long timeout, TimeUnit unit)
- throws InterruptedException {
- aboutToAcquire(readWriteLock);
- try {
- return super.tryLock(timeout, unit);
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public void unlock() {
- try {
- super.unlock();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
- }
-
- private class CycleDetectingReentrantWriteLock
- extends ReentrantReadWriteLock.WriteLock {
-
- final CycleDetectingReentrantReadWriteLock readWriteLock;
-
- CycleDetectingReentrantWriteLock(
- CycleDetectingReentrantReadWriteLock readWriteLock) {
- super(readWriteLock);
- this.readWriteLock = readWriteLock;
- }
-
- @Override
- public void lock() {
- aboutToAcquire(readWriteLock);
- try {
- super.lock();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public void lockInterruptibly() throws InterruptedException {
- aboutToAcquire(readWriteLock);
- try {
- super.lockInterruptibly();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public boolean tryLock() {
- aboutToAcquire(readWriteLock);
- try {
- return super.tryLock();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public boolean tryLock(long timeout, TimeUnit unit)
- throws InterruptedException {
- aboutToAcquire(readWriteLock);
- try {
- return super.tryLock(timeout, unit);
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
-
- @Override
- public void unlock() {
- try {
- super.unlock();
- } finally {
- lockStateChanged(readWriteLock);
- }
- }
- }
-}
diff --git a/guava/src/com/google/common/util/concurrent/ExecutionError.java b/guava/src/com/google/common/util/concurrent/ExecutionError.java
index e462969..ce588eb 100644
--- a/guava/src/com/google/common/util/concurrent/ExecutionError.java
+++ b/guava/src/com/google/common/util/concurrent/ExecutionError.java
@@ -17,8 +17,7 @@
package com.google.common.util.concurrent;
import com.google.common.annotations.GwtCompatible;
-
-import javax.annotation.Nullable;
+import com.google.common.annotations.Beta;
/**
* {@link Error} variant of {@link java.util.concurrent.ExecutionException}. As
@@ -32,6 +31,7 @@ import javax.annotation.Nullable;
* @author Chris Povirk
* @since 10.0
*/
+@Beta
@GwtCompatible
public class ExecutionError extends Error {
/**
@@ -42,21 +42,21 @@ public class ExecutionError extends Error {
/**
* Creates a new instance with the given detail message.
*/
- protected ExecutionError(@Nullable String message) {
+ protected ExecutionError(String message) {
super(message);
}
/**
* Creates a new instance with the given detail message and cause.
*/
- public ExecutionError(@Nullable String message, @Nullable Error cause) {
+ public ExecutionError(String message, Error cause) {
super(message, cause);
}
/**
* Creates a new instance with the given cause.
*/
- public ExecutionError(@Nullable Error cause) {
+ public ExecutionError(Error cause) {
super(cause);
}
diff --git a/guava/src/com/google/common/util/concurrent/ExecutionList.java b/guava/src/com/google/common/util/concurrent/ExecutionList.java
index e1a40d0..d1b78f5 100644
--- a/guava/src/com/google/common/util/concurrent/ExecutionList.java
+++ b/guava/src/com/google/common/util/concurrent/ExecutionList.java
@@ -16,7 +16,6 @@
package com.google.common.util.concurrent;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
@@ -46,7 +45,7 @@ import java.util.logging.Logger;
public final class ExecutionList {
// Logger to log exceptions caught when running runnables.
- @VisibleForTesting static final Logger log =
+ private static final Logger log =
Logger.getLogger(ExecutionList.class.getName());
// The runnable,executor pairs to execute.
diff --git a/guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java b/guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java
index 75a1e94..890479d 100644
--- a/guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java
+++ b/guava/src/com/google/common/util/concurrent/FakeTimeLimiter.java
@@ -16,8 +16,6 @@
package com.google.common.util.concurrent;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.annotations.Beta;
import java.util.concurrent.Callable;
@@ -38,16 +36,12 @@ public final class FakeTimeLimiter implements TimeLimiter {
@Override
public <T> T newProxy(T target, Class<T> interfaceType, long timeoutDuration,
TimeUnit timeoutUnit) {
- checkNotNull(target);
- checkNotNull(interfaceType);
- checkNotNull(timeoutUnit);
return target; // ha ha
}
@Override
public <T> T callWithTimeout(Callable<T> callable, long timeoutDuration,
TimeUnit timeoutUnit, boolean amInterruptible) throws Exception {
- checkNotNull(timeoutUnit);
return callable.call(); // fooled you
}
}
diff --git a/guava/src/com/google/common/util/concurrent/ForwardingService.java b/guava/src/com/google/common/util/concurrent/ForwardingService.java
index 8774232..e39e4db 100644
--- a/guava/src/com/google/common/util/concurrent/ForwardingService.java
+++ b/guava/src/com/google/common/util/concurrent/ForwardingService.java
@@ -19,22 +19,13 @@ package com.google.common.util.concurrent;
import com.google.common.annotations.Beta;
import com.google.common.collect.ForwardingObject;
-import java.util.concurrent.Executor;
-
/**
* A {@link Service} that forwards all method calls to another service.
*
- * @deprecated Instead of using a {@link ForwardingService}, consider using the
- * {@link Service.Listener} functionality to hook into the {@link Service}
- * lifecycle, or if you really do need to provide access to some Service
- * methods, consider just providing the few that you actually need (e.g. just
- * {@link #startAndWait()}) and not implementing Service.
- *
* @author Chris Nokleberg
* @since 1.0
*/
@Beta
-@Deprecated
public abstract class ForwardingService extends ForwardingObject
implements Service {
@@ -66,20 +57,6 @@ public abstract class ForwardingService extends ForwardingObject
@Override public boolean isRunning() {
return delegate().isRunning();
}
-
- /**
- * @since 13.0
- */
- @Override public void addListener(Listener listener, Executor executor) {
- delegate().addListener(listener, executor);
- }
-
- /**
- * @since 14.0
- */
- @Override public Throwable failureCause() {
- return delegate().failureCause();
- }
/**
* A sensible default implementation of {@link #startAndWait()}, in terms of
diff --git a/guava/src/com/google/common/util/concurrent/FutureCallback.java b/guava/src/com/google/common/util/concurrent/FutureCallback.java
index 735d6ab..7b39d4a 100644
--- a/guava/src/com/google/common/util/concurrent/FutureCallback.java
+++ b/guava/src/com/google/common/util/concurrent/FutureCallback.java
@@ -16,6 +16,8 @@
package com.google.common.util.concurrent;
+import com.google.common.annotations.Beta;
+
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -28,6 +30,7 @@ import java.util.concurrent.Future;
* @author Anthony Zana
* @since 10.0
*/
+@Beta
public interface FutureCallback<V> {
/**
* Invoked with the result of the {@code Future} computation when it is
diff --git a/guava/src/com/google/common/util/concurrent/FutureFallback.java b/guava/src/com/google/common/util/concurrent/FutureFallback.java
deleted file mode 100644
index 7d03c67..0000000
--- a/guava/src/com/google/common/util/concurrent/FutureFallback.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.annotations.Beta;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-/**
- * Provides a backup {@code Future} to replace an earlier failed {@code Future}.
- * An implementation of this interface can be applied to an input {@code Future}
- * with {@link Futures#withFallback}.
- *
- * @param <V> the result type of the provided backup {@code Future}
- *
- * @author Bruno Diniz
- * @since 14.0
- */
-@Beta
-public interface FutureFallback<V> {
- /**
- * Returns a {@code Future} to be used in place of the {@code Future} that
- * failed with the given exception. The exception is provided so that the
- * {@code Fallback} implementation can conditionally determine whether to
- * propagate the exception or to attempt to recover.
- *
- * @param t the exception that made the future fail. If the future's {@link
- * Future#get() get} method throws an {@link ExecutionException}, then the
- * cause is passed to this method. Any other thrown object is passed
- * unaltered.
- */
- ListenableFuture<V> create(Throwable t) throws Exception;
-}
diff --git a/guava/src/com/google/common/util/concurrent/Futures.java b/guava/src/com/google/common/util/concurrent/Futures.java
index aad6b43..dc703c5 100644
--- a/guava/src/com/google/common/util/concurrent/Futures.java
+++ b/guava/src/com/google/common/util/concurrent/Futures.java
@@ -21,14 +21,15 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;
+import static com.google.common.util.concurrent.Uninterruptibles.putUninterruptibly;
+import static com.google.common.util.concurrent.Uninterruptibles.takeUninterruptibly;
import static java.lang.Thread.currentThread;
import static java.util.Arrays.asList;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
@@ -38,27 +39,22 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* Static utility methods pertaining to the {@link Future} interface.
*
- * <p>Many of these methods use the {@link ListenableFuture} API; consult the
- * Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained">
- * {@code ListenableFuture}</a>.
- *
* @author Kevin Bourrillion
* @author Nishant Thakkar
* @author Sven Mawson
@@ -75,7 +71,7 @@ public final class Futures {
*
* <p>The given mapping function will be applied to an
* {@link InterruptedException}, a {@link CancellationException}, or an
- * {@link ExecutionException}.
+ * {@link ExecutionException} with the actual cause of the exception.
* See {@link Future#get()} for details on the exceptions thrown.
*
* @since 9.0 (source-compatible since 1.0)
@@ -85,151 +81,6 @@ public final class Futures {
return new MappingCheckedFuture<V, X>(checkNotNull(future), mapper);
}
- private abstract static class ImmediateFuture<V>
- implements ListenableFuture<V> {
-
- private static final Logger log =
- Logger.getLogger(ImmediateFuture.class.getName());
-
- @Override
- public void addListener(Runnable listener, Executor executor) {
- checkNotNull(listener, "Runnable was null.");
- checkNotNull(executor, "Executor was null.");
- try {
- executor.execute(listener);
- } catch (RuntimeException e) {
- // ListenableFuture's contract is that it will not throw unchecked
- // exceptions, so log the bad runnable and/or executor and swallow it.
- log.log(Level.SEVERE, "RuntimeException while executing runnable "
- + listener + " with executor " + executor, e);
- }
- }
-
- @Override
- public boolean cancel(boolean mayInterruptIfRunning) {
- return false;
- }
-
- @Override
- public abstract V get() throws ExecutionException;
-
- @Override
- public V get(long timeout, TimeUnit unit) throws ExecutionException {
- checkNotNull(unit);
- return get();
- }
-
- @Override
- public boolean isCancelled() {
- return false;
- }
-
- @Override
- public boolean isDone() {
- return true;
- }
- }
-
- private static class ImmediateSuccessfulFuture<V> extends ImmediateFuture<V> {
-
- @Nullable private final V value;
-
- ImmediateSuccessfulFuture(@Nullable V value) {
- this.value = value;
- }
-
- @Override
- public V get() {
- return value;
- }
- }
-
- private static class ImmediateSuccessfulCheckedFuture<V, X extends Exception>
- extends ImmediateFuture<V> implements CheckedFuture<V, X> {
-
- @Nullable private final V value;
-
- ImmediateSuccessfulCheckedFuture(@Nullable V value) {
- this.value = value;
- }
-
- @Override
- public V get() {
- return value;
- }
-
- @Override
- public V checkedGet() {
- return value;
- }
-
- @Override
- public V checkedGet(long timeout, TimeUnit unit) {
- checkNotNull(unit);
- return value;
- }
- }
-
- private static class ImmediateFailedFuture<V> extends ImmediateFuture<V> {
-
- private final Throwable thrown;
-
- ImmediateFailedFuture(Throwable thrown) {
- this.thrown = thrown;
- }
-
- @Override
- public V get() throws ExecutionException {
- throw new ExecutionException(thrown);
- }
- }
-
- private static class ImmediateCancelledFuture<V> extends ImmediateFuture<V> {
-
- private final CancellationException thrown;
-
- ImmediateCancelledFuture() {
- this.thrown = new CancellationException("Immediate cancelled future.");
- }
-
- @Override
- public boolean isCancelled() {
- return true;
- }
-
- @Override
- public V get() {
- throw AbstractFuture.cancellationExceptionWithCause(
- "Task was cancelled.", thrown);
- }
- }
-
- private static class ImmediateFailedCheckedFuture<V, X extends Exception>
- extends ImmediateFuture<V> implements CheckedFuture<V, X> {
-
- private final X thrown;
-
- ImmediateFailedCheckedFuture(X thrown) {
- this.thrown = thrown;
- }
-
- @Override
- public V get() throws ExecutionException {
- throw new ExecutionException(thrown);
- }
-
- @Override
- public V checkedGet() throws X {
- throw thrown;
- }
-
- @Override
- public V checkedGet(long timeout, TimeUnit unit) throws X {
- checkNotNull(unit);
- throw thrown;
- }
- }
-
/**
* Creates a {@code ListenableFuture} which has its value set immediately upon
* construction. The getters just return the value. This {@code Future} can't
@@ -237,7 +88,9 @@ public final class Futures {
* {@code true}.
*/
public static <V> ListenableFuture<V> immediateFuture(@Nullable V value) {
- return new ImmediateSuccessfulFuture<V>(value);
+ SettableFuture<V> future = SettableFuture.create();
+ future.set(value);
+ return future;
}
/**
@@ -250,7 +103,14 @@ public final class Futures {
*/
public static <V, X extends Exception> CheckedFuture<V, X>
immediateCheckedFuture(@Nullable V value) {
- return new ImmediateSuccessfulCheckedFuture<V, X>(value);
+ SettableFuture<V> future = SettableFuture.create();
+ future.set(value);
+ return Futures.makeChecked(future, new Function<Exception, X>() {
+ @Override
+ public X apply(Exception e) {
+ throw new AssertionError("impossible");
+ }
+ });
}
/**
@@ -261,21 +121,15 @@ public final class Futures {
* method always returns {@code true}. Calling {@code get()} will immediately
* throw the provided {@code Throwable} wrapped in an {@code
* ExecutionException}.
+ *
+ * @throws Error if the throwable is an {@link Error}.
*/
public static <V> ListenableFuture<V> immediateFailedFuture(
Throwable throwable) {
checkNotNull(throwable);
- return new ImmediateFailedFuture<V>(throwable);
- }
-
- /**
- * Creates a {@code ListenableFuture} which is cancelled immediately upon
- * construction, so that {@code isCancelled()} always returns {@code true}.
- *
- * @since 14.0
- */
- public static <V> ListenableFuture<V> immediateCancelledFuture() {
- return new ImmediateCancelledFuture<V>();
+ SettableFuture<V> future = SettableFuture.create();
+ future.setException(throwable);
+ return future;
}
/**
@@ -284,224 +138,149 @@ public final class Futures {
*
* <p>The returned {@code Future} can't be cancelled, and its {@code isDone()}
* method always returns {@code true}. Calling {@code get()} will immediately
- * throw the provided {@code Exception} wrapped in an {@code
+ * throw the provided {@code Throwable} wrapped in an {@code
* ExecutionException}, and calling {@code checkedGet()} will throw the
* provided exception itself.
+ *
+ * @throws Error if the throwable is an {@link Error}.
*/
public static <V, X extends Exception> CheckedFuture<V, X>
- immediateFailedCheckedFuture(X exception) {
+ immediateFailedCheckedFuture(final X exception) {
checkNotNull(exception);
- return new ImmediateFailedCheckedFuture<V, X>(exception);
+ return makeChecked(Futures.<V>immediateFailedFuture(exception),
+ new Function<Exception, X>() {
+ @Override
+ public X apply(Exception e) {
+ return exception;
+ }
+ });
}
/**
- * Returns a {@code Future} whose result is taken from the given primary
- * {@code input} or, if the primary input fails, from the {@code Future}
- * provided by the {@code fallback}. {@link FutureFallback#create} is not
- * invoked until the primary input has failed, so if the primary input
- * succeeds, it is never invoked. If, during the invocation of {@code
- * fallback}, an exception is thrown, this exception is used as the result of
- * the output {@code Future}.
- *
- * <p>Below is an example of a fallback that returns a default value if an
- * exception occurs:
- *
- * <pre> {@code
- * ListenableFuture<Integer> fetchCounterFuture = ...;
- *
- * // Falling back to a zero counter in case an exception happens when
- * // processing the RPC to fetch counters.
- * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback(
- * fetchCounterFuture, new FutureFallback<Integer>() {
- * public ListenableFuture<Integer> create(Throwable t) {
- * // Returning "0" as the default for the counter when the
- * // exception happens.
- * return immediateFuture(0);
- * }
- * });
- * }</pre>
- *
- * The fallback can also choose to propagate the original exception when
- * desired:
+ * <p>Returns a new {@code ListenableFuture} whose result is asynchronously
+ * derived from the result of the given {@code Future}. More precisely, the
+ * returned {@code Future} takes its result from a {@code Future} produced by
+ * applying the given {@code Function} to the result of the original {@code
+ * Future}. Example:
*
* <pre> {@code
- * ListenableFuture<Integer> fetchCounterFuture = ...;
- *
- * // Falling back to a zero counter only in case the exception was a
- * // TimeoutException.
- * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback(
- * fetchCounterFuture, new FutureFallback<Integer>() {
- * public ListenableFuture<Integer> create(Throwable t) {
- * if (t instanceof TimeoutException) {
- * return immediateFuture(0);
- * }
- * return immediateFailedFuture(t);
+ * ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
+ * Function<RowKey, ListenableFuture<QueryResult>> queryFunction =
+ * new Function<RowKey, ListenableFuture<QueryResult>>() {
+ * public ListenableFuture<QueryResult> apply(RowKey rowKey) {
+ * return dataService.read(rowKey);
* }
- * });
+ * };
+ * ListenableFuture<QueryResult> queryFuture =
+ * chain(rowKeyFuture, queryFunction);
* }</pre>
*
- * Note: If the derived {@code Future} is slow or heavyweight to create
- * (whether the {@code Future} itself is slow or heavyweight to complete is
- * irrelevant), consider {@linkplain #withFallback(ListenableFuture,
- * FutureFallback, Executor) supplying an executor}. If you do not supply an
- * executor, {@code withFallback} will use {@link
- * MoreExecutors#sameThreadExecutor sameThreadExecutor}, which carries some
- * caveats for heavier operations. For example, the call to {@code
- * fallback.create} may run on an unpredictable or undesirable thread:
- *
- * <ul>
- * <li>If the input {@code Future} is done at the time {@code withFallback}
- * is called, {@code withFallback} will call {@code fallback.create} inline.
- * <li>If the input {@code Future} is not yet done, {@code withFallback} will
- * schedule {@code fallback.create} to be run by the thread that completes
- * the input {@code Future}, which may be an internal system thread such as
- * an RPC network thread.
- * </ul>
+ * <p>Note: This overload of {@code chain} is designed for cases in which the
+ * work of creating the derived future is fast and lightweight, as the method
+ * does not accept an {@code Executor} in which to perform the the work. For
+ * heavier derivations, this overload carries some caveats: First, the thread
+ * that the derivation runs in depends on whether the input {@code Future} is
+ * done at the time {@code chain} is called. In particular, if called late,
+ * {@code chain} will run the derivation in the thread that called {@code
+ * chain}. Second, derivations may run in an internal thread of the system
+ * responsible for the input {@code Future}, such as an RPC network thread.
+ * Finally, during the execution of a {@code sameThreadExecutor} {@code
+ * chain} function, all other registered but unexecuted listeners are
+ * prevented from running, even if those listeners are to run in other
+ * executors.
*
- * Also note that, regardless of which thread executes {@code
- * fallback.create}, all other registered but unexecuted listeners are
- * prevented from running during its execution, even if those listeners are
- * to run in other executors.
+ * <p>The returned {@code Future} attempts to keep its cancellation state in
+ * sync with that of the input future and that of the future returned by the
+ * chain function. That is, if the returned {@code Future} is cancelled, it
+ * will attempt to cancel the other two, and if either of the other two is
+ * cancelled, the returned {@code Future} will receive a callback in which it
+ * will attempt to cancel itself.
*
- * @param input the primary input {@code Future}
- * @param fallback the {@link FutureFallback} implementation to be called if
- * {@code input} fails
- * @since 14.0
+ * @param input The future to chain
+ * @param function A function to chain the results of the provided future
+ * to the results of the returned future. This will be run in the thread
+ * that notifies input it is complete.
+ * @return A future that holds result of the chain.
+ * @deprecated Convert your {@code Function} to a {@code AsyncFunction}, and
+ * use {@link #transform(ListenableFuture, AsyncFunction)}. This method is
+ * scheduled to be removed from Guava in Guava release 12.0.
*/
- public static <V> ListenableFuture<V> withFallback(
- ListenableFuture<? extends V> input,
- FutureFallback<? extends V> fallback) {
- return withFallback(input, fallback, sameThreadExecutor());
+ @Deprecated
+ public static <I, O> ListenableFuture<O> chain(
+ ListenableFuture<I> input,
+ Function<? super I, ? extends ListenableFuture<? extends O>> function) {
+ return chain(input, function, MoreExecutors.sameThreadExecutor());
}
/**
- * Returns a {@code Future} whose result is taken from the given primary
- * {@code input} or, if the primary input fails, from the {@code Future}
- * provided by the {@code fallback}. {@link FutureFallback#create} is not
- * invoked until the primary input has failed, so if the primary input
- * succeeds, it is never invoked. If, during the invocation of {@code
- * fallback}, an exception is thrown, this exception is used as the result of
- * the output {@code Future}.
- *
- * <p>Below is an example of a fallback that returns a default value if an
- * exception occurs:
+ * <p>Returns a new {@code ListenableFuture} whose result is asynchronously
+ * derived from the result of the given {@code Future}. More precisely, the
+ * returned {@code Future} takes its result from a {@code Future} produced by
+ * applying the given {@code Function} to the result of the original {@code
+ * Future}. Example:
*
* <pre> {@code
- * ListenableFuture<Integer> fetchCounterFuture = ...;
- *
- * // Falling back to a zero counter in case an exception happens when
- * // processing the RPC to fetch counters.
- * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback(
- * fetchCounterFuture, new FutureFallback<Integer>() {
- * public ListenableFuture<Integer> create(Throwable t) {
- * // Returning "0" as the default for the counter when the
- * // exception happens.
- * return immediateFuture(0);
+ * ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
+ * Function<RowKey, ListenableFuture<QueryResult>> queryFunction =
+ * new Function<RowKey, ListenableFuture<QueryResult>>() {
+ * public ListenableFuture<QueryResult> apply(RowKey rowKey) {
+ * return dataService.read(rowKey);
* }
- * }, sameThreadExecutor());
+ * };
+ * ListenableFuture<QueryResult> queryFuture =
+ * chain(rowKeyFuture, queryFunction, executor);
* }</pre>
*
- * The fallback can also choose to propagate the original exception when
- * desired:
- *
- * <pre> {@code
- * ListenableFuture<Integer> fetchCounterFuture = ...;
- *
- * // Falling back to a zero counter only in case the exception was a
- * // TimeoutException.
- * ListenableFuture<Integer> faultTolerantFuture = Futures.withFallback(
- * fetchCounterFuture, new FutureFallback<Integer>() {
- * public ListenableFuture<Integer> create(Throwable t) {
- * if (t instanceof TimeoutException) {
- * return immediateFuture(0);
- * }
- * return immediateFailedFuture(t);
- * }
- * }, sameThreadExecutor());
- * }</pre>
+ * <p>The returned {@code Future} attempts to keep its cancellation state in
+ * sync with that of the input future and that of the future returned by the
+ * chain function. That is, if the returned {@code Future} is cancelled, it
+ * will attempt to cancel the other two, and if either of the other two is
+ * cancelled, the returned {@code Future} will receive a callback in which it
+ * will attempt to cancel itself.
*
- * When the execution of {@code fallback.create} is fast and lightweight
- * (though the {@code Future} it returns need not meet these criteria),
- * consider {@linkplain #withFallback(ListenableFuture, FutureFallback)
- * omitting the executor} or explicitly specifying {@code
- * sameThreadExecutor}. However, be aware of the caveats documented in the
- * link above.
- *
- * @param input the primary input {@code Future}
- * @param fallback the {@link FutureFallback} implementation to be called if
- * {@code input} fails
- * @param executor the executor that runs {@code fallback} if {@code input}
- * fails
- * @since 14.0
- */
- public static <V> ListenableFuture<V> withFallback(
- ListenableFuture<? extends V> input,
- FutureFallback<? extends V> fallback, Executor executor) {
- checkNotNull(fallback);
- return new FallbackFuture<V>(input, fallback, executor);
- }
-
- /**
- * A future that falls back on a second, generated future, in case its
- * original future fails.
+ * <p>Note: For cases in which the work of creating the derived future is
+ * fast and lightweight, consider {@linkplain Futures#chain(ListenableFuture,
+ * Function) the other overload} or explicit use of {@code
+ * sameThreadExecutor}. For heavier derivations, this choice carries some
+ * caveats: First, the thread that the derivation runs in depends on whether
+ * the input {@code Future} is done at the time {@code chain} is called. In
+ * particular, if called late, {@code chain} will run the derivation in the
+ * thread that called {@code chain}. Second, derivations may run in an
+ * internal thread of the system responsible for the input {@code Future},
+ * such as an RPC network thread. Finally, during the execution of a {@code
+ * sameThreadExecutor} {@code chain} function, all other registered but
+ * unexecuted listeners are prevented from running, even if those listeners
+ * are to run in other executors.
+ *
+ * @param input The future to chain
+ * @param function A function to chain the results of the provided future
+ * to the results of the returned future.
+ * @param executor Executor to run the function in.
+ * @return A future that holds result of the chain.
+ * @deprecated Convert your {@code Function} to a {@code AsyncFunction}, and
+ * use {@link #transform(ListenableFuture, AsyncFunction, Executor)}. This
+ * method is scheduled to be removed from Guava in Guava release 12.0.
*/
- private static class FallbackFuture<V> extends AbstractFuture<V> {
-
- private volatile ListenableFuture<? extends V> running;
-
- FallbackFuture(ListenableFuture<? extends V> input,
- final FutureFallback<? extends V> fallback,
- final Executor executor) {
- running = input;
- addCallback(running, new FutureCallback<V>() {
- @Override
- public void onSuccess(V value) {
- set(value);
- }
-
- @Override
- public void onFailure(Throwable t) {
- if (isCancelled()) {
- return;
- }
- try {
- running = fallback.create(t);
- if (isCancelled()) { // in case cancel called in the meantime
- running.cancel(wasInterrupted());
- return;
- }
- addCallback(running, new FutureCallback<V>() {
- @Override
- public void onSuccess(V value) {
- set(value);
- }
-
- @Override
- public void onFailure(Throwable t) {
- if (running.isCancelled()) {
- cancel(false);
- } else {
- setException(t);
- }
- }
- }, sameThreadExecutor());
- } catch (Exception e) {
- setException(e);
- } catch (Error e) {
- setException(e); // note: rethrows
+ @Deprecated
+ public static <I, O> ListenableFuture<O> chain(ListenableFuture<I> input,
+ final Function<? super I, ? extends ListenableFuture<? extends O>>
+ function,
+ Executor executor) {
+ checkNotNull(function);
+ ChainingListenableFuture<I, O> chain =
+ new ChainingListenableFuture<I, O>(new AsyncFunction<I, O>() {
+ @Override
+ /*
+ * All methods of ListenableFuture are covariant, and we don't expose
+ * the object anywhere that would allow it to be downcast.
+ */
+ @SuppressWarnings("unchecked")
+ public ListenableFuture<O> apply(I input) {
+ return (ListenableFuture) function.apply(input);
}
- }
- }, executor);
- }
-
- @Override
- public boolean cancel(boolean mayInterruptIfRunning) {
- if (super.cancel(mayInterruptIfRunning)) {
- running.cancel(mayInterruptIfRunning);
- return true;
- }
- return false;
- }
+ }, input);
+ input.addListener(chain, executor);
+ return chain;
}
/**
@@ -523,28 +302,20 @@ public final class Futures {
* transform(rowKeyFuture, queryFunction);
* }</pre>
*
- * Note: If the derived {@code Future} is slow or heavyweight to create
- * (whether the {@code Future} itself is slow or heavyweight to complete is
- * irrelevant), consider {@linkplain #transform(ListenableFuture,
- * AsyncFunction, Executor) supplying an executor}. If you do not supply an
- * executor, {@code transform} will use {@link
- * MoreExecutors#sameThreadExecutor sameThreadExecutor}, which carries some
- * caveats for heavier operations. For example, the call to {@code
- * function.apply} may run on an unpredictable or undesirable thread:
- *
- * <ul>
- * <li>If the input {@code Future} is done at the time {@code transform} is
- * called, {@code transform} will call {@code function.apply} inline.
- * <li>If the input {@code Future} is not yet done, {@code transform} will
- * schedule {@code function.apply} to be run by the thread that completes the
- * input {@code Future}, which may be an internal system thread such as an
- * RPC network thread.
- * </ul>
- *
- * Also note that, regardless of which thread executes {@code
- * function.apply}, all other registered but unexecuted listeners are
- * prevented from running during its execution, even if those listeners are
- * to run in other executors.
+ * <p>Note: This overload of {@code transform} is designed for cases in which
+ * the work of creating the derived {@code Future} is fast and lightweight,
+ * as the method does not accept an {@code Executor} in which to perform the
+ * the work. (The created {@code Future} itself need not complete quickly.)
+ * For heavier operations, this overload carries some caveats: First, the
+ * thread that {@code function.apply} runs in depends on whether the input
+ * {@code Future} is done at the time {@code transform} is called. In
+ * particular, if called late, {@code transform} will run the operation in
+ * the thread that called {@code transform}. Second, {@code function.apply}
+ * may run in an internal thread of the system responsible for the input
+ * {@code Future}, such as an RPC network thread. Finally, during the
+ * execution of a {@code sameThreadExecutor} {@code function.apply}, all
+ * other registered but unexecuted listeners are prevented from running, even
+ * if those listeners are to run in other executors.
*
* <p>The returned {@code Future} attempts to keep its cancellation state in
* sync with that of the input future and that of the future returned by the
@@ -591,11 +362,20 @@ public final class Futures {
* cancelled, the returned {@code Future} will receive a callback in which it
* will attempt to cancel itself.
*
- * <p>When the execution of {@code function.apply} is fast and lightweight
- * (though the {@code Future} it returns need not meet these criteria),
- * consider {@linkplain #transform(ListenableFuture, AsyncFunction) omitting
- * the executor} or explicitly specifying {@code sameThreadExecutor}.
- * However, be aware of the caveats documented in the link above.
+ * <p>Note: For cases in which the work of creating the derived future is
+ * fast and lightweight, consider {@linkplain
+ * Futures#transform(ListenableFuture, Function) the other overload} or
+ * explicit use of {@code sameThreadExecutor}. For heavier derivations, this
+ * choice carries some caveats: First, the thread that {@code function.apply}
+ * runs in depends on whether the input {@code Future} is done at the time
+ * {@code transform} is called. In particular, if called late, {@code
+ * transform} will run the operation in the thread that called {@code
+ * transform}. Second, {@code function.apply} may run in an internal thread
+ * of the system responsible for the input {@code Future}, such as an RPC
+ * network thread. Finally, during the execution of a {@code
+ * sameThreadExecutor} {@code function.apply}, all other registered but
+ * unexecuted listeners are prevented from running, even if those listeners
+ * are to run in other executors.
*
* @param input The future to transform
* @param function A function to transform the result of the input future
@@ -631,26 +411,19 @@ public final class Futures {
* transform(queryFuture, rowsFunction);
* }</pre>
*
- * Note: If the transformation is slow or heavyweight, consider {@linkplain
- * #transform(ListenableFuture, Function, Executor) supplying an executor}.
- * If you do not supply an executor, {@code transform} will use {@link
- * MoreExecutors#sameThreadExecutor sameThreadExecutor}, which carries some
- * caveats for heavier operations. For example, the call to {@code
- * function.apply} may run on an unpredictable or undesirable thread:
- *
- * <ul>
- * <li>If the input {@code Future} is done at the time {@code transform} is
- * called, {@code transform} will call {@code function.apply} inline.
- * <li>If the input {@code Future} is not yet done, {@code transform} will
- * schedule {@code function.apply} to be run by the thread that completes the
- * input {@code Future}, which may be an internal system thread such as an
- * RPC network thread.
- * </ul>
- *
- * Also note that, regardless of which thread executes {@code
- * function.apply}, all other registered but unexecuted listeners are
- * prevented from running during its execution, even if those listeners are
- * to run in other executors.
+ * <p>Note: This overload of {@code transform} is designed for cases in which
+ * the transformation is fast and lightweight, as the method does not accept
+ * an {@code Executor} in which to perform the the work. For heavier
+ * transformations, this overload carries some caveats: First, the thread
+ * that the transformation runs in depends on whether the input {@code
+ * Future} is done at the time {@code transform} is called. In particular, if
+ * called late, {@code transform} will perform the transformation in the
+ * thread that called {@code transform}. Second, transformations may run in
+ * an internal thread of the system responsible for the input {@code Future},
+ * such as an RPC network thread. Finally, during the execution of a {@code
+ * sameThreadExecutor} transformation, all other registered but unexecuted
+ * listeners are prevented from running, even if those listeners are to run
+ * in other executors.
*
* <p>The returned {@code Future} attempts to keep its cancellation state in
* sync with that of the input future. That is, if the returned {@code Future}
@@ -661,16 +434,16 @@ public final class Futures {
* <p>An example use of this method is to convert a serializable object
* returned from an RPC into a POJO.
*
- * @param input The future to transform
+ * @param future The future to transform
* @param function A Function to transform the results of the provided future
* to the results of the returned future. This will be run in the thread
* that notifies input it is complete.
* @return A future that holds result of the transformation.
* @since 9.0 (in 1.0 as {@code compose})
*/
- public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> input,
+ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> future,
final Function<? super I, ? extends O> function) {
- return transform(input, function, MoreExecutors.sameThreadExecutor());
+ return transform(future, function, MoreExecutors.sameThreadExecutor());
}
/**
@@ -699,29 +472,39 @@ public final class Futures {
* <p>An example use of this method is to convert a serializable object
* returned from an RPC into a POJO.
*
- * <p>When the transformation is fast and lightweight, consider {@linkplain
- * #transform(ListenableFuture, Function) omitting the executor} or
- * explicitly specifying {@code sameThreadExecutor}. However, be aware of the
- * caveats documented in the link above.
- *
- * @param input The future to transform
+ * <p>Note: For cases in which the transformation is fast and lightweight,
+ * consider {@linkplain Futures#transform(ListenableFuture, Function) the
+ * other overload} or explicit use of {@link
+ * MoreExecutors#sameThreadExecutor}. For heavier transformations, this
+ * choice carries some caveats: First, the thread that the transformation
+ * runs in depends on whether the input {@code Future} is done at the time
+ * {@code transform} is called. In particular, if called late, {@code
+ * transform} will perform the transformation in the thread that called
+ * {@code transform}. Second, transformations may run in an internal thread
+ * of the system responsible for the input {@code Future}, such as an RPC
+ * network thread. Finally, during the execution of a {@code
+ * sameThreadExecutor} transformation, all other registered but unexecuted
+ * listeners are prevented from running, even if those listeners are to run
+ * in other executors.
+ *
+ * @param future The future to transform
* @param function A Function to transform the results of the provided future
* to the results of the returned future.
* @param executor Executor to run the function in.
* @return A future that holds result of the transformation.
* @since 9.0 (in 2.0 as {@code compose})
*/
- public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> input,
+ public static <I, O> ListenableFuture<O> transform(ListenableFuture<I> future,
final Function<? super I, ? extends O> function, Executor executor) {
checkNotNull(function);
- AsyncFunction<I, O> wrapperFunction
- = new AsyncFunction<I, O>() {
+ Function<I, ListenableFuture<O>> wrapperFunction
+ = new Function<I, ListenableFuture<O>>() {
@Override public ListenableFuture<O> apply(I input) {
O output = function.apply(input);
return immediateFuture(output);
}
};
- return transform(input, wrapperFunction, executor);
+ return chain(future, wrapperFunction, executor);
}
/**
@@ -741,43 +524,43 @@ public final class Futures {
* who don't have a {@code ListenableFuture} available and
* do not mind repeated, lazy function evaluation.
*
- * @param input The future to transform
+ * @param future The future to transform
* @param function A Function to transform the results of the provided future
* to the results of the returned future.
* @return A future that returns the result of the transformation.
* @since 10.0
*/
@Beta
- public static <I, O> Future<O> lazyTransform(final Future<I> input,
+ public static <I, O> Future<O> lazyTransform(final Future<I> future,
final Function<? super I, ? extends O> function) {
- checkNotNull(input);
+ checkNotNull(future);
checkNotNull(function);
return new Future<O>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
- return input.cancel(mayInterruptIfRunning);
+ return future.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
- return input.isCancelled();
+ return future.isCancelled();
}
@Override
public boolean isDone() {
- return input.isDone();
+ return future.isDone();
}
@Override
public O get() throws InterruptedException, ExecutionException {
- return applyTransformation(input.get());
+ return applyTransformation(future.get());
}
@Override
public O get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
- return applyTransformation(input.get(timeout, unit));
+ return applyTransformation(future.get(timeout, unit));
}
private O applyTransformation(I input) throws ExecutionException {
@@ -806,6 +589,8 @@ public final class Futures {
private AsyncFunction<? super I, ? extends O> function;
private ListenableFuture<? extends I> inputFuture;
private volatile ListenableFuture<? extends O> outputFuture;
+ private final BlockingQueue<Boolean> mayInterruptIfRunningChannel =
+ new LinkedBlockingQueue<Boolean>(1);
private final CountDownLatch outputCreated = new CountDownLatch(1);
private ChainingListenableFuture(
@@ -815,6 +600,90 @@ public final class Futures {
this.inputFuture = checkNotNull(inputFuture);
}
+ /**
+ * Delegate the get() to the input and output futures, in case
+ * their implementations defer starting computation until their
+ * own get() is invoked.
+ */
+ @Override
+ public O get() throws InterruptedException, ExecutionException {
+ if (!isDone()) {
+ // Invoking get on the inputFuture will ensure our own run()
+ // method below is invoked as a listener when inputFuture sets
+ // its value. Therefore when get() returns we should then see
+ // the outputFuture be created.
+ ListenableFuture<? extends I> inputFuture = this.inputFuture;
+ if (inputFuture != null) {
+ inputFuture.get();
+ }
+
+ // If our listener was scheduled to run on an executor we may
+ // need to wait for our listener to finish running before the
+ // outputFuture has been constructed by the function.
+ outputCreated.await();
+
+ // Like above with the inputFuture, we have a listener on
+ // the outputFuture that will set our own value when its
+ // value is set. Invoking get will ensure the output can
+ // complete and invoke our listener, so that we can later
+ // get the result.
+ ListenableFuture<? extends O> outputFuture = this.outputFuture;
+ if (outputFuture != null) {
+ outputFuture.get();
+ }
+ }
+ return super.get();
+ }
+
+ /**
+ * Delegate the get() to the input and output futures, in case
+ * their implementations defer starting computation until their
+ * own get() is invoked.
+ */
+ @Override
+ public O get(long timeout, TimeUnit unit) throws TimeoutException,
+ ExecutionException, InterruptedException {
+ if (!isDone()) {
+ // Use a single time unit so we can decrease remaining timeout
+ // as we wait for various phases to complete.
+ if (unit != NANOSECONDS) {
+ timeout = NANOSECONDS.convert(timeout, unit);
+ unit = NANOSECONDS;
+ }
+
+ // Invoking get on the inputFuture will ensure our own run()
+ // method below is invoked as a listener when inputFuture sets
+ // its value. Therefore when get() returns we should then see
+ // the outputFuture be created.
+ ListenableFuture<? extends I> inputFuture = this.inputFuture;
+ if (inputFuture != null) {
+ long start = System.nanoTime();
+ inputFuture.get(timeout, unit);
+ timeout -= Math.max(0, System.nanoTime() - start);
+ }
+
+ // If our listener was scheduled to run on an executor we may
+ // need to wait for our listener to finish running before the
+ // outputFuture has been constructed by the function.
+ long start = System.nanoTime();
+ if (!outputCreated.await(timeout, unit)) {
+ throw new TimeoutException();
+ }
+ timeout -= Math.max(0, System.nanoTime() - start);
+
+ // Like above with the inputFuture, we have a listener on
+ // the outputFuture that will set our own value when its
+ // value is set. Invoking get will ensure the output can
+ // complete and invoke our listener, so that we can later
+ // get the result.
+ ListenableFuture<? extends O> outputFuture = this.outputFuture;
+ if (outputFuture != null) {
+ outputFuture.get(timeout, unit);
+ }
+ }
+ return super.get(timeout, unit);
+ }
+
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
/*
@@ -824,6 +693,7 @@ public final class Futures {
if (super.cancel(mayInterruptIfRunning)) {
// This should never block since only one thread is allowed to cancel
// this Future.
+ putUninterruptibly(mayInterruptIfRunningChannel, mayInterruptIfRunning);
cancel(inputFuture, mayInterruptIfRunning);
cancel(outputFuture, mayInterruptIfRunning);
return true;
@@ -859,7 +729,13 @@ public final class Futures {
final ListenableFuture<? extends O> outputFuture = this.outputFuture =
function.apply(sourceResult);
if (isCancelled()) {
- outputFuture.cancel(wasInterrupted());
+ // Handles the case where cancel was called while the function was
+ // being applied.
+ // There is a gap in cancel(boolean) between calling sync.cancel()
+ // and storing the value of mayInterruptIfRunning, so this thread
+ // needs to block, waiting for that value.
+ outputFuture.cancel(
+ takeUninterruptibly(mayInterruptIfRunningChannel));
this.outputFuture = null;
return;
}
@@ -907,52 +783,14 @@ public final class Futures {
}
/**
- * Returns a new {@code ListenableFuture} whose result is the product of
- * calling {@code get()} on the {@code Future} nested within the given {@code
- * Future}, effectively chaining the futures one after the other. Example:
- *
- * <pre> {@code
- * SettableFuture<ListenableFuture<String>> nested = SettableFuture.create();
- * ListenableFuture<String> dereferenced = dereference(nested);
- * }</pre>
- *
- * <p>This call has the same cancellation and execution semantics as {@link
- * #transform(ListenableFuture, AsyncFunction)}, in that the returned {@code
- * Future} attempts to keep its cancellation state in sync with both the
- * input {@code Future} and the nested {@code Future}. The transformation
- * is very lightweight and therefore takes place in the thread that called
- * {@code dereference}.
- *
- * @param nested The nested future to transform.
- * @return A future that holds result of the inner future.
- * @since 13.0
- */
- @Beta
- @SuppressWarnings({"rawtypes", "unchecked"})
- public static <V> ListenableFuture<V> dereference(
- ListenableFuture<? extends ListenableFuture<? extends V>> nested) {
- return Futures.transform((ListenableFuture) nested, (AsyncFunction) DEREFERENCER);
- }
-
- /**
- * Helper {@code Function} for {@link #dereference}.
- */
- private static final AsyncFunction<ListenableFuture<Object>, Object> DEREFERENCER =
- new AsyncFunction<ListenableFuture<Object>, Object>() {
- @Override public ListenableFuture<Object> apply(ListenableFuture<Object> input) {
- return input;
- }
- };
-
- /**
* Creates a new {@code ListenableFuture} whose value is a list containing the
* values of all its input futures, if all succeed. If any input fails, the
* returned future fails.
*
* <p>The list of results is in the same order as the input list.
*
- * <p>Canceling this future will attempt to cancel all the component futures,
- * and if any of the provided futures fails or is canceled, this one is,
+ * <p>Canceling this future does not cancel any of the component futures;
+ * however, if any of the provided futures fails or is canceled, this one is,
* too.
*
* @param futures futures to combine
@@ -963,7 +801,7 @@ public final class Futures {
@Beta
public static <V> ListenableFuture<List<V>> allAsList(
ListenableFuture<? extends V>... futures) {
- return listFuture(ImmutableList.copyOf(futures), true,
+ return new ListFuture<V>(ImmutableList.copyOf(futures), true,
MoreExecutors.sameThreadExecutor());
}
@@ -974,8 +812,8 @@ public final class Futures {
*
* <p>The list of results is in the same order as the input list.
*
- * <p>Canceling this future will attempt to cancel all the component futures,
- * and if any of the provided futures fails or is canceled, this one is,
+ * <p>Canceling this future does not cancel any of the component futures;
+ * however, if any of the provided futures fails or is canceled, this one is,
* too.
*
* @param futures futures to combine
@@ -986,7 +824,7 @@ public final class Futures {
@Beta
public static <V> ListenableFuture<List<V>> allAsList(
Iterable<? extends ListenableFuture<? extends V>> futures) {
- return listFuture(ImmutableList.copyOf(futures), true,
+ return new ListFuture<V>(ImmutableList.copyOf(futures), true,
MoreExecutors.sameThreadExecutor());
}
@@ -998,8 +836,6 @@ public final class Futures {
* indistinguishable from the future having a successful value of
* {@code null}).
*
- * <p>Canceling this future will attempt to cancel all the component futures.
- *
* @param futures futures to combine
* @return a future that provides a list of the results of the component
* futures
@@ -1008,7 +844,7 @@ public final class Futures {
@Beta
public static <V> ListenableFuture<List<V>> successfulAsList(
ListenableFuture<? extends V>... futures) {
- return listFuture(ImmutableList.copyOf(futures), false,
+ return new ListFuture<V>(ImmutableList.copyOf(futures), false,
MoreExecutors.sameThreadExecutor());
}
@@ -1020,8 +856,6 @@ public final class Futures {
* indistinguishable from the future having a successful value of
* {@code null}).
*
- * <p>Canceling this future will attempt to cancel all the component futures.
- *
* @param futures futures to combine
* @return a future that provides a list of the results of the component
* futures
@@ -1030,7 +864,7 @@ public final class Futures {
@Beta
public static <V> ListenableFuture<List<V>> successfulAsList(
Iterable<? extends ListenableFuture<? extends V>> futures) {
- return listFuture(ImmutableList.copyOf(futures), false,
+ return new ListFuture<V>(ImmutableList.copyOf(futures), false,
MoreExecutors.sameThreadExecutor());
}
@@ -1055,26 +889,19 @@ public final class Futures {
* }
* });}</pre>
*
- * Note: If the callback is slow or heavyweight, consider {@linkplain
- * #addCallback(ListenableFuture, FutureCallback, Executor) supplying an
- * executor}. If you do not supply an executor, {@code addCallback} will use
- * {@link MoreExecutors#sameThreadExecutor sameThreadExecutor}, which carries
- * some caveats for heavier operations. For example, the callback may run on
- * an unpredictable or undesirable thread:
- *
- * <ul>
- * <li>If the input {@code Future} is done at the time {@code addCallback} is
- * called, {@code addCallback} will execute the callback inline.
- * <li>If the input {@code Future} is not yet done, {@code addCallback} will
- * schedule the callback to be run by the thread that completes the input
- * {@code Future}, which may be an internal system thread such as an RPC
- * network thread.
- * </ul>
- *
- * Also note that, regardless of which thread executes the callback, all
- * other registered but unexecuted listeners are prevented from running
- * during its execution, even if those listeners are to run in other
- * executors.
+ * <p>Note: This overload of {@code addCallback} is designed for cases in
+ * which the callack is fast and lightweight, as the method does not accept
+ * an {@code Executor} in which to perform the the work. For heavier
+ * callbacks, this overload carries some caveats: First, the thread that the
+ * callback runs in depends on whether the input {@code Future} is done at the
+ * time {@code addCallback} is called and on whether the input {@code Future}
+ * is ever cancelled. In particular, {@code addCallback} may execute the
+ * callback in the thread that calls {@code addCallback} or {@code
+ * Future.cancel}. Second, callbacks may run in an internal thread of the
+ * system responsible for the input {@code Future}, such as an RPC network
+ * thread. Finally, during the execution of a {@code sameThreadExecutor}
+ * callback, all other registered but unexecuted listeners are prevented from
+ * running, even if those listeners are to run in other executors.
*
* <p>For a more general interface to attach a completion listener to a
* {@code Future}, see {@link ListenableFuture#addListener addListener}.
@@ -1111,10 +938,20 @@ public final class Futures {
* }
* });}</pre>
*
- * When the callback is fast and lightweight, consider {@linkplain
- * #addCallback(ListenableFuture, FutureCallback) omitting the executor} or
- * explicitly specifying {@code sameThreadExecutor}. However, be aware of the
- * caveats documented in the link above.
+ * When the callback is fast and lightweight consider {@linkplain
+ * Futures#addCallback(ListenableFuture, FutureCallback) the other overload}
+ * or explicit use of {@link MoreExecutors#sameThreadExecutor
+ * sameThreadExecutor}. For heavier callbacks, this choice carries some
+ * caveats: First, the thread that the callback runs in depends on whether
+ * the input {@code Future} is done at the time {@code addCallback} is called
+ * and on whether the input {@code Future} is ever cancelled. In particular,
+ * {@code addCallback} may execute the callback in the thread that calls
+ * {@code addCallback} or {@code Future.cancel}. Second, callbacks may run in
+ * an internal thread of the system responsible for the input {@code Future},
+ * such as an RPC network thread. Finally, during the execution of a {@code
+ * sameThreadExecutor} callback, all other registered but unexecuted
+ * listeners are prevented from running, even if those listeners are to run
+ * in other executors.
*
* <p>For a more general interface to attach a completion listener to a
* {@code Future}, see {@link ListenableFuture#addListener addListener}.
@@ -1131,22 +968,18 @@ public final class Futures {
Runnable callbackListener = new Runnable() {
@Override
public void run() {
- final V value;
try {
// TODO(user): (Before Guava release), validate that this
// is the thing for IE.
- value = getUninterruptibly(future);
+ V value = getUninterruptibly(future);
+ callback.onSuccess(value);
} catch (ExecutionException e) {
callback.onFailure(e.getCause());
- return;
} catch (RuntimeException e) {
callback.onFailure(e);
- return;
} catch (Error e) {
callback.onFailure(e);
- return;
}
- callback.onSuccess(value);
}
};
future.addListener(callbackListener, executor);
@@ -1434,53 +1267,49 @@ public final class Futures {
}
}
- private interface FutureCombiner<V, C> {
- C combine(List<Optional<V>> values);
- }
-
- private static class CombinedFuture<V, C> extends AbstractFuture<C> {
- ImmutableCollection<? extends ListenableFuture<? extends V>> futures;
+ /**
+ * Class that implements {@link #allAsList} and {@link #successfulAsList}.
+ * The idea is to create a (null-filled) List and register a listener with
+ * each component future to fill out the value in the List when that future
+ * completes.
+ */
+ private static class ListFuture<V> extends AbstractFuture<List<V>> {
+ ImmutableList<? extends ListenableFuture<? extends V>> futures;
final boolean allMustSucceed;
final AtomicInteger remaining;
- FutureCombiner<V, C> combiner;
- List<Optional<V>> values;
+ List<V> values;
- CombinedFuture(
- ImmutableCollection<? extends ListenableFuture<? extends V>> futures,
- boolean allMustSucceed, Executor listenerExecutor,
- FutureCombiner<V, C> combiner) {
+ /**
+ * Constructor.
+ *
+ * @param futures all the futures to build the list from
+ * @param allMustSucceed whether a single failure or cancellation should
+ * propagate to this future
+ * @param listenerExecutor used to run listeners on all the passed in
+ * futures.
+ */
+ ListFuture(
+ final ImmutableList<? extends ListenableFuture<? extends V>> futures,
+ final boolean allMustSucceed, final Executor listenerExecutor) {
this.futures = futures;
+ this.values = Lists.newArrayListWithCapacity(futures.size());
this.allMustSucceed = allMustSucceed;
this.remaining = new AtomicInteger(futures.size());
- this.combiner = combiner;
- this.values = Lists.newArrayListWithCapacity(futures.size());
+
init(listenerExecutor);
}
- /**
- * Must be called at the end of the constructor.
- */
- protected void init(final Executor listenerExecutor) {
+ private void init(final Executor listenerExecutor) {
// First, schedule cleanup to execute when the Future is done.
addListener(new Runnable() {
@Override
public void run() {
- // Cancel all the component futures.
- if (CombinedFuture.this.isCancelled()) {
- for (ListenableFuture<?> future : CombinedFuture.this.futures) {
- future.cancel(CombinedFuture.this.wasInterrupted());
- }
- }
-
// By now the values array has either been set as the Future's value,
// or (in case of failure) is no longer useful.
- CombinedFuture.this.futures = null;
+ ListFuture.this.values = null;
// Let go of the memory held by other futures
- CombinedFuture.this.values = null;
-
- // The combiner may also hold state, so free that as well
- CombinedFuture.this.combiner = null;
+ ListFuture.this.futures = null;
}
}, MoreExecutors.sameThreadExecutor());
@@ -1488,7 +1317,7 @@ public final class Futures {
// Corner case: List is empty.
if (futures.isEmpty()) {
- set(combiner.combine(ImmutableList.<Optional<V>>of()));
+ set(Lists.newArrayList(values));
return;
}
@@ -1503,11 +1332,11 @@ public final class Futures {
// this loop, the last call to addListener() will callback to
// setOneValue(), transitively call our cleanup listener, and set
// this.futures to null.
- // This is not actually a problem, since the foreach only needs
- // this.futures to be non-null at the beginning of the loop.
- int i = 0;
- for (final ListenableFuture<? extends V> listenable : futures) {
- final int index = i++;
+ // We store a reference to futures to avoid the NPE.
+ ImmutableList<? extends ListenableFuture<? extends V>> localFutures = futures;
+ for (int i = 0; i < localFutures.size(); i++) {
+ final ListenableFuture<? extends V> listenable = localFutures.get(i);
+ final int index = i;
listenable.addListener(new Runnable() {
@Override
public void run() {
@@ -1521,12 +1350,12 @@ public final class Futures {
* Sets the value at the given index to that of the given future.
*/
private void setOneValue(int index, Future<? extends V> future) {
- List<Optional<V>> localValues = values;
+ List<V> localValues = values;
if (isDone() || localValues == null) {
// Some other future failed or has been cancelled, causing this one to
// also be cancelled or have an exception set. This should only happen
- // if allMustSucceed is true or if the output itself has been cancelled.
- checkState(allMustSucceed || isCancelled(),
+ // if allMustSucceed is true.
+ checkState(allMustSucceed,
"Future was done before all dependencies completed");
return;
}
@@ -1534,8 +1363,7 @@ public final class Futures {
try {
checkState(future.isDone(),
"Tried to set value from future which is not done");
- V returnValue = getUninterruptibly(future);
- localValues.set(index, Optional.fromNullable(returnValue));
+ localValues.set(index, getUninterruptibly(future));
} catch (CancellationException e) {
if (allMustSucceed) {
// Set ourselves as cancelled. Let the input futures keep running
@@ -1561,9 +1389,9 @@ public final class Futures {
int newRemaining = remaining.decrementAndGet();
checkState(newRemaining >= 0, "Less than 0 remaining futures");
if (newRemaining == 0) {
- FutureCombiner<V, C> localCombiner = combiner;
- if (localCombiner != null) {
- set(localCombiner.combine(localValues));
+ localValues = values;
+ if (localValues != null) {
+ set(Lists.newArrayList(localValues));
} else {
checkState(isDone());
}
@@ -1571,25 +1399,46 @@ public final class Futures {
}
}
- }
+ @Override
+ public List<V> get() throws InterruptedException, ExecutionException {
+ callAllGets();
- /** Used for {@link #allAsList} and {@link #successfulAsList}. */
- private static <V> ListenableFuture<List<V>> listFuture(
- ImmutableList<ListenableFuture<? extends V>> futures,
- boolean allMustSucceed, Executor listenerExecutor) {
- return new CombinedFuture<V, List<V>>(
- futures, allMustSucceed, listenerExecutor,
- new FutureCombiner<V, List<V>>() {
- @Override
- public List<V> combine(List<Optional<V>> values) {
- List<V> result = Lists.newArrayList();
- for (Optional<V> element : values) {
- result.add(element != null ? element.orNull() : null);
+ // This may still block in spite of the calls above, as the listeners may
+ // be scheduled for execution in other threads.
+ return super.get();
+ }
+
+ /**
+ * Calls the get method of all dependency futures to work around a bug in
+ * some ListenableFutures where the listeners aren't called until get() is
+ * called.
+ */
+ private void callAllGets() throws InterruptedException {
+ List<? extends ListenableFuture<? extends V>> oldFutures = futures;
+ if (oldFutures != null && !isDone()) {
+ for (ListenableFuture<? extends V> future : oldFutures) {
+ // We wait for a little while for the future, but if it's not done,
+ // we check that no other futures caused a cancellation or failure.
+ // This can introduce a delay of up to 10ms in reporting an exception.
+ while (!future.isDone()) {
+ try {
+ future.get();
+ } catch (Error e) {
+ throw e;
+ } catch (InterruptedException e) {
+ throw e;
+ } catch (Throwable e) {
+ // ExecutionException / CancellationException / RuntimeException
+ if (allMustSucceed) {
+ return;
+ } else {
+ continue;
+ }
}
- // TODO(user): This should ultimately return an unmodifiableList
- return result;
}
- });
+ }
+ }
+ }
}
/**
diff --git a/guava/src/com/google/common/util/concurrent/JdkFutureAdapters.java b/guava/src/com/google/common/util/concurrent/JdkFutureAdapters.java
index 645a648..6d74bda 100644
--- a/guava/src/com/google/common/util/concurrent/JdkFutureAdapters.java
+++ b/guava/src/com/google/common/util/concurrent/JdkFutureAdapters.java
@@ -19,6 +19,7 @@ package com.google.common.util.concurrent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -41,7 +42,7 @@ public final class JdkFutureAdapters {
* Assigns a thread to the given {@link Future} to provide {@link
* ListenableFuture} functionality.
*
- * <p><b>Warning:</b> If the input future does not already implement {@code
+ * <p><b>Warning:</b> If the input future does not already implement {@link
* ListenableFuture}, the returned future will emulate {@link
* ListenableFuture#addListener} by taking a thread from an internal,
* unbounded pool at the first call to {@code addListener} and holding it
@@ -56,40 +57,17 @@ public final class JdkFutureAdapters {
*/
public static <V> ListenableFuture<V> listenInPoolThread(
Future<V> future) {
- if (future instanceof ListenableFuture) {
+ if (future instanceof ListenableFuture<?>) {
return (ListenableFuture<V>) future;
}
return new ListenableFutureAdapter<V>(future);
}
- /**
- * Submits a blocking task for the given {@link Future} to provide {@link
- * ListenableFuture} functionality.
- *
- * <p><b>Warning:</b> If the input future does not already implement {@code
- * ListenableFuture}, the returned future will emulate {@link
- * ListenableFuture#addListener} by submitting a task to the given executor at
- * at the first call to {@code addListener}. The task must be started by the
- * executor promptly, or else the returned {@code ListenableFuture} may fail
- * to work. The task's execution consists of blocking until the input future
- * is {@linkplain Future#isDone() done}, so each call to this method may
- * claim and hold a thread for an arbitrary length of time. Use of bounded
- * executors or other executors that may fail to execute a task promptly may
- * result in deadlocks.
- *
- * <p>Prefer to create {@code ListenableFuture} instances with {@link
- * SettableFuture}, {@link MoreExecutors#listeningDecorator(
- * java.util.concurrent.ExecutorService)}, {@link ListenableFutureTask},
- * {@link AbstractFuture}, and other utilities over creating plain {@code
- * Future} instances to be upgraded to {@code ListenableFuture} after the
- * fact.
- *
- * @since 12.0
- */
- public static <V> ListenableFuture<V> listenInPoolThread(
+ @VisibleForTesting
+ static <V> ListenableFuture<V> listenInPoolThread(
Future<V> future, Executor executor) {
checkNotNull(executor);
- if (future instanceof ListenableFuture) {
+ if (future instanceof ListenableFuture<?>) {
return (ListenableFuture<V>) future;
}
return new ListenableFutureAdapter<V>(future, executor);
diff --git a/guava/src/com/google/common/util/concurrent/ListenableFuture.java b/guava/src/com/google/common/util/concurrent/ListenableFuture.java
index eb05354..a0ab2db 100644
--- a/guava/src/com/google/common/util/concurrent/ListenableFuture.java
+++ b/guava/src/com/google/common/util/concurrent/ListenableFuture.java
@@ -28,10 +28,6 @@ import java.util.concurrent.RejectedExecutionException;
* computation is {@linkplain Future#isDone() complete}. If the computation has
* already completed when the listener is added, the listener will execute
* immediately.
- *
- * <p>See the Guava User Guide article on <a href=
- * "http://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained">
- * {@code ListenableFuture}</a>.
*
* <h3>Purpose</h3>
*
@@ -102,28 +98,20 @@ public interface ListenableFuture<V> extends Future<V> {
*
* <p>Note: For fast, lightweight listeners that would be safe to execute in
* any thread, consider {@link MoreExecutors#sameThreadExecutor}. For heavier
- * listeners, {@code sameThreadExecutor()} carries some caveats. For
- * example, the listener may run on an unpredictable or undesirable thread:
+ * listeners, {@code sameThreadExecutor()} carries some caveats: First, the
+ * thread that the listener runs in depends on whether the {@code Future} is
+ * done at the time it is added and on whether it is ever canclled. In
+ * particular, listeners may run in the thread that calls {@code addListener}
+ * or the thread that calls {@code cancel}. Second, listeners may run in an
+ * internal thread of the system responsible for the input {@code Future},
+ * such as an RPC network thread. Finally, during the execution of a {@code
+ * sameThreadExecutor()} listener, all other registered but unexecuted
+ * listeners are prevented from running, even if those listeners are to run
+ * in other executors.
*
- * <ul>
- * <li>If the input {@code Future} is done at the time {@code addListener} is
- * called, {@code addListener} will execute the listener inline.
- * <li>If the input {@code Future} is not yet done, {@code addListener} will
- * schedule the listener to be run by the thread that completes the input
- * {@code Future}, which may be an internal system thread such as an RPC
- * network thread.
- * </ul>
- *
- * Also note that, regardless of which thread executes the listener, all
- * other registered but unexecuted listeners are prevented from running
- * during its execution, even if those listeners are to run in other
- * executors.
- *
- * <p>This is the most general listener interface. For common operations
- * performed using listeners, see {@link
- * com.google.common.util.concurrent.Futures}. For a simplified but general
- * listener interface, see {@link
- * com.google.common.util.concurrent.Futures#addCallback addCallback()}.
+ * <p>This is the most general listener interface.
+ * For common operations performed using listeners,
+ * see {@link com.google.common.util.concurrent.Futures}
*
* @param listener the listener to run when the computation is complete
* @param executor the executor to run the listener in
diff --git a/guava/src/com/google/common/util/concurrent/ListenableFutureTask.java b/guava/src/com/google/common/util/concurrent/ListenableFutureTask.java
index 35d6f13..474635c 100644
--- a/guava/src/com/google/common/util/concurrent/ListenableFutureTask.java
+++ b/guava/src/com/google/common/util/concurrent/ListenableFutureTask.java
@@ -27,17 +27,12 @@ import javax.annotation.Nullable;
* interface. Unlike {@code FutureTask}, {@code ListenableFutureTask} does not
* provide an overrideable {@link FutureTask#done() done()} method. For similar
* functionality, call {@link #addListener}.
- *
- * <p>
*
* @author Sven Mawson
* @since 1.0
*/
-public class ListenableFutureTask<V> extends FutureTask<V>
+public final class ListenableFutureTask<V> extends FutureTask<V>
implements ListenableFuture<V> {
- // TODO(cpovirk): explore ways of making ListenableFutureTask final. There are
- // some valid reasons such as BoundedQueueExecutorService to allow extends but it
- // would be nice to make it final to avoid unintended usage.
// The execution list to hold our listeners.
private final ExecutionList executionList = new ExecutionList();
@@ -70,11 +65,11 @@ public class ListenableFutureTask<V> extends FutureTask<V>
return new ListenableFutureTask<V>(runnable, result);
}
- ListenableFutureTask(Callable<V> callable) {
+ private ListenableFutureTask(Callable<V> callable) {
super(callable);
}
- ListenableFutureTask(Runnable runnable, @Nullable V result) {
+ private ListenableFutureTask(Runnable runnable, @Nullable V result) {
super(runnable, result);
}
diff --git a/guava/src/com/google/common/util/concurrent/MoreExecutors.java b/guava/src/com/google/common/util/concurrent/MoreExecutors.java
index bd94db7..915b96d 100644
--- a/guava/src/com/google/common/util/concurrent/MoreExecutors.java
+++ b/guava/src/com/google/common/util/concurrent/MoreExecutors.java
@@ -16,26 +16,15 @@
package com.google.common.util.concurrent;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Queues;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
-import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@@ -44,7 +33,6 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -79,8 +67,16 @@ public final class MoreExecutors {
@Beta
public static ExecutorService getExitingExecutorService(
ThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit) {
- return new Application()
- .getExitingExecutorService(executor, terminationTimeout, timeUnit);
+ executor.setThreadFactory(new ThreadFactoryBuilder()
+ .setDaemon(true)
+ .setThreadFactory(executor.getThreadFactory())
+ .build());
+
+ ExecutorService service = Executors.unconfigurableExecutorService(executor);
+
+ addDelayedShutdownHook(service, terminationTimeout, timeUnit);
+
+ return service;
}
/**
@@ -101,9 +97,19 @@ public final class MoreExecutors {
*/
@Beta
public static ScheduledExecutorService getExitingScheduledExecutorService(
- ScheduledThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit) {
- return new Application()
- .getExitingScheduledExecutorService(executor, terminationTimeout, timeUnit);
+ ScheduledThreadPoolExecutor executor, long terminationTimeout,
+ TimeUnit timeUnit) {
+ executor.setThreadFactory(new ThreadFactoryBuilder()
+ .setDaemon(true)
+ .setThreadFactory(executor.getThreadFactory())
+ .build());
+
+ ScheduledExecutorService service =
+ Executors.unconfigurableScheduledExecutorService(executor);
+
+ addDelayedShutdownHook(service, terminationTimeout, timeUnit);
+
+ return service;
}
/**
@@ -119,9 +125,24 @@ public final class MoreExecutors {
*/
@Beta
public static void addDelayedShutdownHook(
- ExecutorService service, long terminationTimeout, TimeUnit timeUnit) {
- new Application()
- .addDelayedShutdownHook(service, terminationTimeout, timeUnit);
+ final ExecutorService service, final long terminationTimeout,
+ final TimeUnit timeUnit) {
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // We'd like to log progress and failures that may arise in the
+ // following code, but unfortunately the behavior of logging
+ // is undefined in shutdown hooks.
+ // This is because the logging code installs a shutdown hook of its
+ // own. See Cleaner class inside {@link LogManager}.
+ service.shutdown();
+ service.awaitTermination(terminationTimeout, timeUnit);
+ } catch (InterruptedException ignored) {
+ // We're shutting down anyway, so just ignore.
+ }
+ }
+ }));
}
/**
@@ -140,8 +161,9 @@ public final class MoreExecutors {
* @return an unmodifiable version of the input which will not hang the JVM
*/
@Beta
- public static ExecutorService getExitingExecutorService(ThreadPoolExecutor executor) {
- return new Application().getExitingExecutorService(executor);
+ public static ExecutorService getExitingExecutorService(
+ ThreadPoolExecutor executor) {
+ return getExitingExecutorService(executor, 120, TimeUnit.SECONDS);
}
/**
@@ -162,69 +184,7 @@ public final class MoreExecutors {
@Beta
public static ScheduledExecutorService getExitingScheduledExecutorService(
ScheduledThreadPoolExecutor executor) {
- return new Application().getExitingScheduledExecutorService(executor);
- }
-
- /** Represents the current application to register shutdown hooks. */
- @VisibleForTesting static class Application {
-
- final ExecutorService getExitingExecutorService(
- ThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit) {
- useDaemonThreadFactory(executor);
- ExecutorService service = Executors.unconfigurableExecutorService(executor);
- addDelayedShutdownHook(service, terminationTimeout, timeUnit);
- return service;
- }
-
- final ScheduledExecutorService getExitingScheduledExecutorService(
- ScheduledThreadPoolExecutor executor, long terminationTimeout, TimeUnit timeUnit) {
- useDaemonThreadFactory(executor);
- ScheduledExecutorService service = Executors.unconfigurableScheduledExecutorService(executor);
- addDelayedShutdownHook(service, terminationTimeout, timeUnit);
- return service;
- }
-
- final void addDelayedShutdownHook(
- final ExecutorService service, final long terminationTimeout, final TimeUnit timeUnit) {
- checkNotNull(service);
- checkNotNull(timeUnit);
- addShutdownHook(MoreExecutors.newThread("DelayedShutdownHook-for-" + service, new Runnable() {
- @Override
- public void run() {
- try {
- // We'd like to log progress and failures that may arise in the
- // following code, but unfortunately the behavior of logging
- // is undefined in shutdown hooks.
- // This is because the logging code installs a shutdown hook of its
- // own. See Cleaner class inside {@link LogManager}.
- service.shutdown();
- service.awaitTermination(terminationTimeout, timeUnit);
- } catch (InterruptedException ignored) {
- // We're shutting down anyway, so just ignore.
- }
- }
- }));
- }
-
- final ExecutorService getExitingExecutorService(ThreadPoolExecutor executor) {
- return getExitingExecutorService(executor, 120, TimeUnit.SECONDS);
- }
-
- final ScheduledExecutorService getExitingScheduledExecutorService(
- ScheduledThreadPoolExecutor executor) {
- return getExitingScheduledExecutorService(executor, 120, TimeUnit.SECONDS);
- }
-
- @VisibleForTesting void addShutdownHook(Thread hook) {
- Runtime.getRuntime().addShutdownHook(hook);
- }
- }
-
- private static void useDaemonThreadFactory(ThreadPoolExecutor executor) {
- executor.setThreadFactory(new ThreadFactoryBuilder()
- .setDaemon(true)
- .setThreadFactory(executor.getThreadFactory())
- .build());
+ return getExitingScheduledExecutorService(executor, 120, TimeUnit.SECONDS);
}
/**
@@ -483,7 +443,6 @@ public final class MoreExecutors {
private static class ScheduledListeningDecorator
extends ListeningDecorator implements ListeningScheduledExecutorService {
- @SuppressWarnings("hiding")
final ScheduledExecutorService delegate;
ScheduledListeningDecorator(ScheduledExecutorService delegate) {
@@ -516,172 +475,4 @@ public final class MoreExecutors {
command, initialDelay, delay, unit);
}
}
-
- /*
- * This following method is a modified version of one found in
- * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/AbstractExecutorServiceTest.java?revision=1.30
- * which contained the following notice:
- *
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- * Other contributors include Andrew Wright, Jeffrey Hayes,
- * Pat Fisher, Mike Judd.
- */
-
- /**
- * An implementation of {@link ExecutorService#invokeAny} for {@link ListeningExecutorService}
- * implementations.
- */ static <T> T invokeAnyImpl(ListeningExecutorService executorService,
- Collection<? extends Callable<T>> tasks, boolean timed, long nanos)
- throws InterruptedException, ExecutionException, TimeoutException {
- checkNotNull(executorService);
- int ntasks = tasks.size();
- checkArgument(ntasks > 0);
- List<Future<T>> futures = Lists.newArrayListWithCapacity(ntasks);
- BlockingQueue<Future<T>> futureQueue = Queues.newLinkedBlockingQueue();
-
- // For efficiency, especially in executors with limited
- // parallelism, check to see if previously submitted tasks are
- // done before submitting more of them. This interleaving
- // plus the exception mechanics account for messiness of main
- // loop.
-
- try {
- // Record exceptions so that if we fail to obtain any
- // result, we can throw the last exception we got.
- ExecutionException ee = null;
- long lastTime = timed ? System.nanoTime() : 0;
- Iterator<? extends Callable<T>> it = tasks.iterator();
-
- futures.add(submitAndAddQueueListener(executorService, it.next(), futureQueue));
- --ntasks;
- int active = 1;
-
- for (;;) {
- Future<T> f = futureQueue.poll();
- if (f == null) {
- if (ntasks > 0) {
- --ntasks;
- futures.add(submitAndAddQueueListener(executorService, it.next(), futureQueue));
- ++active;
- } else if (active == 0) {
- break;
- } else if (timed) {
- f = futureQueue.poll(nanos, TimeUnit.NANOSECONDS);
- if (f == null) {
- throw new TimeoutException();
- }
- long now = System.nanoTime();
- nanos -= now - lastTime;
- lastTime = now;
- } else {
- f = futureQueue.take();
- }
- }
- if (f != null) {
- --active;
- try {
- return f.get();
- } catch (ExecutionException eex) {
- ee = eex;
- } catch (RuntimeException rex) {
- ee = new ExecutionException(rex);
- }
- }
- }
-
- if (ee == null) {
- ee = new ExecutionException(null);
- }
- throw ee;
- } finally {
- for (Future<T> f : futures) {
- f.cancel(true);
- }
- }
- }
-
- /**
- * Submits the task and adds a listener that adds the future to {@code queue} when it completes.
- */
- private static <T> ListenableFuture<T> submitAndAddQueueListener(
- ListeningExecutorService executorService, Callable<T> task,
- final BlockingQueue<Future<T>> queue) {
- final ListenableFuture<T> future = executorService.submit(task);
- future.addListener(new Runnable() {
- @Override public void run() {
- queue.add(future);
- }
- }, MoreExecutors.sameThreadExecutor());
- return future;
- }
-
- /**
- * Returns a default thread factory used to create new threads.
- *
- * <p>On AppEngine, returns {@code ThreadManager.currentRequestThreadFactory()}.
- * Otherwise, returns {@link Executors#defaultThreadFactory()}.
- *
- * @since 14.0
- */
- @Beta
- public static ThreadFactory platformThreadFactory() {
- if (!isAppEngine()) {
- return Executors.defaultThreadFactory();
- }
- try {
- return (ThreadFactory) Class.forName("com.google.appengine.api.ThreadManager")
- .getMethod("currentRequestThreadFactory")
- .invoke(null);
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException("Couldn't invoke ThreadManager.currentRequestThreadFactory", e);
- } catch (InvocationTargetException e) {
- throw Throwables.propagate(e.getCause());
- }
- }
-
- private static boolean isAppEngine() {
- if (System.getProperty("com.google.appengine.runtime.environment") == null) {
- return false;
- }
- try {
- // If the current environment is null, we're not inside AppEngine.
- return Class.forName("com.google.apphosting.api.ApiProxy")
- .getMethod("getCurrentEnvironment")
- .invoke(null) != null;
- } catch (ClassNotFoundException e) {
- // If ApiProxy doesn't exist, we're not on AppEngine at all.
- return false;
- } catch (InvocationTargetException e) {
- // If ApiProxy throws an exception, we're not in a proper AppEngine environment.
- return false;
- } catch (IllegalAccessException e) {
- // If the method isn't accessible, we're not on a supported version of AppEngine;
- return false;
- } catch (NoSuchMethodException e) {
- // If the method doesn't exist, we're not on a supported version of AppEngine;
- return false;
- }
- }
-
- /**
- * Creates a thread using {@link #platformThreadFactory}, and sets its name to {@code name}
- * unless changing the name is forbidden by the security manager.
- */
- static Thread newThread(String name, Runnable runnable) {
- checkNotNull(name);
- checkNotNull(runnable);
- Thread result = platformThreadFactory().newThread(runnable);
- try {
- result.setName(name);
- } catch (SecurityException e) {
- // OK if we can't set the name in this environment.
- }
- return result;
- }
}
diff --git a/guava/src/com/google/common/util/concurrent/RateLimiter.java b/guava/src/com/google/common/util/concurrent/RateLimiter.java
deleted file mode 100644
index 4085654..0000000
--- a/guava/src/com/google/common/util/concurrent/RateLimiter.java
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Ticker;
-
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * A rate limiter. Conceptually, a rate limiter distributes permits at a
- * configurable rate. Each {@link #acquire()} blocks if necessary until a permit is
- * available, and then takes it. Once acquired, permits need not be released.
- *
- * <p>Rate limiters are often used to restrict the rate at which some
- * physical or logical resource is accessed. This is in contrast to {@link
- * java.util.concurrent.Semaphore} which restricts the number of concurrent
- * accesses instead of the rate (note though that concurrency and rate are closely related,
- * e.g. see <a href="http://en.wikipedia.org/wiki/Little's_law">Little's Law</a>).
- *
- * <p>A {@code RateLimiter} is defined primarily by the rate at which permits
- * are issued. Absent additional configuration, permits will be distributed at a
- * fixed rate, defined in terms of permits per second. Permits will be distributed
- * smoothly, with the delay between individual permits being adjusted to ensure
- * that the configured rate is maintained.
- *
- * <p>It is possible to configure a {@code RateLimiter} to have a warmup
- * period during which time the permits issued each second steadily increases until
- * it hits the stable rate.
- *
- * <p>As an example, imagine that we have a list of tasks to execute, but we don't want to
- * submit more than 2 per second:
- *<pre> {@code
- * final RateLimiter rateLimiter = RateLimiter.create(2.0); // rate is "2 permits per second"
- * void submitTasks(List<Runnable> tasks, Executor executor) {
- * for (Runnable task : tasks) {
- * rateLimiter.acquire(); // may wait
- * executor.execute(task);
- * }
- * }
- *}</pre>
- *
- * <p>As another example, imagine that we produce a stream of data, and we want to cap it
- * at 5kb per second. This could be accomplished by requiring a permit per byte, and specifying
- * a rate of 5000 permits per second:
- *<pre> {@code
- * final RateLimiter rateLimiter = RateLimiter.create(5000.0); // rate = 5000 permits per second
- * void submitPacket(byte[] packet) {
- * rateLimiter.acquire(packet.length);
- * networkService.send(packet);
- * }
- *}</pre>
- *
- * <p>It is important to note that the number of permits requested <i>never</i>
- * affect the throttling of the request itself (an invocation to {@code acquire(1)}
- * and an invocation to {@code acquire(1000)} will result in exactly the same throttling, if any),
- * but it affects the throttling of the <i>next</i> request. I.e., if an expensive task
- * arrives at an idle RateLimiter, it will be granted immediately, but it is the <i>next</i>
- * request that will experience extra throttling, thus paying for the cost of the expensive
- * task.
- *
- * <p>Note: {@code RateLimiter} does not provide fairness guarantees.
- *
- * @author Dimitris Andreou
- * @since 13.0
- */
-// TODO(user): switch to nano precision. A natural unit of cost is "bytes", and a micro precision
-// would mean a maximum rate of "1MB/s", which might be small in some cases.
-@ThreadSafe
-@Beta
-public abstract class RateLimiter {
- /*
- * How is the RateLimiter designed, and why?
- *
- * The primary feature of a RateLimiter is its "stable rate", the maximum rate that
- * is should allow at normal conditions. This is enforced by "throttling" incoming
- * requests as needed, i.e. compute, for an incoming request, the appropriate throttle time,
- * and make the calling thread wait as much.
- *
- * The simplest way to maintain a rate of QPS is to keep the timestamp of the last
- * granted request, and ensure that (1/QPS) seconds have elapsed since then. For example,
- * for a rate of QPS=5 (5 tokens per second), if we ensure that a request isn't granted
- * earlier than 200ms after the the last one, then we achieve the intended rate.
- * If a request comes and the last request was granted only 100ms ago, then we wait for
- * another 100ms. At this rate, serving 15 fresh permits (i.e. for an acquire(15) request)
- * naturally takes 3 seconds.
- *
- * It is important to realize that such a RateLimiter has a very superficial memory
- * of the past: it only remembers the last request. What if the RateLimiter was unused for
- * a long period of time, then a request arrived and was immediately granted?
- * This RateLimiter would immediately forget about that past underutilization. This may
- * result in either underutilization or overflow, depending on the real world consequences
- * of not using the expected rate.
- *
- * Past underutilization could mean that excess resources are available. Then, the RateLimiter
- * should speed up for a while, to take advantage of these resources. This is important
- * when the rate is applied to networking (limiting bandwidth), where past underutilization
- * typically translates to "almost empty buffers", which can be filled immediately.
- *
- * On the other hand, past underutilization could mean that "the server responsible for
- * handling the request has become less ready for future requests", i.e. its caches become
- * stale, and requests become more likely to trigger expensive operations (a more extreme
- * case of this example is when a server has just booted, and it is mostly busy with getting
- * itself up to speed).
- *
- * To deal with such scenarios, we add an extra dimension, that of "past underutilization",
- * modeled by "storedPermits" variable. This variable is zero when there is no
- * underutilization, and it can grow up to maxStoredPermits, for sufficiently large
- * underutilization. So, the requested permits, by an invocation acquire(permits),
- * are served from:
- * - stored permits (if available)
- * - fresh permits (for any remaining permits)
- *
- * How this works is best explained with an example:
- *
- * For a RateLimiter that produces 1 token per second, every second
- * that goes by with the RateLimiter being unused, we increase storedPermits by 1.
- * Say we leave the RateLimiter unused for 10 seconds (i.e., we expected a request at time
- * X, but we are at time X + 10 seconds before a request actually arrives; this is
- * also related to the point made in the last paragraph), thus storedPermits
- * becomes 10.0 (assuming maxStoredPermits >= 10.0). At that point, a request of acquire(3)
- * arrives. We serve this request out of storedPermits, and reduce that to 7.0 (how this is
- * translated to throttling time is discussed later). Immediately after, assume that an
- * acquire(10) request arriving. We serve the request partly from storedPermits,
- * using all the remaining 7.0 permits, and the remaining 3.0, we serve them by fresh permits
- * produced by the rate limiter.
- *
- * We already know how much time it takes to serve 3 fresh permits: if the rate is
- * "1 token per second", then this will take 3 seconds. But what does it mean to serve 7
- * stored permits? As explained above, there is no unique answer. If we are primarily
- * interested to deal with underutilization, then we want stored permits to be given out
- * /faster/ than fresh ones, because underutilization = free resources for the taking.
- * If we are primarily interested to deal with overflow, then stored permits could
- * be given out /slower/ than fresh ones. Thus, we require a (different in each case)
- * function that translates storedPermits to throtting time.
- *
- * This role is played by storedPermitsToWaitTime(double storedPermits, double permitsToTake).
- * The underlying model is a continuous function mapping storedPermits
- * (from 0.0 to maxStoredPermits) onto the 1/rate (i.e. intervals) that is effective at the given
- * storedPermits. "storedPermits" essentially measure unused time; we spend unused time
- * buying/storing permits. Rate is "permits / time", thus "1 / rate = time / permits".
- * Thus, "1/rate" (time / permits) times "permits" gives time, i.e., integrals on this
- * function (which is what storedPermitsToWaitTime() computes) correspond to minimum intervals
- * between subsequent requests, for the specified number of requested permits.
- *
- * Here is an example of storedPermitsToWaitTime:
- * If storedPermits == 10.0, and we want 3 permits, we take them from storedPermits,
- * reducing them to 7.0, and compute the throttling for these as a call to
- * storedPermitsToWaitTime(storedPermits = 10.0, permitsToTake = 3.0), which will
- * evaluate the integral of the function from 7.0 to 10.0.
- *
- * Using integrals guarantees that the effect of a single acquire(3) is equivalent
- * to { acquire(1); acquire(1); acquire(1); }, or { acquire(2); acquire(1); }, etc,
- * since the integral of the function in [7.0, 10.0] is equivalent to the sum of the
- * integrals of [7.0, 8.0], [8.0, 9.0], [9.0, 10.0] (and so on), no matter
- * what the function is. This guarantees that we handle correctly requests of varying weight
- * (permits), /no matter/ what the actual function is - so we can tweak the latter freely.
- * (The only requirement, obviously, is that we can compute its integrals).
- *
- * Note well that if, for this function, we chose a horizontal line, at height of exactly
- * (1/QPS), then the effect of the function is non-existent: we serve storedPermits at
- * exactly the same cost as fresh ones (1/QPS is the cost for each). We use this trick later.
- *
- * If we pick a function that goes /below/ that horizontal line, it means that we reduce
- * the area of the function, thus time. Thus, the RateLimiter becomes /faster/ after a
- * period of underutilization. If, on the other hand, we pick a function that
- * goes /above/ that horizontal line, then it means that the area (time) is increased,
- * thus storedPermits are more costly than fresh permits, thus the RateLimiter becomes
- * /slower/ after a period of underutilization.
- *
- * Last, but not least: consider a RateLimiter with rate of 1 permit per second, currently
- * completely unused, and an expensive acquire(100) request comes. It would be nonsensical
- * to just wait for 100 seconds, and /then/ start the actual task. Why wait without doing
- * anything? A much better approach is to /allow/ the request right away (as if it was an
- * acquire(1) request instead), and postpone /subsequent/ requests as needed. In this version,
- * we allow starting the task immediately, and postpone by 100 seconds future requests,
- * thus we allow for work to get done in the meantime instead of waiting idly.
- *
- * This has important consequences: it means that the RateLimiter doesn't remember the time
- * of the _last_ request, but it remembers the (expected) time of the _next_ request. This
- * also enables us to tell immediately (see tryAcquire(timeout)) whether a particular
- * timeout is enough to get us to the point of the next scheduling time, since we always
- * maintain that. And what we mean by "an unused RateLimiter" is also defined by that
- * notion: when we observe that the "expected arrival time of the next request" is actually
- * in the past, then the difference (now - past) is the amount of time that the RateLimiter
- * was formally unused, and it is that amount of time which we translate to storedPermits.
- * (We increase storedPermits with the amount of permits that would have been produced
- * in that idle time). So, if rate == 1 permit per second, and arrivals come exactly
- * one second after the previous, then storedPermits is _never_ increased -- we would only
- * increase it for arrivals _later_ than the expected one second.
- */
-
- /**
- * Creates a {@code RateLimiter} with the specified stable throughput, given as
- * "permits per second" (commonly referred to as <i>QPS</i>, queries per second).
- *
- * <p>The returned {@code RateLimiter} ensures that on average no more than {@code
- * permitsPerSecond} are issued during any given second, with sustained requests
- * being smoothly spread over each second. When the incoming request rate exceeds
- * {@code permitsPerSecond} the rate limiter will release one permit every {@code
- * (1.0 / permitsPerSecond)} seconds. When the rate limiter is unused,
- * bursts of up to {@code permitsPerSecond} permits will be allowed, with subsequent
- * requests being smoothly limited at the stable rate of {@code permitsPerSecond}.
- *
- * @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in
- * how many permits become available per second.
- */
- public static RateLimiter create(double permitsPerSecond) {
- return create(SleepingTicker.SYSTEM_TICKER, permitsPerSecond);
- }
-
- @VisibleForTesting
- static RateLimiter create(SleepingTicker ticker, double permitsPerSecond) {
- RateLimiter rateLimiter = new Bursty(ticker);
- rateLimiter.setRate(permitsPerSecond);
- return rateLimiter;
- }
-
- /**
- * Creates a {@code RateLimiter} with the specified stable throughput, given as
- * "permits per second" (commonly referred to as <i>QPS</i>, queries per second), and a
- * <i>warmup period</i>, during which the {@code RateLimiter} smoothly ramps up its rate,
- * until it reaches its maximum rate at the end of the period (as long as there are enough
- * requests to saturate it). Similarly, if the {@code RateLimiter} is left <i>unused</i> for
- * a duration of {@code warmupPeriod}, it will gradually return to its "cold" state,
- * i.e. it will go through the same warming up process as when it was first created.
- *
- * <p>The returned {@code RateLimiter} is intended for cases where the resource that actually
- * fulfils the requests (e.g., a remote server) needs "warmup" time, rather than
- * being immediately accessed at the stable (maximum) rate.
- *
- * <p>The returned {@code RateLimiter} starts in a "cold" state (i.e. the warmup period
- * will follow), and if it is left unused for long enough, it will return to that state.
- *
- * @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in
- * how many permits become available per second
- * @param warmupPeriod the duration of the period where the {@code RateLimiter} ramps up its
- * rate, before reaching its stable (maximum) rate
- * @param unit the time unit of the warmupPeriod argument
- */
- // TODO(user): add a burst size of 1-second-worth of permits, as in the metronome?
- public static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit) {
- return create(SleepingTicker.SYSTEM_TICKER, permitsPerSecond, warmupPeriod, unit);
- }
-
- @VisibleForTesting
- static RateLimiter create(
- SleepingTicker ticker, double permitsPerSecond, long warmupPeriod, TimeUnit timeUnit) {
- RateLimiter rateLimiter = new WarmingUp(ticker, warmupPeriod, timeUnit);
- rateLimiter.setRate(permitsPerSecond);
- return rateLimiter;
- }
-
- @VisibleForTesting
- static RateLimiter createBursty(
- SleepingTicker ticker, double permitsPerSecond, int maxBurstSize) {
- Bursty rateLimiter = new Bursty(ticker);
- rateLimiter.setRate(permitsPerSecond);
- rateLimiter.maxPermits = maxBurstSize;
- return rateLimiter;
- }
-
- /**
- * The underlying timer; used both to measure elapsed time and sleep as necessary. A separate
- * object to facilitate testing.
- */
- private final SleepingTicker ticker;
-
- /**
- * The timestamp when the RateLimiter was created; used to avoid possible overflow/time-wrapping
- * errors.
- */
- private final long offsetNanos;
-
- /**
- * The currently stored permits.
- */
- double storedPermits;
-
- /**
- * The maximum number of stored permits.
- */
- double maxPermits;
-
- /**
- * The interval between two unit requests, at our stable rate. E.g., a stable rate of 5 permits
- * per second has a stable interval of 200ms.
- */
- volatile double stableIntervalMicros;
-
- private final Object mutex = new Object();
-
- /**
- * The time when the next request (no matter its size) will be granted. After granting a request,
- * this is pushed further in the future. Large requests push this further than small requests.
- */
- private long nextFreeTicketMicros = 0L; // could be either in the past or future
-
- private RateLimiter(SleepingTicker ticker) {
- this.ticker = ticker;
- this.offsetNanos = ticker.read();
- }
-
- /**
- * Updates the stable rate of this {@code RateLimiter}, that is, the
- * {@code permitsPerSecond} argument provided in the factory method that
- * constructed the {@code RateLimiter}. Currently throttled threads will <b>not</b>
- * be awakened as a result of this invocation, thus they do not observe the new rate;
- * only subsequent requests will.
- *
- * <p>Note though that, since each request repays (by waiting, if necessary) the cost
- * of the <i>previous</i> request, this means that the very next request
- * after an invocation to {@code setRate} will not be affected by the new rate;
- * it will pay the cost of the previous request, which is in terms of the previous rate.
- *
- * <p>The behavior of the {@code RateLimiter} is not modified in any other way,
- * e.g. if the {@code RateLimiter} was configured with a warmup period of 20 seconds,
- * it still has a warmup period of 20 seconds after this method invocation.
- *
- * @param permitsPerSecond the new stable rate of this {@code RateLimiter}.
- */
- public final void setRate(double permitsPerSecond) {
- Preconditions.checkArgument(permitsPerSecond > 0.0
- && !Double.isNaN(permitsPerSecond), "rate must be positive");
- synchronized (mutex) {
- resync(readSafeMicros());
- double stableIntervalMicros = TimeUnit.SECONDS.toMicros(1L) / permitsPerSecond;
- this.stableIntervalMicros = stableIntervalMicros;
- doSetRate(permitsPerSecond, stableIntervalMicros);
- }
- }
-
- abstract void doSetRate(double permitsPerSecond, double stableIntervalMicros);
-
- /**
- * Returns the stable rate (as {@code permits per seconds}) with which this
- * {@code RateLimiter} is configured with. The initial value of this is the same as
- * the {@code permitsPerSecond} argument passed in the factory method that produced
- * this {@code RateLimiter}, and it is only updated after invocations
- * to {@linkplain #setRate}.
- */
- public final double getRate() {
- return TimeUnit.SECONDS.toMicros(1L) / stableIntervalMicros;
- }
-
- /**
- * Acquires a permit from this {@code RateLimiter}, blocking until the request can be granted.
- *
- * <p>This method is equivalent to {@code acquire(1)}.
- */
- public void acquire() {
- acquire(1);
- }
-
- /**
- * Acquires the given number of permits from this {@code RateLimiter}, blocking until the
- * request be granted.
- *
- * @param permits the number of permits to acquire
- */
- public void acquire(int permits) {
- checkPermits(permits);
- long microsToWait;
- synchronized (mutex) {
- microsToWait = reserveNextTicket(permits, readSafeMicros());
- }
- ticker.sleepMicrosUninterruptibly(microsToWait);
- }
-
- /**
- * Acquires a permit from this {@code RateLimiter} if it can be obtained
- * without exceeding the specified {@code timeout}, or returns {@code false}
- * immediately (without waiting) if the permit would not have been granted
- * before the timeout expired.
- *
- * <p>This method is equivalent to {@code tryAcquire(1, timeout, unit)}.
- *
- * @param timeout the maximum time to wait for the permit
- * @param unit the time unit of the timeout argument
- * @return {@code true} if the permit was acquired, {@code false} otherwise
- */
- public boolean tryAcquire(long timeout, TimeUnit unit) {
- return tryAcquire(1, timeout, unit);
- }
-
- /**
- * Acquires permits from this {@link RateLimiter} if it can be acquired immediately without delay.
- *
- * <p>
- * This method is equivalent to {@code tryAcquire(permits, 0, anyUnit)}.
- *
- * @param permits the number of permits to acquire
- * @return {@code true} if the permits were acquired, {@code false} otherwise
- * @since 14.0
- */
- public boolean tryAcquire(int permits) {
- return tryAcquire(permits, 0, TimeUnit.MICROSECONDS);
- }
-
- /**
- * Acquires a permit from this {@link RateLimiter} if it can be acquired immediately without
- * delay.
- *
- * <p>
- * This method is equivalent to {@code tryAcquire(1)}.
- *
- * @return {@code true} if the permit was acquired, {@code false} otherwise
- * @since 14.0
- */
- public boolean tryAcquire() {
- return tryAcquire(1, 0, TimeUnit.MICROSECONDS);
- }
-
- /**
- * Acquires the given number of permits from this {@code RateLimiter} if it can be obtained
- * without exceeding the specified {@code timeout}, or returns {@code false}
- * immediately (without waiting) if the permits would not have been granted
- * before the timeout expired.
- *
- * @param permits the number of permits to acquire
- * @param timeout the maximum time to wait for the permits
- * @param unit the time unit of the timeout argument
- * @return {@code true} if the permits were acquired, {@code false} otherwise
- */
- public boolean tryAcquire(int permits, long timeout, TimeUnit unit) {
- long timeoutMicros = unit.toMicros(timeout);
- checkPermits(permits);
- long microsToWait;
- synchronized (mutex) {
- long nowMicros = readSafeMicros();
- if (nextFreeTicketMicros > nowMicros + timeoutMicros) {
- return false;
- } else {
- microsToWait = reserveNextTicket(permits, nowMicros);
- }
- }
- ticker.sleepMicrosUninterruptibly(microsToWait);
- return true;
- }
-
- private static void checkPermits(int permits) {
- Preconditions.checkArgument(permits > 0, "Requested permits must be positive");
- }
-
- /**
- * Reserves next ticket and returns the wait time that the caller must wait for.
- */
- private long reserveNextTicket(double requiredPermits, long nowMicros) {
- resync(nowMicros);
- long microsToNextFreeTicket = nextFreeTicketMicros - nowMicros;
- double storedPermitsToSpend = Math.min(requiredPermits, this.storedPermits);
- double freshPermits = requiredPermits - storedPermitsToSpend;
-
- long waitMicros = storedPermitsToWaitTime(this.storedPermits, storedPermitsToSpend)
- + (long) (freshPermits * stableIntervalMicros);
-
- this.nextFreeTicketMicros = nextFreeTicketMicros + waitMicros;
- this.storedPermits -= storedPermitsToSpend;
- return microsToNextFreeTicket;
- }
-
- /**
- * Translates a specified portion of our currently stored permits which we want to
- * spend/acquire, into a throttling time. Conceptually, this evaluates the integral
- * of the underlying function we use, for the range of
- * [(storedPermits - permitsToTake), storedPermits].
- *
- * This always holds: {@code 0 <= permitsToTake <= storedPermits}
- */
- abstract long storedPermitsToWaitTime(double storedPermits, double permitsToTake);
-
- private void resync(long nowMicros) {
- // if nextFreeTicket is in the past, resync to now
- if (nowMicros > nextFreeTicketMicros) {
- storedPermits = Math.min(maxPermits,
- storedPermits + (nowMicros - nextFreeTicketMicros) / stableIntervalMicros);
- nextFreeTicketMicros = nowMicros;
- }
- }
-
- private long readSafeMicros() {
- return TimeUnit.NANOSECONDS.toMicros(ticker.read() - offsetNanos);
- }
-
- @Override
- public String toString() {
- return String.format("RateLimiter[stableRate=%3.1fqps]", 1000000.0 / stableIntervalMicros);
- }
-
- /**
- * This implements the following function:
- *
- * ^ throttling
- * |
- * 3*stable + /
- * interval | /.
- * (cold) | / .
- * | / . <-- "warmup period" is the area of the trapezoid between
- * 2*stable + / . halfPermits and maxPermits
- * interval | / .
- * | / .
- * | / .
- * stable +----------/ WARM . }
- * interval | . UP . } <-- this rectangle (from 0 to maxPermits, and
- * | . PERIOD. } height == stableInterval) defines the cooldown period,
- * | . . } and we want cooldownPeriod == warmupPeriod
- * |---------------------------------> storedPermits
- * (halfPermits) (maxPermits)
- *
- * Before going into the details of this particular function, let's keep in mind the basics:
- * 1) The state of the RateLimiter (storedPermits) is a vertical line in this figure.
- * 2) When the RateLimiter is not used, this goes right (up to maxPermits)
- * 3) When the RateLimiter is used, this goes left (down to zero), since if we have storedPermits,
- * we serve from those first
- * 4) When _unused_, we go right at the same speed (rate)! I.e., if our rate is
- * 2 permits per second, and 3 unused seconds pass, we will always save 6 permits
- * (no matter what our initial position was), up to maxPermits.
- * If we invert the rate, we get the "stableInterval" (interval between two requests
- * in a perfectly spaced out sequence of requests of the given rate). Thus, if you
- * want to see "how much time it will take to go from X storedPermits to X+K storedPermits?",
- * the answer is always stableInterval * K. In the same example, for 2 permits per second,
- * stableInterval is 500ms. Thus to go from X storedPermits to X+6 storedPermits, we
- * require 6 * 500ms = 3 seconds.
- *
- * In short, the time it takes to move to the right (save K permits) is equal to the
- * rectangle of width == K and height == stableInterval.
- * 4) When _used_, the time it takes, as explained in the introductory class note, is
- * equal to the integral of our function, between X permits and X-K permits, assuming
- * we want to spend K saved permits.
- *
- * In summary, the time it takes to move to the left (spend K permits), is equal to the
- * area of the function of width == K.
- *
- * Let's dive into this function now:
- *
- * When we have storedPermits <= halfPermits (the left portion of the function), then
- * we spend them at the exact same rate that
- * fresh permits would be generated anyway (that rate is 1/stableInterval). We size
- * this area to be equal to _half_ the specified warmup period. Why we need this?
- * And why half? We'll explain shortly below (after explaining the second part).
- *
- * Stored permits that are beyond halfPermits, are mapped to an ascending line, that goes
- * from stableInterval to 3 * stableInterval. The average height for that part is
- * 2 * stableInterval, and is sized appropriately to have an area _equal_ to the
- * specified warmup period. Thus, by point (4) above, it takes "warmupPeriod" amount of time
- * to go from maxPermits to halfPermits.
- *
- * BUT, by point (3) above, it only takes "warmupPeriod / 2" amount of time to return back
- * to maxPermits, from halfPermits! (Because the trapezoid has double the area of the rectangle
- * of height stableInterval and equivalent width). We decided that the "cooldown period"
- * time should be equivalent to "warmup period", thus a fully saturated RateLimiter
- * (with zero stored permits, serving only fresh ones) can go to a fully unsaturated
- * (with storedPermits == maxPermits) in the same amount of time it takes for a fully
- * unsaturated RateLimiter to return to the stableInterval -- which happens in halfPermits,
- * since beyond that point, we use a horizontal line of "stableInterval" height, simulating
- * the regular rate.
- *
- * Thus, we have figured all dimensions of this shape, to give all the desired
- * properties:
- * - the width is warmupPeriod / stableInterval, to make cooldownPeriod == warmupPeriod
- * - the slope starts at the middle, and goes from stableInterval to 3*stableInterval so
- * to have halfPermits being spend in double the usual time (half the rate), while their
- * respective rate is steadily ramping up
- */
- private static class WarmingUp extends RateLimiter {
-
- final long warmupPeriodMicros;
- /**
- * The slope of the line from the stable interval (when permits == 0), to the cold interval
- * (when permits == maxPermits)
- */
- private double slope;
- private double halfPermits;
-
- WarmingUp(SleepingTicker ticker, long warmupPeriod, TimeUnit timeUnit) {
- super(ticker);
- this.warmupPeriodMicros = timeUnit.toMicros(warmupPeriod);
- }
-
- @Override
- void doSetRate(double permitsPerSecond, double stableIntervalMicros) {
- double oldMaxPermits = maxPermits;
- maxPermits = warmupPeriodMicros / stableIntervalMicros;
- halfPermits = maxPermits / 2.0;
- // Stable interval is x, cold is 3x, so on average it's 2x. Double the time -> halve the rate
- double coldIntervalMicros = stableIntervalMicros * 3.0;
- slope = (coldIntervalMicros - stableIntervalMicros) / halfPermits;
- if (oldMaxPermits == Double.POSITIVE_INFINITY) {
- // if we don't special-case this, we would get storedPermits == NaN, below
- storedPermits = 0.0;
- } else {
- storedPermits = (oldMaxPermits == 0.0)
- ? maxPermits // initial state is cold
- : storedPermits * maxPermits / oldMaxPermits;
- }
- }
-
- @Override
- long storedPermitsToWaitTime(double storedPermits, double permitsToTake) {
- double availablePermitsAboveHalf = storedPermits - halfPermits;
- long micros = 0;
- // measuring the integral on the right part of the function (the climbing line)
- if (availablePermitsAboveHalf > 0.0) {
- double permitsAboveHalfToTake = Math.min(availablePermitsAboveHalf, permitsToTake);
- micros = (long) (permitsAboveHalfToTake * (permitsToTime(availablePermitsAboveHalf)
- + permitsToTime(availablePermitsAboveHalf - permitsAboveHalfToTake)) / 2.0);
- permitsToTake -= permitsAboveHalfToTake;
- }
- // measuring the integral on the left part of the function (the horizontal line)
- micros += (stableIntervalMicros * permitsToTake);
- return micros;
- }
-
- private double permitsToTime(double permits) {
- return stableIntervalMicros + permits * slope;
- }
- }
-
- /**
- * This implements a trivial function, where storedPermits are translated to
- * zero throttling - thus, a client gets an infinite speedup for permits acquired out
- * of the storedPermits pool. This is also used for the special case of the "metronome",
- * where the width of the function is also zero; maxStoredPermits is zero, thus
- * storedPermits and permitsToTake are always zero as well. Such a RateLimiter can
- * not save permits when unused, thus all permits it serves are fresh, using the
- * designated rate.
- */
- private static class Bursty extends RateLimiter {
- Bursty(SleepingTicker ticker) {
- super(ticker);
- }
-
- @Override
- void doSetRate(double permitsPerSecond, double stableIntervalMicros) {
- double oldMaxPermits = this.maxPermits;
- /*
- * We allow the equivalent work of up to one second to be granted with zero waiting, if the
- * rate limiter has been unused for as much. This is to avoid potentially producing tiny
- * wait interval between subsequent requests for sufficiently large rates, which would
- * unnecessarily overconstrain the thread scheduler.
- */
- maxPermits = permitsPerSecond; // one second worth of permits
- storedPermits = (oldMaxPermits == 0.0)
- ? 0.0 // initial state
- : storedPermits * maxPermits / oldMaxPermits;
- }
-
- @Override
- long storedPermitsToWaitTime(double storedPermits, double permitsToTake) {
- return 0L;
- }
- }
-
- @VisibleForTesting
- static abstract class SleepingTicker extends Ticker {
- abstract void sleepMicrosUninterruptibly(long micros);
-
- static final SleepingTicker SYSTEM_TICKER = new SleepingTicker() {
- @Override
- public long read() {
- return systemTicker().read();
- }
-
- @Override
- public void sleepMicrosUninterruptibly(long micros) {
- if (micros > 0) {
- Uninterruptibles.sleepUninterruptibly(micros, TimeUnit.MICROSECONDS);
- }
- }
- };
- }
-}
diff --git a/guava/src/com/google/common/util/concurrent/Service.java b/guava/src/com/google/common/util/concurrent/Service.java
index 861164e..9ad1f3d 100644
--- a/guava/src/com/google/common/util/concurrent/Service.java
+++ b/guava/src/com/google/common/util/concurrent/Service.java
@@ -19,58 +19,57 @@ package com.google.common.util.concurrent;
import com.google.common.annotations.Beta;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
/**
- * An object with an operational state, plus asynchronous {@link #start()} and {@link #stop()}
- * lifecycle methods to transition between states. Example services include webservers, RPC servers
- * and timers.
- *
- * <p>The normal lifecycle of a service is:
+ * An object with an operational state, plus asynchronous {@link #start()} and
+ * {@link #stop()} lifecycle methods to transfer into and out of this state.
+ * Example services include webservers, RPC servers and timers. The normal
+ * lifecycle of a service is:
* <ul>
- * <li>{@linkplain State#NEW NEW} -&gt;
- * <li>{@linkplain State#STARTING STARTING} -&gt;
- * <li>{@linkplain State#RUNNING RUNNING} -&gt;
- * <li>{@linkplain State#STOPPING STOPPING} -&gt;
- * <li>{@linkplain State#TERMINATED TERMINATED}
+ * <li>{@link State#NEW} -&gt;</li>
+ * <li>{@link State#STARTING} -&gt;</li>
+ * <li>{@link State#RUNNING} -&gt;</li>
+ * <li>{@link State#STOPPING} -&gt;</li>
+ * <li>{@link State#TERMINATED}</li>
* </ul>
*
- * <p>There are deviations from this if there are failures or if {@link Service#stop} is called
- * before the {@link Service} reaches the {@linkplain State#RUNNING RUNNING} state. The set of legal
- * transitions form a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a>,
- * therefore every method of the listener will be called at most once. N.B. The {@link State#FAILED}
- * and {@link State#TERMINATED} states are terminal states, once a service enters either of these
- * states it cannot ever leave them.
+ * If the service fails while starting, running or stopping, its state will be
+ * {@link State#FAILED}, and its behavior is undefined. Such a service cannot be
+ * started nor stopped.
*
- * <p>Implementors of this interface are strongly encouraged to extend one of the abstract classes
- * in this package which implement this interface and make the threading and state management
- * easier.
+ * <p>Implementors of this interface are strongly encouraged to extend one of
+ * the abstract classes in this package which implement this interface and
+ * make the threading and state management easier.
*
* @author Jesse Wilson
- * @author Luke Sandberg
- * @since 9.0 (in 1.0 as {@code com.google.common.base.Service})
+ * @since 9.0 (in 1.0 as
+ * {@code com.google.common.base.Service})
*/
-@Beta
+@Beta // TODO(kevinb): make abstract class?
public interface Service {
/**
- * If the service state is {@link State#NEW}, this initiates service startup and returns
- * immediately. If the service has already been started, this method returns immediately without
- * taking action. A stopped service may not be restarted.
+ * If the service state is {@link State#NEW}, this initiates service startup
+ * and returns immediately. If the service has already been started, this
+ * method returns immediately without taking action. A stopped service may not
+ * be restarted.
*
- * @return a future for the startup result, regardless of whether this call initiated startup.
- * Calling {@link ListenableFuture#get} will block until the service has finished
- * starting, and returns one of {@link State#RUNNING}, {@link State#STOPPING} or
- * {@link State#TERMINATED}. If the service fails to start, {@link ListenableFuture#get}
- * will throw an {@link ExecutionException}, and the service's state will be
- * {@link State#FAILED}. If it has already finished starting, {@link ListenableFuture#get}
- * returns immediately. Cancelling this future has no effect on the service.
+ * @return a future for the startup result, regardless of whether this call
+ * initiated startup. Calling {@link ListenableFuture#get} will block
+ * until the service has finished starting, and returns one of {@link
+ * State#RUNNING}, {@link State#STOPPING} or {@link State#TERMINATED}. If
+ * the service fails to start, {@link ListenableFuture#get} will throw an
+ * {@link ExecutionException}, and the service's state will be {@link
+ * State#FAILED}. If it has already finished starting, {@link
+ * ListenableFuture#get} returns immediately. Cancelling this future has
+ * no effect on the service.
*/
ListenableFuture<State> start();
/**
- * Initiates service startup (if necessary), returning once the service has finished starting.
- * Unlike calling {@code start().get()}, this method throws no checked exceptions, and it cannot
- * be {@linkplain Thread#interrupt interrupted}.
+ * Initiates service startup (if necessary), returning once the service has
+ * finished starting. Unlike calling {@code start().get()}, this method throws
+ * no checked exceptions, and it cannot be {@linkplain Thread#interrupt
+ * interrupted}.
*
* @throws UncheckedExecutionException if startup failed
* @return the state of the service when startup finished.
@@ -88,67 +87,39 @@ public interface Service {
State state();
/**
- * If the service is {@linkplain State#STARTING starting} or {@linkplain State#RUNNING running},
- * this initiates service shutdown and returns immediately. If the service is
- * {@linkplain State#NEW new}, it is {@linkplain State#TERMINATED terminated} without having been
- * started nor stopped. If the service has already been stopped, this method returns immediately
- * without taking action.
+ * If the service is {@linkplain State#STARTING starting} or {@linkplain
+ * State#RUNNING running}, this initiates service shutdown and returns
+ * immediately. If the service is {@linkplain State#NEW new}, it is
+ * {@linkplain State#TERMINATED terminated} without having been started nor
+ * stopped. If the service has already been stopped, this method returns
+ * immediately without taking action.
*
- * @return a future for the shutdown result, regardless of whether this call initiated shutdown.
- * Calling {@link ListenableFuture#get} will block until the service has finished shutting
- * down, and either returns {@link State#TERMINATED} or throws an
- * {@link ExecutionException}. If it has already finished stopping,
- * {@link ListenableFuture#get} returns immediately. Cancelling this future has no effect
- * on the service.
+ * @return a future for the shutdown result, regardless of whether this call
+ * initiated shutdown. Calling {@link ListenableFuture#get} will block
+ * until the service has finished shutting down, and either returns
+ * {@link State#TERMINATED} or throws an {@link ExecutionException}. If
+ * it has already finished stopping, {@link ListenableFuture#get} returns
+ * immediately. Cancelling this future has no effect on the service.
*/
ListenableFuture<State> stop();
/**
- * Initiates service shutdown (if necessary), returning once the service has finished stopping. If
- * this is {@link State#STARTING}, startup will be cancelled. If this is {@link State#NEW}, it is
- * {@link State#TERMINATED terminated} without having been started nor stopped. Unlike calling
- * {@code stop().get()}, this method throws no checked exceptions.
+ * Initiates service shutdown (if necessary), returning once the service has
+ * finished stopping. If this is {@link State#STARTING}, startup will be
+ * cancelled. If this is {@link State#NEW}, it is {@link State#TERMINATED
+ * terminated} without having been started nor stopped. Unlike calling {@code
+ * stop().get()}, this method throws no checked exceptions.
*
- * @throws UncheckedExecutionException if the service has failed or fails during shutdown
+ * @throws UncheckedExecutionException if shutdown failed
* @return the state of the service when shutdown finished.
*/
State stopAndWait();
/**
- * Returns the {@link Throwable} that caused this service to fail.
- *
- * @throws IllegalStateException if this service's state isn't {@linkplain State#FAILED FAILED}.
- *
- * @since 14.0
- */
- Throwable failureCause();
-
- /**
- * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given
- * executor. The listener will have the corresponding transition method called whenever the
- * service changes state. The listener will not have previous state changes replayed, so it is
- * suggested that listeners are added before the service starts.
- *
- * <p>There is no guaranteed ordering of execution of listeners, but any listener added through
- * this method is guaranteed to be called whenever there is a state change.
- *
- * <p>Exceptions thrown by a listener will be propagated up to the executor. Any exception thrown
- * during {@code Executor.execute} (e.g., a {@code RejectedExecutionException} or an exception
- * thrown by {@linkplain MoreExecutors#sameThreadExecutor inline execution}) will be caught and
- * logged.
- *
- * @param listener the listener to run when the service changes state is complete
- * @param executor the executor in which the the listeners callback methods will be run. For fast,
- * lightweight listeners that would be safe to execute in any thread, consider
- * {@link MoreExecutors#sameThreadExecutor}.
- * @since 13.0
- */
- void addListener(Listener listener, Executor executor);
-
- /**
* The lifecycle states of a service.
*
- * @since 9.0 (in 1.0 as {@code com.google.common.base.Service.State})
+ * @since 9.0 (in 1.0 as
+ * {@code com.google.common.base.Service.State})
*/
@Beta // should come out of Beta when Service does
enum State {
@@ -174,70 +145,15 @@ public interface Service {
STOPPING,
/**
- * A service in this state has completed execution normally. It does minimal work and consumes
- * minimal resources.
+ * A service in this state has completed execution normally. It does minimal
+ * work and consumes minimal resources.
*/
TERMINATED,
/**
- * A service in this state has encountered a problem and may not be operational. It cannot be
- * started nor stopped.
+ * A service in this state has encountered a problem and may not be
+ * operational. It cannot be started nor stopped.
*/
FAILED
}
-
- /**
- * A listener for the various state changes that a {@link Service} goes through in its lifecycle.
- *
- * @author Luke Sandberg
- * @since 13.0
- */
- @Beta // should come out of Beta when Service does
- interface Listener {
- /**
- * Called when the service transitions from {@linkplain State#NEW NEW} to
- * {@linkplain State#STARTING STARTING}. This occurs when {@link Service#start} or
- * {@link Service#startAndWait} is called the first time.
- */
- void starting();
-
- /**
- * Called when the service transitions from {@linkplain State#STARTING STARTING} to
- * {@linkplain State#RUNNING RUNNING}. This occurs when a service has successfully started.
- */
- void running();
-
- /**
- * Called when the service transitions to the {@linkplain State#STOPPING STOPPING} state. The
- * only valid values for {@code from} are {@linkplain State#STARTING STARTING} or
- * {@linkplain State#RUNNING RUNNING}. This occurs when {@link Service#stop} is called.
- *
- * @param from The previous state that is being transitioned from.
- */
- void stopping(State from);
-
- /**
- * Called when the service transitions to the {@linkplain State#TERMINATED TERMINATED} state.
- * The {@linkplain State#TERMINATED TERMINATED} state is a terminal state in the transition
- * diagram. Therefore, if this method is called, no other methods will be called on the
- * {@link Listener}.
- *
- * @param from The previous state that is being transitioned from. The only valid values for
- * this are {@linkplain State#NEW NEW}, {@linkplain State#RUNNING RUNNING} or
- * {@linkplain State#STOPPING STOPPING}.
- */
- void terminated(State from);
-
- /**
- * Called when the service transitions to the {@linkplain State#FAILED FAILED} state. The
- * {@linkplain State#FAILED FAILED} state is a terminal state in the transition diagram.
- * Therefore, if this method is called, no other methods will be called on the {@link Listener}.
- *
- * @param from The previous state that is being transitioned from. Failure can occur in any
- * state with the exception of {@linkplain State#NEW NEW} or
- * {@linkplain State#TERMINATED TERMINATED}.
- * @param failure The exception that caused the failure.
- */
- void failed(State from, Throwable failure);
- }
}
diff --git a/guava/src/com/google/common/util/concurrent/ServiceManager.java b/guava/src/com/google/common/util/concurrent/ServiceManager.java
deleted file mode 100644
index c779b23..0000000
--- a/guava/src/com/google/common/util/concurrent/ServiceManager.java
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Copyright (C) 2012 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.util.concurrent;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Ordering;
-import com.google.common.collect.Queues;
-import com.google.common.util.concurrent.Service.State;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.Immutable;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * A manager for monitoring and controlling a set of {@link Service services}. This class provides
- * methods for {@linkplain #startAsync() starting}, {@linkplain #stopAsync() stopping} and
- * {@linkplain #servicesByState inspecting} a collection of {@linkplain Service services}.
- * Additionally, users can monitor state transitions with the {@link Listener listener} mechanism.
- *
- * <p>While it is recommended that service lifecycles be managed via this class, state transitions
- * initiated via other mechanisms do not impact the correctness of its methods. For example, if the
- * services are started by some mechanism besides {@link #startAsync}, the listeners will be invoked
- * when appropriate and {@link #awaitHealthy} will still work as expected.
- *
- * <p>Here is a simple example of how to use a {@link ServiceManager} to start a server.
- * <pre> {@code
- * class Server {
- * public static void main(String[] args) {
- * Set<Service> services = ...;
- * ServiceManager manager = new ServiceManager(services);
- * manager.addListener(new Listener() {
- * public void stopped() {}
- * public void healthy() {
- * // Services have been initialized and are healthy, start accepting requests...
- * }
- * public void failure(Service service) {
- * // Something failed, at this point we could log it, notify a load balancer, or take
- * // some other action. For now we will just exit.
- * System.exit(1);
- * }
- * },
- * MoreExecutors.sameThreadExecutor());
- *
- * Runtime.getRuntime().addShutdownHook(new Thread() {
- * public void run() {
- * // Give the services 5 seconds to stop to ensure that we are responsive to shutdown
- * // requests.
- * try {
- * manager.stopAsync().awaitStopped(5, TimeUnit.SECONDS);
- * } catch (TimeoutException timeout) {
- * // stopping timed out
- * }
- * }
- * });
- * manager.startAsync(); // start all the services asynchronously
- * }
- * }}</pre>
- *
- * This class uses the ServiceManager's methods to start all of its services, to respond to service
- * failure and to ensure that when the JVM is shutting down all the services are stopped.
- *
- * @author Luke Sandberg
- * @since 14.0
- */
-@Beta
-@Singleton
-public final class ServiceManager {
- private static final Logger logger = Logger.getLogger(ServiceManager.class.getName());
-
- /**
- * A listener for the aggregate state changes of the services that are under management. Users
- * that need to listen to more fine-grained events (such as when each particular
- * {@link Service service} starts, or terminates), should attach {@link Service.Listener service
- * listeners} to each individual service.
- *
- * @author Luke Sandberg
- * @since 14.0
- */
- @Beta // Should come out of Beta when ServiceManager does
- public static interface Listener {
- /**
- * Called when the service initially becomes healthy.
- *
- * <p>This will be called at most once after all the services have entered the
- * {@linkplain State#RUNNING running} state. If any services fail during start up or
- * {@linkplain State#FAILED fail}/{@linkplain State#TERMINATED terminate} before all other
- * services have started {@linkplain State#RUNNING running} then this method will not be called.
- */
- void healthy();
-
- /**
- * Called when the all of the component services have reached a terminal state, either
- * {@linkplain State#TERMINATED terminated} or {@linkplain State#FAILED failed}.
- */
- void stopped();
-
- /**
- * Called when a component service has {@linkplain State#FAILED failed}.
- *
- * @param service The service that failed.
- */
- void failure(Service service);
- }
-
- /**
- * An encapsulation of all of the state that is accessed by the {@linkplain ServiceListener
- * service listeners}. This is extracted into its own object so that {@link ServiceListener}
- * could be made {@code static} and its instances can be safely constructed and added in the
- * {@link ServiceManager} constructor without having to close over the partially constructed
- * {@link ServiceManager} instance (i.e. avoid leaking a pointer to {@code this}).
- */
- private final ServiceManagerState state;
- private final ImmutableMap<Service, ServiceListener> services;
-
- /**
- * Constructs a new instance for managing the given services.
- *
- * @param services The services to manage
- *
- * @throws IllegalArgumentException if not all services are {@link State#NEW new} or if there are
- * any duplicate services.
- */
- public ServiceManager(Iterable<? extends Service> services) {
- ImmutableList<Service> copy = ImmutableList.copyOf(services);
- this.state = new ServiceManagerState(copy.size());
- ImmutableMap.Builder<Service, ServiceListener> builder = ImmutableMap.builder();
- Executor executor = MoreExecutors.sameThreadExecutor();
- for (Service service : copy) {
- ServiceListener listener = new ServiceListener(service, state);
- service.addListener(listener, executor);
- // We check the state after adding the listener as a way to ensure that our listener was added
- // to a NEW service.
- checkArgument(service.state() == State.NEW, "Can only manage NEW services, %s", service);
- builder.put(service, listener);
- }
- this.services = builder.build();
- }
-
- /**
- * Constructs a new instance for managing the given services. This constructor is provided so that
- * dependency injection frameworks can inject instances of {@link ServiceManager}.
- *
- * @param services The services to manage
- *
- * @throws IllegalStateException if not all services are {@link State#NEW new}.
- */
- @Inject ServiceManager(Set<Service> services) {
- this((Iterable<Service>) services);
- }
-
- /**
- * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given
- * executor. The listener will not have previous state changes replayed, so it is
- * suggested that listeners are added before any of the managed services are
- * {@linkplain Service#start started}.
- *
- * <p>There is no guaranteed ordering of execution of listeners, but any listener added through
- * this method is guaranteed to be called whenever there is a state change.
- *
- * <p>Exceptions thrown by a listener will be propagated up to the executor. Any exception thrown
- * during {@code Executor.execute} (e.g., a {@code RejectedExecutionException} or an exception
- * thrown by {@linkplain MoreExecutors#sameThreadExecutor inline execution}) will be caught and
- * logged.
- *
- * @param listener the listener to run when the manager changes state
- * @param executor the executor in which the the listeners callback methods will be run. For fast,
- * lightweight listeners that would be safe to execute in any thread, consider
- * {@link MoreExecutors#sameThreadExecutor}.
- */
- public void addListener(Listener listener, Executor executor) {
- state.addListener(listener, executor);
- }
-
- /**
- * Initiates service {@linkplain Service#start startup} on all the services being managed. It is
- * only valid to call this method if all of the services are {@linkplain State#NEW new}.
- *
- * @return this
- * @throws IllegalStateException if any of the Services are not {@link State#NEW new} when the
- * method is called, {@link State#TERMINATED terminated} or {@link State#FAILED failed}.
- */
- public ServiceManager startAsync() {
- for (Map.Entry<Service, ServiceListener> entry : services.entrySet()) {
- Service service = entry.getKey();
- State state = service.state();
- checkState(state == State.NEW, "Service %s is %s, cannot start it.", service,
- state);
- }
- for (ServiceListener service : services.values()) {
- service.start();
- }
- return this;
- }
-
- /**
- * Waits for the {@link ServiceManager} to become {@linkplain #isHealthy() healthy}. The manager
- * will become healthy after all the component services have reached the {@linkplain State#RUNNING
- * running} state.
- *
- * @throws IllegalStateException if the service manager reaches a state from which it cannot
- * become {@linkplain #isHealthy() healthy}.
- */
- public void awaitHealthy() {
- state.awaitHealthy();
- checkState(isHealthy(), "Expected to be healthy after starting");
- }
-
- /**
- * Waits for the {@link ServiceManager} to become {@linkplain #isHealthy() healthy} for no more
- * than the given time. The manager will become healthy after all the component services have
- * reached the {@linkplain State#RUNNING running} state.
- *
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @throws TimeoutException if not all of the services have finished starting within the deadline
- * @throws IllegalStateException if the service manager reaches a state from which it cannot
- * become {@linkplain #isHealthy() healthy}.
- */
- public void awaitHealthy(long timeout, TimeUnit unit) throws TimeoutException {
- if (!state.awaitHealthy(timeout, unit)) {
- // It would be nice to tell the caller who we are still waiting on, and this information is
- // likely to be in servicesByState(), however due to race conditions we can't actually tell
- // which services are holding up healthiness. The current set of NEW or STARTING services is
- // likely to point out the culprit, but may not. If we really wanted to solve this we could
- // change state to track exactly which services have started and then we could accurately
- // report on this. But it is only for logging so we likely don't care.
- throw new TimeoutException("Timeout waiting for the services to become healthy.");
- }
- checkState(isHealthy(), "Expected to be healthy after starting");
- }
-
- /**
- * Initiates service {@linkplain Service#stop shutdown} if necessary on all the services being
- * managed.
- *
- * @return this
- */
- public ServiceManager stopAsync() {
- for (Service service : services.keySet()) {
- service.stop();
- }
- return this;
- }
-
- /**
- * Waits for the all the services to reach a terminal state. After this method returns all
- * services will either be {@link Service.State#TERMINATED terminated} or
- * {@link Service.State#FAILED failed}
- */
- public void awaitStopped() {
- state.awaitStopped();
- }
-
- /**
- * Waits for the all the services to reach a terminal state for no more than the given time. After
- * this method returns all services will either be {@link Service.State#TERMINATED terminated} or
- * {@link Service.State#FAILED failed}
- *
- * @param timeout the maximum time to wait
- * @param unit the time unit of the timeout argument
- * @throws TimeoutException if not all of the services have stopped within the deadline
- */
- public void awaitStopped(long timeout, TimeUnit unit) throws TimeoutException {
- if (!state.awaitStopped(timeout, unit)) {
- throw new TimeoutException("Timeout waiting for the services to stop.");
- }
- }
-
- /**
- * Returns true if all services are currently in the {@linkplain State#RUNNING running} state.
- *
- * <p>Users who want more detailed information should use the {@link #servicesByState} method to
- * get detailed information about which services are not running.
- */
- public boolean isHealthy() {
- for (Service service : services.keySet()) {
- if (!service.isRunning()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Provides a snapshot of the current state of all the services under management.
- *
- * <p>N.B. This snapshot it not guaranteed to be consistent, i.e. the set of states returned may
- * not correspond to any particular point in time view of the services.
- */
- public ImmutableMultimap<State, Service> servicesByState() {
- ImmutableMultimap.Builder<State, Service> builder = ImmutableMultimap.builder();
- for (Service service : services.keySet()) {
- builder.put(service.state(), service);
- }
- return builder.build();
- }
-
- /**
- * Returns the service load times. This value will only return startup times for services that
- * have finished starting.
- *
- * @return Map of services and their corresponding startup time in millis, the map entries will be
- * ordered by startup time.
- */
- public ImmutableMap<Service, Long> startupTimes() {
- Map<Service, Long> loadTimeMap = Maps.newHashMapWithExpectedSize(services.size());
- for (Map.Entry<Service, ServiceListener> entry : services.entrySet()) {
- State state = entry.getKey().state();
- if (state != State.NEW && state != State.STARTING) {
- loadTimeMap.put(entry.getKey(), entry.getValue().startupTimeMillis());
- }
- }
- List<Entry<Service, Long>> servicesByStartTime = Ordering.<Long>natural()
- .onResultOf(new Function<Map.Entry<Service, Long>, Long>() {
- @Override public Long apply(Map.Entry<Service, Long> input) {
- return input.getValue();
- }
- })
- .sortedCopy(loadTimeMap.entrySet());
- ImmutableMap.Builder<Service, Long> builder = ImmutableMap.builder();
- for (Map.Entry<Service, Long> entry : servicesByStartTime) {
- builder.put(entry);
- }
- return builder.build();
- }
-
- @Override public String toString() {
- return Objects.toStringHelper(ServiceManager.class)
- .add("services", services.keySet())
- .toString();
- }
-
- /**
- * An encapsulation of all the mutable state of the {@link ServiceManager} that needs to be
- * accessed by instances of {@link ServiceListener}.
- */
- private static final class ServiceManagerState {
- final Monitor monitor = new Monitor();
- final int numberOfServices;
- /** The number of services that have not finished starting up. */
- @GuardedBy("monitor")
- int unstartedServices;
- /** The number of services that have not reached a terminal state. */
- @GuardedBy("monitor")
- int unstoppedServices;
- /**
- * Controls how long to wait for all the service manager to either become healthy or reach a
- * state where it is guaranteed that it can never become healthy.
- */
- final Monitor.Guard awaitHealthGuard = new Monitor.Guard(monitor) {
- @Override public boolean isSatisfied() {
- // All services have started or some service has terminated/failed.
- return unstartedServices == 0 || unstoppedServices != numberOfServices;
- }
- };
- /**
- * Controls how long to wait for all services to reach a terminal state.
- */
- final Monitor.Guard stoppedGuard = new Monitor.Guard(monitor) {
- @Override public boolean isSatisfied() {
- return unstoppedServices == 0;
- }
- };
- /** The listeners to notify during a state transition. */
- @GuardedBy("monitor")
- final List<ListenerExecutorPair> listeners = Lists.newArrayList();
- /**
- * The queue of listeners that are waiting to be executed.
- *
- * <p>Enqueue operations should be protected by {@link #monitor} while dequeue operations should
- * be protected by the implicit lock on this object. This is to ensure that listeners are
- * executed in the correct order and also so that a listener can not hold the {@link #monitor}
- * for an arbitrary amount of time (listeners can only block other listeners, not internal state
- * transitions). We use a concurrent queue implementation so that enqueues can be executed
- * concurrently with dequeues.
- */
- @GuardedBy("queuedListeners")
- final Queue<Runnable> queuedListeners = Queues.newConcurrentLinkedQueue();
-
- ServiceManagerState(int numberOfServices) {
- this.numberOfServices = numberOfServices;
- this.unstoppedServices = numberOfServices;
- this.unstartedServices = numberOfServices;
- }
-
- void addListener(Listener listener, Executor executor) {
- checkNotNull(listener, "listener");
- checkNotNull(executor, "executor");
- monitor.enter();
- try {
- // no point in adding a listener that will never be called
- if (unstartedServices > 0 || unstoppedServices > 0) {
- listeners.add(new ListenerExecutorPair(listener, executor));
- }
- } finally {
- monitor.leave();
- }
- }
-
- void awaitHealthy() {
- monitor.enter();
- try {
- monitor.waitForUninterruptibly(awaitHealthGuard);
- } finally {
- monitor.leave();
- }
- }
-
- boolean awaitHealthy(long timeout, TimeUnit unit) {
- monitor.enter();
- try {
- if (monitor.waitForUninterruptibly(awaitHealthGuard, timeout, unit)) {
- return true;
- }
- return false;
- } finally {
- monitor.leave();
- }
- }
-
- void awaitStopped() {
- monitor.enter();
- try {
- monitor.waitForUninterruptibly(stoppedGuard);
- } finally {
- monitor.leave();
- }
- }
-
- boolean awaitStopped(long timeout, TimeUnit unit) {
- monitor.enter();
- try {
- return monitor.waitForUninterruptibly(stoppedGuard, timeout, unit);
- } finally {
- monitor.leave();
- }
- }
-
- /**
- * This should be called when a service finishes starting up.
- *
- * @param currentlyHealthy whether or not the service that finished starting was healthy at the
- * time that it finished starting.
- */
- @GuardedBy("monitor")
- private void serviceFinishedStarting(Service service, boolean currentlyHealthy) {
- checkState(unstartedServices > 0,
- "All services should have already finished starting but %s just finished.", service);
- unstartedServices--;
- if (currentlyHealthy && unstartedServices == 0 && unstoppedServices == numberOfServices) {
- // This means that the manager is currently healthy, or at least it should have been
- // healthy at some point from some perspective. Calling isHealthy is not currently
- // guaranteed to return true because any service could fail right now. However, the
- // happens-before relationship enforced by the monitor ensures that this method was called
- // before either serviceTerminated or serviceFailed, so we know that the manager was at
- // least healthy for some period of time. Furthermore we are guaranteed that this call to
- // healthy() will be before any call to terminated() or failure(Service) on the listener.
- // So it is correct to execute the listener's health() callback.
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.healthy();
- }
- });
- }
- });
- }
- }
- }
-
- /**
- * This should be called when a service is {@linkplain State#TERMINATED terminated}.
- */
- @GuardedBy("monitor")
- private void serviceTerminated(Service service) {
- serviceStopped(service);
- }
-
- /**
- * This should be called when a service is {@linkplain State#FAILED failed}.
- */
- @GuardedBy("monitor")
- private void serviceFailed(final Service service) {
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.failure(service);
- }
- });
- }
- });
- }
- serviceStopped(service);
- }
-
- /**
- * Should be called whenever a service reaches a terminal state (
- * {@linkplain State#TERMINATED terminated} or
- * {@linkplain State#FAILED failed}).
- */
- @GuardedBy("monitor")
- private void serviceStopped(Service service) {
- checkState(unstoppedServices > 0,
- "All services should have already stopped but %s just stopped.", service);
- unstoppedServices--;
- if (unstoppedServices == 0) {
- checkState(unstartedServices == 0,
- "All services are stopped but %d services haven't finished starting",
- unstartedServices);
- for (final ListenerExecutorPair pair : listeners) {
- queuedListeners.add(new Runnable() {
- @Override public void run() {
- pair.execute(new Runnable() {
- @Override public void run() {
- pair.listener.stopped();
- }
- });
- }
- });
- }
- // no more listeners could possibly be called, so clear them out
- listeners.clear();
- }
- }
-
- /**
- * Attempts to execute all the listeners in {@link #queuedListeners}.
- */
- private void executeListeners() {
- checkState(!monitor.isOccupiedByCurrentThread(),
- "It is incorrect to execute listeners with the monitor held.");
- synchronized (queuedListeners) {
- Runnable listener;
- while ((listener = queuedListeners.poll()) != null) {
- listener.run();
- }
- }
- }
- }
-
- /**
- * A {@link Service} that wraps another service and times how long it takes for it to start and
- * also calls the {@link ServiceManagerState#serviceFinishedStarting},
- * {@link ServiceManagerState#serviceTerminated} and {@link ServiceManagerState#serviceFailed}
- * according to its current state.
- */
- private static final class ServiceListener implements Service.Listener {
- @GuardedBy("watch") // AFAICT Stopwatch is not thread safe so we need to protect accesses
- final Stopwatch watch = new Stopwatch();
- final Service service;
- final ServiceManagerState state;
-
- /**
- * @param service the service that
- */
- ServiceListener(Service service, ServiceManagerState state) {
- this.service = service;
- this.state = state;
- }
-
- @Override public void starting() {
- // This can happen if someone besides the ServiceManager starts the service, in this case
- // our timings may be inaccurate.
- startTimer();
- }
-
- @Override public void running() {
- state.monitor.enter();
- try {
- finishedStarting(true);
- } finally {
- state.monitor.leave();
- state.executeListeners();
- }
- }
-
- @Override public void stopping(State from) {
- if (from == State.STARTING) {
- state.monitor.enter();
- try {
- finishedStarting(false);
- } finally {
- state.monitor.leave();
- state.executeListeners();
- }
- }
- }
-
- @Override public void terminated(State from) {
- logger.info("Service " + service + " has terminated. Previous state was " + from + " state.");
- state.monitor.enter();
- try {
- if (from == State.NEW) {
- // startTimer is idempotent, so this is safe to call and it may be necessary if no one has
- // started the timer yet.
- startTimer();
- finishedStarting(false);
- }
- state.serviceTerminated(service);
- } finally {
- state.monitor.leave();
- state.executeListeners();
- }
- }
-
- @Override public void failed(State from, Throwable failure) {
- logger.log(Level.SEVERE, "Service " + service + " has failed in the " + from + " state.",
- failure);
- state.monitor.enter();
- try {
- if (from == State.STARTING) {
- finishedStarting(false);
- }
- state.serviceFailed(service);
- } finally {
- state.monitor.leave();
- state.executeListeners();
- }
- }
-
- /**
- * Stop the stopwatch, log the startup time and decrement the startup latch
- *
- * @param currentlyHealthy whether or not the service that finished starting is currently
- * healthy
- */
- @GuardedBy("monitor")
- void finishedStarting(boolean currentlyHealthy) {
- synchronized (watch) {
- watch.stop();
- logger.log(Level.INFO, "Started " + service + " in " + startupTimeMillis() + " ms.");
- }
- state.serviceFinishedStarting(service, currentlyHealthy);
- }
-
- void start() {
- startTimer();
- service.start();
- }
-
- /** Start the timer if it hasn't been started. */
- void startTimer() {
- synchronized (watch) {
- if (!watch.isRunning()) { // only start the watch once.
- watch.start();
- logger.log(Level.INFO, "Starting {0}", service);
- }
- }
- }
-
- /** Returns the amount of time it took for the service to finish starting in milliseconds. */
- synchronized long startupTimeMillis() {
- synchronized (watch) {
- return watch.elapsed(MILLISECONDS);
- }
- }
- }
-
- /** Simple value object binding a listener to its executor. */
- @Immutable private static final class ListenerExecutorPair {
- final Listener listener;
- final Executor executor;
-
- ListenerExecutorPair(Listener listener, Executor executor) {
- this.listener = listener;
- this.executor = executor;
- }
-
- /**
- * Executes the given {@link Runnable} on {@link #executor} logging and swallowing all
- * exceptions
- */
- void execute(Runnable runnable) {
- try {
- executor.execute(runnable);
- } catch (Exception e) {
- logger.log(Level.SEVERE, "Exception while executing listener " + listener
- + " with executor " + executor, e);
- }
- }
- }
-}
diff --git a/guava/src/com/google/common/util/concurrent/Striped.java b/guava/src/com/google/common/util/concurrent/Striped.java
deleted file mode 100644
index 3c426f0..0000000
--- a/guava/src/com/google/common/util/concurrent/Striped.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.util.concurrent;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Functions;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.MapMaker;
-import com.google.common.math.IntMath;
-import com.google.common.primitives.Ints;
-
-import java.math.RoundingMode;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * A striped {@code Lock/Semaphore/ReadWriteLock}. This offers the underlying lock striping
- * similar to that of {@code ConcurrentHashMap} in a reusable form, and extends it for
- * semaphores and read-write locks. Conceptually, lock striping is the technique of dividing a lock
- * into many <i>stripes</i>, increasing the granularity of a single lock and allowing independent
- * operations to lock different stripes and proceed concurrently, instead of creating contention
- * for a single lock.
- *
- * <p>The guarantee provided by this class is that equal keys lead to the same lock (or semaphore),
- * i.e. {@code if (key1.equals(key2))} then {@code striped.get(key1) == striped.get(key2)}
- * (assuming {@link Object#hashCode()} is correctly implemented for the keys). Note
- * that if {@code key1} is <strong>not</strong> equal to {@code key2}, it is <strong>not</strong>
- * guaranteed that {@code striped.get(key1) != striped.get(key2)}; the elements might nevertheless
- * be mapped to the same lock. The lower the number of stripes, the higher the probability of this
- * happening.
- *
- * <p>There are three flavors of this class: {@code Striped<Lock>}, {@code Striped<Semaphore>},
- * and {@code Striped<ReadWriteLock>}. For each type, two implementations are offered:
- * {@linkplain #lock(int) strong} and {@linkplain #lazyWeakLock(int) weak}
- * {@code Striped<Lock>}, {@linkplain #semaphore(int, int) strong} and {@linkplain
- * #lazyWeakSemaphore(int, int) weak} {@code Striped<Semaphore>}, and {@linkplain
- * #readWriteLock(int) strong} and {@linkplain #lazyWeakReadWriteLock(int) weak}
- * {@code Striped<ReadWriteLock>}. <i>Strong</i> means that all stripes (locks/semaphores) are
- * initialized eagerly, and are not reclaimed unless {@code Striped} itself is reclaimable.
- * <i>Weak</i> means that locks/semaphores are created lazily, and they are allowed to be reclaimed
- * if nobody is holding on to them. This is useful, for example, if one wants to create a {@code
- * Striped<Lock>} of many locks, but worries that in most cases only a small portion of these
- * would be in use.
- *
- * <p>Prior to this class, one might be tempted to use {@code Map<K, Lock>}, where {@code K}
- * represents the task. This maximizes concurrency by having each unique key mapped to a unique
- * lock, but also maximizes memory footprint. On the other extreme, one could use a single lock
- * for all tasks, which minimizes memory footprint but also minimizes concurrency. Instead of
- * choosing either of these extremes, {@code Striped} allows the user to trade between required
- * concurrency and memory footprint. For example, if a set of tasks are CPU-bound, one could easily
- * create a very compact {@code Striped<Lock>} of {@code availableProcessors() * 4} stripes,
- * instead of possibly thousands of locks which could be created in a {@code Map<K, Lock>}
- * structure.
- *
- * @author Dimitris Andreou
- * @since 13.0
- */
-@Beta
-public abstract class Striped<L> {
- private Striped() {}
-
- /**
- * Returns the stripe that corresponds to the passed key. It is always guaranteed that if
- * {@code key1.equals(key2)}, then {@code get(key1) == get(key2)}.
- *
- * @param key an arbitrary, non-null key
- * @return the stripe that the passed key corresponds to
- */
- public abstract L get(Object key);
-
- /**
- * Returns the stripe at the specified index. Valid indexes are 0, inclusively, to
- * {@code size()}, exclusively.
- *
- * @param index the index of the stripe to return; must be in {@code [0...size())}
- * @return the stripe at the specified index
- */
- public abstract L getAt(int index);
-
- /**
- * Returns the index to which the given key is mapped, so that getAt(indexFor(key)) == get(key).
- */
- abstract int indexFor(Object key);
-
- /**
- * Returns the total number of stripes in this instance.
- */
- public abstract int size();
-
- /**
- * Returns the stripes that correspond to the passed objects, in ascending (as per
- * {@link #getAt(int)}) order. Thus, threads that use the stripes in the order returned
- * by this method are guaranteed to not deadlock each other.
- *
- * <p>It should be noted that using a {@code Striped<L>} with relatively few stripes, and
- * {@code bulkGet(keys)} with a relative large number of keys can cause an excessive number
- * of shared stripes (much like the birthday paradox, where much fewer than anticipated birthdays
- * are needed for a pair of them to match). Please consider carefully the implications of the
- * number of stripes, the intended concurrency level, and the typical number of keys used in a
- * {@code bulkGet(keys)} operation. See <a href="http://www.mathpages.com/home/kmath199.htm">Balls
- * in Bins model</a> for mathematical formulas that can be used to estimate the probability of
- * collisions.
- *
- * @param keys arbitrary non-null keys
- * @return the stripes corresponding to the objects (one per each object, derived by delegating
- * to {@link #get(Object)}; may contain duplicates), in an increasing index order.
- */
- public Iterable<L> bulkGet(Iterable<?> keys) {
- // Initially using the array to store the keys, then reusing it to store the respective L's
- final Object[] array = Iterables.toArray(keys, Object.class);
- int[] stripes = new int[array.length];
- for (int i = 0; i < array.length; i++) {
- stripes[i] = indexFor(array[i]);
- }
- Arrays.sort(stripes);
- for (int i = 0; i < array.length; i++) {
- array[i] = getAt(stripes[i]);
- }
- /*
- * Note that the returned Iterable holds references to the returned stripes, to avoid
- * error-prone code like:
- *
- * Striped<Lock> stripedLock = Striped.lazyWeakXXX(...)'
- * Iterable<Lock> locks = stripedLock.bulkGet(keys);
- * for (Lock lock : locks) {
- * lock.lock();
- * }
- * operation();
- * for (Lock lock : locks) {
- * lock.unlock();
- * }
- *
- * If we only held the int[] stripes, translating it on the fly to L's, the original locks
- * might be garbage collected after locking them, ending up in a huge mess.
- */
- @SuppressWarnings("unchecked") // we carefully replaced all keys with their respective L's
- List<L> asList = (List<L>) Arrays.asList(array);
- return Collections.unmodifiableList(asList);
- }
-
- // Static factories
-
- /**
- * Creates a {@code Striped<Lock>} with eagerly initialized, strongly referenced locks, with the
- * specified fairness. Every lock is reentrant.
- *
- * @param stripes the minimum number of stripes (locks) required
- * @return a new {@code Striped<Lock>}
- */
- public static Striped<Lock> lock(int stripes) {
- return new CompactStriped<Lock>(stripes, new Supplier<Lock>() {
- public Lock get() {
- return new PaddedLock();
- }
- });
- }
-
- /**
- * Creates a {@code Striped<Lock>} with lazily initialized, weakly referenced locks, with the
- * specified fairness. Every lock is reentrant.
- *
- * @param stripes the minimum number of stripes (locks) required
- * @return a new {@code Striped<Lock>}
- */
- public static Striped<Lock> lazyWeakLock(int stripes) {
- return new LazyStriped<Lock>(stripes, new Supplier<Lock>() {
- public Lock get() {
- return new ReentrantLock(false);
- }
- });
- }
-
- /**
- * Creates a {@code Striped<Semaphore>} with eagerly initialized, strongly referenced semaphores,
- * with the specified number of permits and fairness.
- *
- * @param stripes the minimum number of stripes (semaphores) required
- * @param permits the number of permits in each semaphore
- * @return a new {@code Striped<Semaphore>}
- */
- public static Striped<Semaphore> semaphore(int stripes, final int permits) {
- return new CompactStriped<Semaphore>(stripes, new Supplier<Semaphore>() {
- public Semaphore get() {
- return new PaddedSemaphore(permits);
- }
- });
- }
-
- /**
- * Creates a {@code Striped<Semaphore>} with lazily initialized, weakly referenced semaphores,
- * with the specified number of permits and fairness.
- *
- * @param stripes the minimum number of stripes (semaphores) required
- * @param permits the number of permits in each semaphore
- * @return a new {@code Striped<Semaphore>}
- */
- public static Striped<Semaphore> lazyWeakSemaphore(int stripes, final int permits) {
- return new LazyStriped<Semaphore>(stripes, new Supplier<Semaphore>() {
- public Semaphore get() {
- return new Semaphore(permits, false);
- }
- });
- }
-
- /**
- * Creates a {@code Striped<ReadWriteLock>} with eagerly initialized, strongly referenced
- * read-write locks, with the specified fairness. Every lock is reentrant.
- *
- * @param stripes the minimum number of stripes (locks) required
- * @return a new {@code Striped<ReadWriteLock>}
- */
- public static Striped<ReadWriteLock> readWriteLock(int stripes) {
- return new CompactStriped<ReadWriteLock>(stripes, READ_WRITE_LOCK_SUPPLIER);
- }
-
- /**
- * Creates a {@code Striped<ReadWriteLock>} with lazily initialized, weakly referenced
- * read-write locks, with the specified fairness. Every lock is reentrant.
- *
- * @param stripes the minimum number of stripes (locks) required
- * @return a new {@code Striped<ReadWriteLock>}
- */
- public static Striped<ReadWriteLock> lazyWeakReadWriteLock(int stripes) {
- return new LazyStriped<ReadWriteLock>(stripes, READ_WRITE_LOCK_SUPPLIER);
- }
-
- // ReentrantReadWriteLock is large enough to make padding probably unnecessary
- private static final Supplier<ReadWriteLock> READ_WRITE_LOCK_SUPPLIER =
- new Supplier<ReadWriteLock>() {
- public ReadWriteLock get() {
- return new ReentrantReadWriteLock();
- }
- };
-
- private abstract static class PowerOfTwoStriped<L> extends Striped<L> {
- /** Capacity (power of two) minus one, for fast mod evaluation */
- final int mask;
-
- PowerOfTwoStriped(int stripes) {
- Preconditions.checkArgument(stripes > 0, "Stripes must be positive");
- this.mask = stripes > Ints.MAX_POWER_OF_TWO ? ALL_SET : ceilToPowerOfTwo(stripes) - 1;
- }
-
- @Override final int indexFor(Object key) {
- int hash = smear(key.hashCode());
- return hash & mask;
- }
-
- @Override public final L get(Object key) {
- return getAt(indexFor(key));
- }
- }
-
- /**
- * Implementation of Striped where 2^k stripes are represented as an array of the same length,
- * eagerly initialized.
- */
- private static class CompactStriped<L> extends PowerOfTwoStriped<L> {
- /** Size is a power of two. */
- private final Object[] array;
-
- private CompactStriped(int stripes, Supplier<L> supplier) {
- super(stripes);
- Preconditions.checkArgument(stripes <= Ints.MAX_POWER_OF_TWO, "Stripes must be <= 2^30)");
-
- this.array = new Object[mask + 1];
- for (int i = 0; i < array.length; i++) {
- array[i] = supplier.get();
- }
- }
-
- @SuppressWarnings("unchecked") // we only put L's in the array
- @Override public L getAt(int index) {
- return (L) array[index];
- }
-
- @Override public int size() {
- return array.length;
- }
- }
-
- /**
- * Implementation of Striped where up to 2^k stripes can be represented, using a Cache
- * where the key domain is [0..2^k). To map a user key into a stripe, we take a k-bit slice of the
- * user key's (smeared) hashCode(). The stripes are lazily initialized and are weakly referenced.
- */
- private static class LazyStriped<L> extends PowerOfTwoStriped<L> {
- final ConcurrentMap<Integer, L> cache;
- final int size;
-
- LazyStriped(int stripes, Supplier<L> supplier) {
- super(stripes);
- this.size = (mask == ALL_SET) ? Integer.MAX_VALUE : mask + 1;
- this.cache = new MapMaker().weakValues().makeComputingMap(Functions.forSupplier(supplier));
- }
-
- @Override public L getAt(int index) {
- Preconditions.checkElementIndex(index, size());
- return cache.get(index);
- }
-
- @Override public int size() {
- return size;
- }
- }
-
- /**
- * A bit mask were all bits are set.
- */
- private static final int ALL_SET = ~0;
-
- private static int ceilToPowerOfTwo(int x) {
- return 1 << IntMath.log2(x, RoundingMode.CEILING);
- }
-
- /*
- * This method was written by Doug Lea with assistance from members of JCP
- * JSR-166 Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
- *
- * As of 2010/06/11, this method is identical to the (package private) hash
- * method in OpenJDK 7's java.util.HashMap class.
- */
- // Copied from java/com/google/common/collect/Hashing.java
- private static int smear(int hashCode) {
- hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12);
- return hashCode ^ (hashCode >>> 7) ^ (hashCode >>> 4);
- }
-
- private static class PaddedLock extends ReentrantLock {
- /*
- * Padding from 40 into 64 bytes, same size as cache line. Might be beneficial to add
- * a fourth long here, to minimize chance of interference between consecutive locks,
- * but I couldn't observe any benefit from that.
- */
- @SuppressWarnings("unused")
- long q1, q2, q3;
-
- PaddedLock() {
- super(false);
- }
- }
-
- private static class PaddedSemaphore extends Semaphore {
- // See PaddedReentrantLock comment
- @SuppressWarnings("unused")
- long q1, q2, q3;
-
- PaddedSemaphore(int permits) {
- super(permits, false);
- }
- }
-}
diff --git a/guava/src/com/google/common/util/concurrent/ThreadFactoryBuilder.java b/guava/src/com/google/common/util/concurrent/ThreadFactoryBuilder.java
index a05247e..167ad11 100644
--- a/guava/src/com/google/common/util/concurrent/ThreadFactoryBuilder.java
+++ b/guava/src/com/google/common/util/concurrent/ThreadFactoryBuilder.java
@@ -61,12 +61,9 @@ public final class ThreadFactoryBuilder {
* @param nameFormat a {@link String#format(String, Object...)}-compatible
* format String, to which a unique integer (0, 1, etc.) will be supplied
* as the single parameter. This integer will be unique to the built
- * instance of the ThreadFactory and will be assigned sequentially. For
- * example, {@code "rpc-pool-%d"} will generate thread names like
- * {@code "rpc-pool-0"}, {@code "rpc-pool-1"}, {@code "rpc-pool-2"}, etc.
+ * instance of the ThreadFactory and will be assigned sequentially.
* @return this for the builder pattern
*/
- @SuppressWarnings("ReturnValueIgnored")
public ThreadFactoryBuilder setNameFormat(String nameFormat) {
String.format(nameFormat, 0); // fail fast if the format is bad or null
this.nameFormat = nameFormat;
diff --git a/guava/src/com/google/common/util/concurrent/UncheckedExecutionException.java b/guava/src/com/google/common/util/concurrent/UncheckedExecutionException.java
index 77afdc3..c0c99e1 100644
--- a/guava/src/com/google/common/util/concurrent/UncheckedExecutionException.java
+++ b/guava/src/com/google/common/util/concurrent/UncheckedExecutionException.java
@@ -16,10 +16,9 @@
package com.google.common.util.concurrent;
+import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
-import javax.annotation.Nullable;
-
/**
* Unchecked variant of {@link java.util.concurrent.ExecutionException}. As with
* {@code ExecutionException}, the exception's {@linkplain #getCause() cause}
@@ -27,16 +26,17 @@ import javax.annotation.Nullable;
*
* <p>{@code UncheckedExecutionException} is intended as an alternative to
* {@code ExecutionException} when the exception thrown by a task is an
- * unchecked exception. However, it may also wrap a checked exception in some
- * cases.
+ * unchecked exception. This allows the client code to continue to distinguish
+ * between checked and unchecked exceptions, even when they come from other
+ * threads.
*
* <p>When wrapping an {@code Error} from another thread, prefer {@link
- * ExecutionError}. When wrapping a checked exception, prefer {@code
- * ExecutionException}.
+ * ExecutionError}.
*
* @author Charles Fry
* @since 10.0
*/
+@Beta
@GwtCompatible
public class UncheckedExecutionException extends RuntimeException {
/**
@@ -47,21 +47,21 @@ public class UncheckedExecutionException extends RuntimeException {
/**
* Creates a new instance with the given detail message.
*/
- protected UncheckedExecutionException(@Nullable String message) {
+ protected UncheckedExecutionException(String message) {
super(message);
}
/**
* Creates a new instance with the given detail message and cause.
*/
- public UncheckedExecutionException(@Nullable String message, @Nullable Throwable cause) {
+ public UncheckedExecutionException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a new instance with the given cause.
*/
- public UncheckedExecutionException(@Nullable Throwable cause) {
+ public UncheckedExecutionException(Throwable cause) {
super(cause);
}
diff --git a/guava/src/com/google/common/util/concurrent/UncheckedTimeoutException.java b/guava/src/com/google/common/util/concurrent/UncheckedTimeoutException.java
index cefe379..d821c84 100644
--- a/guava/src/com/google/common/util/concurrent/UncheckedTimeoutException.java
+++ b/guava/src/com/google/common/util/concurrent/UncheckedTimeoutException.java
@@ -16,8 +16,6 @@
package com.google.common.util.concurrent;
-import javax.annotation.Nullable;
-
/**
* Unchecked version of {@link java.util.concurrent.TimeoutException}.
*
@@ -27,15 +25,15 @@ import javax.annotation.Nullable;
public class UncheckedTimeoutException extends RuntimeException {
public UncheckedTimeoutException() {}
- public UncheckedTimeoutException(@Nullable String message) {
+ public UncheckedTimeoutException(String message) {
super(message);
}
- public UncheckedTimeoutException(@Nullable Throwable cause) {
+ public UncheckedTimeoutException(Throwable cause) {
super(cause);
}
- public UncheckedTimeoutException(@Nullable String message, @Nullable Throwable cause) {
+ public UncheckedTimeoutException(String message, Throwable cause) {
super(message, cause);
}
diff --git a/guava/src/com/google/common/util/concurrent/Uninterruptibles.java b/guava/src/com/google/common/util/concurrent/Uninterruptibles.java
index 79d7598..89f30b8 100644
--- a/guava/src/com/google/common/util/concurrent/Uninterruptibles.java
+++ b/guava/src/com/google/common/util/concurrent/Uninterruptibles.java
@@ -122,9 +122,6 @@ public final class Uninterruptibles {
* <p>If instead, you wish to treat {@link InterruptedException} uniformly
* with other exceptions, see {@link Futures#get(Future, Class) Futures.get}
* or {@link Futures#makeChecked}.
- *
- * @throws ExecutionException if the computation threw an exception
- * @throws CancellationException if the computation was cancelled
*/
public static <V> V getUninterruptibly(Future<V> future)
throws ExecutionException {
@@ -152,10 +149,6 @@ public final class Uninterruptibles {
* <p>If instead, you wish to treat {@link InterruptedException} uniformly
* with other exceptions, see {@link Futures#get(Future, Class) Futures.get}
* or {@link Futures#makeChecked}.
- *
- * @throws ExecutionException if the computation threw an exception
- * @throws CancellationException if the computation was cancelled
- * @throws TimeoutException if the wait timed out
*/
public static <V> V getUninterruptibly(
Future<V> future, long timeout, TimeUnit unit)
@@ -233,11 +226,6 @@ public final class Uninterruptibles {
/**
* Invokes {@code queue.}{@link BlockingQueue#put(Object) put(element)}
* uninterruptibly.
- *
- * @throws ClassCastException if the class of the specified element prevents
- * it from being added to the given queue
- * @throws IllegalArgumentException if some property of the specified element
- * prevents it from being added to the given queue
*/
public static <E> void putUninterruptibly(BlockingQueue<E> queue, E element) {
boolean interrupted = false;
diff --git a/guava/src/com/google/common/util/concurrent/package-info.java b/guava/src/com/google/common/util/concurrent/package-info.java
index 6ea5069..6281552 100644
--- a/guava/src/com/google/common/util/concurrent/package-info.java
+++ b/guava/src/com/google/common/util/concurrent/package-info.java
@@ -33,4 +33,3 @@
package com.google.common.util.concurrent;
import javax.annotation.ParametersAreNonnullByDefault;
-
diff --git a/pom.xml b/pom.xml
index 14e4284..774b0d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
@@ -11,13 +11,10 @@
</parent>
<groupId>com.google.guava</groupId>
<artifactId>guava-parent</artifactId>
- <version>14.0.1</version>
+ <version>11.0.2</version>
<packaging>pom</packaging>
<name>Guava Maven Parent</name>
<url>http://code.google.com/p/guava-libraries</url>
- <properties>
- <gpg.skip>true</gpg.skip>
- </properties>
<issueManagement>
<system>code.google.com</system>
<url>http://code.google.com/p/guava-libraries/issues</url>
@@ -31,7 +28,7 @@
</license>
</licenses>
<prerequisites>
- <maven>3.0.3</maven>
+ <maven>2.0.9</maven>
</prerequisites>
<scm>
<connection>scm:git:https://code.google.com/p/guava-libraries/</connection>
@@ -41,7 +38,7 @@
<developers>
<developer>
<id>kevinb9n</id>
- <name>Kevin Bourrillion</name>
+ <name>Kevin Bourillion</name>
<email>kevinb@google.com</email>
<organization>Google</organization>
<organizationUrl>http://www.google.com</organizationUrl>
@@ -54,30 +51,9 @@
</developers>
<modules>
<module>guava</module>
+ <module>guava-bootstrap</module>
<module>guava-gwt</module>
<module>guava-testlib</module>
<module>guava-tests</module>
</modules>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>1.4</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals><goal>sign</goal></goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <distributionManagement>
- <site>
- <id>guava-site</id>
- <name>Guava Documentation Site</name>
- <url>scp://dummy.server/dontinstall/usestaging</url>
- </site>
- </distributionManagement>
</project>