aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-01-04 20:03:24 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-01-04 20:03:24 +0000
commit0a310095af0fa59a8a813c9b8d3f1c0ae615ad09 (patch)
treeab8add0e1979a4e9d6d99310a6450db084168da9
parent2a7ff2090a040021a9b64c553893930dd9b253d0 (diff)
parent5e1bee230f5fdb38b09b4e07f197684c76ec4c85 (diff)
downloadlibcore-aml_ips_341510000.tar.gz
Snap for 11273583 from 5e1bee230f5fdb38b09b4e07f197684c76ec4c85 to mainline-ipsec-releaseaml_ips_341510000
Change-Id: Ibf1f16d68757085dac4545433083d736ffa923ac
-rw-r--r--JavaLibrary.bp7
-rw-r--r--api/current.txt321
-rw-r--r--api/module-lib-current.txt41
-rw-r--r--dalvik/src/main/java/dalvik/system/ZygoteHooks.java16
-rw-r--r--expectations/skippedCtsTest.txt196
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java22
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java16
-rw-r--r--luni/src/main/java/javax/xml/datatype/DatatypeConfigurationException.java4
-rw-r--r--luni/src/main/java/libcore/net/NetworkSecurityPolicy.java1
-rw-r--r--luni/src/test/java/libcore/java/net/SocketTest.java43
-rw-r--r--luni/src/test/java/libcore/java/net/URLConnectionTest.java25
-rw-r--r--luni/src/test/java/libcore/java/nio/CharBufferTest.java8
-rw-r--r--luni/src/test/java/libcore/java/nio/channels/MembershipKeyTest.java23
-rw-r--r--luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java8
-rw-r--r--luni/src/test/java/libcore/java/text/DateFormatTest.java9
-rw-r--r--luni/src/test/java/libcore/java/time/format/DateTimeFormatterBuilderTest.java27
-rw-r--r--luni/src/test/java/libcore/java/util/ArraysTest.java22
-rw-r--r--luni/src/test/java/libcore/java/util/FormatterTest.java14
-rw-r--r--luni/src/test/java/libcore/java/util/LocaleTest.java12
-rw-r--r--luni/src/test/java/libcore/java/util/OptionalLongTest.java45
-rw-r--r--luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java29
-rw-r--r--luni/src/test/java/libcore/java/util/WeakHashMapTest.java113
-rw-r--r--luni/src/test/java/libcore/javax/xml/datatype/DatatypeConfigurationExceptionTest.java37
-rw-r--r--luni/src/test/java/libcore/javax/xml/datatype/DatatypeFactoryTest.java124
-rw-r--r--luni/src/test/java/libcore/javax/xml/datatype/XMLGregorianCalendarTest.java118
-rw-r--r--luni/src/test/java/libcore/javax/xml/parsers/DocumentBuilderTest.java60
-rw-r--r--luni/src/test/java/libcore/javax/xml/validation/SchemaFactoryTest.java139
-rw-r--r--luni/src/test/java/libcore/javax/xml/xpath/XPathExceptionTest.java81
-rw-r--r--luni/src/test/java/libcore/javax/xml/xpath/XPathFactoryTest.java47
-rw-r--r--luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java2
-rw-r--r--luni/src/test/java/tests/security/interfaces/RSAKeyTest.java6
-rw-r--r--luni/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java4
-rw-r--r--luni/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java4
-rw-r--r--luni/src/test/java/tests/security/interfaces/Util.java71
-rw-r--r--mmodules/intracoreapi/api/intra/current.txt1
-rw-r--r--ojluni/src/main/java/java/math/BigInteger.java14
-rw-r--r--ojluni/src/main/java/java/text/MergeCollation.java342
-rw-r--r--ojluni/src/main/java/java/text/PatternEntry.java310
-rw-r--r--ojluni/src/main/java/java/util/PriorityQueue.java34
-rw-r--r--ojluni/src/test/Android.bp2
-rw-r--r--ojluni/src/test/java/math/BigInteger/BigIntegerTest.java23
-rw-r--r--ojluni/src/test/java/math/BigInteger/BitLengthOverflow.java67
-rw-r--r--ojluni/src/test/java/math/BigInteger/DoubleValueOverflow.java52
-rw-r--r--ojluni/src/test/java/math/BigInteger/ExtremeShiftingTests.java75
-rw-r--r--ojluni/src/test/java/math/BigInteger/LargeValueExceptions.java200
-rw-r--r--ojluni/src/test/java/math/BigInteger/ModInvTime.java59
-rw-r--r--ojluni/src/test/java/math/BigInteger/ModPow.java15
-rw-r--r--ojluni/src/test/java/math/BigInteger/ModPow65537.java117
-rw-r--r--ojluni/src/test/java/math/BigInteger/ModPowPowersof2.java96
-rw-r--r--ojluni/src/test/java/math/BigInteger/PrimeTest.java4
-rw-r--r--ojluni/src/test/java/math/BigInteger/SerializationTests.java143
-rw-r--r--ojluni/src/test/java/nio/file/Path/PathOps.java30
-rw-r--r--ojluni/src/test/java/text/AttributedCharacterIterator/Attribute/ReadResolve.java90
-rw-r--r--ojluni/src/test/java/text/AttributedString/AttributedStringTest.java260
-rw-r--r--ojluni/src/test/java/text/AttributedString/TestAttributedStringCtor.java57
-rw-r--r--ojluni/src/test/java/text/AttributedString/getRunStartLimitTest.java118
-rw-r--r--ojluni/src/test/java/text/BreakIterator/Bug4533872.java265
-rw-r--r--ojluni/src/test/java/text/BreakIterator/Bug4740757.java78
-rw-r--r--ojluni/src/test/java/text/BreakIterator/Bug4912404.java43
-rw-r--r--ojluni/src/test/java/text/BreakIterator/Bug4932583.java43
-rw-r--r--ojluni/src/test/java/text/BreakIterator/Bug7104012.java80
-rw-r--r--ojluni/src/test/java/text/BreakIterator/Bug8032446.java58
-rw-r--r--ojluni/src/test/java/text/BreakIterator/ExceptionTest.java156
-rw-r--r--ojluni/src/test/java/text/BreakIterator/MirroredBreakIterator.java168
-rw-r--r--ojluni/src/test/java/text/CharacterIterator/CharacterIteratorTest.java290
-rw-r--r--ojluni/src/test/java/text/Collator/Bug5047314.java86
-rw-r--r--ojluni/src/test/java/text/Collator/Bug7200119.java42
-rw-r--r--ojluni/src/test/java/text/Collator/CollatorTest.java145
-rw-r--r--ojluni/src/test/java/text/Collator/MonkeyTest.java151
-rw-r--r--ojluni/src/test/java/text/Format/ChoiceFormat/Bug4387255.java71
-rw-r--r--ojluni/src/test/java/text/Format/ChoiceFormat/Bug8001209.java92
-rw-r--r--ojluni/src/test/java/text/Format/DateFormat/SimpleDateFormatPatternTest.java231
-rw-r--r--ojluni/src/test/java/text/Format/DecimalFormat/Bug8165466.java97
-rw-r--r--ojluni/src/test/java/text/Format/DecimalFormat/GoldenFormattedValues.java870
-rw-r--r--ojluni/src/test/java/text/Format/DecimalFormat/SetGroupingSizeTest.java76
-rw-r--r--ojluni/src/test/java/text/Format/MessageFormat/Bug6481179.java66
-rw-r--r--ojluni/src/test/java/text/Format/MessageFormat/Bug7003643.java76
-rw-r--r--ojluni/src/test/java/text/Format/MessageFormat/MessageFormatsByArgumentIndex.java117
-rw-r--r--ojluni/src/test/java/text/Format/MessageFormat/MessageRegression.java690
-rw-r--r--ojluni/src/test/java/text/Format/MessageFormat/MessageTest.java106
-rw-r--r--ojluni/src/test/java/text/Format/MessageFormat/bug4492719.java83
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/BigDecimalFormat.java1048
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/BigDecimalParse.java713
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/DFSDeserialization142.java55
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/DFSExponential.java91
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/DFSSerialization142.java55
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/PositionTest.java225
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/SerializationLoadTest.java93
-rw-r--r--ojluni/src/test/java/text/Format/NumberFormat/SerializationSaveTest.java82
-rw-r--r--ojluni/src/test/java/text/testlib/HexDumpReader.java117
-rw-r--r--ojluni/src/test/java/text/testlib/IntlTest.java276
-rw-r--r--ojluni/src/test/java/text/testlib/TestUtils.java76
-rw-r--r--ojluni/src/test/java/util/Arrays/ArrayObjectMethods.java508
-rw-r--r--ojluni/src/test/java/util/Arrays/ArraysEqCmpTest.java126
-rw-r--r--ojluni/src/test/java/util/Arrays/AsList.java95
-rw-r--r--ojluni/src/test/java/util/Arrays/CopyMethods.java427
-rw-r--r--ojluni/src/test/java/util/Arrays/Correct.java149
-rw-r--r--ojluni/src/test/java/util/Arrays/Fill.java77
-rw-r--r--ojluni/src/test/java/util/Arrays/FloatDoubleOrder.java125
-rw-r--r--ojluni/src/test/java/util/Arrays/SetAllTest.java283
-rw-r--r--ojluni/src/test/java/util/Arrays/Sorting.java2069
-rw-r--r--ojluni/src/test/java/util/Arrays/SortingHelper.java658
-rw-r--r--ojluni/src/test/java/util/Arrays/SortingNearlySortedPrimitive.java356
-rw-r--r--ojluni/src/test/java/util/Arrays/StreamAndSpliterator.java139
-rw-r--r--ojluni/src/test/java/util/Arrays/TimSortStackSize.java119
-rw-r--r--ojluni/src/test/java/util/BitSet/And.java45
-rw-r--r--ojluni/src/test/java/util/BitSet/BSMethods.java988
-rw-r--r--ojluni/src/test/java/util/BitSet/ImportExport.java158
-rw-r--r--ojluni/src/test/java/util/BitSet/MemoryLeak.java58
-rw-r--r--ojluni/src/test/java/util/BitSet/PreviousBits.java160
-rw-r--r--ojluni/src/test/java/util/BitSet/StickySize.java105
-rw-r--r--ojluni/src/test/java/util/BitSet/stream/BitSetStreamTest.java245
-rw-r--r--ojluni/src/test/java/util/Collections/AddAll.java79
-rw-r--r--ojluni/src/test/java/util/Collections/AsLifoQueue.java100
-rw-r--r--ojluni/src/test/java/util/Collections/BigBinarySearch.java123
-rw-r--r--ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java44
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedIdentityMap.java68
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedListBash.java235
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java63
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedMapBash.java188
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java56
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedNull.java201
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedQueue.java154
-rw-r--r--ojluni/src/test/java/util/Collections/CheckedSetBash.java182
-rw-r--r--ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java200
-rw-r--r--ojluni/src/test/java/util/Collections/Disjoint.java77
-rw-r--r--ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java110
-rw-r--r--ojluni/src/test/java/util/Collections/EmptyIterator.java158
-rw-r--r--ojluni/src/test/java/util/Collections/EmptyNavigableMap.java355
-rw-r--r--ojluni/src/test/java/util/Collections/EmptyNavigableSet.java393
-rw-r--r--ojluni/src/test/java/util/Collections/Enum.java49
-rw-r--r--ojluni/src/test/java/util/Collections/EnumerationAsIterator.java76
-rw-r--r--ojluni/src/test/java/util/Collections/EqualsTest.java69
-rw-r--r--ojluni/src/test/java/util/Collections/FindSubList.java109
-rw-r--r--ojluni/src/test/java/util/Collections/Frequency.java55
-rw-r--r--ojluni/src/test/java/util/Collections/MinMax.java84
-rw-r--r--ojluni/src/test/java/util/Collections/NullComparator.java67
-rw-r--r--ojluni/src/test/java/util/Collections/RacingCollections.java386
-rw-r--r--ojluni/src/test/java/util/Collections/ReplaceAll.java63
-rw-r--r--ojluni/src/test/java/util/Collections/ReverseOrder.java103
-rw-r--r--ojluni/src/test/java/util/Collections/ReverseOrder2.java137
-rw-r--r--ojluni/src/test/java/util/Collections/Rotate.java75
-rw-r--r--ojluni/src/test/java/util/Collections/RotateEmpty.java42
-rw-r--r--ojluni/src/test/java/util/Collections/Ser.java102
-rw-r--r--ojluni/src/test/java/util/Collections/SetFromMap.java71
-rw-r--r--ojluni/src/test/java/util/Collections/SingletonIterator.java77
-rw-r--r--ojluni/src/test/java/util/Collections/Swap.java51
-rw-r--r--ojluni/src/test/java/util/Collections/SyncSubMutexes.java273
-rw-r--r--ojluni/src/test/java/util/Collections/T6433170.java94
-rw-r--r--ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java166
-rw-r--r--ojluni/src/test/java/util/Collections/ViewSynch.java81
-rw-r--r--ojluni/src/test/java/util/Collections/WrappedNull.java193
-rw-r--r--ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java104
-rw-r--r--ojluni/src/test/java/util/Collections/Wrappers.java148
-rw-r--r--ojluni/src/test/java/util/HexFormat/HexFormatTest.java74
-rw-r--r--ojluni/src/test/java/util/PriorityQueue/AddNonComparable.java27
-rw-r--r--ojluni/src/test/java/util/WeakHashMap/GCDuringIteration.java271
-rw-r--r--ojluni/src/test/java/util/WeakHashMap/Iteration.java46
-rw-r--r--ojluni/src/test/java/util/WeakHashMap/ZeroInitCap.java41
-rw-r--r--ojluni/src/test/java/util/concurrent/tck/CollectionTest.java7
-rw-r--r--ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java5
-rw-r--r--ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java13
-rw-r--r--ojluni/src/test/java/util/regex/PatternStreamTest.java27
-rw-r--r--ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorOfIntDataBuilder.java55
-rw-r--r--ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorTestHelper.java755
-rw-r--r--openjdk_java_files.bp2
-rw-r--r--test-rules/src/main/java/libcore/test/reasons/NonMtsReasons.java40
-rw-r--r--tools/checkstyle/ojluni-src-test-header.xml13
-rw-r--r--tools/checkstyle/openjdk-gplv2-copyright.pattern2
-rw-r--r--tools/checkstyle/openjdk-gplv2-plus-classpath-copyright.pattern2
170 files changed, 23507 insertions, 1039 deletions
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 095e67ef47c..4b289bbf407 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -533,6 +533,7 @@ java_library_static {
"//frameworks/base/location/tests/locationtests",
"//frameworks/base/core/tests/coretests",
"//frameworks/base/wifi/tests",
+ "//libcore/ojluni/src/test",
"//libcore/luni/src/test/java9compatibility",
"//packages/modules/Wifi/framework/tests",
],
@@ -541,8 +542,10 @@ java_library_static {
"dalvik/test-rules/src/main/**/*.java",
"test-rules/src/main/**/*.java",
],
- static_libs: ["junit"],
-
+ static_libs: [
+ "junit",
+ "platform-test-annotations",
+ ],
sdk_version: "none",
system_modules: "core-all-system-modules",
}
diff --git a/api/current.txt b/api/current.txt
index a61a7234788..d459f728340 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2880,7 +2880,7 @@ package java.lang {
}
public enum Character.UnicodeScript {
- method @NonNull public static java.lang.Character.UnicodeScript forName(@NonNull String);
+ method @NonNull public static final java.lang.Character.UnicodeScript forName(@NonNull String);
method @NonNull public static java.lang.Character.UnicodeScript of(int);
enum_constant public static final java.lang.Character.UnicodeScript ADLAM;
enum_constant public static final java.lang.Character.UnicodeScript AHOM;
@@ -3095,8 +3095,10 @@ package java.lang {
method @Nullable public Object[] getSigners();
method @NonNull public String getSimpleName();
method @Nullable public Class<? super T> getSuperclass();
+ method @NonNull public String getTypeName();
method @NonNull public java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters();
method public boolean isAnnotation();
+ method public boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
method public boolean isAnonymousClass();
method public boolean isArray();
method public boolean isAssignableFrom(@NonNull Class<?>);
@@ -3695,6 +3697,7 @@ package java.lang {
method public String getSpecificationTitle();
method public String getSpecificationVendor();
method public String getSpecificationVersion();
+ method public boolean isAnnotationPresent(Class<? extends java.lang.annotation.Annotation>);
method public boolean isCompatibleWith(String) throws java.lang.NumberFormatException;
method public boolean isSealed();
method public boolean isSealed(java.net.URL);
@@ -4046,9 +4049,11 @@ package java.lang {
ctor public String(@NonNull StringBuffer);
ctor public String(@NonNull StringBuilder);
method public char charAt(int);
+ method @NonNull public java.util.stream.IntStream chars();
method public int codePointAt(int);
method public int codePointBefore(int);
method public int codePointCount(int, int);
+ method @NonNull public java.util.stream.IntStream codePoints();
method public int compareTo(@NonNull String);
method public int compareToIgnoreCase(@NonNull String);
method @NonNull public String concat(@NonNull String);
@@ -4106,6 +4111,7 @@ package java.lang {
method public char[] toCharArray();
method @NonNull public String toLowerCase(@NonNull java.util.Locale);
method @NonNull public String toLowerCase();
+ method @NonNull public String toString();
method @NonNull public String toUpperCase(@NonNull java.util.Locale);
method @NonNull public String toUpperCase();
method public <R> R transform(@NonNull java.util.function.Function<? super java.lang.String,? extends R>);
@@ -4144,9 +4150,11 @@ package java.lang {
method @NonNull public StringBuffer appendCodePoint(int);
method public int capacity();
method public char charAt(int);
+ method @NonNull public java.util.stream.IntStream chars();
method public int codePointAt(int);
method public int codePointBefore(int);
method public int codePointCount(int, int);
+ method @NonNull public java.util.stream.IntStream codePoints();
method public int compareTo(@NonNull StringBuffer);
method @NonNull public StringBuffer delete(int, int);
method @NonNull public StringBuffer deleteCharAt(int);
@@ -4177,6 +4185,7 @@ package java.lang {
method @NonNull public CharSequence subSequence(int, int);
method @NonNull public String substring(int);
method @NonNull public String substring(int, int);
+ method @NonNull public String toString();
method public void trimToSize();
}
@@ -4201,9 +4210,11 @@ package java.lang {
method @NonNull public StringBuilder appendCodePoint(int);
method public int capacity();
method public char charAt(int);
+ method @NonNull public java.util.stream.IntStream chars();
method public int codePointAt(int);
method public int codePointBefore(int);
method public int codePointCount(int, int);
+ method @NonNull public java.util.stream.IntStream codePoints();
method public int compareTo(@NonNull StringBuilder);
method @NonNull public StringBuilder delete(int, int);
method @NonNull public StringBuilder deleteCharAt(int);
@@ -4234,6 +4245,7 @@ package java.lang {
method @NonNull public CharSequence subSequence(int, int);
method @NonNull public String substring(int);
method @NonNull public String substring(int, int);
+ method @NonNull public String toString();
method public void trimToSize();
}
@@ -4561,8 +4573,8 @@ package java.lang.invoke {
method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
method public java.lang.invoke.MethodHandle asVarargsCollector(Class<?>);
method public java.lang.invoke.MethodHandle bindTo(Object);
- method public final Object invoke(java.lang.Object...) throws java.lang.Throwable;
- method public final Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+ method public final native Object invoke(java.lang.Object...) throws java.lang.Throwable;
+ method public final native Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
method public Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
method public Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
method public boolean isVarargsCollector();
@@ -4735,45 +4747,45 @@ package java.lang.invoke {
public abstract class VarHandle {
method public final java.lang.invoke.MethodType accessModeType(java.lang.invoke.VarHandle.AccessMode);
method public static void acquireFence();
- method public final Object compareAndExchange(java.lang.Object...);
- method public final Object compareAndExchangeAcquire(java.lang.Object...);
- method public final Object compareAndExchangeRelease(java.lang.Object...);
- method public final boolean compareAndSet(java.lang.Object...);
+ method public final native Object compareAndExchange(java.lang.Object...);
+ method public final native Object compareAndExchangeAcquire(java.lang.Object...);
+ method public final native Object compareAndExchangeRelease(java.lang.Object...);
+ method public final native boolean compareAndSet(java.lang.Object...);
method public final java.util.List<java.lang.Class<?>> coordinateTypes();
method public static void fullFence();
- method public final Object get(java.lang.Object...);
- method public final Object getAcquire(java.lang.Object...);
- method public final Object getAndAdd(java.lang.Object...);
- method public final Object getAndAddAcquire(java.lang.Object...);
- method public final Object getAndAddRelease(java.lang.Object...);
- method public final Object getAndBitwiseAnd(java.lang.Object...);
- method public final Object getAndBitwiseAndAcquire(java.lang.Object...);
- method public final Object getAndBitwiseAndRelease(java.lang.Object...);
- method public final Object getAndBitwiseOr(java.lang.Object...);
- method public final Object getAndBitwiseOrAcquire(java.lang.Object...);
- method public final Object getAndBitwiseOrRelease(java.lang.Object...);
- method public final Object getAndBitwiseXor(java.lang.Object...);
- method public final Object getAndBitwiseXorAcquire(java.lang.Object...);
- method public final Object getAndBitwiseXorRelease(java.lang.Object...);
- method public final Object getAndSet(java.lang.Object...);
- method public final Object getAndSetAcquire(java.lang.Object...);
- method public final Object getAndSetRelease(java.lang.Object...);
- method public final Object getOpaque(java.lang.Object...);
- method public final Object getVolatile(java.lang.Object...);
+ method public final native Object get(java.lang.Object...);
+ method public final native Object getAcquire(java.lang.Object...);
+ method public final native Object getAndAdd(java.lang.Object...);
+ method public final native Object getAndAddAcquire(java.lang.Object...);
+ method public final native Object getAndAddRelease(java.lang.Object...);
+ method public final native Object getAndBitwiseAnd(java.lang.Object...);
+ method public final native Object getAndBitwiseAndAcquire(java.lang.Object...);
+ method public final native Object getAndBitwiseAndRelease(java.lang.Object...);
+ method public final native Object getAndBitwiseOr(java.lang.Object...);
+ method public final native Object getAndBitwiseOrAcquire(java.lang.Object...);
+ method public final native Object getAndBitwiseOrRelease(java.lang.Object...);
+ method public final native Object getAndBitwiseXor(java.lang.Object...);
+ method public final native Object getAndBitwiseXorAcquire(java.lang.Object...);
+ method public final native Object getAndBitwiseXorRelease(java.lang.Object...);
+ method public final native Object getAndSet(java.lang.Object...);
+ method public final native Object getAndSetAcquire(java.lang.Object...);
+ method public final native Object getAndSetRelease(java.lang.Object...);
+ method public final native Object getOpaque(java.lang.Object...);
+ method public final native Object getVolatile(java.lang.Object...);
method public final boolean isAccessModeSupported(java.lang.invoke.VarHandle.AccessMode);
method public static void loadLoadFence();
method public static void releaseFence();
- method public final void set(java.lang.Object...);
- method public final void setOpaque(java.lang.Object...);
- method public final void setRelease(java.lang.Object...);
- method public final void setVolatile(java.lang.Object...);
+ method public final native void set(java.lang.Object...);
+ method public final native void setOpaque(java.lang.Object...);
+ method public final native void setRelease(java.lang.Object...);
+ method public final native void setVolatile(java.lang.Object...);
method public static void storeStoreFence();
method public final java.lang.invoke.MethodHandle toMethodHandle(java.lang.invoke.VarHandle.AccessMode);
method public final Class<?> varType();
- method public final boolean weakCompareAndSet(java.lang.Object...);
- method public final boolean weakCompareAndSetAcquire(java.lang.Object...);
- method public final boolean weakCompareAndSetPlain(java.lang.Object...);
- method public final boolean weakCompareAndSetRelease(java.lang.Object...);
+ method public final native boolean weakCompareAndSet(java.lang.Object...);
+ method public final native boolean weakCompareAndSetAcquire(java.lang.Object...);
+ method public final native boolean weakCompareAndSetPlain(java.lang.Object...);
+ method public final native boolean weakCompareAndSetRelease(java.lang.Object...);
}
public enum VarHandle.AccessMode {
@@ -4877,8 +4889,12 @@ package java.lang.reflect {
ctor protected AccessibleObject();
method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+ method public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@NonNull Class<T>);
+ method @Nullable public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@NonNull Class<T>);
method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+ method public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@NonNull Class<T>);
method public boolean isAccessible();
+ method public boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean) throws java.lang.SecurityException;
method public void setAccessible(boolean) throws java.lang.SecurityException;
}
@@ -5070,7 +5086,10 @@ package java.lang.reflect {
public final class Parameter implements java.lang.reflect.AnnotatedElement {
method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+ method public <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@NonNull Class<T>);
+ method @Nullable public <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@NonNull Class<T>);
method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+ method public <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@NonNull Class<T>);
method @NonNull public java.lang.reflect.Executable getDeclaringExecutable();
method public int getModifiers();
method @NonNull public String getName();
@@ -6289,6 +6308,7 @@ package java.nio {
method public final int arrayOffset();
method public abstract java.nio.CharBuffer asReadOnlyBuffer();
method public final char charAt(int);
+ method public java.util.stream.IntStream chars();
method public abstract java.nio.CharBuffer compact();
method public int compareTo(java.nio.CharBuffer);
method public abstract java.nio.CharBuffer duplicate();
@@ -6312,6 +6332,7 @@ package java.nio {
method public abstract java.nio.CharBuffer slice();
method public abstract java.nio.CharBuffer slice(int, int);
method public abstract java.nio.CharBuffer subSequence(int, int);
+ method public String toString();
method public static java.nio.CharBuffer wrap(char[], int, int);
method public static java.nio.CharBuffer wrap(char[]);
method public static java.nio.CharBuffer wrap(CharSequence, int, int);
@@ -7590,6 +7611,7 @@ package java.nio.file.attribute {
}
public interface PosixFileAttributeView extends java.nio.file.attribute.BasicFileAttributeView java.nio.file.attribute.FileOwnerAttributeView {
+ method public String name();
method public java.nio.file.attribute.PosixFileAttributes readAttributes() throws java.io.IOException;
method public void setGroup(java.nio.file.attribute.GroupPrincipal) throws java.io.IOException;
method public void setPermissions(java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
@@ -7884,10 +7906,12 @@ package java.security {
method @Deprecated public final String getName();
method @Deprecated public java.security.PublicKey getPublicKey();
method @Deprecated public final java.security.IdentityScope getScope();
+ method @Deprecated public int hashCode();
method @Deprecated protected boolean identityEquals(java.security.Identity);
method @Deprecated public void removeCertificate(java.security.Certificate) throws java.security.KeyManagementException;
method @Deprecated public void setInfo(String);
method @Deprecated public void setPublicKey(java.security.PublicKey) throws java.security.KeyManagementException;
+ method @Deprecated public String toString();
method @Deprecated public String toString(boolean);
}
@@ -8069,14 +8093,17 @@ package java.security {
public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
ctor public KeyStore.PasswordProtection(char[]);
ctor public KeyStore.PasswordProtection(char[], String, java.security.spec.AlgorithmParameterSpec);
+ method public void destroy() throws javax.security.auth.DestroyFailedException;
method public char[] getPassword();
method public String getProtectionAlgorithm();
method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
+ method public boolean isDestroyed();
}
public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
ctor public KeyStore.PrivateKeyEntry(java.security.PrivateKey, java.security.cert.Certificate[]);
ctor public KeyStore.PrivateKeyEntry(java.security.PrivateKey, java.security.cert.Certificate[], java.util.Set<java.security.KeyStore.Entry.Attribute>);
+ method public java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes();
method public java.security.cert.Certificate getCertificate();
method public java.security.cert.Certificate[] getCertificateChain();
method public java.security.PrivateKey getPrivateKey();
@@ -8088,12 +8115,14 @@ package java.security {
public static final class KeyStore.SecretKeyEntry implements java.security.KeyStore.Entry {
ctor public KeyStore.SecretKeyEntry(javax.crypto.SecretKey);
ctor public KeyStore.SecretKeyEntry(javax.crypto.SecretKey, java.util.Set<java.security.KeyStore.Entry.Attribute>);
+ method public java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes();
method public javax.crypto.SecretKey getSecretKey();
}
public static final class KeyStore.TrustedCertificateEntry implements java.security.KeyStore.Entry {
ctor public KeyStore.TrustedCertificateEntry(java.security.cert.Certificate);
ctor public KeyStore.TrustedCertificateEntry(java.security.cert.Certificate, java.util.Set<java.security.KeyStore.Entry.Attribute>);
+ method public java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes();
method public java.security.cert.Certificate getTrustedCertificate();
}
@@ -10797,6 +10826,7 @@ package java.text {
method public abstract int compare(String, String);
method public int compare(Object, Object);
method public boolean equals(String, String);
+ method public boolean equals(Object);
method public static java.util.Locale[] getAvailableLocales();
method public abstract java.text.CollationKey getCollationKey(String);
method public int getDecomposition();
@@ -11131,6 +11161,7 @@ package java.text {
method public java.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
method public java.text.CollationKey getCollationKey(String);
method public String getRules();
+ method public int hashCode();
}
public class SimpleDateFormat extends java.text.DateFormat {
@@ -11175,6 +11206,7 @@ package java.time {
ctor protected Clock();
method public static java.time.Clock fixed(java.time.Instant, java.time.ZoneId);
method public abstract java.time.ZoneId getZone();
+ method public long millis();
method public static java.time.Clock offset(java.time.Clock, java.time.Duration);
method public static java.time.Clock system(java.time.ZoneId);
method public static java.time.Clock systemDefaultZone();
@@ -11276,6 +11308,7 @@ package java.time {
method public java.time.ZonedDateTime atZone(java.time.ZoneId);
method public int compareTo(java.time.Instant);
method public static java.time.Instant from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public long getEpochSecond();
method public long getLong(java.time.temporal.TemporalField);
method public int getNano();
@@ -11299,6 +11332,8 @@ package java.time {
method public java.time.Instant plusMillis(long);
method public java.time.Instant plusNanos(long);
method public java.time.Instant plusSeconds(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public long toEpochMilli();
method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
@@ -11320,6 +11355,7 @@ package java.time {
}
public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+ method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
method public java.time.LocalDateTime atStartOfDay();
method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
method public java.time.LocalDateTime atTime(java.time.LocalTime);
@@ -11327,18 +11363,31 @@ package java.time {
method public java.time.LocalDateTime atTime(int, int, int);
method public java.time.LocalDateTime atTime(int, int, int, int);
method public java.time.OffsetDateTime atTime(java.time.OffsetTime);
+ method public int compareTo(java.time.chrono.ChronoLocalDate);
method public java.util.stream.Stream<java.time.LocalDate> datesUntil(java.time.LocalDate);
method public java.util.stream.Stream<java.time.LocalDate> datesUntil(java.time.LocalDate, java.time.Period);
+ method public boolean equals(Object);
+ method public String format(java.time.format.DateTimeFormatter);
method public static java.time.LocalDate from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public java.time.chrono.IsoChronology getChronology();
method public int getDayOfMonth();
method public java.time.DayOfWeek getDayOfWeek();
method public int getDayOfYear();
+ method public java.time.chrono.Era getEra();
method public long getLong(java.time.temporal.TemporalField);
method public java.time.Month getMonth();
method public int getMonthValue();
method public int getYear();
+ method public int hashCode();
+ method public boolean isAfter(java.time.chrono.ChronoLocalDate);
+ method public boolean isBefore(java.time.chrono.ChronoLocalDate);
+ method public boolean isEqual(java.time.chrono.ChronoLocalDate);
+ method public boolean isLeapYear();
+ method public boolean isSupported(java.time.temporal.TemporalField);
+ method public boolean isSupported(java.time.temporal.TemporalUnit);
method public int lengthOfMonth();
+ method public int lengthOfYear();
method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
method public java.time.LocalDate minusDays(long);
@@ -11361,7 +11410,11 @@ package java.time {
method public java.time.LocalDate plusMonths(long);
method public java.time.LocalDate plusWeeks(long);
method public java.time.LocalDate plusYears(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+ method public long toEpochDay();
method public long toEpochSecond(java.time.LocalTime, java.time.ZoneOffset);
+ method public String toString();
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.Period until(java.time.chrono.ChronoLocalDate);
method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
@@ -11376,9 +11429,14 @@ package java.time {
}
public final class LocalDateTime implements java.time.chrono.ChronoLocalDateTime<java.time.LocalDate> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+ method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
method public java.time.OffsetDateTime atOffset(java.time.ZoneOffset);
method public java.time.ZonedDateTime atZone(java.time.ZoneId);
+ method public int compareTo(java.time.chrono.ChronoLocalDateTime<?>);
+ method public boolean equals(Object);
+ method public String format(java.time.format.DateTimeFormatter);
method public static java.time.LocalDateTime from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public int getDayOfMonth();
method public java.time.DayOfWeek getDayOfWeek();
method public int getDayOfYear();
@@ -11390,7 +11448,12 @@ package java.time {
method public int getNano();
method public int getSecond();
method public int getYear();
+ method public int hashCode();
+ method public boolean isAfter(java.time.chrono.ChronoLocalDateTime<?>);
+ method public boolean isBefore(java.time.chrono.ChronoLocalDateTime<?>);
+ method public boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
method public boolean isSupported(java.time.temporal.TemporalField);
+ method public boolean isSupported(java.time.temporal.TemporalUnit);
method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
method public java.time.LocalDateTime minusDays(long);
@@ -11425,8 +11488,11 @@ package java.time {
method public java.time.LocalDateTime plusSeconds(long);
method public java.time.LocalDateTime plusWeeks(long);
method public java.time.LocalDateTime plusYears(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public java.time.LocalDate toLocalDate();
method public java.time.LocalTime toLocalTime();
+ method public String toString();
method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
@@ -11450,6 +11516,7 @@ package java.time {
method public int compareTo(java.time.LocalTime);
method public String format(java.time.format.DateTimeFormatter);
method public static java.time.LocalTime from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public int getHour();
method public long getLong(java.time.temporal.TemporalField);
method public int getMinute();
@@ -11482,6 +11549,8 @@ package java.time {
method public java.time.LocalTime plusMinutes(long);
method public java.time.LocalTime plusNanos(long);
method public java.time.LocalTime plusSeconds(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public long toEpochSecond(java.time.LocalDate, java.time.ZoneOffset);
method public long toNanoOfDay();
method public int toSecondOfDay();
@@ -11534,6 +11603,7 @@ package java.time {
method public int compareTo(java.time.MonthDay);
method public String format(java.time.format.DateTimeFormatter);
method public static java.time.MonthDay from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public int getDayOfMonth();
method public long getLong(java.time.temporal.TemporalField);
method public java.time.Month getMonth();
@@ -11549,6 +11619,8 @@ package java.time {
method public static java.time.MonthDay of(int, int);
method public static java.time.MonthDay parse(CharSequence);
method public static java.time.MonthDay parse(CharSequence, java.time.format.DateTimeFormatter);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public java.time.MonthDay with(java.time.Month);
method public java.time.MonthDay withDayOfMonth(int);
method public java.time.MonthDay withMonth(int);
@@ -11561,6 +11633,7 @@ package java.time {
method public int compareTo(java.time.OffsetDateTime);
method public String format(java.time.format.DateTimeFormatter);
method public static java.time.OffsetDateTime from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public int getDayOfMonth();
method public java.time.DayOfWeek getDayOfWeek();
method public int getDayOfYear();
@@ -11607,6 +11680,8 @@ package java.time {
method public java.time.OffsetDateTime plusSeconds(long);
method public java.time.OffsetDateTime plusWeeks(long);
method public java.time.OffsetDateTime plusYears(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public static java.util.Comparator<java.time.OffsetDateTime> timeLineOrder();
method public long toEpochSecond();
method public java.time.Instant toInstant();
@@ -11639,6 +11714,7 @@ package java.time {
method public int compareTo(java.time.OffsetTime);
method public String format(java.time.format.DateTimeFormatter);
method public static java.time.OffsetTime from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public int getHour();
method public long getLong(java.time.temporal.TemporalField);
method public int getMinute();
@@ -11670,6 +11746,8 @@ package java.time {
method public java.time.OffsetTime plusMinutes(long);
method public java.time.OffsetTime plusNanos(long);
method public java.time.OffsetTime plusSeconds(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public long toEpochSecond(java.time.LocalDate);
method public java.time.LocalTime toLocalTime();
method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
@@ -11689,6 +11767,7 @@ package java.time {
public final class Period implements java.time.chrono.ChronoPeriod java.io.Serializable {
method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
method public static java.time.Period between(java.time.LocalDate, java.time.LocalDate);
+ method public boolean equals(Object);
method public static java.time.Period from(java.time.temporal.TemporalAmount);
method public long get(java.time.temporal.TemporalUnit);
method public java.time.chrono.IsoChronology getChronology();
@@ -11696,6 +11775,9 @@ package java.time {
method public int getMonths();
method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
method public int getYears();
+ method public int hashCode();
+ method public boolean isNegative();
+ method public boolean isZero();
method public java.time.Period minus(java.time.temporal.TemporalAmount);
method public java.time.Period minusDays(long);
method public java.time.Period minusMonths(long);
@@ -11714,6 +11796,7 @@ package java.time {
method public java.time.Period plusMonths(long);
method public java.time.Period plusYears(long);
method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
+ method public String toString();
method public long toTotalMonths();
method public java.time.Period withDays(int);
method public java.time.Period withMonths(int);
@@ -11730,6 +11813,7 @@ package java.time {
method public int compareTo(java.time.Year);
method public String format(java.time.format.DateTimeFormatter);
method public static java.time.Year from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public long getLong(java.time.temporal.TemporalField);
method public int getValue();
method public boolean isAfter(java.time.Year);
@@ -11752,6 +11836,8 @@ package java.time {
method public java.time.Year plus(java.time.temporal.TemporalAmount);
method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
method public java.time.Year plusYears(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.Year with(java.time.temporal.TemporalAdjuster);
method public java.time.Year with(java.time.temporal.TemporalField, long);
@@ -11766,6 +11852,7 @@ package java.time {
method public int compareTo(java.time.YearMonth);
method public String format(java.time.format.DateTimeFormatter);
method public static java.time.YearMonth from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public long getLong(java.time.temporal.TemporalField);
method public java.time.Month getMonth();
method public int getMonthValue();
@@ -11793,6 +11880,8 @@ package java.time {
method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
method public java.time.YearMonth plusMonths(long);
method public java.time.YearMonth plusYears(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
@@ -11818,6 +11907,7 @@ package java.time {
method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
method public int compareTo(java.time.ZoneOffset);
method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public String getId();
method public long getLong(java.time.temporal.TemporalField);
method public java.time.zone.ZoneRules getRules();
@@ -11828,17 +11918,23 @@ package java.time {
method public static java.time.ZoneOffset ofHoursMinutes(int, int);
method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
method public static java.time.ZoneOffset ofTotalSeconds(int);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
field public static final java.time.ZoneOffset MAX;
field public static final java.time.ZoneOffset MIN;
field public static final java.time.ZoneOffset UTC;
}
public final class ZonedDateTime implements java.time.chrono.ChronoZonedDateTime<java.time.LocalDate> java.io.Serializable java.time.temporal.Temporal {
+ method public boolean equals(Object);
+ method public String format(java.time.format.DateTimeFormatter);
method public static java.time.ZonedDateTime from(java.time.temporal.TemporalAccessor);
+ method public int get(java.time.temporal.TemporalField);
method public int getDayOfMonth();
method public java.time.DayOfWeek getDayOfWeek();
method public int getDayOfYear();
method public int getHour();
+ method public long getLong(java.time.temporal.TemporalField);
method public int getMinute();
method public java.time.Month getMonth();
method public int getMonthValue();
@@ -11847,7 +11943,9 @@ package java.time {
method public int getSecond();
method public int getYear();
method public java.time.ZoneId getZone();
+ method public int hashCode();
method public boolean isSupported(java.time.temporal.TemporalField);
+ method public boolean isSupported(java.time.temporal.TemporalUnit);
method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
method public java.time.ZonedDateTime minusDays(long);
@@ -11880,9 +11978,13 @@ package java.time {
method public java.time.ZonedDateTime plusSeconds(long);
method public java.time.ZonedDateTime plusWeeks(long);
method public java.time.ZonedDateTime plusYears(long);
+ method public <R> R query(java.time.temporal.TemporalQuery<R>);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public java.time.LocalDate toLocalDate();
method public java.time.LocalDateTime toLocalDateTime();
+ method public java.time.LocalTime toLocalTime();
method public java.time.OffsetDateTime toOffsetDateTime();
+ method public String toString();
method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
@@ -11909,7 +12011,10 @@ package java.time.chrono {
public abstract class AbstractChronology implements java.time.chrono.Chronology {
ctor protected AbstractChronology();
method public int compareTo(java.time.chrono.Chronology);
+ method public boolean equals(Object);
+ method public int hashCode();
method public java.time.chrono.ChronoLocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+ method public String toString();
}
public interface ChronoLocalDate extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoLocalDate> java.time.temporal.TemporalAdjuster {
@@ -12090,7 +12195,9 @@ package java.time.chrono {
method public java.time.chrono.HijrahChronology getChronology();
method public java.time.chrono.HijrahEra getEra();
method public long getLong(java.time.temporal.TemporalField);
+ method public boolean isLeapYear();
method public int lengthOfMonth();
+ method public int lengthOfYear();
method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
method public static java.time.chrono.HijrahDate now();
@@ -12099,6 +12206,9 @@ package java.time.chrono {
method public static java.time.chrono.HijrahDate of(int, int, int);
method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+ method public long toEpochDay();
+ method public String toString();
method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
@@ -12122,6 +12232,7 @@ package java.time.chrono {
method public java.time.LocalDate dateNow(java.time.Clock);
method public java.time.LocalDate dateYearDay(java.time.chrono.Era, int, int);
method public java.time.LocalDate dateYearDay(int, int);
+ method public long epochSecond(int, int, int, int, int, int, java.time.ZoneOffset);
method public java.time.chrono.IsoEra eraOf(int);
method public java.util.List<java.time.chrono.Era> eras();
method public String getCalendarType();
@@ -12174,7 +12285,9 @@ package java.time.chrono {
method public java.time.chrono.JapaneseChronology getChronology();
method public java.time.chrono.JapaneseEra getEra();
method public long getLong(java.time.temporal.TemporalField);
+ method public boolean isSupported(java.time.temporal.TemporalField);
method public int lengthOfMonth();
+ method public int lengthOfYear();
method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
method public static java.time.chrono.JapaneseDate now();
@@ -12184,6 +12297,9 @@ package java.time.chrono {
method public static java.time.chrono.JapaneseDate of(int, int, int);
method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+ method public long toEpochDay();
+ method public String toString();
method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
@@ -12191,8 +12307,10 @@ package java.time.chrono {
}
public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
+ method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
method public int getValue();
method public static java.time.chrono.JapaneseEra of(int);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
method public static java.time.chrono.JapaneseEra valueOf(String);
method public static java.time.chrono.JapaneseEra[] values();
field public static final java.time.chrono.JapaneseEra HEISEI;
@@ -12241,6 +12359,9 @@ package java.time.chrono {
method public static java.time.chrono.MinguoDate of(int, int, int);
method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+ method public long toEpochDay();
+ method public String toString();
method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
@@ -12293,6 +12414,9 @@ package java.time.chrono {
method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+ method public java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+ method public long toEpochDay();
+ method public String toString();
method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
@@ -12756,6 +12880,8 @@ package java.util {
ctor protected AbstractList();
method public void add(int, E);
method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
+ method public boolean equals(@Nullable Object);
+ method public int hashCode();
method public int indexOf(@Nullable Object);
method @NonNull public java.util.Iterator<E> iterator();
method public int lastIndexOf(@Nullable Object);
@@ -12773,7 +12899,9 @@ package java.util {
method public void clear();
method public boolean containsKey(@Nullable Object);
method public boolean containsValue(@Nullable Object);
+ method public boolean equals(@Nullable Object);
method @Nullable public V get(@Nullable Object);
+ method public int hashCode();
method public boolean isEmpty();
method @NonNull public java.util.Set<K> keySet();
method @Nullable public V put(K, V);
@@ -12786,16 +12914,20 @@ package java.util {
public static class AbstractMap.SimpleEntry<K, V> implements java.util.Map.Entry<K,V> java.io.Serializable {
ctor public AbstractMap.SimpleEntry(K, V);
ctor public AbstractMap.SimpleEntry(@NonNull java.util.Map.Entry<? extends K,? extends V>);
+ method public boolean equals(@Nullable Object);
method public K getKey();
method public V getValue();
+ method public int hashCode();
method public V setValue(V);
}
public static class AbstractMap.SimpleImmutableEntry<K, V> implements java.util.Map.Entry<K,V> java.io.Serializable {
ctor public AbstractMap.SimpleImmutableEntry(K, V);
ctor public AbstractMap.SimpleImmutableEntry(@NonNull java.util.Map.Entry<? extends K,? extends V>);
+ method public boolean equals(@Nullable Object);
method public K getKey();
method public V getValue();
+ method public int hashCode();
method public V setValue(V);
}
@@ -12812,6 +12944,8 @@ package java.util {
public abstract class AbstractSet<E> extends java.util.AbstractCollection<E> implements java.util.Set<E> {
ctor protected AbstractSet();
+ method public boolean equals(@Nullable Object);
+ method public int hashCode();
}
public class ArrayDeque<E> extends java.util.AbstractCollection<E> implements java.lang.Cloneable java.util.Deque<E> java.io.Serializable {
@@ -12841,9 +12975,11 @@ package java.util {
method public E remove();
method public E removeFirst();
method public boolean removeFirstOccurrence(@Nullable Object);
+ method public boolean removeIf(@NonNull java.util.function.Predicate<? super E>);
method public E removeLast();
method public boolean removeLastOccurrence(@Nullable Object);
method public int size();
+ method @NonNull public java.util.Spliterator<E> spliterator();
}
public class ArrayList<E> extends java.util.AbstractList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
@@ -12854,7 +12990,11 @@ package java.util {
method public void ensureCapacity(int);
method public void forEach(@NonNull java.util.function.Consumer<? super E>);
method public E get(int);
+ method public boolean removeIf(@NonNull java.util.function.Predicate<? super E>);
+ method public void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
method public int size();
+ method public void sort(@Nullable java.util.Comparator<? super E>);
+ method @NonNull public java.util.Spliterator<E> spliterator();
method public void trimToSize();
}
@@ -13498,6 +13638,7 @@ package java.util {
ctor public EnumMap(java.util.Map<K,? extends V>);
method public java.util.EnumMap<K,V> clone();
method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+ method public V put(K, V);
}
public abstract class EnumSet<E extends java.lang.Enum<E>> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.io.Serializable {
@@ -13620,7 +13761,18 @@ package java.util {
ctor public HashMap();
ctor public HashMap(@NonNull java.util.Map<? extends K,? extends V>);
method @NonNull public Object clone();
+ method @Nullable public V compute(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
+ method @Nullable public V computeIfAbsent(K, @NonNull java.util.function.Function<? super K,? extends V>);
+ method @Nullable public V computeIfPresent(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+ method public void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
+ method @Nullable public V getOrDefault(@Nullable Object, @Nullable V);
+ method @Nullable public V merge(K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
+ method @Nullable public V putIfAbsent(K, V);
+ method public boolean remove(@Nullable Object, @Nullable Object);
+ method public boolean replace(K, @Nullable V, V);
+ method @Nullable public V replace(K, V);
+ method public void replaceAll(@NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
}
public class HashSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.io.Serializable java.util.Set<E> {
@@ -13631,6 +13783,7 @@ package java.util {
method @NonNull public Object clone();
method @NonNull public java.util.Iterator<E> iterator();
method public int size();
+ method @NonNull public java.util.Spliterator<E> spliterator();
}
public class Hashtable<K, V> extends java.util.Dictionary<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
@@ -13640,19 +13793,32 @@ package java.util {
ctor public Hashtable(java.util.Map<? extends K,? extends V>);
method public void clear();
method public Object clone();
+ method public V compute(K, java.util.function.BiFunction<? super K,? super V,? extends V>);
+ method public V computeIfAbsent(K, java.util.function.Function<? super K,? extends V>);
+ method public V computeIfPresent(K, java.util.function.BiFunction<? super K,? super V,? extends V>);
method public boolean contains(Object);
method public boolean containsKey(Object);
method public boolean containsValue(Object);
method public java.util.Enumeration<V> elements();
method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+ method public boolean equals(Object);
+ method public void forEach(java.util.function.BiConsumer<? super K,? super V>);
method public V get(Object);
+ method public V getOrDefault(Object, V);
+ method public int hashCode();
method public boolean isEmpty();
method public java.util.Set<K> keySet();
method public java.util.Enumeration<K> keys();
+ method public V merge(K, V, java.util.function.BiFunction<? super V,? super V,? extends V>);
method public V put(K, V);
method public void putAll(java.util.Map<? extends K,? extends V>);
+ method public V putIfAbsent(K, V);
method protected void rehash();
method public V remove(Object);
+ method public boolean remove(Object, Object);
+ method public boolean replace(K, V, V);
+ method public V replace(K, V);
+ method public void replaceAll(java.util.function.BiFunction<? super K,? super V,? extends V>);
method public int size();
method public java.util.Collection<V> values();
}
@@ -13699,6 +13865,8 @@ package java.util {
ctor public IdentityHashMap(java.util.Map<? extends K,? extends V>);
method public Object clone();
method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+ method public void forEach(java.util.function.BiConsumer<? super K,? super V>);
+ method public void replaceAll(java.util.function.BiFunction<? super K,? super V,? extends V>);
}
public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
@@ -13792,6 +13960,7 @@ package java.util {
method public E element();
method public E getFirst();
method public E getLast();
+ method @NonNull public java.util.ListIterator<E> listIterator(int);
method public boolean offer(E);
method public boolean offerFirst(E);
method public boolean offerLast(E);
@@ -13809,6 +13978,7 @@ package java.util {
method public E removeLast();
method public boolean removeLastOccurrence(@Nullable Object);
method public int size();
+ method @NonNull public java.util.Spliterator<E> spliterator();
}
public interface List<E> extends java.util.Collection<E> {
@@ -14243,6 +14413,7 @@ package java.util {
method public boolean offer(E);
method public E peek();
method public E poll();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
method public final java.util.Spliterator<E> spliterator();
}
@@ -14423,6 +14594,7 @@ package java.util {
method public short nextShort();
method public short nextShort(int);
method public int radix();
+ method public void remove();
method public java.util.Scanner reset();
method public java.util.Scanner skip(java.util.regex.Pattern);
method public java.util.Scanner skip(String);
@@ -14739,6 +14911,7 @@ package java.util {
method public K firstKey();
method @Nullable public java.util.Map.Entry<K,V> floorEntry(K);
method @Nullable public K floorKey(K);
+ method public void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
method @NonNull public java.util.NavigableMap<K,V> headMap(K, boolean);
method @NonNull public java.util.SortedMap<K,V> headMap(K);
method @Nullable public java.util.Map.Entry<K,V> higherEntry(K);
@@ -14750,6 +14923,9 @@ package java.util {
method @NonNull public java.util.NavigableSet<K> navigableKeySet();
method @Nullable public java.util.Map.Entry<K,V> pollFirstEntry();
method @Nullable public java.util.Map.Entry<K,V> pollLastEntry();
+ method public boolean replace(K, @Nullable V, V);
+ method public V replace(K, V);
+ method public void replaceAll(@NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
method @NonNull public java.util.NavigableMap<K,V> subMap(K, boolean, K, boolean);
method @NonNull public java.util.SortedMap<K,V> subMap(K, K);
method @NonNull public java.util.NavigableMap<K,V> tailMap(K, boolean);
@@ -14777,6 +14953,7 @@ package java.util {
method public E pollFirst();
method public E pollLast();
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
method public java.util.SortedSet<E> subSet(E, E);
method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -14830,9 +15007,13 @@ package java.util {
method public void removeAllElements();
method public boolean removeElement(@Nullable Object);
method public void removeElementAt(int);
+ method public boolean removeIf(@NonNull java.util.function.Predicate<? super E>);
+ method public void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
method public void setElementAt(E, int);
method public void setSize(int);
method public int size();
+ method public void sort(@Nullable java.util.Comparator<? super E>);
+ method @NonNull public java.util.Spliterator<E> spliterator();
method public void trimToSize();
field protected int capacityIncrement;
field protected int elementCount;
@@ -14845,6 +15026,8 @@ package java.util {
ctor public WeakHashMap();
ctor public WeakHashMap(@NonNull java.util.Map<? extends K,? extends V>);
method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+ method public void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
+ method public void replaceAll(@NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
}
}
@@ -14879,17 +15062,29 @@ package java.util.concurrent {
method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
method public void put(E) throws java.lang.InterruptedException;
method public int remainingCapacity();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public E take() throws java.lang.InterruptedException;
}
public interface BlockingDeque<E> extends java.util.concurrent.BlockingQueue<E> java.util.Deque<E> {
+ method public boolean add(E);
+ method public boolean contains(Object);
+ method public E element();
+ method public java.util.Iterator<E> iterator();
+ method public boolean offer(E);
method public boolean offerFirst(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
method public boolean offerLast(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+ method public E peek();
+ method public E poll();
method public E pollFirst(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
method public E pollLast(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
method public void putFirst(E) throws java.lang.InterruptedException;
method public void putLast(E) throws java.lang.InterruptedException;
+ method public E remove();
+ method public boolean remove(Object);
+ method public int size();
method public E takeFirst() throws java.lang.InterruptedException;
method public E takeLast() throws java.lang.InterruptedException;
}
@@ -15068,9 +15263,13 @@ package java.util.concurrent {
ctor public ConcurrentHashMap(@NonNull java.util.Map<? extends K,? extends V>);
ctor public ConcurrentHashMap(int, float);
ctor public ConcurrentHashMap(int, float, int);
+ method @Nullable public V compute(@NonNull K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
+ method @Nullable public V computeIfAbsent(@NonNull K, @NonNull java.util.function.Function<? super K,? extends V>);
+ method @Nullable public V computeIfPresent(@NonNull K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
method public boolean contains(@NonNull Object);
method @NonNull public java.util.Enumeration<V> elements();
method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+ method public void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
method public void forEach(long, @NonNull java.util.function.BiConsumer<? super K,? super V>);
method public <U> void forEach(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>, @NonNull java.util.function.Consumer<? super U>);
method public void forEachEntry(long, @NonNull java.util.function.Consumer<? super java.util.Map.Entry<K,V>>);
@@ -15079,11 +15278,14 @@ package java.util.concurrent {
method public <U> void forEachKey(long, @NonNull java.util.function.Function<? super K,? extends U>, @NonNull java.util.function.Consumer<? super U>);
method public void forEachValue(long, @NonNull java.util.function.Consumer<? super V>);
method public <U> void forEachValue(long, @NonNull java.util.function.Function<? super V,? extends U>, @NonNull java.util.function.Consumer<? super U>);
+ method @Nullable public V getOrDefault(@NonNull Object, @Nullable V);
method @NonNull public java.util.concurrent.ConcurrentHashMap.KeySetView<K,V> keySet(@NonNull V);
method @NonNull public java.util.Enumeration<K> keys();
method public long mappingCount();
+ method @Nullable public V merge(@NonNull K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
method @NonNull public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K,java.lang.Boolean> newKeySet();
method @NonNull public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K,java.lang.Boolean> newKeySet(int);
+ method @Nullable public V putIfAbsent(@NonNull K, @NonNull V);
method @Nullable public <U> U reduce(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
method @Nullable public java.util.Map.Entry<K,V> reduceEntries(long, @NonNull java.util.function.BiFunction<java.util.Map.Entry<K,V>,java.util.Map.Entry<K,V>,? extends java.util.Map.Entry<K,V>>);
method @Nullable public <U> U reduceEntries(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
@@ -15103,6 +15305,10 @@ package java.util.concurrent {
method public double reduceValuesToDouble(long, @NonNull java.util.function.ToDoubleFunction<? super V>, double, @NonNull java.util.function.DoubleBinaryOperator);
method public int reduceValuesToInt(long, @NonNull java.util.function.ToIntFunction<? super V>, int, @NonNull java.util.function.IntBinaryOperator);
method public long reduceValuesToLong(long, @NonNull java.util.function.ToLongFunction<? super V>, long, @NonNull java.util.function.LongBinaryOperator);
+ method public boolean remove(@NonNull Object, @Nullable Object);
+ method public boolean replace(@NonNull K, @NonNull V, @NonNull V);
+ method @Nullable public V replace(@NonNull K, @NonNull V);
+ method public void replaceAll(@NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
method @Nullable public <U> U search(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>);
method @Nullable public <U> U searchEntries(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>);
method @Nullable public <U> U searchKeys(long, @NonNull java.util.function.Function<? super K,? extends U>);
@@ -15115,9 +15321,11 @@ package java.util.concurrent {
method public final void clear();
method public boolean contains(@NonNull Object);
method public final boolean containsAll(@NonNull java.util.Collection<?>);
+ method public boolean equals(@Nullable Object);
method public void forEach(@NonNull java.util.function.Consumer<? super K>);
method @NonNull public java.util.concurrent.ConcurrentHashMap<K,V> getMap();
method @Nullable public V getMappedValue();
+ method public int hashCode();
method public final boolean isEmpty();
method @NonNull public java.util.Iterator<K> iterator();
method public boolean remove(@NonNull Object);
@@ -15155,9 +15363,11 @@ package java.util.concurrent {
method public E remove();
method public E removeFirst();
method public boolean removeFirstOccurrence(Object);
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public E removeLast();
method public boolean removeLastOccurrence(Object);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
}
public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue<E> implements java.util.Queue<E> java.io.Serializable {
@@ -15168,7 +15378,9 @@ package java.util.concurrent {
method public boolean offer(E);
method public E peek();
method public E poll();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
}
public interface ConcurrentMap<K, V> extends java.util.Map<K,V> {
@@ -15198,6 +15410,9 @@ package java.util.concurrent {
method public K ceilingKey(K);
method public java.util.concurrent.ConcurrentSkipListMap<K,V> clone();
method public java.util.Comparator<? super K> comparator();
+ method public V compute(K, java.util.function.BiFunction<? super K,? super V,? extends V>);
+ method public V computeIfAbsent(K, java.util.function.Function<? super K,? extends V>);
+ method public V computeIfPresent(K, java.util.function.BiFunction<? super K,? super V,? extends V>);
method public java.util.NavigableSet<K> descendingKeySet();
method public java.util.concurrent.ConcurrentNavigableMap<K,V> descendingMap();
method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
@@ -15205,6 +15420,8 @@ package java.util.concurrent {
method public K firstKey();
method public java.util.Map.Entry<K,V> floorEntry(K);
method public K floorKey(K);
+ method public void forEach(java.util.function.BiConsumer<? super K,? super V>);
+ method public V getOrDefault(Object, V);
method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K, boolean);
method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K);
method public java.util.Map.Entry<K,V> higherEntry(K);
@@ -15214,9 +15431,15 @@ package java.util.concurrent {
method public K lastKey();
method public java.util.Map.Entry<K,V> lowerEntry(K);
method public K lowerKey(K);
+ method public V merge(K, V, java.util.function.BiFunction<? super V,? super V,? extends V>);
method public java.util.NavigableSet<K> navigableKeySet();
method public java.util.Map.Entry<K,V> pollFirstEntry();
method public java.util.Map.Entry<K,V> pollLastEntry();
+ method public V putIfAbsent(K, V);
+ method public boolean remove(Object, Object);
+ method public boolean replace(K, V, V);
+ method public V replace(K, V);
+ method public void replaceAll(java.util.function.BiFunction<? super K,? super V,? extends V>);
method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, boolean, K, boolean);
method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, K);
method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K, boolean);
@@ -15244,6 +15467,7 @@ package java.util.concurrent {
method public E pollFirst();
method public E pollLast();
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
method public java.util.NavigableSet<E> subSet(E, E);
method public java.util.NavigableSet<E> tailSet(E, boolean);
@@ -15264,8 +15488,10 @@ package java.util.concurrent {
method @NonNull public Object clone();
method public boolean contains(@Nullable Object);
method public boolean containsAll(@NonNull java.util.Collection<?>);
+ method public boolean equals(@Nullable Object);
method public void forEach(@NonNull java.util.function.Consumer<? super E>);
method public E get(int);
+ method public int hashCode();
method public int indexOf(@Nullable Object);
method public int indexOf(@Nullable E, int);
method public boolean isEmpty();
@@ -15277,9 +15503,13 @@ package java.util.concurrent {
method public E remove(int);
method public boolean remove(@Nullable Object);
method public boolean removeAll(@NonNull java.util.Collection<?>);
+ method public boolean removeIf(@NonNull java.util.function.Predicate<? super E>);
+ method public void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
method public boolean retainAll(@NonNull java.util.Collection<?>);
method public E set(int, E);
method public int size();
+ method public void sort(@Nullable java.util.Comparator<? super E>);
+ method @NonNull public java.util.Spliterator<E> spliterator();
method @NonNull public java.util.List<E> subList(int, int);
method @NonNull public Object[] toArray();
method @NonNull public <T> T[] toArray(@NonNull T[]);
@@ -15290,7 +15520,9 @@ package java.util.concurrent {
ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
method public void forEach(java.util.function.Consumer<? super E>);
method public java.util.Iterator<E> iterator();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
}
public class CountDownLatch {
@@ -15341,6 +15573,7 @@ package java.util.concurrent {
public class DelayQueue<E extends java.util.concurrent.Delayed> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> {
ctor public DelayQueue();
ctor public DelayQueue(java.util.Collection<? extends E>);
+ method public boolean add(E);
method public int drainTo(java.util.Collection<? super E>);
method public int drainTo(java.util.Collection<? super E>, int);
method public java.util.Iterator<E> iterator();
@@ -15607,9 +15840,11 @@ package java.util.concurrent {
method public int remainingCapacity();
method public E removeFirst();
method public boolean removeFirstOccurrence(Object);
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public E removeLast();
method public boolean removeLastOccurrence(Object);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public E take() throws java.lang.InterruptedException;
method public E takeFirst() throws java.lang.InterruptedException;
method public E takeLast() throws java.lang.InterruptedException;
@@ -15630,7 +15865,9 @@ package java.util.concurrent {
method public E poll();
method public void put(E) throws java.lang.InterruptedException;
method public int remainingCapacity();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public E take() throws java.lang.InterruptedException;
}
@@ -15650,7 +15887,9 @@ package java.util.concurrent {
method public E poll();
method public void put(E);
method public int remainingCapacity();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public E take() throws java.lang.InterruptedException;
method public void transfer(E) throws java.lang.InterruptedException;
method public boolean tryTransfer(E);
@@ -15698,7 +15937,9 @@ package java.util.concurrent {
method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
method public void put(E);
method public int remainingCapacity();
+ method public boolean removeIf(java.util.function.Predicate<? super E>);
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public E take() throws java.lang.InterruptedException;
}
@@ -15824,6 +16065,7 @@ package java.util.concurrent {
method public void put(E) throws java.lang.InterruptedException;
method public int remainingCapacity();
method public int size();
+ method public java.util.Spliterator<E> spliterator();
method public E take() throws java.lang.InterruptedException;
}
@@ -16762,9 +17004,11 @@ package java.util.jar {
method public boolean containsKey(Object);
method public boolean containsValue(Object);
method public java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>> entrySet();
+ method public boolean equals(Object);
method public Object get(Object);
method public String getValue(String);
method public String getValue(java.util.jar.Attributes.Name);
+ method public int hashCode();
method public boolean isEmpty();
method public java.util.Set<java.lang.Object> keySet();
method public Object put(Object, Object);
@@ -17342,6 +17586,7 @@ package java.util.prefs {
method protected abstract void removeSpi(String);
method public void sync() throws java.util.prefs.BackingStoreException;
method protected abstract void syncSpi() throws java.util.prefs.BackingStoreException;
+ method public String toString();
field protected final Object lock;
field protected boolean newNode;
}
@@ -17821,6 +18066,8 @@ package java.util.zip {
method public void reset();
method public void update(int);
method public void update(byte[], int, int);
+ method public void update(byte[]);
+ method public void update(java.nio.ByteBuffer);
}
public class CRC32 implements java.util.zip.Checksum {
@@ -17829,6 +18076,8 @@ package java.util.zip {
method public void reset();
method public void update(int);
method public void update(byte[], int, int);
+ method public void update(byte[]);
+ method public void update(java.nio.ByteBuffer);
}
public final class CRC32C implements java.util.zip.Checksum {
@@ -17837,6 +18086,7 @@ package java.util.zip {
method public void reset();
method public void update(int);
method public void update(byte[], int, int);
+ method public void update(java.nio.ByteBuffer);
}
public class CheckedInputStream extends java.io.FilterInputStream {
@@ -19203,10 +19453,13 @@ package javax.security.auth.x500 {
ctor public X500Principal(String, java.util.Map<java.lang.String,java.lang.String>);
ctor public X500Principal(byte[]);
ctor public X500Principal(java.io.InputStream);
+ method public boolean equals(Object);
method public byte[] getEncoded();
method public String getName();
method public String getName(String);
method public String getName(String, java.util.Map<java.lang.String,java.lang.String>);
+ method public int hashCode();
+ method public String toString();
field public static final String CANONICAL = "CANONICAL";
field public static final String RFC1779 = "RFC1779";
field public static final String RFC2253 = "RFC2253";
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index ffb05b33aa1..df4c80611a1 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -451,7 +451,48 @@ package java.nio {
public class DirectByteBuffer extends java.nio.MappedByteBuffer {
ctor public DirectByteBuffer(int, long, java.io.FileDescriptor, Runnable, boolean);
method public final long address();
+ method public final java.nio.CharBuffer asCharBuffer();
+ method public final java.nio.DoubleBuffer asDoubleBuffer();
+ method public final java.nio.FloatBuffer asFloatBuffer();
+ method public final java.nio.IntBuffer asIntBuffer();
+ method public final java.nio.LongBuffer asLongBuffer();
+ method public final java.nio.ByteBuffer asReadOnlyBuffer();
+ method public final java.nio.ShortBuffer asShortBuffer();
+ method public final java.nio.ByteBuffer compact();
+ method public final java.nio.MappedByteBuffer duplicate();
+ method public final byte get();
+ method public final byte get(int);
+ method public final char getChar();
+ method public final char getChar(int);
+ method public final double getDouble();
+ method public final double getDouble(int);
+ method public final float getFloat();
+ method public final float getFloat(int);
+ method public int getInt();
+ method public int getInt(int);
+ method public final long getLong();
+ method public final long getLong(int);
+ method public final short getShort();
+ method public final short getShort(int);
+ method public final boolean isDirect();
+ method public final boolean isReadOnly();
+ method public final java.nio.ByteBuffer put(byte);
+ method public final java.nio.ByteBuffer put(int, byte);
+ method public final java.nio.ByteBuffer putChar(char);
+ method public final java.nio.ByteBuffer putChar(int, char);
+ method public final java.nio.ByteBuffer putDouble(double);
+ method public final java.nio.ByteBuffer putDouble(int, double);
+ method public final java.nio.ByteBuffer putFloat(float);
+ method public final java.nio.ByteBuffer putFloat(int, float);
+ method public final java.nio.ByteBuffer putInt(int);
+ method public final java.nio.ByteBuffer putInt(int, int);
+ method public final java.nio.ByteBuffer putLong(long);
+ method public final java.nio.ByteBuffer putLong(int, long);
+ method public final java.nio.ByteBuffer putShort(short);
+ method public final java.nio.ByteBuffer putShort(int, short);
method public final void setAccessible(boolean);
+ method public final java.nio.MappedByteBuffer slice();
+ method public final java.nio.MappedByteBuffer slice(int, int);
}
public final class NIOAccess {
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
index a0a66b87219..f1de769e528 100644
--- a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
+++ b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
@@ -159,8 +159,9 @@ public final class ZygoteHooks {
@SystemApi(client = MODULE_LIBRARIES)
public static void preFork() {
Daemons.stop();
+ // At this point Daemons have been joined, but they may still be Unregister()ing.
+ // We wait for that as part of nativePreFork().
token = nativePreFork();
- waitUntilAllThreadsStopped();
}
/**
@@ -259,17 +260,4 @@ public final class ZygoteHooks {
String instructionSet);
private static native boolean nativeZygoteLongSuspendOk();
-
- /**
- * We must not fork until we're single-threaded again. Wait until /proc shows we're
- * down to just one thread.
- */
- private static void waitUntilAllThreadsStopped() {
- File tasks = new File("/proc/self/task");
- // All Java daemons are stopped already. We're just waiting for their OS counterparts to
- // finish as well. This shouldn't take much time so spinning is ok here.
- while (tasks.list().length > 1) {
- Thread.yield();
- }
- }
}
diff --git a/expectations/skippedCtsTest.txt b/expectations/skippedCtsTest.txt
index a17b67cd36a..4ee04feb36c 100644
--- a/expectations/skippedCtsTest.txt
+++ b/expectations/skippedCtsTest.txt
@@ -1,67 +1,131 @@
+/* Do not modify directly.
+ * Generated by tools/non-cts-json-generator/update_skippedCtsTest.sh
+ * which dumps all @NonCts tests.
+ */
[
-{
- bug: 287231726,
- description: "This test doesn't test public APIs.",
- result: EXEC_FAILED,
- names: [
- "libcore.libcore.icu.DateIntervalFormatTest",
- "libcore.libcore.icu.ICUTest",
- "libcore.libcore.icu.LocaleDataTest",
- "libcore.sun.misc.SharedSecretsTest"
- ]
-},
-{
- bug: 287231726,
- description: "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed / changed in the future ART module version.",
- result: EXEC_FAILED,
- names: [
- "libcore.java.lang.ClassTest#test_toGenericString",
- "libcore.java.util.CurrencyTest#test_localeExtension",
- "libcore.java.text.OldDecimalFormatSymbolsTest#test_RIHarmony_compatible",
- "libcore.java.text.OldNumberFormatTest#test_getCurrencyInstanceLjava_util_Locale",
- "org.apache.harmony.tests.java.util.ArrayDequeTest#test_forEachRemaining_CME",
- "org.apache.harmony.tests.java.util.ArrayDequeTest#test_iterator",
- "org.apache.harmony.tests.java.lang.Character_UnicodeBlockTest#test_ofC",
- "org.apache.harmony.tests.java.lang.Character_UnicodeBlockTest#test_ofI",
- "org.apache.harmony.tests.java.util.PriorityQueueTest#test_remove_Ljava_lang_Object_not_Compatible",
- "org.apache.harmony.tests.java.util.PriorityQueueTest#test_spliterator_CME",
- "org.apache.harmony.regex.tests.java.util.regex.PatternTest#testSplitAsStream"
- ]
-},
-{
- bug: 287231726,
- description: "The test depends on locale, but manufacturers / CLDR improves the locale data over time",
- result: EXEC_FAILED,
- names: [
- "libcore.java.text.DecimalFormatTest#testLocaleGroupingSeparator",
- "libcore.java.text.DecimalFormatTest#testSetGroupingSeparator"
- ]
-},
-{
- bug: 286802267,
- description: "The test depends on internal APIs.",
- result: EXEC_FAILED,
- names: [
- "test.java.time.TestClock_System#test_OffsetLimits",
- "test.java.time.TestClock_System#test_OffsetRegular"
- ]
-},
-{
- bug: 286802267,
- description: "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed / changed in the future ART module version.",
- result: EXEC_FAILED,
- names: [
- "tck.java.time.TCKYear#factory_parse_fail",
- "tck.java.time.format.TCKDateTimeParseResolver#test_resolveAmPm"
- ]
-},
-{
- bug: 286802267,
- description: "The test depends on locale, but manufacturers / CLDR improves the locale data over time",
- result: EXEC_FAILED,
- names: [
- "test.java.time.format.TestUnicodeExtension#test_localizedBy",
- "test.java.util.TestFormatter#test"
- ]
-}
-]
+ {
+ "description": "Algorithm might not be available in the future",
+ "names": [
+ "libcore.java.util.random.RandomGeneratorFactoryTest#createsL64X256MixRandomInstance"
+ ]
+ },
+ {
+ "description": "No guarantees are provided around available implementations",
+ "names": [
+ "libcore.java.util.random.RandomGeneratorFactoryTest#checkCurrentlyAvailableImplementations"
+ ]
+ },
+ {
+ "description": "Test for internal APIs.",
+ "names": [
+ "libcore.libcore.icu.DecimalFormatDataTest",
+ "libcore.libcore.icu.SimpleDateFormatDataTest"
+ ]
+ },
+ {
+ "bug": 259671905,
+ "description": "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed in a new mainline module version.",
+ "names": [
+ "org.apache.harmony.security.tests.java.security.ProviderTest#testForEachCME"
+ ]
+ },
+ {
+ "bug": 260847206,
+ "description": "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed in a new mainline module version.",
+ "names": [
+ "org.apache.harmony.tests.javax.security.OldSHA1PRNGSecureRandomTest#testGenerateSeedint01"
+ ]
+ },
+ {
+ "bug": 286802267,
+ "description": "Test for internal APIs.",
+ "names": [
+ "test.java.time.TestClock_System#test_OffsetLimits",
+ "test.java.time.TestClock_System#test_OffsetRegular"
+ ]
+ },
+ {
+ "bug": 286802267,
+ "description": "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed in a new mainline module version.",
+ "names": [
+ "tck.java.time.TCKYear#factory_parse_fail",
+ "tck.java.time.format.TCKDateTimeParseResolver#test_resolveAmPm"
+ ]
+ },
+ {
+ "bug": 286802267,
+ "description": "The test depends on locale, but manufacturers \/ CLDR improves the locale data over time.",
+ "names": [
+ "test.java.time.format.TestUnicodeExtension#test_localizedBy",
+ "test.java.util.TestFormatter#test"
+ ]
+ },
+ {
+ "bug": 287231726,
+ "description": "Test for internal APIs.",
+ "names": [
+ "libcore.jdk.internal.access.SharedSecretsTest",
+ "libcore.libcore.icu.DateIntervalFormatTest",
+ "libcore.libcore.icu.ICUTest",
+ "libcore.libcore.icu.LocaleDataTest"
+ ]
+ },
+ {
+ "bug": 287231726,
+ "description": "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed in a new mainline module version.",
+ "names": [
+ "libcore.java.lang.ClassTest#test_toGenericString",
+ "libcore.java.lang.ClassTest#toGenericString",
+ "libcore.java.text.OldDecimalFormatSymbolsTest#test_RIHarmony_compatible",
+ "libcore.java.text.OldNumberFormatTest#test_getCurrencyInstanceLjava_util_Locale",
+ "libcore.java.util.CurrencyTest#test_localeExtension",
+ "org.apache.harmony.regex.tests.java.util.regex.PatternTest#testSplitAsStream",
+ "org.apache.harmony.tests.java.lang.Character_UnicodeBlockTest#test_ofC",
+ "org.apache.harmony.tests.java.lang.Character_UnicodeBlockTest#test_ofI",
+ "org.apache.harmony.tests.java.util.ArrayDequeTest#test_forEachRemaining_CME",
+ "org.apache.harmony.tests.java.util.ArrayDequeTest#test_iterator",
+ "org.apache.harmony.tests.java.util.PriorityQueueTest#test_remove_Ljava_lang_Object_not_Compatible"
+ ]
+ },
+ {
+ "bug": 287231726,
+ "description": "The test depends on locale, but manufacturers \/ CLDR improves the locale data over time.",
+ "names": [
+ "libcore.java.text.DecimalFormatTest#testLocaleGroupingSeparator",
+ "libcore.java.text.DecimalFormatTest#testSetGroupingSeparator"
+ ]
+ },
+ {
+ "bug": 310050493,
+ "description": "Test for internal APIs.",
+ "names": [
+ "libcore.java.util.UUIDTest#testCurrentImplementation_invalidInputs",
+ "libcore.java.util.UUIDTest#testJava11Implementation_invalidInputs",
+ "libcore.java.util.UUIDTest#testJava8Implementation_allowsLongInputs"
+ ]
+ },
+ {
+ "bug": 310050493,
+ "description": "The test asserts buggy or non-breaking behaviors, but the behavior has been fixed in a new mainline module version.",
+ "names": [
+ "com.android.org.conscrypt.NativeCryptoArgTest#evpMethods",
+ "com.android.org.conscrypt.javax.crypto.CipherTest#test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_noIV",
+ "libcore.java.util.zip.GZIPOutputStreamTest#testShortMessage",
+ "org.apache.harmony.tests.java.util.zip.ZipOutputStreamTest#test_exttSupport"
+ ]
+ },
+ {
+ "bug": 316502724,
+ "description": "SharedSecrets class is at different location in newer ART versions",
+ "names": [
+ "libcore.sun.misc.SharedSecretsTest#testGetJavaIOFileDescriptorAccess_notNull"
+ ]
+ },
+ {
+ "bug": 316502724,
+ "description": "The test was removed and its no longer throws CME",
+ "names": [
+ "org.apache.harmony.tests.java.util.PriorityQueueTest#test_spliterator_CME"
+ ]
+ }
+] \ No newline at end of file
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
index 477a8e2a26a..05d19929bfa 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ProcessManagerTest.java
@@ -16,6 +16,8 @@
package org.apache.harmony.tests.java.lang;
+import android.platform.test.annotations.LargeTest;
+
import junit.framework.TestCase;
import java.io.BufferedReader;
@@ -25,12 +27,24 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
public class ProcessManagerTest extends TestCase {
Thread thread = null;
Process process = null;
boolean isThrown = false;
+ private static final Path TEMP_DIR;
+
+ static {
+ try {
+ TEMP_DIR = Files.createTempDirectory("process-manager-test");
+ TEMP_DIR.toFile().deleteOnExit();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
public void testCat() throws IOException, InterruptedException {
String[] commands = { "cat" };
@@ -156,24 +170,22 @@ public class ProcessManagerTest extends TestCase {
thread.start();
}
+ @LargeTest
public void testHeavyLoad() {
int i;
- for (i = 0; i < 100; i++)
+ for (i = 0; i < 30; i++)
stuff();
}
private static void stuff() {
Runtime rt = Runtime.getRuntime();
try {
- Process proc = rt.exec("ls");
+ Process proc = rt.exec("ls " + TEMP_DIR.toString());
proc.waitFor();
- proc = null;
} catch (Exception ex) {
System.err.println("Failure: " + ex);
throw new RuntimeException(ex);
}
- rt.gc();
- rt = null;
}
FileOutputStream out;
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
index aca5247e8b6..d0f7430df01 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
@@ -2053,7 +2053,8 @@ public class DecimalFormatTest extends TestCase {
char current;
// BigInteger.
- iterator = new DecimalFormat().formatToCharacterIterator(new BigInteger("123456789"));
+ iterator = NumberFormat.getInstance(Locale.US)
+ .formatToCharacterIterator(new BigInteger("123456789"));
runStarts = new int[] { 0, 0, 0, 3, 4, 4, 4, 7, 8, 8, 8 };
runLimits = new int[] { 3, 3, 3, 4, 7, 7, 7, 8, 11, 11, 11 };
result = "123,456,789";
@@ -2068,7 +2069,7 @@ public class DecimalFormatTest extends TestCase {
assertEquals(11, iterator.getEndIndex());
// For BigDecimal with multiplier test.
- DecimalFormat df = new DecimalFormat();
+ DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
df.setMultiplier(10);
iterator = df.formatToCharacterIterator(new BigDecimal("12345678901234567890"));
result = "123,456,789,012,345,678,900";
@@ -2079,7 +2080,7 @@ public class DecimalFormatTest extends TestCase {
}
// For BigDecimal with multiplier test.
- df = new DecimalFormat();
+ df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
df.setMultiplier(-1);
df.setMaximumFractionDigits(20);
iterator = df.formatToCharacterIterator(new BigDecimal("1.23456789012345678901"));
@@ -2090,7 +2091,8 @@ public class DecimalFormatTest extends TestCase {
current = iterator.next();
}
- iterator = new DecimalFormat().formatToCharacterIterator(new BigDecimal("1.23456789E301"));
+ iterator = NumberFormat.getInstance(Locale.US)
+ .formatToCharacterIterator(new BigDecimal("1.23456789E301"));
runStarts = new int[] { 0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14 };
runLimits = new int[] { 2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15 };
result = "12,345,678,900,"; // 000,000,000,000....
@@ -2104,7 +2106,8 @@ public class DecimalFormatTest extends TestCase {
assertEquals(0, iterator.getBeginIndex());
assertEquals(402, iterator.getEndIndex());
- iterator = new DecimalFormat().formatToCharacterIterator(new BigDecimal("1.2345678E4"));
+ iterator = NumberFormat.getInstance(Locale.US)
+ .formatToCharacterIterator(new BigDecimal("1.2345678E4"));
runStarts = new int[] { 0, 0, 2, 3, 3, 3, 6, 7, 7, 7 };
runLimits = new int[] { 2, 2, 3, 6, 6, 6, 7, 10, 10, 10 };
result = "12,345.678";
@@ -2128,7 +2131,8 @@ public class DecimalFormatTest extends TestCase {
Number number = new BigDecimal("1.23456789E1234");
assertEquals("1.23456789E+1234", number.toString());
- iterator = new DecimalFormat().formatToCharacterIterator(number);
+ iterator = NumberFormat.getInstance(Locale.US)
+ .formatToCharacterIterator(number);
runStarts = new int[] { 0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11, 11, 11, 14 };
runLimits = new int[] { 2, 2, 3, 6, 6, 6, 7, 10, 10, 10, 11, 14, 14, 14, 15 };
result = "12,345,678,900,"; // 000,000,000,000....
diff --git a/luni/src/main/java/javax/xml/datatype/DatatypeConfigurationException.java b/luni/src/main/java/javax/xml/datatype/DatatypeConfigurationException.java
index d46d2cd6de1..f4ae2915994 100644
--- a/luni/src/main/java/javax/xml/datatype/DatatypeConfigurationException.java
+++ b/luni/src/main/java/javax/xml/datatype/DatatypeConfigurationException.java
@@ -149,6 +149,8 @@ public class DatatypeConfigurationException extends Exception {
catch (Exception e) {}
}
+ // BEGIN Android-removed: private method not called within the class
+ /*
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
@@ -167,4 +169,6 @@ public class DatatypeConfigurationException extends Exception {
// Ignore exception
catch (Exception e) {}
}
+ */
+ // END Android-removed: private method not called within the class
}
diff --git a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
index aa7cde08301..f161747568d 100644
--- a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
+++ b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
@@ -48,7 +48,6 @@ public abstract class NetworkSecurityPolicy {
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
- @libcore.api.IntraCoreApi
public NetworkSecurityPolicy() {
}
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 8bb21eebd52..dca55a6f0c5 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -16,6 +16,23 @@
package libcore.java.net;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.SOCK_DGRAM;
+
+import static java.util.stream.Collectors.joining;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.system.ErrnoException;
+import android.system.Os;
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
@@ -48,11 +65,16 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import libcore.junit.junit3.TestCaseWithRules;
import libcore.junit.util.ResourceLeakageDetector;
+
+import org.junit.Ignore;
import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
import org.junit.rules.TestRule;
-
-public class SocketTest extends TestCaseWithRules {
+@RunWith(JUnit4.class)
+public class SocketTest {
@Rule
public TestRule resourceLeakageDetectorRule = ResourceLeakageDetector.getRule();
@@ -72,6 +94,7 @@ public class SocketTest extends TestCaseWithRules {
private static final int INET_ECN_MASK = 0x3;
// See http://b/2980559.
+ @Test
public void test_close() throws Exception {
Socket s = new Socket();
s.close();
@@ -84,6 +107,7 @@ public class SocketTest extends TestCaseWithRules {
* This means they give incorrect results on closed sockets (as well
* as requiring an unnecessary call into native code).
*/
+ @Test
public void test_getLocalAddress_after_close() throws Exception {
Socket s = new Socket();
try {
@@ -104,6 +128,7 @@ public class SocketTest extends TestCaseWithRules {
}
// http://code.google.com/p/android/issues/detail?id=7935
+ @Test
public void test_newSocket_connection_refused() throws Exception {
try {
new Socket("localhost", 80);
@@ -114,6 +139,7 @@ public class SocketTest extends TestCaseWithRules {
// http://code.google.com/p/android/issues/detail?id=3123
// http://code.google.com/p/android/issues/detail?id=1933
+ @Test
public void test_socketLocalAndRemoteAddresses() throws Exception {
checkSocketLocalAndRemoteAddresses(false);
checkSocketLocalAndRemoteAddresses(true);
@@ -247,6 +273,7 @@ public class SocketTest extends TestCaseWithRules {
// SocketOptions.setOption has weird behavior for setSoLinger/SO_LINGER.
// This test ensures we do what the RI does.
+ @Test
public void test_SocketOptions_setOption() throws Exception {
MySocketImpl impl = new MySocketImpl();
Socket s = new MySocket(impl);
@@ -295,6 +322,7 @@ public class SocketTest extends TestCaseWithRules {
assertEquals(sockImpl.value, value);
}
+ @Test
public void test_setTrafficClass() throws Exception {
try (Socket s = new Socket()) {
for (int i = 0; i <= 255; ++i) {
@@ -310,6 +338,7 @@ public class SocketTest extends TestCaseWithRules {
}
}
+ @Test
public void testReadAfterClose() throws Exception {
MockServer server = new MockServer();
server.enqueue(new byte[]{5, 3}, 0);
@@ -332,6 +361,7 @@ public class SocketTest extends TestCaseWithRules {
server.shutdown();
}
+ @Test
public void testWriteAfterClose() throws Exception {
MockServer server = new MockServer();
server.enqueue(new byte[0], 3);
@@ -352,6 +382,7 @@ public class SocketTest extends TestCaseWithRules {
}
// http://b/5534202
+ @Test
public void testAvailable() throws Exception {
for (int i = 0; i < 100; i++) {
assertAvailableReturnsZeroAfterSocketReadsAllData();
@@ -389,6 +420,7 @@ public class SocketTest extends TestCaseWithRules {
serverSocket.close();
}
+ @Test
public void testInitialState() throws Exception {
Socket s = new Socket();
try {
@@ -408,6 +440,7 @@ public class SocketTest extends TestCaseWithRules {
}
}
+ @Test
public void testStateAfterClose() throws Exception {
Socket s = new Socket();
s.bind(new InetSocketAddress(Inet4Address.getLocalHost(), 0));
@@ -425,6 +458,7 @@ public class SocketTest extends TestCaseWithRules {
assertEquals(boundAddress.getPort(), localAddressAfterClose.getPort());
}
+ @Test
public void testCloseDuringConnect() throws Exception {
// This address is reserved for documentation: should never be reachable and therefore
// is expected to produce block behavior when attempting to connect().
@@ -481,6 +515,7 @@ public class SocketTest extends TestCaseWithRules {
}
// http://b/29092095
+ @Test
public void testSocketWithProxySet() throws Exception {
ProxySelector ps = ProxySelector.getDefault();
try {
@@ -508,6 +543,7 @@ public class SocketTest extends TestCaseWithRules {
// b/25805791 + b/26470377
+ @Test
public void testFileDescriptorStaysSame() throws Exception {
// SocketImplementation FileDescriptor object shouldn't change after calling
// bind (and many other methods).
@@ -571,6 +607,7 @@ public class SocketTest extends TestCaseWithRules {
}
// b/26354315
+ @Test
public void testDoNotCallCloseFromSocketCtor() {
// Original openJdk7 Socket implementation may call Socket#close() inside a constructor.
// In this case, classes that extend Socket wont be fully constructed when they
@@ -635,6 +672,8 @@ public class SocketTest extends TestCaseWithRules {
}
// b/30007735
+ @Ignore("b/292238663")
+ @Test
public void testSocketTestAllAddresses() throws Exception {
checkLoopbackHost();
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index e823777ed5f..7b00d1d5488 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -30,6 +30,7 @@ import java.lang.reflect.Field;
import java.net.ContentHandler;
import java.net.ContentHandlerFactory;
import org.junit.After;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -3136,21 +3137,26 @@ public final class URLConnectionTest {
}
@Test public void noSslFallback_specifiedProtocols() throws Exception {
- String[] enabledProtocols = { "TLSv1.3", "TLSv1.2", "TLSv1.1" };
+ String[] platformProtocols = platformDefaultTlsProtocols();
+ Assume.assumeTrue(platformProtocols.length > 1);
+ // Leave out one protocol. First in the array will be the oldest protocol with
+ // Conscrypt, but it shouldn't matter which we omit.
+ String[] expectedProtocols =
+ Arrays.copyOfRange(platformProtocols, 1, platformProtocols.length);
+
TestSSLContext testSSLContext = createDefaultTestSSLContext();
SSLSocketFactory serverSocketFactory =
new LimitedProtocolsSocketFactory(
testSSLContext.serverContext.getSocketFactory(),
- enabledProtocols);
+ expectedProtocols);
SSLSocketFactory clientSocketFactory = new LimitedProtocolsSocketFactory(
- testSSLContext.clientContext.getSocketFactory(), enabledProtocols);
+ testSSLContext.clientContext.getSocketFactory(), expectedProtocols);
checkNoFallbackOnFailedHandshake(clientSocketFactory, serverSocketFactory,
- enabledProtocols);
+ expectedProtocols);
}
@Test public void noSslFallback_defaultProtocols() throws Exception {
- // Will need to be updated if the enabled protocols in Android's SSLSocketFactory change
- String[] expectedEnabledProtocols = { "TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1" };
+ String[] expectedEnabledProtocols = platformDefaultTlsProtocols();
TestSSLContext testSSLContext = createDefaultTestSSLContext();
SSLSocketFactory serverSocketFactory = testSSLContext.serverContext.getSocketFactory();
@@ -3159,6 +3165,13 @@ public final class URLConnectionTest {
expectedEnabledProtocols);
}
+ private String[] platformDefaultTlsProtocols() throws Exception {
+ try (SSLSocket socket = (SSLSocket) SSLContext.getDefault().getSocketFactory()
+ .createSocket()) {
+ return socket.getEnabledProtocols();
+ }
+ }
+
private static void assertSslSocket(TlsFallbackDisabledScsvSSLSocket socket,
boolean expectedWasFallbackScsvSet, String... expectedEnabledProtocols) {
Set<String> enabledProtocols =
diff --git a/luni/src/test/java/libcore/java/nio/CharBufferTest.java b/luni/src/test/java/libcore/java/nio/CharBufferTest.java
index 26e57783655..4b90444135f 100644
--- a/luni/src/test/java/libcore/java/nio/CharBufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/CharBufferTest.java
@@ -54,4 +54,12 @@ public class CharBufferTest extends TestCase {
assertEquals((int) low, cb.codePoints().toArray()[1]); // Unmatched surrogate.
assertEquals((int) '0', cb.codePoints().toArray()[2]);
}
+
+ public void testEmpty() {
+ String s = "Hello\n\tworld";
+ CharBuffer cb = CharBuffer.allocate(0);
+ assertTrue(cb.isEmpty());
+ cb = cb.allocate(32).append(s);
+ assertFalse(cb.isEmpty());
+ }
}
diff --git a/luni/src/test/java/libcore/java/nio/channels/MembershipKeyTest.java b/luni/src/test/java/libcore/java/nio/channels/MembershipKeyTest.java
index 427789d48f4..42c15600222 100644
--- a/luni/src/test/java/libcore/java/nio/channels/MembershipKeyTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/MembershipKeyTest.java
@@ -33,24 +33,25 @@ import java.nio.channels.MembershipKey;
public class MembershipKeyTest extends TestCase {
- private MembershipKey key;
- private final int PORT = 5000;
private final String TEST_MESSAGE = "hello";
+ private static final InetAddress MULTICAST_ADDRESS = getMulticastAddress();
+ private static final NetworkInterface NETWORK_INTERFACE = getNetworkInterface();
+
+ private MembershipKey key;
+ private int port = -1;
private DatagramChannel client;
- private InetAddress sourceAddress = Inet4Address.LOOPBACK;
- private final static InetAddress MULTICAST_ADDRESS = getMulticastAddress();
- private final static NetworkInterface NETWORK_INTERFACE = getNetworkInterface();
+ private final InetAddress sourceAddress = Inet4Address.LOOPBACK;
private void init(boolean withSource) throws Exception {
client = DatagramChannel.open(StandardProtocolFamily.INET)
- .bind(new InetSocketAddress(Inet4Address.ANY, PORT));
+ .bind(new InetSocketAddress(Inet4Address.ANY, 0));
client.configureBlocking(false);
-
if (withSource) {
key = client.join(MULTICAST_ADDRESS, NETWORK_INTERFACE, sourceAddress);
} else {
key = client.join(MULTICAST_ADDRESS, NETWORK_INTERFACE);
}
+ port = client.socket().getLocalPort();
}
@Override
@@ -107,7 +108,7 @@ public class MembershipKeyTest extends TestCase {
assertEquals(TEST_MESSAGE.length(), dc
.bind(new InetSocketAddress(Inet4Address.LOOPBACK, 0))
.send(ByteBuffer.wrap(TEST_MESSAGE.getBytes()),
- new InetSocketAddress(MULTICAST_ADDRESS, PORT)));
+ new InetSocketAddress(MULTICAST_ADDRESS, port)));
}
ByteBuffer buffer = ByteBuffer.allocate(1048);
@@ -173,7 +174,7 @@ public class MembershipKeyTest extends TestCase {
assertEquals(TEST_MESSAGE.length(), dc
.bind(new InetSocketAddress(Inet4Address.LOOPBACK, 0))
.send(ByteBuffer.wrap(TEST_MESSAGE.getBytes()),
- new InetSocketAddress(MULTICAST_ADDRESS, PORT)));
+ new InetSocketAddress(MULTICAST_ADDRESS, port)));
}
ByteBuffer buffer = ByteBuffer.allocate(1048);
@@ -223,14 +224,14 @@ public class MembershipKeyTest extends TestCase {
.bind(new InetSocketAddress(Inet4Address.LOOPBACK, 0))
.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true /* enable loop */)
.send(ByteBuffer.wrap(TEST_MESSAGE.getBytes()),
- new InetSocketAddress(MULTICAST_ADDRESS, PORT)));
+ new InetSocketAddress(MULTICAST_ADDRESS, port)));
}
ByteBuffer buffer = ByteBuffer.allocate(1048);
client.receive(buffer);
buffer.flip();
int limits = buffer.limit();
- byte bytes[] = new byte[limits];
+ byte[] bytes = new byte[limits];
buffer.get(bytes, 0, limits);
String receivedMessage = new String(bytes);
assertEquals(TEST_MESSAGE, receivedMessage);
diff --git a/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java b/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java
index fc09ae83125..8f968fe6fd9 100644
--- a/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/CertPathValidatorTest.java
@@ -28,6 +28,8 @@ import java.security.cert.PKIXRevocationChecker;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.security.cert.PKIXRevocationChecker.Option;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@@ -126,7 +128,11 @@ public class CertPathValidatorTest extends TestCaseWithRules {
}
public void test_OCSP_EndEntity_KeyCompromise_Failure() throws Exception {
- runOCSPStapledTest(new RevokedStatus(new Date(), CRLReason.keyCompromise), false);
+ // RFC 6960 isn't specific about what happens if the revocation time is the
+ // current second but RevocationChecker checks whether it's strictly before,
+ // so we subtract one second from now to be sure of the revocation check triggering.
+ Date date = Date.from(Instant.now().minus(1, ChronoUnit.SECONDS));
+ runOCSPStapledTest(new RevokedStatus(date, CRLReason.keyCompromise), false);
}
public void test_OCSP_EndEntity_Good_Success() throws Exception {
diff --git a/luni/src/test/java/libcore/java/text/DateFormatTest.java b/luni/src/test/java/libcore/java/text/DateFormatTest.java
index 5723b636d12..b19d55c008f 100644
--- a/luni/src/test/java/libcore/java/text/DateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DateFormatTest.java
@@ -18,6 +18,11 @@ package libcore.java.text;
import android.icu.util.VersionInfo;
+import dalvik.annotation.compat.VersionCodes;
+
+import libcore.test.annotation.NonMts;
+import libcore.test.reasons.NonMtsReasons;
+
import junit.framework.TestCase;
import java.text.DateFormat;
@@ -70,6 +75,8 @@ public class DateFormatTest extends TestCase {
}
/** Regression test for http://b/266731719. */
+ @NonMts(bug = 289015017, disabledUntilSdk = VersionCodes.UPSIDE_DOWN_CAKE,
+ reason = NonMtsReasons.OEM_CUSTOMIZATION)
public void testParse_lenient_en() throws ParseException {
assertParse_lenient_en(Locale.ENGLISH);
assertParse_lenient_en(Locale.US);
@@ -92,6 +99,8 @@ public class DateFormatTest extends TestCase {
}
/** Regression test for http://b/266731719. */
+ @NonMts(bug = 289015017, disabledUntilSdk = VersionCodes.UPSIDE_DOWN_CAKE,
+ reason = NonMtsReasons.OEM_CUSTOMIZATION)
public void testFormat_forBug266731719() {
assertFormat_forBug266731719(Locale.ENGLISH);
assertFormat_forBug266731719(Locale.US);
diff --git a/luni/src/test/java/libcore/java/time/format/DateTimeFormatterBuilderTest.java b/luni/src/test/java/libcore/java/time/format/DateTimeFormatterBuilderTest.java
index 215f4837fac..653ca937b57 100644
--- a/luni/src/test/java/libcore/java/time/format/DateTimeFormatterBuilderTest.java
+++ b/luni/src/test/java/libcore/java/time/format/DateTimeFormatterBuilderTest.java
@@ -25,8 +25,10 @@ import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.TextStyle;
import java.time.temporal.TemporalQueries;
import java.util.Locale;
+import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -89,4 +91,29 @@ public class DateTimeFormatterBuilderTest {
assertEquals(ZoneOffset.ofHours(1),
formatter.parse("+01:00").query(TemporalQueries.zoneId()));
}
+
+ @Test
+ public void test_appendGenericZoneText() {
+ DateTimeFormatter formatter = new DateTimeFormatterBuilder()
+ .appendGenericZoneText(TextStyle.FULL)
+ .toFormatter(Locale.US);
+
+ assertEquals("Pacific Time", formatter.format(
+ ZonedDateTime.now(ZoneId.of("America/Los_Angeles"))));
+
+ formatter = new DateTimeFormatterBuilder()
+ .appendGenericZoneText(TextStyle.SHORT)
+ .toFormatter(Locale.US);
+
+ assertEquals("PT", formatter.format(
+ ZonedDateTime.now(ZoneId.of("America/Los_Angeles"))));
+
+ formatter = new DateTimeFormatterBuilder()
+ .appendGenericZoneText(TextStyle.FULL, Set.of(ZoneId.of("America/Los_Angeles")))
+ .toFormatter(Locale.US);
+
+ // "America/Los_Angeles" is expected because the zone is in the preferred set.
+ assertEquals(ZoneId.of("America/Los_Angeles"),
+ formatter.parse("Pacific Time").query(TemporalQueries.zoneId()));
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/ArraysTest.java b/luni/src/test/java/libcore/java/util/ArraysTest.java
index a45ccd2bf6e..c2f2c546b6b 100644
--- a/luni/src/test/java/libcore/java/util/ArraysTest.java
+++ b/luni/src/test/java/libcore/java/util/ArraysTest.java
@@ -566,6 +566,28 @@ public class ArraysTest {
}
}
+ /**
+ * java.util.Array#parallelPrefix(T[], int, int, java.util.function.BinaryOperator<T>)
+ */
+ @Test
+ public void parallelPrefix$TII_biggerArray() {
+ String[] strings = new String[1_000];
+ int begin = 0, end = strings.length;
+
+ for (int i = 0; i < strings.length; ++i) {
+ strings[i] = String.valueOf(i);
+ }
+
+ Arrays.parallelPrefix(strings, begin, end, (x, y) -> x + y);
+
+ String currentPrefix = "";
+ for (int i = 0; i < strings.length; ++i) {
+ currentPrefix += String.valueOf(i);
+
+ assertEquals(currentPrefix, strings[i]);
+ }
+ }
+
// http://b/74236526
@Test
public void deepEquals_nestedArraysOfDifferentTypesButEqualValues() {
diff --git a/luni/src/test/java/libcore/java/util/FormatterTest.java b/luni/src/test/java/libcore/java/util/FormatterTest.java
index e54428f2092..f600e3bddf7 100644
--- a/luni/src/test/java/libcore/java/util/FormatterTest.java
+++ b/luni/src/test/java/libcore/java/util/FormatterTest.java
@@ -16,6 +16,8 @@
package libcore.java.util;
+import static org.junit.Assert.assertThrows;
+
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.File;
@@ -28,11 +30,13 @@ import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Calendar;
+import java.util.FormatFlagsConversionMismatchException;
import java.util.Formatter;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
+@SuppressWarnings("FormatString")
public class FormatterTest extends junit.framework.TestCase {
private File aFile;
@@ -292,4 +296,14 @@ public class FormatterTest extends junit.framework.TestCase {
// expected
}
}
+
+ public void test_floatWithAlternateForm() {
+ // when # flag is set, decimal separator is always present.
+ assertEquals("10.", new Formatter(Locale.US).format("%#.0f", 10.12).toString());
+ }
+
+ public void test_numberSignIsNotAllowed_inGeneralFormat() {
+ assertThrows(FormatFlagsConversionMismatchException.class,
+ () -> new Formatter(Locale.US).format("%#.1g", 10.1).toString());
+ }
}
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index f7f0074507a..2a87fc48679 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -160,13 +160,13 @@ public class LocaleTest extends junit.framework.TestCase {
}
public void test_getDisplayCountry_8870289() throws Exception {
- assertEquals("Hong Kong", new Locale("", "HK").getDisplayCountry(Locale.US));
- assertEquals("Palestine", new Locale("", "PS").getDisplayCountry(Locale.US));
+ assertTrue(new Locale("", "HK").getDisplayCountry(Locale.US).contains("Hong Kong"));
+ assertTrue(new Locale("", "PS").getDisplayCountry(Locale.US).contains("Palestine"));
- assertEquals("Cocos (Keeling) Islands", new Locale("", "CC").getDisplayCountry(Locale.US));
- assertEquals("Falkland Islands (Islas Malvinas)", new Locale("", "FK").getDisplayCountry(Locale.US));
- assertEquals("Myanmar (Burma)", new Locale("", "MM").getDisplayCountry(Locale.US));
- assertEquals("Taiwan", new Locale("", "TW").getDisplayCountry(Locale.US));
+ assertTrue(new Locale("", "CC").getDisplayCountry(Locale.US).contains("Cocos (Keeling) Islands"));
+ assertTrue(new Locale("", "FK").getDisplayCountry(Locale.US).contains("Falkland Islands (Islas Malvinas)"));
+ assertTrue(new Locale("", "MM").getDisplayCountry(Locale.US).contains("Myanmar (Burma)"));
+ assertTrue(new Locale("", "TW").getDisplayCountry(Locale.US).contains("Taiwan"));
}
public void test_tl_and_fil() throws Exception {
diff --git a/luni/src/test/java/libcore/java/util/OptionalLongTest.java b/luni/src/test/java/libcore/java/util/OptionalLongTest.java
index 47858f35ff4..9c761a9c3ae 100644
--- a/luni/src/test/java/libcore/java/util/OptionalLongTest.java
+++ b/luni/src/test/java/libcore/java/util/OptionalLongTest.java
@@ -16,9 +16,14 @@
package libcore.java.util;
+import static org.junit.Assert.assertThrows;
+
import junit.framework.TestCase;
+import org.junit.Assert;
+
import java.io.IOException;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.OptionalLong;
import java.util.concurrent.atomic.AtomicLong;
@@ -90,6 +95,46 @@ public class OptionalLongTest extends TestCase {
assertFalse(OptionalLong.of(57).equals(OptionalLong.of(56)));
}
+ public void test_isPresentOrElse_whenEmpty() {
+ var heldValueHolder = new AtomicLong(-1);
+ var whenEmptyHolder = new AtomicLong(-1);
+
+ OptionalLong.empty().ifPresentOrElse(heldValueHolder::set, () -> whenEmptyHolder.set(42));
+
+ assertEquals(42, whenEmptyHolder.get());
+ assertEquals(-1, heldValueHolder.get());
+ }
+
+ public void test_isPresentOrElse_whenNonEmpty() {
+ var heldValueHolder = new AtomicLong(-1);
+ var whenEmptyHolder = new AtomicLong(-1);
+
+ OptionalLong.of(1001L).ifPresentOrElse(heldValueHolder::set, () -> whenEmptyHolder.set(42));
+
+ assertEquals(-1, whenEmptyHolder.get());
+ assertEquals(1001L, heldValueHolder.get());
+ }
+
+ public void test_orElseThrow_nonEmpty() {
+ assertEquals(43, OptionalLong.of(43).orElseThrow());
+ }
+
+ public void test_orElseThrow_empty() {
+ assertThrows(NoSuchElementException.class, () -> OptionalLong.empty().orElseThrow());
+ }
+
+ public void test_stream_nonEmpty() {
+ var elements = OptionalLong.of(42).stream().boxed().toList();
+
+ assertEquals(List.of(42L), elements);
+ }
+
+ public void test_stream_empty() {
+ var elements = OptionalLong.empty().stream().boxed().toList();
+
+ assertEquals(List.of(), elements);
+ }
+
public void testHashCode() {
assertEquals(Long.hashCode(57), OptionalLong.of(57).hashCode());
}
diff --git a/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java b/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java
index 2bedf7c9bc6..c63d53b1145 100644
--- a/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java
@@ -16,6 +16,8 @@
package libcore.java.util;
+import static org.junit.Assert.assertThrows;
+
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@@ -181,6 +183,33 @@ public class SimpleTimeZoneTest extends TestCase {
checkDstNewYork2014(timeZone);
}
+ public void testNegativeDST_isNotAllowed() {
+ assertThrows(IllegalArgumentException.class, () -> new SimpleTimeZone(
+ /* rawOffset= */ 0,
+ /* ID= */ "ID",
+ /* startMonth= */ Calendar.MARCH,
+ /* startDay= */ 0,
+ /* startDayOfWeek= */ Calendar.SUNDAY,
+ /* startTime= */ 0,
+ /* startTimeMode= */ 0,
+ /* endMonth= */ Calendar.NOVEMBER,
+ /* endDay= */ 0,
+ /* endDayOfWeek= */ Calendar.SUNDAY,
+ /* endTime= */ 0,
+ /* endTimeMode= */ 0,
+ /* dstSavings= */ -36_000)); // this is not valid according to the implementation.
+ }
+
+ public void testGetOffset_BC() {
+ var actualOffset = 123456;
+ TimeZone utc = new SimpleTimeZone(actualOffset, "LMT somewhere");
+
+ int returnedOffset =
+ utc.getOffset(GregorianCalendar.BC, 100, Calendar.JANUARY, 10, Calendar.SUNDAY, 0);
+
+ assertEquals(actualOffset, returnedOffset);
+ }
+
/**
* Check that the DST transitions in the supplied {@link TimeZone} are as expected for
* America/New_York in 2014.
diff --git a/luni/src/test/java/libcore/java/util/WeakHashMapTest.java b/luni/src/test/java/libcore/java/util/WeakHashMapTest.java
index a33eb826af3..2cac89af101 100644
--- a/luni/src/test/java/libcore/java/util/WeakHashMapTest.java
+++ b/luni/src/test/java/libcore/java/util/WeakHashMapTest.java
@@ -16,9 +16,14 @@
package libcore.java.util;
+import static org.junit.Assert.assertNotEquals;
+
import junit.framework.TestCase;
+import java.lang.reflect.Field;
import java.util.ConcurrentModificationException;
+import java.util.HashMap;
+import java.util.Map;
import java.util.WeakHashMap;
public class WeakHashMapTest extends TestCase {
@@ -68,6 +73,114 @@ public class WeakHashMapTest extends TestCase {
assertEquals(data.length, map.size());
}
+ public void testContainsNullValue() {
+ var map = new WeakHashMap<String, String>();
+
+ assertFalse(map.containsValue(null));
+
+ map.put("key", "value");
+
+ assertFalse(map.containsValue(null));
+
+ map.put("key", null);
+
+ assertTrue(map.containsValue(null));
+ }
+
+ public void testEntrySet_removeMapping() {
+ var map = new WeakHashMap<String, String>();
+ assertFalse(map.entrySet().remove(new Object()));
+
+ assertFalse(map.entrySet().remove(Map.entry("key", "value")));
+
+ map.put("key", "value");
+
+ assertTrue(map.entrySet().remove(Map.entry("key", "value")));
+ assertTrue(map.isEmpty());
+ }
+
+ public void testEntrySet_clear() {
+ var map = new WeakHashMap<String, String>();
+
+ map.put("key", "value");
+
+ map.entrySet().clear();
+
+ assertTrue(map.isEmpty());
+ }
+
+ public void testEntrySet_entrySetValue() {
+ var map = new WeakHashMap<String, String>();
+
+ map.put("key", "value");
+
+ var entry = map.entrySet().iterator().next();
+
+ entry.setValue("new value");
+
+ assertEquals("new value", map.get("key"));
+ }
+
+ public void testEntrySet_entryEquals() {
+ var map = new WeakHashMap<String, String>();
+
+ map.put("key", "value");
+
+ var entry = map.entrySet().iterator().next();
+
+ assertNotEquals(entry, new Object());
+ assertNotEquals(entry, Map.entry("key", "another value"));
+ }
+
+ public void testKeySet_remove() {
+ var map = new WeakHashMap<String, String>();
+
+ map.put("key", "value");
+ var keys = map.keySet();
+
+ assertFalse(keys.remove(new Object()));
+ }
+
+ public void testKeySet_clear() {
+ var map = new WeakHashMap<String, String>();
+
+ map.put("key", "value");
+ map.keySet().clear();
+
+ assertTrue(map.isEmpty());
+ }
+
+ public void testValues_clear() {
+ var map = new WeakHashMap<String, String>();
+
+ map.put("key", "value");
+ map.values().clear();
+
+ assertTrue(map.isEmpty());
+ }
+
+ public void test_putAll() throws Throwable {
+ var map = new WeakHashMap<String, String>();
+
+ int threshold = threshold(map);
+ var anotherMap = new HashMap<String, String>();
+
+ for (int i = 0; i < 2 * threshold; ++i) {
+ anotherMap.put(String.valueOf(i), "value");
+ }
+
+ // This should trigger resize.
+ map.putAll(anotherMap);
+
+ assertEquals(anotherMap, map);
+ }
+
+ private int threshold(WeakHashMap map) throws Exception {
+ Field threshold = map.getClass().getDeclaredField("threshold");
+ threshold.setAccessible(true);
+ return (int) threshold.get(map);
+ }
+
private void initializeData() {
for (int i = 0; i < data.length; i++) {
data[i] = new Data();
diff --git a/luni/src/test/java/libcore/javax/xml/datatype/DatatypeConfigurationExceptionTest.java b/luni/src/test/java/libcore/javax/xml/datatype/DatatypeConfigurationExceptionTest.java
index 3b6708d6b36..e26ca19a79f 100644
--- a/luni/src/test/java/libcore/javax/xml/datatype/DatatypeConfigurationExceptionTest.java
+++ b/luni/src/test/java/libcore/javax/xml/datatype/DatatypeConfigurationExceptionTest.java
@@ -16,13 +16,19 @@
package libcore.javax.xml.datatype;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import javax.xml.datatype.DatatypeConfigurationException;
+
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
@RunWith(JUnit4.class)
public class DatatypeConfigurationExceptionTest {
@@ -48,4 +54,35 @@ public class DatatypeConfigurationExceptionTest {
assertEquals("java.lang.Throwable", e.getMessage());
assertEquals(t, e.getCause());
}
+
+ @Test
+ public void testPrintStackTrace_noArgs() {
+ Throwable t = new Throwable();
+ DatatypeConfigurationException e = new DatatypeConfigurationException(t);
+ e.printStackTrace();
+ }
+
+ @Test
+ public void testPrintStackTrace_withPrintStream() {
+ Throwable t = new Throwable();
+ DatatypeConfigurationException e = new DatatypeConfigurationException(t);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos, true);
+ e.printStackTrace(ps);
+
+ assertNotEquals(-1, baos.toString().indexOf("javax.xml.datatype.DatatypeConfigurationException"));
+ }
+
+ @Test
+ public void testPrintStackTrace_withPrintWriter() {
+ Throwable t = new Throwable();
+ DatatypeConfigurationException e = new DatatypeConfigurationException(t);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(baos, true);
+ e.printStackTrace(pw);
+
+ assertNotEquals(-1, baos.toString().indexOf("javax.xml.datatype.DatatypeConfigurationException"));
+ }
}
diff --git a/luni/src/test/java/libcore/javax/xml/datatype/DatatypeFactoryTest.java b/luni/src/test/java/libcore/javax/xml/datatype/DatatypeFactoryTest.java
index d062d3cf666..59c3ba4e838 100644
--- a/luni/src/test/java/libcore/javax/xml/datatype/DatatypeFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/xml/datatype/DatatypeFactoryTest.java
@@ -91,6 +91,33 @@ public class DatatypeFactoryTest extends TestCase {
assertNull(duration);
}
+ public void testNewDurationDayTime_nullString() {
+ try {
+ factory.newDurationDayTime(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testNewDurationDayTime_lexicalRepresentationContainsY() {
+ try {
+ factory.newDurationDayTime("Y");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testNewDurationDayTime_lexicalRepresentationContainsM() {
+ try {
+ factory.newDurationDayTime("M");
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
public void testNewDurationDayTime_long() {
Duration duration = factory.newDuration(1000L);
assertEquals(0, duration.getYears());
@@ -107,6 +134,38 @@ public class DatatypeFactoryTest extends TestCase {
assertEquals(0, duration.getHours());
assertEquals(0, duration.getMinutes());
assertEquals(1, duration.getSeconds());
+
+ duration = factory.newDurationDayTime(-1000L);
+ assertEquals(0, duration.getYears());
+ assertEquals(0, duration.getMonths());
+ assertEquals(0, duration.getDays());
+ assertEquals(0, duration.getHours());
+ assertEquals(0, duration.getMinutes());
+ assertEquals(1, duration.getSeconds());
+
+ duration = factory.newDurationDayTime(0);
+ assertEquals(0, duration.getYears());
+ assertEquals(0, duration.getMonths());
+ assertEquals(0, duration.getDays());
+ assertEquals(0, duration.getHours());
+ assertEquals(0, duration.getMinutes());
+ assertEquals(0, duration.getSeconds());
+
+ duration = factory.newDurationDayTime(Long.MIN_VALUE);
+ assertEquals(0, duration.getYears());
+ assertEquals(0, duration.getMonths());
+ assertEquals(0, duration.getDays());
+ assertEquals(7, duration.getHours());
+ assertEquals(12, duration.getMinutes());
+ assertEquals(55, duration.getSeconds());
+
+ duration = factory.newDurationDayTime(12345L);
+ assertEquals(0, duration.getYears());
+ assertEquals(0, duration.getMonths());
+ assertEquals(0, duration.getDays());
+ assertEquals(0, duration.getHours());
+ assertEquals(0, duration.getMinutes());
+ assertEquals(12, duration.getSeconds());
}
public void testNewDurationYearMonth_bii() {
@@ -134,6 +193,33 @@ public class DatatypeFactoryTest extends TestCase {
assertNull(duration);
}
+ public void testNewDurationYearMonth_nullString() {
+ try {
+ factory.newDurationYearMonth(null);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testNewDurationYearMonth_lexicalRepresentationContainsD() {
+ try {
+ factory.newDurationYearMonth("D");
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testNewDurationYearMonth_lexicalRepresentationContainsT() {
+ try {
+ factory.newDurationYearMonth("T");
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
public void testNewDurationYearMonth_long() {
Duration duration = factory.newDurationYearMonth(1000);
assertEquals(0, duration.getYears());
@@ -162,10 +248,33 @@ public class DatatypeFactoryTest extends TestCase {
}
}
+ public void testNewInstance_nullClassLoader() {
+ try {
+ DatatypeFactory.newInstance("factoryClassName", null);
+ fail("Unexpectedly created new instance");
+ } catch (DatatypeConfigurationException expected) {
+ // class loading disabled
+ }
+ }
+
public void testNewXMLGregorianCalendar_iiiiiii() {
XMLGregorianCalendar calendar = factory.newXMLGregorianCalendar(
1, 2, 3, 4, 5, 6, 7, 0);
assertNull(calendar);
+
+ try {
+ factory.newXMLGregorianCalendar(1, 2, 3, 4, 5, 6, -1, 0);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ factory.newXMLGregorianCalendar(1, 2, 3, 4, 5, 6, 1001, 0);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
}
public void testNewXMLGregorianCalendarDate_iiii() {
@@ -181,6 +290,20 @@ public class DatatypeFactoryTest extends TestCase {
public void testNewXMLGregorianCalendarTime_iiiii() {
XMLGregorianCalendar calendar = factory.newXMLGregorianCalendarTime(4, 5, 6, 7, 0);
assertNull(calendar);
+
+ try {
+ factory.newXMLGregorianCalendarTime(4, 5, 6, -1, 0);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ try {
+ factory.newXMLGregorianCalendarTime(4, 5, 6, 1001, 0);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
}
public void testNewXMLGregorianCalendarTime_BigDecimal() {
@@ -238,6 +361,5 @@ public class DatatypeFactoryTest extends TestCase {
BigDecimal fractionalSecond, int timezone) {
return null;
}
-
}
}
diff --git a/luni/src/test/java/libcore/javax/xml/datatype/XMLGregorianCalendarTest.java b/luni/src/test/java/libcore/javax/xml/datatype/XMLGregorianCalendarTest.java
index 012facc595c..553724c72ee 100644
--- a/luni/src/test/java/libcore/javax/xml/datatype/XMLGregorianCalendarTest.java
+++ b/luni/src/test/java/libcore/javax/xml/datatype/XMLGregorianCalendarTest.java
@@ -15,6 +15,8 @@
*/
package libcore.javax.xml.datatype;
+import static org.junit.Assert.assertNotEquals;
+
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.GregorianCalendar;
@@ -65,6 +67,97 @@ public class XMLGregorianCalendarTest extends TestCase {
assertEquals(BigDecimal.valueOf(0.1), calendar.getFractionalSecond());
}
+ public void testEquals_differentObjectParam() {
+ assertNotEquals(Integer.valueOf(0), calendar);
+ }
+
+ public void testEquals_nullObjectParam() {
+ assertNotEquals(null, calendar);
+ }
+
+ public void testEquals_equalObjectParam() {
+ calendar.setYear(2023);
+ calendar.setMonth(6);
+ calendar.setDay(28);
+ calendar.setTime(23, 59, 59, BigDecimal.valueOf(0.1));
+
+ XMLGregorianCalendar anotherCalendar = new XMLGregorianCalendarImpl();
+ anotherCalendar.setYear(2023);
+ anotherCalendar.setMonth(6);
+ anotherCalendar.setDay(28);
+ anotherCalendar.setTime(23, 59, 59, BigDecimal.valueOf(0.1));
+
+ assertEquals(calendar, anotherCalendar);
+ }
+
+ public void testEquals_differentCalendarParam() {
+ calendar.setYear(2023);
+ calendar.setMonth(6);
+ calendar.setDay(28);
+ calendar.setTime(23, 59, 59, BigDecimal.valueOf(0.1));
+
+ XMLGregorianCalendar anotherCalendar = new XMLGregorianCalendarImpl();
+ anotherCalendar.setYear(2023);
+ anotherCalendar.setMonth(7); // different month
+ anotherCalendar.setDay(28);
+ anotherCalendar.setTime(23, 59, 59, BigDecimal.valueOf(0.1));
+
+ assertNotEquals(calendar, anotherCalendar);
+ }
+
+ public void testToString() {
+ calendar.setYear(2006);
+ calendar.setMonth(10);
+ calendar.setDay(23);
+ calendar.setTime(22, 15, 1, BigDecimal.valueOf(0.000000135));
+ calendar.setTimezone(0);
+
+ assertEquals(calendar.toXMLFormat(), calendar.toString());
+ }
+
+ public void testHashCode_sameTimeSameTimezone() {
+ calendar.setTimezone(0);
+
+ XMLGregorianCalendarImpl anotherCalendar = new XMLGregorianCalendarImpl();
+ anotherCalendar.setTimezone(0);
+
+ assertEquals(calendar.hashCode(), anotherCalendar.hashCode());
+ }
+
+ public void testHashCode_differentTimeSameTimezone() {
+ calendar.setTimezone(0);
+
+ XMLGregorianCalendarImpl anotherCalendar = new XMLGregorianCalendarImpl();
+ anotherCalendar.setHour(1);
+ anotherCalendar.setTimezone(0);
+
+ assertNotEquals(calendar.hashCode(), anotherCalendar.hashCode());
+ }
+
+ public void testHashCode_sameTimeDifferentTimezone() {
+ calendar.setHour(1);
+ calendar.setTimezone(0);
+
+ XMLGregorianCalendarImpl anotherCalendar = new XMLGregorianCalendarImpl();
+ anotherCalendar.setHour(1);
+ anotherCalendar.setMinute(30);
+ anotherCalendar.setTimezone(30);
+
+ assertEquals(calendar.hashCode(), anotherCalendar.hashCode());
+ }
+
+ public void testHashCode_differentTimeDifferentTimezone() {
+ calendar.setHour(1);
+ calendar.setTimezone(0);
+
+ XMLGregorianCalendarImpl anotherCalendar = new XMLGregorianCalendarImpl();
+ anotherCalendar.setHour(2);
+ anotherCalendar.setMinute(30);
+ anotherCalendar.setTimezone(30);
+
+ assertNotEquals(calendar.hashCode(), anotherCalendar.hashCode());
+ }
+
/**
* Stub implementation intended for test coverage.
*/
@@ -194,19 +287,26 @@ public class XMLGregorianCalendarTest extends TestCase {
@Override
public int compare(XMLGregorianCalendar rhs) {
- if (year != rhs.getYear()) return year - rhs.getYear();
- if (month != rhs.getMonth()) return month - rhs.getMonth();
- if (day != rhs.getDay()) return day - rhs.getDay();
- if (hour != rhs.getHour()) return hour - rhs.getHour();
- if (minute != rhs.getMinute()) return minute - rhs.getMinute();
- if (second != rhs.getSecond()) return second - rhs.getSecond();
- if (millisecond != rhs.getMillisecond()) return millisecond - getMillisecond();
- return fractional.subtract(rhs.getFractionalSecond()).intValue();
+ if (year != rhs.getYear()) return Integer.signum(year - rhs.getYear());
+ if (month != rhs.getMonth()) return Integer.signum(month - rhs.getMonth());
+ if (day != rhs.getDay()) return Integer.signum(day - rhs.getDay());
+ if (hour != rhs.getHour()) return Integer.signum(hour - rhs.getHour());
+ if (minute != rhs.getMinute()) return Integer.signum(minute - rhs.getMinute());
+ if (second != rhs.getSecond()) return Integer.signum(second - rhs.getSecond());
+ // edge case - millisecond is calculated from fractional second
+ if (getMillisecond() != rhs.getMillisecond())
+ return Integer.signum(getMillisecond() - rhs.getMillisecond());
+ return fractional.compareTo(rhs.getFractionalSecond());
}
@Override
public XMLGregorianCalendar normalize() {
- return null;
+ if (this.timezoneOffset == 30) {
+ this.minute -= 30;
+ this.timezoneOffset = 0;
+ }
+
+ return this;
}
@Override
diff --git a/luni/src/test/java/libcore/javax/xml/parsers/DocumentBuilderTest.java b/luni/src/test/java/libcore/javax/xml/parsers/DocumentBuilderTest.java
index e643bfd25ab..c7919f799c1 100644
--- a/luni/src/test/java/libcore/javax/xml/parsers/DocumentBuilderTest.java
+++ b/luni/src/test/java/libcore/javax/xml/parsers/DocumentBuilderTest.java
@@ -22,6 +22,7 @@ import static tests.support.Support_Xml.firstChildTextOf;
import static tests.support.Support_Xml.firstElementOf;
import javax.xml.parsers.DocumentBuilder;
+
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
@@ -29,6 +30,29 @@ import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
public class DocumentBuilderTest extends junit.framework.TestCase {
+ private static final DocumentBuilder BASE_DOCUMENT_BUILDER = new DocumentBuilder() {
+ @Override
+ public Document parse(InputSource is) { return null; }
+
+ @Override
+ public boolean isNamespaceAware() { return false; }
+
+ @Override
+ public boolean isValidating() { return false; }
+
+ @Override
+ public void setEntityResolver(EntityResolver er) {}
+
+ @Override
+ public void setErrorHandler(ErrorHandler eh) {}
+
+ @Override
+ public Document newDocument() { return null; }
+
+ @Override
+ public DOMImplementation getDOMImplementation() { return null; }
+ };
+
// http://code.google.com/p/android/issues/detail?id=2607
public void test_characterReferences() throws Exception {
assertEquals("aAb", firstChildTextOf(domOf("<p>a&#65;b</p>")));
@@ -73,33 +97,23 @@ public class DocumentBuilderTest extends junit.framework.TestCase {
}
public void testGetSchema() {
- DocumentBuilder db = new DocumentBuilder() {
- @Override
- public Document parse(InputSource is) { return null; }
-
- @Override
- public boolean isNamespaceAware() { return false; }
-
- @Override
- public boolean isValidating() { return false; }
-
- @Override
- public void setEntityResolver(EntityResolver er) {}
-
- @Override
- public void setErrorHandler(ErrorHandler eh) {}
-
- @Override
- public Document newDocument() { return null; }
-
- @Override
- public DOMImplementation getDOMImplementation() { return null; }
- };
+ try {
+ BASE_DOCUMENT_BUILDER.getSchema();
+ fail("Unexpectedly didn't throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {}
+ }
+ public void testReset() {
try {
- db.getSchema();
+ BASE_DOCUMENT_BUILDER.reset();
fail("Unexpectedly didn't throw UnsupportedOperationException");
} catch (UnsupportedOperationException expected) {}
}
+ public void testIsXIncludeAware() {
+ try {
+ BASE_DOCUMENT_BUILDER.isXIncludeAware();
+ fail("Unexpectedly didn't throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {}
+ }
}
diff --git a/luni/src/test/java/libcore/javax/xml/validation/SchemaFactoryTest.java b/luni/src/test/java/libcore/javax/xml/validation/SchemaFactoryTest.java
new file mode 100644
index 00000000000..2f05c2e0736
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/xml/validation/SchemaFactoryTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.xml.validation;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+
+import javax.xml.transform.Source;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+@RunWith(JUnit4.class)
+public class SchemaFactoryTest {
+ private static final SchemaFactory BASE_SCHEMA_FACTORY = new SchemaFactory() {
+ @Override
+ public boolean isSchemaLanguageSupported(String schemaLanguage) {
+ return false;
+ }
+
+ @Override
+ public void setErrorHandler(ErrorHandler errorHandler) {
+
+ }
+
+ @Override
+ public ErrorHandler getErrorHandler() {
+ return null;
+ }
+
+ @Override
+ public void setResourceResolver(LSResourceResolver resourceResolver) {
+
+ }
+
+ @Override
+ public LSResourceResolver getResourceResolver() {
+ return null;
+ }
+
+ @Override
+ public Schema newSchema(Source[] schemas) throws SAXException {
+ return null;
+ }
+
+ @Override
+ public Schema newSchema() throws SAXException {
+ return null;
+ }
+ };
+
+ @Test(expected = NullPointerException.class)
+ public void newInstance3_nullSchemaLanguage() {
+ SchemaFactory.newInstance(null, "factoryClassName", null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void newInstance3_nullFactoryClassName() {
+ SchemaFactory.newInstance("schemaLanguage", null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void newInstance3_ClassNotFoundException() throws ClassNotFoundException {
+ ClassLoader classLoader = mock(ClassLoader.class);
+ when(classLoader.loadClass(eq("factoryClassName")))
+ .thenThrow(new ClassNotFoundException());
+
+ SchemaFactory.newInstance("schemaLanguage", "factoryClassName", classLoader);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void getFeature_nullString() throws SAXNotRecognizedException, SAXNotSupportedException {
+ BASE_SCHEMA_FACTORY.getFeature(null);
+ }
+
+ @Test(expected = SAXNotRecognizedException.class)
+ public void getFeature_validString()
+ throws SAXNotRecognizedException, SAXNotSupportedException{
+ BASE_SCHEMA_FACTORY.getFeature("myFeature");
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void setFeature_nullString() throws SAXNotRecognizedException, SAXNotSupportedException {
+ BASE_SCHEMA_FACTORY.setFeature(null, true);
+ }
+
+ @Test(expected = SAXNotRecognizedException.class)
+ public void setFeature_validString()
+ throws SAXNotRecognizedException, SAXNotSupportedException{
+ BASE_SCHEMA_FACTORY.setFeature("myFeature", true);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void setProperty_nullString()
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ BASE_SCHEMA_FACTORY.setProperty(null, new Object());
+ }
+
+ @Test(expected = SAXNotRecognizedException.class)
+ public void setProperty_validString()
+ throws SAXNotRecognizedException, SAXNotSupportedException{
+ BASE_SCHEMA_FACTORY.setProperty("myProperty", new Object());
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void getProperty_nullString()
+ throws SAXNotRecognizedException, SAXNotSupportedException {
+ BASE_SCHEMA_FACTORY.getProperty(null);
+ }
+
+ @Test(expected = SAXNotRecognizedException.class)
+ public void getProperty_validString()
+ throws SAXNotRecognizedException, SAXNotSupportedException{
+ BASE_SCHEMA_FACTORY.getProperty("myProperty");
+ }
+}
diff --git a/luni/src/test/java/libcore/javax/xml/xpath/XPathExceptionTest.java b/luni/src/test/java/libcore/javax/xml/xpath/XPathExceptionTest.java
index 79e4707b730..13c8252125f 100644
--- a/luni/src/test/java/libcore/javax/xml/xpath/XPathExceptionTest.java
+++ b/luni/src/test/java/libcore/javax/xml/xpath/XPathExceptionTest.java
@@ -17,12 +17,18 @@
package libcore.javax.xml.xpath;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
import javax.xml.xpath.XPathException;
@RunWith(JUnit4.class)
@@ -35,10 +41,85 @@ public class XPathExceptionTest {
}
@Test
+ public void constructorWithStringNull() {
+ try {
+ XPathException unused = new XPathException((String) null);
+ fail("Expected NullPointerException with null String");
+ } catch (NullPointerException ex) {
+ // Expected
+ }
+ }
+
+ @Test
public void constructorWithThrowable() {
Throwable t = new Throwable();
XPathException e = new XPathException(t);
assertEquals("java.lang.Throwable", e.getMessage());
assertEquals(t, e.getCause());
}
+
+ @Test
+ public void constructorWithThrowableNull() {
+ try {
+ XPathException unused = new XPathException((Throwable) null);
+ fail("Expected NullPointerException with null Throwable");
+ } catch (NullPointerException ex) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void printStackTrace_noArgs() {
+ XPathException e = new XPathException("message");
+ e.printStackTrace();
+ }
+
+ @Test
+ public void printStackTraceWithPrintStream_nullCause() {
+ XPathException e = new XPathException("message");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos, true);
+ e.printStackTrace(ps);
+
+ assertNotEquals(-1, baos.toString().indexOf("javax.xml.xpath.XPathException"));
+ }
+
+ @Test
+ public void printStackTraceWithPrintStream_nonNullCause() {
+ XPathException e = new XPathException(new TestCauseException());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(baos, true);
+ e.printStackTrace(ps);
+
+ assertNotEquals(-1, baos.toString().indexOf("TestCauseException"));
+ assertNotEquals(-1, baos.toString().indexOf("javax.xml.xpath.XPathException"));
+ }
+
+ @Test
+ public void printStackTraceWithPrintWriter_nullCause() {
+ XPathException e = new XPathException("message");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(baos, true);
+ e.printStackTrace(pw);
+
+ assertNotEquals(-1, baos.toString().indexOf("javax.xml.xpath.XPathException"));
+ }
+
+ @Test
+ public void printStackTraceWithPrintWriter_nonNullCause() {
+ XPathException e = new XPathException(new TestCauseException());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(baos, true);
+ e.printStackTrace(pw);
+
+ assertNotEquals(-1, baos.toString().indexOf("TestCauseException"));
+ assertNotEquals(-1, baos.toString().indexOf("javax.xml.xpath.XPathException"));
+ }
+
+ // Defining a new exception to be used as cause in printStackTrace tests
+ private static class TestCauseException extends Throwable {}
}
diff --git a/luni/src/test/java/libcore/javax/xml/xpath/XPathFactoryTest.java b/luni/src/test/java/libcore/javax/xml/xpath/XPathFactoryTest.java
index d868eea18bb..6381c2a2ee4 100644
--- a/luni/src/test/java/libcore/javax/xml/xpath/XPathFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/xml/xpath/XPathFactoryTest.java
@@ -84,6 +84,14 @@ public class XPathFactoryTest {
// Expected
}
+ // URI with length 0
+ try {
+ XPathFactory factory = XPathFactory.newInstance("", factoryName, classLoader);
+ fail("Expected IllegalArgumentException Failed for URI with length 0");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
// Bad factory name
try {
final String badFactoryName = factoryName + "Bad";
@@ -94,10 +102,49 @@ public class XPathFactoryTest {
} catch (XPathFactoryConfigurationException e) {
}
+ // Null FactoryClassName
+ try {
+ XPathFactory factory = XPathFactory.newInstance(SUPPORTED_URI, null, classLoader);
+ fail("Expected XPathFactoryConfigurationException for null factoryClassName");
+ } catch (XPathFactoryConfigurationException e) {
+ // Expected
+ }
+
// Null ClassLoader
{
XPathFactory factory = XPathFactory.newInstance(SUPPORTED_URI, factoryName, null);
assertNotNull(factory);
}
}
+
+ @Test
+ public void newInstanceWithUri() throws Throwable {
+ // Null URI
+ {
+ try {
+ XPathFactory factory = XPathFactory.newInstance(null);
+ fail("Expected NPE Failed for null URI");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ // URI with length 0
+ {
+ try {
+ XPathFactory factory = XPathFactory.newInstance("");
+ fail("Expected IllegalArgumentException Failed for URI with length 0");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ // Bad URI
+ try {
+ XPathFactory factory = XPathFactory.newInstance(UNSUPPORTED_URI);
+ fail("Failed for " + UNSUPPORTED_URI);
+ } catch (XPathFactoryConfigurationException e) {
+ // Expected
+ }
+ }
}
diff --git a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
index e56dab394a0..48c44b36aae 100644
--- a/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
+++ b/luni/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
@@ -2220,7 +2220,7 @@ public class PatternTest extends TestCaseWithRules {
}
private int getExpectedEmptyStringSplitLength() {
- if (VMRuntime.getSdkVersion() >= VersionCodes.UPSIDE_DOWN_CAKE
+ if (VMRuntime.getSdkVersion() > VersionCodes.TIRAMISU
&& Compatibility.isChangeEnabled(
Pattern.SPLIT_AS_STREAM_RETURNS_SINGLE_EMPTY_STRING)) {
// The length is 1 because the javadoc says "If this pattern does not match any
diff --git a/luni/src/test/java/tests/security/interfaces/RSAKeyTest.java b/luni/src/test/java/tests/security/interfaces/RSAKeyTest.java
index 619a2ad0295..7a34b9b3ff3 100644
--- a/luni/src/test/java/tests/security/interfaces/RSAKeyTest.java
+++ b/luni/src/test/java/tests/security/interfaces/RSAKeyTest.java
@@ -34,9 +34,9 @@ public class RSAKeyTest extends TestCase {
*/
public void test_getModulus() throws Exception {
KeyFactory gen = KeyFactory.getInstance("RSA");
- final BigInteger n = BigInteger.valueOf(3233);
- final BigInteger d = BigInteger.valueOf(2753);
- final BigInteger e = BigInteger.valueOf(17);
+ final BigInteger n = Util.rsaCrtParam.getModulus();
+ final BigInteger d = Util.rsaCrtParam.getPrivateExponent();
+ final BigInteger e = Util.rsaCrtParam.getPublicExponent();
RSAKey key = null;
// Case 1: check private key
diff --git a/luni/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java b/luni/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java
index a5035a9e677..b9afd4dfa1a 100644
--- a/luni/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java
+++ b/luni/src/test/java/tests/security/interfaces/RSAPrivateKeyTest.java
@@ -30,8 +30,8 @@ public class RSAPrivateKeyTest extends TestCase {
*/
public void test_getPrivateExponent() throws Exception {
KeyFactory gen = KeyFactory.getInstance("RSA");
- final BigInteger n = BigInteger.valueOf(3233);
- final BigInteger d = BigInteger.valueOf(2753);
+ final BigInteger n = Util.rsaCrtParam.getModulus();
+ final BigInteger d = Util.rsaCrtParam.getPrivateExponent();
RSAPrivateKey key = (RSAPrivateKey) gen.generatePrivate(new RSAPrivateKeySpec(
n, d));
assertEquals("invalid private exponent", d, key.getPrivateExponent());
diff --git a/luni/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java b/luni/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java
index 09919af2edc..d56facf3695 100644
--- a/luni/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java
+++ b/luni/src/test/java/tests/security/interfaces/RSAPublicKeyTest.java
@@ -30,8 +30,8 @@ public class RSAPublicKeyTest extends TestCase {
*/
public void test_getPublicExponent() throws Exception {
KeyFactory gen = KeyFactory.getInstance("RSA");
- final BigInteger n = BigInteger.valueOf(3233);
- final BigInteger e = BigInteger.valueOf(17);
+ final BigInteger n = Util.rsaCrtParam.getModulus();
+ final BigInteger e = Util.rsaCrtParam.getPublicExponent();
RSAPublicKey key = (RSAPublicKey) gen.generatePublic(new RSAPublicKeySpec(
n, e));
assertEquals("invalid public exponent", e, key.getPublicExponent());
diff --git a/luni/src/test/java/tests/security/interfaces/Util.java b/luni/src/test/java/tests/security/interfaces/Util.java
index a6ba36d91bb..a482c52475f 100644
--- a/luni/src/test/java/tests/security/interfaces/Util.java
+++ b/luni/src/test/java/tests/security/interfaces/Util.java
@@ -64,10 +64,73 @@ class Util {
* Valid RSA parameters
*/
static final RSAPrivateCrtKeySpec rsaCrtParam = new RSAPrivateCrtKeySpec(
- BigInteger.valueOf(3233), BigInteger.valueOf(17),
- BigInteger.valueOf(2753), BigInteger.valueOf(61),
- BigInteger.valueOf(53), BigInteger.valueOf(53),
- BigInteger.valueOf(49), BigInteger.valueOf(52));
+ new BigInteger(
+ "ab07c37595818b1c0e543c8a0f157e932c7e7be59a45b7575b4101560f"
+ + "270bd4bc33e62da586b33baae8a51b4f30c3166e0e065984"
+ + "6b6915a5a8d5e50de6952989835fed9d271d371de66429d5"
+ + "565e8cd92f11e3c35777ae119b98c3c1d8683589e181bbc1"
+ + "0202db748fa07d0e81c66f33089f2641351ff85c86ede32d"
+ + "a17dd4398d324ea7feb9eb9341bd16f5a525a64696fbf7b1"
+ + "447ad227a4fd3ec95b4674a87f0fb4bf9459d812ded94437"
+ + "8b55e5dd2cfa9e154f0b8a606aaa7ff1411bd989d66a73e8"
+ + "76985d9a87c022b23997e497aa9addcbd76aabff6dc0b661"
+ + "53233aa4f71e63460d6a0814d19e26f91bb6cc562dc815d8"
+ + "0fd619d952d33cbb511c6f",
+ 16),
+ BigInteger.valueOf(65537),
+ new BigInteger(
+ "04e9fd30b4b1fb283c3529642218d101338712d23f037fc80fc42760ac"
+ + "a0c7933e31138cfe338794d04d4ce922f658b49d46e3e1d0"
+ + "8f317ec0bac0228baab3607526042c94965a1d8a4b63575c"
+ + "5cd5eca014dd23b92a1b3332285154568e7c380595282017"
+ + "e491e6724bea258db426da6d11f358ab08f6b93117636062"
+ + "a040383baf7f065696f0f5235be275787742c6d5a0c5052f"
+ + "ad6878078f8f1801f0187b8793984a31135ab522c789bdcd"
+ + "02b9fca48136b090b7d2b7e69f961109fa3ac7edc9c11176"
+ + "c719a4ba960b7cacf8af291d35f55c8427f373f019185608"
+ + "2a57c885b195e6350a37ef9e120fa05a0a65ece5f3124204"
+ + "6bd8ac9b4d0f45b94ad361",
+ 16),
+ new BigInteger(
+ "eb68d3cd6a402405c59e59d69ea5a998f0310a232ebcaa3bab1bec9888"
+ + "125ea7afb3acc65f718187c609e03d422699f387a740a929"
+ + "48229f0a1bf988a6cdf83b8ba989c51881af21f39519b8b4"
+ + "04820db3ff7e92bc691c29319f315de074d66e14ca5a67fa"
+ + "76eef3ebe49ca31a4bb33f56d1006d04960051524a4f0df4"
+ + "0838f1",
+ 16),
+ new BigInteger(
+ "b9fd63d45c6e921487361b25d6d4a056b27e0e62e4e1408dc80ba08c03"
+ + "0110a339e62ffa4a2c642497c9588e66d7c03f377f09ca95"
+ + "c7a1da6eb6773c9ef9e6d312bf51a15fb7f25d792990b312"
+ + "d2c5ed229adab2fe8258508ff193add0599dd876543f51c5"
+ + "1279329ccd3beb3d78542179b978cb66de27d665e7f20ff9"
+ + "ebab5f",
+ 16),
+ new BigInteger(
+ "d6d775ad5bd1abce84bb6edc1b2fafa77f56121d67d3113da17cbba1bd"
+ + "559e83452c227b6cb1a7786539b027d80e68a443e25575cc"
+ + "d2239ea7d83e1503bea85497b2a3a478282ad03e808dd7ee"
+ + "9acaa27ceaa8f67bf3259b46c93581aa8e97002203471cec"
+ + "0dcd2859d9eb46438260d5668319f364a30d292a83dcc02c"
+ + "3db0d1",
+ 16),
+ new BigInteger(
+ "94ede00866536bc9e05364fdb1bee4fd47444544cf3dc7b140647f145e"
+ + "3b76151e01c29d4ad3ad04d83e34192324d41e4ad4010525"
+ + "568bb61b3d24d1780367dfd07d3e62580135a3bfa796e4ad"
+ + "c7f51163ca582148471b6cb7369c286c53b65f64b1255ad6"
+ + "d16a172b13f44cf415ec5839de5869975f80cadf2311e3d5"
+ + "1def45",
+ 16),
+ new BigInteger(
+ "cd611f5e9698258144c87f14326ac40ef0070c447f28a20022a0fa62b2"
+ + "41ebce6a581bcb4754684bae886dcc893aca6390dd368718"
+ + "8e3b80035827a72f050f0356c784922b5d15be932658d427"
+ + "fa122adb87d7d1f32bdf19743c25543f3728d8f55a1d55d6"
+ + "b23cd8223690bd7e594c64517acd5bf925b32dfe56b09d05"
+ + "7b4668",
+ 16));
/**
* Valid EC parameters
diff --git a/mmodules/intracoreapi/api/intra/current.txt b/mmodules/intracoreapi/api/intra/current.txt
index ca1b6748768..003c067cfb7 100644
--- a/mmodules/intracoreapi/api/intra/current.txt
+++ b/mmodules/intracoreapi/api/intra/current.txt
@@ -127,7 +127,6 @@ package libcore.io {
package libcore.net {
@libcore.api.IntraCoreApi public abstract class NetworkSecurityPolicy {
- ctor @libcore.api.IntraCoreApi public NetworkSecurityPolicy();
method @libcore.api.IntraCoreApi public static libcore.net.NetworkSecurityPolicy getInstance();
method @libcore.api.IntraCoreApi public abstract boolean isCertificateTransparencyVerificationRequired(String);
}
diff --git a/ojluni/src/main/java/java/math/BigInteger.java b/ojluni/src/main/java/java/math/BigInteger.java
index cc9b890436d..20fee1d589b 100644
--- a/ojluni/src/main/java/java/math/BigInteger.java
+++ b/ojluni/src/main/java/java/math/BigInteger.java
@@ -1848,6 +1848,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
}
}
+ // BEGIN Android-removed: Fall back to boringssl for large problems.
/**
* Multiplies two BigIntegers using the Karatsuba multiplication
* algorithm. This is a recursive divide-and-conquer algorithm which is
@@ -1863,6 +1864,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
*
* See: http://en.wikipedia.org/wiki/Karatsuba_algorithm
*/
+ /*
private static BigInteger multiplyKaratsuba(BigInteger x, BigInteger y) {
int xlen = x.mag.length;
int ylen = y.mag.length;
@@ -1892,6 +1894,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
return result;
}
}
+ */
/**
* Multiplies two BigIntegers using a 3-way Toom-Cook multiplication
@@ -1921,6 +1924,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
* LNCS #4547. Springer, Madrid, Spain, June 21-22, 2007.
*
*/
+ /*
private static BigInteger multiplyToomCook3(BigInteger a, BigInteger b) {
int alen = a.mag.length;
int blen = b.mag.length;
@@ -1981,6 +1985,8 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
return result;
}
}
+ */
+ // END Android-removed: Fall back to boringssl for large problems.
/**
@@ -2475,23 +2481,28 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
return a.divideKnuth(b, q).toBigInteger(this.signum);
}
+ // BEGIN Android-removed: Fall back to boringssl for large problems.
/**
* Calculates {@code this / val} using the Burnikel-Ziegler algorithm.
* @param val the divisor
* @return {@code this / val}
*/
+ /*
private BigInteger divideBurnikelZiegler(BigInteger val) {
return divideAndRemainderBurnikelZiegler(val)[0];
}
+ */
/**
* Calculates {@code this % val} using the Burnikel-Ziegler algorithm.
* @param val the divisor
* @return {@code this % val}
*/
+ /*
private BigInteger remainderBurnikelZiegler(BigInteger val) {
return divideAndRemainderBurnikelZiegler(val)[1];
}
+ */
/**
* Computes {@code this / val} and {@code this % val} using the
@@ -2499,6 +2510,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
* @param val the divisor
* @return an array containing the quotient and remainder
*/
+ /*
private BigInteger[] divideAndRemainderBurnikelZiegler(BigInteger val) {
MutableBigInteger q = new MutableBigInteger();
MutableBigInteger r = new MutableBigInteger(this).divideAndRemainderBurnikelZiegler(new MutableBigInteger(val), q);
@@ -2506,6 +2518,8 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
BigInteger rBigInt = r.isZero() ? ZERO : r.toBigInteger(signum);
return new BigInteger[] {qBigInt, rBigInt};
}
+ */
+ // END Android-removed: Fall back to boringssl for large problems.
/**
* Returns a BigInteger whose value is <code>(this<sup>exponent</sup>)</code>.
diff --git a/ojluni/src/main/java/java/text/MergeCollation.java b/ojluni/src/main/java/java/text/MergeCollation.java
deleted file mode 100644
index 1b092ed207a..00000000000
--- a/ojluni/src/main/java/java/text/MergeCollation.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved
- *
- * The original version of this source code and documentation is copyrighted
- * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
- * materials are provided under terms of a License Agreement between Taligent
- * and Sun. This technology is protected by multiple US and International
- * patents. This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- *
- */
-
-package java.text;
-
-import java.util.ArrayList;
-
-/**
- * Utility class for normalizing and merging patterns for collation.
- * Patterns are strings of the form <entry>*, where <entry> has the
- * form:
- * <pattern> := <entry>*
- * <entry> := <separator><chars>{"/"<extension>}
- * <separator> := "=", ",", ";", "<", "&"
- * <chars>, and <extension> are both arbitrary strings.
- * unquoted whitespaces are ignored.
- * 'xxx' can be used to quote characters
- * One difference from Collator is that & is used to reset to a current
- * point. Or, in other words, it introduces a new sequence which is to
- * be added to the old.
- * That is: "a < b < c < d" is the same as "a < b & b < c & c < d" OR
- * "a < b < d & b < c"
- * XXX: make '' be a single quote.
- * @see PatternEntry
- * @author Mark Davis, Helena Shih
- */
-
-final class MergeCollation {
-
- /**
- * Creates from a pattern
- * @throws ParseException If the input pattern is incorrect.
- */
- public MergeCollation(String pattern) throws ParseException
- {
- for (int i = 0; i < statusArray.length; i++)
- statusArray[i] = 0;
- setPattern(pattern);
- }
-
- /**
- * recovers current pattern
- */
- public String getPattern() {
- return getPattern(true);
- }
-
- /**
- * recovers current pattern.
- * @param withWhiteSpace puts spacing around the entries, and \n
- * before & and <
- */
- public String getPattern(boolean withWhiteSpace) {
- StringBuffer result = new StringBuffer();
- PatternEntry tmp = null;
- ArrayList<PatternEntry> extList = null;
- int i;
- for (i = 0; i < patterns.size(); ++i) {
- PatternEntry entry = patterns.get(i);
- if (!entry.extension.isEmpty()) {
- if (extList == null)
- extList = new ArrayList<>();
- extList.add(entry);
- } else {
- if (extList != null) {
- PatternEntry last = findLastWithNoExtension(i-1);
- for (int j = extList.size() - 1; j >= 0 ; j--) {
- tmp = extList.get(j);
- tmp.addToBuffer(result, false, withWhiteSpace, last);
- }
- extList = null;
- }
- entry.addToBuffer(result, false, withWhiteSpace, null);
- }
- }
- if (extList != null) {
- PatternEntry last = findLastWithNoExtension(i-1);
- for (int j = extList.size() - 1; j >= 0 ; j--) {
- tmp = extList.get(j);
- tmp.addToBuffer(result, false, withWhiteSpace, last);
- }
- extList = null;
- }
- return result.toString();
- }
-
- private final PatternEntry findLastWithNoExtension(int i) {
- for (--i;i >= 0; --i) {
- PatternEntry entry = patterns.get(i);
- if (entry.extension.isEmpty()) {
- return entry;
- }
- }
- return null;
- }
-
- /**
- * emits the pattern for collation builder.
- * @return emits the string in the format understable to the collation
- * builder.
- */
- public String emitPattern() {
- return emitPattern(true);
- }
-
- /**
- * emits the pattern for collation builder.
- * @param withWhiteSpace puts spacing around the entries, and \n
- * before & and <
- * @return emits the string in the format understable to the collation
- * builder.
- */
- public String emitPattern(boolean withWhiteSpace) {
- StringBuffer result = new StringBuffer();
- for (int i = 0; i < patterns.size(); ++i)
- {
- PatternEntry entry = patterns.get(i);
- if (entry != null) {
- entry.addToBuffer(result, true, withWhiteSpace, null);
- }
- }
- return result.toString();
- }
-
- /**
- * sets the pattern.
- */
- public void setPattern(String pattern) throws ParseException
- {
- patterns.clear();
- addPattern(pattern);
- }
-
- /**
- * adds a pattern to the current one.
- * @param pattern the new pattern to be added
- */
- public void addPattern(String pattern) throws ParseException
- {
- if (pattern == null)
- return;
-
- PatternEntry.Parser parser = new PatternEntry.Parser(pattern);
-
- PatternEntry entry = parser.next();
- while (entry != null) {
- fixEntry(entry);
- entry = parser.next();
- }
- }
-
- /**
- * gets count of separate entries
- * @return the size of pattern entries
- */
- public int getCount() {
- return patterns.size();
- }
-
- /**
- * gets count of separate entries
- * @param index the offset of the desired pattern entry
- * @return the requested pattern entry
- */
- public PatternEntry getItemAt(int index) {
- return patterns.get(index);
- }
-
- //============================================================
- // privates
- //============================================================
- ArrayList<PatternEntry> patterns = new ArrayList<>(); // a list of PatternEntries
-
- private transient PatternEntry saveEntry = null;
- private transient PatternEntry lastEntry = null;
-
- // This is really used as a local variable inside fixEntry, but we cache
- // it here to avoid newing it up every time the method is called.
- private transient StringBuffer excess = new StringBuffer();
-
- //
- // When building a MergeCollation, we need to do lots of searches to see
- // whether a given entry is already in the table. Since we're using an
- // array, this would make the algorithm O(N*N). To speed things up, we
- // use this bit array to remember whether the array contains any entries
- // starting with each Unicode character. If not, we can avoid the search.
- // Using BitSet would make this easier, but it's significantly slower.
- //
- private transient byte[] statusArray = new byte[8192];
- private final byte BITARRAYMASK = (byte)0x1;
- private final int BYTEPOWER = 3;
- private final int BYTEMASK = (1 << BYTEPOWER) - 1;
-
- /*
- If the strength is RESET, then just change the lastEntry to
- be the current. (If the current is not in patterns, signal an error).
- If not, then remove the current entry, and add it after lastEntry
- (which is usually at the end).
- */
- private final void fixEntry(PatternEntry newEntry) throws ParseException
- {
- // check to see whether the new entry has the same characters as the previous
- // entry did (this can happen when a pattern declaring a difference between two
- // strings that are canonically equivalent is normalized). If so, and the strength
- // is anything other than IDENTICAL or RESET, throw an exception (you can't
- // declare a string to be unequal to itself). --rtg 5/24/99
- if (lastEntry != null && newEntry.chars.equals(lastEntry.chars)
- && newEntry.extension.equals(lastEntry.extension)) {
- if (newEntry.strength != Collator.IDENTICAL
- && newEntry.strength != PatternEntry.RESET) {
- throw new ParseException("The entries " + lastEntry + " and "
- + newEntry + " are adjacent in the rules, but have conflicting "
- + "strengths: A character can't be unequal to itself.", -1);
- } else {
- // otherwise, just skip this entry and behave as though you never saw it
- return;
- }
- }
-
- boolean changeLastEntry = true;
- if (newEntry.strength != PatternEntry.RESET) {
- int oldIndex = -1;
-
- if ((newEntry.chars.length() == 1)) {
-
- char c = newEntry.chars.charAt(0);
- int statusIndex = c >> BYTEPOWER;
- byte bitClump = statusArray[statusIndex];
- byte setBit = (byte)(BITARRAYMASK << (c & BYTEMASK));
-
- if (bitClump != 0 && (bitClump & setBit) != 0) {
- oldIndex = patterns.lastIndexOf(newEntry);
- } else {
- // We're going to add an element that starts with this
- // character, so go ahead and set its bit.
- statusArray[statusIndex] = (byte)(bitClump | setBit);
- }
- } else {
- oldIndex = patterns.lastIndexOf(newEntry);
- }
- if (oldIndex != -1) {
- patterns.remove(oldIndex);
- }
-
- excess.setLength(0);
- int lastIndex = findLastEntry(lastEntry, excess);
-
- if (excess.length() != 0) {
- newEntry.extension = excess + newEntry.extension;
- if (lastIndex != patterns.size()) {
- lastEntry = saveEntry;
- changeLastEntry = false;
- }
- }
- if (lastIndex == patterns.size()) {
- patterns.add(newEntry);
- saveEntry = newEntry;
- } else {
- patterns.add(lastIndex, newEntry);
- }
- }
- if (changeLastEntry) {
- lastEntry = newEntry;
- }
- }
-
- private final int findLastEntry(PatternEntry entry,
- StringBuffer excessChars) throws ParseException
- {
- if (entry == null)
- return 0;
-
- if (entry.strength != PatternEntry.RESET) {
- // Search backwards for string that contains this one;
- // most likely entry is last one
-
- int oldIndex = -1;
- if ((entry.chars.length() == 1)) {
- int index = entry.chars.charAt(0) >> BYTEPOWER;
- if ((statusArray[index] &
- (BITARRAYMASK << (entry.chars.charAt(0) & BYTEMASK))) != 0) {
- oldIndex = patterns.lastIndexOf(entry);
- }
- } else {
- oldIndex = patterns.lastIndexOf(entry);
- }
- if ((oldIndex == -1))
- throw new ParseException("couldn't find last entry: "
- + entry, oldIndex);
- return oldIndex + 1;
- } else {
- int i;
- for (i = patterns.size() - 1; i >= 0; --i) {
- PatternEntry e = patterns.get(i);
- if (e.chars.regionMatches(0,entry.chars,0,
- e.chars.length())) {
- excessChars.append(entry.chars, e.chars.length(),
- entry.chars.length());
- break;
- }
- }
- if (i == -1)
- throw new ParseException("couldn't find: " + entry, i);
- return i + 1;
- }
- }
-}
diff --git a/ojluni/src/main/java/java/text/PatternEntry.java b/ojluni/src/main/java/java/text/PatternEntry.java
deleted file mode 100644
index 858c3152cb7..00000000000
--- a/ojluni/src/main/java/java/text/PatternEntry.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved
- *
- * The original version of this source code and documentation is copyrighted
- * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
- * materials are provided under terms of a License Agreement between Taligent
- * and Sun. This technology is protected by multiple US and International
- * patents. This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- *
- */
-
-package java.text;
-
-import java.lang.Character;
-
-/**
- * Utility class for normalizing and merging patterns for collation.
- * This is to be used with MergeCollation for adding patterns to an
- * existing rule table.
- * @see MergeCollation
- * @author Mark Davis, Helena Shih
- */
-
-class PatternEntry {
- /**
- * Gets the current extension, quoted
- */
- public void appendQuotedExtension(StringBuffer toAddTo) {
- appendQuoted(extension,toAddTo);
- }
-
- /**
- * Gets the current chars, quoted
- */
- public void appendQuotedChars(StringBuffer toAddTo) {
- appendQuoted(chars,toAddTo);
- }
-
- /**
- * WARNING this is used for searching in a Vector.
- * Because Vector.indexOf doesn't take a comparator,
- * this method is ill-defined and ignores strength.
- */
- public boolean equals(Object obj) {
- if (obj == null) return false;
- PatternEntry other = (PatternEntry) obj;
- boolean result = chars.equals(other.chars);
- return result;
- }
-
- public int hashCode() {
- return chars.hashCode();
- }
-
- /**
- * For debugging.
- */
- public String toString() {
- StringBuffer result = new StringBuffer();
- addToBuffer(result, true, false, null);
- return result.toString();
- }
-
- /**
- * Gets the strength of the entry.
- */
- final int getStrength() {
- return strength;
- }
-
- /**
- * Gets the expanding characters of the entry.
- */
- final String getExtension() {
- return extension;
- }
-
- /**
- * Gets the core characters of the entry.
- */
- final String getChars() {
- return chars;
- }
-
- // ===== privates =====
-
- void addToBuffer(StringBuffer toAddTo,
- boolean showExtension,
- boolean showWhiteSpace,
- PatternEntry lastEntry)
- {
- if (showWhiteSpace && toAddTo.length() > 0)
- if (strength == Collator.PRIMARY || lastEntry != null)
- toAddTo.append('\n');
- else
- toAddTo.append(' ');
- if (lastEntry != null) {
- toAddTo.append('&');
- if (showWhiteSpace)
- toAddTo.append(' ');
- lastEntry.appendQuotedChars(toAddTo);
- appendQuotedExtension(toAddTo);
- if (showWhiteSpace)
- toAddTo.append(' ');
- }
- var c = switch (strength) {
- case Collator.IDENTICAL -> '=';
- case Collator.TERTIARY -> ',';
- case Collator.SECONDARY -> ';';
- case Collator.PRIMARY -> '<';
- case RESET -> '&';
- case UNSET -> '?';
-
- default -> throw new IllegalStateException("Unexpected value: " + strength);
- };
- toAddTo.append(c);
-
- if (showWhiteSpace)
- toAddTo.append(' ');
- appendQuoted(chars,toAddTo);
- if (showExtension && !extension.isEmpty()) {
- toAddTo.append('/');
- appendQuoted(extension,toAddTo);
- }
- }
-
- static void appendQuoted(String chars, StringBuffer toAddTo) {
- boolean inQuote = false;
- char ch = chars.charAt(0);
- if (Character.isSpaceChar(ch)) {
- inQuote = true;
- toAddTo.append('\'');
- } else {
- if (PatternEntry.isSpecialChar(ch)) {
- inQuote = true;
- toAddTo.append('\'');
- } else {
- switch (ch) {
- case 0x0010: case '\f': case '\r':
- case '\t': case '\n': case '@':
- inQuote = true;
- toAddTo.append('\'');
- break;
- case '\'':
- inQuote = true;
- toAddTo.append('\'');
- break;
- default:
- if (inQuote) {
- inQuote = false; toAddTo.append('\'');
- }
- break;
- }
- }
- }
- toAddTo.append(chars);
- if (inQuote)
- toAddTo.append('\'');
- }
-
- //========================================================================
- // Parsing a pattern into a list of PatternEntries....
- //========================================================================
-
- PatternEntry(int strength,
- StringBuffer chars,
- StringBuffer extension)
- {
- this.strength = strength;
- this.chars = chars.toString();
- this.extension = (extension.length() > 0) ? extension.toString()
- : "";
- }
-
- static class Parser {
- private String pattern;
- private int i;
-
- public Parser(String pattern) {
- this.pattern = pattern;
- this.i = 0;
- }
-
- public PatternEntry next() throws ParseException {
- int newStrength = UNSET;
-
- newChars.setLength(0);
- newExtension.setLength(0);
-
- boolean inChars = true;
- boolean inQuote = false;
- mainLoop:
- while (i < pattern.length()) {
- char ch = pattern.charAt(i);
- if (inQuote) {
- if (ch == '\'') {
- inQuote = false;
- } else {
- if (newChars.length() == 0) newChars.append(ch);
- else if (inChars) newChars.append(ch);
- else newExtension.append(ch);
- }
- } else switch (ch) {
- case '=': if (newStrength != UNSET) break mainLoop;
- newStrength = Collator.IDENTICAL; break;
- case ',': if (newStrength != UNSET) break mainLoop;
- newStrength = Collator.TERTIARY; break;
- case ';': if (newStrength != UNSET) break mainLoop;
- newStrength = Collator.SECONDARY; break;
- case '<': if (newStrength != UNSET) break mainLoop;
- newStrength = Collator.PRIMARY; break;
- case '&': if (newStrength != UNSET) break mainLoop;
- newStrength = RESET; break;
- case '\t':
- case '\n':
- case '\f':
- case '\r':
- case ' ': break; // skip whitespace TODO use Character
- case '/': inChars = false; break;
- case '\'':
- inQuote = true;
- ch = pattern.charAt(++i);
- if (newChars.length() == 0) newChars.append(ch);
- else if (inChars) newChars.append(ch);
- else newExtension.append(ch);
- break;
- default:
- if (newStrength == UNSET) {
- throw new ParseException
- ("missing char (=,;<&) : " +
- pattern.substring(i,
- (i+10 < pattern.length()) ?
- i+10 : pattern.length()),
- i);
- }
- if (PatternEntry.isSpecialChar(ch) && (inQuote == false))
- throw new ParseException
- ("Unquoted punctuation character : " + Integer.toString(ch, 16), i);
- if (inChars) {
- newChars.append(ch);
- } else {
- newExtension.append(ch);
- }
- break;
- }
- i++;
- }
- if (newStrength == UNSET)
- return null;
- if (newChars.length() == 0) {
- throw new ParseException
- ("missing chars (=,;<&): " +
- pattern.substring(i,
- (i+10 < pattern.length()) ?
- i+10 : pattern.length()),
- i);
- }
-
- return new PatternEntry(newStrength, newChars, newExtension);
- }
-
- // We re-use these objects in order to improve performance
- private StringBuffer newChars = new StringBuffer();
- private StringBuffer newExtension = new StringBuffer();
-
- }
-
- static boolean isSpecialChar(char ch) {
- return ((ch == '\u0020') ||
- ((ch <= '\u002F') && (ch >= '\u0022')) ||
- ((ch <= '\u003F') && (ch >= '\u003A')) ||
- ((ch <= '\u0060') && (ch >= '\u005B')) ||
- ((ch <= '\u007E') && (ch >= '\u007B')));
- }
-
-
- static final int RESET = -2;
- static final int UNSET = -1;
-
- int strength = UNSET;
- String chars = "";
- String extension = "";
-}
diff --git a/ojluni/src/main/java/java/util/PriorityQueue.java b/ojluni/src/main/java/java/util/PriorityQueue.java
index 70c99bff9d0..264b1a8983f 100644
--- a/ojluni/src/main/java/java/util/PriorityQueue.java
+++ b/ojluni/src/main/java/java/util/PriorityQueue.java
@@ -25,6 +25,13 @@
package java.util;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
+
+import dalvik.annotation.compat.VersionCodes;
+import dalvik.system.VMRuntime;
+
import java.util.function.Consumer;
import java.util.function.Predicate;
import jdk.internal.misc.SharedSecrets;
@@ -327,7 +334,18 @@ public class PriorityQueue<E> extends AbstractQueue<E>
int i = size;
if (i >= queue.length)
grow(i + 1);
- siftUp(i, e);
+ if (i == 0) {
+ // Android-changed: Keep old behavior on Android 13 or below. http://b/289878283
+ boolean usePreAndroidUBehavior = VMRuntime.getSdkVersion() < VersionCodes.UPSIDE_DOWN_CAKE
+ || !Compatibility.isChangeEnabled(PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT);
+ if (usePreAndroidUBehavior) {
+ queue[0] = e;
+ } else {
+ siftUp(i, e);
+ }
+ } else {
+ siftUp(i, e);
+ }
size = i + 1;
return true;
}
@@ -970,4 +988,18 @@ public class PriorityQueue<E> extends AbstractQueue<E>
if (expectedModCount != modCount)
throw new ConcurrentModificationException();
}
+
+ // Android-added: Backward-compatible flag for offer() API.
+ /**
+ * Since Android 14, {@link PriorityQueue#offer(E)} requires all elements to be comparable if
+ * there was no comparator. Previously, the first element being added did not need to be
+ * comparable.
+ *
+ * This flag is enabled for apps targeting Android 14+.
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = VersionCodes.UPSIDE_DOWN_CAKE)
+ public static final long PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT = 289878283L;
}
diff --git a/ojluni/src/test/Android.bp b/ojluni/src/test/Android.bp
index 0eeb92c53e1..d5924a551da 100644
--- a/ojluni/src/test/Android.bp
+++ b/ojluni/src/test/Android.bp
@@ -57,6 +57,7 @@ java_test {
],
static_libs: [
+ "core-test-rules",
"junit",
"testng",
],
@@ -143,6 +144,7 @@ java_test {
system_modules: "core-all-system-modules",
libs: [
"bouncycastle",
+ "core-test-rules",
"junit",
"okhttp",
"testng",
diff --git a/ojluni/src/test/java/math/BigInteger/BigIntegerTest.java b/ojluni/src/test/java/math/BigInteger/BigIntegerTest.java
index 0e8c4cdec5b..48a819cb87e 100644
--- a/ojluni/src/test/java/math/BigInteger/BigIntegerTest.java
+++ b/ojluni/src/test/java/math/BigInteger/BigIntegerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
* @library /test/lib
* @build jdk.test.lib.RandomFactory
* @run main BigIntegerTest
- * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946 4026465 8074460 8078672 8032027
+ * @bug 4181191 4161971 4227146 4194389 4823171 4624738 4812225 4837946 4026465 8074460 8078672 8032027 8229845
* @summary tests methods in BigInteger (use -Dseed=X to set PRNG seed)
* @run main/timeout=400 BigIntegerTest
* @author madbot
@@ -648,10 +648,11 @@ public class BigIntegerTest {
}
}
+ // BEGIN Android-changed: Fix slow BigInteger string conversion test splitting into multiple.
private static void stringConv_generic() {
// Generic string conversion.
for (int i=0; i<100; i++) {
- byte[] xBytes = new byte[Math.abs(random.nextInt())%100+1];
+ byte xBytes[] = new byte[Math.abs(random.nextInt())%200+1];
random.nextBytes(xBytes);
BigInteger x = new BigInteger(xBytes);
@@ -685,6 +686,17 @@ public class BigIntegerTest {
}
}
+ private static void stringConv_trailingZeros() {
+ // Check value with many trailing zeros.
+ String val = "123456789"
+ + "0".repeat(200);
+ BigInteger b = new BigInteger(val);
+ String s = b.toString();
+ Assert.assertEquals(
+ val, s, String.format("Expected length %d but got %d%n", val.length(), s.length()));
+ }
+ // END Android-changed: Fix slow BigInteger string conversion test splitting into multiple.
+
private static void byteArrayConv(int order) {
for (int i=0; i<SIZE; i++) {
BigInteger x = fetchNumber(order);
@@ -1095,6 +1107,11 @@ public class BigIntegerTest {
}
@Test
+ public void testStringConv_trailingZeros() {
+ stringConv_trailingZeros();
+ }
+
+ @Test
public void testSerialize() throws Exception {
serialize();
}
diff --git a/ojluni/src/test/java/math/BigInteger/BitLengthOverflow.java b/ojluni/src/test/java/math/BigInteger/BitLengthOverflow.java
new file mode 100644
index 00000000000..72d14c4a6cc
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/BitLengthOverflow.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6910473 8272541
+ * @summary Test that bitLength() is not negative
+ * @author Dmitry Nadezhin
+ */
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+import java.util.function.Supplier;
+
+public class BitLengthOverflow {
+ private static void test(Supplier<BigInteger> s) {
+ try {
+ BigInteger x = s.get();
+ System.out.println("Surprisingly passed with correct bitLength() " +
+ x.bitLength());
+ } catch (ArithmeticException e) {
+ // expected
+ System.out.println("Overflow reported by ArithmeticException, as expected");
+ } catch (OutOfMemoryError e) {
+ // possible
+ System.err.println("BitLengthOverflow skipped: OutOfMemoryError");
+ System.err.println("Run jtreg with -javaoption:-Xmx8g");
+ }
+ }
+
+ public static void main(String[] args) {
+ test(() -> {
+ // x = pow(2,Integer.MAX_VALUE)
+ BigInteger x = BigInteger.ONE.shiftLeft(Integer.MAX_VALUE);
+ if (x.bitLength() != (1L << 31)) {
+ throw new RuntimeException("Incorrect bitLength() " +
+ x.bitLength());
+ }
+ return x;
+ });
+ test(() -> {
+ BigInteger a = BigInteger.ONE.shiftLeft(1073742825);
+ BigInteger b = BigInteger.ONE.shiftLeft(1073742825);
+ return a.multiply(b);
+ });
+ }
+}
diff --git a/ojluni/src/test/java/math/BigInteger/DoubleValueOverflow.java b/ojluni/src/test/java/math/BigInteger/DoubleValueOverflow.java
new file mode 100644
index 00000000000..6d2886f1061
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/DoubleValueOverflow.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8021203
+ * @summary Test that doubleValue() doesn't overflow
+ * @author Dmitry Nadezhin
+ */
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+
+public class DoubleValueOverflow {
+
+ public static void main(String[] args) {
+ try {
+ BigInteger x = BigInteger.valueOf(2).shiftLeft(Integer.MAX_VALUE); // x = pow(2,pow(2,31))
+ if (x.doubleValue() != Double.POSITIVE_INFINITY) {
+ throw new RuntimeException("Incorrect doubleValue() " + x.doubleValue());
+ }
+ System.out.println("Passed with correct result");
+ } catch (ArithmeticException e) {
+ // expected
+ System.out.println("Overflow is reported by ArithmeticException, as expected");
+ } catch (OutOfMemoryError e) {
+ // possible
+ System.err.println("DoubleValueOverflow skipped: OutOfMemoryError");
+ System.err.println("Run jtreg with -javaoption:-Xmx8g");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/math/BigInteger/ExtremeShiftingTests.java b/ojluni/src/test/java/math/BigInteger/ExtremeShiftingTests.java
new file mode 100644
index 00000000000..197e508a303
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/ExtremeShiftingTests.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6371401
+ * @summary Tests of shiftLeft and shiftRight on Integer.MIN_VALUE
+ * @requires os.maxMemory >= 1g
+ * @run main/othervm -Xmx512m ExtremeShiftingTests
+ * @author Joseph D. Darcy
+ */
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+import static java.math.BigInteger.*;
+
+public class ExtremeShiftingTests {
+ public static void main(String... args) {
+ // BEGIN Android-removed: Test fails on Android.
+ // java.lang.OutOfMemoryError: Failed to allocate a 268435472 byte allocation ...
+ /*
+ BigInteger bi = ONE.shiftLeft(Integer.MIN_VALUE);
+ if (!bi.equals(ZERO))
+ throw new RuntimeException("1 << " + Integer.MIN_VALUE);
+
+ bi = ZERO.shiftLeft(Integer.MIN_VALUE);
+ if (!bi.equals(ZERO))
+ throw new RuntimeException("0 << " + Integer.MIN_VALUE);
+
+ bi = BigInteger.valueOf(-1);
+ bi = bi.shiftLeft(Integer.MIN_VALUE);
+ if (!bi.equals(BigInteger.valueOf(-1)))
+ throw new RuntimeException("-1 << " + Integer.MIN_VALUE);
+
+ try {
+ ONE.shiftRight(Integer.MIN_VALUE);
+ throw new RuntimeException("1 >> " + Integer.MIN_VALUE);
+ } catch (ArithmeticException ae) {
+ ; // Expected
+ }
+
+ bi = ZERO.shiftRight(Integer.MIN_VALUE);
+ if (!bi.equals(ZERO))
+ throw new RuntimeException("0 >> " + Integer.MIN_VALUE);
+
+ try {
+ BigInteger.valueOf(-1).shiftRight(Integer.MIN_VALUE);
+ throw new RuntimeException("-1 >> " + Integer.MIN_VALUE);
+ } catch (ArithmeticException ae) {
+ ; // Expected
+ }
+ */
+ // END Android-removed: Test fails on Android.
+ }
+}
diff --git a/ojluni/src/test/java/math/BigInteger/LargeValueExceptions.java b/ojluni/src/test/java/math/BigInteger/LargeValueExceptions.java
new file mode 100644
index 00000000000..efa988c970e
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/LargeValueExceptions.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8200698
+ * @summary Tests that exceptions are thrown for ops which would overflow
+ * @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g)
+ * @run testng/othervm -Xmx4g LargeValueExceptions
+ */
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+import static java.math.BigInteger.ONE;
+import org.testng.annotations.Test;
+
+//
+// The intent of this test is to probe the boundaries between overflow and
+// non-overflow, principally for multiplication and squaring, specifically
+// the largest values which should not overflow and the smallest values which
+// should. The transition values used are not necessarily at the exact
+// boundaries but should be "close." Quite a few different values were used
+// experimentally before settling on the ones in this test. For multiplication
+// and squaring all cases are exercised: definite overflow and non-overflow
+// which can be detected "up front," and "indefinite" overflow, i.e., overflow
+// which cannot be detected up front so further calculations are required.
+//
+// Testing negative values is unnecessary. For both multiplication and squaring
+// the paths lead to the Toom-Cook algorithm where the signum is used only to
+// determine the sign of the result and not in the intermediate calculations.
+// This is also true for exponentiation.
+//
+// @Test annotations with optional element "enabled" set to "false" should
+// succeed when "enabled" is set to "true" but they take too to run in the
+// course of the typical regression test execution scenario.
+//
+public class LargeValueExceptions {
+ // BigInteger.MAX_MAG_LENGTH
+ private static final int MAX_INTS = 1 << 26;
+
+ // Number of bits corresponding to MAX_INTS
+ private static final long MAX_BITS = (0xffffffffL & MAX_INTS) << 5L;
+
+ // Half BigInteger.MAX_MAG_LENGTH
+ private static final int MAX_INTS_HALF = MAX_INTS / 2;
+
+ // --- squaring ---
+
+ // Largest no overflow determined by examining data lengths alone.
+ @Test(enabled=false)
+ public void squareNoOverflow() {
+ BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1).subtract(ONE);
+ BigInteger y = x.multiply(x);
+ }
+
+ // Smallest no overflow determined by extra calculations.
+ @Test(enabled=false)
+ public void squareIndefiniteOverflowSuccess() {
+ BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1);
+ BigInteger y = x.multiply(x);
+ }
+
+ // Largest overflow detected by extra calculations.
+ @Test(expectedExceptions=ArithmeticException.class,enabled=false)
+ public void squareIndefiniteOverflowFailure() {
+ BigInteger x = ONE.shiftLeft(16*MAX_INTS).subtract(ONE);
+ BigInteger y = x.multiply(x);
+ }
+
+ // Smallest overflow detected by examining data lengths alone.
+ // BEGIN Android-changed: Test fails on Android.
+ // java.lang.OutOfMemoryError: Failed to allocate a 134217744 byte allocation ...
+ @Test(expectedExceptions=ArithmeticException.class,enabled=false)
+ // END Android-changed: Test fails on Android.
+ public void squareDefiniteOverflow() {
+ BigInteger x = ONE.shiftLeft(16*MAX_INTS);
+ BigInteger y = x.multiply(x);
+ }
+
+ // --- multiplication ---
+
+ // Largest no overflow determined by examining data lengths alone.
+ @Test(enabled=false)
+ public void multiplyNoOverflow() {
+ final int halfMaxBits = MAX_INTS_HALF << 5;
+
+ BigInteger x = ONE.shiftLeft(halfMaxBits).subtract(ONE);
+ BigInteger y = ONE.shiftLeft(halfMaxBits - 1).subtract(ONE);
+ BigInteger z = x.multiply(y);
+ }
+
+ // Smallest no overflow determined by extra calculations.
+ @Test(enabled=false)
+ public void multiplyIndefiniteOverflowSuccess() {
+ BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2) - 1);
+ long m = MAX_BITS - x.bitLength();
+
+ BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2) - 1);
+ long n = MAX_BITS - y.bitLength();
+
+ if (m + n != MAX_BITS) {
+ throw new RuntimeException("Unexpected leading zero sum");
+ }
+
+ BigInteger z = x.multiply(y);
+ }
+
+ // Largest overflow detected by extra calculations.
+ @Test(expectedExceptions=ArithmeticException.class,enabled=false)
+ public void multiplyIndefiniteOverflowFailure() {
+ BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);
+ long m = MAX_BITS - x.bitLength();
+
+ BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);
+ long n = MAX_BITS - y.bitLength();
+
+ if (m + n != MAX_BITS) {
+ throw new RuntimeException("Unexpected leading zero sum");
+ }
+
+ BigInteger z = x.multiply(y);
+ }
+
+ // Smallest overflow detected by examining data lengths alone.
+ // BEGIN Android-changed: Test fails on Android.
+ // java.lang.OutOfMemoryError: Failed to allocate a 134217744 byte allocation ...
+ @Test(expectedExceptions=ArithmeticException.class,enabled=false)
+ // END Android-changed: Test fails on Android.
+ public void multiplyDefiniteOverflow() {
+ // multiply by 4 as MAX_INTS_HALF refers to ints
+ byte[] xmag = new byte[4*MAX_INTS_HALF];
+ xmag[0] = (byte)0xff;
+ BigInteger x = new BigInteger(1, xmag);
+
+ byte[] ymag = new byte[4*MAX_INTS_HALF + 1];
+ ymag[0] = (byte)0xff;
+ BigInteger y = new BigInteger(1, ymag);
+
+ BigInteger z = x.multiply(y);
+ }
+
+ // --- exponentiation ---
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void powOverflow() {
+ BigInteger.TEN.pow(Integer.MAX_VALUE);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void powOverflow1() {
+ int shift = 20;
+ int exponent = 1 << shift;
+ BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent));
+ BigInteger y = x.pow(exponent);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class)
+ public void powOverflow2() {
+ int shift = 20;
+ int exponent = 1 << shift;
+ BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).add(ONE);
+ BigInteger y = x.pow(exponent);
+ }
+
+ @Test(expectedExceptions=ArithmeticException.class,enabled=false)
+ public void powOverflow3() {
+ int shift = 20;
+ int exponent = 1 << shift;
+ BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).subtract(ONE);
+ BigInteger y = x.pow(exponent);
+ }
+
+ @Test(enabled=false)
+ public void powOverflow4() {
+ int shift = 20;
+ int exponent = 1 << shift;
+ BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent - 1)).add(ONE);
+ BigInteger y = x.pow(exponent);
+ }
+}
diff --git a/ojluni/src/test/java/math/BigInteger/ModInvTime.java b/ojluni/src/test/java/math/BigInteger/ModInvTime.java
new file mode 100644
index 00000000000..95cb0f7caa0
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/ModInvTime.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8225603
+ * @summary Tests whether modInverse() completes in a reasonable time
+ * @run main/othervm ModInvTime
+ */
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+
+public class ModInvTime {
+ public static void main(String[] args) throws InterruptedException {
+ BigInteger prime = new BigInteger("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643");
+ BigInteger s = new BigInteger("9552729729729327851382626410162104591956625415831952158766936536163093322096473638446154604799898109762512409920799");
+ System.out.format("int length: %d, modulus length: %d%n",
+ s.bitLength(), prime.bitLength());
+
+ System.out.println("Computing modular inverse ...");
+ BigInteger mi = s.modInverse(prime);
+ System.out.format("Modular inverse: %s%n", mi);
+ check(s, prime, mi);
+
+ BigInteger ns = s.negate();
+ BigInteger nmi = ns.modInverse(prime);
+ System.out.format("Modular inverse of negation: %s%n", nmi);
+ check(ns, prime, nmi);
+ }
+
+ public static void check(BigInteger val, BigInteger mod, BigInteger inv) {
+ BigInteger r = inv.multiply(val).remainder(mod);
+ if (r.signum() == -1)
+ r = r.add(mod);
+ if (!r.equals(BigInteger.ONE))
+ throw new RuntimeException("Numerically incorrect modular inverse");
+ }
+}
diff --git a/ojluni/src/test/java/math/BigInteger/ModPow.java b/ojluni/src/test/java/math/BigInteger/ModPow.java
index b31c0f6e61c..41cc337c41e 100644
--- a/ojluni/src/test/java/math/BigInteger/ModPow.java
+++ b/ojluni/src/test/java/math/BigInteger/ModPow.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,18 @@
*/
/* @test
- * @bug 4181191
- * @summary test BigInteger modPow method
+ * @bug 4181191 8215759
+ * @summary test BigInteger modPow method (use -Dseed=X to set PRNG seed)
+ * @library /test/lib
+ * @build jdk.test.lib.RandomFactory
+ * @run main ModPow
+ * @key randomness
*/
package test.java.math.BigInteger;
import java.math.BigInteger;
import java.util.Random;
+import jdk.test.lib.RandomFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -41,7 +46,9 @@ public class ModPow {
Random rnd = new Random(1234);
for (int i=0; i<2000; i++) {
- BigInteger m = new BigInteger(800, rnd);
+ // Clamp random modulus to a positive value or modPow() will
+ // throw an ArithmeticException.
+ BigInteger m = new BigInteger(800, rnd).max(BigInteger.ONE);
BigInteger base = new BigInteger(16, rnd);
if (rnd.nextInt() % 2 == 0)
base = base.negate();
diff --git a/ojluni/src/test/java/math/BigInteger/ModPow65537.java b/ojluni/src/test/java/math/BigInteger/ModPow65537.java
new file mode 100644
index 00000000000..c616bbcd8e1
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/ModPow65537.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @build jdk.test.lib.RandomFactory
+ * @run main ModPow65537
+ * @bug 4891312 8074460 8078672
+ * @summary verify that modPow() not broken by the special case for 65537 (use -Dseed=X to set PRNG seed)
+ * @author Andreas Sterbenz
+ * @key randomness
+ */
+
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.*;
+import java.util.Random;
+import jdk.test.lib.RandomFactory;
+
+public class ModPow65537 {
+
+ public static void main(String[] args) throws Exception {
+ // BEGIN Android-removed: Test fails on Android.
+ // java.security.NoSuchProviderException: no such provider: SunRsaSign.
+ /*
+ // SunRsaSign uses BigInteger internally
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "SunRsaSign");
+ kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(65537)));
+ KeyPair kp = kpg.generateKeyPair();
+ testSigning(kp);
+
+ kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(65539)));
+ kp = kpg.generateKeyPair();
+ testSigning(kp);
+
+ kpg.initialize(new RSAKeyGenParameterSpec(512, BigInteger.valueOf(3)));
+ kp = kpg.generateKeyPair();
+ testSigning(kp);
+
+ // basic known answer test
+ BigInteger base = new
+ BigInteger("19058071224156864789844466979330892664777520457048234786139035643344145635582");
+ BigInteger mod = new
+ BigInteger("75554098474976067521257305210610421240510163914613117319380559667371251381587");
+ BigInteger exp1 = BigInteger.valueOf(65537);
+ BigInteger exp2 = BigInteger.valueOf(75537);
+ BigInteger exp3 = new BigInteger("13456870775607312149");
+
+ BigInteger res1 = new
+ BigInteger("5770048609366563851320890693196148833634112303472168971638730461010114147506");
+ BigInteger res2 = new
+ BigInteger("63446979364051087123350579021875958137036620431381329472348116892915461751531");
+ BigInteger res3 = new
+ BigInteger("39016891919893878823999350081191675846357272199067075794096200770872982089502");
+
+ if (base.modPow(exp1, mod).equals(res1) == false) {
+ throw new Exception("Error using " + exp1);
+ }
+ if (base.modPow(exp2, mod).equals(res2) == false) {
+ throw new Exception("Error using " + exp2);
+ }
+ if (base.modPow(exp3, mod).equals(res3) == false) {
+ throw new Exception("Error using " + exp3);
+ }
+
+ System.out.println("Passed");
+ */
+ // END Android-removed: Test fails on Android.
+ }
+
+ // BEGIN Android-removed: Test fails on Android.
+ // java.security.NoSuchProviderException: no such provider: SunRsaSign.
+ /*
+ private static void testSigning(KeyPair kp) throws Exception {
+ System.out.println(kp.getPublic());
+ byte[] data = new byte[1024];
+ Random random = RandomFactory.getRandom();
+ random.nextBytes(data);
+
+ Signature sig = Signature.getInstance("SHA1withRSA", "SunRsaSign");
+ sig.initSign(kp.getPrivate());
+ sig.update(data);
+ byte[] sigBytes = sig.sign();
+
+ sig.initVerify(kp.getPublic());
+ sig.update(data);
+ if (sig.verify(sigBytes) == false) {
+ throw new Exception("signature verification failed");
+ }
+ System.out.println("OK");
+ }
+ */
+}
diff --git a/ojluni/src/test/java/math/BigInteger/ModPowPowersof2.java b/ojluni/src/test/java/math/BigInteger/ModPowPowersof2.java
new file mode 100644
index 00000000000..11a0ea619ac
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/ModPowPowersof2.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ @bug 4098742
+ @summary Test biginteger modpow method
+ @author Michael McCloskey
+ @run main/othervm ModPowPowersof2
+*/
+
+package test.java.math.BigInteger;
+
+import java.math.BigInteger;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * This class tests to see if using modPow on a power
+ * of two crashes the vm
+ *
+ */
+public class ModPowPowersof2 {
+
+ public static void main(String args[]) throws Exception {
+ // BEGIN Android-removed: Test fails on Android.
+ // java.io.IOException: Cannot run program "<path-to-art>/bin/java": error=2, No such file or directory
+ /*
+ // Construct a command that runs the test in other vm
+ String[] command = new String[4];
+ int n = 0;
+
+ command[n++] = System.getProperty("java.home") + File.separator +
+ "bin" + File.separator + "java";
+ if (System.getProperty("java.class.path") != null) {
+ command[n++] = "-classpath";
+ command[n++] = System.getProperty("java.class.path");
+ }
+
+ command[n++] = "ModPowPowersof2$ModTester";
+
+ // Exec another vm to run test in
+ Process p = null;
+ p = Runtime.getRuntime().exec(command);
+
+ // Read the result to determine if test failed
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ p.getInputStream()));
+ String s;
+ s = in.readLine();
+ if (s == null)
+ throw new RuntimeException("ModPow causes vm crash");
+ */
+ // Android-removed Test fails on Android.
+ }
+
+ // BEGIN Android-removed: Test fails on Android.
+ // java.io.IOException: Cannot run program "<path-to-art>/bin/java": error=2, No such file or directory
+ /*
+ public static class ModTester {
+ public static void main(String [] args) {
+ BigInteger two = BigInteger.valueOf(2);
+ BigInteger four = BigInteger.valueOf(4);
+
+ two.modPow(two, BigInteger.valueOf(4));
+ two.modPow(two, BigInteger.valueOf(8));
+ two.modPow(four, BigInteger.valueOf(8));
+
+ System.out.println("success");
+ }
+ }
+ */
+ // Android-removed Test fails on Android.
+
+}
diff --git a/ojluni/src/test/java/math/BigInteger/PrimeTest.java b/ojluni/src/test/java/math/BigInteger/PrimeTest.java
index e0e4c886205..7a4cb048025 100644
--- a/ojluni/src/test/java/math/BigInteger/PrimeTest.java
+++ b/ojluni/src/test/java/math/BigInteger/PrimeTest.java
@@ -4,9 +4,7 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
diff --git a/ojluni/src/test/java/math/BigInteger/SerializationTests.java b/ojluni/src/test/java/math/BigInteger/SerializationTests.java
new file mode 100644
index 00000000000..7faaca3c482
--- /dev/null
+++ b/ojluni/src/test/java/math/BigInteger/SerializationTests.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8282252
+ * @summary Verify BigInteger objects are serialized properly.
+ */
+
+package test.java.math.BigInteger;
+
+import java.math.*;
+import java.io.*;
+import java.util.Arrays;
+import java.util.List;
+
+public class SerializationTests {
+
+ public static void main(String... args) throws Exception {
+ checkBigIntegerSerialRoundTrip();
+ checkBigIntegerSubSerialRoundTrip();
+ }
+
+ private static void checkSerialForm(BigInteger bi) throws Exception {
+ checkSerialForm0(bi);
+ checkSerialForm0(bi.negate());
+ }
+
+ private static void checkSerialForm0(BigInteger bi) throws Exception {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try(ObjectOutputStream oos = new ObjectOutputStream(bos)) {
+ oos.writeObject(bi);
+ oos.flush();
+ }
+
+ ObjectInputStream ois = new
+ ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ BigInteger tmp = (BigInteger)ois.readObject();
+
+ if (!bi.equals(tmp) ||
+ bi.hashCode() != tmp.hashCode() ||
+ bi.getClass() != tmp.getClass() ||
+ // For extra measure, directly test equality of components
+ bi.signum() != tmp.signum() ||
+ !Arrays.equals(bi.toByteArray(), (tmp.toByteArray())) ) {
+ System.err.print(" original : " + bi);
+ System.err.println(" (hash: 0x" + Integer.toHexString(bi.hashCode()) + ")");
+ System.err.print("serialized : " + tmp);
+ System.err.println(" (hash: 0x" + Integer.toHexString(tmp.hashCode()) + ")");
+ throw new RuntimeException("Bad serial roundtrip");
+ }
+ }
+
+ private static void checkBigIntegerSerialRoundTrip() throws Exception {
+ var values =
+ List.of(BigInteger.ZERO,
+ BigInteger.ONE,
+ BigInteger.TWO,
+ BigInteger.TEN,
+ BigInteger.valueOf(100),
+ BigInteger.valueOf(Integer.MAX_VALUE),
+ BigInteger.valueOf(Long.MAX_VALUE-1),
+ new BigInteger("9223372036854775808")); // Long.MAX_VALUE + 1
+
+ for(BigInteger value : values) {
+ checkSerialForm(value);
+ }
+ }
+
+ // Subclass with specialized toString output
+ private static class BigIntegerSub extends BigInteger {
+ public BigIntegerSub(BigInteger bi) {
+ super(bi.toByteArray());
+ }
+
+ @Override
+ public String toString() {
+ return Arrays.toString(toByteArray());
+ }
+ }
+
+ // Subclass defining a serialVersionUID
+ private static class BigIntegerSubSVUID extends BigInteger {
+ @java.io.Serial
+ private static long serialVesionUID = 0x0123_4567_89ab_cdefL;
+
+ public BigIntegerSubSVUID(BigInteger bi) {
+ super(bi.toByteArray());
+ }
+
+ @Override
+ public String toString() {
+ return Arrays.toString(toByteArray());
+ }
+ }
+
+ // Subclass defining writeReplace
+ private static class BigIntegerSubWR extends BigInteger {
+ public BigIntegerSubWR(BigInteger bi) {
+ super(bi.toByteArray());
+ }
+
+ // Just return this; could use a serial proxy instead
+ @java.io.Serial
+ private Object writeReplace() throws ObjectStreamException {
+ return this;
+ }
+ }
+
+
+ private static void checkBigIntegerSubSerialRoundTrip() throws Exception {
+ var values = List.of(BigInteger.ZERO,
+ BigInteger.ONE,
+ BigInteger.TEN,
+ new BigInteger("9223372036854775808")); // Long.MAX_VALUE + 1
+
+ for(var value : values) {
+ checkSerialForm(new BigIntegerSub(value));
+ checkSerialForm(new BigIntegerSubSVUID(value));
+ checkSerialForm(new BigIntegerSubWR(value));
+ }
+ }
+}
diff --git a/ojluni/src/test/java/nio/file/Path/PathOps.java b/ojluni/src/test/java/nio/file/Path/PathOps.java
index 6c262231547..b2daa7787e6 100644
--- a/ojluni/src/test/java/nio/file/Path/PathOps.java
+++ b/ojluni/src/test/java/nio/file/Path/PathOps.java
@@ -27,6 +27,7 @@
*/
package test.java.nio.file.Path;
+import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
@@ -47,6 +48,14 @@ public class PathOps {
}
}
+ private PathOps(URI uri) {
+ try {
+ path = Path.of(uri);
+ } catch (Exception x) {
+ exc = x;
+ }
+ }
+
void checkPath() {
if (path == null) {
throw new InternalError("path is null");
@@ -480,6 +489,27 @@ public class PathOps {
.name("bar");
}
+ // BEGIN Android-added: Tests for of().
+ static PathOps testOf(String first) {
+ try {
+ return new PathOps(new URI (first));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Test
+ public static void doOfTests() {
+ Path cwd = Paths.get("").toAbsolutePath();
+
+ // construction
+ testOf("file:///foo/")
+ .string("/foo");
+ testOf("file:///foo/bar/gus/")
+ .string("/foo/bar/gus");
+ }
+ // END Android-added: Tests for of().
+
@Test
public static void npes() {
try {
diff --git a/ojluni/src/test/java/text/AttributedCharacterIterator/Attribute/ReadResolve.java b/ojluni/src/test/java/text/AttributedCharacterIterator/Attribute/ReadResolve.java
new file mode 100644
index 00000000000..022d33a30db
--- /dev/null
+++ b/ojluni/src/test/java/text/AttributedCharacterIterator/Attribute/ReadResolve.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ @bug 4136620 4144590
+ @summary Make sure that Attribute & subclasses are serialized and deserialized correctly
+ @modules java.desktop
+ */
+
+package test.java.text.AttributedCharacterIterator.Attribute;
+
+import java.text.AttributedCharacterIterator.Attribute;
+import java.awt.font.TextAttribute;
+import java.io.*;
+
+public class ReadResolve {
+
+ public static void main(String[] args) throws Exception {
+ testSerializationCycle(Attribute.LANGUAGE);
+ testSerializationCycle(TextAttribute.INPUT_METHOD_HIGHLIGHT);
+
+ boolean gotException = false;
+ Attribute result = null;
+ try {
+ result = doSerializationCycle(FakeAttribute.LANGUAGE);
+ } catch (Throwable e) {
+ gotException = true;
+ }
+ if (!gotException) {
+ throw new RuntimeException("Attribute should throw an exception when given a fake \"language\" attribute. Deserialized object: " + result);
+ }
+ }
+
+ static Attribute doSerializationCycle(Attribute attribute) throws Exception {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(attribute);
+ oos.flush();
+
+ byte[] data = baos.toByteArray();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ Attribute result = (Attribute) ois.readObject();
+
+ return result;
+ }
+
+ static void testSerializationCycle(Attribute attribute) throws Exception {
+ Attribute result = doSerializationCycle(attribute);
+ if (result != attribute) {
+ throw new RuntimeException("attribute changed identity during serialization/deserialization");
+ }
+ }
+
+ private static class FakeAttribute extends Attribute {
+
+ // This LANGUAGE attribute should never be confused with the
+ // Attribute.LANGUAGE attribute. However, we don't override
+ // readResolve here, so that deserialization goes
+ // to Attribute. Attribute has to catch this problem and reject
+ // the fake attribute.
+ static final FakeAttribute LANGUAGE = new FakeAttribute("language");
+
+ FakeAttribute(String name) {
+ super(name);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/AttributedString/AttributedStringTest.java b/ojluni/src/test/java/text/AttributedString/AttributedStringTest.java
new file mode 100644
index 00000000000..034fa6ebcbb
--- /dev/null
+++ b/ojluni/src/test/java/text/AttributedString/AttributedStringTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4139771
+ * @summary test all aspects of AttributedString class
+ */
+
+package test.java.text.AttributedString;
+
+import java.text.Annotation;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedCharacterIterator.Attribute;
+import java.text.AttributedString;
+import java.text.CharacterIterator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+
+public class AttributedStringTest {
+
+ private static final String text = "Hello, world!";
+ private static final Annotation hi = new Annotation("hi");
+ private static final int[] array5_13 = {5, 13};
+ private static final int[] array3_9_13 = {3, 9, 13};
+ private static final int[] array5_9_13 = {5, 9, 13};
+ private static final int[] array3_5_9_13 = {3, 5, 9, 13};
+ private static final Attribute[] arrayLanguage = {Attribute.LANGUAGE};
+ private static final Attribute[] arrayLanguageReading = {Attribute.LANGUAGE, Attribute.READING};
+ private static final Set setLanguageReading = new HashSet();
+ static {
+ setLanguageReading.add(Attribute.LANGUAGE);
+ setLanguageReading.add(Attribute.READING);
+ }
+
+
+ public static final void main(String argv[]) throws Exception {
+
+
+ AttributedString string;
+ AttributedCharacterIterator iterator;
+
+ // create a string with text, but no attributes
+ string = new AttributedString(text);
+ iterator = string.getIterator();
+
+ // make sure the text is there and attributes aren't
+ checkIteratorText(iterator, text);
+ if (!iterator.getAllAttributeKeys().isEmpty()) {
+ throwException(iterator, "iterator provides attributes where none are defined");
+ }
+
+ // add an attribute to a subrange
+ string.addAttribute(Attribute.LANGUAGE, Locale.ENGLISH, 3, 9);
+ iterator = string.getIterator();
+
+ // make sure the attribute is defined, and it's on the correct subrange
+ checkIteratorAttributeKeys(iterator, arrayLanguage);
+ checkIteratorSubranges(iterator, array3_9_13);
+ checkIteratorAttribute(iterator, 0, Attribute.LANGUAGE, null);
+ checkIteratorAttribute(iterator, 3, Attribute.LANGUAGE, Locale.ENGLISH);
+ checkIteratorAttribute(iterator, 9, Attribute.LANGUAGE, null);
+
+ // add an attribute to a subrange
+ string.addAttribute(Attribute.READING, hi, 0, 5);
+ iterator = string.getIterator();
+
+ // make sure the attribute is defined, and it's on the correct subrange
+ checkIteratorAttributeKeys(iterator, arrayLanguageReading);
+ checkIteratorSubranges(iterator, array3_5_9_13);
+ checkIteratorAttribute(iterator, 0, Attribute.READING, hi);
+ checkIteratorAttribute(iterator, 3, Attribute.READING, hi);
+ checkIteratorAttribute(iterator, 5, Attribute.READING, null);
+ checkIteratorAttribute(iterator, 9, Attribute.READING, null);
+
+ // make sure the first attribute wasn't adversely affected
+ // in particular, we shouldn't see separate subranges (3,5) and (5,9).
+ checkIteratorSubranges(iterator, Attribute.LANGUAGE, array3_9_13);
+ checkIteratorAttribute(iterator, 0, Attribute.LANGUAGE, null);
+ checkIteratorAttribute(iterator, 3, Attribute.LANGUAGE, Locale.ENGLISH);
+ checkIteratorAttribute(iterator, 5, Attribute.LANGUAGE, Locale.ENGLISH);
+ checkIteratorAttribute(iterator, 9, Attribute.LANGUAGE, null);
+
+ // for the entire set of attributes, we expect four subranges
+ checkIteratorSubranges(iterator, setLanguageReading, array3_5_9_13);
+
+ // redefine the language attribute so that both language and reading are continuous from 0 to 5
+ string.addAttribute(Attribute.LANGUAGE, Locale.US, 0, 5);
+ iterator = string.getIterator();
+
+ // make sure attributes got changed and merged correctly
+ checkIteratorAttributeKeys(iterator, arrayLanguageReading);
+ checkIteratorSubranges(iterator, array3_5_9_13);
+ checkIteratorSubranges(iterator, Attribute.LANGUAGE, array5_9_13);
+ checkIteratorSubranges(iterator, Attribute.READING, array5_13);
+ checkIteratorSubranges(iterator, setLanguageReading, array5_9_13);
+ checkIteratorAttribute(iterator, 0, Attribute.LANGUAGE, Locale.US);
+ checkIteratorAttribute(iterator, 3, Attribute.LANGUAGE, Locale.US);
+ checkIteratorAttribute(iterator, 5, Attribute.LANGUAGE, Locale.ENGLISH);
+ checkIteratorAttribute(iterator, 9, Attribute.LANGUAGE, null);
+
+ // make sure an annotation is only returned if its range is contained in the iterator's range
+ iterator = string.getIterator(null, 3, 5);
+ checkIteratorAttribute(iterator, 3, Attribute.READING, null);
+ checkIteratorAttribute(iterator, 5, Attribute.READING, null);
+ iterator = string.getIterator(null, 0, 4);
+ checkIteratorAttribute(iterator, 0, Attribute.READING, null);
+ checkIteratorAttribute(iterator, 3, Attribute.READING, null);
+ iterator = string.getIterator(null, 0, 5);
+ checkIteratorAttribute(iterator, 0, Attribute.READING, hi);
+ checkIteratorAttribute(iterator, 4, Attribute.READING, hi);
+ checkIteratorAttribute(iterator, 5, Attribute.READING, null);
+
+ }
+
+ private static final void checkIteratorText(AttributedCharacterIterator iterator, String expectedText) throws Exception {
+ if (iterator.getEndIndex() - iterator.getBeginIndex() != expectedText.length()) {
+ throwException(iterator, "text length doesn't match between original text and iterator");
+ }
+
+ char c = iterator.first();
+ for (int i = 0; i < expectedText.length(); i++) {
+ if (c != expectedText.charAt(i)) {
+ throwException(iterator, "text content doesn't match between original text and iterator");
+ }
+ c = iterator.next();
+ }
+ if (c != CharacterIterator.DONE) {
+ throwException(iterator, "iterator text doesn't end with DONE");
+ }
+ }
+
+ private static final void checkIteratorAttributeKeys(AttributedCharacterIterator iterator, Attribute[] expectedKeys) throws Exception {
+ Set iteratorKeys = iterator.getAllAttributeKeys();
+ if (iteratorKeys.size() != expectedKeys.length) {
+ throwException(iterator, "number of keys returned by iterator doesn't match expectation");
+ }
+ for (int i = 0; i < expectedKeys.length; i++) {
+ if (!iteratorKeys.contains(expectedKeys[i])) {
+ throwException(iterator, "expected key wasn't found in iterator's key set");
+ }
+ }
+ }
+
+ private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, int[] expectedLimits) throws Exception {
+ int previous = 0;
+ char c = iterator.first();
+ for (int i = 0; i < expectedLimits.length; i++) {
+ if (iterator.getRunStart() != previous || iterator.getRunLimit() != expectedLimits[i]) {
+ throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart() + ", " + iterator.getRunLimit());
+ }
+ previous = expectedLimits[i];
+ c = iterator.setIndex(previous);
+ }
+ if (c != CharacterIterator.DONE) {
+ throwException(iterator, "iterator's run sequence doesn't end with DONE");
+ }
+ }
+
+ private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, Attribute key, int[] expectedLimits) throws Exception {
+ int previous = 0;
+ char c = iterator.first();
+ for (int i = 0; i < expectedLimits.length; i++) {
+ if (iterator.getRunStart(key) != previous || iterator.getRunLimit(key) != expectedLimits[i]) {
+ throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart(key) + ", " + iterator.getRunLimit(key) + " for key " + key);
+ }
+ previous = expectedLimits[i];
+ c = iterator.setIndex(previous);
+ }
+ if (c != CharacterIterator.DONE) {
+ throwException(iterator, "iterator's run sequence doesn't end with DONE");
+ }
+ }
+
+ private static final void checkIteratorSubranges(AttributedCharacterIterator iterator, Set keys, int[] expectedLimits) throws Exception {
+ int previous = 0;
+ char c = iterator.first();
+ for (int i = 0; i < expectedLimits.length; i++) {
+ if (iterator.getRunStart(keys) != previous || iterator.getRunLimit(keys) != expectedLimits[i]) {
+ throwException(iterator, "run boundaries are not as expected: " + iterator.getRunStart(keys) + ", " + iterator.getRunLimit(keys) + " for keys " + keys);
+ }
+ previous = expectedLimits[i];
+ c = iterator.setIndex(previous);
+ }
+ if (c != CharacterIterator.DONE) {
+ throwException(iterator, "iterator's run sequence doesn't end with DONE");
+ }
+ }
+
+ private static final void checkIteratorAttribute(AttributedCharacterIterator iterator, int index, Attribute key, Object expectedValue) throws Exception {
+ iterator.setIndex(index);
+ Object value = iterator.getAttribute(key);
+ if (!((expectedValue == null && value == null) || (expectedValue != null && expectedValue.equals(value)))) {
+ throwException(iterator, "iterator returns wrong attribute value - " + value + " instead of " + expectedValue);
+ }
+ value = iterator.getAttributes().get(key);
+ if (!((expectedValue == null && value == null) || (expectedValue != null && expectedValue.equals(value)))) {
+ throwException(iterator, "iterator's map returns wrong attribute value - " + value + " instead of " + expectedValue);
+ }
+ }
+
+ private static final void throwException(AttributedCharacterIterator iterator, String details) throws Exception {
+ dumpIterator(iterator);
+ throw new Exception(details);
+ }
+
+ private static final void dumpIterator(AttributedCharacterIterator iterator) {
+ Set attributeKeys = iterator.getAllAttributeKeys();
+ System.out.print("All attributes: ");
+ Iterator keyIterator = attributeKeys.iterator();
+ while (keyIterator.hasNext()) {
+ Attribute key = (Attribute) keyIterator.next();
+ System.out.print(key);
+ }
+ for(char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next()) {
+ if (iterator.getIndex() == iterator.getBeginIndex() ||
+ iterator.getIndex() == iterator.getRunStart()) {
+ System.out.println();
+ Map attributes = iterator.getAttributes();
+ Set entries = attributes.entrySet();
+ Iterator attributeIterator = entries.iterator();
+ while (attributeIterator.hasNext()) {
+ Map.Entry entry = (Map.Entry) attributeIterator.next();
+ System.out.print("<" + entry.getKey() + ": "
+ + entry.getValue() + ">");
+ }
+ }
+ System.out.print(" ");
+ System.out.print(c);
+ }
+ System.out.println();
+ System.out.println("done");
+ System.out.println();
+ }
+
+}
diff --git a/ojluni/src/test/java/text/AttributedString/TestAttributedStringCtor.java b/ojluni/src/test/java/text/AttributedString/TestAttributedStringCtor.java
new file mode 100644
index 00000000000..fdc4cc72886
--- /dev/null
+++ b/ojluni/src/test/java/text/AttributedString/TestAttributedStringCtor.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4146853
+ * @summary Make sure we can construct an AttributedString from
+ * an AttributedCharacterIterator covering only a subrange
+ * @modules java.desktop
+ */
+
+package test.java.text.AttributedString;
+
+import java.awt.font.TextAttribute;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.util.Hashtable;
+
+public class TestAttributedStringCtor {
+
+ public static void main(String[] args) {
+
+ // Create a new AttributedString with one attribute.
+ Hashtable attributes = new Hashtable();
+ attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+ AttributedString origString = new AttributedString("Hello world.", attributes);
+
+ // Create an iterator over part of the AttributedString.
+ AttributedCharacterIterator iter = origString.getIterator(null, 4, 6);
+
+ // Attempt to create a new AttributedString from the iterator.
+ // This will throw IllegalArgumentException.
+ AttributedString newString = new AttributedString(iter);
+
+ // Without the exception this would get executed.
+ System.out.println("DONE");
+ }
+}
diff --git a/ojluni/src/test/java/text/AttributedString/getRunStartLimitTest.java b/ojluni/src/test/java/text/AttributedString/getRunStartLimitTest.java
new file mode 100644
index 00000000000..62d4e781d53
--- /dev/null
+++ b/ojluni/src/test/java/text/AttributedString/getRunStartLimitTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4151160
+ * @summary Make sure to return correct run start and limit values
+ * when the iterator has been created with begin and end index values.
+ * @modules java.desktop
+ */
+
+package test.java.text.AttributedString;
+
+import java.awt.font.TextAttribute;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.Annotation;
+
+public class getRunStartLimitTest {
+
+ public static void main(String[] args) throws Exception {
+
+ String text = "Hello world";
+ AttributedString as = new AttributedString(text);
+
+ // add non-Annotation attributes
+ as.addAttribute(TextAttribute.WEIGHT,
+ TextAttribute.WEIGHT_LIGHT,
+ 0,
+ 3);
+ as.addAttribute(TextAttribute.WEIGHT,
+ TextAttribute.WEIGHT_BOLD,
+ 3,
+ 5);
+ as.addAttribute(TextAttribute.WEIGHT,
+ TextAttribute.WEIGHT_EXTRABOLD,
+ 5,
+ text.length());
+
+ // add Annotation attributes
+ as.addAttribute(TextAttribute.WIDTH,
+ new Annotation(TextAttribute.WIDTH_EXTENDED),
+ 0,
+ 3);
+ as.addAttribute(TextAttribute.WIDTH,
+ new Annotation(TextAttribute.WIDTH_CONDENSED),
+ 3,
+ 4);
+
+ AttributedCharacterIterator aci = as.getIterator(null, 2, 4);
+
+ aci.first();
+ int runStart = aci.getRunStart();
+ if (runStart != 2) {
+ throw new Exception("1st run start is wrong. ("+runStart+" should be 2.)");
+ }
+
+ int runLimit = aci.getRunLimit();
+ if (runLimit != 3) {
+ throw new Exception("1st run limit is wrong. ("+runLimit+" should be 3.)");
+ }
+
+ Object value = aci.getAttribute(TextAttribute.WEIGHT);
+ if (value != TextAttribute.WEIGHT_LIGHT) {
+ throw new Exception("1st run attribute is wrong. ("
+ +value+" should be "+TextAttribute.WEIGHT_LIGHT+".)");
+ }
+
+ value = aci.getAttribute(TextAttribute.WIDTH);
+ if (value != null) {
+ throw new Exception("1st run annotation is wrong. ("
+ +value+" should be null.)");
+ }
+
+ aci.setIndex(runLimit);
+ runStart = aci.getRunStart();
+ if (runStart != 3) {
+ throw new Exception("2nd run start is wrong. ("+runStart+" should be 3.)");
+ }
+
+ runLimit = aci.getRunLimit();
+ if (runLimit != 4) {
+ throw new Exception("2nd run limit is wrong. ("+runLimit+" should be 4.)");
+ }
+ value = aci.getAttribute(TextAttribute.WEIGHT);
+ if (value != TextAttribute.WEIGHT_BOLD) {
+ throw new Exception("2nd run attribute is wrong. ("
+ +value+" should be "+TextAttribute.WEIGHT_BOLD+".)");
+ }
+
+ value = aci.getAttribute(TextAttribute.WIDTH);
+ if (!(value instanceof Annotation)
+ || (((Annotation)value).getValue() != TextAttribute.WIDTH_CONDENSED)) {
+ throw new Exception("2nd run annotation is wrong. (" + value + " should be "
+ + new Annotation(TextAttribute.WIDTH_CONDENSED)+".)");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/Bug4533872.java b/ojluni/src/test/java/text/BreakIterator/Bug4533872.java
new file mode 100644
index 00000000000..c9bbe4520df
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/Bug4533872.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4533872 4640853
+ * @library /java/text/testlib
+ * @summary Unit tests for supplementary character support (JSR-204) and Unicode 4.0 support
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.BreakIterator;
+import java.util.Locale;
+
+import test.java.text.testlib.IntlTest;
+
+public class Bug4533872 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new Bug4533872().run(args);
+ }
+
+ static final String[] given = {
+ /* Lu Nd Lu Ll */
+ "XYZ12345 ABCDE abcde",
+ /* Nd Lo Nd Lu Po Lu Ll */
+ "123\uD800\uDC00345 ABC\uFF61XYZ abc",
+ /* Nd Lo Nd Lu Po Lu Ll */
+ "123\uD800\uDC00345 ABC\uD800\uDD00XYZ abc",
+ /* Lu Ll Cs Ll Cs Lu Lo Lu */
+ "ABCabc\uDC00xyz\uD800ABC\uD800\uDC00XYZ",
+ };
+
+ // Golden data for TestNext(), TestBoundar() and TestPrintEach*ward()
+ static final String[][] expected = {
+ {"XYZ12345", " ", "ABCDE", " ", "abcde"},
+ {"123\uD800\uDC00345", " ", "ABC", "\uFF61", "XYZ", " ", "abc"},
+ {"123\uD800\uDC00345", " ", "ABC", "\uD800\uDD00", "XYZ", " ", "abc"},
+ {"ABCabc", "\uDC00", "xyz", "\uD800", "ABC\uD800\uDC00XYZ"},
+ };
+
+ BreakIterator iter;
+ int start, end, current;
+
+ /*
+ * Test for next(int n)
+ */
+ void TestNext() {
+ iter = BreakIterator.getWordInstance(Locale.US);
+
+ for (int i = 0; i < given.length; i++) {
+ iter.setText(given[i]);
+ start = iter.first();
+ int j = expected[i].length - 1;
+ start = iter.next(j);
+ end = iter.next();
+
+ if (!expected[i][j].equals(given[i].substring(start, end))) {
+ errln("Word break failure: printEachForward() expected:<" +
+ expected[i][j] + ">, got:<" +
+ given[i].substring(start, end) +
+ "> start=" + start + " end=" + end);
+ }
+ }
+ }
+
+ /*
+ * Test for isBoundary(int n)
+ */
+ void TestIsBoundary() {
+ iter = BreakIterator.getWordInstance(Locale.US);
+
+ for (int i = 0; i < given.length; i++) {
+ iter.setText(given[i]);
+
+ start = iter.first();
+ end = iter.next();
+
+ while (end < given[i].length()) {
+ if (!iter.isBoundary(end)) {
+ errln("Word break failure: isBoundary() This should be a boundary. Index=" +
+ end + " for " + given[i]);
+ }
+ end = iter.next();
+ }
+ }
+ }
+
+
+ /*
+ * The followig test cases were made based on examples in BreakIterator's
+ * API Doc.
+ */
+
+ /*
+ * Test mainly for next() and current()
+ */
+ void TestPrintEachForward() {
+ iter = BreakIterator.getWordInstance(Locale.US);
+
+ for (int i = 0; i < given.length; i++) {
+ iter.setText(given[i]);
+ start = iter.first();
+
+ // Check current()'s return value - should be same as first()'s.
+ current = iter.current();
+ if (start != current) {
+ errln("Word break failure: printEachForward() Unexpected current value: current()=" +
+ current + ", expected(=first())=" + start);
+ }
+
+ int j = 0;
+ for (end = iter.next();
+ end != BreakIterator.DONE;
+ start = end, end = iter.next(), j++) {
+
+ // Check current()'s return value - should be same as next()'s.
+ current = iter.current();
+ if (end != current) {
+ errln("Word break failure: printEachForward() Unexpected current value: current()=" +
+ current + ", expected(=next())=" + end);
+ }
+
+ if (!expected[i][j].equals(given[i].substring(start, end))) {
+ errln("Word break failure: printEachForward() expected:<" +
+ expected[i][j] + ">, got:<" +
+ given[i].substring(start, end) +
+ "> start=" + start + " end=" + end);
+ }
+ }
+ }
+ }
+
+ /*
+ * Test mainly for previous() and current()
+ */
+ void TestPrintEachBackward() {
+ iter = BreakIterator.getWordInstance(Locale.US);
+
+ for (int i = 0; i < given.length; i++) {
+ iter.setText(given[i]);
+ end = iter.last();
+
+ // Check current()'s return value - should be same as last()'s.
+ current = iter.current();
+ if (end != current) {
+ errln("Word break failure: printEachBackward() Unexpected current value: current()=" +
+ current + ", expected(=last())=" + end);
+ }
+
+ int j;
+ for (start = iter.previous(), j = expected[i].length-1;
+ start != BreakIterator.DONE;
+ end = start, start = iter.previous(), j--) {
+
+ // Check current()'s return value - should be same as previous()'s.
+ current = iter.current();
+ if (start != current) {
+ errln("Word break failure: printEachBackward() Unexpected current value: current()=" +
+ current + ", expected(=previous())=" + start);
+ }
+
+ if (!expected[i][j].equals(given[i].substring(start, end))) {
+ errln("Word break failure: printEachBackward() expected:<" +
+ expected[i][j] + ">, got:<" +
+ given[i].substring(start, end) +
+ "> start=" + start + " end=" + end);
+ }
+ }
+ }
+ }
+
+ /*
+ * Test mainly for following() and previous()
+ */
+ void TestPrintAt_1() {
+ iter = BreakIterator.getWordInstance(Locale.US);
+
+ int[][] index = {
+ {2, 8, 10, 15, 17},
+ {1, 8, 10, 12, 15, 17, 20},
+ {3, 8, 10, 13, 16, 18, 20},
+ {4, 6, 9, 10, 16},
+ };
+
+ for (int i = 0; i < given.length; i++) {
+ iter.setText(given[i]);
+ for (int j = index[i].length-1; j >= 0; j--) {
+ end = iter.following(index[i][j]);
+ start = iter.previous();
+
+ if (!expected[i][j].equals(given[i].substring(start, end))) {
+ errln("Word break failure: printAt_1() expected:<" +
+ expected[i][j] + ">, got:<" +
+ given[i].substring(start, end) +
+ "> start=" + start + " end=" + end);
+ }
+ }
+ }
+ }
+
+ /*
+ * Test mainly for preceding() and next()
+ */
+ void TestPrintAt_2() {
+ iter = BreakIterator.getWordInstance(Locale.US);
+
+ int[][] index = {
+ {2, 9, 10, 15, 17},
+ {1, 9, 10, 13, 16, 18, 20},
+ {4, 9, 10, 13, 16, 18, 20},
+ {6, 7, 10, 11, 15},
+ };
+
+ for (int i = 0; i < given.length; i++) {
+ iter.setText(given[i]);
+
+ // Check preceding(0)'s return value - should equals BreakIterator.DONE.
+ if (iter.preceding(0) != BreakIterator.DONE) {
+ errln("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" +
+ iter.preceding(0));
+ }
+
+ for (int j = 0; j < index[i].length; j++) {
+ start = iter.preceding(index[i][j]);
+ end = iter.next();
+
+ if (!expected[i][j].equals(given[i].substring(start, end))) {
+ errln("Word break failure: printAt_2() expected:<" +
+ expected[i][j] + ">, got:<" +
+ given[i].substring(start, end) +
+ "> start=" + start + " end=" + end);
+ }
+ }
+
+ // Check next()'s return value - should equals BreakIterator.DONE.
+ end = iter.last();
+ start = iter.next();
+ if (start != BreakIterator.DONE) {
+ errln("Word break failure: printAt_2() expected:-1(BreakIterator.DONE), got:" + start);
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/Bug4740757.java b/ojluni/src/test/java/text/BreakIterator/Bug4740757.java
new file mode 100644
index 00000000000..7b20289ad13
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/Bug4740757.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4740757
+ * @summary Confirm line-breaking behavior of Hangul
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.*;
+import java.util.*;
+
+public class Bug4740757 {
+
+ private static boolean err = false;
+
+ public static void main(String[] args) {
+ Locale defaultLocale = Locale.getDefault();
+ if (defaultLocale.getLanguage().equals("th")) {
+ Locale.setDefault(Locale.KOREA);
+ test4740757();
+ Locale.setDefault(defaultLocale);
+ } else {
+ test4740757();
+ }
+
+ if (err) {
+ throw new RuntimeException("Incorrect Line-breaking");
+ }
+ }
+
+ private static void test4740757() {
+ String source = "\uc548\ub155\ud558\uc138\uc694? \uc88b\uc740 \uc544\uce68, \uc5ec\ubcf4\uc138\uc694! \uc548\ub155. End.";
+ String expected = "\uc548/\ub155/\ud558/\uc138/\uc694? /\uc88b/\uc740 /\uc544/\uce68, /\uc5ec/\ubcf4/\uc138/\uc694! /\uc548/\ub155. /End./";
+
+ BreakIterator bi = BreakIterator.getLineInstance(Locale.KOREAN);
+ bi.setText(source);
+ int start = bi.first();
+ int end = bi.next();
+ StringBuilder sb = new StringBuilder();
+
+ for (; end != BreakIterator.DONE; start = end, end = bi.next()) {
+ sb.append(source.substring(start,end));
+ sb.append('/');
+ }
+
+ if (!expected.equals(sb.toString())) {
+ System.err.println("Failed: Hangul line-breaking failed." +
+ "\n\tExpected: " + expected +
+ "\n\tGot: " + sb +
+ "\nin " + Locale.getDefault() + " locale.");
+ err = true;
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/Bug4912404.java b/ojluni/src/test/java/text/BreakIterator/Bug4912404.java
new file mode 100644
index 00000000000..2ad9573b3c7
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/Bug4912404.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4912404
+ * @summary Confirm that BreakIterator.equals(null) return false.
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.BreakIterator;
+
+public class Bug4912404 {
+
+ public static void main(String[] args) {
+ BreakIterator b = BreakIterator.getWordInstance();
+ b.setText("abc");
+ if (b.equals(null)) {
+ throw new RuntimeException("BreakIterator.equals(null) should return false.");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/Bug4932583.java b/ojluni/src/test/java/text/BreakIterator/Bug4932583.java
new file mode 100644
index 00000000000..1b52b604e91
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/Bug4932583.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run main/timeout=60 Bug4932583
+ * @bug 4932583
+ * @summary Confirm that BreakIterator doesn't get caught in an infinite loop.
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class Bug4932583 {
+ public static void main(String[] args) {
+ BreakIterator iterator = BreakIterator.getCharacterInstance();
+ iterator.setText("\uDB40\uDFFF");
+ int boundary = iterator.next();
+ }
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/Bug7104012.java b/ojluni/src/test/java/text/BreakIterator/Bug7104012.java
new file mode 100644
index 00000000000..acfc8b0ec13
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/Bug7104012.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 7104012
+ * @summary Confirm that AIOBE is not thrown.
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.*;
+import java.util.*;
+
+public class Bug7104012 {
+
+ public static void main(String[] args) {
+ boolean err = false;
+
+ List<String> data = new ArrayList<>();
+ data.add("\udb40");
+ data.add(" \udb40");
+ data.add("\udc53");
+ data.add(" \udc53");
+ data.add(" \udb40\udc53");
+ data.add("\udb40\udc53");
+ data.add("ABC \udb40\udc53 123");
+ data.add("\udb40\udc53 ABC \udb40\udc53");
+
+ for (Locale locale : Locale.getAvailableLocales()) {
+ List<BreakIterator> breakIterators = new ArrayList<>();
+ breakIterators.add(BreakIterator.getCharacterInstance(locale));
+ breakIterators.add(BreakIterator.getLineInstance(locale));
+ breakIterators.add(BreakIterator.getSentenceInstance(locale));
+ breakIterators.add(BreakIterator.getWordInstance(locale));
+
+ for (BreakIterator bi : breakIterators) {
+ for (String str : data) {
+ try {
+ bi.setText(str);
+ bi.first();
+ while (bi.next() != BreakIterator.DONE) { }
+ bi.last();
+ while (bi.previous() != BreakIterator.DONE) { }
+ }
+ catch (ArrayIndexOutOfBoundsException ex) {
+ System.out.println(" " + data.indexOf(str)
+ + ": BreakIterator(" + locale
+ + ") threw AIOBE.");
+ err = true;
+ }
+ }
+ }
+ }
+
+ if (err) {
+ throw new RuntimeException("Unexpected exeption.");
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/Bug8032446.java b/ojluni/src/test/java/text/BreakIterator/Bug8032446.java
new file mode 100644
index 00000000000..731242e50bb
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/Bug8032446.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8032446
+ * @summary Confirm that BreakIterator works as expected with new characters in Unicode 7.
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.*;
+import java.util.*;
+
+public class Bug8032446 {
+
+ public static void main(String[] args) {
+ boolean err = false;
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0x10860; i <= 0x10876; i++) { // Palmyrene Letters
+ sb.append(Character.toChars(i));
+ }
+ sb.append(" ");
+ for (int i = 0x10879; i <= 0x1087D; i++) { // Palmyrene Numbers
+ sb.append(Character.toChars(i));
+ }
+ String s = sb.toString();
+
+ BreakIterator bi = BreakIterator.getWordInstance(Locale.ROOT);
+ bi.setText(s);
+ bi.first();
+
+ if (bi.next() != s.indexOf(' ')) {
+ throw new RuntimeException("Unexpected word breaking.");
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/ExceptionTest.java b/ojluni/src/test/java/text/BreakIterator/ExceptionTest.java
new file mode 100644
index 00000000000..24318717ae5
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/ExceptionTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 6521742
+ * @summary test exceptions
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.*;
+import java.util.*;
+import static java.text.BreakIterator.DONE;
+
+public class ExceptionTest {
+ private static final String text =
+ "An ordered collection (also known as a sequence). "
+ + "The user of this interface has precise control over "
+ + "where in the list each element is inserted. "
+ + "The user can access elements by their integer index (position in the list), "
+ + "and search for elements in the list.";
+
+ public static void main(String[] args) {
+ BreakIterator bi = BreakIterator.getWordInstance();
+ bi.setText(text);
+ MirroredBreakIterator mirror = new MirroredBreakIterator(bi);
+ final int first = bi.first();
+ if (first != 0) {
+ throw new RuntimeException("first != 0: " + first);
+ }
+ final int last = bi.last();
+ bi = BreakIterator.getWordInstance();
+ bi.setText(text);
+ int length = text.length();
+
+ /*
+ * following(int)
+ */
+ for (int i = 0; i <= length; i++) {
+ if (i == length) {
+ check(bi.following(i), DONE);
+ }
+ check(bi.following(i), mirror.following(i));
+ check(bi.current(), mirror.current());
+ }
+ for (int i = -length; i < 0; i++) {
+ checkFollowingException(bi, i);
+ checkFollowingException(mirror, i);
+ check(bi.current(), mirror.current());
+ }
+ for (int i = 1; i < length; i++) {
+ checkFollowingException(bi, length + i);
+ checkFollowingException(mirror, length + i);
+ check(bi.current(), mirror.current());
+ }
+
+ /*
+ * preceding(int)
+ */
+ for (int i = length; i >= 0; i--) {
+ if (i == 0) {
+ check(bi.preceding(i), DONE);
+ }
+ check(bi.preceding(i), mirror.preceding(i));
+ check(bi.current(), mirror.current());
+ }
+ for (int i = -length; i < 0; i++) {
+ checkPrecedingException(bi, i);
+ checkPrecedingException(mirror, i);
+ check(bi.current(), mirror.current());
+ }
+ for (int i = 1; i < length; i++) {
+ checkPrecedingException(bi, length + i);
+ checkPrecedingException(mirror, length + i);
+ check(bi.current(), mirror.current());
+ }
+
+ /*
+ * isBoundary(int)
+ */
+ for (int i = 0; i <= length; i++) {
+ check(bi.isBoundary(i), mirror.isBoundary(i));
+ check(bi.current(), mirror.current());
+ }
+ for (int i = -length; i < 0; i++) {
+ checkIsBoundaryException(bi, i);
+ checkIsBoundaryException(mirror, i);
+ }
+ for (int i = 1; i < length; i++) {
+ checkIsBoundaryException(bi, length + i);
+ checkIsBoundaryException(mirror, length + i);
+ }
+ }
+
+ private static void check(int i1, int i2) {
+ if (i1 != i2) {
+ throw new RuntimeException(i1 + " != " + i2);
+ }
+ }
+
+ private static void check(boolean b1, boolean b2) {
+ if (b1 != b2) {
+ throw new RuntimeException(b1 + " != " + b2);
+ }
+ }
+
+ private static void checkFollowingException(BreakIterator bi, int offset) {
+ try {
+ bi.following(offset);
+ } catch (IllegalArgumentException e) {
+ return; // OK
+ }
+ throw new RuntimeException(bi + ": following() doesn't throw an IAE with offset "
+ + offset);
+ }
+
+ private static void checkPrecedingException(BreakIterator bi, int offset) {
+ try {
+ bi.preceding(offset);
+ } catch (IllegalArgumentException e) {
+ return; // OK
+ }
+ throw new RuntimeException(bi + ": preceding() doesn't throw an IAE with offset "
+ + offset);
+ }
+
+ private static void checkIsBoundaryException(BreakIterator bi, int offset) {
+ try {
+ bi.isBoundary(offset);
+ } catch (IllegalArgumentException e) {
+ return; // OK
+ }
+ throw new RuntimeException(bi + ": isBoundary() doesn't throw an IAE with offset "
+ + offset);
+ }
+}
diff --git a/ojluni/src/test/java/text/BreakIterator/MirroredBreakIterator.java b/ojluni/src/test/java/text/BreakIterator/MirroredBreakIterator.java
new file mode 100644
index 00000000000..79ccc091fc8
--- /dev/null
+++ b/ojluni/src/test/java/text/BreakIterator/MirroredBreakIterator.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.text.BreakIterator;
+
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+public class MirroredBreakIterator extends BreakIterator {
+ private final List<Integer> boundaries;
+ private int charIndex;
+ private int boundaryIndex;
+
+ MirroredBreakIterator(BreakIterator bi) {
+ List<Integer> b = new ArrayList<Integer>();
+ int i = bi.first();
+ charIndex = i;
+ for (; i != DONE; i = bi.next()) {
+ b.add(i);
+ }
+ boundaries = Collections.unmodifiableList(b);
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (Exception e) {
+ throw new RuntimeException("clone failed", e);
+ }
+ }
+
+ @Override
+ public int first() {
+ return changeIndices(0);
+ }
+
+ @Override
+ public int last() {
+ return changeIndices(boundaries.size() - 1);
+ }
+
+ @Override
+ public int next(int n) {
+ if (n == 0) {
+ return current();
+ }
+ int newBoundary = boundaryIndex + n;
+ if (newBoundary < 0) {
+ first();
+ return DONE;
+ }
+ if (newBoundary > lastBoundary()) {
+ last();
+ return DONE;
+ }
+ return changeIndices(newBoundary);
+ }
+
+ @Override
+ public int next() {
+ if (boundaryIndex == lastBoundary()) {
+ return DONE;
+ }
+ return changeIndices(boundaryIndex + 1);
+ }
+
+ @Override
+ public int previous() {
+ if (boundaryIndex == 0) {
+ return DONE;
+ }
+ return changeIndices(boundaryIndex - 1);
+ }
+
+ @Override
+ public int following(int offset) {
+ validateOffset(offset);
+ for (int b = 0; b <= lastBoundary(); b++) {
+ int i = boundaries.get(b);
+ if (i > offset) {
+ return changeIndices(i, b);
+ }
+ }
+ return DONE;
+ }
+
+ @Override
+ public int preceding(int offset) {
+ validateOffset(offset);
+ for (int b = lastBoundary(); b >= 0; b--) {
+ int i = boundaries.get(b);
+ if (i < offset) {
+ return changeIndices(i, b);
+ }
+ }
+ return DONE;
+ }
+
+ @Override
+ public boolean isBoundary(int offset) {
+ // Call the default impelementation in BreakIterator
+ return super.isBoundary(offset);
+ }
+
+ @Override
+ public int current() {
+ return charIndex;
+ }
+
+ @Override
+ public CharacterIterator getText() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setText(CharacterIterator newText) {
+ throw new UnsupportedOperationException();
+ }
+
+ private int lastBoundary() {
+ return boundaries.size() - 1;
+ }
+
+ private int changeIndices(int newCharIndex, int newBoundary) {
+ boundaryIndex = newBoundary;
+ return charIndex = newCharIndex;
+ }
+
+ private int changeIndices(int newBoundary) {
+ try {
+ return changeIndices(boundaries.get(newBoundary), newBoundary);
+ } catch (IndexOutOfBoundsException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private void validateOffset(int offset) {
+ if (offset < boundaries.get(0) || offset > boundaries.get(lastBoundary())) {
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/CharacterIterator/CharacterIteratorTest.java b/ojluni/src/test/java/text/CharacterIterator/CharacterIteratorTest.java
new file mode 100644
index 00000000000..9ad95dcc1fc
--- /dev/null
+++ b/ojluni/src/test/java/text/CharacterIterator/CharacterIteratorTest.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test for Character Iterator
+ */
+
+/*
+ *
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ * Portions copyright (c) 2007 Sun Microsystems, Inc.
+ * All Rights Reserved.
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ */
+
+package test.java.text.CharacterIterator;
+
+import java.text.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class CharacterIteratorTest extends IntlTest {
+ public static void main(String[] args) throws Exception {
+ new CharacterIteratorTest().run(args);
+ }
+
+ public CharacterIteratorTest() {
+ }
+
+ public void TestConstructionAndEquality() {
+ String testText = "Now is the time for all good men to come to the aid of their country.";
+ String testText2 = "Don't bother using this string.";
+
+ CharacterIterator test1 = new StringCharacterIterator(testText);
+ CharacterIterator test2 = new StringCharacterIterator(testText, 5);
+ CharacterIterator test3 = new StringCharacterIterator(testText, 2, 20, 5);
+ CharacterIterator test4 = new StringCharacterIterator(testText2);
+ CharacterIterator test5 = (CharacterIterator)test1.clone();
+
+ if (test1.equals(test2) || test1.equals(test3) || test1.equals(test4))
+ errln("Construation or equals() failed: Two unequal iterators tested equal");
+
+ if (!test1.equals(test5))
+ errln("clone() or equals() failed: Two clones tested unequal");
+
+ if (test1.hashCode() == test2.hashCode() || test1.hashCode() == test3.hashCode()
+ || test1.hashCode() == test4.hashCode())
+ errln("hash() failed: different objects have same hash code");
+
+ if (test1.hashCode() != test5.hashCode())
+ errln("hash() failed: identical objects have different hash codes");
+
+ test1.setIndex(5);
+ if (!test1.equals(test2) || test1.equals(test5))
+ errln("setIndex() failed");
+ }
+
+ public void TestIteration() {
+ String text = "Now is the time for all good men to come to the aid of their country.";
+
+ CharacterIterator iter = new StringCharacterIterator(text, 5);
+
+ if (iter.current() != text.charAt(5))
+ errln("Iterator didn't start out in the right place.");
+
+ char c = iter.first();
+ int i = 0;
+
+ if (iter.getBeginIndex() != 0 || iter.getEndIndex() != text.length())
+ errln("getBeginIndex() or getEndIndex() failed");
+
+ logln("Testing forward iteration...");
+ do {
+ if (c == CharacterIterator.DONE && i != text.length())
+ errln("Iterator reached end prematurely");
+ else if (c != text.charAt(i))
+ errln("Character mismatch at position " + i + ", iterator has " + c +
+ ", string has " + text.charAt(c));
+
+ if (iter.current() != c)
+ errln("current() isn't working right");
+ if (iter.getIndex() != i)
+ errln("getIndex() isn't working right");
+
+ if (c != CharacterIterator.DONE) {
+ c = iter.next();
+ i++;
+ }
+ } while (c != CharacterIterator.DONE);
+
+ c = iter.last();
+ i = text.length() - 1;
+
+ logln("Testing backward iteration...");
+ do {
+ if (c == CharacterIterator.DONE && i >= 0)
+ errln("Iterator reached end prematurely");
+ else if (c != text.charAt(i))
+ errln("Character mismatch at position " + i + ", iterator has " + c +
+ ", string has " + text.charAt(c));
+
+ if (iter.current() != c)
+ errln("current() isn't working right");
+ if (iter.getIndex() != i)
+ errln("getIndex() isn't working right");
+
+ if (c != CharacterIterator.DONE) {
+ c = iter.previous();
+ i--;
+ }
+ } while (c != CharacterIterator.DONE);
+
+ iter = new StringCharacterIterator(text, 5, 15, 10);
+ if (iter.getBeginIndex() != 5 || iter.getEndIndex() != 15)
+ errln("creation of a restricted-range iterator failed");
+
+ if (iter.getIndex() != 10 || iter.current() != text.charAt(10))
+ errln("starting the iterator in the middle didn't work");
+
+ c = iter.first();
+ i = 5;
+
+ logln("Testing forward iteration over a range...");
+ do {
+ if (c == CharacterIterator.DONE && i != 15)
+ errln("Iterator reached end prematurely");
+ else if (c != text.charAt(i))
+ errln("Character mismatch at position " + i + ", iterator has " + c +
+ ", string has " + text.charAt(c));
+
+ if (iter.current() != c)
+ errln("current() isn't working right");
+ if (iter.getIndex() != i)
+ errln("getIndex() isn't working right");
+
+ if (c != CharacterIterator.DONE) {
+ c = iter.next();
+ i++;
+ }
+ } while (c != CharacterIterator.DONE);
+
+ c = iter.last();
+ i = 14;
+
+ logln("Testing backward iteration over a range...");
+ do {
+ if (c == CharacterIterator.DONE && i >= 5)
+ errln("Iterator reached end prematurely");
+ else if (c != text.charAt(i))
+ errln("Character mismatch at position " + i + ", iterator has " + c +
+ ", string has " + text.charAt(c));
+
+ if (iter.current() != c)
+ errln("current() isn't working right");
+ if (iter.getIndex() != i)
+ errln("getIndex() isn't working right");
+
+ if (c != CharacterIterator.DONE) {
+ c = iter.previous();
+ i--;
+ }
+ } while (c != CharacterIterator.DONE);
+ }
+
+ /**
+ * @bug 4082050 4078261 4078255
+ */
+ public void TestPathologicalCases() {
+ String text = "This is only a test.";
+
+/*
+This test is commented out until API-change approval for bug #4082050 goes through.
+ // test for bug #4082050 (don't get an error if begin == end, even though all
+ // operations on the iterator will cause exceptions)
+ // [I actually fixed this so that you CAN create an iterator with begin == end,
+ // but all operations on it return DONE.]
+ CharacterIterator iter = new StringCharacterIterator(text, 5, 5, 5);
+ if (iter.first() != CharacterIterator.DONE
+ || iter.next() != CharacterIterator.DONE
+ || iter.last() != CharacterIterator.DONE
+ || iter.previous() != CharacterIterator.DONE
+ || iter.current() != CharacterIterator.DONE
+ || iter.getIndex() != 5)
+ errln("Got something other than DONE when performing operations on an empty StringCharacterIterator");
+*/
+CharacterIterator iter = null;
+
+ // if we try to construct a StringCharacterIterator with an endIndex that's off
+ // the end of the String under iterator, we're supposed to get an
+ // IllegalArgumentException
+ boolean gotException = false;
+ try {
+ iter = new StringCharacterIterator(text, 5, 100, 5);
+ }
+ catch (IllegalArgumentException e) {
+ gotException = true;
+ }
+ if (!gotException)
+ errln("StringCharacterIterator didn't throw an exception when given an invalid substring range.");
+
+ // test for bug #4078255 (getting wrong value from next() when we're at the end
+ // of the string)
+ iter = new StringCharacterIterator(text);
+ int expectedIndex = iter.getEndIndex();
+ int actualIndex;
+
+ iter.last();
+ actualIndex = iter.getIndex();
+ if (actualIndex != expectedIndex - 1)
+ errln("last() failed: expected " + (expectedIndex - 1) + ", got " + actualIndex);
+
+ iter.next();
+ actualIndex = iter.getIndex();
+ if (actualIndex != expectedIndex)
+ errln("next() after last() failed: expected " + expectedIndex + ", got " + actualIndex);
+
+ iter.next();
+ actualIndex = iter.getIndex();
+ if (actualIndex != expectedIndex)
+ errln("second next() after last() failed: expected " + expectedIndex + ", got " + actualIndex);
+ }
+
+ /*
+ * @bug 4123771 4051073
+ * #4123771 is actually a duplicate of bug #4051073, which was fixed some time ago, but
+ * no one ever added a regression test for it.
+ */
+ public void TestBug4123771() {
+ String text = "Some string for testing";
+ StringCharacterIterator iter = new StringCharacterIterator(text);
+ int index = iter.getEndIndex();
+ try {
+ char c = iter.setIndex(index);
+ }
+ catch (Exception e) {
+ System.out.println("method setIndex(int position) throws unexpected exception " + e);
+ System.out.println(" position: " + index);
+ System.out.println(" getEndIndex(): " + iter.getEndIndex());
+ System.out.println(" text.length(): " + text.length());
+ errln(""); // re-throw the exception through our test framework
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Collator/Bug5047314.java b/ojluni/src/test/java/text/Collator/Bug5047314.java
new file mode 100644
index 00000000000..ddd2d043dc5
--- /dev/null
+++ b/ojluni/src/test/java/text/Collator/Bug5047314.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5047314
+ * @summary verify that compare() and getCollationKey() don't go into an infinite loop for unfinished Thai/Lao text.
+ * @run main/timeout=60 Bug5047314
+ */
+package test.java.text.Collator;
+
+import java.text.Collator;
+import java.util.Locale;
+
+public class Bug5047314 {
+
+ private static Collator colLao = Collator.getInstance(new Locale("lo"));
+ private static Collator colThai = Collator.getInstance(new Locale("th"));
+
+ private static String[] textLao = {
+ "\u0ec0", "\u0ec1", "\u0ec2", "\u0ec3", "\u0ec4"
+ };
+ private static String[] textThai = {
+ "\u0e40", "\u0e41", "\u0e42", "\u0e43", "\u0e44"
+ };
+
+ public static void main(String[] args) {
+ testLao1();
+ testLao2();
+ testThai1();
+ testThai2();
+ }
+
+ private static void testLao1() {
+ System.out.print("Test(Lao 1) .... ");
+ for (int i = 0; i < textLao.length; i++) {
+ colLao.compare(textLao[i], textLao[i]);
+ }
+ System.out.println("Passed.");
+ }
+
+ private static void testLao2() {
+ System.out.print("Test(Lao 2) .... ");
+ for (int i = 0; i < textLao.length; i++) {
+ colLao.compare(textLao[i], textLao[i]);
+ }
+ System.out.println("Passed.");
+ }
+
+ private static void testThai1() {
+ System.out.print("Test(Thai 1) .... ");
+ for (int i = 0; i < textThai.length; i++) {
+ colThai.compare(textThai[i], textThai[i]);
+ }
+ System.out.println("Passed.");
+ }
+
+ private static void testThai2() {
+ System.out.print("Test(Thai 2) .... ");
+ for (int i = 0; i < textThai.length; i++) {
+ colThai.getCollationKey(textThai[i]);
+ }
+ System.out.println("Passed.");
+ }
+
+}
diff --git a/ojluni/src/test/java/text/Collator/Bug7200119.java b/ojluni/src/test/java/text/Collator/Bug7200119.java
new file mode 100644
index 00000000000..d2117376be0
--- /dev/null
+++ b/ojluni/src/test/java/text/Collator/Bug7200119.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7200119
+ * @summary verify that getAvailableLocales() contains Locale.US
+ */
+package test.java.text.Collator;
+
+import java.text.*;
+import java.util.*;
+
+public class Bug7200119 {
+ public static void main(String[] args) {
+ List<Locale> avail = Arrays.asList(Collator.getAvailableLocales());
+
+ if (!avail.contains(Locale.US)) {
+ throw new RuntimeException("Failed.");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Collator/CollatorTest.java b/ojluni/src/test/java/text/Collator/CollatorTest.java
new file mode 100644
index 00000000000..a183d8f1874
--- /dev/null
+++ b/ojluni/src/test/java/text/Collator/CollatorTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.text.Collator;
+
+import java.lang.reflect.*;
+import java.util.Hashtable;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.io.*;
+import java.text.*;
+
+import test.java.text.testlib.IntlTest;
+
+/**
+ * CollatorTest is a base class for tests that can be run conveniently from
+ * the command line as well as under the Java test harness.
+ * <p>
+ * Sub-classes implement a set of methods named Test<something>. Each
+ * of these methods performs some test. Test methods should indicate
+ * errors by calling either err or errln. This will increment the
+ * errorCount field and may optionally print a message to the log.
+ * Debugging information may also be added to the log via the log
+ * and logln methods. These methods will add their arguments to the
+ * log only if the test is being run in verbose mode.
+ */
+public abstract class CollatorTest extends IntlTest {
+
+ //------------------------------------------------------------------------
+ // These methods are utilities specific to the Collation tests..
+ //------------------------------------------------------------------------
+
+ protected void assertEqual(CollationElementIterator i1, CollationElementIterator i2) {
+ int c1, c2, count = 0;
+ do {
+ c1 = i1.next();
+ c2 = i2.next();
+ if (c1 != c2) {
+ errln(" " + count + ": " + c1 + " != " + c2);
+ break;
+ }
+ count++;
+ } while (c1 != CollationElementIterator.NULLORDER);
+ }
+
+ // Replace nonprintable characters with unicode escapes
+ static protected String prettify(String str) {
+ StringBuffer result = new StringBuffer();
+
+ String zero = "0000";
+
+ for (int i = 0; i < str.length(); i++) {
+ char ch = str.charAt(i);
+ if (ch < 0x09 || (ch > 0x0A && ch < 0x20)|| (ch > 0x7E && ch < 0xA0) || ch > 0x100) {
+ String hex = Integer.toString((int)ch,16);
+
+ result.append("\\u" + zero.substring(0, 4 - hex.length()) + hex);
+ } else {
+ result.append(ch);
+ }
+ }
+ return result.toString();
+ }
+
+ // Produce a printable representation of a CollationKey
+ static protected String prettify(CollationKey key) {
+ StringBuffer result = new StringBuffer();
+ byte[] bytes = key.toByteArray();
+
+ for (int i = 0; i < bytes.length; i += 2) {
+ int val = (bytes[i] << 8) + bytes[i+1];
+ result.append(Integer.toString(val, 16) + " ");
+ }
+ return result.toString();
+ }
+
+ //------------------------------------------------------------------------
+ // Everything below here is boilerplate code that makes it possible
+ // to add a new test by simply adding a function to an existing class
+ //------------------------------------------------------------------------
+
+ protected void doTest(Collator col, int strength,
+ String[] source, String[] target, int[] result) {
+ if (source.length != target.length) {
+ errln("Data size mismatch: source = " +
+ source.length + ", target = " + target.length);
+
+ return; // Return if "-nothrow" is specified.
+ }
+ if (source.length != result.length) {
+ errln("Data size mismatch: source & target = " +
+ source.length + ", result = " + result.length);
+
+ return; // Return if "-nothrow" is specified.
+ }
+
+ col.setStrength(strength);
+ for (int i = 0; i < source.length ; i++) {
+ doTest(col, source[i], target[i], result[i]);
+ }
+ }
+
+ protected void doTest(Collator col,
+ String source, String target, int result) {
+ char relation = '=';
+ if (result <= -1) {
+ relation = '<';
+ } else if (result >= 1) {
+ relation = '>';
+ }
+
+ int compareResult = col.compare(source, target);
+ CollationKey sortKey1 = col.getCollationKey(source);
+ CollationKey sortKey2 = col.getCollationKey(target);
+ int keyResult = sortKey1.compareTo(sortKey2);
+ if (compareResult != keyResult) {
+ errln("Compare and Collation Key results are different! Source = " +
+ source + " Target = " + target);
+ }
+ if (keyResult != result) {
+ errln("Collation Test failed! Source = " + source + " Target = " +
+ target + " result should be " + relation);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Collator/MonkeyTest.java b/ojluni/src/test/java/text/Collator/MonkeyTest.java
new file mode 100644
index 00000000000..7a4b98d1809
--- /dev/null
+++ b/ojluni/src/test/java/text/Collator/MonkeyTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test Collation, Monkey style
+ */
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+package test.java.text.Collator;
+
+import java.io.IOException;
+import java.util.Random;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Locale;
+import java.text.Collator;
+import java.text.RuleBasedCollator;
+import java.text.CollationKey;
+
+public class MonkeyTest extends CollatorTest
+{
+ public static void main(String[] args) throws Exception {
+ new MonkeyTest().run(args);
+ }
+
+ public void report(String s, String t, int result, int revResult)
+ {
+ if (result == -1)
+ {
+ if (revResult != 1)
+ errln(" --> Test Failed");
+ }
+ else if (result == 1)
+ {
+ if (revResult != -1)
+ errln(" --> Test Failed");
+ }
+ else if (result == 0)
+ {
+ if (revResult != 0)
+ errln(" --> Test Failed");
+ }
+ }
+
+ public void TestCollationKey()
+ {
+ String source = "-abcdefghijklmnopqrstuvwxyz#&^$@";
+ Random r = new Random(3);
+ int s = checkValue(r.nextInt() % source.length());
+ int t = checkValue(r.nextInt() % source.length());
+ int slen = checkValue((r.nextInt() - source.length()) % source.length());
+ int tlen = checkValue((r.nextInt() - source.length()) % source.length());
+ String subs = source.substring((s > slen ? slen : s), (s >= slen ? s : slen));
+ String subt = source.substring((t > tlen ? tlen : t), (t >= tlen ? t : tlen));
+ myCollator.setStrength(Collator.TERTIARY);
+ CollationKey CollationKey1 = myCollator.getCollationKey(subs);
+ CollationKey CollationKey2 = myCollator.getCollationKey(subt);
+ int result = CollationKey1.compareTo(CollationKey2); // Tertiary
+ int revResult = CollationKey2.compareTo(CollationKey1); // Tertiary
+ report(("CollationKey(" + subs + ")"), ("CollationKey(" + subt + ")"), result, revResult);
+ myCollator.setStrength(Collator.SECONDARY);
+ CollationKey1 = myCollator.getCollationKey(subs);
+ CollationKey2 = myCollator.getCollationKey(subt);
+ result = CollationKey1.compareTo(CollationKey2); // Secondary
+ revResult = CollationKey2.compareTo(CollationKey1); // Secondary
+ report(("CollationKey(" + subs + ")") , ("CollationKey(" + subt + ")"), result, revResult);
+ myCollator.setStrength(Collator.PRIMARY);
+ CollationKey1 = myCollator.getCollationKey(subs);
+ CollationKey2 = myCollator.getCollationKey(subt);
+ result = CollationKey1.compareTo(CollationKey2); // Primary
+ revResult = CollationKey2.compareTo(CollationKey1); // Primary
+ report(("CollationKey(" + subs + ")"), ("CollationKey(" + subt + ")"), result, revResult);
+ String addOne = subs + "\uE000";
+ CollationKey1 = myCollator.getCollationKey(subs);
+ CollationKey2 = myCollator.getCollationKey(addOne);
+ result = CollationKey1.compareTo(CollationKey2);
+ if (result != -1)
+ errln("CollationKey(" + subs + ")" + ".LT." + "CollationKey(" + addOne + ") Failed.");
+ result = CollationKey2.compareTo(CollationKey1);
+ if (result != 1)
+ errln("CollationKey(" + addOne + ")" + ".GT." + "CollationKey(" + subs + ") Failed.");
+ }
+ private static int checkValue(int value)
+ {
+ value *= (value > 0) ? 1 : -1;
+ return value;
+ }
+ public void TestCompare()
+ {
+ String source = "-abcdefghijklmnopqrstuvwxyz#&^$@";
+ Random r = new Random(3);
+ int s = checkValue(r.nextInt() % source.length());
+ int t = checkValue(r.nextInt() % source.length());
+ int slen = checkValue((r.nextInt() - source.length()) % source.length());
+ int tlen = checkValue((r.nextInt() - source.length()) % source.length());
+ String subs = source.substring((s > slen ? slen : s), (s >= slen ? s : slen));
+ String subt = source.substring((t > tlen ? tlen : t), (t >= tlen ? t : tlen));
+ myCollator.setStrength(Collator.TERTIARY);
+ int result = myCollator.compare(subs, subt); // Tertiary
+ int revResult = myCollator.compare(subt, subs); // Tertiary
+ report(subs, subt, result, revResult);
+ myCollator.setStrength(Collator.SECONDARY);
+ result = myCollator.compare(subs, subt); // Secondary
+ revResult = myCollator.compare(subt, subs); // Secondary
+ report(subs, subt, result, revResult);
+ myCollator.setStrength(Collator.PRIMARY);
+ result = myCollator.compare(subs, subt); // Primary
+ revResult = myCollator.compare(subt, subs); // Primary
+ report(subs, subt, result, revResult);
+ String addOne = subs + "\uE000";
+ result = myCollator.compare(subs, addOne);
+ if (result != -1)
+ errln("Test : " + subs + " .LT. " + addOne + " Failed.");
+ result = myCollator.compare(addOne, subs);
+ if (result != 1)
+ errln("Test : " + addOne + " .GE. " + subs + " Failed.");
+ }
+ private static Collator myCollator = Collator.getInstance();
+}
diff --git a/ojluni/src/test/java/text/Format/ChoiceFormat/Bug4387255.java b/ojluni/src/test/java/text/Format/ChoiceFormat/Bug4387255.java
new file mode 100644
index 00000000000..233d7b7616d
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/ChoiceFormat/Bug4387255.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4387255
+ * @summary Verifies that ChoiceFormat can handle large numbers of choices
+ */
+
+package test.java.text.Format.ChoiceFormat;
+
+import java.text.ChoiceFormat;
+
+public class Bug4387255 {
+
+ private static final double[] doubles = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35};
+
+ private static final String[] strings = {
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
+ "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
+ "U", "V", "W", "X", "Y", "Z"};
+
+ private static final String pattern =
+ "0#0|1#1|2#2|3#3|4#4|5#5|6#6|7#7|8#8|9#9" +
+ "|10#A|11#B|12#C|13#D|14#E|15#F|16#G|17#H|18#I|19#J" +
+ "|20#K|21#L|22#M|23#N|24#O|25#P|26#Q|27#R|28#S|29#T" +
+ "|30#U|31#V|32#W|33#X|34#Y|35#Z";
+
+ public static void main(String[] args) throws Exception {
+ ChoiceFormat choiceFormat1 = new ChoiceFormat(doubles, strings);
+ ChoiceFormat choiceFormat2 = new ChoiceFormat(pattern);
+ if (!choiceFormat1.equals(choiceFormat2)) {
+ System.out.println("choiceFormat1: " + choiceFormat1.toPattern());
+ System.out.println("choiceFormat2: " + choiceFormat2.toPattern());
+ throw new RuntimeException();
+ }
+
+ for (int i = 0; i < doubles.length; i++) {
+ String result = choiceFormat2.format(doubles[i]);
+ if (!result.equals(strings[i])) {
+ throw new RuntimeException("Wrong format result - expected " +
+ strings[i] + ", got " + result);
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/ChoiceFormat/Bug8001209.java b/ojluni/src/test/java/text/Format/ChoiceFormat/Bug8001209.java
new file mode 100644
index 00000000000..cb8a2879581
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/ChoiceFormat/Bug8001209.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8001209
+ * @summary Confirm that the values set by setChoices() are not mutable.
+ */
+package test.java.text.Format.ChoiceFormat;
+
+import java.text.*;
+
+public class Bug8001209 {
+
+ public static void main(String[] args) throws Exception {
+ boolean err = false;
+
+ // Borrow an example in API doc
+ double[] limits = {1,2,3,4,5,6,7};
+ String[] dayOfWeekNames = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+ ChoiceFormat form = new ChoiceFormat(limits, dayOfWeekNames);
+ ParsePosition status = new ParsePosition(0);
+
+ StringBuilder before = new StringBuilder();
+ for (double i = 1.0; i <= 7.0; ++i) {
+ status.setIndex(0);
+ String s = form.format(i);
+ before.append(" ");
+ before.append(s);
+ before.append(form.parse(form.format(i),status));
+ }
+ String original = before.toString();
+
+ double[] newLimits = form.getLimits();
+ String[] newFormats = (String[])form.getFormats();
+ newFormats[6] = "Doyoubi";
+ StringBuilder after = new StringBuilder();
+ for (double i = 1.0; i <= 7.0; ++i) {
+ status.setIndex(0);
+ String s = form.format(i);
+ after.append(" ");
+ after.append(s);
+ after.append(form.parse(form.format(i),status));
+ }
+ if (!original.equals(after.toString())) {
+ err = true;
+ System.err.println(" Expected:" + before
+ + "\n Got: " + after);
+ }
+
+ dayOfWeekNames[6] = "Saturday";
+ after = new StringBuilder();
+ for (double i = 1.0; i <= 7.0; ++i) {
+ status.setIndex(0);
+ String s = form.format(i);
+ after.append(" ");
+ after.append(s);
+ after.append(form.parse(form.format(i),status));
+ }
+ if (!original.equals(after.toString())) {
+ err = true;
+ System.err.println(" Expected:" + before
+ + "\n Got: " + after);
+ }
+
+ if (err) {
+ throw new RuntimeException("Failed.");
+ } else {
+ System.out.println("Passed.");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/DateFormat/SimpleDateFormatPatternTest.java b/ojluni/src/test/java/text/Format/DateFormat/SimpleDateFormatPatternTest.java
new file mode 100644
index 00000000000..8acac13d3f5
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/DateFormat/SimpleDateFormatPatternTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4326988 6990146 8231213
+ * @summary test SimpleDateFormat, check its pattern in the constructor
+ * @run testng/othervm SimpleDateFormatPatternTest
+ */
+package test.java.text.Format.DateFormat;
+
+import java.lang.IllegalArgumentException;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class SimpleDateFormatPatternTest {
+ private static String[] validPat = {
+ "yyyy-MM-dd h.mm.ss.a z",
+ "yyyy'M'd' ahh'mm'ss' z",
+ "dd MMMM yyyy hh:mm:ss",
+ "d MMM yy HH:mm:ss",
+ "dd/MM/yyyy HH:mm:ss",
+ "d' / 'MMMM' / 'yyyy HH:mm:ss z",
+ "d.M.yyyy H:mm:ss",
+ "d' de 'MMMM' de 'yyyy H'h'm'min's's' z",
+ "dd. MMMM yyyy HH:mm:ss z",
+ "d-M-yyyy H:mm:ss",
+ "EEEE''d MMMM G yyyy, H' 'm' 'ss' '",
+ "dd.MMM.yyyy HH:mm:ss",
+ "yy-MM-dd h:mm:ss.a",
+ "d' de 'MMMM' de 'yyyy hh:mm:ss a z",
+ "EEEE d MMMM yyyy H' h 'mm' min 'ss' s 'z",
+ "d MMMM yyyy H:mm:ss",
+ "d/MM/yyyy hh:mm:ss a",
+ "EEEE, d, MMMM yyyy HH:mm:ss z",
+ "EEEE, d. MMMM yyyy HH.mm.' h' z",
+ "EEEE, d' / 'MMMM' / 'yyyy HH:mm:ss z",
+ "d/MM/yyyy HH:mm:ss",
+ "d MMMM yyyy H:mm:ss z",
+ "MMMM d, yyyy h:mm:ss a z",
+ "yyyy. MMMM d. H:mm:ss z",
+ "d' de 'MMMM' de 'yyyy H:mm:ss z",
+ "EEEE, MMMM d, yyyy h:mm:ss a z",
+ "d/M/yyyy H:mm:ss",
+ "d-MMM-yy HH:mm:ss",
+ "EEEE d' de 'MMMM' de 'yyyy hh:mm:ss a z",
+ "yyyy'M'd' ahh'mm'ss'",
+ "yyyy'MM'dd' EEEE ahh'mm'ss'",
+ "EEEE, d MMMM yyyy HH:mm:ss z",
+
+ //6990146: 'Y' for year; 'X' for time zone; 'u' for day number of the week
+ "d/M/YYYY H:mm:ss",
+ "d-MMM-YY HH:mm:ss",
+ "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a X",
+ "YYYY M d ahh:mm:ss",
+ "YYYY MM dd EEEE u ahh/mm/ss",
+ "EEEE, u, d MMMM YYYY HH:mm:ss X",
+ "YYYY M d Z ahh mm ss",
+ "YYYY-MM-dd EEEE u ahh-mm-ss",
+
+ //*added for sr-Latn*
+ "EEEE, dd. MMMM y. HH.mm.ss zzzz",
+ "dd. MMMM y. HH.mm.ss z",
+ "dd.MM.y. HH.mm.ss",
+ "d.M.yy. HH.mm"
+ };
+
+ private static String[] invalidPat = {
+ "yyyy'M'd' ahh:mm:ss",
+ "EEEe d MM MM yyyy HH' h 'mm zzzZ",
+ "d MMMM\\ yyyy, H' 'm' 'g",
+ "EEEE d' @# MMMMde 'yyys HHH'mm z",
+ "yyyy'MMe 2 #dd' EEEEahh'mm'ss' z,z",
+ "yyyy.M.d H;mm.ses",
+ "EEEe, d MMMM yyyy h:mm:ss a z",
+ "EEEE, MMMM d, 'y y y y h:mm:ss 'o''clock' a z",
+ "dd MMMM yyyy 0HHcl:mm:ss z",
+ "d.M_M_y.yy1yy HextH:mm|45:",
+ "d,D MMMTTTTTTTTTKM yy|+yy HH:m m:ss z",
+ "d-MDtM M-yy H:mm:ss",
+ "yyyy/M///m/nM/d Dd H:m$m:s s",
+ "EEEE, dd. MMMM yyyy HH:m'''m' Uhr 'z",
+ //6990146
+ "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a x",
+ "EEEE, U, d MMMM YYYY HH:mm:ss Z"
+ };
+
+ private static Locale[] locales = DateFormat.getAvailableLocales();
+ private static Object[][] dfAllLocalesObj = createAllLocales();
+ private static Object[][] invalidPatObj = createPatternObj(invalidPat);
+ private static Object[][] validPatObj = createPatternObj(validPat);
+
+ private static Object[][] createAllLocales() {
+ Object[][] objArray = new Object[locales.length][];
+ for (int i = 0; i < locales.length; i++) {
+ objArray[i] = new Object[1];
+ objArray[i][0] = locales[i];
+ }
+ return objArray;
+ }
+
+ private static Object[][] createPatternObj(String[] pattern){
+ Object[][] objArray = new Object[locales.length * pattern.length][];
+ int k = 0;
+ for (int i = 0; i < locales.length; i++) {
+ for (int j = 0; j < pattern.length; j++) {
+ objArray[k] = new Object[2];
+ objArray[k][0] = pattern[j];
+ objArray[k][1] = locales[i];
+ k = k + 1;
+ }
+ }
+ return objArray;
+ }
+
+ @DataProvider(name = "dfAllLocalesObj")
+ Object[][] dfAllLocalesObj() {
+ return dfAllLocalesObj;
+ }
+
+ @DataProvider(name = "invalidPatternObj")
+ Object[][] invalidPatternObj() {
+ return invalidPatObj;
+ }
+
+ @DataProvider(name = "validPatternObj")
+ Object[][] validPatternObj() {
+ return validPatObj;
+ }
+
+ //check Constructors for invalid pattern
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException1(String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern);
+ }
+
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException2(String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern, new DateFormatSymbols());
+ }
+
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException3 (String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern, Locale.getDefault());
+ }
+
+ @Test(dataProvider = "invalidPatternObj",
+ expectedExceptions = IllegalArgumentException.class)
+ public void testIllegalArgumentException4(String pattern, Locale loc)
+ throws IllegalArgumentException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat().applyPattern(pattern);
+ }
+
+ //check Constructors for null pattern
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException1(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(null);
+ }
+
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException2(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(null, new DateFormatSymbols());
+ }
+
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException3(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(null, Locale.getDefault());
+ }
+
+ @Test(dataProvider = "dfAllLocalesObj",
+ expectedExceptions = NullPointerException.class)
+ public void testNullPointerException4(Locale loc)
+ throws NullPointerException {
+ Locale.setDefault(loc);
+ new SimpleDateFormat().applyPattern(null);
+ }
+
+ @Test(dataProvider = "validPatternObj")
+ //check Constructors for valid pattern
+ public void testValidPattern(String pattern, Locale loc) {
+ Locale.setDefault(loc);
+ new SimpleDateFormat(pattern);
+ new SimpleDateFormat(pattern, new DateFormatSymbols());
+ new SimpleDateFormat(pattern, Locale.getDefault());
+ new SimpleDateFormat().applyPattern(pattern);
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/DecimalFormat/Bug8165466.java b/ojluni/src/test/java/text/Format/DecimalFormat/Bug8165466.java
new file mode 100644
index 00000000000..073b88cc62c
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/DecimalFormat/Bug8165466.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8165466
+ * @summary Checks the subsequent function calls of the DecimalFormat.format()
+ * method in which the minimumFractionDigit is set to 0 and one of
+ * the format() call include formatting of the number with zero
+ * fraction value e.g. 0.00, 9.00
+ */
+
+package test.java.text.Format.DecimalFormat;
+
+import java.text.DecimalFormat;
+import java.util.Locale;
+
+public class Bug8165466 {
+
+ public static void main(String[] args) {
+ DecimalFormat nf = (DecimalFormat) DecimalFormat
+ .getPercentInstance(Locale.US);
+ nf.setMaximumFractionDigits(3);
+ nf.setMinimumFractionDigits(0);
+ nf.setMultiplier(1);
+
+ double d = 0.005678;
+ String result = nf.format(d);
+ if (!result.equals("0.006%")) {
+ throw new RuntimeException("[Failed while formatting the double"
+ + " value: " + d + " Expected: 0.006%, Found: " + result
+ + "]");
+ }
+
+ d = 0.00;
+ result = nf.format(d);
+ if (!result.equals("0%")) {
+ throw new RuntimeException("[Failed while formatting the double"
+ + " value: " + d + " Expected: 0%, Found: " + result
+ + "]");
+ }
+
+ d = 0.005678;
+ result = nf.format(d);
+ if (!result.equals("0.006%")) {
+ throw new RuntimeException("[Failed while formatting the double"
+ + " value: " + d + " Expected: 0.006%, Found: " + result
+ + "]");
+ }
+
+ //checking with the non zero value
+ d = 0.005678;
+ result = nf.format(d);
+ if (!result.equals("0.006%")) {
+ throw new RuntimeException("[Failed while formatting the double"
+ + " value: " + d + " Expected: 0.006%, Found: " + result
+ + "]");
+ }
+
+ d = 9.00;
+ result = nf.format(d);
+ if (!result.equals("9%")) {
+ throw new RuntimeException("[Failed while formatting the double"
+ + " value: " + d + " Expected: 9%, Found: " + result
+ + "]");
+ }
+
+ d = 0.005678;
+ result = nf.format(d);
+ if (!result.equals("0.006%")) {
+ throw new RuntimeException("[Failed while formatting the double"
+ + " value: " + d + " Expected: 0.006%, Found: " + result
+ + "]");
+ }
+ }
+
+}
+
diff --git a/ojluni/src/test/java/text/Format/DecimalFormat/GoldenFormattedValues.java b/ojluni/src/test/java/text/Format/DecimalFormat/GoldenFormattedValues.java
new file mode 100644
index 00000000000..5690819cfbe
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/DecimalFormat/GoldenFormattedValues.java
@@ -0,0 +1,870 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.text.Format.DecimalFormat;
+
+/* This is a machine generated file - Please DO NOT EDIT !
+ * Change RoundingAndPropertyTest instead,
+ * and run with "-gengold" argument to regenerate (without copyright header).
+ */
+
+/* This file contains the set of result Strings expected from calling inside
+ * RoundingAndPropertyTest the method NumberFormat.format() upon the set of
+ * double values provided in GoldenDoubleValues.java. It contains three arrays,
+ * each containing arrays of unicode values representing the expected string
+ * result when calling format() on the corresponding (i.e. same index) double
+ * value found in GoldenDoubleValues arrays :
+ * - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,
+ * when using FullLocalizationTestLocale to format.
+ * - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used
+ * in the decimal pattern case together with TestLocale.
+ * - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used
+ * in the currency pattern case together with TestLocale.
+ * Please see documentation in RoundingAndPropertyTest.java for more details.
+ *
+ * This file generated by running RoundingAndPropertyTest with "-gengold" argument.
+ */
+
+class GoldenFormattedValues {
+
+ // The formatted values below were generated from golden values
+ // listed in GoldenDoubleValues.java, using the following jvm version :
+ // Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 1.9.0-internal-fastdebug
+ // locale for golden double values : en_US
+ // locale for testing digit localization : hi_IN
+
+ // The array of int[] unicode values storing the expected results
+ // when experiencing full localization of digits on DecimalLocalizationValues.
+ static int[][] DecimalDigitsLocalizedFormattedValues = {
+ { 49, 46, 49, 50, 51 },
+ { 49, 50, 46, 49, 50, 51 },
+ { 49, 50, 51, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52, 46, 49, 50, 51 },
+ { 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
+ { 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
+ { 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
+ { 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52 },
+ { 49, 44, 50, 51, 52, 46, 57 },
+ { 49, 44, 50, 51, 52, 46, 57, 57 },
+ { 49, 44, 50, 51, 52, 46, 57, 57, 57 },
+ };
+
+ // The array of int[] unicode values storing the expected results
+ // when calling Decimal.format(double) on the decimal GoldenDoubleValues.
+ static int[][] DecimalGoldenFormattedValues = {
+ { 48 },
+ { 45, 48 },
+ { 48 },
+ { 48 },
+ { 45, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 51 },
+ { 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51, 52 },
+ { 45, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56 },
+ { 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56 },
+ { 45, 49, 44, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 78, 97, 78 },
+ { 8734 },
+ { 45, 8734 },
+ { 49, 55, 57, 44, 55, 54, 57, 44, 51, 49, 51, 44, 52, 56, 54, 44, 50, 51, 49, 44, 53, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 56, 56 },
+ { 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 56, 56 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 46, 49, 50, 51 },
+ { 49, 50, 46, 49, 50, 51 },
+ { 49, 50, 51, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52, 46, 49, 50, 51 },
+ { 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
+ { 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
+ { 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
+ { 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
+ { 45, 49, 46, 49, 50, 51 },
+ { 45, 49, 50, 46, 49, 50, 51 },
+ { 45, 49, 50, 51, 46, 49, 50, 51 },
+ { 45, 49, 44, 50, 51, 52, 46, 49, 50, 51 },
+ { 45, 49, 50, 44, 51, 52, 53, 46, 49, 50, 51 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50, 51 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50, 51 },
+ { 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50, 51 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50, 51 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50, 51 },
+ { 48, 46, 49 },
+ { 48, 46, 49, 50 },
+ { 48, 46, 49, 50, 51 },
+ { 48, 46, 49, 50, 51 },
+ { 49, 48, 46, 49 },
+ { 49, 48, 46, 49, 50 },
+ { 49, 48, 46, 49, 50, 51 },
+ { 49, 48, 46, 49, 50, 51 },
+ { 49, 48, 48, 46, 49 },
+ { 49, 48, 48, 46, 49, 50 },
+ { 49, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 48, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 48, 46, 49 },
+ { 49, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 44, 48, 48, 48, 46, 49 },
+ { 49, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 48, 46, 49 },
+ { 45, 48, 46, 49, 50 },
+ { 45, 48, 46, 49, 50, 51 },
+ { 45, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 46, 49 },
+ { 45, 49, 48, 46, 49, 50 },
+ { 45, 49, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 48, 46, 49 },
+ { 45, 49, 48, 48, 46, 49, 50 },
+ { 45, 49, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50, 51 },
+ { 49, 46, 57, 57, 57 },
+ { 49, 50, 46, 57, 57, 57 },
+ { 49, 50, 51, 46, 57, 57, 57 },
+ { 49, 44, 50, 51, 52, 46, 57, 57, 57 },
+ { 49, 50, 44, 51, 52, 53, 46, 57, 57, 57 },
+ { 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 57 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 57 },
+ { 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 57 },
+ { 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 57 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 57 },
+ { 50 },
+ { 49, 51 },
+ { 49, 50, 52 },
+ { 49, 44, 50, 51, 53 },
+ { 49, 50, 44, 51, 52, 54 },
+ { 49, 50, 51, 44, 52, 53, 55 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 56 },
+ { 49, 50, 44, 51, 52, 53, 44, 54, 55, 57 },
+ { 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49 },
+ { 45, 49, 46, 57, 57, 57 },
+ { 45, 49, 50, 46, 57, 57, 57 },
+ { 45, 49, 50, 51, 46, 57, 57, 57 },
+ { 45, 49, 44, 50, 51, 52, 46, 57, 57, 57 },
+ { 45, 49, 50, 44, 51, 52, 53, 46, 57, 57, 57 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57, 57 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57, 57 },
+ { 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57, 57 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57, 57 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57, 57 },
+ { 45, 50 },
+ { 45, 49, 51 },
+ { 45, 49, 50, 52 },
+ { 45, 49, 44, 50, 51, 53 },
+ { 45, 49, 50, 44, 51, 52, 54 },
+ { 45, 49, 50, 51, 44, 52, 53, 55 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 56 },
+ { 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49 },
+ { 49, 49, 48 },
+ { 49, 44, 49, 48, 48 },
+ { 49, 49, 44, 48, 48, 48 },
+ { 49, 49, 48, 44, 48, 48, 48 },
+ { 49, 44, 49, 48, 48, 44, 48, 48, 48 },
+ { 49, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 49, 48 },
+ { 45, 49, 44, 49, 48, 48 },
+ { 45, 49, 49, 44, 48, 48, 48 },
+ { 45, 49, 49, 48, 44, 48, 48, 48 },
+ { 45, 49, 44, 49, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 50 },
+ { 50, 48 },
+ { 50, 48, 48 },
+ { 50, 44, 48, 48, 48 },
+ { 50, 48, 44, 48, 48, 48 },
+ { 50, 48, 48, 44, 48, 48, 48 },
+ { 50, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 50, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 50 },
+ { 45, 50, 48 },
+ { 45, 50, 48, 48 },
+ { 45, 50, 44, 48, 48, 48 },
+ { 45, 50, 48, 44, 48, 48, 48 },
+ { 45, 50, 48, 48, 44, 48, 48, 48 },
+ { 45, 50, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 48 },
+ { 49, 48, 48 },
+ { 49, 44, 48, 48, 48 },
+ { 49, 48, 44, 48, 48, 48 },
+ { 49, 48, 48, 44, 48, 48, 48 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 57, 46, 57, 57, 57 },
+ { 57, 57, 46, 57, 57, 57 },
+ { 57, 57, 57, 46, 57, 57, 57 },
+ { 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 49, 48 },
+ { 45, 49, 48, 48 },
+ { 45, 49, 44, 48, 48, 48 },
+ { 45, 49, 48, 44, 48, 48, 48 },
+ { 45, 49, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48 },
+ { 45, 57, 46, 57, 57, 57 },
+ { 45, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 45, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 49 },
+ { 49, 50 },
+ { 49, 50, 51 },
+ { 49, 44, 50, 51, 52 },
+ { 49, 50, 44, 51, 52, 53 },
+ { 49, 50, 51, 44, 52, 53, 54 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55 },
+ { 49, 50, 44, 51, 52, 53, 44, 54, 55, 56 },
+ { 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57 },
+ { 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48 },
+ { 45, 49 },
+ { 45, 49, 50 },
+ { 45, 49, 50, 51 },
+ { 45, 49, 44, 50, 51, 52 },
+ { 45, 49, 50, 44, 51, 52, 53 },
+ { 45, 49, 50, 51, 44, 52, 53, 54 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55 },
+ { 45, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56 },
+ { 45, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57 },
+ { 45, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48 },
+ { 45, 50, 44, 53, 57, 57, 46, 52 },
+ { 45, 50, 44, 53, 57, 57, 46, 51, 52 },
+ { 45, 50, 44, 53, 57, 57, 46, 51, 51, 52 },
+ { 49 },
+ { 49 },
+ { 49 },
+ { 49 },
+ { 49 },
+ { 49, 46, 48, 48, 49 },
+ { 49, 46, 48, 48, 49 },
+ { 49, 46, 48, 48, 49 },
+ { 49, 46, 48, 48, 49 },
+ { 49, 46, 48, 48, 49 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 50 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 46, 50, 50, 51 },
+ { 49, 48, 48, 44, 57, 49, 51, 46, 54, 55, 49 },
+ { 49, 57, 57, 44, 57, 57, 57, 46, 57, 57, 57 },
+ { 50, 53, 49, 44, 56, 52, 54, 46, 51, 52, 55 },
+ { 50, 53, 51, 44, 50, 52, 51, 46, 56, 56, 51 },
+ { 51, 54, 53, 44, 48, 52, 53, 46, 56, 53, 51 },
+ { 51, 49, 52, 44, 55, 51, 52, 46, 57, 54, 49 },
+ { 53, 52, 49, 44, 49, 51, 51, 46, 57, 55, 53 },
+ { 56, 53, 56, 44, 51, 55, 50, 46, 49, 50, 51 },
+ { 49, 44, 48, 48, 49, 44, 48, 48, 48 },
+ { 49, 44, 51, 52, 55, 44, 53, 48, 53, 46, 55, 56, 50 },
+ { 51, 44, 51, 53, 56, 44, 56, 52, 52, 46, 49, 57, 55 },
+ { 57, 44, 57, 57, 55, 44, 57, 55, 57, 46, 52, 48, 57 },
+ { 57, 44, 57, 57, 51, 44, 55, 52, 51, 46, 49, 53, 57 },
+ { 57, 44, 57, 51, 56, 44, 54, 55, 49, 46, 57, 48, 57 },
+ { 51, 44, 51, 56, 53, 44, 51, 48, 50, 46, 53, 52, 55 },
+ { 51, 44, 52, 48, 52, 44, 54, 52, 50, 46, 54, 54, 49 },
+ { 51, 44, 52, 51, 49, 44, 50, 56, 48, 46, 48, 56, 55 },
+ { 51, 44, 52, 51, 56, 44, 55, 53, 54, 46, 52, 55, 53 },
+ { 51, 44, 52, 52, 54, 44, 48, 53, 51, 46, 55, 56, 55 },
+ { 51, 44, 52, 53, 55, 44, 57, 49, 55, 46, 53, 49, 51 },
+ { 51, 44, 52, 54, 53, 44, 51, 57, 51, 46, 57, 48, 49 },
+ { 51, 44, 52, 56, 52, 44, 55, 51, 52, 46, 48, 49, 53 },
+ { 51, 44, 52, 57, 50, 44, 48, 51, 49, 46, 51, 50, 55 },
+ { 51, 44, 53, 48, 51, 44, 56, 57, 53, 46, 48, 53, 51 },
+ { 51, 44, 53, 49, 49, 44, 51, 55, 49, 46, 52, 52, 49 },
+ { 51, 44, 53, 49, 56, 44, 54, 54, 56, 46, 55, 53, 51 },
+ { 51, 44, 53, 51, 48, 44, 53, 51, 50, 46, 52, 55, 57 },
+ { 51, 44, 53, 51, 56, 44, 48, 48, 56, 46, 56, 54, 55 },
+ { 51, 44, 53, 52, 53, 44, 51, 48, 54, 46, 49, 55, 57 },
+ { 51, 44, 53, 53, 55, 44, 49, 54, 57, 46, 57, 48, 53 },
+ { 51, 44, 53, 53, 55, 44, 51, 52, 56, 46, 57, 56, 49 },
+ { 51, 44, 53, 54, 52, 44, 54, 52, 54, 46, 50, 57, 51 },
+ { 51, 44, 53, 56, 51, 44, 57, 56, 54, 46, 52, 48, 55 },
+ { 51, 44, 53, 57, 49, 44, 50, 56, 51, 46, 55, 49, 57 },
+ { 51, 44, 54, 48, 51, 44, 49, 52, 55, 46, 52, 52, 53 },
+ { 51, 44, 54, 49, 48, 44, 54, 50, 51, 46, 56, 51, 51 },
+ { 51, 44, 54, 49, 55, 44, 57, 50, 49, 46, 49, 52, 53 },
+ { 51, 44, 54, 50, 57, 44, 55, 56, 52, 46, 56, 55, 49 },
+ { 51, 44, 54, 51, 55, 44, 50, 54, 49, 46, 50, 53, 57 },
+ { 51, 44, 54, 53, 54, 44, 52, 50, 50, 46, 50, 57, 55 },
+ { 51, 44, 54, 53, 54, 44, 54, 48, 49, 46, 51, 55, 51 },
+ { 51, 44, 54, 54, 51, 44, 56, 57, 56, 46, 54, 56, 53 },
+ { 51, 44, 54, 55, 53, 44, 55, 54, 50, 46, 52, 49, 49 },
+ { 51, 44, 54, 56, 51, 44, 50, 51, 56, 46, 55, 57, 57 },
+ { 51, 44, 54, 57, 48, 44, 53, 51, 54, 46, 49, 49, 49 },
+ { 51, 44, 55, 48, 50, 44, 51, 57, 57, 46, 56, 51, 55 },
+ { 51, 44, 55, 48, 57, 44, 56, 55, 54, 46, 50, 50, 53 },
+ { 51, 44, 55, 49, 55, 44, 49, 55, 51, 46, 53, 51, 55 },
+ { 51, 44, 55, 50, 57, 44, 48, 51, 55, 46, 50, 54, 51 },
+ { 51, 44, 55, 51, 54, 44, 53, 49, 51, 46, 54, 53, 49 },
+ { 51, 44, 55, 53, 53, 44, 56, 53, 51, 46, 55, 54, 53 },
+ { 51, 44, 55, 54, 51, 44, 49, 53, 49, 46, 48, 55, 55 },
+ { 51, 44, 55, 55, 53, 44, 48, 49, 52, 46, 56, 48, 51 },
+ { 51, 44, 55, 56, 50, 44, 52, 57, 49, 46, 49, 57, 49 },
+ { 51, 44, 55, 56, 57, 44, 55, 56, 56, 46, 53, 48, 51 },
+ { 51, 44, 56, 48, 49, 44, 54, 53, 50, 46, 50, 50, 57 },
+ { 51, 44, 56, 48, 57, 44, 49, 50, 56, 46, 54, 49, 55 },
+ { 51, 44, 56, 49, 54, 44, 52, 50, 53, 46, 57, 50, 57 },
+ { 51, 44, 56, 50, 56, 44, 50, 56, 57, 46, 54, 53, 53 },
+ { 51, 44, 56, 50, 56, 44, 52, 54, 56, 46, 55, 51, 49 },
+ { 51, 44, 56, 51, 53, 44, 55, 54, 54, 46, 48, 52, 51 },
+ { 51, 44, 56, 53, 53, 44, 49, 48, 54, 46, 49, 53, 55 },
+ { 51, 44, 56, 54, 50, 44, 52, 48, 51, 46, 52, 54, 57 },
+ { 51, 44, 56, 55, 52, 44, 50, 54, 55, 46, 49, 57, 53 },
+ { 51, 44, 56, 56, 49, 44, 55, 52, 51, 46, 53, 56, 51 },
+ { 51, 44, 56, 56, 57, 44, 48, 52, 48, 46, 56, 57, 53 },
+ { 51, 44, 57, 48, 48, 44, 57, 48, 52, 46, 54, 50, 49 },
+ { 51, 44, 57, 48, 56, 44, 51, 56, 49, 46, 48, 48, 57 },
+ { 51, 44, 57, 50, 55, 44, 53, 52, 50, 46, 48, 52, 55 },
+ { 51, 44, 57, 50, 55, 44, 55, 50, 49, 46, 49, 50, 51 },
+ { 51, 44, 57, 51, 53, 44, 48, 49, 56, 46, 52, 51, 53 },
+ { 51, 44, 57, 52, 54, 44, 56, 56, 50, 46, 49, 54, 49 },
+ { 51, 44, 57, 53, 52, 44, 51, 53, 56, 46, 53, 52, 57 },
+ { 51, 44, 57, 54, 49, 44, 54, 53, 53, 46, 56, 54, 49 },
+ { 51, 44, 57, 55, 51, 44, 53, 49, 57, 46, 53, 56, 55 },
+ { 51, 44, 57, 56, 48, 44, 57, 57, 53, 46, 57, 55, 53 },
+ { 51, 44, 57, 56, 56, 44, 50, 57, 51, 46, 50, 56, 55 },
+ { 52, 44, 48, 48, 48, 44, 49, 53, 55, 46, 48, 49, 51 },
+ { 52, 44, 48, 48, 55, 44, 54, 51, 51, 46, 52, 48, 49 },
+ { 52, 44, 48, 50, 54, 44, 57, 55, 51, 46, 53, 49, 53 },
+ { 52, 44, 48, 51, 52, 44, 50, 55, 48, 46, 56, 50, 55 },
+ { 52, 44, 48, 52, 54, 44, 49, 51, 52, 46, 53, 53, 51 },
+ { 52, 44, 48, 53, 51, 44, 54, 49, 48, 46, 57, 52, 49 },
+ { 52, 44, 48, 54, 48, 44, 57, 48, 56, 46, 50, 53, 51 },
+ { 52, 44, 48, 55, 50, 44, 55, 55, 49, 46, 57, 55, 57 },
+ { 52, 44, 48, 56, 48, 44, 50, 52, 56, 46, 51, 54, 55 },
+ { 52, 44, 48, 56, 55, 44, 53, 52, 53, 46, 54, 55, 57 },
+ { 52, 44, 48, 57, 57, 44, 52, 48, 57, 46, 52, 48, 53 },
+ { 52, 44, 48, 57, 57, 44, 53, 56, 56, 46, 52, 56, 49 },
+ { 52, 44, 49, 48, 54, 44, 56, 56, 53, 46, 55, 57, 51 },
+ { 52, 44, 49, 50, 54, 44, 50, 50, 53, 46, 57, 48, 55 },
+ { 52, 44, 49, 51, 51, 44, 53, 50, 51, 46, 50, 49, 57 },
+ { 52, 44, 49, 52, 53, 44, 51, 56, 54, 46, 57, 52, 53 },
+ { 52, 44, 49, 53, 50, 44, 56, 54, 51, 46, 51, 51, 51 },
+ { 52, 44, 49, 54, 48, 44, 49, 54, 48, 46, 54, 52, 53 },
+ { 52, 44, 49, 55, 50, 44, 48, 50, 52, 46, 51, 55, 49 },
+ { 52, 44, 49, 55, 57, 44, 53, 48, 48, 46, 55, 53, 57 },
+ { 52, 44, 49, 57, 56, 44, 54, 54, 49, 46, 55, 57, 55 },
+ { 52, 44, 50, 48, 51, 44, 52, 48, 55, 46, 50, 56, 55 },
+ { 52, 44, 50, 49, 48, 44, 55, 48, 52, 46, 53, 57, 57 },
+ { 52, 44, 50, 49, 51, 44, 52, 51, 53, 46, 52, 57, 55 },
+ };
+
+ // The array of int[] unicode values storing the expected results
+ // when calling Decimal.format(double) on the currency GoldenDoubleValues.
+ static int[][] CurrencyGoldenFormattedValues = {
+ { 36, 48, 46, 48, 48 },
+ { 45, 36, 48, 46, 48, 48 },
+ { 36, 48, 46, 48, 48 },
+ { 36, 48, 46, 48, 48 },
+ { 45, 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51 },
+ { 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 54, 46, 50, 51 },
+ { 45, 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56, 46, 48, 48 },
+ { 36, 50, 44, 49, 52, 55, 44, 52, 56, 51, 44, 54, 52, 56, 46, 48, 48 },
+ { 45, 36, 49, 44, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 78, 97, 78 },
+ { 36, 8734 },
+ { 45, 36, 8734 },
+ { 36, 49, 55, 57, 44, 55, 54, 57, 44, 51, 49, 51, 44, 52, 56, 54, 44, 50, 51, 49, 44, 53, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 57 },
+ { 36, 57, 44, 56, 55, 54, 44, 53, 52, 51, 44, 50, 49, 48, 46, 57, 57 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 44, 48, 49, 50, 44, 51, 52, 53, 44, 54, 55, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 46, 49, 50 },
+ { 36, 49, 50, 46, 49, 50 },
+ { 36, 49, 50, 51, 46, 49, 50 },
+ { 36, 49, 44, 50, 51, 52, 46, 49, 50 },
+ { 36, 49, 50, 44, 51, 52, 53, 46, 49, 50 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50 },
+ { 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50 },
+ { 45, 36, 49, 46, 49, 50 },
+ { 45, 36, 49, 50, 46, 49, 50 },
+ { 45, 36, 49, 50, 51, 46, 49, 50 },
+ { 45, 36, 49, 44, 50, 51, 52, 46, 49, 50 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 46, 49, 50 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 46, 49, 50 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 49, 50 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 49, 50 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 49, 50 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 49, 50 },
+ { 36, 48, 46, 49, 48 },
+ { 36, 48, 46, 49, 50 },
+ { 36, 48, 46, 49, 50 },
+ { 36, 49, 48, 46, 49, 48 },
+ { 36, 49, 48, 46, 49, 50 },
+ { 36, 49, 48, 46, 49, 50 },
+ { 36, 49, 48, 48, 46, 49, 48 },
+ { 36, 49, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 48, 46, 49, 50 },
+ { 36, 49, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 48, 46, 49, 48 },
+ { 45, 36, 48, 46, 49, 50 },
+ { 45, 36, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 46, 49, 48 },
+ { 45, 36, 49, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 48 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 49, 50 },
+ { 36, 49, 46, 57, 57 },
+ { 36, 49, 50, 46, 57, 57 },
+ { 36, 49, 50, 51, 46, 57, 57 },
+ { 36, 49, 44, 50, 51, 52, 46, 57, 57 },
+ { 36, 49, 50, 44, 51, 52, 53, 46, 57, 57 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57 },
+ { 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57 },
+ { 36, 50, 46, 48, 48 },
+ { 36, 49, 51, 46, 48, 48 },
+ { 36, 49, 50, 52, 46, 48, 48 },
+ { 36, 49, 44, 50, 51, 53, 46, 48, 48 },
+ { 36, 49, 50, 44, 51, 52, 54, 46, 48, 48 },
+ { 36, 49, 50, 51, 44, 52, 53, 55, 46, 48, 48 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 56, 46, 48, 48 },
+ { 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57, 46, 48, 48 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48, 46, 48, 48 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49, 46, 48, 48 },
+ { 45, 36, 49, 46, 57, 57 },
+ { 45, 36, 49, 50, 46, 57, 57 },
+ { 45, 36, 49, 50, 51, 46, 57, 57 },
+ { 45, 36, 49, 44, 50, 51, 52, 46, 57, 57 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 46, 57, 57 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 46, 57, 57 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 57, 57 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 57, 57 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 57, 57 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 57, 57 },
+ { 45, 36, 50, 46, 48, 48 },
+ { 45, 36, 49, 51, 46, 48, 48 },
+ { 45, 36, 49, 50, 52, 46, 48, 48 },
+ { 45, 36, 49, 44, 50, 51, 53, 46, 48, 48 },
+ { 45, 36, 49, 50, 44, 51, 52, 54, 46, 48, 48 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 55, 46, 48, 48 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 56, 46, 48, 48 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 57, 46, 48, 48 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 57, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 49, 46, 48, 48 },
+ { 36, 49, 49, 48, 46, 48, 48 },
+ { 36, 49, 44, 49, 48, 48, 46, 48, 48 },
+ { 36, 49, 49, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 49, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 49, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 49, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 46, 48, 48 },
+ { 36, 50, 48, 46, 48, 48 },
+ { 36, 50, 48, 48, 46, 48, 48 },
+ { 36, 50, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 46, 48, 48 },
+ { 45, 36, 50, 48, 46, 48, 48 },
+ { 45, 36, 50, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 50, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 48, 46, 48, 48 },
+ { 36, 49, 48, 48, 46, 48, 48 },
+ { 36, 49, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 36, 57, 46, 57, 57 },
+ { 36, 57, 57, 46, 57, 57 },
+ { 36, 57, 57, 57, 46, 57, 57 },
+ { 36, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 49, 48, 46, 48, 48 },
+ { 45, 36, 49, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 49, 44, 48, 48, 48, 44, 48, 48, 48, 44, 48, 48, 48, 46, 48, 48 },
+ { 45, 36, 57, 46, 57, 57 },
+ { 45, 36, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 45, 36, 57, 57, 57, 44, 57, 57, 57, 44, 57, 57, 57, 46, 57, 57 },
+ { 36, 49, 46, 48, 48 },
+ { 36, 49, 50, 46, 48, 48 },
+ { 36, 49, 50, 51, 46, 48, 48 },
+ { 36, 49, 44, 50, 51, 52, 46, 48, 48 },
+ { 36, 49, 50, 44, 51, 52, 53, 46, 48, 48 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 46, 48, 48 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 48, 48 },
+ { 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 48, 48 },
+ { 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 48, 48 },
+ { 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 48, 48 },
+ { 45, 36, 49, 46, 48, 48 },
+ { 45, 36, 49, 50, 46, 48, 48 },
+ { 45, 36, 49, 50, 51, 46, 48, 48 },
+ { 45, 36, 49, 44, 50, 51, 52, 46, 48, 48 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 46, 48, 48 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 46, 48, 48 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 46, 48, 48 },
+ { 45, 36, 49, 50, 44, 51, 52, 53, 44, 54, 55, 56, 46, 48, 48 },
+ { 45, 36, 49, 50, 51, 44, 52, 53, 54, 44, 55, 56, 57, 46, 48, 48 },
+ { 45, 36, 49, 44, 50, 51, 52, 44, 53, 54, 55, 44, 56, 57, 48, 46, 48, 48 },
+ { 45, 36, 50, 44, 53, 57, 57, 46, 52, 48 },
+ { 45, 36, 50, 44, 53, 57, 57, 46, 51, 52 },
+ { 45, 36, 50, 44, 53, 57, 57, 46, 51, 51 },
+ { 36, 49, 46, 48, 48 },
+ { 36, 49, 46, 48, 48 },
+ { 36, 49, 46, 48, 48 },
+ { 36, 49, 46, 48, 48 },
+ { 36, 49, 46, 48, 48 },
+ { 36, 49, 46, 48, 49 },
+ { 36, 49, 46, 48, 49 },
+ { 36, 49, 46, 48, 49 },
+ { 36, 49, 46, 48, 49 },
+ { 36, 49, 46, 48, 49 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 50 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 46, 50, 51 },
+ { 36, 49, 44, 48, 48, 57, 44, 49, 51, 54, 46, 55, 49 },
+ { 36, 50, 44, 53, 49, 56, 44, 52, 54, 51, 46, 52, 54 },
+ { 36, 50, 44, 53, 51, 50, 44, 52, 51, 56, 46, 56, 51 },
+ { 36, 51, 44, 54, 53, 48, 44, 52, 53, 56, 46, 53, 51 },
+ { 36, 51, 44, 49, 52, 55, 44, 51, 52, 57, 46, 54, 50 },
+ { 36, 53, 44, 52, 49, 49, 44, 51, 51, 57, 46, 55, 53 },
+ { 36, 56, 44, 53, 56, 51, 44, 55, 50, 49, 46, 50, 50 },
+ { 36, 49, 51, 44, 52, 55, 53, 44, 48, 53, 55, 46, 56, 50 },
+ { 36, 51, 51, 44, 53, 56, 56, 44, 52, 52, 49, 46, 57, 56 },
+ { 36, 57, 57, 44, 57, 55, 57, 44, 55, 57, 52, 46, 48, 56 },
+ { 36, 57, 57, 44, 57, 51, 55, 44, 52, 51, 49, 46, 53, 56 },
+ { 36, 57, 57, 44, 51, 56, 54, 44, 55, 49, 57, 46, 48, 56 },
+ { 36, 51, 51, 44, 56, 53, 51, 44, 48, 50, 53, 46, 52, 55 },
+ { 36, 51, 52, 44, 48, 52, 54, 44, 52, 50, 54, 46, 54, 48 },
+ { 36, 51, 52, 44, 51, 49, 50, 44, 56, 48, 48, 46, 56, 55 },
+ { 36, 51, 52, 44, 51, 56, 55, 44, 53, 54, 52, 46, 55, 53 },
+ { 36, 51, 52, 44, 52, 54, 48, 44, 53, 51, 55, 46, 56, 55 },
+ { 36, 51, 52, 44, 53, 55, 57, 44, 49, 55, 53, 46, 49, 50 },
+ { 36, 51, 52, 44, 54, 53, 51, 44, 57, 51, 57, 46, 48, 50 },
+ { 36, 51, 52, 44, 56, 52, 55, 44, 51, 52, 48, 46, 49, 53 },
+ { 36, 51, 52, 44, 57, 50, 48, 44, 51, 49, 51, 46, 50, 55 },
+ { 36, 51, 53, 44, 48, 51, 56, 44, 57, 53, 48, 46, 53, 50 },
+ { 36, 51, 53, 44, 49, 49, 51, 44, 55, 49, 52, 46, 52, 49 },
+ { 36, 51, 53, 44, 49, 56, 54, 44, 54, 56, 55, 46, 53, 51 },
+ { 36, 51, 53, 44, 51, 48, 53, 44, 51, 50, 52, 46, 55, 56 },
+ { 36, 51, 53, 44, 51, 56, 48, 44, 48, 56, 56, 46, 54, 55 },
+ { 36, 51, 53, 44, 52, 53, 51, 44, 48, 54, 49, 46, 55, 57 },
+ { 36, 51, 53, 44, 53, 55, 49, 44, 54, 57, 57, 46, 48, 53 },
+ { 36, 51, 53, 44, 53, 55, 51, 44, 52, 56, 57, 46, 56, 49 },
+ { 36, 51, 53, 44, 54, 52, 54, 44, 52, 54, 50, 46, 57, 51 },
+ { 36, 51, 53, 44, 56, 51, 57, 44, 56, 54, 52, 46, 48, 55 },
+ { 36, 51, 53, 44, 57, 49, 50, 44, 56, 51, 55, 46, 50, 48 },
+ { 36, 51, 54, 44, 48, 51, 49, 44, 52, 55, 52, 46, 52, 53 },
+ { 36, 51, 54, 44, 49, 48, 54, 44, 50, 51, 56, 46, 51, 51 },
+ { 36, 51, 54, 44, 49, 55, 57, 44, 50, 49, 49, 46, 52, 53 },
+ { 36, 51, 54, 44, 50, 57, 55, 44, 56, 52, 56, 46, 55, 48 },
+ { 36, 51, 54, 44, 51, 55, 50, 44, 54, 49, 50, 46, 53, 57 },
+ { 36, 51, 54, 44, 53, 54, 52, 44, 50, 50, 50, 46, 57, 55 },
+ { 36, 51, 54, 44, 53, 54, 54, 44, 48, 49, 51, 46, 55, 51 },
+ { 36, 51, 54, 44, 54, 51, 56, 44, 57, 56, 54, 46, 56, 53 },
+ { 36, 51, 54, 44, 55, 53, 55, 44, 54, 50, 52, 46, 49, 48 },
+ { 36, 51, 54, 44, 56, 51, 50, 44, 51, 56, 55, 46, 57, 57 },
+ { 36, 51, 54, 44, 57, 48, 53, 44, 51, 54, 49, 46, 49, 49 },
+ { 36, 51, 55, 44, 48, 50, 51, 44, 57, 57, 56, 46, 51, 55 },
+ { 36, 51, 55, 44, 48, 57, 56, 44, 55, 54, 50, 46, 50, 53 },
+ { 36, 51, 55, 44, 49, 55, 49, 44, 55, 51, 53, 46, 51, 55 },
+ { 36, 51, 55, 44, 50, 57, 48, 44, 51, 55, 50, 46, 54, 50 },
+ { 36, 51, 55, 44, 51, 54, 53, 44, 49, 51, 54, 46, 53, 50 },
+ { 36, 51, 55, 44, 53, 53, 56, 44, 53, 51, 55, 46, 54, 53 },
+ { 36, 51, 55, 44, 54, 51, 49, 44, 53, 49, 48, 46, 55, 55 },
+ { 36, 51, 55, 44, 55, 53, 48, 44, 49, 52, 56, 46, 48, 50 },
+ { 36, 51, 55, 44, 56, 50, 52, 44, 57, 49, 49, 46, 57, 49 },
+ { 36, 51, 55, 44, 56, 57, 55, 44, 56, 56, 53, 46, 48, 51 },
+ { 36, 51, 56, 44, 48, 49, 54, 44, 53, 50, 50, 46, 50, 56 },
+ { 36, 51, 56, 44, 48, 57, 49, 44, 50, 56, 54, 46, 49, 55 },
+ { 36, 51, 56, 44, 49, 54, 52, 44, 50, 53, 57, 46, 50, 57 },
+ { 36, 51, 56, 44, 50, 56, 50, 44, 56, 57, 54, 46, 53, 53 },
+ { 36, 51, 56, 44, 50, 56, 52, 44, 54, 56, 55, 46, 51, 49 },
+ { 36, 51, 56, 44, 51, 53, 55, 44, 54, 54, 48, 46, 52, 51 },
+ { 36, 51, 56, 44, 53, 53, 49, 44, 48, 54, 49, 46, 53, 55 },
+ { 36, 51, 56, 44, 54, 50, 52, 44, 48, 51, 52, 46, 55, 48 },
+ { 36, 51, 56, 44, 55, 52, 50, 44, 54, 55, 49, 46, 57, 53 },
+ { 36, 51, 56, 44, 56, 49, 55, 44, 52, 51, 53, 46, 56, 51 },
+ { 36, 51, 56, 44, 56, 57, 48, 44, 52, 48, 56, 46, 57, 53 },
+ { 36, 51, 57, 44, 48, 48, 57, 44, 48, 52, 54, 46, 50, 48 },
+ { 36, 51, 57, 44, 48, 56, 51, 44, 56, 49, 48, 46, 48, 57 },
+ { 36, 51, 57, 44, 50, 55, 53, 44, 52, 50, 48, 46, 52, 55 },
+ { 36, 51, 57, 44, 50, 55, 55, 44, 50, 49, 49, 46, 50, 51 },
+ { 36, 51, 57, 44, 51, 53, 48, 44, 49, 56, 52, 46, 51, 53 },
+ { 36, 51, 57, 44, 52, 54, 56, 44, 56, 50, 49, 46, 54, 48 },
+ { 36, 51, 57, 44, 53, 52, 51, 44, 53, 56, 53, 46, 52, 57 },
+ { 36, 51, 57, 44, 54, 49, 54, 44, 53, 53, 56, 46, 54, 49 },
+ { 36, 51, 57, 44, 55, 51, 53, 44, 49, 57, 53, 46, 56, 55 },
+ { 36, 51, 57, 44, 56, 48, 57, 44, 57, 53, 57, 46, 55, 53 },
+ { 36, 51, 57, 44, 56, 56, 50, 44, 57, 51, 50, 46, 56, 55 },
+ { 36, 52, 48, 44, 48, 48, 49, 44, 53, 55, 48, 46, 49, 50 },
+ { 36, 52, 48, 44, 48, 55, 54, 44, 51, 51, 52, 46, 48, 50 },
+ { 36, 52, 48, 44, 50, 54, 57, 44, 55, 51, 53, 46, 49, 53 },
+ { 36, 52, 48, 44, 51, 52, 50, 44, 55, 48, 56, 46, 50, 55 },
+ { 36, 52, 48, 44, 52, 54, 49, 44, 51, 52, 53, 46, 53, 50 },
+ { 36, 52, 48, 44, 53, 51, 54, 44, 49, 48, 57, 46, 52, 49 },
+ { 36, 52, 48, 44, 54, 48, 57, 44, 48, 56, 50, 46, 53, 51 },
+ { 36, 52, 48, 44, 55, 50, 55, 44, 55, 49, 57, 46, 55, 56 },
+ { 36, 52, 48, 44, 56, 48, 50, 44, 52, 56, 51, 46, 54, 55 },
+ { 36, 52, 48, 44, 56, 55, 53, 44, 52, 53, 54, 46, 55, 57 },
+ { 36, 52, 48, 44, 57, 57, 52, 44, 48, 57, 52, 46, 48, 53 },
+ { 36, 52, 48, 44, 57, 57, 53, 44, 56, 56, 52, 46, 56, 49 },
+ { 36, 52, 49, 44, 48, 54, 56, 44, 56, 53, 55, 46, 57, 51 },
+ { 36, 52, 49, 44, 50, 54, 50, 44, 50, 53, 57, 46, 48, 55 },
+ { 36, 52, 49, 44, 51, 51, 53, 44, 50, 51, 50, 46, 50, 48 },
+ { 36, 52, 49, 44, 52, 53, 51, 44, 56, 54, 57, 46, 52, 53 },
+ { 36, 52, 49, 44, 53, 50, 56, 44, 54, 51, 51, 46, 51, 51 },
+ { 36, 52, 49, 44, 54, 48, 49, 44, 54, 48, 54, 46, 52, 53 },
+ { 36, 52, 49, 44, 55, 50, 48, 44, 50, 52, 51, 46, 55, 48 },
+ { 36, 52, 49, 44, 55, 57, 53, 44, 48, 48, 55, 46, 53, 57 },
+ { 36, 52, 49, 44, 57, 56, 54, 44, 54, 49, 55, 46, 57, 55 },
+ { 36, 52, 50, 44, 48, 51, 52, 44, 48, 55, 50, 46, 56, 55 },
+ { 36, 52, 50, 44, 49, 48, 55, 44, 48, 52, 53, 46, 57, 56 },
+ { 36, 52, 50, 44, 49, 51, 52, 44, 51, 53, 52, 46, 57, 56 },
+ };
+
+}
diff --git a/ojluni/src/test/java/text/Format/DecimalFormat/SetGroupingSizeTest.java b/ojluni/src/test/java/text/Format/DecimalFormat/SetGroupingSizeTest.java
new file mode 100644
index 00000000000..a28c00bc276
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/DecimalFormat/SetGroupingSizeTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8212749
+ * @summary test whether input value check for
+ * DecimalFormat.setGroupingSize(int) works correctly.
+ * @run testng/othervm SetGroupingSizeTest
+ */
+
+package test.java.text.Format.DecimalFormat;
+
+import java.text.DecimalFormat;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class SetGroupingSizeTest {
+
+ @DataProvider
+ public static Object[][] validGroupingSizes() {
+ return new Object[][] {
+ { 0 },
+ { Byte.MAX_VALUE },
+ };
+ }
+
+ @DataProvider
+ public static Object[][] invalidGroupingSizes() {
+ return new Object[][] {
+ { Byte.MIN_VALUE - 1 },
+ { Byte.MIN_VALUE },
+ { -1 },
+ { Byte.MAX_VALUE + 1 },
+ { Integer.MIN_VALUE },
+ { Integer.MAX_VALUE },
+ };
+ }
+
+ @Test(dataProvider = "validGroupingSizes")
+ public void test_validGroupingSize(int newVal) {
+ DecimalFormat df = new DecimalFormat();
+ df.setGroupingSize(newVal);
+ assertEquals(df.getGroupingSize(), newVal);
+ }
+
+ @Test(dataProvider = "invalidGroupingSizes",
+ expectedExceptions = IllegalArgumentException.class)
+ public void test_invalidGroupingSize(int newVal) {
+ DecimalFormat df = new DecimalFormat();
+ df.setGroupingSize(newVal);
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/MessageFormat/Bug6481179.java b/ojluni/src/test/java/text/Format/MessageFormat/Bug6481179.java
new file mode 100644
index 00000000000..aab78f1b88b
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/MessageFormat/Bug6481179.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Confirm that a bug in an error message has been fixed.
+ * @bug 6481179
+ */
+
+package test.java.text.Format.MessageFormat;
+
+import java.text.MessageFormat;
+import java.text.ParseException;
+
+public class Bug6481179 {
+
+ public static void main(String[] args) {
+ boolean err = false;
+
+ try {
+ MessageFormat.format("Testdata {1,invalid_format_type}",
+ new Object[] { "val0", "val1" });
+
+ System.err.println("Error: IllegalArgumentException should be thrown.");
+ err = true;
+ }
+ catch (IllegalArgumentException e) {
+ String expected = "unknown format type: invalid_format_type";
+ String got = e.getMessage();
+
+ if (!expected.equals(got)) {
+ System.err.println("Error: Unexpected error message: " + got);
+ err = true;
+ }
+ }
+ catch (Exception e) {
+ System.err.println("Error: Unexpected exception was thrown: " + e);
+ err = true;
+ }
+
+ if (err) {
+ throw new RuntimeException("Failed.");
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/text/Format/MessageFormat/Bug7003643.java b/ojluni/src/test/java/text/Format/MessageFormat/Bug7003643.java
new file mode 100644
index 00000000000..57abba42d64
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/MessageFormat/Bug7003643.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7003643
+ * @summary Make sure MessageFormat.toPattern produces correct quoting. (SPI part is tested in PluggableLocale tests.)
+ * @key randomness
+ */
+
+package test.java.text.Format.MessageFormat;
+
+import java.text.*;
+import java.util.*;
+
+public class Bug7003643 {
+ private static final int N = 5;
+
+ private static final String[] elements = {
+ "'{'", "'{", "{", "''", "}", "a", "'",
+ };
+
+ public static void main(String[] args) {
+ Random rand = new Random();
+ int count = 0;
+ int max = (int) (Math.pow((double)elements.length, (double)N)/0.52);
+ while (count < max) {
+ // Create a random pattern. If the produced pattern is
+ // valid, then proceed with the round-trip testing.
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < N; i++) {
+ sb.append(elements[rand.nextInt(elements.length)]);
+ }
+ String pattern = sb.toString();
+ MessageFormat mf = null;
+ try {
+ mf = new MessageFormat(pattern);
+ } catch (IllegalArgumentException e) {
+ // bad pattern data
+ }
+ if (mf == null) {
+ continue;
+ }
+ count++;
+ String res1 = MessageFormat.format(pattern, 123);
+ String toPattern = mf.toPattern();
+ String res2 = MessageFormat.format(toPattern, 123);
+ if (!res1.equals(res2)) {
+ String s = String.format("Failed%n pattern=\"%s\" => result=\"%s\"%n"
+ + " toPattern()=\"%s\" => result=\"%s\"%n",
+ pattern, res1, toPattern, res2);
+ throw new RuntimeException(s);
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/MessageFormat/MessageFormatsByArgumentIndex.java b/ojluni/src/test/java/text/Format/MessageFormat/MessageFormatsByArgumentIndex.java
new file mode 100644
index 00000000000..3084266da23
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/MessageFormat/MessageFormatsByArgumentIndex.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4105380
+ * @summary basic tests for new methods getFormatsByArgumentIndex, setFormatByArgumentIndex, setFormatsByArgumentIndex
+ */
+
+package test.java.text.Format.MessageFormat;
+
+import java.text.ChoiceFormat;
+import java.text.Format;
+import java.text.MessageFormat;
+import java.text.NumberFormat;
+
+public class MessageFormatsByArgumentIndex {
+
+ private static String choicePattern = "0.0#are no files|1.0#is one file|1.0<are {0,number,integer} files";
+
+ public static void main(String[] args) {
+ Format[] subformats;
+
+ MessageFormat format = new MessageFormat("{3, choice," + choicePattern + "}, {2}, {0}");
+
+ subformats = format.getFormatsByArgumentIndex();
+ checkSubformatLength(subformats, 4);
+ checkSubformat(subformats, 0, null);
+ checkSubformat(subformats, 1, null);
+ checkSubformat(subformats, 2, null);
+ checkSubformat(subformats, 3, new ChoiceFormat(choicePattern));
+
+ subformats = format.getFormats();
+ checkSubformatLength(subformats, 3);
+ checkSubformat(subformats, 0, new ChoiceFormat(choicePattern));
+ checkSubformat(subformats, 1, null);
+ checkSubformat(subformats, 2, null);
+
+ format.setFormatByArgumentIndex(0, NumberFormat.getInstance());
+
+ checkPattern(format.toPattern(), "{3,choice," + choicePattern + "}, {2}, {0,number}");
+
+ subformats = format.getFormatsByArgumentIndex();
+ checkSubformatLength(subformats, 4);
+ checkSubformat(subformats, 0, NumberFormat.getInstance());
+ checkSubformat(subformats, 1, null);
+ checkSubformat(subformats, 2, null);
+ checkSubformat(subformats, 3, new ChoiceFormat(choicePattern));
+
+ subformats = format.getFormats();
+ checkSubformatLength(subformats, 3);
+ checkSubformat(subformats, 0, new ChoiceFormat(choicePattern));
+ checkSubformat(subformats, 1, null);
+ checkSubformat(subformats, 2, NumberFormat.getInstance());
+
+ format.setFormatsByArgumentIndex(subformats);
+
+ checkPattern(format.toPattern(), "{3,choice," + choicePattern + "}, {2,number}, {0,choice," + choicePattern + "}");
+
+ subformats = format.getFormatsByArgumentIndex();
+ checkSubformatLength(subformats, 4);
+ checkSubformat(subformats, 0, new ChoiceFormat(choicePattern));
+ checkSubformat(subformats, 1, null);
+ checkSubformat(subformats, 2, NumberFormat.getInstance());
+ checkSubformat(subformats, 3, new ChoiceFormat(choicePattern));
+
+ subformats = format.getFormats();
+ checkSubformatLength(subformats, 3);
+ checkSubformat(subformats, 0, new ChoiceFormat(choicePattern));
+ checkSubformat(subformats, 1, NumberFormat.getInstance());
+ checkSubformat(subformats, 2, new ChoiceFormat(choicePattern));
+
+ }
+
+ private static void checkPattern(String actual, String expected) {
+ if (!expected.equals(actual)) {
+ throw new RuntimeException("unexpected pattern:\n expected: " + expected + "\n actual: " + actual);
+ }
+ }
+
+ private static void checkSubformatLength(Format[] subformats, int expected) {
+ if (subformats.length != expected) {
+ throw new RuntimeException("unexpected subformat length:\n expected: " + expected + "\n actual: " + subformats.length);
+ }
+ }
+
+ private static void checkSubformat(Format[] subformats, int index, Format expected) {
+ Format subformat = subformats[index];
+ if (subformat == expected) {
+ return;
+ }
+ if ((subformat != null) && subformat.equals(expected)) {
+ return;
+ }
+ throw new RuntimeException("found unexpected subformat for argument " + index + ":\n expected: " + expected + "\n actual: " + subformat);
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/MessageFormat/MessageRegression.java b/ojluni/src/test/java/text/Format/MessageFormat/MessageRegression.java
new file mode 100644
index 00000000000..cd019152dc3
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/MessageFormat/MessageRegression.java
@@ -0,0 +1,690 @@
+/*
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4031438 4058973 4074764 4094906 4104976 4105380 4106659 4106660 4106661
+ * 4111739 4112104 4113018 4114739 4114743 4116444 4118592 4118594 4120552
+ * 4142938 4169959 4232154 4293229 8187551
+ * @summary Regression tests for MessageFormat and associated classes
+ * @library /java/text/testlib
+ * @run main MessageRegression
+ */
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+package test.java.text.Format.MessageFormat;
+
+import java.text.*;
+import java.util.*;
+import java.io.IOException;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+import test.java.text.testlib.IntlTest;
+import test.java.text.testlib.TestUtils;
+
+public class MessageRegression extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new MessageRegression().run(args);
+ }
+
+ /* @bug 4074764
+ * Null exception when formatting pattern with MessageFormat
+ * with no parameters.
+ */
+ public void Test4074764() {
+ String[] pattern = {"Message without param",
+ "Message with param:{0}",
+ "Longer Message with param {0}"};
+ //difference between the two param strings are that
+ //in the first one, the param position is within the
+ //length of the string without param while it is not so
+ //in the other case.
+
+ MessageFormat messageFormatter = new MessageFormat("");
+
+ try {
+ //Apply pattern with param and print the result
+ messageFormatter.applyPattern(pattern[1]);
+ Object[] params = {new String("BUG"), new Date()};
+ String tempBuffer = messageFormatter.format(params);
+ if (!tempBuffer.equals("Message with param:BUG"))
+ errln("MessageFormat with one param test failed.");
+ logln("Formatted with one extra param : " + tempBuffer);
+
+ //Apply pattern without param and print the result
+ messageFormatter.applyPattern(pattern[0]);
+ tempBuffer = messageFormatter.format(null);
+ if (!tempBuffer.equals("Message without param"))
+ errln("MessageFormat with no param test failed.");
+ logln("Formatted with no params : " + tempBuffer);
+
+ tempBuffer = messageFormatter.format(params);
+ if (!tempBuffer.equals("Message without param"))
+ errln("Formatted with arguments > subsitution failed. result = " + tempBuffer.toString());
+ logln("Formatted with extra params : " + tempBuffer);
+ //This statement gives an exception while formatting...
+ //If we use pattern[1] for the message with param,
+ //we get an NullPointerException in MessageFormat.java(617)
+ //If we use pattern[2] for the message with param,
+ //we get an StringArrayIndexOutOfBoundsException in MessageFormat.java(614)
+ //Both are due to maxOffset not being reset to -1
+ //in applyPattern() when the pattern does not
+ //contain any param.
+ } catch (Exception foo) {
+ errln("Exception when formatting with no params.");
+ }
+ }
+
+ /* @bug 4058973
+ * MessageFormat.toPattern has weird rounding behavior.
+ */
+ public void Test4058973() {
+
+ MessageFormat fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}");
+ String pat = fmt.toPattern();
+ if (!pat.equals("{0,choice,0.0#no files|1.0#one file|1.0< {0,number,integer} files}")) {
+ errln("MessageFormat.toPattern failed");
+ }
+ }
+ /* @bug 4031438
+ * More robust message formats.
+ */
+ public void Test4031438() {
+ Locale locale = Locale.getDefault();
+ if (!TestUtils.usesAsciiDigits(locale)) {
+ logln("Skipping this test because locale is " + locale);
+ return;
+ }
+
+ String pattern1 = "Impossible {1} has occurred -- status code is {0} and message is {2}.";
+ String pattern2 = "Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'.";
+
+ MessageFormat messageFormatter = new MessageFormat("");
+
+ try {
+ logln("Apply with pattern : " + pattern1);
+ messageFormatter.applyPattern(pattern1);
+ Object[] params = {7};
+ String tempBuffer = messageFormatter.format(params);
+ if (!tempBuffer.equals("Impossible {1} has occurred -- status code is 7 and message is {2}."))
+ errln("Tests arguments < substitution failed. Formatted text=" +
+ "<" + tempBuffer + ">");
+ logln("Formatted with 7 : " + tempBuffer);
+ ParsePosition status = new ParsePosition(0);
+ Object[] objs = messageFormatter.parse(tempBuffer, status);
+ if (objs[params.length] != null)
+ errln("Parse failed with more than expected arguments");
+ for (int i = 0; i < objs.length; i++) {
+ if (objs[i] != null && !objs[i].toString().equals(params[i].toString())) {
+ errln("Parse failed on object " + objs[i] + " at index : " + i);
+ }
+ }
+ tempBuffer = messageFormatter.format(null);
+ if (!tempBuffer.equals("Impossible {1} has occurred -- status code is {0} and message is {2}."))
+ errln("Tests with no arguments failed");
+ logln("Formatted with null : " + tempBuffer);
+ logln("Apply with pattern : " + pattern2);
+ messageFormatter.applyPattern(pattern2);
+ tempBuffer = messageFormatter.format(params);
+ if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {1} test plus other {2} stuff."))
+ errln("quote format test (w/ params) failed.");
+ logln("Formatted with params : " + tempBuffer);
+ tempBuffer = messageFormatter.format(null);
+ if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff."))
+ errln("quote format test (w/ null) failed.");
+ logln("Formatted with null : " + tempBuffer);
+ logln("toPattern : " + messageFormatter.toPattern());
+ } catch (Exception foo) {
+ errln("Exception when formatting in bug 4031438. "+foo.getMessage());
+ }
+ }
+ public void Test4052223()
+ {
+ ParsePosition pos = new ParsePosition(0);
+ if (pos.getErrorIndex() != -1) {
+ errln("ParsePosition.getErrorIndex initialization failed.");
+ }
+ MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree.");
+ String str = new String("There is one apple growing on the peach tree.");
+ Object[] objs = fmt.parse(str, pos);
+ logln("unparsable string , should fail at " + pos.getErrorIndex());
+ if (pos.getErrorIndex() == -1)
+ errln("Bug 4052223 failed : parsing string " + str);
+ pos.setErrorIndex(4);
+ if (pos.getErrorIndex() != 4)
+ errln("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4");
+ ChoiceFormat f = new ChoiceFormat(
+ "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2.");
+ pos.setIndex(0); pos.setErrorIndex(-1);
+ Number obj = f.parse("are negative", pos);
+ if (pos.getErrorIndex() != -1 && obj.doubleValue() == -1.0)
+ errln("Parse with \"are negative\" failed, at " + pos.getErrorIndex());
+ pos.setIndex(0); pos.setErrorIndex(-1);
+ obj = f.parse("are no or fraction ", pos);
+ if (pos.getErrorIndex() != -1 && obj.doubleValue() == 0.0)
+ errln("Parse with \"are no or fraction\" failed, at " + pos.getErrorIndex());
+ pos.setIndex(0); pos.setErrorIndex(-1);
+ obj = f.parse("go postal", pos);
+ if (pos.getErrorIndex() == -1 && !Double.isNaN(obj.doubleValue()))
+ errln("Parse with \"go postal\" failed, at " + pos.getErrorIndex());
+ }
+ /* @bug 4104976
+ * ChoiceFormat.equals(null) throws NullPointerException
+ */
+ public void Test4104976()
+ {
+ double[] limits = {1, 20};
+ String[] formats = {"xyz", "abc"};
+ ChoiceFormat cf = new ChoiceFormat(limits, formats);
+ try {
+ log("Compares to null is always false, returned : ");
+ logln(cf.equals(null) ? "TRUE" : "FALSE");
+ } catch (Exception foo) {
+ errln("ChoiceFormat.equals(null) throws exception.");
+ }
+ }
+ /* @bug 4106659
+ * ChoiceFormat.ctor(double[], String[]) doesn't check
+ * whether lengths of input arrays are equal.
+ */
+ public void Test4106659()
+ {
+ double[] limits = {1, 2, 3};
+ String[] formats = {"one", "two"};
+ ChoiceFormat cf = null;
+ try {
+ cf = new ChoiceFormat(limits, formats);
+ } catch (Exception foo) {
+ logln("ChoiceFormat constructor should check for the array lengths");
+ cf = null;
+ }
+ if (cf != null) errln(cf.format(5));
+ }
+
+ /* @bug 4106660
+ * ChoiceFormat.ctor(double[], String[]) allows unordered double array.
+ * This is not a bug, added javadoc to emphasize the use of limit
+ * array must be in ascending order.
+ */
+ public void Test4106660()
+ {
+ double[] limits = {3, 1, 2};
+ String[] formats = {"Three", "One", "Two"};
+ ChoiceFormat cf = new ChoiceFormat(limits, formats);
+ double d = 5.0;
+ String str = cf.format(d);
+ if (!str.equals("Two"))
+ errln("format(" + d + ") = " + cf.format(d));
+ }
+
+ /* @bug 4111739
+ * MessageFormat is incorrectly serialized/deserialized.
+ */
+ public void Test4111739()
+ {
+ MessageFormat format1 = null;
+ MessageFormat format2 = null;
+ ObjectOutputStream ostream = null;
+ ByteArrayOutputStream baos = null;
+ ObjectInputStream istream = null;
+
+ try {
+ baos = new ByteArrayOutputStream();
+ ostream = new ObjectOutputStream(baos);
+ } catch(IOException e) {
+ errln("Unexpected exception : " + e.getMessage());
+ return;
+ }
+
+ try {
+ format1 = new MessageFormat("pattern{0}");
+ ostream.writeObject(format1);
+ ostream.flush();
+
+ byte bytes[] = baos.toByteArray();
+
+ istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
+ format2 = (MessageFormat)istream.readObject();
+ } catch(Exception e) {
+ errln("Unexpected exception : " + e.getMessage());
+ }
+
+ if (!format1.equals(format2)) {
+ errln("MessageFormats before and after serialization are not" +
+ " equal\nformat1 = " + format1 + "(" + format1.toPattern() + ")\nformat2 = " +
+ format2 + "(" + format2.toPattern() + ")");
+ } else {
+ logln("Serialization for MessageFormat is OK.");
+ }
+ }
+ /* @bug 4114743
+ * MessageFormat.applyPattern allows illegal patterns.
+ */
+ public void Test4114743()
+ {
+ String originalPattern = "initial pattern";
+ MessageFormat mf = new MessageFormat(originalPattern);
+ try {
+ String illegalPattern = "ab { '}' de";
+ mf.applyPattern(illegalPattern);
+ errln("illegal pattern: \"" + illegalPattern + "\"");
+ } catch (IllegalArgumentException foo) {
+ if (!originalPattern.equals(mf.toPattern()))
+ errln("pattern after: \"" + mf.toPattern() + "\"");
+ }
+ }
+
+ /* @bug 4116444
+ * MessageFormat.parse has different behavior in case of null.
+ */
+ public void Test4116444()
+ {
+ String[] patterns = {"", "one", "{0,date,short}"};
+ MessageFormat mf = new MessageFormat("");
+
+ for (int i = 0; i < patterns.length; i++) {
+ String pattern = patterns[i];
+ mf.applyPattern(pattern);
+ try {
+ Object[] array = mf.parse(null, new ParsePosition(0));
+ logln("pattern: \"" + pattern + "\"");
+ log(" parsedObjects: ");
+ if (array != null) {
+ log("{");
+ for (int j = 0; j < array.length; j++) {
+ if (array[j] != null)
+ err("\"" + array[j].toString() + "\"");
+ else
+ log("null");
+ if (j < array.length - 1) log(",");
+ }
+ log("}") ;
+ } else {
+ log("null");
+ }
+ logln("");
+ } catch (Exception e) {
+ errln("pattern: \"" + pattern + "\"");
+ errln(" Exception: " + e.getMessage());
+ }
+ }
+
+ }
+ /* @bug 4114739 (FIX and add javadoc)
+ * MessageFormat.format has undocumented behavior about empty format objects.
+ */
+ public void Test4114739()
+ {
+
+ MessageFormat mf = new MessageFormat("<{0}>");
+ Object[] objs1 = null;
+ Object[] objs2 = {};
+ Object[] objs3 = {null};
+ try {
+ logln("pattern: \"" + mf.toPattern() + "\"");
+ log("format(null) : ");
+ logln("\"" + mf.format(objs1) + "\"");
+ log("format({}) : ");
+ logln("\"" + mf.format(objs2) + "\"");
+ log("format({null}) :");
+ logln("\"" + mf.format(objs3) + "\"");
+ } catch (Exception e) {
+ errln("Exception thrown for null argument tests.");
+ }
+ }
+
+ /* @bug 4113018
+ * MessageFormat.applyPattern works wrong with illegal patterns.
+ */
+ public void Test4113018()
+ {
+ String originalPattern = "initial pattern";
+ MessageFormat mf = new MessageFormat(originalPattern);
+ String illegalPattern = "format: {0, xxxYYY}";
+ logln("pattern before: \"" + mf.toPattern() + "\"");
+ logln("illegal pattern: \"" + illegalPattern + "\"");
+ try {
+ mf.applyPattern(illegalPattern);
+ errln("Should have thrown IllegalArgumentException for pattern : " + illegalPattern);
+ } catch (IllegalArgumentException e) {
+ if (!originalPattern.equals(mf.toPattern()))
+ errln("pattern after: \"" + mf.toPattern() + "\"");
+ }
+ }
+ /* @bug 4106661
+ * ChoiceFormat is silent about the pattern usage in javadoc.
+ */
+ public void Test4106661()
+ {
+ ChoiceFormat fmt = new ChoiceFormat(
+ "-1#are negative| 0#are no or fraction | 1#is one |1.0<is 1+ |2#are two |2<are more than 2.");
+ logln("Formatter Pattern : " + fmt.toPattern());
+
+ logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
+ logln("Format with -1.0 : " + fmt.format(-1.0));
+ logln("Format with 0 : " + fmt.format(0));
+ logln("Format with 0.9 : " + fmt.format(0.9));
+ logln("Format with 1.0 : " + fmt.format(1));
+ logln("Format with 1.5 : " + fmt.format(1.5));
+ logln("Format with 2 : " + fmt.format(2));
+ logln("Format with 2.1 : " + fmt.format(2.1));
+ logln("Format with NaN : " + fmt.format(Double.NaN));
+ logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
+ }
+ /* @bug 4094906
+ * ChoiceFormat should accept \u221E as eq. to INF.
+ */
+ public void Test4094906()
+ {
+ ChoiceFormat fmt = new ChoiceFormat(
+ "-\u221E<are negative|0<are no or fraction|1#is one|1.0<is 1+|\u221E<are many.");
+ if (!fmt.toPattern().startsWith("-\u221E<are negative|0.0<are no or fraction|1.0#is one|1.0<is 1+|\u221E<are many."))
+ errln("Formatter Pattern : " + fmt.toPattern());
+ logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY));
+ logln("Format with -1.0 : " + fmt.format(-1.0));
+ logln("Format with 0 : " + fmt.format(0));
+ logln("Format with 0.9 : " + fmt.format(0.9));
+ logln("Format with 1.0 : " + fmt.format(1));
+ logln("Format with 1.5 : " + fmt.format(1.5));
+ logln("Format with 2 : " + fmt.format(2));
+ logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY));
+ }
+
+ /* @bug 4118592
+ * MessageFormat.parse fails with ChoiceFormat.
+ */
+ public void Test4118592()
+ {
+ MessageFormat mf = new MessageFormat("");
+ String pattern = "{0,choice,1#YES|2#NO}";
+ String prefix = "";
+ for (int i = 0; i < 5; i++) {
+ String formatted = prefix + "YES";
+ mf.applyPattern(prefix + pattern);
+ prefix += "x";
+ Object[] objs = mf.parse(formatted, new ParsePosition(0));
+ logln(i + ". pattern :\"" + mf.toPattern() + "\"");
+ log(" \"" + formatted + "\" parsed as ");
+ if (objs == null) logln(" null");
+ else logln(" " + objs[0]);
+ }
+ }
+ /* @bug 4118594
+ * MessageFormat.parse fails for some patterns.
+ */
+ public void Test4118594()
+ {
+ MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
+ String forParsing = "x, y, z";
+ Object[] objs = mf.parse(forParsing, new ParsePosition(0));
+ logln("pattern: \"" + mf.toPattern() + "\"");
+ logln("text for parsing: \"" + forParsing + "\"");
+ if (!objs[0].toString().equals("z"))
+ errln("argument0: \"" + objs[0] + "\"");
+ mf.setLocale(Locale.US);
+ mf.applyPattern("{0,number,#.##}, {0,number,#.#}");
+ Object[] oldobjs = {3.1415};
+ String result = mf.format( oldobjs );
+ logln("pattern: \"" + mf.toPattern() + "\"");
+ logln("text for parsing: \"" + result + "\"");
+ // result now equals "3.14, 3.1"
+ if (!result.equals("3.14, 3.1"))
+ errln("result = " + result);
+ Object[] newobjs = mf.parse(result, new ParsePosition(0));
+ // newobjs now equals {new Double(3.1)}
+ if (((Double)newobjs[0]).doubleValue() != 3.1)
+ errln( "newobjs[0] = " + newobjs[0]);
+ }
+ /* @bug 4105380
+ * When using ChoiceFormat, MessageFormat is not good for I18n.
+ */
+ public void Test4105380()
+ {
+ String patternText1 = "The disk \"{1}\" contains {0}.";
+ String patternText2 = "There are {0} on the disk \"{1}\"";
+ MessageFormat form1 = new MessageFormat(patternText1);
+ MessageFormat form2 = new MessageFormat(patternText2);
+ double[] filelimits = {0,1,2};
+ String[] filepart = {"no files","one file","{0,number} files"};
+ ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
+ form1.setFormat(1, fileform);
+ form2.setFormat(0, fileform);
+ Object[] testArgs = {12373L, "MyDisk"};
+ logln(form1.format(testArgs));
+ logln(form2.format(testArgs));
+ }
+ /* @bug 4120552
+ * MessageFormat.parse incorrectly sets errorIndex.
+ */
+ public void Test4120552()
+ {
+ MessageFormat mf = new MessageFormat("pattern");
+ String texts[] = {"pattern", "pat", "1234"};
+ logln("pattern: \"" + mf.toPattern() + "\"");
+ for (int i = 0; i < texts.length; i++) {
+ ParsePosition pp = new ParsePosition(0);
+ Object[] objs = mf.parse(texts[i], pp);
+ log(" text for parsing: \"" + texts[i] + "\"");
+ if (objs == null) {
+ logln(" (incorrectly formatted string)");
+ if (pp.getErrorIndex() == -1)
+ errln("Incorrect error index: " + pp.getErrorIndex());
+ } else {
+ logln(" (correctly formatted string)");
+ }
+ }
+ }
+
+ /**
+ * @bug 4142938
+ * MessageFormat handles single quotes in pattern wrong.
+ * This is actually a problem in ChoiceFormat; it doesn't
+ * understand single quotes.
+ */
+ public void Test4142938() {
+ String pat = "''Vous'' {0,choice,0#n''|1#}avez s\u00E9lectionne\u00E9 " +
+ "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} " +
+ "personnel{0,choice,0#s|1#|2#s}.";
+ MessageFormat mf = new MessageFormat(pat);
+
+ String[] PREFIX = {
+ "'Vous' n'avez s\u00E9lectionne\u00E9 aucun clients personnels.",
+ "'Vous' avez s\u00E9lectionne\u00E9 ",
+ "'Vous' avez s\u00E9lectionne\u00E9 "
+ };
+ String[] SUFFIX = {
+ null,
+ " client personnel.",
+ " clients personnels."
+ };
+
+ for (int i=0; i<3; i++) {
+ String out = mf.format(new Object[]{i});
+ if (SUFFIX[i] == null) {
+ if (!out.equals(PREFIX[i]))
+ errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"");
+ }
+ else {
+ if (!out.startsWith(PREFIX[i]) ||
+ !out.endsWith(SUFFIX[i]))
+ errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" +
+ SUFFIX[i] + "\"");
+ }
+ }
+ }
+
+ /**
+ * @bug 4142938
+ * Test the applyPattern and toPattern handling of single quotes
+ * by ChoiceFormat. (This is in here because this was a bug reported
+ * against MessageFormat.) The single quote is used to quote the
+ * pattern characters '|', '#', '<', and '\u2264'. Two quotes in a row
+ * is a quote literal.
+ */
+ public void TestChoicePatternQuote() {
+ String[] DATA = {
+ // Pattern 0 value 1 value
+ "0#can''t|1#can", "can't", "can",
+ "0#'pound(#)=''#'''|1#xyz", "pound(#)='#'", "xyz",
+ "0#'1<2 | 1\u22641'|1#''", "1<2 | 1\u22641", "'",
+ };
+ for (int i=0; i<DATA.length; i+=3) {
+ try {
+ ChoiceFormat cf = new ChoiceFormat(DATA[i]);
+ for (int j=0; j<=1; ++j) {
+ String out = cf.format(j);
+ if (!out.equals(DATA[i+1+j]))
+ errln("Fail: Pattern \"" + DATA[i] + "\" x "+j+" -> " +
+ out + "; want \"" + DATA[i+1+j] + '"');
+ }
+ String pat = cf.toPattern();
+ String pat2 = new ChoiceFormat(pat).toPattern();
+ if (!pat.equals(pat2))
+ errln("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
+ else
+ logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"');
+ }
+ catch (IllegalArgumentException e) {
+ errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e);
+ }
+ }
+ }
+
+ /**
+ * @bug 4112104
+ * MessageFormat.equals(null) throws a NullPointerException. The JLS states
+ * that it should return false.
+ */
+ public void Test4112104() {
+ MessageFormat format = new MessageFormat("");
+ try {
+ // This should NOT throw an exception
+ if (format.equals(null)) {
+ // It also should return false
+ errln("MessageFormat.equals(null) returns false");
+ }
+ }
+ catch (NullPointerException e) {
+ errln("MessageFormat.equals(null) throws " + e);
+ }
+ }
+
+ /**
+ * @bug 4169959
+ * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG.
+ */
+ public void Test4169959() {
+ // This works
+ logln(MessageFormat.format( "This will {0}", "work"));
+
+ // This fails
+ logln(MessageFormat.format( "This will {0}",
+ new Object[]{ null } ) );
+ }
+
+ public void test4232154() {
+ boolean gotException = false;
+ try {
+ MessageFormat format = new MessageFormat("The date is {0:date}");
+ } catch (Exception e) {
+ gotException = true;
+ if (!(e instanceof IllegalArgumentException)) {
+ throw new RuntimeException("got wrong exception type");
+ }
+ if ("argument number too large at ".equals(e.getMessage())) {
+ throw new RuntimeException("got wrong exception message");
+ }
+ }
+ if (!gotException) {
+ throw new RuntimeException("didn't get exception for invalid input");
+ }
+ }
+
+ public void test4293229() {
+ MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''");
+ Object[] args = { null };
+ String expected = "'{0}' '{0}'";
+ String result = format.format(args);
+ if (!result.equals(expected)) {
+ throw new RuntimeException("wrong format result - expected \"" +
+ expected + "\", got \"" + result + "\"");
+ }
+ }
+
+ /**
+ * @bug 8187551
+ * test MessageFormat.setFormat() method to throw AIOOBE on invalid index.
+ */
+ public void test8187551() {
+ //invalid cases ("pattern", "invalid format element index")
+ String[][] invalidCases = {{"The disk \"{1}\" contains {0}.", "2"},
+ {"The disk \"{1}\" contains {0}.", "9"},
+ {"On {1}, there are {0} and {2} folders", "3"}};
+
+ //invalid cases (must throw exception)
+ Arrays.stream(invalidCases).forEach(entry -> messageSetFormat(entry[0],
+ Integer.valueOf(entry[1])));
+ }
+
+ // test MessageFormat.setFormat() method for the given pattern and
+ // format element index
+ private void messageSetFormat(String pattern, int elemIndex) {
+ MessageFormat form = new MessageFormat(pattern);
+
+ double[] fileLimits = {0, 1, 2};
+ String[] filePart = {"no files", "one file", "{0,number} files"};
+ ChoiceFormat fileForm = new ChoiceFormat(fileLimits, filePart);
+
+ boolean AIOOBEThrown = false;
+ try {
+ form.setFormat(elemIndex, fileForm);
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ AIOOBEThrown = true;
+ }
+
+ if (!AIOOBEThrown) {
+ throw new RuntimeException("[FAILED: Must throw" +
+ " ArrayIndexOutOfBoundsException for" +
+ " invalid index " + elemIndex + " used in" +
+ " MessageFormat.setFormat(index, format)]");
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/text/Format/MessageFormat/MessageTest.java b/ojluni/src/test/java/text/Format/MessageFormat/MessageTest.java
new file mode 100644
index 00000000000..6db035f9717
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/MessageFormat/MessageTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /java/text/testlib
+ * @summary test MessageFormat
+ */
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+
+package test.java.text.Format.MessageFormat;
+
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class MessageTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new MessageTest().run(args);
+ }
+
+
+ public void TestMSGPatternTest() {
+ Object[] testArgs = {
+ 1D, 3456D,
+ "Disk", new Date(10000000000L)};
+
+ String[] testCases = {
+ "Quotes '', '{', 'a' {0} '{0}'",
+ "Quotes '', '{', 'a' {0,number} '{0}'",
+ "'{'1,number,'#',##} {1,number,'#',##}",
+ "There are {1} files on {2} at {3}",
+ "On {2}, there are {1} files, with {0,number,currency}.",
+ "'{1,number,percent}', {1,number,percent}, ",
+ "'{1,date,full}', {1,date,full}, ",
+ "'{3,date,full}', {3,date,full}, ",
+ "'{1,number,#,##}' {1,number,#,##}",
+ };
+
+ for (int i = 0; i < testCases.length; ++i) {
+ Locale save = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ logln("");
+ logln( i + " Pat in: " + testCases[i]);
+ MessageFormat form = new MessageFormat(testCases[i]);
+ logln( i + " Pat out: " + form.toPattern());
+ String result = form.format(testArgs);
+ logln( i + " Result: " + result);
+ Object[] values = form.parse(result);
+ for (int j = 0; j < testArgs.length; ++j) {
+ Object testArg = testArgs[j];
+ Object value = null;
+ if (j < values.length) {
+ value = values[j];
+ }
+ if ((testArg == null && value != null)
+ || (testArg != null && !testArg.equals(value))) {
+ logln( i + " " + j + " old: " + testArg);
+ logln( i + " " + j + " new: " + value);
+ }
+ }
+ }
+ catch(java.text.ParseException pe ) {
+ throw new RuntimeException("Error: MessageFormat.parse throws ParseException");
+ }
+ finally{
+ Locale.setDefault(save);
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/MessageFormat/bug4492719.java b/ojluni/src/test/java/text/Format/MessageFormat/bug4492719.java
new file mode 100644
index 00000000000..929737da906
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/MessageFormat/bug4492719.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ *
+ * @bug 4492719
+ * @library /java/text/testlib
+ * @summary Confirm that Message.parse() interprets time zone which uses "GMT+/-" format correctly and doesn't throw ParseException.
+ */
+
+package test.java.text.Format.MessageFormat;
+
+import java.util.*;
+import java.text.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class bug4492719 extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ Locale savedLocale = Locale.getDefault();
+ TimeZone savedTimeZone = TimeZone.getDefault();
+ MessageFormat mf;
+ boolean err =false;
+
+ String[] formats = {
+ "short", "medium", "long", "full"
+ };
+ String[] timezones = {
+ "America/Los_Angeles", "GMT", "GMT+09:00", "GMT-8:00",
+ "GMT+123", "GMT-1234", "GMT+2", "GMT-13"
+ };
+ String text;
+
+ Locale.setDefault(Locale.US);
+
+ try {
+ for (int i = 0; i < timezones.length; i++) {
+ TimeZone.setDefault(TimeZone.getTimeZone(timezones[i]));
+
+ for (int j = 0; j < formats.length; j++) {
+ mf = new MessageFormat("{0,time," + formats[j] + "} - time");
+ text = MessageFormat.format("{0,time," + formats[j] + "} - time",
+ new Object [] { new Date(123456789012L)});
+ Object[] objs = mf.parse(text);
+ }
+ }
+ } catch (ParseException e) {
+ err = true;
+ System.err.println("Invalid ParseException occurred : " +
+ e.getMessage());
+ System.err.println(" TimeZone=" + TimeZone.getDefault());
+ }
+ finally {
+ Locale.setDefault(savedLocale);
+ TimeZone.setDefault(savedTimeZone);
+ if (err) {
+ throw new Exception("MessageFormat.parse(\"GMT format\") failed.");
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/BigDecimalFormat.java b/ojluni/src/test/java/text/Format/NumberFormat/BigDecimalFormat.java
new file mode 100644
index 00000000000..c99f61e4ddb
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/BigDecimalFormat.java
@@ -0,0 +1,1048 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4018937 8008577
+ * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected.
+ * @library /java/text/testlib
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalFormat
+ */
+
+package test.java.text.Format.NumberFormat;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.*;
+import java.util.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class BigDecimalFormat extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new BigDecimalFormat().run(args);
+ }
+
+ static final String nonsep_int =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ static final String sep_int =
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890";
+
+ static final String nonsep_zero =
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000";
+
+ static final String sep_zero =
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000";
+
+ static final String fra =
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789";
+
+
+ StringBuffer formatted = new StringBuffer(1000);
+ FieldPosition fp;
+
+ /**
+ * Test for normal big numbers which have the fraction part
+ */
+ void test_Format_in_NumberFormat_BigDecimal() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 0.000...789
+ // To: 0.000...789 (same as From)
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + "123456789";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, from, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...789
+ // To: -0.000...789 (same as From)
+ // ~ : FieldPosition(SIGN)
+ fp = new FieldPosition(NumberFormat.Field.SIGN);
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "123456789";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, from, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 0, 1);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...7890.012...789
+ // To: 123,4...7,890.012...789
+ // ~~~~~~~~~~~~~ : FieldPosition(INTEGER_FIELD)
+ fp = new FieldPosition(DecimalFormat.INTEGER_FIELD);
+ formatted.setLength(0);
+ from = nonsep_int + "." + fra;
+ to = sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 0, 479);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...7890.012...789
+ // To: -123,4...7,890.012...789
+ // ~~~~~~~~~ : FieldPosition(FRACTION_FIELD)
+ fp = new FieldPosition(DecimalFormat.FRACTION_FIELD);
+ formatted.setLength(0);
+ from = "-" + nonsep_int + "." + fra;
+ to = "-" + sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 481, 841);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...78900000...0000.000...789
+ // To: 123,4...7,890,000,0...0,000.000...789
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero + "." + nonsep_zero + fra;
+ to = sep_int + "," + sep_zero + "." + nonsep_zero + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000.000...789
+ // To: -123,4...7,890,000,0...0,000.000...789
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero + "." + nonsep_zero + fra;
+ to = "-" + sep_int + "," + sep_zero + "." + nonsep_zero + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...78900000...0000
+ // To: 123,4...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero;
+ to = sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000
+ // To: -123,4...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero;
+ to = "-" + sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...78900000...0000.0...0
+ // To: 1,234...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero + "." + nonsep_zero;
+ to = sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000.0...0
+ // To: -1,234...7,890,000,0...0,000
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero + "." + nonsep_zero;
+ to = "-" + sep_int + "," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0000
+ // To: 0
+ formatted.setLength(0);
+ from = nonsep_zero;
+ to = "0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -000...0000
+ // To: 0
+ formatted.setLength(0);
+ from = "-" + nonsep_zero;
+ to = "0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...00001234
+ // To: 1,234
+ formatted.setLength(0);
+ from = nonsep_zero + "1234";
+ to = "1,234";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -000...00001234
+ // To: -1,234
+ // ~ : FieldPosition(GROUPING_SEPARATOR)
+ fp = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
+ formatted.setLength(0);
+ from = "-" + nonsep_zero + "1234";
+ to = "-1,234";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 2, 3);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0000.0...0
+ // To: 0
+ formatted.setLength(0);
+ from = nonsep_zero + "." + nonsep_zero;
+ to = "0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.0");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 1);
+
+ // From: -000...0000.0...0
+ // To: 0.0
+ formatted.setLength(0);
+ from = "-" + nonsep_zero + "." + nonsep_zero;
+ to = "0.0";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1234...7890.012...7890...0
+ // To: 1,234...7,890.0123...789
+ formatted.setLength(0);
+ from = nonsep_int + "." + fra + nonsep_zero;
+ to = sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...7890.012...7890...0
+ // To: -1,234...7,890.0123...789
+ formatted.setLength(0);
+ from = "-" + nonsep_int + "." + fra + nonsep_zero;
+ to = "-" + sep_int + "." + fra;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1123...890.012...789
+ // To : 1.123...8900123...789E360
+ // ~~~ : FieldPosition(EXPONENT)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT);
+ formatted.setLength(0);
+ from = "1" + nonsep_int + "." + fra;
+ to = "1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 723, 726);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1123...890.012...789
+ // To : -1.123...8900123...789E360
+ formatted.setLength(0);
+ from = "-1" + nonsep_int + "." + fra;
+ to = "-1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 0);
+
+ // From: 0.000...0001123...890.012...789
+ // To : 1.123...8900123...789E-360
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + "1" + fra;
+ to = "1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...0001123...890.012...789
+ // To : -1.123...8900123...789E-360
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "1" + fra;
+ to = "-1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 1123...890.012...789000...000
+ // To : 1.123...8900123...789E360
+ formatted.setLength(0);
+ from = "1" + nonsep_int + "." + fra + nonsep_zero;
+ to = "1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1123...890.012...789000...000
+ // To : -1.123...8900123...789E360
+ // ~ : FieldPosition(EXPONENT_SYMBOL)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT_SYMBOL);
+ formatted.setLength(0);
+ from = "-1" + nonsep_int + "." + fra + nonsep_zero;
+ to = "-1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 723, 724);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 0.000...0001123...890.012...789000...000
+ // To : 1.123...8900123...789E-360
+ // ~ : FieldPosition(EXPONENT_SIGN)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT_SIGN);
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + "1" + fra + nonsep_zero;
+ to = "1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 363, 364);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...0001123...890.012...789000...000
+ // To : -1.123...8900123...789E-360
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "1" + fra + nonsep_zero;
+ to = "-1." + fra + "E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: ABC1123...890.012...789
+ // To : ABC1.123...890.0123...789
+ formatted = new StringBuffer("ABC");
+ from = "1" + nonsep_int + "." + fra;
+ to = "ABC1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: ABC-1123...890.012...789
+ // To : ABC-1.123...890.0123...789
+ // ~ : FieldPosition(DECIMAL_SEPARATOR)
+ fp = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
+ formatted = new StringBuffer("ABC");
+ from = "-1" + nonsep_int + "." + fra;
+ to = "ABC-1." + nonsep_int + fra + "E360";
+ nf.format(new BigDecimal(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 5, 6);
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, 726, 0);
+
+ // From: 0.000...000012...7890123456789
+ // To: 0.000...000012...789012346 (Shorter than From)
+ formatted.setLength(0);
+ from = "0." + nonsep_zero + fra + fra;
+ to = "0." + nonsep_zero + fra + "012346";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, 723, 0);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -0.000...000012...7890123456789
+ // To: -0.000...000012...789012 (Shorter than From)
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + fra + fra;
+ to = "-0." + nonsep_zero + fra + "012";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("00000.###E0");
+ setDigits(nf, 5, 5, 370, 0);
+
+ // From: 1234567890.012...78901234567890
+ // To: 12345.67890012...789012346E5
+ formatted.setLength(0);
+ from = "1234567890." + fra + "0123456789";
+ to = "12345.67890" + fra + "01235E5";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, 364, 0);
+
+ // From: -0.000...0001012...7890123456789
+ // To: -1.012...789012E-361
+ formatted.setLength(0);
+ from = "-0." + nonsep_zero + "1" + fra + "0123456789";
+ to = "-1." + fra + "0123E-361";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, 366, 0);
+
+ // From: 1012...78901234567890
+ // To: 1.012...789012346E370
+ formatted.setLength(0);
+ from = "1" + fra + "0123456789";
+ to = "1." + fra + "012346E370";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, 363, 0);
+
+ // From: -1012...7890123456789
+ // To: -1.012...789012E370
+ formatted.setLength(0);
+ from = "-1" + fra + "0123456789";
+ to = "-1." + fra + "012E370";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 720);
+
+ // From: 1234...78900000...0000.0...0
+ // To: 1,234...7,890,000,0...0,000.0...0
+ formatted.setLength(0);
+ from = nonsep_int + nonsep_zero + "." + nonsep_zero + nonsep_zero;
+ to = sep_int + "," + sep_zero + "." + nonsep_zero + nonsep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...78900000...0000.0...0
+ // To: -1,234...7,890,000,0...0,000.0...0
+ formatted.setLength(0);
+ from = "-" + nonsep_int + nonsep_zero + "." + nonsep_zero + nonsep_zero;
+ to = "-" + sep_int + "," + sep_zero + "." + nonsep_zero + nonsep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal big numbers which have the fraction part with multiplier
+ */
+ void test_Format_in_NumberFormat_BigDecimal_usingMultiplier() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+ ((DecimalFormat)nf).setMultiplier(250000000);
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(true);
+
+ // From: 1000...0000.000...000
+ // To: 250,0...0,000.
+ formatted.setLength(0);
+ from = "1" + nonsep_zero + "." + nonsep_zero;
+ to = "250,000,000," + sep_zero + ".";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(false);
+
+ // From: -1000...0000.000...000
+ // To: -250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero + "." + nonsep_zero;
+ to = "-250,000,000," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+ ((DecimalFormat)nf).setMultiplier(-250000000);
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(true);
+
+ // From: 1000...0000.000...000
+ // To: -250,0...0,000.
+ formatted.setLength(0);
+ from = "1" + nonsep_zero + "." + nonsep_zero;
+ to = "-250,000,000," + sep_zero + ".";
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(false);
+
+ // From: -1000...0000.000...000
+ // To: 250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero + "." + nonsep_zero;
+ to = "250,000,000," + sep_zero;
+ nf.format(new BigDecimal(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part
+ */
+ void test_Format_in_NumberFormat_BigInteger() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1234...7890
+ // To: 123,4...7,890
+ formatted.setLength(0);
+ from = nonsep_int;
+ to = sep_int;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1234...7890
+ // To: -123,4...7,890
+ // ~~~~~~~~~~~~~ : FieldPosition(INTEGER_FIELD)
+ fp = new FieldPosition(DecimalFormat.INTEGER_FIELD);
+ formatted.setLength(0);
+ from = "-" + nonsep_int;
+ to = "-" + sep_int;
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 1, 480);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0001234...7890
+ // To: 123,4...7,890
+ formatted.setLength(0);
+ from = nonsep_zero + nonsep_int;
+ to = sep_int;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -000...0001234...7890
+ // To: -123,4...7,890
+ // ~ : FieldPosition(SIGN)
+ fp = new FieldPosition(NumberFormat.Field.SIGN);
+ formatted.setLength(0);
+ from = "-" + nonsep_zero + nonsep_int;
+ to = "-" + sep_int;
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 0, 1);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: 000...0000
+ // To: 0
+ formatted.setLength(0);
+ from = nonsep_zero;
+ to = "0";
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.0");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 1);
+
+ // From: -000...0000
+ // To: 0.0
+ fp = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
+ formatted.setLength(0);
+ from = "-" + nonsep_zero;
+ to = "0.0";
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 1, 2);
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 0);
+
+ // From: 10123...789
+ // To : 1.0123...789E360
+ // ~~~ : FieldPosition(EXPONENT)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT);
+ formatted.setLength(0);
+ from = "1" + fra;
+ to = "1." + fra + "E360";
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 363, 366);
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1012...789
+ // To : -1.012...789E360
+ formatted.setLength(0);
+ from = "-1" + fra;
+ to = "-1." + fra + "E360";
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("00000.###E0");
+ setDigits(nf, 5, 5, Integer.MAX_VALUE, 720);
+
+ // From: 12345012...789000...000
+ // To : 12345.012...789000...000E720
+ // ~~~ : FieldPosition(EXPONENT)
+ fp = new FieldPosition(NumberFormat.Field.EXPONENT);
+ formatted.setLength(0);
+ from = "12345" + fra + nonsep_zero;
+ to = "12345." + fra + nonsep_zero + "E720";
+ nf.format(new BigInteger(from), formatted, fp);
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ checkFieldPosition(from, fp, 727, 730);
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("00000.###E0");
+ setDigits(nf, 5, 5, Integer.MAX_VALUE, 365);
+
+ // From: -1234567890012...789000...000
+ // To : -12345.67890012...789E365
+ formatted.setLength(0);
+ from = "-1234567890" + fra;
+ to = "-12345.67890" + fra + "E365";
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part with
+ * multiplier
+ */
+ void test_Format_in_NumberFormat_BigInteger_usingMultiplier() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(250000000);
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1000...0000
+ // To: 250,0...0,000
+ formatted.setLength(0);
+ from = "1" + nonsep_zero;
+ to = "250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1000...0000
+ // To: -250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero;
+ to = "-250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(-250000000);
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ // From: 1000...0000
+ // To: -250,0...0,000
+ formatted.setLength(0);
+ from = "1" + nonsep_zero;
+ to = "-250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ // From: -1000...0000
+ // To: 250,0...0,000
+ formatted.setLength(0);
+ from = "-1" + nonsep_zero;
+ to = "250,000,000," + sep_zero;
+ nf.format(new BigInteger(from), formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for normal Long numbers when maximum and minimum digits are
+ * specified
+ */
+ void test_Format_in_NumberFormat_Long_checkDigits() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 0);
+
+ // From: 1234567890
+ // To: 000,0...0,000,123,456,789
+ // -------------
+ // 300 zeros
+ formatted.setLength(0);
+ from = "123456789";
+ to = sep_zero.substring(0, 399) + ",123,456,789";
+ nf.format(123456789L, formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("##0.###");
+ ((DecimalFormat)nf).setMultiplier(-1);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 360);
+
+ // From: 1234567890
+ // To: -0000...0000123456789.000...000
+ // -------------
+ // 300 zeros
+ formatted.setLength(0);
+ from = "123456789";
+ to = "-" + nonsep_zero.substring(0, 300) + "123456789." +
+ nonsep_zero.substring(0, 340);
+ nf.format(123456789L, formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(Integer.MAX_VALUE);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 0);
+
+ // From: Long.MAX_VALUE
+ // To: 000,0...0,000,019,807,040,619,342,712,359,383,728,129
+ // ---------------
+ // 280 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MAX_VALUE);
+ to = sep_zero.substring(0, 373) +
+ "19,807,040,619,342,712,359,383,728,129";
+ nf.format(Long.MAX_VALUE, formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("0.###E0");
+ ((DecimalFormat)nf).setMultiplier(Integer.MIN_VALUE);
+ setDigits(nf, 1, 1, Integer.MAX_VALUE, 360);
+
+ // From: Long.MAX_VALUE
+ // To: -1.9807040628566084396238503936000...000E28
+ // ---------
+ // 312 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MAX_VALUE);
+ to = "-1.9807040628566084396238503936" +
+ nonsep_zero.substring(0, 312) + "E28";
+ nf.format(Long.MAX_VALUE, formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("##0.###E0");
+ ((DecimalFormat)nf).setMultiplier(Integer.MAX_VALUE);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 360);
+
+ // From: Long.MIN_VALUE
+ // To: -198070406193427123615312117760000...0000.000...000E-280
+ // ----------- ---------
+ // 280 zeros 340 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MIN_VALUE);
+ to = "-19807040619342712361531211776" +
+ nonsep_zero.substring(0, 280) + "." +
+ nonsep_zero.substring(0, 340) + "E-280";
+ nf.format(Long.MIN_VALUE, formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+
+ /* ------------------------------------------------------------------ */
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ ((DecimalFormat)nf).setMultiplier(Integer.MIN_VALUE);
+ setDigits(nf, Integer.MAX_VALUE, 360, Integer.MAX_VALUE, 360);
+
+ // From: Long.MIN_VALUE
+ // To: 000,0...0,000,019,807,040,628,566,084,398,385,987,584.000...000
+ // --------------- ---------
+ // 280 zeros 340 zeros
+ formatted.setLength(0);
+ from = Long.toString(Long.MIN_VALUE);
+ to = sep_zero.substring(0, 373) +
+ "19,807,040,628,566,084,398,385,987,584." +
+ nonsep_zero.substring(0, 340);
+ nf.format(Long.MIN_VALUE, formatted, new FieldPosition(0));
+ checkFormat(from, formatted, to, ((DecimalFormat)nf).getMultiplier());
+ }
+
+ /**
+ * Test for special numbers
+ * Double.NaN
+ * Double.POSITIVE_INFINITY
+ * Double.NEGATIVE_INFINITY
+ */
+ void test_Format_in_NumberFormat_SpecialNumber() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ ((DecimalFormat)nf).applyPattern("#,##0.###");
+ setDigits(nf, Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+
+ double[] numbers = {
+ -0.0, 0.0, Double.NaN,
+ Double.POSITIVE_INFINITY, 5.1, 5.0,
+ Double.NEGATIVE_INFINITY, -5.1, -5.0,
+ };
+ int multipliers[] = {0, 5, -5};
+ String[][] expected = {
+ {"-0", "0", "\ufffd", "\ufffd", "0", "0", "\ufffd", "-0", "-0"},
+ {"-0", "0", "\ufffd", "\u221e", "25.5", "25", "-\u221e", "-25.5",
+ "-25"},
+ {"0", "-0", "\ufffd", "-\u221e", "-25.5", "-25", "\u221e", "25.5",
+ "25"},
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ ((DecimalFormat)nf).setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ formatted.setLength(0);
+ from = String.valueOf(numbers[j]);
+ nf.format(numbers[j], formatted, new FieldPosition(0));
+ checkFormat(from, formatted, expected[i][j],
+ ((DecimalFormat)nf).getMultiplier());
+ }
+ }
+ }
+
+ /**
+ * Test for Long.MIN_VALUE
+ * (Formatting Long.MIN_VALUE w/ multiplier=-1 used to return a wrong
+ * number.)
+ */
+ void test_Format_in_NumberFormat_Other() {
+ String from, to;
+
+ NumberFormat nf = NumberFormat.getInstance(Locale.US);
+ if (!(nf instanceof DecimalFormat)) {
+ throw new RuntimeException("Couldn't get DecimalFormat instance.");
+ }
+
+ long[] numbers = {
+ Long.MIN_VALUE,
+ };
+ int multipliers[] = {1, -1};
+ String[][] expected = {
+ {"-9,223,372,036,854,775,808"}, // Long.MIN_VALUE
+ {"9,223,372,036,854,775,808"}, // Long.MIN_VALUE * (-1)
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ ((DecimalFormat)nf).setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ formatted.setLength(0);
+ from = String.valueOf(numbers[j]);
+ nf.format(numbers[j], formatted, new FieldPosition(0));
+ checkFormat(from, formatted, expected[i][j],
+ ((DecimalFormat)nf).getMultiplier());
+ }
+ }
+ }
+
+ /**
+ * Test for MessageFormat
+ */
+ void test_Format_in_MessageFormat() {
+ MessageFormat mf = new MessageFormat(
+ " {0, number}\n" +
+ " {0, number, integer}\n" +
+ " {0, number, currency}\n" +
+ " {0, number, percent}\n" +
+ " {0, number,0.###########E0}\n" +
+
+ " {1, number}\n" +
+ " {1, number, integer}\n" +
+ " {1, number, currency}\n" +
+ " {1, number, percent}\n" +
+ " {1, number,0.#######E0}\n",
+ Locale.US
+ );
+ Object[] testArgs = {
+ new BigInteger("9876543210987654321098765432109876543210"),
+ new BigDecimal("-12345678901234567890.98765432109876543210987654321"),
+ };
+ String expected =
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210\n" +
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210\n" +
+ " $9,876,543,210,987,654,321,098,765,432,109,876,543,210.00\n" +
+ " 987,654,321,098,765,432,109,876,543,210,987,654,321,000%\n" +
+ " 9.87654321099E39\n" +
+
+ " -12,345,678,901,234,567,890.988\n" +
+ " -12,345,678,901,234,567,891\n" +
+ " ($12,345,678,901,234,567,890.99)\n" +
+ " -1,234,567,890,123,456,789,099%\n" +
+ " -1.2345679E19\n"
+ ;
+
+ if (!expected.equals(mf.format(testArgs))) {
+ errln("Wrong format.\n got:\n" + mf.format(testArgs) +
+ " expected:\n" + expected);
+ }
+ }
+
+ private void setDigits(NumberFormat nf,
+ int i_max, int i_min, int f_max, int f_min) {
+ nf.setMaximumIntegerDigits(i_max);
+ nf.setMinimumIntegerDigits(i_min);
+ nf.setMaximumFractionDigits(f_max);
+ nf.setMinimumFractionDigits(f_min);
+ }
+
+ private void checkFormat(String orig, StringBuffer got, String expected,
+ int multiplier) {
+ if (!expected.equals(new String(got))) {
+ errln("Formatting... failed." +
+ "\n original: " + orig +
+ "\n multiplier: " + multiplier +
+ "\n formatted: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private void checkFieldPosition(String orig, FieldPosition fp, int begin,
+ int end) {
+ int position;
+
+ if ((position = fp.getBeginIndex()) != begin) {
+ errln("Formatting... wrong Begin index returned for " +
+ fp.getFieldAttribute() + "." +
+ "\n original: " + orig +
+ "\n got: " + position +
+ "\n expected: " + begin + "\n");
+ }
+ if ((position = fp.getEndIndex()) != end) {
+ errln("Formatting... wrong End index returned for " +
+ fp.getFieldAttribute() + "." +
+ "\n original: " + orig +
+ "\n got: " + position +
+ "\n expected: " + end + "\n");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/BigDecimalParse.java b/ojluni/src/test/java/text/Format/NumberFormat/BigDecimalParse.java
new file mode 100644
index 00000000000..388ed97078b
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/BigDecimalParse.java
@@ -0,0 +1,713 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4018937 8008577
+ * @summary Confirm that methods which are newly added to support BigDecimal and BigInteger work as expected.
+ * @library /java/text/testlib
+ * @run main/othervm -Djava.locale.providers=COMPAT,SPI BigDecimalParse
+ */
+
+package test.java.text.Format.NumberFormat;
+
+import java.math.BigDecimal;
+import java.text.*;
+import java.util.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class BigDecimalParse extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ Locale loc = Locale.getDefault();
+ try {
+ Locale.setDefault(Locale.US);
+ new BigDecimalParse().run(args);
+ } finally {
+ // restore the reserved locale
+ Locale.setDefault(loc);
+ }
+ }
+
+ static final String nonsep_int =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ static final String sep_int =
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890," +
+ "123,456,789,012,345,678,901,234,567,890";
+
+ static final String nonsep_zero =
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000" +
+ "000000000000000000000000000000000000000000000000000000000000";
+
+ static final String sep_zero =
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000," +
+ "000,000,000,000,000,000,000,000,000,000";
+
+ static final String fra =
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789";
+
+
+ Number parsed = null;
+ ParsePosition pp;
+ boolean exceptionOccurred;
+ String msg;
+ DecimalFormat df;
+
+ /**
+ * Test for normal big numbers which have the fraction part
+ */
+ void test_Parse_in_DecimalFormat_BigDecimal() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 1234...7890.012...789
+ // To: BigDecimal 1234...7890.012...789
+ check(nonsep_int + "." + fra, new BigDecimal(nonsep_int + "." + fra));
+
+ // From: -1,234...7,890.012...789
+ // To: BigDecimal -1234...7890.012...789
+ check("-" + sep_int + "." + fra,
+ new BigDecimal("-" + nonsep_int + "." + fra));
+
+ // From: 000...0000.0...0
+ // To: BigDecimal 0E-360
+ check(nonsep_zero + "." + nonsep_zero,
+ new BigDecimal(nonsep_zero + "." + nonsep_zero));
+
+ // From: 0.000...0000123...789E370
+ // To: BigDecimal 0.0123...789
+ check("0.0000000000" + nonsep_zero + fra + "E370",
+ new BigDecimal("0.0000000000" + nonsep_zero + fra + "E370"));
+
+ // From: 0.1123...890E-360
+ // To: BigDecimal 1.123...890E-361
+ check("0.1" + nonsep_int + "E-360",
+ new BigDecimal("0.1" + nonsep_int + "E-360"));
+
+ // From: 000...0000.0...0123...7890
+ // To: BigDecimal 1.234...890E-361
+ check(nonsep_zero + "." + nonsep_zero + nonsep_int,
+ new BigDecimal(nonsep_zero + "." + nonsep_zero + nonsep_int));
+
+ // From: 0.123...890E360
+ // To: BigDecimal 123...890
+ check("0." + nonsep_int + "E360",
+ new BigDecimal("0." + nonsep_int + "E360"));
+ }
+
+ /**
+ * Test for normal big numbers which have the fraction part with multiplier
+ */
+ void test_Parse_in_DecimalFormat_BigDecimal_usingMultiplier() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 250,0...0,000.000...000
+ // To: 1000...0000.000...000
+ df.setMultiplier(250000000);
+ check("250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
+
+ // From: -250,0...0,000.000...000
+ // To: -1000...0000.000...000
+ check("-250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
+
+ // From: 250,0...0,000.000...000
+ // To: -1000...0000.000...000
+ df.setMultiplier(-250000000);
+ check("250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
+
+ // From: -250,0...0,000.000...000
+ // To: 1000...0000.000...000
+ check("-250,000,000," + sep_zero + "." + nonsep_zero,
+ new BigDecimal("1" + nonsep_zero + "." + nonsep_zero));
+
+ // Confirm that ArithmeticException is handled properly
+ // From: 1000.000
+ // To: 333.333
+ df.setMultiplier(3);
+ check("1000.000", new BigDecimal("333.333"));
+
+ // Confirm that ArithmeticException is handled properly
+ // From: 10000.0000
+ // To: 303.0303
+ df.setMultiplier(33);
+ check("10000.0000", new BigDecimal("303.0303"));
+ }
+
+ /**
+ * Test for division by zero (BigDecimal)
+ */
+ void test_Parse_in_DecimalFormat_BigDecimal_DivisionByZero() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+ df.setMultiplier(0);
+
+ // From: 1000.000
+ // To: Double.POSITIVE_INFINITY
+ check("1000.000", Double.POSITIVE_INFINITY);
+
+ // From: -1000
+ // To: Double.NEGATIVE_INFINITY
+ check("-1000", Double.NEGATIVE_INFINITY);
+
+ // From: -0.00
+ // To: Double.NaN
+ check("-0.00", Double.NaN);
+ }
+
+ /**
+ * Test for division by zero (Double)
+ */
+ void test_Parse_in_DecimalFormat_Double_DivisionByZero() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(false);
+ df.setMultiplier(0);
+
+ // From: 1000.000
+ // To: Double.POSITIVE_INFINITY
+ check("1000.000", Double.POSITIVE_INFINITY);
+
+ // From: -1000.000
+ // To: Double.NEGATIVE_INFINITY
+ check("-1000.000", Double.NEGATIVE_INFINITY);
+
+ // From: 0.0
+ // To: Double.NaN
+ check("0.0", Double.NaN);
+
+ // From: -0.0 (Double)
+ // To: Double.NaN
+ check("-0.0", Double.NaN);
+
+ // From: Double.NaN
+ // To: Double.NaN
+ check("\ufffd", Double.NaN);
+
+ // From: Double.POSITIVE_INFINITY
+ // To: Double.NaN
+ check("\u221e", Double.POSITIVE_INFINITY);
+
+ // From: Double.NEGATIVE_INFINITY
+ // To: Double.NaN
+ check("-\u221e", Double.NEGATIVE_INFINITY);
+ }
+
+ /**
+ * Test for division by zero (Long)
+ */
+ void test_Parse_in_DecimalFormat_Long_DivisionByZero() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(false);
+ df.setMultiplier(0);
+
+ // From: 1000
+ // To: Double.POSITIVE_INFINITY
+ check("1000", Double.POSITIVE_INFINITY);
+
+ // From: -1000
+ // To: Double.NEGATIVE_INFINITY
+ check("-1000", Double.NEGATIVE_INFINITY);
+
+ // From: -000 (Long)
+ // To: Double.NaN
+ check("-000", Double.NaN);
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part
+ */
+ void test_Parse_in_DecimalFormat_BigInteger() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 123...890
+ // To: BigDecimal 123...890
+ check(nonsep_int + nonsep_int, new BigDecimal(nonsep_int + nonsep_int));
+
+ // From: 123,4...7,890
+ // To: BigDecimal 1234...7890
+ check(sep_int + "," + sep_int, new BigDecimal(nonsep_int + nonsep_int));
+
+ // From: -000...000123...890
+ // To: BigDecimal -123...890
+ check("-" + nonsep_zero + nonsep_int, new BigDecimal("-" + nonsep_int));
+
+ // From: -000,0...0,000,123,4...7,890
+ // To: BigDecimal -123...890
+ check("-" + sep_zero + "," + sep_int, new BigDecimal("-" + nonsep_int));
+ }
+
+ /**
+ * Test for normal big numbers which don't have the fraction part with
+ * multiplier
+ */
+ void test_Parse_in_DecimalFormat_BigInteger_usingMultiplier() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ // From: 250,0...0,000
+ // To: 1000...0000
+ df.setMultiplier(250000000);
+ check("250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
+
+ // From: -250,0...0,000
+ // To: -1000...0000
+ check("-250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
+
+ // From: 250,0...0,000
+ // To: -1000...0000
+ df.setMultiplier(-250000000);
+ check("250,000,000," + sep_zero, new BigDecimal("-1" + nonsep_zero));
+
+ // From: -250,0...0,000
+ // To: 1000...0000
+ check("-250,000,000," + sep_zero, new BigDecimal("1" + nonsep_zero));
+
+ // From: 250,0...0,000E-360
+ // To: -1000...0000.000...000
+ check("250,000,000," + sep_zero + "," + sep_zero + "E-360",
+ new BigDecimal("-1" + nonsep_zero + "." + nonsep_zero));
+
+ // Confirm that a division which results in a irrational number is done
+ // properly
+ // From: 1000
+ // To: 333
+ df.setMultiplier(3);
+ check("1000", new BigDecimal("333"));
+ }
+
+ /**
+ * Test for special numbers
+ * Double.NaN
+ * Double.POSITIVE_INFINITY
+ * Double.NEGATIVE_INFINITY
+ */
+ void test_Parse_in_DecimalFormat_SpecialNumber() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ String[] numbers = {
+ "0", "0.0", "25", "25.0", "25.5", "\u221e", "\ufffd",
+ "-0", "-0.0", "-25", "-25.0", "-25.5", "-\u221e",
+ };
+ int multipliers[] = {5, -5};
+ Number[][] expected = {
+ {
+ new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
+ new BigDecimal("5.0"), new BigDecimal("5.1"),
+ Double.POSITIVE_INFINITY, Double.NaN,
+ new BigDecimal("0"), new BigDecimal("0.0"),
+ new BigDecimal("-5"), new BigDecimal("-5.0"),
+ new BigDecimal("-5.1"),
+ Double.NEGATIVE_INFINITY, Double.NaN,
+ },
+ {
+ new BigDecimal("0"), new BigDecimal("0.0"),
+ new BigDecimal("-5"), new BigDecimal("-5.0"),
+ new BigDecimal("-5.1"),
+ Double.NEGATIVE_INFINITY, Double.NaN,
+ new BigDecimal("0"), new BigDecimal("0.0"), new BigDecimal("5"),
+ new BigDecimal("5.0"), new BigDecimal("5.1"),
+ Double.POSITIVE_INFINITY,
+ },
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ df.setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ check(String.valueOf(numbers[j]), expected[i][j]);
+ }
+ }
+ }
+
+ /**
+ * Test for special numbers
+ */
+ void test_Parse_in_DecimalFormat_Other() {
+ df = new DecimalFormat();
+ df.setParseBigDecimal(true);
+
+ String[] numbers = {
+ "-9223372036854775808", // Long.MIN_VALUE
+ };
+ int multipliers[] = {1, -1};
+ String[][] expected = {
+ {"-9223372036854775808"}, // Long.MIN_VALUE
+ {"9223372036854775808"}, // Long.MAX_VALUE+1 = abs(MIN_VALUE)
+ };
+
+ for (int i = 0; i < multipliers.length; i++) {
+ df.setMultiplier(multipliers[i]);
+ for (int j = 0; j < numbers.length; j++) {
+ check(String.valueOf(numbers[j]),
+ new BigDecimal(expected[i][j]));
+ }
+ }
+ }
+
+ static final String[] patterns = {
+ " {0, number} ",
+ " {0, number} ",
+ " {0, number, currency} ",
+ " {0, number, currency} ",
+ " {0, number, percent} ",
+ " {0, number, percent} ",
+ " {0, number,#,##0.###E0} ",
+ " {0, number,#,##0.###E0} ",
+
+ " {0, number} ",
+ " {0, number} ",
+ " {0, number, integer} ",
+ " {0, number, integer} ",
+ " {0, number, currency} ",
+ " {0, number, currency} ",
+ " {0, number, percent} ",
+ " {0, number, percent} ",
+ " {0, number,#,##0.###E0} ",
+ " {0, number,#,##0.###E0} ",
+ };
+ static final String[] from = {
+ " 12,345,678,901,234,567,890.98765432109876543210987654321 ",
+ " -12,345,678,901,234,567,890.98765432109876543210987654321 ",
+ " $12,345,678,901,234,567,890.98765432109876543210987654321 ",
+ " ($12,345,678,901,234,567,890.98765432109876543210987654321) ",
+ " 1,234,567,890,123,456,789,098.76543210987654321098765432100% ",
+ " -1,234,567,890,123,456,789,098.76543210987654321098765432100% ",
+ " 12,345,678,901,234,567,890.98765432109876543210987654321E-20 ",
+ " -12,345,678,901,234,567,890.98765432109876543210987654321E-20 ",
+
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210 ",
+ " -9,876,543,210,987,654,321,098,765,432,109,876,543,210 ",
+ " 9,876,543,210,987,654,321,098,765,432,109,876,543,210E5 ",
+ " -9,876,543,210,987,654,321,098,765,432,109,876,543,210E-5 ",
+ " $9,876,543,210,987,654,321,098,765,432,109,876,543,210.00 ",
+ " ($9,876,543,210,987,654,321,098,765,432,109,876,543,210.00) ",
+ " 987,654,321,098,765,432,109,876,543,210,987,654,321,012% ",
+ " -987,654,321,098,765,432,109,876,543,210,987,654,321,012% ",
+ " 98,765,432,109,876,543,210.98765432109876543210E20 ",
+ " -987,654,321,098,765,432,109,876,543,210,987,654,321,000,000,000,000,000,000,000E-20 ",
+ };
+
+ static final String[] expected1 = { // isParseIntegerOnly() == false
+ "12345678901234567890.98765432109876543210987654321",
+ "-12345678901234567890.98765432109876543210987654321",
+ "12345678901234567890.98765432109876543210987654321",
+ "-12345678901234567890.98765432109876543210987654321",
+ "12345678901234567890.98765432109876543210987654321",
+ "-12345678901234567890.98765432109876543210987654321",
+ "0.1234567890123456789098765432109876543210987654321",
+ "-0.1234567890123456789098765432109876543210987654321",
+
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "9.876543210987654321098765432109876543210E44",
+ "-98765432109876543210987654321098765.43210",
+ "9876543210987654321098765432109876543210.00",
+ "-9876543210987654321098765432109876543210.00",
+ "9876543210987654321098765432109876543210.12",
+ "-9876543210987654321098765432109876543210.12",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210.00000000000000000000",
+ };
+ static final int[] parsePosition1 = {
+ 60, 61, 61, 63, 64, 65, 64, 65,
+ 57, 58, 59, 61, 61, 63, 60, 61, 54, 88,
+ };
+
+ /**
+ * Test for MessageFormat: setParseIntegerOnly(false)
+ */
+ void test_Parse_in_MessageFormat_NotParseIntegerOnly() {
+ for (int i=0; i < patterns.length; i++) {
+ pp = new ParsePosition(0);
+ Object[] parsed = null;
+
+ try {
+ MessageFormat mf = new MessageFormat(patterns[i]);
+ Format[] formats = mf.getFormats();
+ for (int j=0; j < formats.length; j++) {
+ ((DecimalFormat)formats[j]).setParseBigDecimal(true);
+ }
+
+ parsed = mf.parse(from[i], pp);
+
+ if (pp.getErrorIndex() != -1) {
+ errln("Case" + (i+1) +
+ ": getErrorIndex() returns wrong value. expected:-1, got:"+
+ pp.getErrorIndex() + " for " + from[i]);
+ }
+ if (pp.getIndex() != parsePosition1[i]) {
+ errln("Case" + (i+1) +
+ ": getIndex() returns wrong value. expected:" +
+ parsePosition1[i] + ", got:"+ pp.getIndex() +
+ " for " + from[i]);
+ }
+ }
+ catch(Exception e) {
+ errln("Unexpected exception: " + e.getMessage());
+ }
+
+ checkType(from[i], getType(new BigDecimal(expected1[i])),
+ getType((Number)parsed[0]));
+ checkParse(from[i], new BigDecimal(expected1[i]),
+ (Number)parsed[0]);
+ }
+ }
+
+ static final String[] expected2 = { // isParseIntegerOnly() == true
+ "12345678901234567890",
+ "-12345678901234567890",
+ "12345678901234567890",
+ "-12345678901234567890",
+ "12345678901234567890",
+ "-12345678901234567890",
+ "0",
+ "0",
+
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "9.876543210987654321098765432109876543210E44",
+ "-98765432109876543210987654321098765.43210",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "9876543210987654321098765432109876543210.12",
+ "-9876543210987654321098765432109876543210.12",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210.00000000000000000000",
+ };
+ static final int[][] parsePosition2 = { // {errorIndex, index}
+ /*
+ * Should keep in mind that the expected result is different from
+ * DecimalFormat.parse() for some cases.
+ */
+ {28, 0}, // parsing stopped at '.'
+ {29, 0}, // parsing stopped at '.'
+ {29, 0}, // parsing stopped at '.'
+ {2, 0}, // parsing stopped at '(' because cannot find ')'
+ {2, 0}, // parsing stopped at the first numeric
+ // because cannot find '%'
+ {2, 0}, // parsing stopped at the first numeric
+ // because cannot find '%'
+ {28, 0}, // parsing stopped at '.'
+ {29, 0}, // parsing stopped at '.'
+
+ {-1, 57}, {-1, 58}, {-1, 59}, {-1, 61},
+ {56, 0}, // parsing stopped at '.'
+ // because cannot find '%'
+ {2, 0}, // parsing stopped at '(' because cannot find ')'
+ {-1, 60}, {-1, 61},
+ {28, 0}, // parsing stopped at '.'
+ {-1, 88},
+ };
+
+ /**
+ * Test for MessageFormat: setParseIntegerOnly(true)
+ */
+ void test_Parse_in_MessageFormat_ParseIntegerOnly() {
+ for (int i=0; i < patterns.length; i++) {
+ pp = new ParsePosition(0);
+ Object[] parsed = null;
+
+ try {
+ MessageFormat mf = new MessageFormat(patterns[i]);
+ Format[] formats = mf.getFormats();
+ for (int j=0; j < formats.length; j++) {
+ ((DecimalFormat)formats[j]).setParseBigDecimal(true);
+ ((DecimalFormat)formats[j]).setParseIntegerOnly(true);
+ }
+
+ parsed = mf.parse(from[i], pp);
+
+ if (pp.getErrorIndex() != parsePosition2[i][0]) {
+ errln("Case" + (i+1) +
+ ": getErrorIndex() returns wrong value. expected:" +
+ parsePosition2[i][0] + ", got:"+ pp.getErrorIndex() +
+ " for " + from[i]);
+ }
+ if (pp.getIndex() != parsePosition2[i][1]) {
+ errln("Case" + (i+1) +
+ ": getIndex() returns wrong value. expected:" +
+ parsePosition2[i][1] + ", got:"+ pp.getIndex() +
+ " for " + from[i]);
+ }
+ }
+ catch(Exception e) {
+ errln("Unexpected exception: " + e.getMessage());
+ }
+
+ if (parsePosition2[i][0] == -1) {
+ checkType(from[i], getType(new BigDecimal(expected2[i])),
+ getType((Number)parsed[0]));
+ checkParse(from[i], new BigDecimal(expected2[i]),
+ (Number)parsed[0]);
+ }
+ }
+ }
+
+ static final String[] from3 = {
+ "12,345,678,901,234,567,890.98765432109876543210987654321",
+ "-12,345,678,901,234,567,890.98765432109876543210987654321",
+ "9,876,543,210,987,654,321,098,765,432,109,876,543,210",
+ "-9,876,543,210,987,654,321,098,765,432,109,876,543,210",
+ "1234556790000E-8",
+ };
+ static final String[] expected3 = {
+ "12345678901234567890",
+ "-12345678901234567890",
+ "9876543210987654321098765432109876543210",
+ "-9876543210987654321098765432109876543210",
+ "12345.56790000",
+ };
+ static final int[][] parsePosition3 = { // {errorIndex, index}
+ {-1, 26},
+ {-1, 27},
+ {-1, 53},
+ {-1, 54},
+ {-1, 16},
+ };
+
+ /**
+ * Test for DecimalFormat: setParseIntegerOnly(true)
+ */
+ void test_Parse_in_DecimalFormat_ParseIntegerOnly() {
+ DecimalFormat df = (DecimalFormat)NumberFormat.getIntegerInstance();
+ df.setParseBigDecimal(true);
+
+ for (int i=0; i < from3.length; i++) {
+ pp = new ParsePosition(0);
+ Number parsed = null;
+
+ try {
+ parsed = df.parse(from3[i], pp);
+
+ if (pp.getErrorIndex() != parsePosition3[i][0]) {
+ errln("Case" + (i+1) +
+ ": getErrorIndex() returns wrong value. expected:" +
+ parsePosition3[i][0] + ", got:"+ pp.getErrorIndex() +
+ " for " + from3[i]);
+ }
+ if (pp.getIndex() != parsePosition3[i][1]) {
+ errln("Case" + (i+1) +
+ ": getIndex() returns wrong value. expected:" +
+ parsePosition3[i][1] + ", got:"+ pp.getIndex() +
+ " for " + from3[i]);
+ }
+ }
+ catch(Exception e) {
+ errln("Unexpected exception: " + e.getMessage());
+ }
+
+ if (parsePosition3[i][0] == -1) {
+ checkType(from3[i], getType(new BigDecimal(expected3[i])),
+ getType(parsed));
+ checkParse(from3[i], new BigDecimal(expected3[i]), parsed);
+ }
+ }
+ }
+
+ protected void check(String from, Number to) {
+ pp = new ParsePosition(0);
+ try {
+ parsed = df.parse(from, pp);
+ }
+ catch(Exception e) {
+ exceptionOccurred = true;
+ errln(e.getMessage());
+ }
+ if (!exceptionOccurred) {
+ checkParse(from, to, parsed);
+ checkType(from, getType(to), getType(parsed));
+ checkParsePosition(from, from.length(), pp.getIndex());
+ }
+ }
+
+ private void checkParse(String orig, Number expected, Number got) {
+ if (!expected.equals(got)) {
+ errln("Parsing... failed." +
+ "\n original: " + orig +
+ "\n parsed: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private void checkType(String orig, String expected, String got) {
+ if (!expected.equals(got)) {
+ errln("Parsing... unexpected Class returned." +
+ "\n original: " + orig +
+ "\n got: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private void checkParsePosition(String orig, int expected, int got) {
+ if (expected != got) {
+ errln("Parsing... wrong ParsePosition returned." +
+ "\n original: " + orig +
+ "\n got: " + got +
+ "\n expected: " + expected + "\n");
+ }
+ }
+
+ private String getType(Number number) {
+ return number.getClass().getName();
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/DFSDeserialization142.java b/ojluni/src/test/java/text/Format/NumberFormat/DFSDeserialization142.java
new file mode 100644
index 00000000000..ef69d84ad09
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/DFSDeserialization142.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * No at-test for this test, because it needs to be run on older version JDK than 1.6 to test.
+ * It was tested using 1.4.2. The file object was created using JDK1.6.
+ */
+
+package test.java.text.Format.NumberFormat;
+
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class DFSDeserialization142{
+
+ public static void main(String[] args)
+ {
+ try {
+
+ File file = new File("DecimalFormatSymbols.current");
+ FileInputStream istream = new FileInputStream(file);
+ ObjectInputStream p = new ObjectInputStream(istream);
+ DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject();
+ if (dfs.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
+ System.out.println("Serialization/Deserialization Test Passed.");
+ }else{
+ throw new Exception("Serialization/Deserialization Test Failed:"+dfs.getCurrencySymbol());
+ }
+ istream.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/DFSExponential.java b/ojluni/src/test/java/text/Format/NumberFormat/DFSExponential.java
new file mode 100644
index 00000000000..1cb1e770a1b
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/DFSExponential.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4068067
+ * @library /java/text/testlib
+ * @summary test NumberFormat with exponential separator symbols. It also tests the new
+ * public methods in DecimalFormatSymbols, setExponentSeparator() and
+ * getExponentSeparator()
+ */
+
+package test.java.text.Format.NumberFormat;
+
+import java.util.*;
+import java.text.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class DFSExponential extends IntlTest
+{
+
+ public static void main(String[] args) throws Exception {
+ new DFSExponential().run(args);
+ }
+
+
+ public void DFSExponenTest() throws Exception {
+ DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
+ String pat[] = { "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" };
+ double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
+ long lval[] = { 0, -1, 1, 123456789 };
+ String valFormat[][] = {
+ {"1.234x10^-2", "1.2346x10^8", "1.23x10^300", "-3.1416x10^-271"},
+ {"12.340x10^-03", "12.346x10^07", "12.300x10^299", "-31.416x10^-272"},
+ {"12.34x10^-003", "123.4568x10^006", "1.23x10^300", "-314.1593x10^-273"},
+ {"1.234x10^-2", "1.235x10^8", "1.23x10^300", "[3.142x10^-271]"},
+ };
+
+
+ int ival = 0, ilval = 0;
+ logln("Default exponent separator: "+sym.getExponentSeparator());
+ try {
+ sym.setExponentSeparator("x10^");
+ } catch (NullPointerException e){
+ errln("null String was passed to set an exponent separator symbol");
+ throw new RuntimeException("Test Malfunction: null String was passed to set an exponent separator symbol" );
+ }
+ logln("Current exponent separator: "+sym.getExponentSeparator());
+
+ for (int p=0; p<pat.length; ++p){
+ DecimalFormat fmt = new DecimalFormat(pat[p], sym);
+ logln(" Pattern: " + fmt.toPattern());
+ String locPattern = fmt.toLocalizedPattern();
+ logln(" Localized pattern: "+locPattern);
+ //fmt.applyLocalizedPattern(locPattern);
+ //System.out.println(" fmt.applyLocalizedPattern(): "+fmt.toLocalizedPattern());
+
+ for (int v=0; v<val.length; ++v) {
+ String s = fmt.format(val[v]);
+ logln(" " + val[v]+" --> "+s);
+ if(valFormat[p][v].equals(s)){
+ logln(": Passed");
+ }else{
+ errln(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s);
+ throw new RuntimeException(" Failed: Should be formatted as "+valFormat[p][v]+ "but got "+s);
+ }
+ }
+ } //end of the first for loop
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/DFSSerialization142.java b/ojluni/src/test/java/text/Format/NumberFormat/DFSSerialization142.java
new file mode 100644
index 00000000000..e3672a1c4b8
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/DFSSerialization142.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * No at-test for this test, because it needs to be run on JDK 1.4.2
+ * Instead, the resulting serialized file
+ * DecimalFormatSymbols.142 is archived.
+ */
+
+package test.java.text.Format.NumberFormat;
+
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class DFSSerialization142 {
+
+ public static void main(String[] args)
+ {
+ try {
+
+ DecimalFormatSymbols dfs= new DecimalFormatSymbols();
+ System.out.println("Default currency symbol in the default locale : " + dfs.getCurrencySymbol());
+ dfs.setCurrencySymbol("*SpecialCurrencySymbol*");
+ System.out.println("The special currency symbol is set : " + dfs.getCurrencySymbol());
+ FileOutputStream ostream = new FileOutputStream("DecimalFormatSymbols.142");
+ ObjectOutputStream p = new ObjectOutputStream(ostream);
+ p.writeObject(dfs);
+ ostream.close();
+ System.out.println("DecimalFormatSymbols saved ok.");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/PositionTest.java b/ojluni/src/test/java/text/Format/NumberFormat/PositionTest.java
new file mode 100644
index 00000000000..c9316187f53
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/PositionTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4109023 4153060 4153061
+ * @library /java/text/testlib
+ * @summary test ParsePosition and FieldPosition
+ */
+/*
+(C) Copyright Taligent, Inc. 1996 - All Rights Reserved
+(C) Copyright IBM Corp. 1996 - All Rights Reserved
+
+ The original version of this source code and documentation is copyrighted and
+owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are
+provided under terms of a License Agreement between Taligent and Sun. This
+technology is protected by multiple US and International patents. This notice and
+attribution to Taligent may not be removed.
+ Taligent is a registered trademark of Taligent, Inc.
+*/
+
+package test.java.text.Format.NumberFormat;
+
+import java.text.*;
+import java.io.*;
+
+import test.java.text.testlib.IntlTest;
+
+public class PositionTest extends IntlTest {
+
+ public static void main(String[] args) throws Exception {
+ new PositionTest().run(args);
+ }
+
+ public void TestParsePosition() {
+ ParsePosition pp1 = new ParsePosition(0);
+ if (pp1.getIndex() == 0) {
+ logln("PP constructor() tested.");
+ }else{
+ errln("*** PP getIndex or constructor() result");
+ }
+
+ {
+ int to = 5;
+ ParsePosition pp2 = new ParsePosition ( to );
+ if (pp2.getIndex() == 5) {
+ logln("PP getIndex and constructor(TextOffset) tested.");
+ }else{
+ errln("*** PP getIndex or constructor(TextOffset) result");
+ }
+ pp2.setIndex( 3 );
+ if (pp2.getIndex() == 3) {
+ logln("PP setIndex tested.");
+ }else{
+ errln("*** PP getIndex or setIndex result");
+ }
+ }
+
+ ParsePosition pp2, pp3;
+ pp2 = new ParsePosition( 3 );
+ pp3 = new ParsePosition( 5 );
+ ParsePosition pp4 = new ParsePosition(5);
+ if (! pp2.equals(pp3)) {
+ logln("PP not equals tested.");
+ }else{
+ errln("*** PP not equals fails");
+ }
+ if (pp3.equals(pp4)) {
+ logln("PP equals tested.");
+ }else{
+ errln("*** PP equals fails (" + pp3.getIndex() + " != " + pp4.getIndex() + ")");
+ }
+
+ ParsePosition pp5;
+ pp5 = pp4;
+ if (pp4.equals(pp5)) {
+ logln("PP operator= tested.");
+ }else{
+ errln("*** PP operator= operator== or operator != result");
+ }
+
+ }
+
+ public void TestFieldPosition() {
+ FieldPosition fp = new FieldPosition( 7 );
+
+ if (fp.getField() == 7) {
+ logln("FP constructor(int) and getField tested.");
+ }else{
+ errln("*** FP constructor(int) or getField");
+ }
+
+ FieldPosition fph = new FieldPosition( 3 );
+ if ( fph.getField() != 3) errln("*** FP getField or heap constr.");
+
+ boolean err1 = false;
+ boolean err2 = false;
+ boolean err3 = false;
+// for (long i = -50; i < 50; i++ ) {
+// fp.setField( i+8 );
+// fp.setBeginIndex( i+6 );
+// fp.setEndIndex( i+7 );
+// if (fp.getField() != i+8) err1 = true;
+// if (fp.getBeginIndex() != i+6) err2 = true;
+// if (fp.getEndIndex() != i+7) err3 = true;
+// }
+ if (!err1) {
+ logln("FP setField and getField tested.");
+ }else{
+ errln("*** FP setField or getField");
+ }
+ if (!err2) {
+ logln("FP setBeginIndex and getBeginIndex tested.");
+ }else{
+ errln("*** FP setBeginIndex or getBeginIndex");
+ }
+ if (!err3) {
+ logln("FP setEndIndex and getEndIndex tested.");
+ }else{
+ errln("*** FP setEndIndex or getEndIndex");
+ }
+
+ logln("");
+ }
+
+ public void TestFieldPosition_example() {
+ //***** no error detection yet !!!!!!!
+ //***** this test is for compiler checks and visual verification only.
+ double doubleNum[] = { 123456789.0, -12345678.9, 1234567.89, -123456.789,
+ 12345.6789, -1234.56789, 123.456789, -12.3456789, 1.23456789};
+ int dNumSize = doubleNum.length;
+
+ DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance();
+ fmt.setDecimalSeparatorAlwaysShown(true);
+
+ final int tempLen = 20;
+ StringBuffer temp;
+
+ for (int i=0; i<dNumSize; i++) {
+ temp = new StringBuffer(); // Get new buffer
+
+ FieldPosition pos = new FieldPosition(NumberFormat.INTEGER_FIELD);
+ StringBuffer buf = new StringBuffer();
+ //char fmtText[tempLen];
+ //ToCharString(fmt->format(doubleNum[i], buf, pos), fmtText);
+ StringBuffer res = fmt.format(doubleNum[i], buf, pos);
+ int tempOffset = (tempLen <= (tempLen - pos.getEndIndex())) ?
+ tempLen : (tempLen - pos.getEndIndex());
+ for (int j=0; j<tempOffset; j++) temp.append('='); // initialize
+ //cout << temp << fmtText << endl;
+ logln("FP " + temp + res);
+ }
+
+ logln("");
+ }
+ /* @bug 4109023
+ * Need to override ParsePosition.equals and FieldPosition.equals.
+ */
+ public void Test4109023()
+ {
+
+ ParsePosition p = new ParsePosition(3);
+ ParsePosition p2 = new ParsePosition(3);
+ if (!p.equals(p2))
+ errln("Error : ParsePosition.equals() failed");
+ FieldPosition fp = new FieldPosition(2);
+ FieldPosition fp2 = new FieldPosition(2);
+ if (!fp.equals(fp2))
+ errln("Error : FieldPosition.equals() failed");
+ }
+
+ /**
+ * @bug 4153060
+ * ParsePosition.hashCode() returns different values on equal objects.
+ */
+ public void Test4153060() {
+ ParsePosition p = new ParsePosition(53);
+ ParsePosition q = new ParsePosition(53);
+ if (!p.equals(q)) {
+ errln("" + p + " and " + q + " are not equal and should be");
+ }
+ if (p.hashCode() != q.hashCode()) {
+ errln("ParsePosition.hashCode() different for equal objects");
+ } else {
+ logln("hashCode(" + p + ") = " + p.hashCode());
+ }
+ }
+
+ /**
+ * @bug 4153061
+ * FieldPosition.hashCode() returns different values on equal objects.
+ */
+ public void Test4153061() {
+ FieldPosition p = new FieldPosition(53);
+ FieldPosition q = new FieldPosition(53);
+ if (!p.equals(q)) {
+ errln("" + p + " and " + q + " are not equal and should be");
+ }
+ if (p.hashCode() != q.hashCode()) {
+ errln("FieldPosition.hashCode() different for equal objects");
+ } else {
+ logln("hashCode(" + p + ") = " + p.hashCode());
+ }
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/SerializationLoadTest.java b/ojluni/src/test/java/text/Format/NumberFormat/SerializationLoadTest.java
new file mode 100644
index 00000000000..d4a21ba4395
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/SerializationLoadTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4101150
+ * @library /java/text/testlib
+ * @build SerializationLoadTest HexDumpReader
+ * @run main SerializationLoadTest
+ * @summary test serialization compatibility of DecimalFormat and DecimalFormatSymbols
+ * @key randomness
+ */
+
+package test.java.text.Format.NumberFormat.SerializationLoadTest;
+
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Random;
+
+import test.java.text.testlib.HexDumpReader;
+
+public class SerializationLoadTest {
+
+ public static void main(String[] args)
+ {
+ try {
+ InputStream istream1 = HexDumpReader.getStreamFromHexDump("DecimalFormat.114.txt");
+ ObjectInputStream p = new ObjectInputStream(istream1);
+ CheckDecimalFormat it = (CheckDecimalFormat)p.readObject();
+ System.out.println("1.1.4 DecimalFormat Loaded ok.");
+ System.out.println(it.Update());
+ System.out.println("Called Update successfully.");
+ istream1.close();
+
+ InputStream istream2 = HexDumpReader.getStreamFromHexDump("DecimalFormatSymbols.114.txt");
+ ObjectInputStream p2 = new ObjectInputStream(istream2);
+ CheckDecimalFormatSymbols it2 = (CheckDecimalFormatSymbols)p2.readObject();
+ System.out.println("1.1.4 DecimalFormatSymbols Loaded ok.");
+ System.out.println("getDigit : " + it2.Update());
+ System.out.println("Called Update successfully.");
+ istream2.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+@SuppressWarnings("serial")
+class CheckDecimalFormat implements Serializable
+{
+ DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance();
+
+ public String Update()
+ {
+ Random r = new Random();
+ return _decFormat.format(r.nextDouble());
+ }
+}
+
+@SuppressWarnings("serial")
+class CheckDecimalFormatSymbols implements Serializable
+{
+ DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols();
+
+ public char Update()
+ {
+ return _decFormatSymbols.getDigit();
+ }
+}
diff --git a/ojluni/src/test/java/text/Format/NumberFormat/SerializationSaveTest.java b/ojluni/src/test/java/text/Format/NumberFormat/SerializationSaveTest.java
new file mode 100644
index 00000000000..f97eda20804
--- /dev/null
+++ b/ojluni/src/test/java/text/Format/NumberFormat/SerializationSaveTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * No at-test for this test, because it needs to be run on JDK 1.1.4.
+ * Instead, the resulting serialized files DecimalFormat.114 and
+ * DecimalFormatSymbols.114 are archived.
+ */
+
+package test.java.text.Format.NumberFormat.SerializationSaveTest;
+
+import java.text.*;
+import java.util.*;
+import java.io.*;
+
+public class SerializationSaveTest {
+
+ public static void main(String[] args)
+ {
+ try {
+ CheckDecimalFormat it = new CheckDecimalFormat();
+ System.out.println(it.Update());
+ FileOutputStream ostream = new FileOutputStream("DecimalFormat.114");
+ ObjectOutputStream p = new ObjectOutputStream(ostream);
+ p.writeObject(it);
+ ostream.close();
+ System.out.println("DecimalFormat saved ok.");
+ CheckDecimalFormatSymbols it2 = new CheckDecimalFormatSymbols();
+ System.out.println("getDigit : " + it2.Update());
+ FileOutputStream ostream2 = new FileOutputStream("DecimalFormatSymbols.114");
+ ObjectOutputStream p2 = new ObjectOutputStream(ostream2);
+ p2.writeObject(it2);
+ ostream2.close();
+ System.out.println("DecimalFormatSymbols saved ok.");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+@SuppressWarnings("serial")
+class CheckDecimalFormat implements Serializable
+{
+ DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance();
+
+ public String Update()
+ {
+ Random r = new Random();
+ return _decFormat.format(r.nextDouble());
+ }
+}
+
+@SuppressWarnings("serial")
+class CheckDecimalFormatSymbols implements Serializable
+{
+ DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols();
+
+ public char Update()
+ {
+ return _decFormatSymbols.getDigit();
+ }
+}
diff --git a/ojluni/src/test/java/text/testlib/HexDumpReader.java b/ojluni/src/test/java/text/testlib/HexDumpReader.java
new file mode 100644
index 00000000000..7221bb0762d
--- /dev/null
+++ b/ojluni/src/test/java/text/testlib/HexDumpReader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.text.testlib;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * HexDumpReader provides utility methods to read a hex dump text file
+ * and convert to an InputStream. The format supported by the methods
+ * can be generated by the following command.
+ *
+ * $ od -vw -t x1 foo | sed -r -e 's/^[0-9]+ ?//' -e 's/ //g' -e '/^$/d'
+ */
+public class HexDumpReader {
+ public static InputStream getStreamFromHexDump(String fileName) {
+ return getStreamFromHexDump(new File(System.getProperty("test.src", "."),
+ fileName));
+ }
+
+ public static InputStream getStreamFromHexDump(File hexFile) {
+ ByteArrayBuilder bab = new ByteArrayBuilder();
+ int lineNo = 0;
+ try (BufferedReader reader
+ = new BufferedReader(new InputStreamReader(new FileInputStream(hexFile),
+ "us-ascii"))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ lineNo++;
+ line = line.trim();
+ // Skip blank and comment lines.
+ if (line.length() == 0) {
+ continue;
+ }
+ int x = line.indexOf('#');
+ if (x == 0) {
+ continue;
+ }
+ if (x > 0) {
+ line = line.substring(0, x).trim();
+ }
+ int len = line.length();
+ for (int i = 0; i < len; i += 2) {
+ bab.put((byte)Integer.parseInt(line, i, i + 2, 16));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(hexFile.getName() + ":error:" + lineNo + ": " + e, e);
+ }
+ return new ByteArrayInputStream(bab.toArray());
+ }
+
+
+ private static class ByteArrayBuilder {
+ private static final int BUFFER_SIZE = 4096;
+
+ private int size;
+ private List<byte[]> bytes;
+ private byte[] current;
+ private int offset;
+
+ ByteArrayBuilder() {
+ bytes = new ArrayList<>();
+ current = new byte[BUFFER_SIZE];
+ }
+
+ void put(byte b) {
+ if (offset == BUFFER_SIZE) {
+ bytes.add(current);
+ current = new byte[BUFFER_SIZE];
+ offset = 0;
+ }
+ current[offset++] = b;
+ size++;
+ }
+
+ byte[] toArray() {
+ byte[] buf = new byte[size];
+ int ptr = 0;
+ for (byte[] ba : bytes) {
+ System.arraycopy(ba, 0, buf, ptr, ba.length);
+ ptr += ba.length;
+ }
+ System.arraycopy(current, 0, buf, ptr, offset);
+ assert ptr + offset == size;
+ return buf;
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/text/testlib/IntlTest.java b/ojluni/src/test/java/text/testlib/IntlTest.java
new file mode 100644
index 00000000000..b0c5cde61c7
--- /dev/null
+++ b/ojluni/src/test/java/text/testlib/IntlTest.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.text.testlib;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * IntlTest is a base class for tests that can be run conveniently from
+ * the command line as well as under the Java test harness.
+ * <p>
+ * Sub-classes implement a set of public void methods named "Test*" or
+ * "test*" with no arguments. Each of these methods performs some
+ * test. Test methods should indicate errors by calling either err() or
+ * errln(). This will increment the errorCount field and may optionally
+ * print a message to the log. Debugging information may also be added to
+ * the log via the log and logln methods. These methods will add their
+ * arguments to the log only if the test is being run in verbose mode.
+ */
+public abstract class IntlTest {
+
+ //------------------------------------------------------------------------
+ // Everything below here is boilerplate code that makes it possible
+ // to add a new test by simply adding a method to an existing class.
+ //------------------------------------------------------------------------
+
+ protected IntlTest() {
+ // Populate testMethods with all the test methods.
+ Method[] methods = getClass().getDeclaredMethods();
+ for (Method method : methods) {
+ if (Modifier.isPublic(method.getModifiers())
+ && method.getReturnType() == void.class
+ && method.getParameterCount() == 0) {
+ String name = method.getName();
+ if (name.length() > 4) {
+ if (name.startsWith("Test") || name.startsWith("test")) {
+ testMethods.put(name, method);
+ }
+ }
+ }
+ }
+ }
+
+ protected void run(String[] args) throws Exception
+ {
+ // Set up the log and reference streams. We use PrintWriters in order to
+ // take advantage of character conversion. The JavaEsc converter will
+ // convert Unicode outside the ASCII range to Java's \\uxxxx notation.
+ log = new PrintWriter(System.out, true);
+
+ // Parse the test arguments. They can be either the flag
+ // "-verbose" or names of test methods. Create a list of
+ // tests to be run.
+ List<Method> testsToRun = new ArrayList<>(args.length);
+ for (String arg : args) {
+ switch (arg) {
+ case "-verbose":
+ verbose = true;
+ break;
+ case "-prompt":
+ prompt = true;
+ break;
+ case "-nothrow":
+ nothrow = true;
+ break;
+ case "-exitcode":
+ exitCode = true;
+ break;
+ default:
+ Method m = testMethods.get(arg);
+ if (m == null) {
+ System.out.println("Method " + arg + ": not found");
+ usage();
+ return;
+ }
+ testsToRun.add(m);
+ break;
+ }
+ }
+
+ // If no test method names were given explicitly, run them all.
+ if (testsToRun.isEmpty()) {
+ testsToRun.addAll(testMethods.values());
+ }
+
+ System.out.println(getClass().getName() + " {");
+ indentLevel++;
+
+ // Run the list of tests given in the test arguments
+ for (Method testMethod : testsToRun) {
+ int oldCount = errorCount;
+
+ writeTestName(testMethod.getName());
+
+ try {
+ testMethod.invoke(this, new Object[0]);
+ } catch (IllegalAccessException e) {
+ errln("Can't acces test method " + testMethod.getName());
+ } catch (InvocationTargetException e) {
+ errln("Uncaught exception thrown in test method "
+ + testMethod.getName());
+ e.getTargetException().printStackTrace(this.log);
+ }
+ writeTestResult(errorCount - oldCount);
+ }
+ indentLevel--;
+ writeTestResult(errorCount);
+
+ if (prompt) {
+ System.out.println("Hit RETURN to exit...");
+ try {
+ System.in.read();
+ } catch (IOException e) {
+ System.out.println("Exception: " + e.toString() + e.getMessage());
+ }
+ }
+ if (nothrow) {
+ if (exitCode) {
+ System.exit(errorCount);
+ }
+ if (errorCount > 0) {
+ throw new IllegalArgumentException("encountered " + errorCount + " errors");
+ }
+ }
+ }
+
+ /**
+ * Adds the given message to the log if we are in verbose mode.
+ */
+ protected void log(String message) {
+ logImpl(message, false);
+ }
+
+ protected void logln(String message) {
+ logImpl(message, true);
+ }
+
+ protected void logln() {
+ logImpl(null, true);
+ }
+
+ private void logImpl(String message, boolean newline) {
+ if (verbose) {
+ if (message != null) {
+ indent(indentLevel + 1);
+ log.print(message);
+ }
+ if (newline) {
+ log.println();
+ }
+ }
+ }
+
+ protected void err(String message) {
+ errImpl(message, false);
+ }
+
+ protected void errln(String message) {
+ errImpl(message, true);
+ }
+
+ private void errImpl(String message, boolean newline) {
+ errorCount++;
+ indent(indentLevel + 1);
+ log.print(message);
+ if (newline) {
+ log.println();
+ }
+ log.flush();
+
+ if (!nothrow) {
+ throw new RuntimeException(message);
+ }
+ }
+
+ protected int getErrorCount() {
+ return errorCount;
+ }
+
+ protected void writeTestName(String testName) {
+ indent(indentLevel);
+ log.print(testName);
+ log.flush();
+ needLineFeed = true;
+ }
+
+ protected void writeTestResult(int count) {
+ if (!needLineFeed) {
+ indent(indentLevel);
+ log.print("}");
+ }
+ needLineFeed = false;
+
+ if (count != 0) {
+ log.println(" FAILED");
+ } else {
+ log.println(" Passed");
+ }
+ }
+
+ /*
+ * Returns a spece-delimited hex String.
+ */
+ protected static String toHexString(String s) {
+ StringBuilder sb = new StringBuilder(" ");
+
+ for (int i = 0; i < s.length(); i++) {
+ sb.append(Integer.toHexString(s.charAt(i)));
+ sb.append(' ');
+ }
+
+ return sb.toString();
+ }
+
+ private void indent(int distance) {
+ if (needLineFeed) {
+ log.println(" {");
+ needLineFeed = false;
+ }
+ log.print(SPACES.substring(0, distance * 2));
+ }
+
+ /**
+ * Print a usage message for this test class.
+ */
+ void usage() {
+ System.out.println(getClass().getName() +
+ ": [-verbose] [-nothrow] [-exitcode] [-prompt] [test names]");
+
+ System.out.println(" Available test names:");
+ for (String methodName : testMethods.keySet()) {
+ System.out.println("\t" + methodName);
+ }
+ }
+
+ private boolean prompt;
+ private boolean nothrow;
+ protected boolean verbose;
+ private boolean exitCode;
+ private PrintWriter log;
+ private int indentLevel;
+ private boolean needLineFeed;
+ private int errorCount;
+
+ private final Map<String, Method> testMethods = new LinkedHashMap<>();
+
+ private static final String SPACES = " ";
+}
diff --git a/ojluni/src/test/java/text/testlib/TestUtils.java b/ojluni/src/test/java/text/testlib/TestUtils.java
new file mode 100644
index 00000000000..c3f582d960a
--- /dev/null
+++ b/ojluni/src/test/java/text/testlib/TestUtils.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.text.testlib;
+
+import java.text.DecimalFormatSymbols;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+import java.util.Locale.Builder;
+
+/**
+ * TestUtils provides utility methods to get a locale-dependent attribute.
+ * For example,
+ * - whether or not a non-Gregorian calendar is used
+ * - whether or not non-ASCII digits are used
+ *
+ * This class was developed to help testing for internationalization &
+ * localization and is not versatile.
+ */
+public class TestUtils {
+
+ /**
+ * Returns true if the give locale uses Gregorian calendar.
+ */
+ public static boolean usesGregorianCalendar(Locale locale) {
+ return Calendar.getInstance(locale).getClass() == GregorianCalendar.class;
+ }
+
+ /**
+ * Returns true if the given locale uses ASCII digits.
+ */
+ public static boolean usesAsciiDigits(Locale locale) {
+ return DecimalFormatSymbols.getInstance(locale).getZeroDigit() == '0';
+ }
+
+ /**
+ * Returns true if the given locale has a special variant which is treated
+ * as ill-formed in BCP 47.
+ *
+ * BCP 47 requires a variant subtag to be 5 to 8 alphanumerics or a
+ * single numeric followed by 3 alphanumerics.
+ * However, note that this methods doesn't check a variant so rigorously
+ * because this is a utility method for testing. Intended special variants
+ * are: JP, NY, and TH, which can be commonly provided by
+ * Locale.getAvailableLocales().
+ *
+ */
+ public static boolean hasSpecialVariant(Locale locale) {
+ String variant = locale.getVariant();
+ return !variant.isEmpty()
+ && "JP".equals(variant) || "NY".equals(variant) || "TH".equals(variant);
+ }
+
+}
diff --git a/ojluni/src/test/java/util/Arrays/ArrayObjectMethods.java b/ojluni/src/test/java/util/Arrays/ArrayObjectMethods.java
new file mode 100644
index 00000000000..03d19066f2c
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/ArrayObjectMethods.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4906359 6239296
+ * @summary Basic test for content-based array object methods
+ * @author Josh Bloch, Martin Buchholz
+ * @key randomness
+ */
+
+package test.java.util.Arrays;
+
+import java.util.*;
+import java.io.*;
+
+public class ArrayObjectMethods {
+ int[] sizes = {0, 10, 100, 200, 1000};
+
+ void test(String[] args) throws Throwable {
+ equal(Arrays.deepToString(null), "null");
+ equal(Arrays.deepToString(new Object[]{}), "[]");
+ equal(Arrays.deepToString(new Object[]{null}), "[null]");
+ equal(Arrays.deepToString(new Object[]{null, 1}), "[null, 1]");
+ equal(Arrays.deepToString(new Object[]{1, null}), "[1, null]");
+ equal(Arrays.deepToString(new Object[]{new Object[]{}, null}), "[[], null]");
+
+ {
+ Object[] a = {1, null};
+ a[1] = a;
+ equal(Arrays.deepToString(a), "[1, [...]]");
+ a[0] = a;
+ equal(Arrays.deepToString(a), "[[...], [...]]");
+ a[0] = a[1] = new Object[]{1, null, a};
+ equal(Arrays.deepToString(a), "[[1, null, [...]], [1, null, [...]]]");
+ }
+
+ for (int size : sizes) {
+ {
+ long[] a = Rnd.longArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ int[] a = Rnd.intArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ short[] a = Rnd.shortArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ char[] a = Rnd.charArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ byte[] a = Rnd.byteArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ boolean[] a = Rnd.booleanArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ double[] a = Rnd.doubleArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ float[] a = Rnd.floatArray(size);
+ equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
+ equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
+ }
+ {
+ Object[] a = Rnd.flatObjectArray(size);
+ equal(Arrays.toString(a), Arrays.asList(a).toString());
+ equal(Arrays.deepToString(a), Arrays.asList(a).toString());
+ equal(Arrays.hashCode(a), Arrays.asList(a).hashCode());
+ }
+
+ if (size <= 200) {
+ Object[] a = Rnd.nestedObjectArray(size);
+ List aList = deepToList(a);
+ equal(Arrays.toString(a), Arrays.asList(a).toString());
+ equal(Arrays.deepToString(a), aList.toString());
+ equal(Arrays.deepHashCode(a), aList.hashCode());
+ equal(Arrays.hashCode(a), Arrays.asList(a).hashCode());
+
+ Object[] deepCopy = (Object[]) deepCopy(a);
+ check(Arrays.deepEquals(a, deepCopy));
+ check(Arrays.deepEquals(deepCopy, a));
+
+ // Make deepCopy != a
+ if (size == 0)
+ deepCopy = new Object[] {"foo"};
+ else if (deepCopy[deepCopy.length - 1] == null)
+ deepCopy[deepCopy.length - 1] = "baz";
+ else
+ deepCopy[deepCopy.length - 1] = null;
+ check(! Arrays.deepEquals(a, deepCopy));
+ check(! Arrays.deepEquals(deepCopy, a));
+ }
+ }
+ }
+
+ // Utility method to turn an array into a list "deeply," turning
+ // all primitives into objects
+ List<Object> deepToList(Object[] a) {
+ List<Object> result = new ArrayList<Object>();
+ for (Object e : a) {
+ if (e instanceof byte[])
+ result.add(PrimitiveArrays.asList((byte[])e));
+ else if (e instanceof short[])
+ result.add(PrimitiveArrays.asList((short[])e));
+ else if (e instanceof int[])
+ result.add(PrimitiveArrays.asList((int[])e));
+ else if (e instanceof long[])
+ result.add(PrimitiveArrays.asList((long[])e));
+ else if (e instanceof char[])
+ result.add(PrimitiveArrays.asList((char[])e));
+ else if (e instanceof double[])
+ result.add(PrimitiveArrays.asList((double[])e));
+ else if (e instanceof float[])
+ result.add(PrimitiveArrays.asList((float[])e));
+ else if (e instanceof boolean[])
+ result.add(PrimitiveArrays.asList((boolean[])e));
+ else if (e instanceof Object[])
+ result.add(deepToList((Object[])e));
+ else
+ result.add(e);
+ }
+ return result;
+ }
+
+ // Utility method to do a deep copy of an object *very slowly* using
+ // serialization/deserialization
+ Object deepCopy(Object oldObj) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(oldObj);
+ oos.flush();
+ ByteArrayInputStream bin = new ByteArrayInputStream(
+ bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bin);
+ return ois.readObject();
+ } catch(Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new ArrayObjectMethods().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
+
+/**
+ * Methods to generate "interesting" random primitives and primitive
+ * arrays. Unlike Random.nextXxx, these methods return small values
+ * and boundary values (e.g., 0, -1, NaN) with greater than normal
+ * likelihood.
+ */
+
+class Rnd {
+ private static Random rnd = new Random();
+
+ public static long nextLong() {
+ switch(rnd.nextInt(10)) {
+ case 0: return 0;
+ case 1: return Long.MIN_VALUE;
+ case 2: return Long.MAX_VALUE;
+ case 3: case 4: case 5:
+ return (long) (rnd.nextInt(20) - 10);
+ default: return rnd.nextLong();
+ }
+ }
+
+ public static int nextInt() {
+ switch(rnd.nextInt(10)) {
+ case 0: return 0;
+ case 1: return Integer.MIN_VALUE;
+ case 2: return Integer.MAX_VALUE;
+ case 3: case 4: case 5:
+ return rnd.nextInt(20) - 10;
+ default: return rnd.nextInt();
+ }
+ }
+
+ public static short nextShort() {
+ switch(rnd.nextInt(10)) {
+ case 0: return 0;
+ case 1: return Short.MIN_VALUE;
+ case 2: return Short.MAX_VALUE;
+ case 3: case 4: case 5:
+ return (short) (rnd.nextInt(20) - 10);
+ default: return (short) rnd.nextInt();
+ }
+ }
+
+ public static char nextChar() {
+ switch(rnd.nextInt(10)) {
+ case 0: return 0;
+ case 1: return Character.MIN_VALUE;
+ case 2: return Character.MAX_VALUE;
+ case 3: case 4: case 5:
+ return (char) (rnd.nextInt(20) - 10);
+ default: return (char) rnd.nextInt();
+ }
+ }
+
+ public static byte nextByte() {
+ switch(rnd.nextInt(10)) {
+ case 0: return 0;
+ case 1: return Byte.MIN_VALUE;
+ case 2: return Byte.MAX_VALUE;
+ case 3: case 4: case 5:
+ return (byte) (rnd.nextInt(20) - 10);
+ default: return (byte) rnd.nextInt();
+ }
+ }
+
+ public static boolean nextBoolean() {
+ return rnd.nextBoolean();
+ }
+
+ public static double nextDouble() {
+ switch(rnd.nextInt(20)) {
+ case 0: return 0;
+ case 1: return -0.0;
+ case 2: return Double.MIN_VALUE;
+ case 3: return Double.MAX_VALUE;
+ case 4: return Double.NaN;
+ case 5: return Double.NEGATIVE_INFINITY;
+ case 6: return Double.POSITIVE_INFINITY;
+ case 7: case 8: case 9:
+ return (rnd.nextInt(20) - 10);
+ default: return rnd.nextDouble();
+ }
+ }
+
+ public static float nextFloat() {
+ switch(rnd.nextInt(20)) {
+ case 0: return 0;
+ case 1: return -0.0f;
+ case 2: return Float.MIN_VALUE;
+ case 3: return Float.MAX_VALUE;
+ case 4: return Float.NaN;
+ case 5: return Float.NEGATIVE_INFINITY;
+ case 6: return Float.POSITIVE_INFINITY;
+ case 7: case 8: case 9:
+ return (rnd.nextInt(20) - 10);
+ default: return rnd.nextFloat();
+ }
+ }
+
+ public static Object nextObject() {
+ switch(rnd.nextInt(10)) {
+ case 0: return null;
+ case 1: return "foo";
+ case 2: case 3: case 4:
+ return Double.valueOf(nextDouble());
+ default: return Integer.valueOf(nextInt());
+ }
+ }
+
+ public static long[] longArray(int length) {
+ long[] result = new long[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextLong();
+ return result;
+ }
+
+ public static int[] intArray(int length) {
+ int[] result = new int[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextInt();
+ return result;
+ }
+
+ public static short[] shortArray(int length) {
+ short[] result = new short[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextShort();
+ return result;
+ }
+
+ public static char[] charArray(int length) {
+ char[] result = new char[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextChar();
+ return result;
+ }
+
+ public static byte[] byteArray(int length) {
+ byte[] result = new byte[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextByte();
+ return result;
+ }
+
+ public static boolean[] booleanArray(int length) {
+ boolean[] result = new boolean[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextBoolean();
+ return result;
+ }
+
+ public static double[] doubleArray(int length) {
+ double[] result = new double[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextDouble();
+ return result;
+ }
+
+ public static float[] floatArray(int length) {
+ float[] result = new float[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextFloat();
+ return result;
+ }
+
+ public static Object[] flatObjectArray(int length) {
+ Object[] result = new Object[length];
+ for (int i = 0; i < length; i++)
+ result[i] = Rnd.nextObject();
+ return result;
+ }
+
+ // Calling this for length >> 100 is likely to run out of memory! It
+ // should be perhaps be tuned to allow for longer arrays
+ public static Object[] nestedObjectArray(int length) {
+ Object[] result = new Object[length];
+ for (int i = 0; i < length; i++) {
+ switch(rnd.nextInt(16)) {
+ case 0: result[i] = nestedObjectArray(length/2);
+ break;
+ case 1: result[i] = longArray(length/2);
+ break;
+ case 2: result[i] = intArray(length/2);
+ break;
+ case 3: result[i] = shortArray(length/2);
+ break;
+ case 4: result[i] = charArray(length/2);
+ break;
+ case 5: result[i] = byteArray(length/2);
+ break;
+ case 6: result[i] = floatArray(length/2);
+ break;
+ case 7: result[i] = doubleArray(length/2);
+ break;
+ case 8: result[i] = longArray(length/2);
+ break;
+ default: result[i] = Rnd.nextObject();
+ }
+ }
+ return result;
+ }
+}
+
+/**
+ * Primitive arrays viewed as lists. Inefficient but cool.
+ * This utility should be generally useful in writing regression/unit/basic
+ * tests.
+ */
+
+class PrimitiveArrays {
+ public static List<Long> asList(final long[] a) {
+ return new AbstractList<Long>() {
+ public Long get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Long set(int i, Long e) {
+ long oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Integer> asList(final int[] a) {
+ return new AbstractList<Integer>() {
+ public Integer get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Integer set(int i, Integer e) {
+ int oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Short> asList(final short[] a) {
+ return new AbstractList<Short>() {
+ public Short get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Short set(int i, Short e) {
+ short oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Character> asList(final char[] a) {
+ return new AbstractList<Character>() {
+ public Character get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Character set(int i, Character e) {
+ Character oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Byte> asList(final byte[] a) {
+ return new AbstractList<Byte>() {
+ public Byte get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Byte set(int i, Byte e) {
+ Byte oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Boolean> asList(final boolean[] a) {
+ return new AbstractList<Boolean>() {
+ public Boolean get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Boolean set(int i, Boolean e) {
+ Boolean oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Double> asList(final double[] a) {
+ return new AbstractList<Double>() {
+ public Double get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Double set(int i, Double e) {
+ Double oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+
+ public static List<Float> asList(final float[] a) {
+ return new AbstractList<Float>() {
+ public Float get(int i) { return a[i]; }
+ public int size() { return a.length; }
+
+ public Float set(int i, Float e) {
+ Float oldVal = a[i];
+ a[i] = e;
+ return oldVal;
+ }
+ };
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/ArraysEqCmpTest.java b/ojluni/src/test/java/util/Arrays/ArraysEqCmpTest.java
index 727f7dcae62..380f5b3903c 100644
--- a/ojluni/src/test/java/util/Arrays/ArraysEqCmpTest.java
+++ b/ojluni/src/test/java/util/Arrays/ArraysEqCmpTest.java
@@ -27,7 +27,7 @@ package test.java.util.Arrays;
* @bug 8033148 8141409
* @summary tests for array equals and compare
* @run testng ArraysEqCmpTest
- */
+*/
import org.testng.Assert;
import org.testng.annotations.DataProvider;
@@ -106,7 +106,7 @@ public class ArraysEqCmpTest {
if (componentType.isPrimitive()) {
cpy = l.findStatic(Arrays.class, "copyOfRange",
- MethodType.methodType(arrayType, arrayType, int.class, int.class));
+ MethodType.methodType(arrayType, arrayType, int.class, int.class));
MethodType eqt = MethodType.methodType(
boolean.class, arrayType, arrayType);
@@ -118,21 +118,21 @@ public class ArraysEqCmpTest {
String compareName = unsigned ? "compareUnsigned" : "compare";
cmp = l.findStatic(Arrays.class, compareName,
- eqt.changeReturnType(int.class));
+ eqt.changeReturnType(int.class));
cmpr = l.findStatic(Arrays.class, compareName,
- eqrt.changeReturnType(int.class));
+ eqrt.changeReturnType(int.class));
mm = l.findStatic(Arrays.class, "mismatch",
- eqt.changeReturnType(int.class));
+ eqt.changeReturnType(int.class));
mmr = l.findStatic(Arrays.class, "mismatch",
- eqrt.changeReturnType(int.class));
+ eqrt.changeReturnType(int.class));
toString = l.findStatic(Arrays.class, "toString",
- MethodType.methodType(String.class, arrayType));
+ MethodType.methodType(String.class, arrayType));
}
else {
cpy = l.findStatic(Arrays.class, "copyOfRange",
- MethodType.methodType(Object[].class, Object[].class, int.class, int.class));
+ MethodType.methodType(Object[].class, Object[].class, int.class, int.class));
MethodType eqt = MethodType.methodType(
boolean.class, Object[].class, Object[].class);
@@ -151,12 +151,12 @@ public class ArraysEqCmpTest {
cmpr = l.findStatic(Arrays.class, "compare", cmprt);
mm = l.findStatic(Arrays.class, "mismatch",
- eqt.changeReturnType(int.class));
+ eqt.changeReturnType(int.class));
mmr = l.findStatic(Arrays.class, "mismatch",
- eqrt.changeReturnType(int.class));
+ eqrt.changeReturnType(int.class));
toString = l.findStatic(Arrays.class, "toString",
- MethodType.methodType(String.class, Object[].class));
+ MethodType.methodType(String.class, Object[].class));
}
}
@@ -218,7 +218,7 @@ public class ArraysEqCmpTest {
}
boolean equals(Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
try {
return (boolean) eqr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex);
}
@@ -243,7 +243,7 @@ public class ArraysEqCmpTest {
}
int compare(Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
try {
return (int) cmpr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex);
}
@@ -268,7 +268,7 @@ public class ArraysEqCmpTest {
}
int mismatch(Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
try {
return (int) mmr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex);
}
@@ -357,7 +357,7 @@ public class ArraysEqCmpTest {
@Override
boolean equals(Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
try {
return (boolean) eqcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
}
@@ -384,7 +384,7 @@ public class ArraysEqCmpTest {
@Override
int compare(Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
try {
return (int) cmpcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
}
@@ -411,7 +411,7 @@ public class ArraysEqCmpTest {
@Override
int mismatch(Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
try {
return (int) mismatchcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
}
@@ -729,27 +729,27 @@ public class ArraysEqCmpTest {
// All nulls
testArrayType(arrayType,
- (at, s) -> {
- Object a = at.construct(s);
- for (int x = 0; x < s; x++) {
- at.set(a, x, null);
- }
- return a;
- },
- cloner);
+ (at, s) -> {
+ Object a = at.construct(s);
+ for (int x = 0; x < s; x++) {
+ at.set(a, x, null);
+ }
+ return a;
+ },
+ cloner);
// Some nulls
testArrayType(arrayType,
- (at, s) -> {
- Object a = at.construct(s);
- for (int x = 0; x < s; x++) {
- int v = x % 8;
- at.set(a, x, v == 0 ? null : v);
- }
- return a;
- },
- cloner);
+ (at, s) -> {
+ Object a = at.construct(s);
+ for (int x = 0; x < s; x++) {
+ int v = x % 8;
+ at.set(a, x, v == 0 ? null : v);
+ }
+ return a;
+ },
+ cloner);
Integer[] a = new Integer[]{null, 0};
Integer[] b = new Integer[]{0, 0};
@@ -764,37 +764,37 @@ public class ArraysEqCmpTest {
// One ref
Integer one = 1;
testArrayType(arrayType,
- (at, s) -> {
- Integer[] a = (Integer[]) at.construct(s);
- for (int x = 0; x < s; x++) {
- a[x] = one;
- }
- return a;
- },
- cloner);
+ (at, s) -> {
+ Integer[] a = (Integer[]) at.construct(s);
+ for (int x = 0; x < s; x++) {
+ a[x] = one;
+ }
+ return a;
+ },
+ cloner);
// All ref
testArrayType(arrayType,
- (at, s) -> {
- Integer[] a = (Integer[]) at.construct(s);
- for (int x = 0; x < s; x++) {
- a[x] = Integer.valueOf(s);
- }
- return a;
- },
- cloner);
+ (at, s) -> {
+ Integer[] a = (Integer[]) at.construct(s);
+ for (int x = 0; x < s; x++) {
+ a[x] = Integer.valueOf(s);
+ }
+ return a;
+ },
+ cloner);
// Some same ref
testArrayType(arrayType,
- (at, s) -> {
- Integer[] a = (Integer[]) at.construct(s);
- for (int x = 0; x < s; x++) {
- int v = x % 8;
- a[x] = v == 1 ? one : new Integer(v);
- }
- return a;
- },
- cloner);
+ (at, s) -> {
+ Integer[] a = (Integer[]) at.construct(s);
+ for (int x = 0; x < s; x++) {
+ int v = x % 8;
+ a[x] = v == 1 ? one : new Integer(v);
+ }
+ return a;
+ },
+ cloner);
}
@Test(dataProvider = "signedUnsignedArrayTypes")
@@ -835,8 +835,8 @@ public class ArraysEqCmpTest {
}
void testArrayType(ArrayType<?> at,
- BiFunction<ArrayType<?>, Integer, Object> constructor,
- BiFunction<ArrayType<?>, Object, Object> cloner) {
+ BiFunction<ArrayType<?>, Integer, Object> constructor,
+ BiFunction<ArrayType<?>, Object, Object> cloner) {
int n = arraySizeFor(at.componentType);
for (int s : ranges(0, n)) {
@@ -944,7 +944,7 @@ public class ArraysEqCmpTest {
}
static boolean isEqual(ArrayType<?> at, Object a, int aFromIndex, int aToIndex,
- Object b, int bFromIndex, int bToIndex) {
+ Object b, int bFromIndex, int bToIndex) {
int aLength = aToIndex - aFromIndex;
int bLength = bToIndex - bFromIndex;
if (aLength != bLength)
@@ -1079,7 +1079,7 @@ public class ArraysEqCmpTest {
for (int bFrom : froms) {
for (int bTo : tos) {
if (aFrom >= 0 && aTo <= s &&
- bFrom >= 0 && bTo <= s) continue;
+ bFrom >= 0 && bTo <= s) continue;
testAIOBE(() -> arrayType.equals(a, aFrom, aTo, a, bFrom, bTo));
testAIOBE(() -> arrayType.compare(a, aFrom, aTo, a, bFrom, bTo));
diff --git a/ojluni/src/test/java/util/Arrays/AsList.java b/ojluni/src/test/java/util/Arrays/AsList.java
new file mode 100644
index 00000000000..6376edf6f88
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/AsList.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8155600
+ * @summary Tests for Arrays.asList()
+ * @run testng AsList
+ */
+
+package test.java.util.Arrays;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.stream.IntStream;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+public class AsList {
+ /*
+ * Iterator contract test
+ */
+ @Test(dataProvider = "Arrays")
+ public void testIterator(Object[] array) {
+ Iterator<Object> itr = Arrays.asList(array).iterator();
+ for (int i = 0; i < array.length; i++) {
+ assertTrue(itr.hasNext());
+ assertTrue(itr.hasNext()); // must be idempotent
+ assertSame(array[i], itr.next());
+ try {
+ itr.remove();
+ fail("Remove must throw");
+ } catch (UnsupportedOperationException ex) {
+ // expected
+ }
+ }
+ assertFalse(itr.hasNext());
+ for (int i = 0; i < 3; i++) {
+ assertFalse(itr.hasNext());
+ try {
+ itr.next();
+ fail("Next succeed when there's no data left");
+ } catch (NoSuchElementException ex) {
+ // expected
+ }
+ }
+ }
+
+ @DataProvider(name = "Arrays")
+ public static Object[][] arrays() {
+ Object[][] arrays = {
+ { new Object[] { } },
+ { new Object[] { 1 } },
+ { new Object[] { null } },
+ { new Object[] { null, 1 } },
+ { new Object[] { 1, null } },
+ { new Object[] { null, null } },
+ { new Object[] { null, 1, 2 } },
+ { new Object[] { 1, null, 2 } },
+ { new Object[] { 1, 2, null } },
+ { new Object[] { null, null, null } },
+ { new Object[] { 1, 2, 3, null, 4 } },
+ { new Object[] { "a", "a", "a", "a" } },
+ { IntStream.range(0, 100).boxed().toArray() }
+ };
+
+ return arrays;
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/CopyMethods.java b/ojluni/src/test/java/util/Arrays/CopyMethods.java
new file mode 100644
index 00000000000..37ac5f54fb4
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/CopyMethods.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4655503
+ * @summary Test for array cloning and slicing methods.
+ * @author John Rose
+ * @key randomness
+ */
+
+package test.java.util.Arrays;
+
+import java.util.*;
+import java.lang.reflect.*;
+
+public class CopyMethods {
+ static int muzzle; // if !=0, suppresses ("muzzles") messages
+
+ static int maxLen = 40; // maximum length of test arrays
+ static int shortStepsNear = 4; // interesting span near critical values
+ static int downShift = 3;
+
+ static int testCasesRun = 0;
+ static long consing = 0;
+
+ // very simple tests, mainly to test the framework itself
+ static void simpleTests() {
+ int[] a = (int[]) makeArray(3, int.class);
+ if (muzzle == 0)
+ System.out.println("int[] a = "+Arrays.toString(a));
+ check(a.length == 3);
+ check(a[0] == testValues[0]);
+ check(a[1] == testValues[1]);
+ check(a[2] == testValues[2]);
+ checkArray(a, int.class, 3, 0, 3);
+ // negative test of testing framework:
+ for (int bad = -2; bad < a.length; bad++) {
+ try {
+ int[] aa = a.clone();
+ if (bad < 0) aa = new int[4];
+ else aa[bad] = 0;
+ ++muzzle;
+ // the following check should fail!
+ if (bad == -2)
+ checkArray(new String[3], int.class, 0, 0, a.length);
+ else
+ checkArray(aa, int.class, 0, 0, a.length);
+ throw new Error("Should Not Reach Here");
+ } catch (RuntimeException ee) {
+ --muzzle;
+ if (muzzle == 0)
+ System.out.println("Expected: "+ee);
+ }
+ }
+ checkArray(Arrays.copyOf(a, 0), int.class, 0, 0, 3);
+ checkArray(Arrays.copyOf(a, 1), int.class, 1, 0, 3);
+ checkArray(Arrays.copyOf(a, 2), int.class, 2, 0, 3);
+ checkArray(Arrays.copyOf(a, 3), int.class, 3, 0, 3);
+ checkArray(Arrays.copyOf(a, 4), int.class, 4, 0, 3);
+
+ // quick test of copyOfRange
+ int[] ar = Arrays.copyOfRange(a, 1, 3);
+ check(ar.length == 2);
+ check(ar[0] == a[1]);
+ check(ar[1] == a[2]);
+ checkArray(ar, int.class, 2, 1, 2);
+ ar = Arrays.copyOfRange(a, 2, 4);
+ check(ar.length == 2);
+ check(ar[0] == a[2]);
+ check(ar[1] == 0);
+ checkArray(ar, int.class, 2, 2, 1);
+ ar = Arrays.copyOfRange(a, 3, 5);
+ check(ar.length == 2);
+ check(ar[0] == 0);
+ check(ar[1] == 0);
+ checkArray(ar, int.class, 2, 3, 0);
+ byte[] ba = (byte[]) makeArray(3, byte.class);
+ if (muzzle == 0)
+ System.out.println("byte[] ba = "+Arrays.toString(ba));
+ for (int j = 0; j <= ba.length+2; j++) {
+ byte[] bb = Arrays.copyOf(ba, j);
+ if (muzzle == 0)
+ System.out.println("copyOf(ba,"+j+") = "+
+ Arrays.toString(bb));
+ checkArray(bb, byte.class, j, 0, ba.length);
+ byte[] bbr = Arrays.copyOfRange(ba, 0, j);
+ check(Arrays.equals(bb, bbr));
+ }
+ for (int i = 0; i <= a.length; i++) {
+ for (int j = i; j <= a.length+2; j++) {
+ byte[] br = Arrays.copyOfRange(ba, i, j);
+ if (muzzle == 0)
+ System.out.println("copyOfRange(ba,"+i+","+j+") = "+
+ Arrays.toString(br));
+ checkArray(br, byte.class, j-i, i, ba.length-i);
+ }
+ }
+ String[] sa = (String[]) makeArray(3, String.class);
+ if (muzzle == 0)
+ System.out.println("String[] sa = "+Arrays.toString(sa));
+ check(sa[0].equals(Integer.toHexString(testValues[0])));
+ check(sa[1].equals(Integer.toHexString(testValues[1])));
+ check(sa[2].equals(Integer.toHexString(testValues[2])));
+ checkArray(sa, String.class, sa.length, 0, sa.length);
+ String[] sa4 = Arrays.copyOf(sa, sa.length+1);
+ check(sa4[0] == sa[0]);
+ check(sa4[1] == sa[1]);
+ check(sa4[2] == sa[2]);
+ check(sa4[sa.length] == null);
+ checkArray(sa4, String.class, sa4.length, 0, sa.length);
+ String[] sr4 = Arrays.copyOfRange(sa, 1, 5);
+ check(sr4[0] == sa[1]);
+ check(sr4[1] == sa[2]);
+ check(sr4[2] == null);
+ check(sr4[3] == null);
+ checkArray(sr4, String.class, 4, 1, sa.length-1);
+ if (muzzle == 0)
+ System.out.println("simpleTests done");
+ }
+
+ // the framework: a fixed series of test values
+ static final int[] testValues;
+ static {
+ testValues = new int[1000];
+ Random r = new Random();
+ for (int i = 0; i < testValues.length; i++) {
+ testValues[i] = r.nextInt();
+ }
+ }
+ /** Return a canonical test value of a desired index and type.
+ * The original test values are random ints. Derive other test
+ * values as follows:
+ * <pre>
+ * int tv = testValues[i]
+ * (C)tv C is byte, short, char, long, float, double
+ * (tv&1)!=0 C is boolean
+ * (Integer)tv C is Object and tv%16 != 0
+ * null C is Object and tv%16 == 0
+ * Integer.toHexString(tv) C is String and tv != 0
+ * null C is String and tv == 0
+ * </pre>
+ * are derived by ordinary Java coercions, except that boolean
+ * samples the LSB of the int value, and String is the hex numeral.
+ *
+ * (Also, the 0th String is null, and the 0th Object mod 16 is null,
+ * regardless of the original int test value.)
+ */
+ static Object testValue(int i, Class<?> c) {
+ int tv = testValues[i % testValues.length];
+ if (i >= testValues.length) tv ^= i;
+ // Turn the canonical int to a float, boolean, String, whatever:
+ return invoke(coercers.get(c), tv);
+ }
+ /** Build a test array of the given length,
+ * packed with a subsequence of the test values.
+ * The first element of the array is always testValue(0).
+ */
+ static Object makeArray(int len, Class<?> c) {
+ Object a = Array.newInstance(c, len);
+ for (int i = 0; i < len; i++) {
+ Array.set(a, i, testValue(i, c));
+ }
+ return a;
+ }
+ /** Check that the given array has the required length.
+ * Check also that it is packed, up to firstNull, with
+ * a particular subsequence of the canonical test values.
+ * The subsequence must begin with a[0] == testValue(offset).
+ * At a[firstNull] and beyond, the array must contain null values.
+ */
+ static void checkArray(Object a, Class<?> c, int requiredLen, int offset, int firstNull) {
+ check(c == a.getClass().getComponentType());
+ Object nullValue = nullValues.get(c);
+ // Note: asserts in here are not part of the test program.
+ // They verify the integrity of the test method itself.
+ assert(nullValues.containsKey(c));
+
+ int misses = 0;
+ int firstMiss = -1;
+ // Check required length first.
+ int length = Array.getLength(a);
+ if (length != requiredLen && requiredLen != -1) {
+ if (muzzle == 0)
+ System.out.println("*** a.length = "+length+" != "+requiredLen);
+ ++misses;
+ }
+
+ for (int i = 0; i < length; i++) {
+ Object tv = (i >= firstNull) ? nullValue : testValue(i+offset, c);
+ Object ai = Array.get(a, i);
+ if (!eq(ai, tv)) {
+ if (muzzle == 0)
+ System.out.println("*** a["+i+"] = "+ai+" != "+tv);
+ if (misses == 0) firstMiss = i;
+ if (++misses > 10) break;
+ }
+ }
+ if (misses != 0) {
+ Method toString = toStrings.get(c);
+ if (toString == null) toString = toStrings.get(Object.class);
+ throw new RuntimeException("checkArray failed at "+firstMiss
+ +" "+c+"[]"
+ +" : "+invoke(toString, a));
+ }
+ }
+ // Typical comparison helper. Why isn't this a method somewhere.
+ static boolean eq(Object x, Object y) {
+ return x == null? y == null: x.equals(y);
+ }
+ // Exception-ignoring invoke function.
+ static Object invoke(Method m, Object... args) {
+ Exception ex;
+ try {
+ return m.invoke(null, args);
+ } catch (InvocationTargetException ee) {
+ ex = ee;
+ } catch (IllegalAccessException ee) {
+ ex = ee;
+ } catch (IllegalArgumentException ee) {
+ ex = ee;
+ }
+ ArrayList<Object> call = new ArrayList<Object>();
+ call.add(m); Collections.addAll(call, args);
+ throw new RuntimeException(call+" : "+ex);
+ }
+ // version of assert() that runs unconditionally
+ static void check(boolean z) {
+ if (!z) throw new RuntimeException("check failed");
+ }
+
+
+ /** Run about 10**5 distinct parameter combinations
+ * on copyOf and copyOfRange. Use all primitive types,
+ * and String and Object.
+ * Try to all critical values, looking for fencepost errors.
+ */
+ static void fullTests(int maxLen, Class<?> c) {
+ Method cloner = cloners.get(c);
+ assert(cloner != null) : c;
+ Method cloneRanger = cloneRangers.get(c);
+ // Note: asserts in here are not part of the test program.
+ // They verify the integrity of the test method itself.
+ assert(cloneRanger != null) : c;
+ for (int src = 0; src <= maxLen; src = inc(src, 0, maxLen)) {
+ Object a = makeArray(src, c);
+ for (int x : new ArrayList<Integer>()) {}
+ for (int j = 0; j <= maxLen; j = inc(j, src, maxLen)) {
+ // b = Arrays.copyOf(a, j);
+ Object b = invoke(cloner, a, j);
+ checkArray(b, c, j, 0, src);
+ testCasesRun++;
+ consing += j;
+
+ int maxI = Math.min(src, j);
+ for (int i = 0; i <= maxI; i = inc(i, src, maxI)) {
+ // r = Arrays.copyOfRange(a, i, j);
+ Object r = invoke(cloneRanger, a, i, j);
+ checkArray(r, c, j-i, i, src-i);
+ //System.out.println("case c="+c+" src="+src+" i="+i+" j="+j);
+ testCasesRun++;
+ consing += j-i;
+ }
+ }
+ }
+ }
+ // Increment x by at least one. Increment by a little more unless
+ // it is near a critical value, either zero, crit1, or crit2.
+ static int inc(int x, int crit1, int crit2) {
+ int D = shortStepsNear;
+ if (crit1 > crit2) { int t = crit1; crit1 = crit2; crit2 = t; }
+ assert(crit1 <= crit2);
+ assert(x <= crit2); // next1 or next2 must be the limit value
+ x += 1;
+ if (x > D) {
+ if (x < crit1-D) {
+ x += (x << 1) >> downShift; // giant step toward crit1-D
+ if (x > crit1-D) x = crit1-D;
+ } else if (x >= crit1+D && x < crit2-D) {
+ x += (x << 1) >> downShift; // giant step toward crit2-D
+ if (x > crit2-D) x = crit2-D;
+ }
+ }
+ return x;
+ }
+
+ public static void main(String[] av) {
+ boolean verbose = (av.length != 0);
+ muzzle = (verbose? 0: 1);
+ if (muzzle == 0)
+ System.out.println("test values: "+Arrays.toString(Arrays.copyOf(testValues, 5))+"...");
+
+ simpleTests();
+
+ muzzle = 0; // turn on print statements (affects failures only)
+
+ fullTests();
+ if (verbose)
+ System.out.println("ran "+testCasesRun+" tests, avg len="
+ +(float)consing/testCasesRun);
+
+ // test much larger arrays, more sparsely
+ maxLen = 500;
+ shortStepsNear = 2;
+ downShift = 0;
+ testCasesRun = 0;
+ consing = 0;
+ fullTests();
+ if (verbose)
+ System.out.println("ran "+testCasesRun+" tests, avg len="
+ +(float)consing/testCasesRun);
+ }
+
+ static void fullTests() {
+ for (Class<?> c : allTypes) {
+ fullTests(maxLen, c);
+ }
+ }
+
+ // We must run all the our tests on each of 8 distinct primitive types,
+ // and two reference types (Object, String) for good measure.
+ // This would be a pain to write out by hand, statically typed.
+ // So, use reflection. Following are the tables of methods we use.
+ // (The initial simple tests exercise enough of the static typing
+ // features of the API to ensure that they compile as advertised.)
+
+ static Object coerceToObject(int x) { return (x & 0xF) == 0? null: new Integer(x); }
+ static String coerceToString(int x) { return (x == 0)? null: Integer.toHexString(x); }
+ static Integer coerceToInteger(int x) { return (x == 0)? null: x; }
+ static byte coerceToByte(int x) { return (byte)x; }
+ static short coerceToShort(int x) { return (short)x; }
+ static int coerceToInt(int x) { return x; }
+ static long coerceToLong(int x) { return x; }
+ static char coerceToChar(int x) { return (char)x; }
+ static float coerceToFloat(int x) { return x; }
+ static double coerceToDouble(int x) { return x; }
+ static boolean coerceToBoolean(int x) { return (x&1) != 0; }
+
+ static Integer[] copyOfIntegerArray(Object[] a, int len) {
+ // This guy exercises the API based on a type-token.
+ // Note the static typing.
+ return Arrays.copyOf(a, len, Integer[].class);
+ }
+ static Integer[] copyOfIntegerArrayRange(Object[] a, int m, int n) {
+ // This guy exercises the API based on a type-token.
+ // Note the static typing.
+ return Arrays.copyOfRange(a, m, n, Integer[].class);
+ }
+
+ static final List<Class<?>> allTypes
+ = Arrays.asList(new Class<?>[]
+ { Object.class, String.class, Integer.class,
+ byte.class, short.class, int.class, long.class,
+ char.class, float.class, double.class,
+ boolean.class
+ });
+ static final HashMap<Class<?>,Method> coercers;
+ static final HashMap<Class<?>,Method> cloners;
+ static final HashMap<Class<?>,Method> cloneRangers;
+ static final HashMap<Class<?>,Method> toStrings;
+ static final HashMap<Class<?>,Object> nullValues;
+ static {
+ coercers = new HashMap<Class<?>,Method>();
+ Method[] testMethods = CopyMethods.class.getDeclaredMethods();
+ Method cia = null, ciar = null;
+ for (int i = 0; i < testMethods.length; i++) {
+ Method m = testMethods[i];
+ if (!Modifier.isStatic(m.getModifiers())) continue;
+ Class<?> rt = m.getReturnType();
+ if (m.getName().startsWith("coerceTo") && allTypes.contains(rt))
+ coercers.put(m.getReturnType(), m);
+ if (m.getName().equals("copyOfIntegerArray"))
+ cia = m;
+ if (m.getName().equals("copyOfIntegerArrayRange"))
+ ciar = m;
+ }
+ Method[] arrayMethods = Arrays.class.getDeclaredMethods();
+ cloners = new HashMap<Class<?>,Method>();
+ cloneRangers = new HashMap<Class<?>,Method>();
+ toStrings = new HashMap<Class<?>,Method>();
+ for (int i = 0; i < arrayMethods.length; i++) {
+ Method m = arrayMethods[i];
+ if (!Modifier.isStatic(m.getModifiers())) continue;
+ Class<?> rt = m.getReturnType();
+ if (m.getName().equals("copyOf")
+ && m.getParameterTypes().length == 2)
+ cloners.put(rt.getComponentType(), m);
+ if (m.getName().equals("copyOfRange")
+ && m.getParameterTypes().length == 3)
+ cloneRangers.put(rt.getComponentType(), m);
+ if (m.getName().equals("toString")) {
+ Class<?> pt = m.getParameterTypes()[0];
+ toStrings.put(pt.getComponentType(), m);
+ }
+ }
+ cloners.put(String.class, cloners.get(Object.class));
+ cloneRangers.put(String.class, cloneRangers.get(Object.class));
+ assert(cia != null);
+ cloners.put(Integer.class, cia);
+ assert(ciar != null);
+ cloneRangers.put(Integer.class, ciar);
+ nullValues = new HashMap<Class<?>,Object>();
+ for (Class<?> c : allTypes) {
+ nullValues.put(c, invoke(coercers.get(c), 0));
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/Correct.java b/ojluni/src/test/java/util/Arrays/Correct.java
new file mode 100644
index 00000000000..1c4ddcd0457
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/Correct.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4726380 8037097
+ * @summary Check that different sorts give equivalent results.
+ * @run testng Correct
+ * @key randomness
+ */
+
+package test.java.util.Arrays;
+
+import java.util.*;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.fail;
+import static org.testng.Assert.assertEquals;
+
+public class Correct {
+
+ static final Random rnd = new Random();
+ static final int ITERATIONS = 1000;
+ static final int TEST_SIZE = 1000;
+
+ @Test
+ public void testDefaultSort() {
+ for (int i=0; i<ITERATIONS; i++) {
+ int size = rnd.nextInt(TEST_SIZE) + 1;
+ Integer[] array1 = getIntegerArray(size);
+ Integer[] array2 = Arrays.copyOf(array1, array1.length);
+ Arrays.sort(array1, array1.length/3, array1.length/2);
+ stupidSort(array2, array2.length/3, array2.length/2);
+ assertEquals(array1, array2, "Arrays did not match. size=" + size);
+ }
+ }
+
+ @Test(dataProvider = "Comparators")
+ public void testComparatorSort(Comparator<Integer> comparator) {
+ for (int i=0; i<ITERATIONS; i++) {
+ int size = rnd.nextInt(TEST_SIZE) + 1;
+ Integer[] array1 = getIntegerArray(size);
+ Integer[] array2 = Arrays.copyOf(array1, array1.length);
+ Arrays.sort(array1, array1.length/3, array1.length/2, comparator);
+ stupidSort(array2, array2.length/3, array2.length/2, comparator);
+ assertEquals(array1, array2, "Arrays did not match. size=" + size);
+ }
+ }
+
+ static Integer[] getIntegerArray(int size) {
+ Integer[] blah = new Integer[size];
+ for (int x=0; x<size; x++) {
+ blah[x] = new Integer(rnd.nextInt());
+ }
+ return blah;
+ }
+
+ static void stupidSort(Integer[] a1, int from, int to) {
+ if (from > to - 1 )
+ return;
+
+ for (int x=from; x<to; x++) {
+ Integer lowest = a1[x];
+ int lowestIndex = x;
+ for (int y=x + 1; y<to; y++) {
+ if (((Comparable)a1[y]).compareTo((Comparable)lowest) < 0) {
+ lowest = a1[y];
+ lowestIndex = y;
+ }
+ }
+ if (lowestIndex != x) {
+ swap(a1, x, lowestIndex);
+ }
+ }
+ }
+
+ static void stupidSort(Integer[] a1, int from, int to, Comparator<Integer> comparator) {
+ if (from > to - 1 )
+ return;
+
+ for (int x=from; x<to; x++) {
+ Integer lowest = a1[x];
+ int lowestIndex = x;
+ for (int y=x + 1; y<to; y++) {
+ if (comparator.compare(a1[y], lowest) < 0) {
+ lowest = a1[y];
+ lowestIndex = y;
+ }
+ }
+ if (lowestIndex != x) {
+ swap(a1, x, lowestIndex);
+ }
+ }
+ }
+
+ static <T> void swap(T[] x, int a, int b) {
+ T t = x[a];
+ x[a] = x[b];
+ x[b] = t;
+ }
+
+ @DataProvider(name = "Comparators", parallel = true)
+ public static Iterator<Object[]> comparators() {
+ Object[][] comparators = new Object[][] {
+ new Object[] { Comparator.naturalOrder() },
+ new Object[] { Comparator.<Integer>naturalOrder().reversed() },
+ new Object[] { STANDARD_ORDER },
+ new Object[] { STANDARD_ORDER.reversed() },
+ new Object[] { REVERSE_ORDER },
+ new Object[] { REVERSE_ORDER.reversed() },
+ new Object[] { Comparator.comparingInt(Integer::intValue) }
+ };
+
+ return Arrays.asList(comparators).iterator();
+ }
+
+ private static final Comparator<Integer> STANDARD_ORDER = new Comparator<Integer>() {
+ public int compare(Integer o1, Integer o2) {
+ return o1.compareTo(o2);
+ }
+ };
+
+ private static final Comparator<Integer> REVERSE_ORDER = new Comparator<Integer>() {
+ public int compare(Integer o1, Integer o2) {
+ return - o1.compareTo(o2);
+ }
+ };
+}
diff --git a/ojluni/src/test/java/util/Arrays/Fill.java b/ojluni/src/test/java/util/Arrays/Fill.java
new file mode 100644
index 00000000000..930c0b0b258
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/Fill.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4229892
+ * @summary Arrays.fill(Object[], ...) should throw ArrayStoreException
+ * @author Martin Buchholz
+ */
+
+package test.java.util.Arrays;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+@SuppressWarnings("ArrayFillIncompatibleType")
+public class Fill {
+ private static void realMain(String[] args) throws Throwable {
+ try {
+ Arrays.fill(new Integer[3], "foo");
+ fail("Expected ArrayStoreException");
+ }
+ catch (ArrayStoreException e) { pass(); }
+ catch (Throwable t) { unexpected(t); }
+
+ try {
+ Arrays.fill(new Integer[3], 0, 2, "foo");
+ fail("Expected ArrayStoreException");
+ }
+ catch (ArrayStoreException e) { pass(); }
+ catch (Throwable t) { unexpected(t); }
+
+ try {
+ Arrays.fill(new Integer[3], 0, 4, "foo");
+ fail("Expected ArrayIndexOutOfBoundsException");
+ }
+ catch (ArrayIndexOutOfBoundsException e) { pass(); }
+ catch (Throwable t) { unexpected(t); }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/ojluni/src/test/java/util/Arrays/FloatDoubleOrder.java b/ojluni/src/test/java/util/Arrays/FloatDoubleOrder.java
new file mode 100644
index 00000000000..af721e3a4d4
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/FloatDoubleOrder.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4143272 6548425
+ * @summary The natural ordering on Float and Double was not even a partial
+ * order (i.e., it violated the contract of Comparable.compareTo).
+ * Now it's a total ordering. Arrays.sort(double[])
+ * and Arrays.sort(double[]) reflect the new ordering. Also,
+ * Arrays.equals(double[], double[]) and
+ * Arrays.equals(float[], float[]) reflect the definition of
+ * equality used by Float and Double.
+ */
+
+package test.java.util.Arrays;
+
+import java.util.*;
+
+@SuppressWarnings("unchecked")
+public class FloatDoubleOrder {
+ void test(String[] args) throws Throwable {
+ double[] unsortedDbl = new double[] {1.0d, 3.7d, Double.NaN, -2.0d,
+ Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0d, -0.0d};
+
+ double[] sortedDbl = new double[] {Double.NEGATIVE_INFINITY, -2.0d,
+ -0.0d, 0.0d, 1.0d, 3.7d, Double.POSITIVE_INFINITY, Double.NaN};
+
+ List list = new ArrayList();
+ for (int i=0; i<unsortedDbl.length; i++)
+ list.add(new Double(unsortedDbl[i]));
+ Collections.sort(list);
+
+ List sortedList = new ArrayList();
+ for (int i=0; i<sortedDbl.length; i++)
+ sortedList.add(new Double(sortedDbl[i]));
+
+ check(list.equals(sortedList));
+
+ Arrays.sort(unsortedDbl);
+ check(Arrays.equals(unsortedDbl, sortedDbl));
+
+ double negNan = Double.longBitsToDouble(0xfff8000000000000L);
+ for (int i = 0; i < sortedDbl.length; i++) {
+ equal(Arrays.binarySearch(sortedDbl, sortedDbl[i]), i);
+ if (Double.isNaN(sortedDbl[i]))
+ equal(Arrays.binarySearch(sortedDbl, negNan), i);
+ }
+
+ float[] unsortedFlt = new float[] {1.0f, 3.7f, Float.NaN, -2.0f,
+ Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0f, -0.0f};
+
+ float[] sortedFlt = new float[] {Float.NEGATIVE_INFINITY, -2.0f,
+ -0.0f, 0.0f, 1.0f, 3.7f, Float.POSITIVE_INFINITY, Float.NaN};
+
+ list.clear();
+ for (int i=0; i<unsortedFlt.length; i++)
+ list.add(new Float(unsortedFlt[i]));
+ Collections.sort(list);
+
+ sortedList.clear();
+ for (int i=0; i<sortedFlt.length; i++)
+ sortedList.add(new Float(sortedFlt[i]));
+
+ check(list.equals(sortedList));
+
+ Arrays.sort(unsortedFlt);
+ check(Arrays.equals(unsortedFlt, sortedFlt));
+
+ float negNaN = Float.intBitsToFloat(0xFfc00000);
+ for (int i = 0; i < sortedDbl.length; i++) {
+ equal(Arrays.binarySearch(sortedFlt, sortedFlt[i]), i);
+ if (Float.isNaN(sortedFlt[i]))
+ equal(Arrays.binarySearch(sortedFlt, negNaN), i);
+ }
+
+
+ // 6548425: Arrays.sort incorrectly sorts a double array
+ // containing negative zeros
+ double[] da = {-0.0d, -0.0d, 0.0d, -0.0d};
+ Arrays.sort(da, 1, 4);
+ check(Arrays.equals(da, new double[] {-0.0d, -0.0d, -0.0d, 0.0d}));
+
+ float[] fa = {-0.0f, -0.0f, 0.0f, -0.0f};
+ Arrays.sort(fa, 1, 4);
+ check(Arrays.equals(fa, new float[] {-0.0f, -0.0f, -0.0f, 0.0f}));
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new FloatDoubleOrder().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/ojluni/src/test/java/util/Arrays/SetAllTest.java b/ojluni/src/test/java/util/Arrays/SetAllTest.java
new file mode 100644
index 00000000000..b0692cb5652
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/SetAllTest.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8012650
+ * @summary Unit test for setAll, parallelSetAll variants
+ * @run testng SetAllTest
+ */
+
+package test.java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.function.IntFunction;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.fail;
+
+@Test
+public class SetAllTest {
+ private static final IntFunction<String> toString = i -> "N" + Integer.valueOf(i);
+ private static final IntFunction<String> fillString = i -> "X";
+ private static final String[] r0 = {};
+ private static final String[] r1 = { "N0" };
+ private static final String[] r10 = { "N0", "N1", "N2", "N3", "N4", "N5", "N6", "N7", "N8", "N9" };
+
+ private Object[][] stringData = new Object[][] {
+ { "empty", 0, toString, r0 },
+ { "one", 1, toString, r1 },
+ { "ten", 10, toString, r10 },
+ { "fill", 3, fillString, new String[] { "X", "X", "X" }}
+ };
+
+ private static final IntUnaryOperator toInt = i -> i << 1;
+ private static final IntUnaryOperator fillInt = i -> 99;
+ private static final int[] ir0 = {};
+ private static final int[] ir1 = { 0 };
+ private static final int[] ir10 = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 };
+ private Object[][] intData = new Object[][] {
+ { "empty", 0, toInt, ir0 },
+ { "one", 1, toInt, ir1 },
+ { "ten", 10, toInt, ir10 },
+ { "fill", 3, fillInt, new int[] { 99, 99, 99 }}
+ };
+
+ private static final IntToLongFunction toLong = i -> i << 1;
+ private static final IntToLongFunction fillLong = i -> 9999L;
+ private static final long[] lr0 = {};
+ private static final long[] lr1 = { 0L };
+ private static final long[] lr10 = { 0L, 2L, 4L, 6L, 8L, 10L, 12L, 14L, 16L, 18L };
+ private Object[][] longData = new Object[][] {
+ { "empty", 0, toLong, lr0 },
+ { "one", 1, toLong, lr1 },
+ { "ten", 10, toLong, lr10 },
+ { "fill", 3, fillLong, new long[] { 9999L, 9999L, 9999L }}
+ };
+
+ private static final IntToDoubleFunction toDouble = i -> i * 1.1;
+ private static final IntToDoubleFunction fillDouble = i -> 3.14;
+ private static final double[] dr0 = {};
+ private static final double[] dr1 = { 0.0 };
+ private static final double[] dr10 = { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
+ private Object[][] doubleData = new Object[][] {
+ { "empty", 0, toDouble, dr0 },
+ { "one", 1, toDouble, dr1 },
+ { "ten", 10, toDouble, dr10 },
+ { "fill", 3, fillDouble, new double[] { 3.14, 3.14, 3.14 }}
+ };
+
+ @DataProvider(name="string")
+ public Object[][] stringTests() { return stringData; }
+
+ @DataProvider(name="int")
+ public Object[][] intTests() { return intData; }
+
+ @DataProvider(name="long")
+ public Object[][] longTests() { return longData; }
+
+ @DataProvider(name="double")
+ public Object[][] doubleTests() { return doubleData; }
+
+ @Test(dataProvider = "string")
+ public void testSetAllString(String name, int size, IntFunction<String> generator, String[] expected) {
+ String[] result = new String[size];
+ Arrays.setAll(result, generator);
+ assertEquals(result, expected, "setAll(String[], IntFunction<String>) case " + name + " failed.");
+
+ // ensure fresh array
+ result = new String[size];
+ Arrays.parallelSetAll(result, generator);
+ assertEquals(result, expected, "parallelSetAll(String[], IntFunction<String>) case " + name + " failed.");
+ }
+
+ @Test(dataProvider = "int")
+ public void testSetAllInt(String name, int size, IntUnaryOperator generator, int[] expected) {
+ int[] result = new int[size];
+ Arrays.setAll(result, generator);
+ assertEquals(result, expected, "setAll(int[], IntUnaryOperator) case " + name + " failed.");
+
+ // ensure fresh array
+ result = new int[size];
+ Arrays.parallelSetAll(result, generator);
+ assertEquals(result, expected, "parallelSetAll(int[], IntUnaryOperator) case " + name + " failed.");
+ }
+
+ @Test(dataProvider = "long")
+ public void testSetAllLong(String name, int size, IntToLongFunction generator, long[] expected) {
+ long[] result = new long[size];
+ Arrays.setAll(result, generator);
+ assertEquals(result, expected, "setAll(long[], IntToLongFunction) case " + name + " failed.");
+
+ // ensure fresh array
+ result = new long[size];
+ Arrays.parallelSetAll(result, generator);
+ assertEquals(result, expected, "parallelSetAll(long[], IntToLongFunction) case " + name + " failed.");
+ }
+
+ private void assertDoubleArrayEquals(double[] actual, double[] expected, double delta, String msg) {
+ if (actual.length != expected.length) {
+ fail(msg + ": length mismatch, expected " + expected.length + ", got " + actual.length);
+ }
+
+ for (int i = 0; i < actual.length; i++) {
+ assertEquals(actual[i], expected[i], delta, msg + "(mismatch at index " + i + ")");
+ }
+ }
+
+ @Test(dataProvider = "double")
+ public void testSetAllDouble(String name, int size, IntToDoubleFunction generator, double[] expected) {
+ double[] result = new double[size];
+ Arrays.setAll(result, generator);
+ assertDoubleArrayEquals(result, expected, 0.05, "setAll(double[], IntToDoubleFunction) case " + name + " failed.");
+
+ // ensure fresh array
+ result = new double[size];
+ Arrays.parallelSetAll(result, generator);
+ assertDoubleArrayEquals(result, expected, 0.05, "setAll(double[], IntToDoubleFunction) case " + name + " failed.");
+ }
+
+ @Test
+ public void testStringSetNulls() {
+ String[] ar = new String[2];
+ try {
+ Arrays.setAll(null, (IntFunction<String>) i -> "X");
+ fail("Arrays.setAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(null, (IntFunction<String>) i -> "X");
+ fail("Arrays.parallelSetAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.setAll(ar, null);
+ fail("Arrays.setAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(ar, null);
+ fail("Arrays.parallelSetAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testIntSetNulls() {
+ int[] ar = new int[2];
+ try {
+ Arrays.setAll(null, (IntUnaryOperator) i -> i);
+ fail("Arrays.setAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(null, (IntUnaryOperator) i -> i);
+ fail("Arrays.parallelSetAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.setAll(ar, null);
+ fail("Arrays.setAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(ar, null);
+ fail("Arrays.parallelSetAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testLongSetNulls() {
+ long[] ar = new long[2];
+ try {
+ Arrays.setAll(null, (IntToLongFunction) i -> Long.MAX_VALUE);
+ fail("Arrays.setAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(null, (IntToLongFunction) i -> Long.MAX_VALUE);
+ fail("Arrays.parallelSetAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.setAll(ar, null);
+ fail("Arrays.setAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(ar, null);
+ fail("Arrays.parallelSetAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testDoubleSetNulls() {
+ double[] ar = new double[2];
+ try {
+ Arrays.setAll(null, (IntToDoubleFunction) i -> Math.E);
+ fail("Arrays.setAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(null, (IntToDoubleFunction) i -> Math.E);
+ fail("Arrays.parallelSetAll(null, foo) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.setAll(ar, null);
+ fail("Arrays.setAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ try {
+ Arrays.parallelSetAll(ar, null);
+ fail("Arrays.parallelSetAll(array, null) should throw NPE");
+ } catch (NullPointerException npe) {
+ // expected
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/Sorting.java b/ojluni/src/test/java/util/Arrays/Sorting.java
new file mode 100644
index 00000000000..c025da9e919
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/Sorting.java
@@ -0,0 +1,2069 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @compile/module=java.base java/util/SortingHelper.java
+ * @bug 6880672 6896573 6899694 6976036 7013585 7018258 8003981 8226297
+ * @build Sorting
+ * @run main Sorting -shortrun
+ * @summary Exercise Arrays.sort, Arrays.parallelSort
+ *
+ * @author Vladimir Yaroslavskiy
+ * @author Jon Bentley
+ * @author Josh Bloch
+ */
+
+package test.java.util.Arrays;
+
+import android.platform.test.annotations.LargeTest;
+
+import java.io.PrintStream;
+import java.util.Comparator;
+import java.util.Random;
+
+@LargeTest
+@SuppressWarnings("IdentityBinaryExpression")
+public class Sorting {
+
+ private static final PrintStream out = System.out;
+ private static final PrintStream err = System.err;
+
+ // Array lengths used in a long run (default)
+ private static final int[] LONG_RUN_LENGTHS = {
+ 1, 3, 8, 21, 55, 100, 1_000, 10_000, 100_000 };
+
+ // Array lengths used in a short run
+ private static final int[] SHORT_RUN_LENGTHS = {
+ 1, 8, 55, 100, 10_000 };
+
+ // Random initial values used in a long run (default)
+ private static final TestRandom[] LONG_RUN_RANDOMS = {
+ TestRandom.BABA, TestRandom.DEDA, TestRandom.C0FFEE };
+
+ // Random initial values used in a short run
+ private static final TestRandom[] SHORT_RUN_RANDOMS = {
+ TestRandom.C0FFEE };
+
+ // Constants used in subarray sorting
+ private static final int A380 = 0xA380;
+ private static final int B747 = 0xB747;
+
+ public static void main(String[] args) {
+ long start = System.currentTimeMillis();
+ // Android-changed: coverage run with this flag set to true takes too
+ // much time. Locally it was killed after 45 minutes.
+ // boolean shortRun = args.length > 0 && args[0].equals("-shortrun");
+ boolean shortRun = true;
+
+ int[] lengths = shortRun ? SHORT_RUN_LENGTHS : LONG_RUN_LENGTHS;
+ TestRandom[] randoms = shortRun ? SHORT_RUN_RANDOMS : LONG_RUN_RANDOMS;
+
+ new InnerState(SortingHelper.DUAL_PIVOT_QUICKSORT, randoms, lengths).testCore();
+ new InnerState(SortingHelper.PARALLEL_SORT, randoms, lengths).testCore();
+ new InnerState(SortingHelper.HEAP_SORT, randoms, lengths).testBasic();
+ new InnerState(SortingHelper.ARRAYS_SORT, randoms, lengths).testAll();
+ new InnerState(SortingHelper.ARRAYS_PARALLEL_SORT, randoms, lengths).testAll();
+
+ long end = System.currentTimeMillis();
+ out.format("PASSED in %d sec.\n", (end - start) / 1000);
+ }
+
+ // Android-changed: runner can't run test with non-default contructor.
+ private static class InnerState {
+ private final SortingHelper sortingHelper;
+ private final TestRandom[] randoms;
+ private final int[] lengths;
+ private Object[] gold;
+ private Object[] test;
+
+ public InnerState(SortingHelper sortingHelper, TestRandom[] randoms, int[] lengths) {
+ this.sortingHelper = sortingHelper;
+ this.randoms = randoms;
+ this.lengths = lengths;
+ }
+
+ private void testBasic() {
+ testEmptyArray();
+
+ for (int length : lengths) {
+ createData(length);
+ testBasic(length);
+ }
+ }
+
+ private void testBasic(int length) {
+ for (TestRandom random : randoms) {
+ testWithInsertionSort(length, random);
+ testWithCheckSum(length, random);
+ testWithScrambling(length, random);
+ }
+ }
+
+ private void testCore() {
+ for (int length : lengths) {
+ createData(length);
+ testCore(length);
+ }
+ }
+
+ private void testCore(int length) {
+ testBasic(length);
+
+ for (TestRandom random : randoms) {
+ testMergingSort(length, random);
+ testSubArray(length, random);
+ testNegativeZero(length, random);
+ testFloatingPointSorting(length, random);
+ }
+ }
+
+ private void testAll() {
+ for (int length : lengths) {
+ createData(length);
+ testAll(length);
+ }
+ }
+
+ private void testAll(int length) {
+ testCore(length);
+
+ for (TestRandom random : randoms) {
+ testRange(length, random);
+ testStability(length, random);
+ }
+ }
+
+ private void testEmptyArray() {
+ testEmptyAndNullIntArray();
+ testEmptyAndNullLongArray();
+ testEmptyAndNullByteArray();
+ testEmptyAndNullCharArray();
+ testEmptyAndNullShortArray();
+ testEmptyAndNullFloatArray();
+ testEmptyAndNullDoubleArray();
+ }
+
+ private void testStability(int length, TestRandom random) {
+ printTestName("Test stability", random, length);
+
+ Pair[] a = build(length, random);
+ sortingHelper.sort(a);
+ checkSorted(a);
+ checkStable(a);
+
+ a = build(length, random);
+ sortingHelper.sort(a, pairComparator);
+ checkSorted(a);
+ checkStable(a);
+
+ out.println();
+ }
+
+ private void testEmptyAndNullIntArray() {
+ sortingHelper.sort(new int[]{});
+ sortingHelper.sort(new int[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(int[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(int[]) shouldn't catch null array");
+ }
+
+ private void testEmptyAndNullLongArray() {
+ sortingHelper.sort(new long[]{});
+ sortingHelper.sort(new long[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(long[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(long[]) shouldn't catch null array");
+ }
+
+ private void testEmptyAndNullByteArray() {
+ sortingHelper.sort(new byte[]{});
+ sortingHelper.sort(new byte[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(byte[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(byte[]) shouldn't catch null array");
+ }
+
+ private void testEmptyAndNullCharArray() {
+ sortingHelper.sort(new char[]{});
+ sortingHelper.sort(new char[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(char[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(char[]) shouldn't catch null array");
+ }
+
+ private void testEmptyAndNullShortArray() {
+ sortingHelper.sort(new short[]{});
+ sortingHelper.sort(new short[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(short[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(short[]) shouldn't catch null array");
+ }
+
+ private void testEmptyAndNullFloatArray() {
+ sortingHelper.sort(new float[]{});
+ sortingHelper.sort(new float[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(float[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(float[]) shouldn't catch null array");
+ }
+
+ private void testEmptyAndNullDoubleArray() {
+ sortingHelper.sort(new double[]{});
+ sortingHelper.sort(new double[]{}, 0, 0);
+
+ try {
+ sortingHelper.sort(null);
+ } catch (NullPointerException expected) {
+ try {
+ sortingHelper.sort(null, 0, 0);
+ } catch (NullPointerException expected2) {
+ return;
+ }
+ fail(sortingHelper + "(double[],fromIndex,toIndex) shouldn't " +
+ "catch null array");
+ }
+ fail(sortingHelper + "(double[]) shouldn't catch null array");
+ }
+
+ private void testSubArray(int length, TestRandom random) {
+ if (length < 4) {
+ return;
+ }
+ for (int m = 1; m < length / 2; m <<= 1) {
+ int fromIndex = m;
+ int toIndex = length - m;
+
+ prepareSubArray((int[]) gold[0], fromIndex, toIndex);
+ convertData(length);
+
+ for (int i = 0; i < test.length; i++) {
+ printTestName("Test subarray", random, length,
+ ", m = " + m + ", " + getType(i));
+ sortingHelper.sort(test[i], fromIndex, toIndex);
+ checkSubArray(test[i], fromIndex, toIndex);
+ }
+ }
+ out.println();
+ }
+
+ private void testRange(int length, TestRandom random) {
+ if (length < 2) {
+ return;
+ }
+ for (int m = 1; m < length; m <<= 1) {
+ for (int i = 1; i <= length; i++) {
+ ((int[]) gold[0])[i - 1] = i % m + m % i;
+ }
+ convertData(length);
+
+ for (int i = 0; i < test.length; i++) {
+ printTestName("Test range check", random, length,
+ ", m = " + m + ", " + getType(i));
+ checkRange(test[i], m);
+ }
+ }
+ out.println();
+ }
+
+ private void checkSorted(Pair[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i].getKey() > a[i + 1].getKey()) {
+ fail("Array is not sorted at " + i + "-th position: " +
+ a[i].getKey() + " and " + a[i + 1].getKey());
+ }
+ }
+ }
+
+ private void checkStable(Pair[] a) {
+ for (int i = 0; i < a.length / 4; ) {
+ int key1 = a[i].getKey();
+ int value1 = a[i++].getValue();
+ int key2 = a[i].getKey();
+ int value2 = a[i++].getValue();
+ int key3 = a[i].getKey();
+ int value3 = a[i++].getValue();
+ int key4 = a[i].getKey();
+ int value4 = a[i++].getValue();
+
+ if (!(key1 == key2 && key2 == key3 && key3 == key4)) {
+ fail("Keys are different " + key1 + ", " + key2 + ", " +
+ key3 + ", " + key4 + " at position " + i);
+ }
+ if (!(value1 < value2 && value2 < value3 && value3 < value4)) {
+ fail("Sorting is not stable at position " + i +
+ ". Second values have been changed: " + value1 + ", " +
+ value2 + ", " + value3 + ", " + value4);
+ }
+ }
+ }
+
+ private Pair[] build(int length, Random random) {
+ Pair[] a = new Pair[length * 4];
+
+ for (int i = 0; i < a.length; ) {
+ int key = random.nextInt();
+ a[i++] = new Pair(key, 1);
+ a[i++] = new Pair(key, 2);
+ a[i++] = new Pair(key, 3);
+ a[i++] = new Pair(key, 4);
+ }
+ return a;
+ }
+
+ private void testWithInsertionSort(int length, TestRandom random) {
+ if (length > 1000) {
+ return;
+ }
+ for (int m = 1; m <= length; m <<= 1) {
+ for (UnsortedBuilder builder : UnsortedBuilder.values()) {
+ builder.build((int[]) gold[0], m, random);
+ convertData(length);
+
+ for (int i = 0; i < test.length; i++) {
+ printTestName("Test with insertion sort", random, length,
+ ", m = " + m + ", " + getType(i) + " " + builder);
+ sortingHelper.sort(test[i]);
+ sortByInsertionSort(gold[i]);
+ compare(test[i], gold[i]);
+ }
+ }
+ }
+ out.println();
+ }
+
+ private void testMergingSort(int length, TestRandom random) {
+ if (length < (4 << 10)) { // DualPivotQuicksort.MIN_TRY_MERGE_SIZE
+ return;
+ }
+ final int PERIOD = 50;
+
+ for (int m = PERIOD - 2; m <= PERIOD + 2; m++) {
+ for (MergingBuilder builder : MergingBuilder.values()) {
+ builder.build((int[]) gold[0], m);
+ convertData(length);
+
+ for (int i = 0; i < test.length; i++) {
+ printTestName("Test merging sort", random, length,
+ ", m = " + m + ", " + getType(i) + " " + builder);
+ sortingHelper.sort(test[i]);
+ checkSorted(test[i]);
+ }
+ }
+ }
+ out.println();
+ }
+
+ private void testWithCheckSum(int length, TestRandom random) {
+ for (int m = 1; m <= length; m <<= 1) {
+ for (UnsortedBuilder builder : UnsortedBuilder.values()) {
+ builder.build((int[]) gold[0], m, random);
+ convertData(length);
+
+ for (int i = 0; i < test.length; i++) {
+ printTestName("Test with check sum", random, length,
+ ", m = " + m + ", " + getType(i) + " " + builder);
+ sortingHelper.sort(test[i]);
+ checkWithCheckSum(test[i], gold[i]);
+ }
+ }
+ }
+ out.println();
+ }
+
+ private void testWithScrambling(int length, TestRandom random) {
+ for (int m = 1; m <= length; m <<= 1) {
+ for (SortedBuilder builder : SortedBuilder.values()) {
+ builder.build((int[]) gold[0], m);
+ convertData(length);
+
+ for (int i = 0; i < test.length; i++) {
+ printTestName("Test with scrambling", random, length,
+ ", m = " + m + ", " + getType(i) + " " + builder);
+ scramble(test[i], random);
+ sortingHelper.sort(test[i]);
+ compare(test[i], gold[i]);
+ }
+ }
+ }
+ out.println();
+ }
+
+ private void testNegativeZero(int length, TestRandom random) {
+ for (int i = 5; i < test.length; i++) {
+ printTestName("Test negative zero -0.0", random, length, " " + getType(i));
+
+ NegativeZeroBuilder builder = NegativeZeroBuilder.values()[i - 5];
+ builder.build(test[i], random);
+
+ sortingHelper.sort(test[i]);
+ checkNegativeZero(test[i]);
+ }
+ out.println();
+ }
+
+ private void testFloatingPointSorting(int length, TestRandom random) {
+ if (length < 2) {
+ return;
+ }
+ final int MAX = 13;
+
+ for (int a = 0; a < MAX; a++) {
+ for (int g = 0; g < MAX; g++) {
+ for (int z = 0; z < MAX; z++) {
+ for (int n = 0; n < MAX; n++) {
+ for (int p = 0; p < MAX; p++) {
+ if (a + g + z + n + p != length) {
+ continue;
+ }
+ for (int i = 5; i < test.length; i++) {
+ printTestName("Test float-pointing sorting", random, length,
+ ", a = " + a + ", g = " + g + ", z = " + z +
+ ", n = " + n + ", p = " + p + ", " + getType(
+ i));
+ FloatingPointBuilder builder =
+ FloatingPointBuilder.values()[i - 5];
+ builder.build(gold[i], a, g, z, n, p, random);
+ copy(test[i], gold[i]);
+ scramble(test[i], random);
+ sortingHelper.sort(test[i]);
+ compare(test[i], gold[i], a, n, g);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (int m = 13; m > 4; m--) {
+ int t = length / m;
+ int g = t, z = t, n = t, p = t;
+ int a = length - g - z - n - p;
+
+ for (int i = 5; i < test.length; i++) {
+ printTestName("Test float-pointing sorting", random, length,
+ ", a = " + a + ", g = " + g + ", z = " + z +
+ ", n = " + n + ", p = " + p + ", " + getType(i));
+ FloatingPointBuilder builder = FloatingPointBuilder.values()[i - 5];
+ builder.build(gold[i], a, g, z, n, p, random);
+ copy(test[i], gold[i]);
+ scramble(test[i], random);
+ sortingHelper.sort(test[i]);
+ compare(test[i], gold[i], a, n, g);
+ }
+ }
+ out.println();
+ }
+
+ private void prepareSubArray(int[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ a[i] = A380;
+ }
+ int middle = (fromIndex + toIndex) >>> 1;
+ int k = 0;
+
+ for (int i = fromIndex; i < middle; i++) {
+ a[i] = k++;
+ }
+
+ for (int i = middle; i < toIndex; i++) {
+ a[i] = k--;
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ a[i] = B747;
+ }
+ }
+
+ private void scramble(Object a, Random random) {
+ if (a instanceof int[]) {
+ scramble((int[]) a, random);
+ } else if (a instanceof long[]) {
+ scramble((long[]) a, random);
+ } else if (a instanceof byte[]) {
+ scramble((byte[]) a, random);
+ } else if (a instanceof char[]) {
+ scramble((char[]) a, random);
+ } else if (a instanceof short[]) {
+ scramble((short[]) a, random);
+ } else if (a instanceof float[]) {
+ scramble((float[]) a, random);
+ } else if (a instanceof double[]) {
+ scramble((double[]) a, random);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void scramble(int[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void scramble(long[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void scramble(byte[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void scramble(char[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void scramble(short[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void scramble(float[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void scramble(double[] a, Random random) {
+ for (int i = 0; i < a.length * 7; i++) {
+ swap(a, random.nextInt(a.length), random.nextInt(a.length));
+ }
+ }
+
+ private void swap(int[] a, int i, int j) {
+ int t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void swap(long[] a, int i, int j) {
+ long t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void swap(byte[] a, int i, int j) {
+ byte t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void swap(char[] a, int i, int j) {
+ char t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void swap(short[] a, int i, int j) {
+ short t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void swap(float[] a, int i, int j) {
+ float t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void swap(double[] a, int i, int j) {
+ double t = a[i];
+ a[i] = a[j];
+ a[j] = t;
+ }
+
+ private void checkWithCheckSum(Object test, Object gold) {
+ checkSorted(test);
+ checkCheckSum(test, gold);
+ }
+
+ private void fail(String message) {
+ err.format("\n*** TEST FAILED ***\n\n%s\n\n", message);
+ throw new RuntimeException("Test failed");
+ }
+
+ private void checkNegativeZero(Object a) {
+ if (a instanceof float[]) {
+ checkNegativeZero((float[]) a);
+ } else if (a instanceof double[]) {
+ checkNegativeZero((double[]) a);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void checkNegativeZero(float[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (Float.floatToRawIntBits(a[i]) == 0 && Float.floatToRawIntBits(a[i + 1]) < 0) {
+ fail(a[i] + " before " + a[i + 1] + " at position " + i);
+ }
+ }
+ }
+
+ private void checkNegativeZero(double[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (Double.doubleToRawLongBits(a[i]) == 0 && Double.doubleToRawLongBits(a[i + 1])
+ < 0) {
+ fail(a[i] + " before " + a[i + 1] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(Object a, Object b, int numNaN, int numNeg, int numNegZero) {
+ if (a instanceof float[]) {
+ compare((float[]) a, (float[]) b, numNaN, numNeg, numNegZero);
+ } else if (a instanceof double[]) {
+ compare((double[]) a, (double[]) b, numNaN, numNeg, numNegZero);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void compare(float[] a, float[] b, int numNaN, int numNeg, int numNegZero) {
+ for (int i = a.length - numNaN; i < a.length; i++) {
+ if (a[i] == a[i]) {
+ fail("There must be NaN instead of " + a[i] + " at position " + i);
+ }
+ }
+ final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f);
+
+ for (int i = numNeg; i < numNeg + numNegZero; i++) {
+ if (NEGATIVE_ZERO != Float.floatToIntBits(a[i])) {
+ fail("There must be -0.0 instead of " + a[i] + " at position " + i);
+ }
+ }
+
+ for (int i = 0; i < a.length - numNaN; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(double[] a, double[] b, int numNaN, int numNeg, int numNegZero) {
+ for (int i = a.length - numNaN; i < a.length; i++) {
+ if (a[i] == a[i]) {
+ fail("There must be NaN instead of " + a[i] + " at position " + i);
+ }
+ }
+ final long NEGATIVE_ZERO = Double.doubleToLongBits(-0.0d);
+
+ for (int i = numNeg; i < numNeg + numNegZero; i++) {
+ if (NEGATIVE_ZERO != Double.doubleToLongBits(a[i])) {
+ fail("There must be -0.0 instead of " + a[i] + " at position " + i);
+ }
+ }
+
+ for (int i = 0; i < a.length - numNaN; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(Object a, Object b) {
+ if (a instanceof int[]) {
+ compare((int[]) a, (int[]) b);
+ } else if (a instanceof long[]) {
+ compare((long[]) a, (long[]) b);
+ } else if (a instanceof byte[]) {
+ compare((byte[]) a, (byte[]) b);
+ } else if (a instanceof char[]) {
+ compare((char[]) a, (char[]) b);
+ } else if (a instanceof short[]) {
+ compare((short[]) a, (short[]) b);
+ } else if (a instanceof float[]) {
+ compare((float[]) a, (float[]) b);
+ } else if (a instanceof double[]) {
+ compare((double[]) a, (double[]) b);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void compare(int[] a, int[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(long[] a, long[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(byte[] a, byte[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(char[] a, char[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(short[] a, short[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(float[] a, float[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private void compare(double[] a, double[] b) {
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i]) {
+ fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);
+ }
+ }
+ }
+
+ private String getType(int i) {
+ Object a = test[i];
+
+ if (a instanceof int[]) {
+ return "INT ";
+ }
+ if (a instanceof long[]) {
+ return "LONG ";
+ }
+ if (a instanceof byte[]) {
+ return "BYTE ";
+ }
+ if (a instanceof char[]) {
+ return "CHAR ";
+ }
+ if (a instanceof short[]) {
+ return "SHORT ";
+ }
+ if (a instanceof float[]) {
+ return "FLOAT ";
+ }
+ if (a instanceof double[]) {
+ return "DOUBLE";
+ }
+ fail("Unknown type of array: " + a.getClass().getName());
+ return null;
+ }
+
+ private void checkSorted(Object a) {
+ if (a instanceof int[]) {
+ checkSorted((int[]) a);
+ } else if (a instanceof long[]) {
+ checkSorted((long[]) a);
+ } else if (a instanceof byte[]) {
+ checkSorted((byte[]) a);
+ } else if (a instanceof char[]) {
+ checkSorted((char[]) a);
+ } else if (a instanceof short[]) {
+ checkSorted((short[]) a);
+ } else if (a instanceof float[]) {
+ checkSorted((float[]) a);
+ } else if (a instanceof double[]) {
+ checkSorted((double[]) a);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void checkSorted(int[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(long[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(byte[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(char[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(short[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(float[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkSorted(double[] a) {
+ for (int i = 0; i < a.length - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+ }
+
+ private void checkCheckSum(Object test, Object gold) {
+ if (checkSumXor(test) != checkSumXor(gold)) {
+ fail("Original and sorted arrays are not identical [^]");
+ }
+ if (checkSumPlus(test) != checkSumPlus(gold)) {
+ fail("Original and sorted arrays are not identical [+]");
+ }
+ }
+
+ private int checkSumXor(Object a) {
+ if (a instanceof int[]) {
+ return checkSumXor((int[]) a);
+ }
+ if (a instanceof long[]) {
+ return checkSumXor((long[]) a);
+ }
+ if (a instanceof byte[]) {
+ return checkSumXor((byte[]) a);
+ }
+ if (a instanceof char[]) {
+ return checkSumXor((char[]) a);
+ }
+ if (a instanceof short[]) {
+ return checkSumXor((short[]) a);
+ }
+ if (a instanceof float[]) {
+ return checkSumXor((float[]) a);
+ }
+ if (a instanceof double[]) {
+ return checkSumXor((double[]) a);
+ }
+ fail("Unknown type of array: " + a.getClass().getName());
+ return -1;
+ }
+
+ private int checkSumXor(int[] a) {
+ int checkSum = 0;
+
+ for (int e : a) {
+ checkSum ^= e;
+ }
+ return checkSum;
+ }
+
+ private int checkSumXor(long[] a) {
+ long checkSum = 0;
+
+ for (long e : a) {
+ checkSum ^= e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumXor(byte[] a) {
+ byte checkSum = 0;
+
+ for (byte e : a) {
+ checkSum ^= e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumXor(char[] a) {
+ char checkSum = 0;
+
+ for (char e : a) {
+ checkSum ^= e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumXor(short[] a) {
+ short checkSum = 0;
+
+ for (short e : a) {
+ checkSum ^= e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumXor(float[] a) {
+ int checkSum = 0;
+
+ for (float e : a) {
+ checkSum ^= (int) e;
+ }
+ return checkSum;
+ }
+
+ private int checkSumXor(double[] a) {
+ int checkSum = 0;
+
+ for (double e : a) {
+ checkSum ^= (int) e;
+ }
+ return checkSum;
+ }
+
+ private int checkSumPlus(Object a) {
+ if (a instanceof int[]) {
+ return checkSumPlus((int[]) a);
+ }
+ if (a instanceof long[]) {
+ return checkSumPlus((long[]) a);
+ }
+ if (a instanceof byte[]) {
+ return checkSumPlus((byte[]) a);
+ }
+ if (a instanceof char[]) {
+ return checkSumPlus((char[]) a);
+ }
+ if (a instanceof short[]) {
+ return checkSumPlus((short[]) a);
+ }
+ if (a instanceof float[]) {
+ return checkSumPlus((float[]) a);
+ }
+ if (a instanceof double[]) {
+ return checkSumPlus((double[]) a);
+ }
+ fail("Unknown type of array: " + a.getClass().getName());
+ return -1;
+ }
+
+ private int checkSumPlus(int[] a) {
+ int checkSum = 0;
+
+ for (int e : a) {
+ checkSum += e;
+ }
+ return checkSum;
+ }
+
+ private int checkSumPlus(long[] a) {
+ long checkSum = 0;
+
+ for (long e : a) {
+ checkSum += e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumPlus(byte[] a) {
+ byte checkSum = 0;
+
+ for (byte e : a) {
+ checkSum += e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumPlus(char[] a) {
+ char checkSum = 0;
+
+ for (char e : a) {
+ checkSum += e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumPlus(short[] a) {
+ short checkSum = 0;
+
+ for (short e : a) {
+ checkSum += e;
+ }
+ return (int) checkSum;
+ }
+
+ private int checkSumPlus(float[] a) {
+ int checkSum = 0;
+
+ for (float e : a) {
+ checkSum += (int) e;
+ }
+ return checkSum;
+ }
+
+ private int checkSumPlus(double[] a) {
+ int checkSum = 0;
+
+ for (double e : a) {
+ checkSum += (int) e;
+ }
+ return checkSum;
+ }
+
+ private void sortByInsertionSort(Object a) {
+ if (a instanceof int[]) {
+ sortByInsertionSort((int[]) a);
+ } else if (a instanceof long[]) {
+ sortByInsertionSort((long[]) a);
+ } else if (a instanceof byte[]) {
+ sortByInsertionSort((byte[]) a);
+ } else if (a instanceof char[]) {
+ sortByInsertionSort((char[]) a);
+ } else if (a instanceof short[]) {
+ sortByInsertionSort((short[]) a);
+ } else if (a instanceof float[]) {
+ sortByInsertionSort((float[]) a);
+ } else if (a instanceof double[]) {
+ sortByInsertionSort((double[]) a);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void sortByInsertionSort(int[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ int ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void sortByInsertionSort(long[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ long ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void sortByInsertionSort(byte[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ byte ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void sortByInsertionSort(char[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ char ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void sortByInsertionSort(short[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ short ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void sortByInsertionSort(float[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ float ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void sortByInsertionSort(double[] a) {
+ for (int j, i = 1; i < a.length; i++) {
+ double ai = a[i];
+
+ for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+ a[j + 1] = a[j];
+ }
+ a[j + 1] = ai;
+ }
+ }
+
+ private void checkSubArray(Object a, int fromIndex, int toIndex) {
+ if (a instanceof int[]) {
+ checkSubArray((int[]) a, fromIndex, toIndex);
+ } else if (a instanceof long[]) {
+ checkSubArray((long[]) a, fromIndex, toIndex);
+ } else if (a instanceof byte[]) {
+ checkSubArray((byte[]) a, fromIndex, toIndex);
+ } else if (a instanceof char[]) {
+ checkSubArray((char[]) a, fromIndex, toIndex);
+ } else if (a instanceof short[]) {
+ checkSubArray((short[]) a, fromIndex, toIndex);
+ } else if (a instanceof float[]) {
+ checkSubArray((float[]) a, fromIndex, toIndex);
+ } else if (a instanceof double[]) {
+ checkSubArray((double[]) a, fromIndex, toIndex);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void checkSubArray(int[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != A380) {
+ fail("Range sort changes left element at position " + i + hex(a[i], A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != B747) {
+ fail("Range sort changes right element at position " + i + hex(a[i], B747));
+ }
+ }
+ }
+
+ private void checkSubArray(long[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != (long) A380) {
+ fail("Range sort changes left element at position " + i + hex(a[i], A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != (long) B747) {
+ fail("Range sort changes right element at position " + i + hex(a[i], B747));
+ }
+ }
+ }
+
+ private void checkSubArray(byte[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != (byte) A380) {
+ fail("Range sort changes left element at position " + i + hex(a[i], A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != (byte) B747) {
+ fail("Range sort changes right element at position " + i + hex(a[i], B747));
+ }
+ }
+ }
+
+ private void checkSubArray(char[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != (char) A380) {
+ fail("Range sort changes left element at position " + i + hex(a[i], A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != (char) B747) {
+ fail("Range sort changes right element at position " + i + hex(a[i], B747));
+ }
+ }
+ }
+
+ private void checkSubArray(short[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != (short) A380) {
+ fail("Range sort changes left element at position " + i + hex(a[i], A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != (short) B747) {
+ fail("Range sort changes right element at position " + i + hex(a[i], B747));
+ }
+ }
+ }
+
+ private void checkSubArray(float[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != (float) A380) {
+ fail("Range sort changes left element at position " + i + hex((long) a[i],
+ A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != (float) B747) {
+ fail("Range sort changes right element at position " + i + hex((long) a[i],
+ B747));
+ }
+ }
+ }
+
+ private void checkSubArray(double[] a, int fromIndex, int toIndex) {
+ for (int i = 0; i < fromIndex; i++) {
+ if (a[i] != (double) A380) {
+ fail("Range sort changes left element at position " + i + hex((long) a[i],
+ A380));
+ }
+ }
+
+ for (int i = fromIndex; i < toIndex - 1; i++) {
+ if (a[i] > a[i + 1]) {
+ fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i
+ + 1]);
+ }
+ }
+
+ for (int i = toIndex; i < a.length; i++) {
+ if (a[i] != (double) B747) {
+ fail("Range sort changes right element at position " + i + hex((long) a[i],
+ B747));
+ }
+ }
+ }
+
+ private void checkRange(Object a, int m) {
+ if (a instanceof int[]) {
+ checkRange((int[]) a, m);
+ } else if (a instanceof long[]) {
+ checkRange((long[]) a, m);
+ } else if (a instanceof byte[]) {
+ checkRange((byte[]) a, m);
+ } else if (a instanceof char[]) {
+ checkRange((char[]) a, m);
+ } else if (a instanceof short[]) {
+ checkRange((short[]) a, m);
+ } else if (a instanceof float[]) {
+ checkRange((float[]) a, m);
+ } else if (a instanceof double[]) {
+ checkRange((double[]) a, m);
+ } else {
+ fail("Unknown type of array: " + a.getClass().getName());
+ }
+ }
+
+ private void checkRange(int[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void checkRange(long[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void checkRange(byte[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void checkRange(char[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void checkRange(short[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void checkRange(float[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void checkRange(double[] a, int m) {
+ try {
+ sortingHelper.sort(a, m + 1, m);
+ fail(sortingHelper + " does not throw IllegalArgumentException " +
+ "as expected: fromIndex = " + (m + 1) + " toIndex = " + m);
+ } catch (IllegalArgumentException iae) {
+ try {
+ sortingHelper.sort(a, -m, a.length);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: fromIndex = " + (-m));
+ } catch (ArrayIndexOutOfBoundsException aoe) {
+ try {
+ sortingHelper.sort(a, 0, a.length + m);
+ fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +
+ "as expected: toIndex = " + (a.length + m));
+ } catch (ArrayIndexOutOfBoundsException expected) {
+ }
+ }
+ }
+ }
+
+ private void copy(Object dst, Object src) {
+ if (src instanceof float[]) {
+ copy((float[]) dst, (float[]) src);
+ } else if (src instanceof double[]) {
+ copy((double[]) dst, (double[]) src);
+ } else {
+ fail("Unknown type of array: " + src.getClass().getName());
+ }
+ }
+
+ private void copy(float[] dst, float[] src) {
+ System.arraycopy(src, 0, dst, 0, src.length);
+ }
+
+ private void copy(double[] dst, double[] src) {
+ System.arraycopy(src, 0, dst, 0, src.length);
+ }
+
+ private void printTestName(String test, TestRandom random, int length) {
+ printTestName(test, random, length, "");
+ }
+
+ private void createData(int length) {
+ gold = new Object[]{
+ new int[length], new long[length],
+ new byte[length], new char[length], new short[length],
+ new float[length], new double[length]
+ };
+
+ test = new Object[]{
+ new int[length], new long[length],
+ new byte[length], new char[length], new short[length],
+ new float[length], new double[length]
+ };
+ }
+
+ private void convertData(int length) {
+ for (int i = 1; i < gold.length; i++) {
+ TypeConverter converter = TypeConverter.values()[i - 1];
+ converter.convert((int[]) gold[0], gold[i]);
+ }
+
+ for (int i = 0; i < gold.length; i++) {
+ System.arraycopy(gold[i], 0, test[i], 0, length);
+ }
+ }
+
+ private String hex(long a, int b) {
+ return ": " + Long.toHexString(a) + ", must be " + Integer.toHexString(b);
+ }
+
+ private void printTestName(String test, TestRandom random, int length, String message) {
+ out.println("[" + sortingHelper + "] '" + test +
+ "' length = " + length + ", random = " + random + message);
+ }
+ }
+
+ private static enum TypeConverter {
+ LONG {
+ void convert(int[] src, Object dst) {
+ long[] b = (long[]) dst;
+
+ for (int i = 0; i < src.length; i++) {
+ b[i] = (long) src[i];
+ }
+ }
+ },
+
+ BYTE {
+ void convert(int[] src, Object dst) {
+ byte[] b = (byte[]) dst;
+
+ for (int i = 0; i < src.length; i++) {
+ b[i] = (byte) src[i];
+ }
+ }
+ },
+
+ CHAR {
+ void convert(int[] src, Object dst) {
+ char[] b = (char[]) dst;
+
+ for (int i = 0; i < src.length; i++) {
+ b[i] = (char) src[i];
+ }
+ }
+ },
+
+ SHORT {
+ void convert(int[] src, Object dst) {
+ short[] b = (short[]) dst;
+
+ for (int i = 0; i < src.length; i++) {
+ b[i] = (short) src[i];
+ }
+ }
+ },
+
+ FLOAT {
+ void convert(int[] src, Object dst) {
+ float[] b = (float[]) dst;
+
+ for (int i = 0; i < src.length; i++) {
+ b[i] = (float) src[i];
+ }
+ }
+ },
+
+ DOUBLE {
+ void convert(int[] src, Object dst) {
+ double[] b = (double[]) dst;
+
+ for (int i = 0; i < src.length; i++) {
+ b[i] = (double) src[i];
+ }
+ }
+ };
+
+ abstract void convert(int[] src, Object dst);
+ }
+
+ private static enum SortedBuilder {
+ STEPS {
+ void build(int[] a, int m) {
+ for (int i = 0; i < m; i++) {
+ a[i] = 0;
+ }
+
+ for (int i = m; i < a.length; i++) {
+ a[i] = 1;
+ }
+ }
+ };
+
+ abstract void build(int[] a, int m);
+ }
+
+ private static enum UnsortedBuilder {
+ RANDOM {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextInt();
+ }
+ }
+ },
+
+ ASCENDING {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = m + i;
+ }
+ }
+ },
+
+ DESCENDING {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = a.length - m - i;
+ }
+ }
+ },
+
+ EQUAL {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = m;
+ }
+ }
+ },
+
+ SAW {
+ void build(int[] a, int m, Random random) {
+ int incCount = 1;
+ int decCount = a.length;
+ int i = 0;
+ int period = m--;
+
+ while (true) {
+ for (int k = 1; k <= period; k++) {
+ if (i >= a.length) {
+ return;
+ }
+ a[i++] = incCount++;
+ }
+ period += m;
+
+ for (int k = 1; k <= period; k++) {
+ if (i >= a.length) {
+ return;
+ }
+ a[i++] = decCount--;
+ }
+ period += m;
+ }
+ }
+ },
+
+ REPEATED {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i % m;
+ }
+ }
+ },
+
+ DUPLICATED {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextInt(m);
+ }
+ }
+ },
+
+ ORGAN_PIPES {
+ void build(int[] a, int m, Random random) {
+ int middle = a.length / (m + 1);
+
+ for (int i = 0; i < middle; i++) {
+ a[i] = i;
+ }
+
+ for (int i = middle; i < a.length; i++) {
+ a[i] = a.length - i - 1;
+ }
+ }
+ },
+
+ STAGGER {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = (i * m + i) % a.length;
+ }
+ }
+ },
+
+ PLATEAU {
+ void build(int[] a, int m, Random random) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = Math.min(i, m);
+ }
+ }
+ },
+
+ SHUFFLE {
+ void build(int[] a, int m, Random random) {
+ int x = 0, y = 0;
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextBoolean() ? (x += 2) : (y += 2);
+ }
+ }
+ },
+
+ LATCH {
+ void build(int[] a, int m, Random random) {
+ int max = a.length / m;
+ max = max < 2 ? 2 : max;
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i % max;
+ }
+ }
+ };
+
+ abstract void build(int[] a, int m, Random random);
+ }
+
+ private static enum MergingBuilder {
+ ASCENDING {
+ void build(int[] a, int m) {
+ int period = a.length / m;
+ int v = 1, i = 0;
+
+ for (int k = 0; k < m; k++) {
+ v = 1;
+
+ for (int p = 0; p < period; p++) {
+ a[i++] = v++;
+ }
+ }
+
+ for (int j = i; j < a.length - 1; j++) {
+ a[j] = v++;
+ }
+
+ a[a.length - 1] = 0;
+ }
+ },
+
+ DESCENDING {
+ void build(int[] a, int m) {
+ int period = a.length / m;
+ int v = -1, i = 0;
+
+ for (int k = 0; k < m; k++) {
+ v = -1;
+
+ for (int p = 0; p < period; p++) {
+ a[i++] = v--;
+ }
+ }
+
+ for (int j = i; j < a.length - 1; j++) {
+ a[j] = v--;
+ }
+
+ a[a.length - 1] = 0;
+ }
+ },
+
+ POINT {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = 0;
+ }
+ a[a.length / 2] = m;
+ }
+ },
+
+ LINE {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ reverse(a, 0, a.length - 1);
+ }
+ },
+
+ PEARL {
+ void build(int[] a, int m) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ reverse(a, 0, 2);
+ }
+ },
+
+ RING {
+ void build(int[] a, int m) {
+ int k1 = a.length / 3;
+ int k2 = a.length / 3 * 2;
+ int level = a.length / 3;
+
+ for (int i = 0, k = level; i < k1; i++) {
+ a[i] = k--;
+ }
+
+ for (int i = k1; i < k2; i++) {
+ a[i] = 0;
+ }
+
+ for (int i = k2, k = level; i < a.length; i++) {
+ a[i] = k--;
+ }
+ }
+ };
+
+ abstract void build(int[] a, int m);
+
+ private static void reverse(int[] a, int lo, int hi) {
+ for (--hi; lo < hi; ) {
+ int tmp = a[lo];
+ a[lo++] = a[hi];
+ a[hi--] = tmp;
+ }
+ }
+ }
+
+ private static enum NegativeZeroBuilder {
+ FLOAT {
+ void build(Object o, Random random) {
+ float[] a = (float[]) o;
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextBoolean() ? -0.0f : 0.0f;
+ }
+ }
+ },
+
+ DOUBLE {
+ void build(Object o, Random random) {
+ double[] a = (double[]) o;
+
+ for (int i = 0; i < a.length; i++) {
+ a[i] = random.nextBoolean() ? -0.0d : 0.0d;
+ }
+ }
+ };
+
+ abstract void build(Object o, Random random);
+ }
+
+ private static enum FloatingPointBuilder {
+ FLOAT {
+ void build(Object o, int a, int g, int z, int n, int p, Random random) {
+ float negativeValue = -random.nextFloat();
+ float positiveValue = random.nextFloat();
+ float[] x = (float[]) o;
+ int fromIndex = 0;
+
+ writeValue(x, negativeValue, fromIndex, n);
+ fromIndex += n;
+
+ writeValue(x, -0.0f, fromIndex, g);
+ fromIndex += g;
+
+ writeValue(x, 0.0f, fromIndex, z);
+ fromIndex += z;
+
+ writeValue(x, positiveValue, fromIndex, p);
+ fromIndex += p;
+
+ writeValue(x, Float.NaN, fromIndex, a);
+ }
+ },
+
+ DOUBLE {
+ void build(Object o, int a, int g, int z, int n, int p, Random random) {
+ double negativeValue = -random.nextFloat();
+ double positiveValue = random.nextFloat();
+ double[] x = (double[]) o;
+ int fromIndex = 0;
+
+ writeValue(x, negativeValue, fromIndex, n);
+ fromIndex += n;
+
+ writeValue(x, -0.0d, fromIndex, g);
+ fromIndex += g;
+
+ writeValue(x, 0.0d, fromIndex, z);
+ fromIndex += z;
+
+ writeValue(x, positiveValue, fromIndex, p);
+ fromIndex += p;
+
+ writeValue(x, Double.NaN, fromIndex, a);
+ }
+ };
+
+ abstract void build(Object o, int a, int g, int z, int n, int p, Random random);
+
+ private static void writeValue(float[] a, float value, int fromIndex, int count) {
+ for (int i = fromIndex; i < fromIndex + count; i++) {
+ a[i] = value;
+ }
+ }
+
+ private static void writeValue(double[] a, double value, int fromIndex, int count) {
+ for (int i = fromIndex; i < fromIndex + count; i++) {
+ a[i] = value;
+ }
+ }
+ }
+
+ private static Comparator<Pair> pairComparator = new Comparator<Pair>() {
+
+ @Override
+ public int compare(Pair p1, Pair p2) {
+ return p1.compareTo(p2);
+ }
+ };
+
+ private static class Pair implements Comparable<Pair> {
+
+ private Pair(int key, int value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ int getKey() {
+ return key;
+ }
+
+ int getValue() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(Pair pair) {
+ return Integer.compare(key, pair.key);
+ }
+
+ @Override
+ public String toString() {
+ return "(" + key + ", " + value + ")";
+ }
+
+ private int key;
+ private int value;
+ }
+
+ private static class TestRandom extends Random {
+
+ private static final TestRandom BABA = new TestRandom(0xBABA);
+ private static final TestRandom DEDA = new TestRandom(0xDEDA);
+ private static final TestRandom C0FFEE = new TestRandom(0xC0FFEE);
+
+ private TestRandom(long seed) {
+ super(seed);
+ this.seed = Long.toHexString(seed).toUpperCase();
+ }
+
+ @Override
+ public String toString() {
+ return seed;
+ }
+
+ private String seed;
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/SortingHelper.java b/ojluni/src/test/java/util/Arrays/SortingHelper.java
new file mode 100644
index 00000000000..6b5763cc222
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/SortingHelper.java
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.util.Arrays;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * This class provides access to package-private
+ * methods of DualPivotQuicksort class.
+ *
+ * @author Vladimir Yaroslavskiy
+ *
+ * @version 2019.09.19
+ *
+ * @since 14
+ */
+public enum SortingHelper {
+
+ DUAL_PIVOT_QUICKSORT("Dual-Pivot Quicksort") {
+
+ @Override
+ public void sort(Object a) {
+ // BEGIN Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ /*
+ if (a instanceof int[]) {
+ DualPivotQuicksort.sort((int[]) a, SEQUENTIAL, 0, ((int[]) a).length);
+ } else if (a instanceof long[]) {
+ DualPivotQuicksort.sort((long[]) a, SEQUENTIAL, 0, ((long[]) a).length);
+ } else if (a instanceof byte[]) {
+ DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
+ } else if (a instanceof char[]) {
+ DualPivotQuicksort.sort((char[]) a, SEQUENTIAL, 0, ((char[]) a).length);
+ } else if (a instanceof short[]) {
+ DualPivotQuicksort.sort((short[]) a, SEQUENTIAL, 0, ((short[]) a).length);
+ } else if (a instanceof float[]) {
+ DualPivotQuicksort.sort((float[]) a, SEQUENTIAL, 0, ((float[]) a).length);
+ } else if (a instanceof double[]) {
+ DualPivotQuicksort.sort((double[]) a, SEQUENTIAL, 0, ((double[]) a).length);
+ } else {
+ fail(a);
+ }
+ */
+ try {
+ if (a instanceof int[]) {
+ MethodHandleHolder.INT_SORT.invoke(
+ (int[]) a, SEQUENTIAL, 0, ((int[]) a).length);
+ } else if (a instanceof long[]) {
+ MethodHandleHolder.LONG_SORT.invoke(
+ (long[]) a, SEQUENTIAL, 0, ((long[]) a).length);
+ } else if (a instanceof byte[]) {
+ MethodHandleHolder.BYTE_SORT.invoke(
+ (byte[]) a, 0, ((byte[]) a).length);
+ } else if (a instanceof char[]) {
+ MethodHandleHolder.CHAR_SORT.invoke(
+ (char[]) a, SEQUENTIAL, 0, ((char[]) a).length);
+ } else if (a instanceof short[]) {
+ MethodHandleHolder.SHORT_SORT.invoke(
+ (short[]) a, SEQUENTIAL, 0, ((short[]) a).length);
+ } else if (a instanceof float[]) {
+ MethodHandleHolder.FLOAT_SORT.invoke(
+ (float[]) a, SEQUENTIAL, 0, ((float[]) a).length);
+ } else if (a instanceof double[]) {
+ MethodHandleHolder.DOUBLE_SORT.invoke(
+ (double[]) a, SEQUENTIAL, 0, ((double[]) a).length);
+ } else {
+ fail(a);
+ }
+ } catch (RuntimeException re) {
+ // propagate RuntimeException as it is.
+ throw re;
+ } catch (Throwable e) {
+ throw new AssertionError(e);
+ }
+ // END Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ }
+
+ @Override
+ public void sort(Object a, int low, int high) {
+ // BEGIN Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ /*
+ if (a instanceof int[]) {
+ DualPivotQuicksort.sort((int[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof long[]) {
+ DualPivotQuicksort.sort((long[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof byte[]) {
+ DualPivotQuicksort.sort((byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ DualPivotQuicksort.sort((char[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof short[]) {
+ DualPivotQuicksort.sort((short[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof float[]) {
+ DualPivotQuicksort.sort((float[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof double[]) {
+ DualPivotQuicksort.sort((double[]) a, SEQUENTIAL, low, high);
+ } else {
+ fail(a);
+ }
+ */
+ try {
+ if (a instanceof int[]) {
+ MethodHandleHolder.INT_SORT.invoke(
+ (int[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof long[]) {
+ MethodHandleHolder.LONG_SORT.invoke(
+ (long[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof byte[]) {
+ MethodHandleHolder.BYTE_SORT.invoke(
+ (byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ MethodHandleHolder.CHAR_SORT.invoke(
+ (char[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof short[]) {
+ MethodHandleHolder.SHORT_SORT.invoke(
+ (short[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof float[]) {
+ MethodHandleHolder.FLOAT_SORT.invoke(
+ (float[]) a, SEQUENTIAL, low, high);
+ } else if (a instanceof double[]) {
+ MethodHandleHolder.DOUBLE_SORT.invoke(
+ (double[]) a, SEQUENTIAL, low, high);
+ } else {
+ fail(a);
+ }
+ } catch (RuntimeException re) {
+ // propagate RuntimeException as it is.
+ throw re;
+ } catch (Throwable e) {
+ throw new AssertionError(e);
+ }
+ // END Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ }
+
+ @Override
+ public void sort(Object[] a) {
+ fail(a);
+ }
+
+ @Override
+ public void sort(Object[] a, Comparator comparator) {
+ fail(a);
+ }
+ },
+
+ PARALLEL_SORT("Parallel sort") {
+
+ @Override
+ public void sort(Object a) {
+ // BEGIN Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ /*
+ if (a instanceof int[]) {
+ DualPivotQuicksort.sort((int[]) a, PARALLEL, 0, ((int[]) a).length);
+ } else if (a instanceof long[]) {
+ DualPivotQuicksort.sort((long[]) a, PARALLEL, 0, ((long[]) a).length);
+ } else if (a instanceof byte[]) {
+ DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
+ } else if (a instanceof char[]) {
+ DualPivotQuicksort.sort((char[]) a, PARALLEL, 0, ((char[]) a).length);
+ } else if (a instanceof short[]) {
+ DualPivotQuicksort.sort((short[]) a, PARALLEL, 0, ((short[]) a).length);
+ } else if (a instanceof float[]) {
+ DualPivotQuicksort.sort((float[]) a, PARALLEL, 0, ((float[]) a).length);
+ } else if (a instanceof double[]) {
+ DualPivotQuicksort.sort((double[]) a, PARALLEL, 0, ((double[]) a).length);
+ } else {
+ fail(a);
+ }
+ */
+ try {
+ if (a instanceof int[]) {
+ MethodHandleHolder.INT_SORT.invoke(
+ (int[]) a, PARALLEL, 0, ((int[]) a).length);
+ } else if (a instanceof long[]) {
+ MethodHandleHolder.LONG_SORT.invoke(
+ (long[]) a, PARALLEL, 0, ((long[]) a).length);
+ } else if (a instanceof byte[]) {
+ MethodHandleHolder.BYTE_SORT.invoke(
+ (byte[]) a, 0, ((byte[]) a).length);
+ } else if (a instanceof char[]) {
+ MethodHandleHolder.CHAR_SORT.invoke(
+ (char[]) a, PARALLEL, 0, ((char[]) a).length);
+ } else if (a instanceof short[]) {
+ MethodHandleHolder.SHORT_SORT.invoke(
+ (short[]) a, PARALLEL, 0, ((short[]) a).length);
+ } else if (a instanceof float[]) {
+ MethodHandleHolder.FLOAT_SORT.invoke(
+ (float[]) a, PARALLEL, 0, ((float[]) a).length);
+ } else if (a instanceof double[]) {
+ MethodHandleHolder.DOUBLE_SORT.invoke(
+ (double[]) a, PARALLEL, 0, ((double[]) a).length);
+ } else {
+ fail(a);
+ }
+ } catch (RuntimeException re) {
+ // propagate RuntimeException as it is.
+ throw re;
+ } catch (Throwable e) {
+ throw new AssertionError(e);
+ }
+ // END Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ }
+
+ @Override
+ public void sort(Object a, int low, int high) {
+ // BEGIN Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ /*
+ if (a instanceof int[]) {
+ DualPivotQuicksort.sort((int[]) a, PARALLEL, low, high);
+ } else if (a instanceof long[]) {
+ DualPivotQuicksort.sort((long[]) a, PARALLEL, low, high);
+ } else if (a instanceof byte[]) {
+ DualPivotQuicksort.sort((byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ DualPivotQuicksort.sort((char[]) a, PARALLEL, low, high);
+ } else if (a instanceof short[]) {
+ DualPivotQuicksort.sort((short[]) a, PARALLEL, low, high);
+ } else if (a instanceof float[]) {
+ DualPivotQuicksort.sort((float[]) a, PARALLEL, low, high);
+ } else if (a instanceof double[]) {
+ DualPivotQuicksort.sort((double[]) a, PARALLEL, low, high);
+ } else {
+ fail(a);
+ }
+ */
+ try {
+ if (a instanceof int[]) {
+ MethodHandleHolder.INT_SORT.invoke(
+ (int[]) a, PARALLEL, low, high);
+ } else if (a instanceof long[]) {
+ MethodHandleHolder.LONG_SORT.invoke(
+ (long[]) a, PARALLEL, low, high);
+ } else if (a instanceof byte[]) {
+ MethodHandleHolder.BYTE_SORT.invoke(
+ (byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ MethodHandleHolder.CHAR_SORT.invoke(
+ (char[]) a, PARALLEL, low, high);
+ } else if (a instanceof short[]) {
+ MethodHandleHolder.SHORT_SORT.invoke(
+ (short[]) a, PARALLEL, low, high);
+ } else if (a instanceof float[]) {
+ MethodHandleHolder.FLOAT_SORT.invoke(
+ (float[]) a, PARALLEL, low, high);
+ } else if (a instanceof double[]) {
+ MethodHandleHolder.DOUBLE_SORT.invoke(
+ (double[]) a, PARALLEL, low, high);
+ } else {
+ fail(a);
+ }
+ } catch (RuntimeException re) {
+ // propagate RuntimeException as it is.
+ throw re;
+ } catch (Throwable e) {
+ throw new AssertionError(e);
+ }
+ // END Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ }
+
+ @Override
+ public void sort(Object[] a) {
+ fail(a);
+ }
+
+ @Override
+ public void sort(Object[] a, Comparator comparator) {
+ fail(a);
+ }
+ },
+
+ HEAP_SORT("Heap sort") {
+
+ @Override
+ public void sort(Object a) {
+ // BEGIN Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ /*
+ if (a instanceof int[]) {
+ DualPivotQuicksort.sort(null, (int[]) a, BIG_DEPTH, 0, ((int[]) a).length);
+ } else if (a instanceof long[]) {
+ DualPivotQuicksort.sort(null, (long[]) a, BIG_DEPTH, 0, ((long[]) a).length);
+ } else if (a instanceof byte[]) {
+ DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
+ } else if (a instanceof char[]) {
+ DualPivotQuicksort.sort((char[]) a, BIG_DEPTH, 0, ((char[]) a).length);
+ } else if (a instanceof short[]) {
+ DualPivotQuicksort.sort((short[]) a, BIG_DEPTH, 0, ((short[]) a).length);
+ } else if (a instanceof float[]) {
+ DualPivotQuicksort.sort(null, (float[]) a, BIG_DEPTH, 0, ((float[]) a).length);
+ } else if (a instanceof double[]) {
+ DualPivotQuicksort.sort(null, (double[]) a, BIG_DEPTH, 0, ((double[]) a).length);
+ } else {
+ fail(a);
+ }
+ */
+ try {
+ if (a instanceof int[]) {
+ MethodHandleHolder.INT_SORTER_SORT.invoke(
+ null, (int[]) a, BIG_DEPTH, 0, ((int[]) a).length);
+ } else if (a instanceof long[]) {
+ MethodHandleHolder.LONG_SORTER_SORT.invoke(
+ null, (long[]) a, BIG_DEPTH, 0, ((long[]) a).length);
+ } else if (a instanceof byte[]) {
+ MethodHandleHolder.BYTE_SORT.invoke(
+ (byte[]) a, 0, ((byte[]) a).length);
+ } else if (a instanceof char[]) {
+ MethodHandleHolder.CHAR_SORT.invoke(
+ (char[]) a, BIG_DEPTH, 0, ((char[]) a).length);
+ } else if (a instanceof short[]) {
+ MethodHandleHolder.SHORT_SORT.invoke(
+ (short[]) a, BIG_DEPTH, 0, ((short[]) a).length);
+ } else if (a instanceof float[]) {
+ MethodHandleHolder.FLOAT_SORTER_SORT.invoke(
+ null, (float[]) a, BIG_DEPTH, 0, ((float[]) a).length);
+ } else if (a instanceof double[]) {
+ MethodHandleHolder.DOUBLE_SORTER_SORT.invoke(
+ null, (double[]) a, BIG_DEPTH, 0, ((double[]) a).length);
+ } else {
+ fail(a);
+ }
+ } catch (RuntimeException re) {
+ // propagate RuntimeException as it is.
+ throw re;
+ } catch (Throwable e) {
+ throw new AssertionError(e);
+ }
+ // END Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ }
+
+ @Override
+ public void sort(Object a, int low, int high) {
+ // BEGIN Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ /*
+ if (a instanceof int[]) {
+ DualPivotQuicksort.sort(null, (int[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof long[]) {
+ DualPivotQuicksort.sort(null, (long[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof byte[]) {
+ DualPivotQuicksort.sort((byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ DualPivotQuicksort.sort((char[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof short[]) {
+ DualPivotQuicksort.sort((short[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof float[]) {
+ DualPivotQuicksort.sort(null, (float[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof double[]) {
+ DualPivotQuicksort.sort(null, (double[]) a, BIG_DEPTH, low, high);
+ } else {
+ fail(a);
+ }
+
+ */
+ try {
+ if (a instanceof int[]) {
+ MethodHandleHolder.INT_SORTER_SORT.invoke(
+ null, (int[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof long[]) {
+ MethodHandleHolder.LONG_SORTER_SORT.invoke(
+ null, (long[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof byte[]) {
+ MethodHandleHolder.BYTE_SORT.invoke((byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ MethodHandleHolder.CHAR_SORT.invoke(
+ (char[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof short[]) {
+ MethodHandleHolder.SHORT_SORT.invoke(
+ (short[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof float[]) {
+ MethodHandleHolder.FLOAT_SORTER_SORT.invoke(
+ null, (float[]) a, BIG_DEPTH, low, high);
+ } else if (a instanceof double[]) {
+ MethodHandleHolder.DOUBLE_SORTER_SORT.invoke(
+ null, (double[]) a, BIG_DEPTH, low, high);
+ } else {
+ fail(a);
+ }
+ } catch (RuntimeException re) {
+ // propagate RuntimeException as it is.
+ throw re;
+ } catch (Throwable e) {
+ throw new AssertionError(e);
+ }
+ // END Android-changed: we can't place this class in java.util,
+ // using reflection to get these methods.
+ }
+
+ @Override
+ public void sort(Object[] a) {
+ fail(a);
+ }
+
+ @Override
+ public void sort(Object[] a, Comparator comparator) {
+ fail(a);
+ }
+ },
+
+ ARRAYS_SORT("Arrays.sort") {
+
+ @Override
+ public void sort(Object a) {
+ if (a instanceof int[]) {
+ Arrays.sort((int[]) a);
+ } else if (a instanceof long[]) {
+ Arrays.sort((long[]) a);
+ } else if (a instanceof byte[]) {
+ Arrays.sort((byte[]) a);
+ } else if (a instanceof char[]) {
+ Arrays.sort((char[]) a);
+ } else if (a instanceof short[]) {
+ Arrays.sort((short[]) a);
+ } else if (a instanceof float[]) {
+ Arrays.sort((float[]) a);
+ } else if (a instanceof double[]) {
+ Arrays.sort((double[]) a);
+ } else {
+ fail(a);
+ }
+ }
+
+ @Override
+ public void sort(Object a, int low, int high) {
+ if (a instanceof int[]) {
+ Arrays.sort((int[]) a, low, high);
+ } else if (a instanceof long[]) {
+ Arrays.sort((long[]) a, low, high);
+ } else if (a instanceof byte[]) {
+ Arrays.sort((byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ Arrays.sort((char[]) a, low, high);
+ } else if (a instanceof short[]) {
+ Arrays.sort((short[]) a, low, high);
+ } else if (a instanceof float[]) {
+ Arrays.sort((float[]) a, low, high);
+ } else if (a instanceof double[]) {
+ Arrays.sort((double[]) a, low, high);
+ } else {
+ fail(a);
+ }
+ }
+
+ @Override
+ public void sort(Object[] a) {
+ Arrays.sort(a);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void sort(Object[] a, Comparator comparator) {
+ Arrays.sort(a, comparator);
+ }
+ },
+
+ ARRAYS_PARALLEL_SORT("Arrays.parallelSort") {
+
+ @Override
+ public void sort(Object a) {
+ if (a instanceof int[]) {
+ Arrays.parallelSort((int[]) a);
+ } else if (a instanceof long[]) {
+ Arrays.parallelSort((long[]) a);
+ } else if (a instanceof byte[]) {
+ Arrays.parallelSort((byte[]) a);
+ } else if (a instanceof char[]) {
+ Arrays.parallelSort((char[]) a);
+ } else if (a instanceof short[]) {
+ Arrays.parallelSort((short[]) a);
+ } else if (a instanceof float[]) {
+ Arrays.parallelSort((float[]) a);
+ } else if (a instanceof double[]) {
+ Arrays.parallelSort((double[]) a);
+ } else {
+ fail(a);
+ }
+ }
+
+ @Override
+ public void sort(Object a, int low, int high) {
+ if (a instanceof int[]) {
+ Arrays.parallelSort((int[]) a, low, high);
+ } else if (a instanceof long[]) {
+ Arrays.parallelSort((long[]) a, low, high);
+ } else if (a instanceof byte[]) {
+ Arrays.parallelSort((byte[]) a, low, high);
+ } else if (a instanceof char[]) {
+ Arrays.parallelSort((char[]) a, low, high);
+ } else if (a instanceof short[]) {
+ Arrays.parallelSort((short[]) a, low, high);
+ } else if (a instanceof float[]) {
+ Arrays.parallelSort((float[]) a, low, high);
+ } else if (a instanceof double[]) {
+ Arrays.parallelSort((double[]) a, low, high);
+ } else {
+ fail(a);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void sort(Object[] a) {
+ Arrays.parallelSort((Comparable[]) a);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void sort(Object[] a, Comparator comparator) {
+ Arrays.parallelSort(a, comparator);
+ }
+ };
+
+ abstract public void sort(Object a);
+
+ abstract public void sort(Object a, int low, int high);
+
+ abstract public void sort(Object[] a);
+
+ abstract public void sort(Object[] a, Comparator comparator);
+
+ private SortingHelper(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ private static void fail(Object a) {
+ throw new RuntimeException("Unexpected type of array: " + a.getClass().getName());
+ }
+
+ private String name;
+
+ /**
+ * Parallelism level for sequential and parallel sorting.
+ */
+ private static final int SEQUENTIAL = 0;
+ private static final int PARALLEL = 87;
+
+ /**
+ * Heap sort will be invoked, if recursion depth is too big.
+ * Value is taken from DualPivotQuicksort.MAX_RECURSION_DEPTH.
+ */
+ private static final int BIG_DEPTH = 64 * (3 << 1);
+}
+
+// BEGIN Android-added: we can't place this class in java.util,
+// using reflection to get these methods.
+class MethodHandleHolder {
+ public static final MethodHandle INT_SORT;
+ public static final MethodHandle LONG_SORT;
+ public static final MethodHandle BYTE_SORT;
+ public static final MethodHandle CHAR_SORT;
+ public static final MethodHandle SHORT_SORT;
+ public static final MethodHandle FLOAT_SORT;
+ public static final MethodHandle DOUBLE_SORT;
+
+ public static final MethodHandle INT_SORTER_SORT;
+ public static final MethodHandle LONG_SORTER_SORT;
+ public static final MethodHandle FLOAT_SORTER_SORT;
+ public static final MethodHandle DOUBLE_SORTER_SORT;
+
+
+ static {
+ try {
+ INT_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", int[].class, int.class, int.class, int.class));
+ LONG_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", long[].class, int.class, int.class, int.class));
+ BYTE_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", byte[].class, int.class, int.class));
+ CHAR_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", char[].class, int.class, int.class, int.class));
+ SHORT_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", short[].class, int.class, int.class, int.class));
+ FLOAT_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", float[].class, int.class, int.class, int.class));
+ DOUBLE_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod(
+ "sort", double[].class, int.class, int.class, int.class));
+
+ Class<?> sorterClass = Class.forName("java.util.DualPivotQuicksort$Sorter");
+ INT_SORTER_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod("sort", sorterClass,
+ int[].class, int.class, int.class, int.class));
+ LONG_SORTER_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod("sort", sorterClass,
+ long[].class, int.class, int.class, int.class));
+ FLOAT_SORTER_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod("sort", sorterClass,
+ float[].class, int.class, int.class, int.class));
+ DOUBLE_SORTER_SORT = makeAccessibleAndUnreflect(
+ Class.forName("java.util.DualPivotQuicksort")
+ .getDeclaredMethod("sort", sorterClass,
+ double[].class, int.class, int.class, int.class));
+ } catch (Exception e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private static MethodHandle makeAccessibleAndUnreflect(Method method)
+ throws IllegalAccessException {
+ method.setAccessible(true);
+ return MethodHandles.lookup().unreflect(method);
+ }
+}
+// END Android-changed: we can't place this class in java.util,
+// using reflection to get these methods. \ No newline at end of file
diff --git a/ojluni/src/test/java/util/Arrays/SortingNearlySortedPrimitive.java b/ojluni/src/test/java/util/Arrays/SortingNearlySortedPrimitive.java
new file mode 100644
index 00000000000..5850b0b6129
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/SortingNearlySortedPrimitive.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2015 Goldman Sachs.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8154049
+ * @summary Tests the sorting of a large array of sorted primitive values,
+ * predominently for cases where the array is nearly sorted. This tests
+ * code that detects patterns in the array to determine if it is nearly
+ * sorted and if so employs and optimizes merge sort rather than a
+ * Dual-Pivot QuickSort.
+ *
+ * @run testng SortingNearlySortedPrimitive
+ */
+
+package test.java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringJoiner;
+import java.util.function.IntFunction;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+public class SortingNearlySortedPrimitive {
+
+ static final int BASE = 3;
+ static final int WIDTH = 4;
+ // Should be > DualPivotQuicksort.QUICKSORT_THRESHOLD
+ static final int PAD = 300;
+
+ Stream<int[]> createCombinations() {
+ // Create all combinations for the BASE value and double the WIDTH
+ // elements
+ // This is create various combinations of ascending, descending and
+ // equal runs to exercise the nearly sorted code paths
+ return IntStream.range(0, (int) Math.pow(BASE, 2 * WIDTH)).
+ mapToObj(this::createArray);
+ }
+
+ // Create an array which at either end is filled with -ve and +ve elements
+ // according to the base value and padded with zeros in between
+ int[] createArray(int v) {
+ int[] a = new int[WIDTH + PAD + WIDTH];
+
+ // Fill head of array
+ for (int j = 0; j < WIDTH; j++) {
+ a[j] = (v % BASE) - (BASE / 2);
+ v /= BASE;
+ }
+ // Fill tail of array
+ for (int j = 0; j < WIDTH; j++) {
+ a[WIDTH + PAD + j] = (v % BASE) - (BASE / 2);
+ v /= BASE;
+ }
+ return a;
+ }
+
+ @Test
+ public void testCombination() {
+ createCombinations().forEach(a -> {
+ try {
+ // Clone source array to ensure it is not modified
+ this.sortAndAssert(a.clone());
+ this.sortAndAssert(floatCopyFromInt(a));
+ this.sortAndAssert(doubleCopyFromInt(a));
+ this.sortAndAssert(longCopyFromInt(a));
+ this.sortAndAssert(shortCopyFromInt(a));
+ this.sortAndAssert(charCopyFromInt(a));
+ } catch (AssertionError sae) {
+ AssertionError ae = new AssertionError("Sort failed for " + arrayToString(a));
+ ae.addSuppressed(sae);
+ throw ae;
+ }
+ });
+ }
+
+ String arrayToString(int[] a) {
+ int[] l = Arrays.copyOfRange(a, 0, WIDTH + 2);
+ int[] r = Arrays.copyOfRange(a, a.length - (WIDTH + 2), a.length);
+ StringJoiner sj = new StringJoiner(",", "[", "]");
+ for (int i : l) {
+ sj.add(Integer.toString(i));
+ }
+ sj.add("...");
+ for (int i : r) {
+ sj.add(Integer.toString(i));
+ }
+ return sj.toString();
+ }
+
+
+ @DataProvider(name = "shapes")
+ public Object[][] createShapes() {
+ Stream<List<Object>> baseCases = Stream.of(
+ List.of("hiZeroLowTest", (IntFunction<int[]>) this::hiZeroLowData),
+ List.of("endLessThanTest", (IntFunction<int[]>) this::endLessThanData),
+ List.of("highFlatLowTest", (IntFunction<int[]>) this::highFlatLowData),
+ List.of("identicalTest", (IntFunction<int[]>) this::identicalData),
+ List.of("sortedReversedSortedTest", (IntFunction<int[]>) this::sortedReversedSortedData),
+ List.of("pairFlipTest", (IntFunction<int[]>) this::pairFlipData),
+ List.of("zeroHiTest", (IntFunction<int[]>) this::zeroHiData)
+ );
+
+ // Ensure the following inequality holds for certain sizes
+ // DualPivotQuicksort.QUICKSORT_THRESHOLD <= size - 1
+ // < DualPivotQuicksort.COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR
+ // This guarantees that code paths are taken for checking nearly sorted
+ // arrays for all primitive types
+ List<Integer> sizes = List.of(100, 1_000, 10_000, 1_000_000);
+ return baseCases.
+ flatMap(l -> sizes.stream().map(s -> append(l, s))).
+ toArray(Object[][]::new);
+ }
+
+ Object[] append(List<Object> l, Object value) {
+ List<Object> nl = new ArrayList<>(l);
+ nl.add(value);
+ return nl.toArray();
+ }
+
+ @Test(dataProvider = "shapes")
+ public void testShapes(String testName, IntFunction<int[]> dataMethod, int size) {
+ int[] intSourceArray = dataMethod.apply(size);
+
+ // Clone source array to ensure it is not modified
+ this.sortAndAssert(intSourceArray.clone());
+ this.sortAndAssert(floatCopyFromInt(intSourceArray));
+ this.sortAndAssert(doubleCopyFromInt(intSourceArray));
+ this.sortAndAssert(longCopyFromInt(intSourceArray));
+ this.sortAndAssert(shortCopyFromInt(intSourceArray));
+ this.sortAndAssert(charCopyFromInt(intSourceArray));
+ }
+
+ private float[] floatCopyFromInt(int[] src) {
+ float[] result = new float[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = src[i];
+ }
+ return result;
+ }
+
+ private double[] doubleCopyFromInt(int[] src) {
+ double[] result = new double[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = src[i];
+ }
+ return result;
+ }
+
+ private long[] longCopyFromInt(int[] src) {
+ long[] result = new long[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = src[i];
+ }
+ return result;
+ }
+
+ private short[] shortCopyFromInt(int[] src) {
+ short[] result = new short[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = (short) src[i];
+ }
+ return result;
+ }
+
+ private char[] charCopyFromInt(int[] src) {
+ char[] result = new char[src.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = (char) src[i];
+ }
+ return result;
+ }
+
+ private void sortAndAssert(int[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ }
+
+ private void sortAndAssert(char[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ }
+
+ private void sortAndAssert(short[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ }
+
+ private void sortAndAssert(double[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ }
+
+ private void sortAndAssert(float[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ }
+
+ private void sortAndAssert(long[] array) {
+ Arrays.sort(array);
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < array[i - 1]) {
+ throw new AssertionError("not sorted");
+ }
+ }
+ }
+
+ private int[] zeroHiData(int size) {
+ int[] array = new int[size];
+
+ int threeQuarters = (int) (size * 0.75);
+ for (int i = 0; i < threeQuarters; i++) {
+ array[i] = 0;
+ }
+ int k = 1;
+ for (int i = threeQuarters; i < size; i++) {
+ array[i] = k;
+ k++;
+ }
+
+ return array;
+ }
+
+ private int[] hiZeroLowData(int size) {
+ int[] array = new int[size];
+
+ int oneThird = size / 3;
+ for (int i = 0; i < oneThird; i++) {
+ array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ for (int i = oneThird; i < twoThirds; i++) {
+ array[i] = 0;
+ }
+ for (int i = twoThirds; i < size; i++) {
+ array[i] = oneThird - i + twoThirds;
+ }
+ return array;
+ }
+
+ private int[] highFlatLowData(int size) {
+ int[] array = new int[size];
+
+ int oneThird = size / 3;
+ for (int i = 0; i < oneThird; i++) {
+ array[i] = i;
+ }
+ int twoThirds = oneThird * 2;
+ int constant = oneThird - 1;
+ for (int i = oneThird; i < twoThirds; i++) {
+ array[i] = constant;
+ }
+ for (int i = twoThirds; i < size; i++) {
+ array[i] = constant - i + twoThirds;
+ }
+
+ return array;
+ }
+
+ private int[] identicalData(int size) {
+ int[] array = new int[size];
+ int listNumber = 24;
+
+ for (int i = 0; i < size; i++) {
+ array[i] = listNumber;
+ }
+
+ return array;
+ }
+
+ private int[] endLessThanData(int size) {
+ int[] array = new int[size];
+
+ for (int i = 0; i < size - 1; i++) {
+ array[i] = 3;
+ }
+ array[size - 1] = 1;
+
+ return array;
+ }
+
+ private int[] sortedReversedSortedData(int size) {
+ int[] array = new int[size];
+
+ for (int i = 0; i < size / 2; i++) {
+ array[i] = i;
+ }
+ int num = 0;
+ for (int i = size / 2; i < size; i++) {
+ array[i] = size - num;
+ num++;
+ }
+
+ return array;
+ }
+
+ private int[] pairFlipData(int size) {
+ int[] array = new int[size];
+
+ for (int i = 0; i < size; i++) {
+ array[i] = i;
+ }
+ for (int i = 0; i < size; i += 2) {
+ int temp = array[i];
+ array[i] = array[i + 1];
+ array[i + 1] = temp;
+ }
+
+ return array;
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/StreamAndSpliterator.java b/ojluni/src/test/java/util/Arrays/StreamAndSpliterator.java
new file mode 100644
index 00000000000..863ed5fb381
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/StreamAndSpliterator.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8037857
+ * @summary tests for stream and spliterator factory methods
+ * @run testng StreamAndSpliterator
+ */
+
+package test.java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Spliterators;
+
+import org.testng.Assert.ThrowingRunnable;
+
+import static org.testng.Assert.assertThrows;
+
+public class StreamAndSpliterator {
+ @Test
+ public void testStreamNPEs() {
+ assertThrowsNPE(() -> Arrays.stream((int[]) null, 0, 0));
+ assertThrowsNPE(() -> Arrays.stream((long[]) null, 0, 0));
+ assertThrowsNPE(() -> Arrays.stream((double[]) null, 0, 0));
+ assertThrowsNPE(() -> Arrays.stream((String[]) null, 0, 0));
+ }
+
+ @Test
+ public void testStreamAIOBEs() {
+ // origin > fence
+ assertThrowsAIOOB(() -> Arrays.stream(new int[]{}, 1, 0));
+ assertThrowsAIOOB(() -> Arrays.stream(new long[]{}, 1, 0));
+ assertThrowsAIOOB(() -> Arrays.stream(new double[]{}, 1, 0));
+ assertThrowsAIOOB(() -> Arrays.stream(new String[]{}, 1, 0));
+
+ // bad origin
+ assertThrowsAIOOB(() -> Arrays.stream(new int[]{}, -1, 0));
+ assertThrowsAIOOB(() -> Arrays.stream(new long[]{}, -1, 0));
+ assertThrowsAIOOB(() -> Arrays.stream(new double[]{}, -1, 0));
+ assertThrowsAIOOB(() -> Arrays.stream(new String[]{}, -1, 0));
+
+ // bad fence
+ assertThrowsAIOOB(() -> Arrays.stream(new int[]{}, 0, 1));
+ assertThrowsAIOOB(() -> Arrays.stream(new long[]{}, 0, 1));
+ assertThrowsAIOOB(() -> Arrays.stream(new double[]{}, 0, 1));
+ assertThrowsAIOOB(() -> Arrays.stream(new String[]{}, 0, 1));
+ }
+
+
+ @Test
+ public void testSpliteratorNPEs() {
+ assertThrowsNPE(() -> Arrays.spliterator((int[]) null, 0, 0));
+ assertThrowsNPE(() -> Arrays.spliterator((long[]) null, 0, 0));
+ assertThrowsNPE(() -> Arrays.spliterator((double[]) null, 0, 0));
+ assertThrowsNPE(() -> Arrays.spliterator((String[]) null, 0, 0));
+ }
+
+ @Test
+ public void testSpliteratorAIOBEs() {
+ // origin > fence
+ assertThrowsAIOOB(() -> Arrays.spliterator(new int[]{}, 1, 0));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new long[]{}, 1, 0));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new double[]{}, 1, 0));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new String[]{}, 1, 0));
+
+ // bad origin
+ assertThrowsAIOOB(() -> Arrays.spliterator(new int[]{}, -1, 0));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new long[]{}, -1, 0));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new double[]{}, -1, 0));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new String[]{}, -1, 0));
+
+ // bad fence
+ assertThrowsAIOOB(() -> Arrays.spliterator(new int[]{}, 0, 1));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new long[]{}, 0, 1));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new double[]{}, 0, 1));
+ assertThrowsAIOOB(() -> Arrays.spliterator(new String[]{}, 0, 1));
+ }
+
+
+ @Test
+ public void testSpliteratorNPEsFromSpliterators() {
+ assertThrowsNPE(() -> Spliterators.spliterator((int[]) null, 0, 0, 0));
+ assertThrowsNPE(() -> Spliterators.spliterator((long[]) null, 0, 0, 0));
+ assertThrowsNPE(() -> Spliterators.spliterator((double[]) null, 0, 0, 0));
+ assertThrowsNPE(() -> Spliterators.spliterator((String[]) null, 0, 0, 0));
+ }
+
+ @Test
+ public void testSpliteratorAIOBEsFromSpliterators() {
+ // origin > fence
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new int[]{}, 1, 0, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new long[]{}, 1, 0, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new double[]{}, 1, 0, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new String[]{}, 1, 0, 0));
+
+ // bad origin
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new int[]{}, -1, 0, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new long[]{}, -1, 0, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new double[]{}, -1, 0, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new String[]{}, -1, 0, 0));
+
+ // bad fence
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new int[]{}, 0, 1, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new long[]{}, 0, 1, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new double[]{}, 0, 1, 0));
+ assertThrowsAIOOB(() -> Spliterators.spliterator(new String[]{}, 0, 1, 0));
+ }
+
+ void assertThrowsNPE(ThrowingRunnable r) {
+ assertThrows(NullPointerException.class, r);
+ }
+
+ void assertThrowsAIOOB(ThrowingRunnable r) {
+ assertThrows(ArrayIndexOutOfBoundsException.class, r);
+ }
+}
diff --git a/ojluni/src/test/java/util/Arrays/TimSortStackSize.java b/ojluni/src/test/java/util/Arrays/TimSortStackSize.java
new file mode 100644
index 00000000000..f3828c3a178
--- /dev/null
+++ b/ojluni/src/test/java/util/Arrays/TimSortStackSize.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8011944
+ * @summary Test TimSort stack size
+ */
+
+package test.java.util.Arrays;
+
+import java.util.Arrays;
+import java.util.ArrayDeque;
+
+public class TimSortStackSize {
+
+ public static void main(String[] args) {
+ testComparableTimSort();
+ testTimSort();
+ }
+
+ static void testComparableTimSort() {
+ System.out.printf("testComparableTimSort()%n");
+ Arrays.sort(genData());
+ }
+
+ static void testTimSort() {
+ System.out.printf("testTimSort()%n");
+ Arrays.sort(genData(), Integer::compare);
+ }
+
+ private static final int MIN = 16;
+
+ private static final int BOUND1 = 2 * MIN + 1;
+ private static final int BOUND2 = BOUND1 + MIN + 2;
+ private static final int BOUND3 = BOUND1 + 1 + BOUND2;
+ private static final int BOUND4 = BOUND2 + 1 + BOUND3;
+ private static final int BOUND5 = BOUND3 + 1 + BOUND4;
+
+ static int build(int size, int B, ArrayDeque<Integer> chunks) {
+ chunks.addFirst(B);
+ if (size < BOUND1) {
+ chunks.addFirst(size);
+ return size;
+ }
+
+ int asize = (size + 2) / 2;
+ if (size >= BOUND2 && asize < BOUND1) {
+ asize = BOUND1;
+ } else if (size >= BOUND3 && asize < BOUND2) {
+ asize = BOUND2;
+ } else if (size >= BOUND4 && asize < BOUND3) {
+ asize = BOUND3;
+ } else if (size >= BOUND5 && asize < BOUND4) {
+ asize = BOUND4;
+ }
+ if (size - asize >= B) {
+ throw new AssertionError(" " + size + " , " + asize + " , " + B);
+ }
+ return build(asize, size - asize, chunks);
+ }
+
+ static Integer[] genData() {
+ ArrayDeque<Integer> chunks = new ArrayDeque<Integer>();
+ chunks.addFirst(MIN);
+
+ int B = MIN + 4;
+ int A = B + MIN + 1;
+
+ for (int i = 0; i < 8; i++) {
+ int eps = build(A, B, chunks);
+ B = B + A + 1;
+ A = B + eps + 1;
+ }
+ chunks.addFirst(B);
+ chunks.addFirst(A);
+ int total = 0;
+ for (Integer len : chunks) {
+ total += len;
+ }
+ int pow = MIN;
+ while (pow < total) {
+ pow += pow;
+ }
+ chunks.addLast(pow - total);
+ System.out.println(" Total: " + total);
+ Integer[] array = new Integer[pow];
+ int off = 0;
+ int pos = 0;
+ for (Integer len : chunks) {
+ for (int i = 0; i < len; i++) {
+ array[pos++] = Integer.valueOf(i == 0 ? 0 : 1);
+ }
+ off++;
+ }
+ return array;
+ }
+
+}
diff --git a/ojluni/src/test/java/util/BitSet/And.java b/ojluni/src/test/java/util/BitSet/And.java
new file mode 100644
index 00000000000..5b56eada014
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/And.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.util.BitSet;
+
+/**
+ * @test
+ * @bug 4201163
+ * @summary test the BitSet.and() method
+ */
+import java.util.BitSet;
+
+public final class And {
+ public static void main(String[] args) throws Exception {
+ BitSet a = new BitSet();
+ BitSet b = new BitSet();
+
+ a.set(0);
+ a.set(70);
+ b.set(40);
+ a.and(b);
+ if (a.length() != 0)
+ throw new RuntimeException("Incorrect length after and().");
+ }
+}
diff --git a/ojluni/src/test/java/util/BitSet/BSMethods.java b/ojluni/src/test/java/util/BitSet/BSMethods.java
new file mode 100644
index 00000000000..26243c9e5d4
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/BSMethods.java
@@ -0,0 +1,988 @@
+/*
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4098239 4107540 4080736 4261102 4274710 4305272
+ * 4979017 4979028 4979031 5030267 6222207 8040806
+ * @summary Test the operation of the methods of BitSet class
+ * @author Mike McCloskey, Martin Buchholz
+ * @run main/othervm BSMethods
+ * @key randomness
+ */
+
+package test.java.util.BitSet;
+
+import java.util.*;
+
+/**
+ * This is a simple test class created to run tests on the BitSet class.
+ *
+ */
+public class BSMethods {
+
+ private static Random generator = new Random();
+ private static boolean failure = false;
+
+ private static void fail(String diagnostic) {
+ new Error(diagnostic).printStackTrace();
+ failure = true;
+ }
+
+ private static void check(boolean condition) {
+ check(condition, "something's fishy");
+ }
+
+ private static void check(boolean condition, String diagnostic) {
+ if (! condition)
+ fail(diagnostic);
+ }
+
+ private static void checkEmpty(BitSet s) {
+ check(s.isEmpty(), "isEmpty");
+ check(s.length() == 0, "length");
+ check(s.cardinality() == 0, "cardinality");
+ check(s.equals(new BitSet()) , "equals");
+ check(s.equals(new BitSet(0)) , "equals");
+ check(s.equals(new BitSet(127)), "equals");
+ check(s.equals(new BitSet(128)), "equals");
+ check(s.nextSetBit(0) == -1, "nextSetBit");
+ check(s.nextSetBit(127) == -1, "nextSetBit");
+ check(s.nextSetBit(128) == -1, "nextSetBit");
+ check(s.nextClearBit(0) == 0, "nextClearBit");
+ check(s.nextClearBit(127) == 127, "nextClearBit");
+ check(s.nextClearBit(128) == 128, "nextClearBit");
+ check(s.toString().equals("{}"), "toString");
+ check(! s.get(0), "get");
+ }
+
+ private static BitSet makeSet(int... elts) {
+ BitSet s = new BitSet();
+ for (int elt : elts)
+ s.set(elt);
+ return s;
+ }
+
+ private static void checkEquality(BitSet s, BitSet t) {
+ checkSanity(s, t);
+ check(s.equals(t), "equals");
+ check(s.toString().equals(t.toString()), "equal strings");
+ check(s.length() == t.length(), "equal lengths");
+ check(s.cardinality() == t.cardinality(), "equal cardinalities");
+ }
+
+ private static void checkSanity(BitSet... sets) {
+ for (BitSet s : sets) {
+ int len = s.length();
+ int cardinality1 = s.cardinality();
+ int cardinality2 = 0;
+ for (int i = s.nextSetBit(0); i >= 0; i = s.nextSetBit(i+1)) {
+ check(s.get(i));
+ cardinality2++;
+ }
+ check(s.nextSetBit(len) == -1, "last set bit");
+ check(s.nextClearBit(len) == len, "last set bit");
+ check(s.isEmpty() == (len == 0), "emptiness");
+ check(cardinality1 == cardinality2, "cardinalities");
+ check(len <= s.size(), "length <= size");
+ check(len >= 0, "length >= 0");
+ check(cardinality1 >= 0, "cardinality >= 0");
+ }
+ }
+
+ public static void main(String[] args) {
+
+ //testFlipTime();
+
+ // These are the single bit versions
+ testSetGetClearFlip();
+
+ // Test the ranged versions
+ testClear();
+
+ testFlip();
+ testSet();
+ testGet();
+
+ // BitSet interaction calls
+ testAndNot();
+ testAnd();
+ testOr();
+ testXor();
+
+ // Miscellaneous calls
+ testLength();
+ testEquals();
+ testNextSetBit();
+ testNextClearBit();
+ testIntersects();
+ testCardinality();
+ testEmpty();
+ testEmpty2();
+ testToString();
+ testLogicalIdentities();
+
+ if (failure)
+ throw new RuntimeException("One or more BitSet failures.");
+ }
+
+ private static void report(String testName, int failCount) {
+ System.err.println(testName+": " +
+ (failCount==0 ? "Passed":"Failed("+failCount+")"));
+ if (failCount > 0)
+ failure = true;
+ }
+
+ private static void testFlipTime() {
+ // Make a fairly random bitset
+ BitSet b1 = new BitSet();
+ b1.set(1000);
+ long startTime = System.currentTimeMillis();
+ for(int x=0; x<100000; x++) {
+ b1.flip(100, 900);
+ }
+ long endTime = System.currentTimeMillis();
+ long total = endTime - startTime;
+ System.out.println("Multiple word flip Time "+total);
+
+ startTime = System.currentTimeMillis();
+ for(int x=0; x<100000; x++) {
+ b1.flip(2, 44);
+ }
+ endTime = System.currentTimeMillis();
+ total = endTime - startTime;
+ System.out.println("Single word flip Time "+total);
+ }
+
+ private static void testNextSetBit() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ BitSet testSet = new BitSet();
+ int[] history = new int[numberOfSetBits];
+
+ // Set some random bits and remember them
+ int nextBitToSet = 0;
+ for (int x=0; x<numberOfSetBits; x++) {
+ nextBitToSet += generator.nextInt(30)+1;
+ history[x] = nextBitToSet;
+ testSet.set(nextBitToSet);
+ }
+
+ // Verify their retrieval using nextSetBit()
+ int historyIndex = 0;
+ for(int x=testSet.nextSetBit(0); x>=0; x=testSet.nextSetBit(x+1)) {
+ if (x != history[historyIndex++])
+ failCount++;
+ }
+
+ checkSanity(testSet);
+ }
+
+ report("NextSetBit ", failCount);
+ }
+
+ private static void testNextClearBit() {
+ int failCount = 0;
+
+ for (int i=0; i<1000; i++) {
+ BitSet b = new BitSet(256);
+ int[] history = new int[10];
+
+ // Set all the bits
+ for (int x=0; x<256; x++)
+ b.set(x);
+
+ // Clear some random bits and remember them
+ int nextBitToClear = 0;
+ for (int x=0; x<10; x++) {
+ nextBitToClear += generator.nextInt(24)+1;
+ history[x] = nextBitToClear;
+ b.clear(nextBitToClear);
+ }
+
+ // Verify their retrieval using nextClearBit()
+ int historyIndex = 0;
+ for(int x=b.nextClearBit(0); x<256; x=b.nextClearBit(x+1)) {
+ if (x != history[historyIndex++])
+ failCount++;
+ }
+
+ checkSanity(b);
+ }
+
+ // regression test for 4350178
+ BitSet bs = new BitSet();
+ if (bs.nextClearBit(0) != 0)
+ failCount++;
+ for (int i = 0; i < 64; i++) {
+ bs.set(i);
+ if (bs.nextClearBit(0) != i+1)
+ failCount++;
+ }
+
+ checkSanity(bs);
+
+ report("NextClearBit ", failCount);
+ }
+
+ private static void testSetGetClearFlip() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet testSet = new BitSet();
+ HashSet<Integer> history = new HashSet<Integer>();
+
+ // Set a random number of bits in random places
+ // up to a random maximum
+ int nextBitToSet = 0;
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+ for (int x=0; x<numberOfSetBits; x++) {
+ nextBitToSet = generator.nextInt(highestPossibleSetBit);
+ history.add(new Integer(nextBitToSet));
+ testSet.set(nextBitToSet);
+ }
+
+ // Make sure each bit is set appropriately
+ for (int x=0; x<highestPossibleSetBit; x++) {
+ if (testSet.get(x) != history.contains(new Integer(x)))
+ failCount++;
+ }
+
+ // Clear the bits
+ Iterator<Integer> setBitIterator = history.iterator();
+ while (setBitIterator.hasNext()) {
+ Integer setBit = setBitIterator.next();
+ testSet.clear(setBit.intValue());
+ }
+
+ // Verify they were cleared
+ for (int x=0; x<highestPossibleSetBit; x++)
+ if (testSet.get(x))
+ failCount++;
+ if(testSet.length() != 0)
+ failCount++;
+
+ // Set them with set(int, boolean)
+ setBitIterator = history.iterator();
+ while (setBitIterator.hasNext()) {
+ Integer setBit = setBitIterator.next();
+ testSet.set(setBit.intValue(), true);
+ }
+
+ // Make sure each bit is set appropriately
+ for (int x=0; x<highestPossibleSetBit; x++) {
+ if (testSet.get(x) != history.contains(new Integer(x)))
+ failCount++;
+ }
+
+ // Clear them with set(int, boolean)
+ setBitIterator = history.iterator();
+ while (setBitIterator.hasNext()) {
+ Integer setBit = (Integer)setBitIterator.next();
+ testSet.set(setBit.intValue(), false);
+ }
+
+ // Verify they were cleared
+ for (int x=0; x<highestPossibleSetBit; x++)
+ if (testSet.get(x))
+ failCount++;
+ if(testSet.length() != 0)
+ failCount++;
+
+ // Flip them on
+ setBitIterator = history.iterator();
+ while (setBitIterator.hasNext()) {
+ Integer setBit = (Integer)setBitIterator.next();
+ testSet.flip(setBit.intValue());
+ }
+
+ // Verify they were flipped
+ for (int x=0; x<highestPossibleSetBit; x++) {
+ if (testSet.get(x) != history.contains(new Integer(x)))
+ failCount++;
+ }
+
+ // Flip them off
+ setBitIterator = history.iterator();
+ while (setBitIterator.hasNext()) {
+ Integer setBit = (Integer)setBitIterator.next();
+ testSet.flip(setBit.intValue());
+ }
+
+ // Verify they were flipped
+ for (int x=0; x<highestPossibleSetBit; x++)
+ if (testSet.get(x))
+ failCount++;
+ if(testSet.length() != 0)
+ failCount++;
+
+ checkSanity(testSet);
+ }
+
+ report("SetGetClearFlip ", failCount);
+ }
+
+ private static void testAndNot() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ BitSet b2 = new BitSet(256);
+
+ // Set some random bits in first set and remember them
+ int nextBitToSet = 0;
+ for (int x=0; x<10; x++)
+ b1.set(generator.nextInt(255));
+
+ // Set some random bits in second set and remember them
+ for (int x=10; x<20; x++)
+ b2.set(generator.nextInt(255));
+
+ // andNot the sets together
+ BitSet b3 = (BitSet)b1.clone();
+ b3.andNot(b2);
+
+ // Examine each bit of b3 for errors
+ for(int x=0; x<256; x++) {
+ boolean bit1 = b1.get(x);
+ boolean bit2 = b2.get(x);
+ boolean bit3 = b3.get(x);
+ if (!(bit3 == (bit1 & (!bit2))))
+ failCount++;
+ }
+ checkSanity(b1, b2, b3);
+ }
+
+ report("AndNot ", failCount);
+ }
+
+ private static void testAnd() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ BitSet b2 = new BitSet(256);
+
+ // Set some random bits in first set and remember them
+ int nextBitToSet = 0;
+ for (int x=0; x<10; x++)
+ b1.set(generator.nextInt(255));
+
+ // Set more random bits in second set and remember them
+ for (int x=10; x<20; x++)
+ b2.set(generator.nextInt(255));
+
+ // And the sets together
+ BitSet b3 = (BitSet)b1.clone();
+ b3.and(b2);
+
+ // Examine each bit of b3 for errors
+ for(int x=0; x<256; x++) {
+ boolean bit1 = b1.get(x);
+ boolean bit2 = b2.get(x);
+ boolean bit3 = b3.get(x);
+ if (!(bit3 == (bit1 & bit2)))
+ failCount++;
+ }
+ checkSanity(b1, b2, b3);
+ }
+
+ // `and' that happens to clear the last word
+ BitSet b4 = makeSet(2, 127);
+ b4.and(makeSet(2, 64));
+ checkSanity(b4);
+ if (!(b4.equals(makeSet(2))))
+ failCount++;
+
+ report("And ", failCount);
+ }
+
+ private static void testOr() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ BitSet b2 = new BitSet(256);
+ int[] history = new int[20];
+
+ // Set some random bits in first set and remember them
+ int nextBitToSet = 0;
+ for (int x=0; x<10; x++) {
+ nextBitToSet = generator.nextInt(255);
+ history[x] = nextBitToSet;
+ b1.set(nextBitToSet);
+ }
+
+ // Set more random bits in second set and remember them
+ for (int x=10; x<20; x++) {
+ nextBitToSet = generator.nextInt(255);
+ history[x] = nextBitToSet;
+ b2.set(nextBitToSet);
+ }
+
+ // Or the sets together
+ BitSet b3 = (BitSet)b1.clone();
+ b3.or(b2);
+
+ // Verify the set bits of b3 from the history
+ int historyIndex = 0;
+ for(int x=0; x<20; x++) {
+ if (!b3.get(history[x]))
+ failCount++;
+ }
+
+ // Examine each bit of b3 for errors
+ for(int x=0; x<256; x++) {
+ boolean bit1 = b1.get(x);
+ boolean bit2 = b2.get(x);
+ boolean bit3 = b3.get(x);
+ if (!(bit3 == (bit1 | bit2)))
+ failCount++;
+ }
+ checkSanity(b1, b2, b3);
+ }
+
+ report("Or ", failCount);
+ }
+
+ private static void testXor() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ BitSet b2 = new BitSet(256);
+
+ // Set some random bits in first set and remember them
+ int nextBitToSet = 0;
+ for (int x=0; x<10; x++)
+ b1.set(generator.nextInt(255));
+
+ // Set more random bits in second set and remember them
+ for (int x=10; x<20; x++)
+ b2.set(generator.nextInt(255));
+
+ // Xor the sets together
+ BitSet b3 = (BitSet)b1.clone();
+ b3.xor(b2);
+
+ // Examine each bit of b3 for errors
+ for(int x=0; x<256; x++) {
+ boolean bit1 = b1.get(x);
+ boolean bit2 = b2.get(x);
+ boolean bit3 = b3.get(x);
+ if (!(bit3 == (bit1 ^ bit2)))
+ failCount++;
+ }
+ checkSanity(b1, b2, b3);
+ b3.xor(b3); checkEmpty(b3);
+ }
+
+ // xor that happens to clear the last word
+ BitSet b4 = makeSet(2, 64, 127);
+ b4.xor(makeSet(64, 127));
+ checkSanity(b4);
+ if (!(b4.equals(makeSet(2))))
+ failCount++;
+
+ report("Xor ", failCount);
+ }
+
+ private static void testEquals() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ // Create BitSets of different sizes
+ BitSet b1 = new BitSet(generator.nextInt(1000)+1);
+ BitSet b2 = new BitSet(generator.nextInt(1000)+1);
+
+ // Set some random bits
+ int nextBitToSet = 0;
+ for (int x=0; x<10; x++) {
+ nextBitToSet += generator.nextInt(50)+1;
+ b1.set(nextBitToSet);
+ b2.set(nextBitToSet);
+ }
+
+ // Verify their equality despite different storage sizes
+ if (!b1.equals(b2))
+ failCount++;
+ checkEquality(b1,b2);
+ }
+
+ report("Equals ", failCount);
+ }
+
+ private static void testLength() {
+ int failCount = 0;
+
+ // Test length after set
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ int highestSetBit = 0;
+
+ for(int x=0; x<100; x++) {
+ int nextBitToSet = generator.nextInt(255);
+ if (nextBitToSet > highestSetBit)
+ highestSetBit = nextBitToSet;
+ b1.set(nextBitToSet);
+ if (b1.length() != highestSetBit + 1)
+ failCount++;
+ }
+ checkSanity(b1);
+ }
+
+ // Test length after flip
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ for(int x=0; x<100; x++) {
+ // Flip a random range twice
+ int rangeStart = generator.nextInt(100);
+ int rangeEnd = rangeStart + generator.nextInt(100);
+ b1.flip(rangeStart);
+ b1.flip(rangeStart);
+ if (b1.length() != 0)
+ failCount++;
+ b1.flip(rangeStart, rangeEnd);
+ b1.flip(rangeStart, rangeEnd);
+ if (b1.length() != 0)
+ failCount++;
+ }
+ checkSanity(b1);
+ }
+
+ // Test length after or
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ BitSet b2 = new BitSet(256);
+ int bit1 = generator.nextInt(100);
+ int bit2 = generator.nextInt(100);
+ int highestSetBit = (bit1 > bit2) ? bit1 : bit2;
+ b1.set(bit1);
+ b2.set(bit2);
+ b1.or(b2);
+ if (b1.length() != highestSetBit + 1)
+ failCount++;
+ checkSanity(b1, b2);
+ }
+
+ report("Length ", failCount);
+ }
+
+ private static void testClear() {
+ int failCount = 0;
+
+ for (int i=0; i<1000; i++) {
+ BitSet b1 = new BitSet();
+
+ // Make a fairly random bitset
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++)
+ b1.set(generator.nextInt(highestPossibleSetBit));
+
+ BitSet b2 = (BitSet)b1.clone();
+
+ // Clear out a random range
+ int rangeStart = generator.nextInt(100);
+ int rangeEnd = rangeStart + generator.nextInt(100);
+
+ // Use the clear(int, int) call on b1
+ b1.clear(rangeStart, rangeEnd);
+
+ // Use a loop on b2
+ for (int x=rangeStart; x<rangeEnd; x++)
+ b2.clear(x);
+
+ // Verify their equality
+ if (!b1.equals(b2)) {
+ System.out.println("rangeStart = " + rangeStart);
+ System.out.println("rangeEnd = " + rangeEnd);
+ System.out.println("b1 = " + b1);
+ System.out.println("b2 = " + b2);
+ failCount++;
+ }
+ checkEquality(b1,b2);
+ }
+
+ report("Clear ", failCount);
+ }
+
+ private static void testSet() {
+ int failCount = 0;
+
+ // Test set(int, int)
+ for (int i=0; i<1000; i++) {
+ BitSet b1 = new BitSet();
+
+ // Make a fairly random bitset
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++)
+ b1.set(generator.nextInt(highestPossibleSetBit));
+
+ BitSet b2 = (BitSet)b1.clone();
+
+ // Set a random range
+ int rangeStart = generator.nextInt(100);
+ int rangeEnd = rangeStart + generator.nextInt(100);
+
+ // Use the set(int, int) call on b1
+ b1.set(rangeStart, rangeEnd);
+
+ // Use a loop on b2
+ for (int x=rangeStart; x<rangeEnd; x++)
+ b2.set(x);
+
+ // Verify their equality
+ if (!b1.equals(b2)) {
+ System.out.println("Set 1");
+ System.out.println("rangeStart = " + rangeStart);
+ System.out.println("rangeEnd = " + rangeEnd);
+ System.out.println("b1 = " + b1);
+ System.out.println("b2 = " + b2);
+ failCount++;
+ }
+ checkEquality(b1,b2);
+ }
+
+ // Test set(int, int, boolean)
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet();
+
+ // Make a fairly random bitset
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++)
+ b1.set(generator.nextInt(highestPossibleSetBit));
+
+ BitSet b2 = (BitSet)b1.clone();
+ boolean setOrClear = generator.nextBoolean();
+
+ // Set a random range
+ int rangeStart = generator.nextInt(100);
+ int rangeEnd = rangeStart + generator.nextInt(100);
+
+ // Use the set(int, int, boolean) call on b1
+ b1.set(rangeStart, rangeEnd, setOrClear);
+
+ // Use a loop on b2
+ for (int x=rangeStart; x<rangeEnd; x++)
+ b2.set(x, setOrClear);
+
+ // Verify their equality
+ if (!b1.equals(b2)) {
+ System.out.println("Set 2");
+ System.out.println("b1 = " + b1);
+ System.out.println("b2 = " + b2);
+ failCount++;
+ }
+ checkEquality(b1,b2);
+ }
+
+ report("Set ", failCount);
+ }
+
+ private static void testFlip() {
+ int failCount = 0;
+
+ for (int i=0; i<1000; i++) {
+ BitSet b1 = new BitSet();
+
+ // Make a fairly random bitset
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++)
+ b1.set(generator.nextInt(highestPossibleSetBit));
+
+ BitSet b2 = (BitSet)b1.clone();
+
+ // Flip a random range
+ int rangeStart = generator.nextInt(100);
+ int rangeEnd = rangeStart + generator.nextInt(100);
+
+ // Use the flip(int, int) call on b1
+ b1.flip(rangeStart, rangeEnd);
+
+ // Use a loop on b2
+ for (int x=rangeStart; x<rangeEnd; x++)
+ b2.flip(x);
+
+ // Verify their equality
+ if (!b1.equals(b2))
+ failCount++;
+ checkEquality(b1,b2);
+ }
+
+ report("Flip ", failCount);
+ }
+
+ private static void testGet() {
+ int failCount = 0;
+
+ for (int i=0; i<1000; i++) {
+ BitSet b1 = new BitSet();
+
+ // Make a fairly random bitset
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++)
+ b1.set(generator.nextInt(highestPossibleSetBit));
+
+ // Get a new set from a random range
+ int rangeStart = generator.nextInt(100);
+ int rangeEnd = rangeStart + generator.nextInt(100);
+
+ BitSet b2 = b1.get(rangeStart, rangeEnd);
+
+ BitSet b3 = new BitSet();
+ for(int x=rangeStart; x<rangeEnd; x++)
+ b3.set(x-rangeStart, b1.get(x));
+
+ // Verify their equality
+ if (!b2.equals(b3)) {
+ System.out.println("start="+rangeStart);
+ System.out.println("end="+rangeEnd);
+ System.out.println(b1);
+ System.out.println(b2);
+ System.out.println(b3);
+ failCount++;
+ }
+ checkEquality(b2,b3);
+ }
+
+ report("Get ", failCount);
+ }
+
+
+ private static void testIntersects() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+ BitSet b2 = new BitSet(256);
+
+ // Set some random bits in first set
+ int nextBitToSet = 0;
+ for (int x=0; x<30; x++) {
+ nextBitToSet = generator.nextInt(255);
+ b1.set(nextBitToSet);
+ }
+
+ // Set more random bits in second set
+ for (int x=0; x<30; x++) {
+ nextBitToSet = generator.nextInt(255);
+ b2.set(nextBitToSet);
+ }
+
+ // Make sure they intersect
+ nextBitToSet = generator.nextInt(255);
+ b1.set(nextBitToSet);
+ b2.set(nextBitToSet);
+
+ if (!b1.intersects(b2))
+ failCount++;
+
+ // Remove the common set bits
+ b1.andNot(b2);
+
+ // Make sure they don't intersect
+ if (b1.intersects(b2))
+ failCount++;
+
+ checkSanity(b1, b2);
+ }
+
+ report("Intersects ", failCount);
+ }
+
+ private static void testCardinality() {
+ int failCount = 0;
+
+ for (int i=0; i<100; i++) {
+ BitSet b1 = new BitSet(256);
+
+ // Set a random number of increasing bits
+ int nextBitToSet = 0;
+ int iterations = generator.nextInt(20)+1;
+ for (int x=0; x<iterations; x++) {
+ nextBitToSet += generator.nextInt(20)+1;
+ b1.set(nextBitToSet);
+ }
+
+ if (b1.cardinality() != iterations) {
+ System.out.println("Iterations is "+iterations);
+ System.out.println("Cardinality is "+b1.cardinality());
+ failCount++;
+ }
+
+ checkSanity(b1);
+ }
+
+ report("Cardinality ", failCount);
+ }
+
+ private static void testEmpty() {
+ int failCount = 0;
+
+ BitSet b1 = new BitSet();
+ if (!b1.isEmpty())
+ failCount++;
+
+ int nextBitToSet = 0;
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+ for (int x=0; x<numberOfSetBits; x++) {
+ nextBitToSet = generator.nextInt(highestPossibleSetBit);
+ b1.set(nextBitToSet);
+ if (b1.isEmpty())
+ failCount++;
+ b1.clear(nextBitToSet);
+ if (!b1.isEmpty())
+ failCount++;
+ }
+
+ report("Empty ", failCount);
+ }
+
+ private static void testEmpty2() {
+ {BitSet t = new BitSet(); t.set(100); t.clear(3,600); checkEmpty(t);}
+ checkEmpty(new BitSet(0));
+ checkEmpty(new BitSet(342));
+ BitSet s = new BitSet(0);
+ checkEmpty(s);
+ s.clear(92); checkEmpty(s);
+ s.clear(127,127); checkEmpty(s);
+ s.set(127,127); checkEmpty(s);
+ s.set(128,128); checkEmpty(s);
+ BitSet empty = new BitSet();
+ {BitSet t = new BitSet(); t.and (empty); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.or (empty); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.xor (empty); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.andNot(empty); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.and (t); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.or (t); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.xor (t); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.andNot(t); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.and(makeSet(1)); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.and(makeSet(127)); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.and(makeSet(128)); checkEmpty(t);}
+ {BitSet t = new BitSet(); t.flip(7);t.flip(7); checkEmpty(t);}
+ {BitSet t = new BitSet(); checkEmpty(t.get(200,300));}
+ {BitSet t = makeSet(2,5); check(t.get(2,6).equals(makeSet(0,3)),"");}
+ }
+
+ private static void testToString() {
+ check(new BitSet().toString().equals("{}"));
+ check(makeSet(2,3,42,43,234).toString().equals("{2, 3, 42, 43, 234}"));
+
+ final long MB = 1024*1024;
+ if (Runtime.getRuntime().maxMemory() >= 512*MB) {
+ // only run it if we have enough memory
+ try {
+ check(makeSet(Integer.MAX_VALUE-1).toString().equals(
+ "{" + (Integer.MAX_VALUE-1) + "}"));
+ check(makeSet(Integer.MAX_VALUE).toString().equals(
+ "{" + Integer.MAX_VALUE + "}"));
+ check(makeSet(0, 1, Integer.MAX_VALUE-1, Integer.MAX_VALUE).toString().equals(
+ "{0, 1, " + (Integer.MAX_VALUE-1) + ", " + Integer.MAX_VALUE + "}"));
+ } catch (IndexOutOfBoundsException exc) {
+ fail("toString() with indices near MAX_VALUE");
+ }
+ }
+ }
+
+ private static void testLogicalIdentities() {
+ int failCount = 0;
+
+ // Verify that (!b1)|(!b2) == !(b1&b2)
+ for (int i=0; i<50; i++) {
+ // Construct two fairly random bitsets
+ BitSet b1 = new BitSet();
+ BitSet b2 = new BitSet();
+
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++) {
+ b1.set(generator.nextInt(highestPossibleSetBit));
+ b2.set(generator.nextInt(highestPossibleSetBit));
+ }
+
+ BitSet b3 = (BitSet) b1.clone();
+ BitSet b4 = (BitSet) b2.clone();
+
+ for (int x=0; x<highestPossibleSetBit; x++) {
+ b1.flip(x);
+ b2.flip(x);
+ }
+ b1.or(b2);
+ b3.and(b4);
+ for (int x=0; x<highestPossibleSetBit; x++)
+ b3.flip(x);
+ if (!b1.equals(b3))
+ failCount++;
+ checkSanity(b1, b2, b3, b4);
+ }
+
+ // Verify that (b1&(!b2)|(b2&(!b1) == b1^b2
+ for (int i=0; i<50; i++) {
+ // Construct two fairly random bitsets
+ BitSet b1 = new BitSet();
+ BitSet b2 = new BitSet();
+
+ int numberOfSetBits = generator.nextInt(100) + 1;
+ int highestPossibleSetBit = generator.nextInt(1000) + 1;
+
+ for (int x=0; x<numberOfSetBits; x++) {
+ b1.set(generator.nextInt(highestPossibleSetBit));
+ b2.set(generator.nextInt(highestPossibleSetBit));
+ }
+
+ BitSet b3 = (BitSet) b1.clone();
+ BitSet b4 = (BitSet) b2.clone();
+ BitSet b5 = (BitSet) b1.clone();
+ BitSet b6 = (BitSet) b2.clone();
+
+ for (int x=0; x<highestPossibleSetBit; x++)
+ b2.flip(x);
+ b1.and(b2);
+ for (int x=0; x<highestPossibleSetBit; x++)
+ b3.flip(x);
+ b3.and(b4);
+ b1.or(b3);
+ b5.xor(b6);
+ if (!b1.equals(b5))
+ failCount++;
+ checkSanity(b1, b2, b3, b4, b5, b6);
+ }
+ report("Logical Identities ", failCount);
+ }
+
+}
diff --git a/ojluni/src/test/java/util/BitSet/ImportExport.java b/ojluni/src/test/java/util/BitSet/ImportExport.java
new file mode 100644
index 00000000000..83417611f44
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/ImportExport.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5037068
+ * @summary Test import/export constructors and methods
+ * @author Martin Buchholz
+ * @key randomness
+ */
+
+package test.java.util.BitSet;
+
+import java.nio.*;
+import java.util.*;
+
+public class ImportExport {
+ final Random rnd = new Random();
+
+ void equal(byte[] x, byte[] y) {
+ check(Arrays.equals(x, y));
+ }
+
+ void equal(long[] x, long[] y) {
+ check(Arrays.equals(x, y));
+ }
+
+ void equal(byte[] bytes, BitSet s) {
+ equal(s, BitSet.valueOf(bytes));
+ equal(s, BitSet.valueOf(ByteBuffer.wrap(bytes)));
+ equal(s, BitSet.valueOf(
+ ByteBuffer.wrap(
+ Arrays.copyOf(bytes, bytes.length + 8 + rnd.nextInt(8)))
+ .order(ByteOrder.LITTLE_ENDIAN)
+ .asLongBuffer()));
+ }
+
+ void checkEmptyBitSet(BitSet s) {
+ equal(s.toByteArray(), new byte[0]);
+ equal(s.toLongArray(), new long[0]);
+ check(s.isEmpty());
+ }
+
+ void test(String[] args) throws Throwable {
+ for (int i = 0; i < 17; i++) {
+ byte[] bytes = new byte[i];
+ BitSet s = new BitSet();
+ equal(bytes, s);
+ equal(BitSet.valueOf(bytes).toByteArray(), new byte[0]);
+ if (i > 0) {
+ int k = rnd.nextInt(i);
+ for (int j = 0; j < 8; j++) {
+ bytes[k] |= 1 << j;
+ s.set(8*k+j);
+ equal(bytes, s);
+ byte[] expected = new byte[k+1]; expected[k] = bytes[k];
+ equal(BitSet.valueOf(bytes).toByteArray(), expected);
+ ByteBuffer bb = ByteBuffer.wrap(bytes);
+ bb.position(k);
+ equal(BitSet.valueOf(bb).toByteArray(),
+ new byte[]{bytes[k]});
+ }
+ }
+ }
+ for (int i = 0; i < 100; i++) {
+ byte[] bytes = new byte[rnd.nextInt(17)];
+ for (int j = 0; j < bytes.length; j++)
+ bytes[j] = (byte) rnd.nextInt(0x100);
+ BitSet s = BitSet.valueOf(bytes);
+ byte[] expected = s.toByteArray();
+ equal(expected.length, (s.length()+7)/8);
+ if (bytes.length == 0)
+ continue;
+ if (expected.length > 0)
+ check(expected[expected.length-1] != 0);
+ if (bytes[bytes.length-1] != 0)
+ equal(bytes, expected);
+ int n = rnd.nextInt(8 * bytes.length);
+ equal(s.get(n), ((bytes[n/8] & (1<<(n%8))) != 0));
+ }
+
+ for (int i = 0; i < 3; i++) {
+ checkEmptyBitSet(BitSet.valueOf(new byte[i]));
+ checkEmptyBitSet(BitSet.valueOf(ByteBuffer.wrap(new byte[i])));
+ checkEmptyBitSet(BitSet.valueOf(new byte[i*64]));
+ checkEmptyBitSet(BitSet.valueOf(ByteBuffer.wrap(new byte[i*64])));
+ checkEmptyBitSet(BitSet.valueOf(new long[i]));
+ checkEmptyBitSet(BitSet.valueOf(LongBuffer.wrap(new long[i])));
+ }
+
+ {
+ long[] longs = new long[rnd.nextInt(10)];
+ for (int i = 0; i < longs.length; i++)
+ longs[i] = rnd.nextLong();
+ LongBuffer b1 = LongBuffer.wrap(longs);
+ LongBuffer b2 = LongBuffer.allocate(longs.length + 10);
+ for (int i = 0; i < b2.limit(); i++)
+ b2.put(i, rnd.nextLong());
+ int beg = rnd.nextInt(10);
+ b2.position(beg);
+ b2.put(longs);
+ b2.limit(b2.position());
+ b2.position(beg);
+ BitSet s1 = BitSet.valueOf(longs);
+ BitSet s2 = BitSet.valueOf(b1);
+ BitSet s3 = BitSet.valueOf(b2);
+ equal(s1, s2);
+ equal(s1, s3);
+ if (longs.length > 0 && longs[longs.length -1] != 0) {
+ equal(longs, s1.toLongArray());
+ equal(longs, s2.toLongArray());
+ equal(longs, s3.toLongArray());
+ }
+ for (int i = 0; i < 64 * longs.length; i++) {
+ equal(s1.get(i), ((longs [i/64] & (1L<<(i%64))) != 0));
+ equal(s2.get(i), ((b1.get(i/64) & (1L<<(i%64))) != 0));
+ equal(s3.get(i), ((b2.get(b2.position()+i/64) & (1L<<(i%64))) != 0));
+ }
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new ImportExport().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/ojluni/src/test/java/util/BitSet/MemoryLeak.java b/ojluni/src/test/java/util/BitSet/MemoryLeak.java
new file mode 100644
index 00000000000..948487385b4
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/MemoryLeak.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4091185
+ * @summary Repeatedly OR BitSets; No OutOfMemoryException should result
+ */
+
+package test.java.util.BitSet;
+
+import java.util.*;
+
+/**
+ * This is a simple test class that repeatedly ORs two
+ * BitSets of unequal size together. Previously this
+ * caused an exponential growth in the memory underlying
+ * the BitSets quickly using all available memory
+ */
+public class MemoryLeak {
+
+ public static void main(String[] args) {
+
+ //create 2 test bitsets
+ BitSet setOne = new BitSet();
+ BitSet setTwo = new BitSet();
+
+ setOne.set(64);
+ setTwo.set(129);
+
+ //test for bug #4091185
+ //exponential set growth causing memory depletion
+ for (int i = 0; i < 50; i++) {
+ setOne.or(setTwo);
+ setTwo.or(setOne);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/BitSet/PreviousBits.java b/ojluni/src/test/java/util/BitSet/PreviousBits.java
new file mode 100644
index 00000000000..389d9fae883
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/PreviousBits.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6410729 6586631
+ * @summary Test previousClearBit, previousSetBit
+ * @key randomness
+ */
+
+package test.java.util.BitSet;
+
+import java.util.*;
+
+public class PreviousBits {
+
+ void testHashCode(final BitSet s) {
+ long h = 1234;
+ long[] words = s.toLongArray();
+ for (int i = words.length; --i >= 0; )
+ h ^= words[i] * (i + 1);
+ equal((int)((h >> 32) ^ h), s.hashCode());
+ }
+
+ void testOutOfBounds(final BitSet s) {
+ THROWS(IndexOutOfBoundsException.class,
+ new F(){void f(){ s.previousSetBit(-2);}},
+ new F(){void f(){ s.previousClearBit(-2);}},
+ new F(){void f(){ s.previousSetBit(Integer.MIN_VALUE);}},
+ new F(){void f(){ s.previousClearBit(Integer.MIN_VALUE);}},
+ new F(){void f(){ s.nextSetBit(-1);}},
+ new F(){void f(){ s.nextClearBit(-1);}},
+ new F(){void f(){ s.nextSetBit(Integer.MIN_VALUE);}},
+ new F(){void f(){ s.nextClearBit(Integer.MIN_VALUE);}});
+ }
+
+ void test(String[] args) throws Throwable {
+ final BitSet s = new BitSet();
+
+ // Test empty bitset
+ testOutOfBounds(s);
+ testHashCode(s);
+
+ for (int i = -1; i < 93;) {
+ equal(-1, s.previousSetBit(i));
+ equal( i, s.previousClearBit(i));
+ i++;
+ equal(-1, s.nextSetBit(i));
+ equal( i, s.nextClearBit(i));
+ }
+
+ // Test "singleton" bitsets
+ for (int j = 0; j < 161; j++) {
+ s.clear();
+ s.set(j);
+ testOutOfBounds(s);
+ testHashCode(s);
+
+ for (int i = -1; i < j; i++) {
+ equal(-1, s.previousSetBit(i));
+ equal( i, s.previousClearBit(i));
+ if (i >= 0) {
+ equal(j, s.nextSetBit(i));
+ equal(i, s.nextClearBit(i));
+ }
+ }
+
+ equal(j, s.previousSetBit(j));
+ equal(j-1, s.previousClearBit(j));
+ equal(j, s.nextSetBit(j));
+ equal(j+1, s.nextClearBit(j));
+
+ for (int i = j+1; i < j+100; i++) {
+ equal(j, s.previousSetBit(i));
+ equal(i, s.previousClearBit(i));
+ equal(-1, s.nextSetBit(i));
+ equal(i, s.nextClearBit(i));
+ }
+ }
+
+ // set even bits
+ s.clear();
+ for (int i = 0; i <= 128; i+=2)
+ s.set(i);
+ testHashCode(s);
+ for (int i = 1; i <= 128; i++) {
+ equal(s.previousSetBit(i),
+ ((i & 1) == 0) ? i : i - 1);
+ equal(s.previousClearBit(i),
+ ((i & 1) == 0) ? i - 1 : i);
+ }
+
+ // set odd bits as well
+ for (int i = 1; i <= 128; i+=2)
+ s.set(i);
+ testHashCode(s);
+ for (int i = 1; i <= 128; i++) {
+ equal(s.previousSetBit(i), i);
+ equal(s.previousClearBit(i), -1);
+ }
+
+ // Test loops documented in javadoc
+ Random rnd = new Random();
+ s.clear();
+ for (int i = 0; i < 10; i++)
+ s.set(rnd.nextInt(1066));
+ List<Integer> down = new ArrayList<Integer>();
+ for (int i = s.length(); (i = s.previousSetBit(i-1)) >= 0; )
+ down.add(i);
+ List<Integer> up = new ArrayList<Integer>();
+ for (int i = s.nextSetBit(0); i >= 0; i = s.nextSetBit(i+1))
+ up.add(i);
+ Collections.reverse(up);
+ equal(up, down);
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new PreviousBits().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ abstract class F {abstract void f() throws Throwable;}
+ void THROWS(Class<? extends Throwable> k, F... fs) {
+ for (F f : fs)
+ try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/BitSet/StickySize.java b/ojluni/src/test/java/util/BitSet/StickySize.java
new file mode 100644
index 00000000000..76cfd3d89ad
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/StickySize.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6404711
+ * @summary Check capacity management
+ * @author Martin Buchholz
+ */
+
+package test.java.util.BitSet;
+
+import java.io.*;
+import java.util.*;
+
+public class StickySize {
+ static void equalClones(BitSet s, int expectedSize) {
+ equal(expectedSize, clone(s).size());
+ equal(expectedSize, serialClone(s).size());
+ equal(expectedSize, s.size());
+ equal(clone(s), serialClone(s));
+ }
+
+ private static void realMain(String[] args) {
+ BitSet s;
+
+ s = new BitSet(); // non-sticky
+ equal(s.size(), 64);
+ equalClones(s, 0);
+ s.set(3*64);
+ s.set(7*64);
+ equal(s.size(), 8*64);
+ equalClones(s, 8*64);
+ s.clear(7*64);
+ equal(s.size(), 8*64);
+ equalClones(s, 4*64);
+
+ s = new BitSet(8*64); // sticky
+ equalClones(s, 8*64);
+ s.set(3*64);
+ s.set(7*64);
+ equalClones(s, 8*64);
+ s.clear(7*64);
+ equalClones(s, 8*64);
+ equalClones(clone(s), 8*64);
+ equalClones(serialClone(s), 8*64);
+ s.set(17*64); // Expand beyond sticky size
+ equalClones(s, 18*64);
+ s.clear(17*64);
+ equalClones(s, 4*64);
+ }
+
+ static BitSet clone(BitSet s) {
+ return (BitSet) s.clone();
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ static byte[] serializedForm(Object obj) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(obj);
+ return baos.toByteArray();
+ } catch (IOException e) { throw new RuntimeException(e); }}
+ static Object readObject(byte[] bytes)
+ throws IOException, ClassNotFoundException {
+ InputStream is = new ByteArrayInputStream(bytes);
+ return new ObjectInputStream(is).readObject();}
+ @SuppressWarnings("unchecked")
+ static <T> T serialClone(T obj) {
+ try { return (T) readObject(serializedForm(obj)); }
+ catch (Exception e) { throw new RuntimeException(e); }}
+}
diff --git a/ojluni/src/test/java/util/BitSet/stream/BitSetStreamTest.java b/ojluni/src/test/java/util/BitSet/stream/BitSetStreamTest.java
new file mode 100644
index 00000000000..629abc9c158
--- /dev/null
+++ b/ojluni/src/test/java/util/BitSet/stream/BitSetStreamTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.util.BitSet.stream;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.List;
+import java.util.PrimitiveIterator;
+import java.util.Random;
+import java.util.Spliterator;
+import org.openjdk.testlib.java.util.SpliteratorOfIntDataBuilder;
+import org.openjdk.testlib.java.util.SpliteratorTestHelper;
+import java.util.function.IntConsumer;
+import java.util.function.IntSupplier;
+import java.util.function.Supplier;
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.util.stream.Collectors.toList;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertThrows;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @test
+ * @summary test BitSet stream
+ * @bug 8012645 8076442
+ * @requires os.maxMemory >= 2g
+ * @library /lib/testlibrary/bootlib
+ * @build java.base/java.util.SpliteratorTestHelper
+ * java.base/java.util.SpliteratorOfIntDataBuilder
+ * @run testng/othervm -Xms512m -Xmx1024m BitSetStreamTest
+ */
+public class BitSetStreamTest extends SpliteratorTestHelper {
+ static class Fibs implements IntSupplier {
+ private int n1 = 0;
+ private int n2 = 1;
+
+ static int fibs(int n) {
+ Fibs f = new Fibs();
+ while (n-- > 0) f.getAsInt();
+ return f.getAsInt();
+ }
+
+ public int getAsInt() { int s = n1; n1 = n2; n2 = s + n1; return s; }
+ }
+
+ @Test
+ public void testFibs() {
+ Fibs f = new Fibs();
+ assertEquals(0, f.getAsInt());
+ assertEquals(1, f.getAsInt());
+ assertEquals(1, f.getAsInt());
+ assertEquals(2, f.getAsInt());
+ assertEquals(3, f.getAsInt());
+ assertEquals(5, f.getAsInt());
+ assertEquals(8, f.getAsInt());
+ assertEquals(13, f.getAsInt());
+ assertEquals(987, Fibs.fibs(16));
+ }
+
+
+ @DataProvider(name = "cases")
+ public static Object[][] produceCases() {
+ return new Object[][] {
+ { "none", IntStream.empty() },
+ { "index 0", IntStream.of(0) },
+ { "index 255", IntStream.of(255) },
+ { "index 0 and 255", IntStream.of(0, 255) },
+ // Android-removed: these case OOME.
+ // { "index Integer.MAX_VALUE", IntStream.of(Integer.MAX_VALUE) },
+ // { "index Integer.MAX_VALUE - 1", IntStream.of(Integer.MAX_VALUE - 1) },
+ // { "index 0 and Integer.MAX_VALUE", IntStream.of(0, Integer.MAX_VALUE) },
+ { "every bit", IntStream.range(0, 255) },
+ { "step 2", IntStream.range(0, 255).map(f -> f * 2) },
+ { "step 3", IntStream.range(0, 255).map(f -> f * 3) },
+ { "step 5", IntStream.range(0, 255).map(f -> f * 5) },
+ { "step 7", IntStream.range(0, 255).map(f -> f * 7) },
+ { "1, 10, 100, 1000", IntStream.of(1, 10, 100, 1000) },
+ { "25 fibs", IntStream.generate(new Fibs()).limit(25) }
+ };
+ }
+
+ @Test(dataProvider = "cases")
+ public void testBitsetStream(String name, IntStream data) {
+ BitSet bs = data.collect(BitSet::new, BitSet::set, BitSet::or);
+
+ assertEquals(bs.cardinality(), bs.stream().count());
+
+ int[] indexHolder = new int[] { -1 };
+ bs.stream().forEach(i -> {
+ int ei = indexHolder[0];
+ indexHolder[0] = bs.nextSetBit(ei + 1);
+ assertEquals(i, indexHolder[0]);
+ });
+
+ PrimitiveIterator.OfInt it = bs.stream().iterator();
+ for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
+ assertTrue(it.hasNext());
+ assertEquals(it.nextInt(), i);
+ if (i == Integer.MAX_VALUE)
+ break; // or (i + 1) would overflow
+ }
+ assertFalse(it.hasNext());
+ }
+
+ static Object[][] spliteratorOfIntDataProvider;
+
+ @DataProvider(name = "BitSet.stream.spliterator")
+ public static Object[][] spliteratorOfIntDataProvider() {
+ if (spliteratorOfIntDataProvider != null) {
+ return spliteratorOfIntDataProvider;
+ }
+
+ List<Object[]> data = new ArrayList<>();
+
+ Object[][] bitStreamTestcases = new Object[][] {
+ { "none", IntStream.empty().toArray() },
+ { "index 0", IntStream.of(0).toArray() },
+ { "index 255", IntStream.of(255).toArray() },
+ { "index 0 and 255", IntStream.of(0, 255).toArray() },
+ // Android-removed: these cause OOME.
+ // { "index Integer.MAX_VALUE", IntStream.of(Integer.MAX_VALUE).toArray() },
+ // { "index Integer.MAX_VALUE - 1", IntStream.of(Integer.MAX_VALUE - 1).toArray() },
+ // { "index 0 and Integer.MAX_VALUE", IntStream.of(0, Integer.MAX_VALUE).toArray() },
+ { "every bit", IntStream.range(0, 255).toArray() },
+ { "step 2", IntStream.range(0, 255).map(f -> f * 2).toArray() },
+ { "step 3", IntStream.range(0, 255).map(f -> f * 3).toArray() },
+ { "step 5", IntStream.range(0, 255).map(f -> f * 5).toArray() },
+ { "step 7", IntStream.range(0, 255).map(f -> f * 7).toArray() },
+ { "1, 10, 100, 1000", IntStream.of(1, 10, 100, 1000).toArray() },
+ };
+ for (Object[] tc : bitStreamTestcases) {
+ String description = (String)tc[0];
+ int[] exp = (int[])tc[1];
+ SpliteratorOfIntDataBuilder db = new SpliteratorOfIntDataBuilder(
+ data, IntStream.of(exp).boxed().collect(toList()));
+
+ db.add("BitSet.stream.spliterator() {" + description + "}", () ->
+ IntStream.of(exp).collect(BitSet::new, BitSet::set, BitSet::or).
+ stream().spliterator()
+ );
+ }
+ return spliteratorOfIntDataProvider = data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ assertThrows(NullPointerException.class, () -> s.get().forEachRemaining((IntConsumer) null));
+ assertThrows(NullPointerException.class, () -> s.get().tryAdvance((IntConsumer) null));
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testForEach(exp, s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntTryAdvance(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testTryAdvance(exp, s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntMixedTryAdvanceForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testMixedTryAdvanceForEach(exp, s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testMixedTraverseAndSplit(exp, s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testSplitAfterFullTraversal(s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntSplitOnce(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testSplitOnce(exp, s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntSplitSixDeep(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testSplitSixDeep(exp, s, intBoxingConsumer());
+ }
+
+ @Test(dataProvider = "BitSet.stream.spliterator")
+ public void testIntSplitUntilNull(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+ testSplitUntilNull(exp, s, intBoxingConsumer());
+ }
+
+ @Test
+ public void testRandomStream() {
+ final int size = 1024 * 1024;
+ final int[] seeds = {
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
+ 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
+ final byte[] bytes = new byte[size];
+ for (int seed : seeds) {
+ final Random random = new Random(seed);
+ random.nextBytes(bytes);
+
+ BitSet bitSet = BitSet.valueOf(bytes);
+ testBitSetContents(bitSet, bitSet.stream().toArray());
+ testBitSetContents(bitSet, bitSet.stream().parallel().toArray());
+ }
+ }
+
+ void testBitSetContents(BitSet bitSet, int[] array) {
+ int cardinality = bitSet.cardinality();
+ assertEquals(array.length, cardinality);
+ int nextSetBit = -1;
+ for (int i = 0; i < cardinality; i++) {
+ nextSetBit = bitSet.nextSetBit(nextSetBit + 1);
+ assertEquals(array[i], nextSetBit);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/AddAll.java b/ojluni/src/test/java/util/Collections/AddAll.java
new file mode 100644
index 00000000000..644035be0df
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/AddAll.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4822887
+ * @summary Basic test for Collections.addAll
+ * @author Josh Bloch
+ * @key randomness
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+public class AddAll {
+ static final int N = 100;
+ public static void main(String[] args) {
+ test(new ArrayList<Integer>());
+ test(new LinkedList<Integer>());
+ test(new HashSet<Integer>());
+ test(new LinkedHashSet<Integer>());
+ }
+
+ private static Random rnd = new Random();
+
+ static void test(Collection<Integer> c) {
+ int x = 0;
+ for (int i = 0; i < N; i++) {
+ int rangeLen = rnd.nextInt(10);
+ if (Collections.addAll(c, range(x, x + rangeLen)) !=
+ (rangeLen != 0))
+ throw new RuntimeException("" + rangeLen);
+ x += rangeLen;
+ }
+ if (c instanceof List) {
+ if (!c.equals(Arrays.asList(range(0, x))))
+ throw new RuntimeException(x +": "+c);
+ } else {
+ if (!c.equals(new HashSet<Integer>(Arrays.asList(range(0, x)))))
+ throw new RuntimeException(x +": "+c);
+ }
+ }
+
+ private static Integer[] range(int from, int to) {
+ Integer[] result = new Integer[to - from];
+ for (int i = from, j=0; i < to; i++, j++)
+ result[j] = new Integer(i);
+ return result;
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/AsLifoQueue.java b/ojluni/src/test/java/util/Collections/AsLifoQueue.java
new file mode 100644
index 00000000000..1c64d973dd9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/AsLifoQueue.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6301085 6192552 6365601
+ * @summary Basic tests for asLifoQueue
+ * @author Martin Buchholz
+ */
+
+package test.java.util.Collections;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+public class AsLifoQueue {
+
+ private static void realMain(String[] args) throws Throwable {
+ try {
+ Deque<String> deq = new ArrayDeque<String>();
+ check(deq.addAll(Arrays.asList("b", "a", "c")));
+ equal(deq.toString(), "[b, a, c]");
+ check(deq.add("d"));
+ equal(deq.toString(), "[b, a, c, d]");
+ Queue<String> q = Collections.asLifoQueue(deq);
+ check(q.add("e"));
+ equal(deq.toString(),"[e, b, a, c, d]");
+ } catch (Throwable t) { unexpected(t); }
+
+ // Inspired by an excellent bug report by Jason Mehrens
+ try {
+ final Queue<String> q =
+ Collections.asLifoQueue(new LinkedBlockingDeque<String>(3));
+ check(q.isEmpty()); equal(q.size(), 0);
+ check(q.add("a")); check(! q.isEmpty()); equal(q.size(), 1);
+ check(q.offer("b"));
+ check(q.add("c"));
+ equal(q.size(), 3);
+ check(! q.offer("d"));
+ equal(q.size(), 3);
+ THROWS(IllegalStateException.class, () -> q.add("d"));
+ equal(q.size(), 3);
+ equal(q.toString(), "[c, b, a]");
+ equal(q.peek(), "c");
+ equal(q.element(), "c");
+ equal(q.remove(), "c");
+ equal(q.poll(), "b");
+ equal(q.peek(), "a");
+ equal(q.remove(), "a");
+ THROWS(NoSuchElementException.class, () -> q.remove());
+ equal(q.poll(), null);
+ check(q.isEmpty());
+ equal(q.size(), 0);
+ } catch (Throwable t) { unexpected(t); }
+
+ THROWS(NullPointerException.class, () -> Collections.asLifoQueue(null));
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ interface Fun {void f() throws Throwable;}
+ private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
+ for (Fun f : fs)
+ try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/BigBinarySearch.java b/ojluni/src/test/java/util/Collections/BigBinarySearch.java
new file mode 100644
index 00000000000..30046b9874a
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/BigBinarySearch.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5045582
+ * @summary binarySearch of Collections larger than 1<<30
+ * @author Martin Buchholz
+ */
+
+package test.java.util.Collections;
+
+import java.util.AbstractList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.RandomAccess;
+
+public class BigBinarySearch {
+
+ // Allows creation of very "big" collections without using too
+ // many real resources
+ static class SparseIntegerList
+ extends AbstractList<Integer>
+ implements RandomAccess
+ {
+ private Map<Integer,Integer> m = new HashMap<>();
+
+ public Integer get(int i) {
+ if (i < 0) throw new IndexOutOfBoundsException(""+i);
+ Integer v = m.get(i);
+ return (v == null) ? Integer.valueOf(0) : v;
+ }
+
+ public int size() {
+ return Collections.max(m.keySet()) + 1;
+ }
+
+ public Integer set(int i, Integer v) {
+ if (i < 0) throw new IndexOutOfBoundsException(""+i);
+ Integer ret = get(i);
+ if (v == 0)
+ m.remove(i);
+ else
+ m.put(i, v);
+ return ret;
+ }
+ }
+
+ /** Checks that binarySearch finds an element where we got it. */
+ private static void checkBinarySearch(List<Integer> l, int i) {
+ try { equal(i, Collections.binarySearch(l, l.get(i))); }
+ catch (Throwable t) { unexpected(t); }
+ }
+
+ /** Checks that binarySearch finds an element where we got it. */
+ private static void checkBinarySearch(List<Integer> l, int i,
+ Comparator<Integer> comparator) {
+ try { equal(i, Collections.binarySearch(l, l.get(i), comparator)); }
+ catch (Throwable t) { unexpected(t); }
+ }
+
+ private static void realMain(String[] args) throws Throwable {
+ final int n = (1<<30) + 47;
+
+ System.out.println("binarySearch(List<Integer>, Integer)");
+ List<Integer> big = new SparseIntegerList();
+ big.set( 0, -44);
+ big.set( 1, -43);
+ big.set(n-2, 43);
+ big.set(n-1, 44);
+ int[] ints = { 0, 1, n-2, n-1 };
+ Comparator<Integer> reverse = Collections.reverseOrder();
+ Comparator<Integer> natural = Collections.reverseOrder(reverse);
+
+ for (int i : ints) {
+ checkBinarySearch(big, i);
+ checkBinarySearch(big, i, null);
+ checkBinarySearch(big, i, natural);
+ }
+ for (int i : ints)
+ big.set(i, - big.get(i));
+ for (int i : ints)
+ checkBinarySearch(big, i, reverse);
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java b/ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java
new file mode 100644
index 00000000000..8472e8de57c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4528331 5006032
+ * @summary Test Collections.binarySearch() with a null comparator
+ */
+
+package test.java.util.Collections;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class BinarySearchNullComparator {
+ public static void main(String[] args) throws Exception {
+ List list = Arrays.asList(new String[] {"I", "Love", "You"});
+
+ int result = Collections.binarySearch(list, "You", null);
+ if (result != 2)
+ throw new Exception("Result: " + result);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedIdentityMap.java b/ojluni/src/test/java/util/Collections/CheckedIdentityMap.java
new file mode 100644
index 00000000000..fd8a24d0de9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedIdentityMap.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6585904
+ * @run testng CheckedIdentityMap
+ * @summary Checked collections with underlying maps with identity comparisons
+ */
+
+package test.java.util.Collections;
+
+import org.testng.annotations.Test;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import static java.util.Collections.checkedMap;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+
+public class CheckedIdentityMap {
+
+ @Test
+ public void testHashCode() {
+ Map<Integer, Integer> m1 = checkedMap(
+ new IdentityHashMap<Integer, Integer>(),
+ Integer.class, Integer.class);
+ Map<Integer, Integer> m2 = checkedMap(
+ new IdentityHashMap<Integer, Integer>(),
+ Integer.class, Integer.class);
+ // NB: these are unique instances. Compare vs. Integer.valueOf(1)
+ m1.put(new Integer(1), new Integer(1));
+ m2.put(new Integer(1), new Integer(1));
+
+ Map.Entry<Integer, Integer> e1 = m1.entrySet().iterator().next();
+ Map.Entry<Integer, Integer> e2 = m2.entrySet().iterator().next();
+
+ assertNotEquals(e1, e2);
+ assertEquals(e1.hashCode(), hashCode(e1));
+ assertEquals(e2.hashCode(), hashCode(e2));
+ }
+
+ static int hashCode(Map.Entry<?,?> e) {
+ return (System.identityHashCode(e.getKey()) ^
+ System.identityHashCode(e.getValue()));
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedListBash.java b/ojluni/src/test/java/util/Collections/CheckedListBash.java
new file mode 100644
index 00000000000..2d7dd2a4d0d
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedListBash.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4904067
+ * @summary Unit test for Collections.checkedList
+ * @author Josh Bloch
+ * @key randomness
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Random;
+
+public class CheckedListBash {
+ static Random rnd = new Random();
+
+ public static void main(String[] args) {
+ int numItr = 100;
+ int listSize = 100;
+
+ for (int i=0; i<numItr; i++) {
+ List s1 = newList();
+ AddRandoms(s1, listSize);
+
+ List s2 = newList();
+ AddRandoms(s2, listSize);
+
+ List intersection = clone(s1); intersection.retainAll(s2);
+ List diff1 = clone(s1); diff1.removeAll(s2);
+ List diff2 = clone(s2); diff2.removeAll(s1);
+ List union = clone(s1); union.addAll(s2);
+
+ if (diff1.removeAll(diff2))
+ fail("List algebra identity 2 failed");
+ if (diff1.removeAll(intersection))
+ fail("List algebra identity 3 failed");
+ if (diff2.removeAll(diff1))
+ fail("List algebra identity 4 failed");
+ if (diff2.removeAll(intersection))
+ fail("List algebra identity 5 failed");
+ if (intersection.removeAll(diff1))
+ fail("List algebra identity 6 failed");
+ if (intersection.removeAll(diff1))
+ fail("List algebra identity 7 failed");
+
+ intersection.addAll(diff1); intersection.addAll(diff2);
+ if (!(intersection.containsAll(union) &&
+ union.containsAll(intersection)))
+ fail("List algebra identity 1 failed");
+
+ Iterator e = union.iterator();
+ while (e.hasNext())
+ intersection.remove(e.next());
+ if (!intersection.isEmpty())
+ fail("Copy nonempty after deleting all elements.");
+
+ e = union.iterator();
+ while (e.hasNext()) {
+ Object o = e.next();
+ if (!union.contains(o))
+ fail("List doesn't contain one of its elements.");
+ e.remove();
+ }
+ if (!union.isEmpty())
+ fail("List nonempty after deleting all elements.");
+
+ s1.clear();
+ if (s1.size() != 0)
+ fail("Clear didn't reduce size to zero.");
+
+ s1.addAll(0, s2);
+ if (!(s1.equals(s2) && s2.equals(s1)))
+ fail("addAll(int, Collection) doesn't work.");
+ // Reverse List
+ for (int j=0, n=s1.size(); j<n; j++)
+ s1.set(j, s1.set(n-j-1, s1.get(j)));
+ // Reverse it again
+ for (int j=0, n=s1.size(); j<n; j++)
+ s1.set(j, s1.set(n-j-1, s1.get(j)));
+ if (!(s1.equals(s2) && s2.equals(s1)))
+ fail("set(int, Object) doesn't work");
+ }
+
+ List s = newList();
+ for (int i=0; i<listSize; i++)
+ s.add(new Integer(i));
+ if (s.size() != listSize)
+ fail("Size of [0..n-1] != n");
+
+ List even = clone(s);
+ Iterator it = even.iterator();
+ while (it.hasNext())
+ if (((Integer)it.next()).intValue() % 2 == 1)
+ it.remove();
+ it = even.iterator();
+ while (it.hasNext())
+ if (((Integer)it.next()).intValue() % 2 == 1)
+ fail("Failed to remove all odd nubmers.");
+
+ List odd = clone(s);
+ for (int i=0; i<(listSize/2); i++)
+ odd.remove(i);
+ for (int i=0; i<(listSize/2); i++)
+ if (((Integer)odd.get(i)).intValue() % 2 != 1)
+ fail("Failed to remove all even nubmers.");
+
+ List all = clone(odd);
+ for (int i=0; i<(listSize/2); i++)
+ all.add(2*i, even.get(i));
+ if (!all.equals(s))
+ fail("Failed to reconstruct ints from odds and evens.");
+
+ all = clone(odd);
+ ListIterator itAll = all.listIterator(all.size());
+ ListIterator itEven = even.listIterator(even.size());
+ while (itEven.hasPrevious()) {
+ itAll.previous();
+ itAll.add(itEven.previous());
+ itAll.previous(); // ???
+ }
+ itAll = all.listIterator();
+ while (itAll.hasNext()) {
+ Integer i = (Integer)itAll.next();
+ itAll.set(new Integer(i.intValue()));
+ }
+ itAll = all.listIterator();
+ it = s.iterator();
+ while (it.hasNext())
+ if (it.next()==itAll.next())
+ fail("Iterator.set failed to change value.");
+ if (!all.equals(s))
+ fail("Failed to reconstruct ints with ListIterator.");
+
+ it = all.listIterator();
+ int i=0;
+ while (it.hasNext()) {
+ Object o = it.next();
+ if (all.indexOf(o) != all.lastIndexOf(o))
+ fail("Apparent duplicate detected.");
+ if (all.subList(i, all.size()).indexOf(o) != 0 ||
+ all.subList(i+1, all.size()).indexOf(o) != -1)
+ fail("subList/indexOf is screwy.");
+ if (all.subList(0,i+1).lastIndexOf(o) != i)
+ fail("subList/lastIndexOf is screwy.");
+ i++;
+ }
+
+ List l = newList();
+ AddRandoms(l, listSize);
+ Integer[] ia = (Integer[]) l.toArray(new Integer[0]);
+ if (!l.equals(Arrays.asList(ia)))
+ fail("toArray(Object[]) is hosed (1)");
+ ia = new Integer[listSize];
+ Integer[] ib = (Integer[]) l.toArray(ia);
+ if (ia != ib || !l.equals(Arrays.asList(ia)))
+ fail("toArray(Object[]) is hosed (2)");
+ ia = new Integer[listSize+1];
+ ia[listSize] = new Integer(69);
+ ib = (Integer[]) l.toArray(ia);
+ if (ia != ib || ia[listSize] != null
+ || !l.equals(Arrays.asList(ia).subList(0, listSize)))
+ fail("toArray(Object[]) is hosed (3)");
+
+ }
+
+ // Done inefficiently so as to exercise toArray
+ static List clone(List s) {
+ List a = Arrays.asList(s.toArray());
+ if (s.hashCode() != a.hashCode())
+ fail("Incorrect hashCode computation.");
+
+ List clone = newList();
+ clone.addAll(a);
+ if (!s.equals(clone))
+ fail("List not equal to copy.");
+ if (!s.containsAll(clone))
+ fail("List does not contain copy.");
+ if (!clone.containsAll(s))
+ fail("Copy does not contain list.");
+
+ return clone;
+ }
+
+ static List newList() {
+ List s = Collections.checkedList(new ArrayList(), Integer.class);
+ if (!s.isEmpty())
+ fail("New instance non empty.");
+ return s;
+ }
+
+ static void AddRandoms(List s, int n) {
+ for (int i = 0; i < n; i++) {
+ Integer e = rnd.nextInt(n);
+
+ int preSize = s.size();
+ if (!s.add(e))
+ fail("Add failed.");
+ int postSize = s.size();
+ if (postSize - preSize != 1)
+ fail("Add didn't increase size by 1.");
+ }
+ }
+
+ static void fail(String s) {
+ throw new RuntimeException(s);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java b/ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java
new file mode 100644
index 00000000000..48ec9d88c8a
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8047795 8053938
+ * @summary Ensure that replaceAll operator cannot add bad elements
+ * @author Mike Duigou
+ */
+
+package test.java.util.Collections;
+
+import java.util.*;
+import java.util.function.UnaryOperator;
+
+public class CheckedListReplaceAll {
+ public static void main(String[] args) {
+ List unwrapped = Arrays.asList(new Object[]{1, 2, 3});
+ List<Object> wrapped = Collections.checkedList(unwrapped, Integer.class);
+
+ UnaryOperator evil = e -> (((int) e) % 2 != 0) ? e : "evil";
+
+ try {
+ wrapped.replaceAll(evil);
+ System.out.printf("Bwahaha! I have defeated you! %s\n", wrapped);
+ throw new RuntimeException("String added to checked List<Integer>");
+ } catch (ClassCastException thwarted) {
+ thwarted.printStackTrace(System.out);
+ System.out.println("Curses! Foiled again!");
+ }
+
+ unwrapped = Arrays.asList(new Object[]{}); // Empty list
+ wrapped = Collections.checkedList(unwrapped, Integer.class);
+ try {
+ wrapped.replaceAll((UnaryOperator)null);
+ System.out.printf("Bwahaha! I have defeated you! %s\n", wrapped);
+ throw new RuntimeException("NPE not thrown when passed a null operator");
+ } catch (NullPointerException thwarted) {
+ thwarted.printStackTrace(System.out);
+ System.out.println("Curses! Foiled again!");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedMapBash.java b/ojluni/src/test/java/util/Collections/CheckedMapBash.java
new file mode 100644
index 00000000000..2d4db768df0
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedMapBash.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4904067 5023830 7129185 8072015
+ * @summary Unit test for Collections.checkedMap
+ * @author Josh Bloch
+ * @run testng CheckedMapBash
+ * @key randomness
+ */
+
+package test.java.util.Collections;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.fail;
+
+public class CheckedMapBash {
+ static final Random rnd = new Random();
+ static final Object nil = new Integer(0);
+ static final int numItr = 100;
+ static final int mapSize = 100;
+
+ @Test(dataProvider = "Bash.Supplier<Map<Integer,Integer>>")
+ public static void testCheckedMap(String description, Supplier<Map<Integer,Integer>> supplier) {
+ Map m = supplier.get();
+ Object head = nil;
+
+ for (int j=0; j<mapSize; j++) {
+ Object newHead;
+ do {
+ newHead = new Integer(rnd.nextInt());
+ } while (m.containsKey(newHead) || newHead.equals(nil));
+ m.put(newHead, head);
+ head = newHead;
+ }
+ if (m.size() != mapSize)
+ fail("Size not as expected.");
+
+ {
+ HashMap hm = new HashMap(m);
+ if (! (hm.hashCode() == m.hashCode() &&
+ hm.entrySet().hashCode() == m.entrySet().hashCode() &&
+ hm.keySet().hashCode() == m.keySet().hashCode()))
+ fail("Incorrect hashCode computation.");
+
+ if (! (hm.equals(m) &&
+ hm.entrySet().equals(m.entrySet()) &&
+ hm.keySet().equals(m.keySet()) &&
+ m.equals(hm) &&
+ m.entrySet().equals(hm.entrySet()) &&
+ m.keySet().equals(hm.keySet())))
+ fail("Incorrect equals computation.");
+ }
+
+ Map m2 = supplier.get(); m2.putAll(m);
+ m2.values().removeAll(m.keySet());
+ if (m2.size()!= 1 || !m2.containsValue(nil))
+ fail("Collection views test failed.");
+
+ int j=0;
+ while (head != nil) {
+ if (!m.containsKey(head))
+ fail("Linked list doesn't contain a link.");
+ Object newHead = m.get(head);
+ if (newHead == null)
+ fail("Could not retrieve a link.");
+ m.remove(head);
+ head = newHead;
+ j++;
+ }
+ if (!m.isEmpty())
+ fail("Map nonempty after removing all links.");
+ if (j != mapSize)
+ fail("Linked list size not as expected.");
+ }
+
+ @Test(dataProvider = "Supplier<Map<Integer,Integer>>")
+ public static void testCheckedMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
+ Map m = supplier.get();
+ for (int i=0; i<mapSize; i++)
+ if (m.put(new Integer(i), new Integer(2*i)) != null)
+ fail("put returns a non-null value erroneously.");
+ for (int i=0; i<2*mapSize; i++)
+ if (m.containsValue(new Integer(i)) != (i%2==0))
+ fail("contains value "+i);
+ if (m.put(nil, nil) == null)
+ fail("put returns a null value erroneously.");
+ Map m2 = supplier.get(); m2.putAll(m);
+ if (!m.equals(m2))
+ fail("Clone not equal to original. (1)");
+ if (!m2.equals(m))
+ fail("Clone not equal to original. (2)");
+ Set s = m.entrySet(), s2 = m2.entrySet();
+ if (!s.equals(s2))
+ fail("Clone not equal to original. (3)");
+ if (!s2.equals(s))
+ fail("Clone not equal to original. (4)");
+ if (!s.containsAll(s2))
+ fail("Original doesn't contain clone!");
+ if (!s2.containsAll(s))
+ fail("Clone doesn't contain original!");
+
+ s2.removeAll(s);
+ if (!m2.isEmpty())
+ fail("entrySet().removeAll failed.");
+
+ m2.putAll(m);
+ m2.clear();
+ if (!m2.isEmpty())
+ fail("clear failed.");
+
+ Iterator i = m.entrySet().iterator();
+ while (i.hasNext()) {
+ i.next();
+ i.remove();
+ }
+ if (!m.isEmpty())
+ fail("Iterator.remove() failed");
+ }
+
+ @DataProvider(name = "Bash.Supplier<Map<Integer,Integer>>", parallel = true)
+ public static Iterator<Object[]> bashNavigableMapProvider() {
+ ArrayList<Object[]> iters = new ArrayList<>(makeCheckedMaps());
+ iters.ensureCapacity(numItr * iters.size());
+ for (int each=1; each < numItr; each++) {
+ iters.addAll(makeCheckedMaps());
+ }
+ return iters.iterator();
+ }
+
+ @DataProvider(name = "Supplier<Map<Integer,Integer>>", parallel = true)
+ public static Iterator<Object[]> navigableMapProvider() {
+ return makeCheckedMaps().iterator();
+ }
+
+ public static Collection<Object[]> makeCheckedMaps() {
+ Object[][] params = {
+ {"Collections.checkedMap(HashMap)",
+ (Supplier) () -> Collections.checkedMap(new HashMap(), Integer.class, Integer.class)},
+ {"Collections.checkedMap(TreeMap(reverseOrder))",
+ (Supplier) () -> Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
+ {"Collections.checkedMap(TreeMap.descendingMap())",
+ (Supplier) () -> Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
+ {"Collections.checkedNavigableMap(TreeMap)",
+ (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)},
+ {"Collections.checkedNavigableMap(TreeMap(reverseOrder))",
+ (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
+ {"Collections.checkedNavigableMap(TreeMap.descendingMap())",
+ (Supplier) () -> Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
+ };
+ return Arrays.asList(params);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java b/ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java
new file mode 100644
index 00000000000..b474a10057c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8047795
+ * @summary Ensure that replaceAll operator cannot add bad elements
+ * @author Mike Duigou
+ */
+
+package test.java.util.Collections;
+
+import java.util.*;
+import java.util.function.BiFunction;
+
+public class CheckedMapReplaceAll {
+ public static void main(String[] args) {
+ Map<Integer,Double> unwrapped = new HashMap<>();
+ unwrapped.put(1, 1.0);
+ unwrapped.put(2, 2.0);
+ unwrapped.put(3, 3.0);
+
+ Map<Integer,Double> wrapped = Collections.checkedMap(unwrapped, Integer.class, Double.class);
+
+ BiFunction evil = (k, v) -> (((int)k) % 2 != 0) ? v : "evil";
+
+ try {
+ wrapped.replaceAll(evil);
+ System.out.printf("Bwahaha! I have defeated you! %s\n", wrapped);
+ throw new RuntimeException("String added to checked Map<Integer,Double>");
+ } catch (ClassCastException thwarted) {
+ thwarted.printStackTrace(System.out);
+ System.out.println("Curses! Foiled again!");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedNull.java b/ojluni/src/test/java/util/Collections/CheckedNull.java
new file mode 100644
index 00000000000..91b5d9f0548
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedNull.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6409434
+ * @summary Test behavior of nulls in checked collections
+ */
+
+package test.java.util.Collections;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.TreeSet;
+
+import static java.util.Collections.singleton;
+import static java.util.Collections.singletonMap;
+
+@SuppressWarnings({"unchecked","serial"})
+public class CheckedNull {
+
+ void test(String[] args) throws Throwable {
+ testCollection(Collections.checkedCollection(
+ new ArrayList<String>(), String.class));
+ testCollection(Collections.checkedList(
+ new ArrayList<String>(), String.class));
+ testCollection(Collections.checkedSet(
+ new HashSet<String>(), String.class));
+
+ final Comparator nullLow = new Comparator() {
+ public int compare(Object x, Object y) {
+ return x == y ? 0 :
+ x == null ? -1 :
+ y == null ? 1 :
+ ((Comparable)x).compareTo(y); }};
+ testCollection(Collections.checkedSortedSet(
+ new TreeSet<String>(nullLow), String.class));
+
+ testMap(Collections.checkedMap(
+ new HashMap<String, String>(),
+ String.class, String.class));
+ }
+
+ ClassCastException cce(F f) {
+ try { f.f(); fail(); return null; }
+ catch (ClassCastException cce) { pass(); return cce; }
+ catch (Throwable t) { unexpected(t); return null; }
+ }
+
+ void equalCCE(F ... fs) {
+ String detailMessage = null;
+ for (F f : fs)
+ if (detailMessage == null)
+ detailMessage = cce(f).getMessage();
+ else
+ equal(detailMessage, cce(f).getMessage());
+ }
+
+ void add(Collection c, Object o) {
+ int s = c.size();
+ check(! c.contains(o));
+ check(c.add(o));
+ check(c.contains(o));
+ equal(c.size(), s+1);
+ check(c.remove(o));
+ check(! c.contains(o));
+ check(c.addAll(singleton(o)));
+ check(c.contains(o));
+ equal(c.size(), s+1);
+ check(c.remove(o));
+ equal(c.size(), s);
+ }
+
+ void testCollection(final Collection c) {
+ try {
+ check(c.isEmpty());
+ add(c, null);
+ add(c, "foo");
+
+ check(c.add("bar"));
+ add(c, null);
+ add(c, "foo");
+
+ equalCCE(
+ new F(){void f(){ c.add(1); }},
+ new F(){void f(){ c.addAll(singleton(1)); }});
+
+ } catch (Throwable t) { unexpected(t); }
+ }
+
+ void put(Map m, Object k, Object v) {
+ int s = m.size();
+ check(! m.containsKey(k));
+ check(! m.containsValue(v));
+ equal(null, m.put(k, v));
+ check(m.containsKey(k));
+ check(m.containsValue(v));
+ equal(m.size(), s+1);
+ equal(v, m.remove(k));
+ check(! m.containsKey(k));
+ check(! m.containsValue(v));
+ m.putAll(singletonMap(k,v));
+ check(m.containsKey(k));
+ check(m.containsValue(v));
+ equal(m.size(), s+1);
+ equal(v,m.remove(k));
+ equal(m.size(), s);
+ }
+
+ void testMap(final Map m) {
+ try {
+ check(m.isEmpty());
+
+ put(m, "foo", null);
+ put(m, null, "foo");
+ put(m, null, null);
+ put(m, "foo", "bar");
+
+ m.put("a", "b");
+
+ put(m, "foo", null);
+ put(m, null, "foo");
+ put(m, null, null);
+ put(m, "foo", "bar");
+
+ equalCCE(
+ new F(){void f(){ m.put(1, "foo"); }},
+ new F(){void f(){ m.putAll(singletonMap(1, "foo")); }});
+
+ final Collection cheater = new ArrayList() {
+ public boolean contains(Object o) {
+ if (o instanceof Map.Entry)
+ ((Map.Entry)o).setValue(1);
+ return false; }};
+
+ equalCCE(
+ new F(){void f(){ m.put("foo", 1); }},
+ new F(){void f(){ m.putAll(singletonMap("foo", 1)); }},
+ new F(){void f(){
+ ((Map.Entry)m.entrySet().iterator().next()).setValue(1); }},
+ new F(){void f(){
+ m.entrySet().removeAll(cheater);}},
+ new F(){void f(){
+ m.entrySet().retainAll(cheater);}});
+
+ equalCCE(
+ new F(){void f(){ m.put(3, 1); }},
+ new F(){void f(){ m.putAll(singletonMap(3, 1)); }});
+
+ equal(m.size(), 1);
+ equal(m.keySet(), singleton("a"));
+ equal(m.entrySet(),
+ singleton(new AbstractMap.SimpleImmutableEntry("a","b")));
+
+ } catch (Throwable t) { unexpected(t); }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new CheckedNull().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ abstract class F {abstract void f() throws Throwable;}
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedQueue.java b/ojluni/src/test/java/util/Collections/CheckedQueue.java
new file mode 100644
index 00000000000..109d1170282
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedQueue.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5020931 8048207
+ * @summary Unit test for Collections.checkedQueue
+ * @run testng CheckedQueue
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collections;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.fail;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+
+
+public class CheckedQueue {
+
+ /**
+ * This test adds items to a queue.
+ */
+ @Test
+ public void testAdd() {
+ int arrayLength = 10;
+ Queue<String> abq = Collections.checkedQueue(new ArrayBlockingQueue<>(arrayLength), String.class);
+
+ for (int i = 0; i < arrayLength; i++) {
+ abq.add(Integer.toString(i));
+ }
+
+ try {
+ abq.add("full");
+ } catch (IllegalStateException full) {
+
+ }
+ }
+
+ /**
+ * This test tests the CheckedQueue.add method. It creates a queue of
+ * {@code String}s gets the checked queue, and attempt to add an Integer to
+ * the checked queue.
+ */
+ @Test(expectedExceptions = ClassCastException.class)
+ public void testAddFail1() {
+ int arrayLength = 10;
+ ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(arrayLength + 1);
+
+ for (int i = 0; i < arrayLength; i++) {
+ abq.add(Integer.toString(i));
+ }
+
+ Queue q = Collections.checkedQueue(abq, String.class);
+ q.add(0);
+ }
+
+ /**
+ * This test tests the CheckedQueue.add method. It creates a queue of one
+ * {@code String}, gets the checked queue, and attempt to add an Integer to
+ * the checked queue.
+ */
+ @Test(expectedExceptions = ClassCastException.class)
+ public void testAddFail2() {
+ ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(1);
+ Queue q = Collections.checkedQueue(abq, String.class);
+
+ q.add(0);
+ }
+
+ /**
+ * This test tests the Collections.checkedQueue method call for nulls in
+ * each and both of the parameters.
+ */
+ @Test
+ public void testArgs() {
+ ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(1);
+ Queue q;
+
+ try {
+ q = Collections.checkedQueue(null, String.class);
+ fail( "should throw NullPointerException.");
+ } catch(NullPointerException npe) {
+ // Do nothing
+ }
+
+ try {
+ q = Collections.checkedQueue(abq, null);
+ fail( "should throw NullPointerException.");
+ } catch(Exception e) {
+ // Do nothing
+ }
+
+ try {
+ q = Collections.checkedQueue(null, null);
+ fail( "should throw NullPointerException.");
+ } catch(Exception e) {
+ // Do nothing
+ }
+ }
+
+ /**
+ * This test tests the CheckedQueue.offer method.
+ */
+ @Test
+ public void testOffer() {
+ ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(1);
+ Queue q = Collections.checkedQueue(abq, String.class);
+
+ try {
+ q.offer(null);
+ fail("should throw NullPointerException.");
+ } catch (NullPointerException npe) {
+ // Do nothing
+ }
+
+ try {
+ q.offer(0);
+ fail("should throw ClassCastException.");
+ } catch (ClassCastException cce) {
+ // Do nothing
+ }
+
+ assertTrue(q.offer("0"), "queue should have room");
+
+ // no room at the inn!
+ assertFalse(q.offer("1"), "queue should be full");
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedSetBash.java b/ojluni/src/test/java/util/Collections/CheckedSetBash.java
new file mode 100644
index 00000000000..a120bc557d3
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedSetBash.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4904067 7129185
+ * @summary Unit test for Collections.checkedSet
+ * @author Josh Bloch
+ * @run testng CheckedSetBash
+ * @key randomness
+ */
+
+package test.java.util.Collections;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+public class CheckedSetBash {
+ static final int numItr = 100;
+ static final int setSize = 100;
+ static final Random rnd = new Random();
+
+ @Test(dataProvider = "Supplier<Set<Integer>>")
+ public static void testCheckedSet(String description, Supplier<Set<Integer>> supplier) {
+
+ Set<Integer> s1 = supplier.get();
+ assertTrue(s1.isEmpty());
+
+ AddRandoms(s1, setSize);
+
+ Set<Integer> s2 = supplier.get();
+
+ assertTrue(s2.isEmpty());
+
+ AddRandoms(s2, setSize);
+
+ Set<Integer> intersection = clone(s1, supplier);
+ intersection.retainAll(s2);
+ Set<Integer> diff1 = clone(s1, supplier); diff1.removeAll(s2);
+ Set<Integer> diff2 = clone(s2, supplier); diff2.removeAll(s1);
+ Set<Integer> union = clone(s1, supplier); union.addAll(s2);
+
+ if (diff1.removeAll(diff2))
+ fail("Set algebra identity 2 failed");
+ if (diff1.removeAll(intersection))
+ fail("Set algebra identity 3 failed");
+ if (diff2.removeAll(diff1))
+ fail("Set algebra identity 4 failed");
+ if (diff2.removeAll(intersection))
+ fail("Set algebra identity 5 failed");
+ if (intersection.removeAll(diff1))
+ fail("Set algebra identity 6 failed");
+ if (intersection.removeAll(diff1))
+ fail("Set algebra identity 7 failed");
+
+ intersection.addAll(diff1); intersection.addAll(diff2);
+ if (!intersection.equals(union))
+ fail("Set algebra identity 1 failed");
+
+ if (new HashSet(union).hashCode() != union.hashCode())
+ fail("Incorrect hashCode computation.");
+
+ Iterator e = union.iterator();
+ while (e.hasNext())
+ if (!intersection.remove(e.next()))
+ fail("Couldn't remove element from copy.");
+ if (!intersection.isEmpty())
+ fail("Copy nonempty after deleting all elements.");
+
+ e = union.iterator();
+ while (e.hasNext()) {
+ Object o = e.next();
+ if (!union.contains(o))
+ fail("Set doesn't contain one of its elements.");
+ e.remove();
+ if (union.contains(o))
+ fail("Set contains element after deletion.");
+ }
+ if (!union.isEmpty())
+ fail("Set nonempty after deleting all elements.");
+
+ s1.clear();
+ if (!s1.isEmpty())
+ fail("Set nonempty after clear.");
+ }
+
+ // Done inefficiently so as to exercise toArray
+ static <T> Set<T> clone(Set<T> s, Supplier<Set<T>> supplier) {
+ Set<T> clone = supplier.get();
+ List<T> arrayList = Arrays.asList((T[]) s.toArray());
+ clone.addAll(arrayList);
+ if (!s.equals(clone))
+ fail("Set not equal to copy.");
+ if (!s.containsAll(clone))
+ fail("Set does not contain copy.");
+ if (!clone.containsAll(s))
+ fail("Copy does not contain set.");
+ return clone;
+ }
+
+ static void AddRandoms(Set s, int n) {
+ for (int i = 0; i < n; i++) {
+ Integer e = rnd.nextInt(n);
+
+ int preSize = s.size();
+ boolean prePresent = s.contains(e);
+ boolean added = s.add(e);
+ if (!s.contains(e))
+ fail("Element not present after addition.");
+ if (added == prePresent)
+ fail("added == alreadyPresent");
+ int postSize = s.size();
+ if (added && preSize == postSize)
+ fail("Add returned true, but size didn't change.");
+ if (!added && preSize != postSize)
+ fail("Add returned false, but size changed.");
+ }
+ }
+
+ @DataProvider(name = "Supplier<Set<Integer>>", parallel = true)
+ public static Iterator<Object[]> navigableSetsProvider() {
+ ArrayList<Object[]> iters = new ArrayList<>(makeCheckedSets());
+ iters.ensureCapacity(numItr * iters.size());
+ for (int each=1; each < numItr; each++) {
+ iters.addAll(makeCheckedSets());
+ }
+ return iters.iterator();
+ }
+
+ public static Collection<Object[]> makeCheckedSets() {
+ Object[][] params = {
+ {"Collections.checkedSet(HashSet)",
+ (Supplier) () -> Collections.checkedSet(new HashSet(), Integer.class)},
+ {"Collections.checkedSet(TreeSet(reverseOrder))",
+ (Supplier) () -> Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
+ {"Collections.checkedSet(TreeSet.descendingSet())",
+ (Supplier) () -> Collections.checkedSet(new TreeSet().descendingSet(), Integer.class)},
+ {"Collections.checkedNavigableSet(TreeSet)",
+ (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(), Integer.class)},
+ {"Collections.checkedNavigableSet(TreeSet(reverseOrder))",
+ (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
+ {"Collections.checkedNavigableSet(TreeSet.descendingSet())",
+ (Supplier) () -> Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class)},
+ };
+ return Arrays.asList(params);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java b/ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java
new file mode 100644
index 00000000000..bf055b66d32
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2018 Google Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run junit DelegatingIteratorForEachRemaining
+ */
+
+package test.java.util.Collections;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+public class DelegatingIteratorForEachRemaining {
+
+ static abstract class ForwardingIterator<E> implements Iterator<E> {
+ private final Iterator<E> delegate;
+
+ protected ForwardingIterator(Iterator<E> delegate) {
+ this.delegate = Objects.requireNonNull(delegate);
+ }
+
+ @Override public boolean hasNext() { return delegate.hasNext(); }
+ @Override public E next() { return delegate.next(); }
+ @Override public void remove() { delegate.remove(); }
+ @Override public void forEachRemaining(Consumer<? super E> action) {
+ delegate.forEachRemaining(action);
+ }
+ }
+
+ static final class ThrowingIterator<E> extends ForwardingIterator<E> {
+ public ThrowingIterator(Iterator<E> delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public void forEachRemaining(Consumer<? super E> action) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static abstract class ForwardingSet<E> implements Set<E> {
+ private final Set<E> delegate;
+
+ protected ForwardingSet(Set<E> delegate) {
+ this.delegate = Objects.requireNonNull(delegate);
+ }
+
+ @Override public int size() { return delegate.size(); }
+ @Override public boolean isEmpty() { return delegate.isEmpty(); }
+ @Override public boolean contains(Object o) { return delegate.contains(o); }
+ @Override public Iterator<E> iterator() { return delegate.iterator(); }
+ @Override public Object[] toArray() { return delegate.toArray(); }
+ @Override public <T> T[] toArray( T[] ts) { return delegate.toArray(ts); }
+ @Override public boolean add(E e) { return delegate.add(e); }
+ @Override public boolean remove(Object o) { return delegate.remove(o); }
+ @Override public boolean containsAll( Collection<?> c) { return delegate.containsAll(c); }
+ @Override public boolean addAll( Collection<? extends E> c) { return delegate.addAll(c); }
+ @Override public boolean retainAll( Collection<?> c) { return delegate.retainAll(c); }
+ @Override public boolean removeAll( Collection<?> c) { return delegate.removeAll(c); }
+ @Override public void clear() { delegate.clear(); }
+ @Override public boolean equals(Object o) { return delegate.equals(o); }
+ @Override public int hashCode() { return delegate.hashCode(); }
+ @Override public Spliterator<E> spliterator() { return delegate.spliterator(); }
+ @Override public boolean removeIf(Predicate<? super E> filter) { return delegate.removeIf(filter); }
+ @Override public Stream<E> stream() { return delegate.stream(); }
+ @Override public Stream<E> parallelStream() { return delegate.parallelStream(); }
+ @Override public void forEach(Consumer<? super E> action) { delegate.forEach(action); }
+ }
+
+ static class ThrowingSet<E> extends ForwardingSet<E> {
+ public ThrowingSet(Set<E> delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ThrowingIterator<E> iterator() {
+ return new ThrowingIterator<>(super.iterator());
+ }
+ }
+
+ static abstract class ForwardingMap<K, V> implements Map<K, V> {
+ private final Map<K, V> delegate;
+
+ public ForwardingMap(Map<K, V> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override public int size() { return delegate.size(); }
+ @Override public boolean isEmpty() { return delegate.isEmpty(); }
+ @Override public boolean containsKey(Object o) { return delegate.containsKey(o); }
+ @Override public boolean containsValue(Object o) { return delegate.containsValue(o); }
+ @Override public V get(Object o) { return delegate.get(o); }
+ @Override public V put(K k, V v) { return delegate.put(k, v); }
+ @Override public V remove(Object o) { return delegate.remove(o); }
+ @Override public void putAll(Map<? extends K, ? extends V> map) { delegate.putAll(map); }
+ @Override public void clear() { delegate.clear(); }
+ @Override public Set<K> keySet() { return delegate.keySet(); }
+ @Override public Collection<V> values() { return delegate.values(); }
+ @Override public Set<Entry<K, V>> entrySet() { return delegate.entrySet(); }
+ @Override public boolean equals(Object o) { return delegate.equals(o); }
+ @Override public int hashCode() { return delegate.hashCode(); }
+ @Override public V getOrDefault(Object key, V defaultValue) { return delegate.getOrDefault(key, defaultValue); }
+ @Override public void forEach(BiConsumer<? super K, ? super V> action) { delegate.forEach(action); }
+ @Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { delegate.replaceAll(function); }
+ @Override public V putIfAbsent(K key, V value) { return delegate.putIfAbsent(key, value); }
+ @Override public boolean remove(Object key, Object value) { return delegate.remove(key, value); }
+ @Override public boolean replace(K key, V oldValue, V newValue) { return delegate.replace(key, oldValue, newValue); }
+ @Override public V replace(K key, V value) { return delegate.replace(key, value); }
+ @Override public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { return delegate.computeIfAbsent(key, mappingFunction); }
+ @Override public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { return delegate.computeIfPresent(key, remappingFunction); }
+ @Override public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { return delegate.compute(key, remappingFunction); }
+ @Override public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { return delegate.merge(key, value, remappingFunction); }
+ }
+
+ static class ThrowingMap<K, V> extends ForwardingMap<K, V> {
+ public ThrowingMap(Map<K, V> delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ThrowingSet<Entry<K, V>> entrySet() {
+ return new ThrowingSet<>(super.entrySet());
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return new ThrowingSet(super.keySet());
+ }
+ }
+
+ static<E> void assertThrowingIterator(Iterator<E> iterator) {
+ try {
+ iterator.forEachRemaining((entry) -> {});
+ Assert.fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ private static Map<String, Object> map() {
+ Map<String, Object> map = new HashMap<>();
+ map.put("name", "Bill");
+ map.put("age", 23);
+ return new ThrowingMap<>(map);
+ }
+
+ @Test public void testUnwrapped() {
+ assertThrowingIterator(map().entrySet().iterator());
+ assertThrowingIterator(map().keySet().iterator());
+ }
+
+ @Test public void test_unmodifiableMap_entrySet() {
+ assertThrowingIterator(Collections.unmodifiableMap(map()).entrySet().iterator());
+ }
+
+ @Test public void test_checkedMap_entrySet() {
+ assertThrowingIterator(Collections.checkedMap(map(), String.class, Object.class).entrySet().iterator());
+ }
+
+ @Test public void test_entrySet_checkedSet() {
+ Set<Map.Entry<String, Object>> entrySet = map().entrySet();
+ Class clazz = entrySet.iterator().next().getClass();
+ assertThrowingIterator(Collections.checkedSet(entrySet, clazz).iterator());
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/Disjoint.java b/ojluni/src/test/java/util/Collections/Disjoint.java
new file mode 100644
index 00000000000..748629c94b9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Disjoint.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4339792
+ * @summary Basic test for Collections.disjoint
+ * @author Josh Bloch
+ * @key randomness
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+public class Disjoint {
+ static final int N = 20;
+
+ public static void main(String[] args) {
+ // Make an array of lists each of which shares a single element
+ // with its "neighbors," and no elements with other lists in the array
+ Random rnd = new Random();
+ List[] lists = new List[N];
+ int x = 0;
+ for (int i = 0; i < N; i++) {
+ int size = rnd.nextInt(10) + 2;
+ List<Integer> list = new ArrayList<>(size);
+ for (int j = 1; j < size; j++)
+ list.add(x++);
+ list.add(x);
+ Collections.shuffle(list);
+
+ lists[i] = list;
+ }
+
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ boolean disjoint = (Math.abs(i - j) > 1);
+ List<Integer> a = (List<Integer>) lists[i];
+ List<Integer> b = (List<Integer>) lists[j];
+
+ if (Collections.disjoint(a, b) != disjoint)
+ throw new RuntimeException("A: " + i + ", " + j);
+ if (Collections.disjoint(new HashSet<Integer>(a), b)
+ != disjoint)
+ throw new RuntimeException("B: " + i + ", " + j);
+ if (Collections.disjoint(new HashSet<Integer>(a),
+ new HashSet<Integer>(b)) != disjoint)
+ throw new RuntimeException("C: " + i + ", " + j);
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java b/ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java
new file mode 100644
index 00000000000..466c35e29bb
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4684279 7129185
+ * @summary Empty utility collections should be singletons
+ * @author Josh Bloch
+ * @run testng EmptyCollectionSerialization
+ */
+
+package test.java.util.Collections;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.fail;
+
+public class EmptyCollectionSerialization {
+ private static Object patheticDeepCopy(Object o) throws Exception {
+ // Serialize
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(o);
+ byte[] serializedForm = bos.toByteArray();
+
+ // Deserialize
+ InputStream is = new ByteArrayInputStream(serializedForm);
+ ObjectInputStream ois = new ObjectInputStream(is);
+ return ois.readObject();
+ }
+
+ @Test(dataProvider="SerializableSingletons")
+ public static void serializableSingletons(String description, Supplier<Object> o) {
+ try {
+ Object singleton = o.get();
+ assertSame(o.get(), singleton, description + ": broken Supplier not returning singleton");
+ Object copy = patheticDeepCopy(singleton);
+ assertSame(copy, singleton, description + ": " +
+ copy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(copy)) +
+ " is not the singleton " +
+ singleton.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(singleton)));
+ } catch (Exception all) {
+ fail(description + ": Unexpected Exception", all);
+ }
+ }
+
+ @DataProvider(name = "SerializableSingletons", parallel = true)
+ public static Iterator<Object[]> navigableMapProvider() {
+ return makeSingletons().iterator();
+ }
+
+ public static Collection<Object[]> makeSingletons() {
+ Object[][] params = {
+ {"Collections.EMPTY_LIST",
+ (Supplier) () -> Collections.EMPTY_LIST},
+ {"Collections.EMPTY_MAP",
+ (Supplier) () -> Collections.EMPTY_MAP},
+ {"Collections.EMPTY_SET",
+ (Supplier) () -> Collections.EMPTY_SET},
+ {"Collections.emptyList()",
+ (Supplier) () -> Collections.emptyList()},
+ {"Collections.emptyMap()",
+ (Supplier) () -> Collections.emptyMap()},
+ {"Collections.emptySet()",
+ (Supplier) () -> Collections.emptySet()},
+ {"Collections.emptySortedSet()",
+ (Supplier) () -> Collections.emptySortedSet()},
+ {"Collections.emptySortedMap()",
+ (Supplier) () -> Collections.emptySortedMap()},
+ {"Collections.emptyNavigableSet()",
+ (Supplier) () -> Collections.emptyNavigableSet()},
+ {"Collections.emptyNavigableMap()",
+ (Supplier) () -> Collections.emptyNavigableMap()},
+ };
+ return Arrays.asList(params);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyIterator.java b/ojluni/src/test/java/util/Collections/EmptyIterator.java
new file mode 100644
index 00000000000..a311d8553dd
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyIterator.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5017904 6356890 8004928
+ * @summary Test empty iterators, enumerations, and collections
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.concurrent.SynchronousQueue;
+
+import static java.util.Collections.emptyEnumeration;
+import static java.util.Collections.emptyIterator;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyListIterator;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.nCopies;
+import static java.util.Collections.unmodifiableMap;
+
+public class EmptyIterator {
+
+ void test(String[] args) throws Throwable {
+ testEmptyCollection(emptyList());
+ testEmptyCollection(emptySet());
+ testEmptyCollection(new SynchronousQueue<Object>());
+ testEmptyMap(emptyMap());
+
+ Hashtable<?,?> emptyTable = new Hashtable<>();
+ testEmptyEnumeration(emptyTable.keys());
+ testEmptyEnumeration(emptyTable.elements());
+ testEmptyIterator(emptyTable.keySet().iterator());
+ testEmptyIterator(emptyTable.values().iterator());
+ testEmptyIterator(emptyTable.entrySet().iterator());
+
+ final Enumeration<EmptyIterator> finalEmptyTyped = emptyEnumeration();
+ testEmptyEnumeration(finalEmptyTyped);
+
+ final Enumeration<?> finalEmptyAbstract = emptyEnumeration();
+ testEmptyEnumeration(finalEmptyAbstract);
+
+ testEmptyIterator(emptyIterator());
+ }
+
+ void testEmptyEnumeration(final Enumeration<?> e) {
+ check(e == emptyEnumeration());
+ check(!e.hasMoreElements());
+ THROWS(NoSuchElementException.class,
+ new F(){void f(){ e.nextElement(); }});
+ }
+
+ void testEmptyIterator(final Iterator<?> it) {
+ check(it == emptyIterator());
+ check(! it.hasNext());
+ THROWS(NoSuchElementException.class,
+ new F(){void f(){ it.next(); }});
+ THROWS(IllegalStateException.class,
+ new F(){void f(){ it.remove(); }});
+ }
+
+ void testEmptyMap(Map<?,?> m) {
+ check(m == emptyMap());
+ check(m.entrySet().iterator() ==
+ Collections.<Map.Entry<?,?>>emptyIterator());
+ check(m.values().iterator() == emptyIterator());
+ check(m.keySet().iterator() == emptyIterator());
+ equal(m, unmodifiableMap(m));
+
+ testEmptyCollection(m.keySet());
+ testEmptyCollection(m.entrySet());
+ testEmptyCollection(m.values());
+ }
+
+ void testToArray(final Collection<?> c) {
+ Object[] a = c.toArray();
+ equal(a.length, 0);
+ equal(a.getClass().getComponentType(), Object.class);
+ THROWS(NullPointerException.class,
+ new F(){void f(){ c.toArray((Object[])null); }});
+
+ {
+ String[] t = new String[0];
+ check(c.toArray(t) == t);
+ }
+
+ {
+ String[] t = nCopies(10, "").toArray(new String[0]);
+ check(c.toArray(t) == t);
+ check(t[0] == null);
+ for (int i=1; i<t.length; i++)
+ check(t[i] == "");
+ }
+ }
+
+ void testEmptyCollection(final Collection<?> c) {
+ testEmptyIterator(c.iterator());
+
+ check(c.iterator() == emptyIterator());
+ if (c instanceof List)
+ check(((List<?>)c).listIterator() == emptyListIterator());
+
+ testToArray(c);
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new EmptyIterator().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ abstract class F {abstract void f() throws Throwable;}
+ void THROWS(Class<? extends Throwable> k, F... fs) {
+ for (F f : fs)
+ try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyNavigableMap.java b/ojluni/src/test/java/util/Collections/EmptyNavigableMap.java
new file mode 100644
index 00000000000..40f6c5d5dd9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyNavigableMap.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4533691 7129185
+ * @summary Unit test for Collections.emptyNavigableMap
+ * @run testng EmptyNavigableMap
+ */
+
+package test.java.util.Collections;
+
+import org.testng.Assert;
+import org.testng.Assert.ThrowingRunnable;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableMap;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+public class EmptyNavigableMap {
+
+ public static <T> void assertInstance(T actual, Class<? extends T> expected) {
+ assertInstance(actual, expected, null);
+ }
+
+ public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
+ assertTrue(expected.isInstance(actual), ((null != message) ? message : "")
+ + " " + (actual == null ? "<null>" : actual.getClass().getSimpleName()) + " != " + expected.getSimpleName() + ". ");
+ }
+
+ public static <T extends Throwable> void assertEmptyNavigableMap(Object obj) {
+ assertInstance(obj, NavigableMap.class);
+ assertTrue(((NavigableMap)obj).isEmpty() && (((NavigableMap)obj).size() == 0));
+ }
+
+ public static <T extends Throwable> void assertEmptyNavigableMap(Object obj, String message) {
+ assertInstance(obj, NavigableMap.class, message);
+ assertTrue(((NavigableMap)obj).isEmpty() && (((NavigableMap)obj).size() == 0),
+ ((null != message) ? message : "") + " Not empty. ");
+ }
+
+ private <T extends Throwable> void assertThrows(Class<T> throwableClass,
+ ThrowingRunnable runnable,
+ String message) {
+ try {
+ Assert.assertThrows(throwableClass, runnable);
+ } catch (AssertionError e) {
+ throw new AssertionError(String.format("%s%n%s",
+ ((null != message) ? message : ""), e.getMessage()), e);
+ }
+ }
+
+ private void assertThrowsCCE(ThrowingRunnable r, String s) {
+ assertThrows(ClassCastException.class, r, s);
+ }
+
+ private void assertThrowsNPE(ThrowingRunnable r, String s) {
+ assertThrows(NullPointerException.class, r, s);
+ }
+
+ private void assertThrowsIAE(ThrowingRunnable r, String s) {
+ assertThrows(IllegalArgumentException.class, r, s);
+ }
+
+ public static final boolean isDescending(SortedMap<?,?> set) {
+ if (null == set.comparator()) {
+ // natural order
+ return false;
+ }
+
+ if (Collections.reverseOrder() == set.comparator()) {
+ // reverse natural order.
+ return true;
+ }
+
+ if (set.comparator().equals(Collections.reverseOrder(Collections.reverseOrder(set.comparator())))) {
+ // it's a Collections.reverseOrder(Comparator).
+ return true;
+ }
+
+ throw new IllegalStateException("can't determine ordering for " + set);
+ }
+
+ /**
+ * Tests that the comparator is {@code null}.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testComparatorIsNull(String description, NavigableMap<?,?> navigableMap) {
+ Comparator comparator = navigableMap.comparator();
+
+ assertTrue(comparator == null || comparator == Collections.reverseOrder(), description + ": Comparator (" + comparator + ") is not null.");
+ }
+
+ /**
+ * Tests that contains requires Comparable
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testContainsRequiresComparable(String description, NavigableMap<?,?> navigableMap) {
+ assertThrowsCCE(
+ () -> navigableMap.containsKey(new Object()),
+ description + ": Comparable should be required");
+ }
+
+ /**
+ * Tests that the contains method returns {@code false}.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testContains(String description, NavigableMap<?,?> navigableMap) {
+ assertFalse(navigableMap.containsKey(new Integer(1)),
+ description + ": Should not contain any elements.");
+ assertFalse(navigableMap.containsValue(new Integer(1)),
+ description + ": Should not contain any elements.");
+ }
+
+ /**
+ * Tests that the containsAll method returns {@code false}.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testContainsAll(String description, NavigableMap<?,?> navigableMap) {
+ TreeMap treeMap = new TreeMap();
+ treeMap.put("1", 1);
+ treeMap.put("2", 2);
+ treeMap.put("3", 3);
+
+ assertFalse(navigableMap.equals(treeMap), "Should not contain any elements.");
+ }
+
+ /**
+ * Tests that the iterator is empty.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testEmptyIterator(String description, NavigableMap<?,?> navigableMap) {
+ assertFalse(navigableMap.keySet().iterator().hasNext(), "The iterator is not empty.");
+ assertFalse(navigableMap.values().iterator().hasNext(), "The iterator is not empty.");
+ assertFalse(navigableMap.entrySet().iterator().hasNext(), "The iterator is not empty.");
+ }
+
+ /**
+ * Tests that the set is empty.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testIsEmpty(String description, NavigableMap<?,?> navigableMap) {
+ assertTrue(navigableMap.isEmpty(), "The set is not empty.");
+ }
+
+ /**
+ * Tests the headMap() method.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testHeadMap(String description, NavigableMap navigableMap) {
+ assertThrowsNPE(
+ () -> { NavigableMap ss = navigableMap.headMap(null, false); },
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsCCE(
+ () -> { NavigableMap ss = navigableMap.headMap(new Object(), true); },
+ description + ": Must throw ClassCastException for non-Comparable element");
+
+ NavigableMap ss = navigableMap.headMap("1", false);
+
+ assertEmptyNavigableMap(ss, description + ": Returned value is not empty navigable set.");
+ }
+
+ /**
+ * Tests that the size is 0.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testSizeIsZero(String description, NavigableMap<?,?> navigableMap) {
+ assertTrue(0 == navigableMap.size(), "The size of the set is not 0.");
+ }
+
+ /**
+ * Tests the subMap() method.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testSubMap(String description, NavigableMap navigableMap) {
+ assertThrowsNPE(
+ () -> {
+ SortedMap ss = navigableMap.subMap(null, BigInteger.TEN);
+ },
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsNPE(
+ () -> {
+ SortedMap ss = navigableMap.subMap(BigInteger.ZERO, null);
+ },
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsNPE(
+ () -> {
+ SortedMap ss = navigableMap.subMap(null, null);
+ },
+ description + ": Must throw NullPointerException for null element");
+
+ Object obj1 = new Object();
+ Object obj2 = new Object();
+
+ assertThrowsCCE(
+ () -> {
+ SortedMap ss = navigableMap.subMap(obj1, BigInteger.TEN);
+ },
+ description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+ assertThrowsCCE(
+ () -> {
+ SortedMap ss = navigableMap.subMap(BigInteger.ZERO, obj2);
+ },
+ description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+ assertThrowsCCE(
+ () -> {
+ SortedMap ss = navigableMap.subMap(obj1, obj2);
+ },
+ description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+ // minimal range
+ navigableMap.subMap(BigInteger.ZERO, false, BigInteger.ZERO, false);
+ navigableMap.subMap(BigInteger.ZERO, false, BigInteger.ZERO, true);
+ navigableMap.subMap(BigInteger.ZERO, true, BigInteger.ZERO, false);
+ navigableMap.subMap(BigInteger.ZERO, true, BigInteger.ZERO, true);
+
+ Object first = isDescending(navigableMap) ? BigInteger.TEN : BigInteger.ZERO;
+ Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+ assertThrowsIAE(
+ () -> navigableMap.subMap(last, true, first, false),
+ description + ": Must throw IllegalArgumentException when fromElement is not less than toElement.");
+
+ navigableMap.subMap(first, true, last, false);
+ }
+
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testSubMapRanges(String description, NavigableMap navigableMap) {
+ Object first = isDescending(navigableMap) ? BigInteger.TEN : BigInteger.ZERO;
+ Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+ NavigableMap subMap = navigableMap.subMap(first, true, last, true);
+
+ // same subset
+ subMap.subMap(first, true, last, true);
+
+ // slightly smaller
+ NavigableMap ns = subMap.subMap(first, false, last, false);
+ // slight expansion
+ assertThrowsIAE(
+ () -> ns.subMap(first, true, last, true),
+ description + ": Expansion should not be allowed");
+
+ // much smaller
+ subMap.subMap(first, false, BigInteger.ONE, false);
+ }
+
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testheadMapRanges(String description, NavigableMap navigableMap) {
+ NavigableMap subMap = navigableMap.headMap(BigInteger.ONE, true);
+
+ // same subset
+ subMap.headMap(BigInteger.ONE, true);
+
+ // slightly smaller
+ NavigableMap ns = subMap.headMap(BigInteger.ONE, false);
+
+ // slight expansion
+ assertThrowsIAE(
+ () -> ns.headMap(BigInteger.ONE, true),
+ description + ": Expansion should not be allowed");
+
+ // much smaller
+ subMap.headMap(isDescending(subMap) ? BigInteger.TEN : BigInteger.ZERO, true);
+ }
+
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testTailMapRanges(String description, NavigableMap navigableMap) {
+ NavigableMap subMap = navigableMap.tailMap(BigInteger.ONE, true);
+
+ // same subset
+ subMap.tailMap(BigInteger.ONE, true);
+
+ // slightly smaller
+ NavigableMap ns = subMap.tailMap(BigInteger.ONE, false);
+
+ // slight expansion
+ assertThrowsIAE(
+ () -> ns.tailMap(BigInteger.ONE, true),
+ description + ": Expansion should not be allowed");
+
+ // much smaller
+ subMap.tailMap(isDescending(subMap) ? BigInteger.ZERO : BigInteger.TEN, false);
+ }
+
+ /**
+ * Tests the tailMap() method.
+ */
+ @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+ public void testTailMap(String description, NavigableMap navigableMap) {
+ assertThrowsNPE(
+ () -> navigableMap.tailMap(null),
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsCCE(
+ () -> navigableMap.tailMap(new Object()),
+ description);
+
+ NavigableMap ss = navigableMap.tailMap("1", true);
+
+ assertEmptyNavigableMap(ss, description + ": Returned value is not empty navigable set.");
+ }
+
+ @DataProvider(name = "NavigableMap<?,?>", parallel = true)
+ public static Iterator<Object[]> navigableMapsProvider() {
+ return makeNavigableMaps().iterator();
+ }
+
+ public static Collection<Object[]> makeNavigableMaps() {
+ return Arrays.asList(
+ new Object[]{"UnmodifiableNavigableMap(TreeMap)", Collections.unmodifiableNavigableMap(new TreeMap())},
+ new Object[]{"UnmodifiableNavigableMap(TreeMap.descendingMap()", Collections.unmodifiableNavigableMap(new TreeMap().descendingMap())},
+ new Object[]{"UnmodifiableNavigableMap(TreeMap.descendingMap().descendingMap()", Collections.unmodifiableNavigableMap(new TreeMap().descendingMap().descendingMap())},
+ new Object[]{"emptyNavigableMap()", Collections.emptyNavigableMap()},
+ new Object[]{"emptyNavigableMap().descendingMap()", Collections.emptyNavigableMap().descendingMap()},
+ new Object[]{"emptyNavigableMap().descendingMap().descendingMap()", Collections.emptyNavigableMap().descendingMap().descendingMap()}
+ );
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyNavigableSet.java b/ojluni/src/test/java/util/Collections/EmptyNavigableSet.java
new file mode 100644
index 00000000000..19a9bba2035
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyNavigableSet.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4533691 7129185
+ * @summary Unit test for Collections.emptyNavigableSet
+ * @run testng EmptyNavigableSet
+ */
+
+package test.java.util.Collections;
+
+import org.testng.Assert;
+import org.testng.Assert.ThrowingRunnable;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+public class EmptyNavigableSet {
+
+ public static <T> void assertInstance(T actual, Class<? extends T> expected) {
+ assertInstance(actual, expected, null);
+ }
+
+ public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
+ assertTrue(expected.isInstance(actual), ((null != message) ? message : "")
+ + " " + (actual == null ? "<null>" : actual.getClass().getSimpleName()) + " != " + expected.getSimpleName() + ". ");
+ }
+
+ public static <T extends Throwable> void assertEmptyNavigableSet(Object obj) {
+ assertInstance(obj, NavigableSet.class);
+ assertTrue(((NavigableSet)obj).isEmpty() && (((NavigableSet)obj).size() == 0));
+ }
+
+ public static <T extends Throwable> void assertEmptyNavigableSet(Object obj, String message) {
+ assertInstance(obj, NavigableSet.class, message);
+ assertTrue(((NavigableSet)obj).isEmpty() && (((NavigableSet)obj).size() == 0),
+ ((null != message) ? message : "") + " Not empty. ");
+ }
+
+ private <T extends Throwable> void assertThrows(Class<T> throwableClass,
+ ThrowingRunnable runnable,
+ String message) {
+ try {
+ Assert.assertThrows(throwableClass, runnable);
+ } catch (AssertionError e) {
+ throw new AssertionError(String.format("%s%n%s",
+ ((null != message) ? message : ""), e.getMessage()), e);
+ }
+ }
+
+ private void assertThrowsCCE(ThrowingRunnable r, String s) {
+ assertThrows(ClassCastException.class, r, s);
+ }
+
+ private void assertThrowsNPE(ThrowingRunnable r, String s) {
+ assertThrows(NullPointerException.class, r, s);
+ }
+
+ private void assertThrowsIAE(ThrowingRunnable r, String s) {
+ assertThrows(IllegalArgumentException.class, r, s);
+ }
+
+ private void assertThrowsNSEE(ThrowingRunnable r, String s) {
+ assertThrows(NoSuchElementException.class, r, s);
+ }
+
+ public static final boolean isDescending(SortedSet<?> set) {
+ if (null == set.comparator()) {
+ // natural order
+ return false;
+ }
+
+ if (Collections.reverseOrder() == set.comparator()) {
+ // reverse natural order.
+ return true;
+ }
+
+ if (set.comparator().equals(Collections.reverseOrder(Collections.reverseOrder(set.comparator())))) {
+ // it's a Collections.reverseOrder(Comparator).
+ return true;
+ }
+
+ throw new IllegalStateException("can't determine ordering for " + set);
+ }
+
+ /**
+ * Tests that the comparator is {@code null}.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testComparatorIsNull(String description, NavigableSet<?> navigableSet) {
+ Comparator comparator = navigableSet.comparator();
+
+ assertTrue(comparator == null || comparator == Collections.reverseOrder(), description + ": Comparator (" + comparator + ") is not null.");
+ }
+
+ /**
+ * Tests that contains requires Comparable
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testContainsRequiresComparable(String description, NavigableSet<?> navigableSet) {
+ assertThrowsCCE(
+ () -> navigableSet.contains(new Object()),
+ description + ": Comparable should be required");
+ }
+
+ /**
+ * Tests that the contains method returns {@code false}.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testContains(String description, NavigableSet<?> navigableSet) {
+ assertFalse(navigableSet.contains(new Integer(1)),
+ description + ": Should not contain any elements.");
+ }
+
+ /**
+ * Tests that the containsAll method returns {@code false}.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testContainsAll(String description, NavigableSet<?> navigableSet) {
+ TreeSet treeSet = new TreeSet();
+ treeSet.add("1");
+ treeSet.add("2");
+ treeSet.add("3");
+
+ assertFalse(navigableSet.containsAll(treeSet), "Should not contain any elements.");
+ }
+
+ /**
+ * Tests that the iterator is empty.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testEmptyIterator(String description, NavigableSet<?> navigableSet) {
+ assertFalse(navigableSet.iterator().hasNext(), "The iterator is not empty.");
+ }
+
+ /**
+ * Tests that the set is empty.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testIsEmpty(String description, NavigableSet<?> navigableSet) {
+ assertTrue(navigableSet.isEmpty(), "The set is not empty.");
+ }
+
+ /**
+ * Tests that the first() method throws NoSuchElementException
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testFirst(String description, NavigableSet<?> navigableSet) {
+ assertThrowsNSEE(navigableSet::first, description);
+ }
+
+ /**
+ * Tests the headSet() method.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testHeadSet(String description, NavigableSet navigableSet) {
+ assertThrowsNPE(
+ () -> { NavigableSet ns = navigableSet.headSet(null, false); },
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsCCE(
+ () -> { NavigableSet ns = navigableSet.headSet(new Object(), true); },
+ description + ": Must throw ClassCastException for non-Comparable element");
+
+ NavigableSet ns = navigableSet.headSet("1", false);
+
+ assertEmptyNavigableSet(ns, description + ": Returned value is not empty navigable set.");
+ }
+
+ /**
+ * Tests that the last() method throws NoSuchElementException
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testLast(String description, NavigableSet<?> navigableSet) {
+ assertThrowsNSEE(navigableSet::last, description);
+ }
+
+ /**
+ * Tests that the size is 0.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testSizeIsZero(String description, NavigableSet<?> navigableSet) {
+ assertTrue(0 == navigableSet.size(), "The size of the set is not 0.");
+ }
+
+ /**
+ * Tests the subSet() method.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testSubSet(String description, NavigableSet navigableSet) {
+ assertThrowsNPE(
+ () -> {
+ SortedSet ss = navigableSet.subSet(null, BigInteger.TEN);
+ },
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsNPE(
+ () -> {
+ SortedSet ss = navigableSet.subSet(BigInteger.ZERO, null);
+ },
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsNPE(
+ () -> {
+ SortedSet ss = navigableSet.subSet(null, null);
+ },
+ description + ": Must throw NullPointerException for null element");
+
+ Object obj1 = new Object();
+ Object obj2 = new Object();
+
+ assertThrowsCCE(
+ () -> {
+ SortedSet ss = navigableSet.subSet(obj1, BigInteger.TEN);
+ },
+ description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+ assertThrowsCCE(
+ () -> {
+ SortedSet ss = navigableSet.subSet(BigInteger.ZERO, obj2);
+ },
+ description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+ assertThrowsCCE(
+ () -> {
+ SortedSet ss = navigableSet.subSet(obj1, obj2);
+ },
+ description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+ // minimal range
+ navigableSet.subSet(BigInteger.ZERO, false, BigInteger.ZERO, false);
+ navigableSet.subSet(BigInteger.ZERO, false, BigInteger.ZERO, true);
+ navigableSet.subSet(BigInteger.ZERO, true, BigInteger.ZERO, false);
+ navigableSet.subSet(BigInteger.ZERO, true, BigInteger.ZERO, true);
+
+ Object first = isDescending(navigableSet) ? BigInteger.TEN : BigInteger.ZERO;
+ Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+ assertThrowsIAE(
+ () -> navigableSet.subSet(last, true, first, false),
+ description
+ + ": Must throw IllegalArgumentException when fromElement is not less than toElement.");
+
+ navigableSet.subSet(first, true, last, false);
+ }
+
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testSubSetRanges(String description, NavigableSet navigableSet) {
+ Object first = isDescending(navigableSet) ? BigInteger.TEN : BigInteger.ZERO;
+ Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+ NavigableSet subSet = navigableSet.subSet(first, true, last, true);
+
+ // same subset
+ subSet.subSet(first, true, last, true);
+
+ // slightly smaller
+ NavigableSet ns = subSet.subSet(first, false, last, false);
+ // slight expansion
+ assertThrowsIAE(
+ () -> ns.subSet(first, true, last, true),
+ description + ": Expansion should not be allowed");
+
+ // much smaller
+ subSet.subSet(first, false, BigInteger.ONE, false);
+ }
+
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testheadSetRanges(String description, NavigableSet navigableSet) {
+ NavigableSet subSet = navigableSet.headSet(BigInteger.ONE, true);
+
+ // same subset
+ subSet.headSet(BigInteger.ONE, true);
+
+ // slightly smaller
+ NavigableSet ns = subSet.headSet(BigInteger.ONE, false);
+
+ // slight expansion
+ assertThrowsIAE(
+ () -> ns.headSet(BigInteger.ONE, true),
+ description + ": Expansion should not be allowed");
+
+ // much smaller
+ subSet.headSet(isDescending(subSet) ? BigInteger.TEN : BigInteger.ZERO, true);
+ }
+
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testTailSetRanges(String description, NavigableSet navigableSet) {
+ NavigableSet subSet = navigableSet.tailSet(BigInteger.ONE, true);
+
+ // same subset
+ subSet.tailSet(BigInteger.ONE, true);
+
+ // slightly smaller
+ NavigableSet ns = subSet.tailSet(BigInteger.ONE, false);
+
+ // slight expansion
+ assertThrowsIAE(
+ () -> ns.tailSet(BigInteger.ONE, true),
+ description + ": Expansion should not be allowed");
+
+ // much smaller
+ subSet.tailSet(isDescending(subSet) ? BigInteger.ZERO : BigInteger.TEN, false);
+ }
+
+ /**
+ * Tests the tailSet() method.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testTailSet(String description, NavigableSet navigableSet) {
+ assertThrowsNPE(
+ () -> navigableSet.tailSet(null),
+ description + ": Must throw NullPointerException for null element");
+
+ assertThrowsCCE(
+ () -> navigableSet.tailSet(new Object()),
+ description);
+
+ NavigableSet ss = navigableSet.tailSet("1", true);
+
+ assertEmptyNavigableSet(ss, description + ": Returned value is not empty navigable set.");
+ }
+
+ /**
+ * Tests that the array has a size of 0.
+ */
+ @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+ public void testToArray(String description, NavigableSet<?> navigableSet) {
+ Object[] emptyNavigableSetArray = navigableSet.toArray();
+
+ assertTrue(emptyNavigableSetArray.length == 0, "Returned non-empty Array.");
+
+ emptyNavigableSetArray = new Object[20];
+
+ Object[] result = navigableSet.toArray(emptyNavigableSetArray);
+
+ assertSame(emptyNavigableSetArray, result);
+
+ assertNull(result[0]);
+ }
+
+ @DataProvider(name = "NavigableSet<?>", parallel = true)
+ public static Iterator<Object[]> navigableSetsProvider() {
+ return makeNavigableSets().iterator();
+ }
+
+ public static Collection<Object[]> makeNavigableSets() {
+ return Arrays.asList(
+ new Object[]{"UnmodifiableNavigableSet(TreeSet)", Collections.unmodifiableNavigableSet(new TreeSet())},
+ new Object[]{"UnmodifiableNavigableSet(TreeSet.descendingSet()", Collections.unmodifiableNavigableSet(new TreeSet().descendingSet())},
+ new Object[]{"UnmodifiableNavigableSet(TreeSet.descendingSet().descendingSet()", Collections.unmodifiableNavigableSet(new TreeSet().descendingSet().descendingSet())},
+ new Object[]{"emptyNavigableSet()", Collections.emptyNavigableSet()},
+ new Object[]{"emptyNavigableSet().descendingSet()", Collections.emptyNavigableSet().descendingSet()},
+ new Object[]{"emptyNavigableSet().descendingSet().descendingSet()", Collections.emptyNavigableSet().descendingSet().descendingSet()}
+ );
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/Enum.java b/ojluni/src/test/java/util/Collections/Enum.java
new file mode 100644
index 00000000000..99acd7193f0
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Enum.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4323074
+ * @summary Basic test for new Enumeration -> List converter
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+public class Enum {
+ public static void main(String[] args) throws Exception {
+ int[] sizes = {0, 10, 100};
+ for (int i=0; i<sizes.length; i++) {
+ Vector v = new Vector();
+ int size = sizes[i];
+ for (int j=0; j<size; j++)
+ v.add(new Integer(j));
+ List l = Collections.list(v.elements());
+ if (!l.equals(v))
+ throw new Exception("Copy failed: "+size);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java b/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java
index 60cad8f55a6..5930c4c00de 100644
--- a/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java
+++ b/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java
@@ -76,43 +76,43 @@ public class EnumerationAsIterator {
@DataProvider
public static Iterator<Object[]> unmodifiable() {
return Arrays.asList(
- of("Default-wrapped ArrayList",
- () -> wrapInDefault(
- Collections.enumeration(new ArrayList<>(Arrays.asList("a")))),
- Arrays.asList("a")),
-
- of("Unmodifiable ArrayList",
- Collections.unmodifiableList(new ArrayList<>(Arrays.asList("a"))),
- Arrays.asList("a")),
-
- of("Modifiable ArrayList",
- new ArrayList<>(Arrays.asList("a")),
- Arrays.asList("a"))
+ of("Default-wrapped ArrayList",
+ () -> wrapInDefault(
+ Collections.enumeration(new ArrayList<>(Arrays.asList("a")))),
+ Arrays.asList("a")),
+
+ of("Unmodifiable ArrayList",
+ Collections.unmodifiableList(new ArrayList<>(Arrays.asList("a"))),
+ Arrays.asList("a")),
+
+ of("Modifiable ArrayList",
+ new ArrayList<>(Arrays.asList("a")),
+ Arrays.asList("a"))
).iterator();
}
@DataProvider
public static Iterator<Object[]> others() {
return Arrays.asList(
- of("Default Collections.emptyEnumeration()",
- () -> wrapInDefault(Collections.emptyEnumeration()),
- Collections.emptyList()),
+ of("Default Collections.emptyEnumeration()",
+ () -> wrapInDefault(Collections.emptyEnumeration()),
+ Collections.emptyList()),
- of("Collections.emptyEnumeration()",
- Collections::emptyEnumeration,
- Collections.emptyList()),
+ of("Collections.emptyEnumeration()",
+ Collections::emptyEnumeration,
+ Collections.emptyList()),
- of("Collections.emptyList()",
- Collections.emptyList(),
- Collections.emptyList()),
+ of("Collections.emptyList()",
+ Collections.emptyList(),
+ Collections.emptyList()),
- of("Collections.singletonList()",
- Collections.singletonList("a"),
- Collections.singletonList("a")),
+ of("Collections.singletonList()",
+ Collections.singletonList("a"),
+ Collections.singletonList("a")),
- of("Arrays.asList(...)",
- Arrays.asList("a", "b", "c"),
- Arrays.asList("a", "b", "c"))
+ of("Arrays.asList(...)",
+ Arrays.asList("a", "b", "c"),
+ Arrays.asList("a", "b", "c"))
).iterator();
}
@@ -147,8 +147,8 @@ public class EnumerationAsIterator {
@Test(dataProvider = "all")
public void consumeByForEachRemaining(String description,
- Supplier<Enumeration<?>> s,
- Collection<?> exp) {
+ Supplier<Enumeration<?>> s,
+ Collection<?> exp) {
Iterator<?> i = s.get().asIterator();
AtomicInteger ai = new AtomicInteger();
i.forEachRemaining(e -> ai.getAndIncrement());
@@ -167,8 +167,8 @@ public class EnumerationAsIterator {
@Test(dataProvider = "all")
public void consumeByNextThenForEachRemaining(String description,
- Supplier<Enumeration<?>> s,
- Collection<?> exp) {
+ Supplier<Enumeration<?>> s,
+ Collection<?> exp) {
Iterator<?> i = s.get().asIterator();
AtomicInteger ai = new AtomicInteger();
if (i.hasNext()) {
@@ -201,22 +201,22 @@ public class EnumerationAsIterator {
}
@Test(dataProvider = "unmodifiable",
- expectedExceptions=UnsupportedOperationException.class)
+ expectedExceptions=UnsupportedOperationException.class)
public void removeThrowsAfterAdvancingE(String description,
- Supplier<Enumeration<?>> s,
- Collection<?> exp) {
+ Supplier<Enumeration<?>> s,
+ Collection<?> exp) {
Enumeration<?> e = s.get();
e.nextElement();
e.asIterator().remove();
}
@Test(dataProvider = "unmodifiable",
- expectedExceptions=UnsupportedOperationException.class)
+ expectedExceptions=UnsupportedOperationException.class)
public void removeThrowsAfterAdvancingI(String description,
- Supplier<Enumeration<?>> s,
- Collection<?> exp) {
+ Supplier<Enumeration<?>> s,
+ Collection<?> exp) {
Iterator<?> i = s.get().asIterator();
i.next();
i.remove();
}
-} \ No newline at end of file
+}
diff --git a/ojluni/src/test/java/util/Collections/EqualsTest.java b/ojluni/src/test/java/util/Collections/EqualsTest.java
new file mode 100644
index 00000000000..ca1fd2f1246
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EqualsTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7144488
+ * @summary Infinite recursion for some equals tests in Collections
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class EqualsTest {
+ public static void main(String[] args) {
+ boolean test;
+
+ /* synchronizedList test */
+ List list = Collections.synchronizedList(new ArrayList());
+ list.add(list);
+ test = list.equals(list);
+ assertTrue(test);
+ list.remove(list);
+
+ /* synchronizedSet test */
+ Set s = Collections.synchronizedSet(new HashSet());
+ s.add(s);
+ test = s.equals(s);
+ assertTrue(test);
+
+ /* synchronizedMap test */
+ Map m = Collections.synchronizedMap(new HashMap());
+ test = m.equals(m);
+ assertTrue(test);
+
+ }
+
+ private static void assertTrue(boolean b) {
+ if (!b)
+ throw new RuntimeException("assertion failed");
+ }
+}
+
diff --git a/ojluni/src/test/java/util/Collections/FindSubList.java b/ojluni/src/test/java/util/Collections/FindSubList.java
new file mode 100644
index 00000000000..eac53fcd47c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/FindSubList.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4323074
+ * @summary Basic test for Collections.indexOfSubList/lastIndexOfSubList
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+
+public class FindSubList {
+ public static void main(String[] args) throws Exception {
+ int N = 500;
+ List source = new ArrayList(3 * N);
+ List[] target = new List[N+1];
+ int[] index = new int[N+1];
+ for (int i=0; i<=N; i++) {
+ List t = new ArrayList();
+ String s = Integer.toString(i, 2);
+ for (int j=0, len = s.length(); j<len; j++)
+ t.add(s.charAt(j)=='1' ? "1" : "0");
+ target[i] = t;
+ if (i == N) {
+ index[i] = -1;
+ } else {
+ index[i] = source.size();
+ source.addAll(t);
+ source.add("*");
+ }
+ }
+
+ List[] src = {
+ source,
+ new LinkedList(source),
+ new Vector(source),
+ Arrays.asList(source.toArray())
+ };
+ for (int j=0; j<src.length; j++) {
+ List s = src[j];
+
+ for (int i=0; i<=N; i++) {
+ int idx = Collections.indexOfSubList(s, target[i]);
+ if (idx != index[i])
+ throw new Exception(s.getClass()+" indexOfSubList: " + i +
+ "is " + idx + ", should be "+index[i]);
+ }
+
+ if (Collections.indexOfSubList(s,Collections.nCopies(2*s.size(),
+ "0")) != -1)
+ throw new Exception(s.getClass()+" indexOfSubList: big target");
+
+ }
+
+ Collections.reverse(source);
+ int srcSize = source.size();
+ for (int i=0; i<=N; i++) {
+ Collections.reverse(target[i]);
+ if (i != N)
+ index[i] = srcSize - index[i] - target[i].size();
+ }
+ List[] src2 = {
+ source,
+ new LinkedList(source),
+ new Vector(source),
+ Arrays.asList(source.toArray())
+ };
+ for (int j=0; j<src2.length; j++) {
+ List s = src2[j];
+
+ for (int i=0; i<=N; i++) {
+ int idx = Collections.lastIndexOfSubList(s, target[i]);
+ if (idx != index[i])
+ throw new Exception(s.getClass()+" lastIdexOfSubList: "+i +
+ "is " + idx + ", should be "+index[i]);
+ }
+ if (Collections.indexOfSubList(s,Collections.nCopies(2*s.size(),
+ "0")) != -1)
+ throw new Exception(s.getClass()+" lastIndexOfSubList: big tgt");
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/Frequency.java b/ojluni/src/test/java/util/Collections/Frequency.java
new file mode 100644
index 00000000000..fbf72fa77bc
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Frequency.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4193200
+ * @summary Basic test for Collections.frequency
+ * @author Josh Bloch
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Frequency {
+ static final int N = 100;
+ public static void main(String[] args) {
+ test(new ArrayList<Integer>());
+ test(new LinkedList<Integer>());
+ }
+
+ static void test(List<Integer> list) {
+ for (int i = 0; i < N; i++)
+ for (int j = 0; j < i; j++)
+ list.add(i);
+ Collections.shuffle(list);
+
+ for (int i = 0; i < N; i++)
+ if (Collections.frequency(list, i) != i)
+ throw new RuntimeException(list.getClass() + ": " + i);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/MinMax.java b/ojluni/src/test/java/util/Collections/MinMax.java
new file mode 100644
index 00000000000..aa00345de22
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/MinMax.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4486049
+ * @summary min and max methods fail if size changes in between a call to size
+ * and an attempt to iterate.
+ * @author Josh Bloch
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public class MinMax {
+ public static void main(String[] args) {
+ Set s = new LyingSet();
+ s.add("x");
+ if (!Collections.min(s).equals("x"))
+ throw new RuntimeException("1: " + Collections.min(s));
+ if (!Collections.max(s).equals("x"))
+ throw new RuntimeException("2: " + Collections.max(s));
+
+ s.add("y");
+ if (!Collections.min(s).equals("x"))
+ throw new RuntimeException("3: " + Collections.min(s));
+ if (!Collections.max(s).equals("y"))
+ throw new RuntimeException("4: " + Collections.max(s));
+
+ s.add("w");
+ if (!Collections.min(s).equals("w"))
+ throw new RuntimeException("5: " + Collections.min(s));
+ if (!Collections.max(s).equals("y"))
+ throw new RuntimeException("6: " + Collections.max(s));
+
+ s.clear();
+ s.add("x");
+ if (!Collections.min(s, Collections.reverseOrder()).equals("x"))
+ throw new RuntimeException("1a: " + Collections.min(s));
+ if (!Collections.max(s, Collections.reverseOrder()).equals("x"))
+ throw new RuntimeException("2a: " + Collections.max(s));
+
+ s.add("y");
+ if (!Collections.min(s, Collections.reverseOrder()).equals("y"))
+ throw new RuntimeException("3a: " + Collections.min(s));
+ if (!Collections.max(s, Collections.reverseOrder()).equals("x"))
+ throw new RuntimeException("4a: " + Collections.max(s));
+
+ s.add("w");
+ if (!Collections.min(s, Collections.reverseOrder()).equals("y"))
+ throw new RuntimeException("5a: " + Collections.min(s));
+ if (!Collections.max(s, Collections.reverseOrder()).equals("w"))
+ throw new RuntimeException("6a: " + Collections.max(s));
+ }
+}
+
+class LyingSet extends LinkedHashSet {
+ public int size() {
+ return super.size() + 1; // Lies, lies, all lies!
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/NullComparator.java b/ojluni/src/test/java/util/Collections/NullComparator.java
new file mode 100644
index 00000000000..c1d29bbbfe0
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/NullComparator.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4224271
+ * @summary A null Comparator is now specified to indicate natural ordering.
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class NullComparator {
+ public static void main(String[] args) throws Exception {
+ List list = new ArrayList(100);
+ for (int i=0; i<100; i++)
+ list.add(new Integer(i));
+ List sorted = new ArrayList(list);
+ Collections.shuffle(list);
+
+ Object[] a = list.toArray();
+ Arrays.sort(a, null);
+ if (!Arrays.asList(a).equals(sorted))
+ throw new Exception("Arrays.sort");
+ a = list.toArray();
+ Arrays.sort(a, 0, 100, null);
+ if (!Arrays.asList(a).equals(sorted))
+ throw new Exception("Arrays.sort(from, to)");
+ if (Arrays.binarySearch(a, new Integer(69)) != 69)
+ throw new Exception("Arrays.binarySearch");
+
+ List tmp = new ArrayList(list);
+ Collections.sort(tmp, null);
+ if (!tmp.equals(sorted))
+ throw new Exception("Collections.sort");
+ if (Collections.binarySearch(tmp, new Integer(69)) != 69)
+ throw new Exception("Collections.binarySearch");
+ if (!Collections.min(list, null).equals(new Integer(0)))
+ throw new Exception("Collections.min");
+ if (!Collections.max(list, null).equals(new Integer(99)))
+ throw new Exception("Collections.max");
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/RacingCollections.java b/ojluni/src/test/java/util/Collections/RacingCollections.java
new file mode 100644
index 00000000000..0b39842b3bb
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/RacingCollections.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6360946 6360948
+ * @summary Test various operations on concurrently mutating collections
+ * @author Martin Buchholz
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+
+import static java.util.Collections.asLifoQueue;
+import static java.util.Collections.checkedList;
+import static java.util.Collections.checkedMap;
+import static java.util.Collections.checkedSet;
+import static java.util.Collections.newSetFromMap;
+import static java.util.Collections.synchronizedList;
+import static java.util.Collections.synchronizedMap;
+import static java.util.Collections.synchronizedSet;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableMap;
+import static java.util.Collections.unmodifiableSet;
+
+public class RacingCollections {
+ /**
+ * How long to run each "race" (in milliseconds).
+ * Turn this up to some higher value like 1000 for stress testing:
+ * java -Dmillis=1000 RacingCollections
+ */
+ static final long defaultWorkTimeMillis = Long.getLong("millis", 10L);
+
+ /**
+ * Whether to print debug information.
+ */
+ static final boolean debug = Boolean.getBoolean("debug");
+
+ static final Integer one = 1;
+ static final Integer two = 2;
+
+ /**
+ * A thread that mutates an object forever, alternating between
+ * being empty and containing singleton "two"
+ */
+ static class Frobber extends CheckedThread {
+ volatile boolean done = false;
+ boolean keepGoing(int i) { return (i % 128 != 0) || ! done; }
+
+ final Object elLoco;
+ Frobber(Object elLoco) {
+ this.elLoco = elLoco;
+ this.start();
+ }
+
+ @SuppressWarnings("unchecked")
+ void clear(Object o) {
+ if (o instanceof Collection)
+ ((Collection<?>)o).clear();
+ else
+ ((Map<?,?>)o).clear();
+ }
+
+ @SuppressWarnings("unchecked")
+ void realRun() {
+ // Mutate elLoco wildly forever, checking occasionally for "done"
+ clear(elLoco);
+ if (elLoco instanceof List) {
+ List<Integer> l = (List<Integer>) elLoco;
+ for (int i = 0; keepGoing(i); i++) {
+ switch (i%2) {
+ case 0: l.add(two); break;
+ case 1: l.add(0, two); break;
+ }
+ switch (i%2) {
+ case 0: l.remove(two); break;
+ case 1: l.remove(0); break;
+ }}}
+ else if (elLoco instanceof Deque) {
+ Deque<Integer> q = (Deque<Integer>) elLoco;
+ for (int i = 0; keepGoing(i); i++) {
+ switch (i%6) {
+ case 0: q.add(two); break;
+ case 1: q.addFirst(two); break;
+ case 2: q.addLast(two); break;
+ case 3: q.offer(two); break;
+ case 4: q.offerFirst(two); break;
+ case 5: q.offerLast(two); break;
+ }
+ switch (i%6) {
+ case 0: q.remove(two); break;
+ case 1: q.removeFirst(); break;
+ case 2: q.removeLast(); break;
+ case 3: q.poll(); break;
+ case 4: q.pollFirst(); break;
+ case 5: q.pollLast(); break;
+ }}}
+ else if (elLoco instanceof Queue) {
+ Queue<Integer> q = (Queue<Integer>) elLoco;
+ for (int i = 0; keepGoing(i); i++) {
+ switch (i%2) {
+ case 0: q.add(two); break;
+ case 1: q.offer(two); break;
+ }
+ switch (i%2) {
+ case 0: q.remove(two); break;
+ case 1: q.poll(); break;
+ }}}
+ else if (elLoco instanceof Map) {
+ Map<Integer, Boolean> m = (Map<Integer, Boolean>) elLoco;
+ for (int i = 0; keepGoing(i); i++) {
+ m.put(two, true);
+ m.remove(two);
+ }}
+ else if (elLoco instanceof Collection) {
+ Collection<Integer> c = (Collection<Integer>) elLoco;
+ for (int i = 0; keepGoing(i); i++) {
+ c.add(two);
+ c.remove(two);
+ }}
+ else { throw new Error("Huh? " + elLoco); }
+ }
+
+ void enoughAlready() {
+ done = true;
+ try { join(); } catch (Throwable t) { unexpected(t); }
+ }
+ }
+
+ private static void checkEqualSanity(Object theRock, Object elLoco) {
+ //equal(theRock, theRock);
+ equal(elLoco, elLoco);
+
+ // It would be nice someday to have theRock and elLoco never "equal",
+ // although the meaning of "equal" for mutating collections
+ // is a bit fuzzy. Uncomment when/if we fix:
+ // 6374942: Improve thread safety of collection .equals() methods
+ //notEqual(theRock, elLoco);
+ //notEqual(elLoco, theRock);
+
+ notEqual(theRock.toString(), elLoco.toString());
+ }
+
+ static class Looper {
+ final long quittingTime;
+ int i = 0;
+ Looper() { this(defaultWorkTimeMillis); }
+ Looper(long workTimeMillis) {
+ quittingTime = System.nanoTime() + workTimeMillis * 1024 * 1024;
+ }
+ boolean keepGoing() {
+ return (i++ % 128 != 0) || (System.nanoTime() - quittingTime < 0);
+ }
+ }
+
+ private static void frob(Object theRock, Object elLoco) {
+ Frobber frobber = new Frobber(elLoco);
+ try {
+ if (theRock instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<Integer> c = (Collection<Integer>) theRock;
+ if (! c.contains(one))
+ c.add(one);
+ } else {
+ @SuppressWarnings("unchecked")
+ Map<Integer, Boolean> m = (Map<Integer, Boolean>) theRock;
+ if (! m.containsKey(one))
+ m.put(one, true);
+ }
+ for (Looper looper = new Looper(); looper.keepGoing(); )
+ checkEqualSanity(theRock, elLoco);
+ }
+ catch (Throwable t) { unexpected(t); }
+ finally { frobber.enoughAlready(); }
+ }
+
+ private static List<Map<Integer, Boolean>> newConcurrentMaps() {
+ List<Map<Integer, Boolean>> list = new ArrayList<>();
+ list.add(new ConcurrentHashMap<Integer, Boolean>());
+ list.add(new ConcurrentSkipListMap<Integer, Boolean>());
+ return list;
+ }
+
+ private static List<Map<Integer, Boolean>> maps() {
+ List<Map<Integer, Boolean>> list = newConcurrentMaps();
+ list.add(new Hashtable<Integer, Boolean>());
+ list.add(new HashMap<Integer, Boolean>());
+ list.add(new TreeMap<Integer, Boolean>());
+ Comparator<Integer> cmp = new Comparator<>() {
+ public int compare(Integer x, Integer y) {
+ return x - y;
+ }};
+ list.add(new TreeMap<Integer, Boolean>(Collections.reverseOrder(cmp)));
+ return list;
+ }
+
+ private static List<Set<Integer>> newConcurrentSets() {
+ List<Set<Integer>> list = new ArrayList<>();
+ list.add(new ConcurrentSkipListSet<Integer>());
+ list.add(new CopyOnWriteArraySet<Integer>());
+ return list;
+ }
+
+ private static List<Set<Integer>> newSets() {
+ List<Set<Integer>> list = newConcurrentSets();
+ list.add(new HashSet<Integer>());
+ list.add(new TreeSet<Integer>());
+ list.add(new TreeSet<Integer>(Collections.reverseOrder()));
+ return list;
+ }
+
+ private static List<List<Integer>> newConcurrentLists() {
+ List<List<Integer>> list = new ArrayList<>();
+ list.add(new CopyOnWriteArrayList<Integer>());
+ return list;
+ }
+
+ private static List<List<Integer>> newLists() {
+ List<List<Integer>> list = newConcurrentLists();
+ list.add(new Vector<Integer>());
+ list.add(new ArrayList<Integer>());
+ return list;
+ }
+
+ private static List<Queue<Integer>> newConcurrentQueues() {
+ List<Queue<Integer>> list = new ArrayList<>(newConcurrentDeques());
+ list.add(new ArrayBlockingQueue<Integer>(10));
+ list.add(new LinkedBlockingQueue<Integer>(10));
+ list.add(new LinkedTransferQueue<Integer>());
+ list.add(new ConcurrentLinkedQueue<Integer>());
+ return list;
+ }
+
+ private static List<Queue<Integer>> newQueues() {
+ List<Queue<Integer>> list = new ArrayList<>(newDeques());
+ list.add(new LinkedBlockingQueue<Integer>(10));
+ return list;
+ }
+
+ private static List<Deque<Integer>> newConcurrentDeques() {
+ List<Deque<Integer>> list = new ArrayList<>();
+ list.add(new LinkedBlockingDeque<Integer>(10));
+ list.add(new ConcurrentLinkedDeque<Integer>());
+ return list;
+ }
+
+ private static List<Deque<Integer>> newDeques() {
+ List<Deque<Integer>> list = newConcurrentDeques();
+ list.add(new ArrayDeque<Integer>());
+ list.add(new LinkedList<Integer>());
+ return list;
+ }
+
+ private static void describe(Class<?> k, Object x, Object y) {
+ if (debug)
+ System.out.printf("%s: %s, %s%n", k.getSimpleName(),
+ x.getClass().getSimpleName(),
+ y.getClass().getSimpleName());
+ }
+
+ private static void realMain(String[] args) {
+ for (Map<Integer, Boolean> x : maps())
+ for (Map<Integer, Boolean> y : newConcurrentMaps()) {
+ describe(Map.class, x, y);
+ x.put(one, true);
+ frob(x, y);
+ frob(unmodifiableMap(x), y);
+ frob(synchronizedMap(x), y);
+ frob(x, synchronizedMap(y));
+ frob(checkedMap(x, Integer.class, Boolean.class), y);
+ frob(x, checkedMap(y, Integer.class, Boolean.class));
+ x.clear();
+ frob(newSetFromMap(x), newSetFromMap(y));
+ frob(x.keySet(), newSetFromMap(y));
+ }
+
+ for (Set<Integer> x : newSets())
+ for (Set<Integer> y : newConcurrentSets()) {
+ describe(Set.class, x, y);
+ frob(x, y);
+ frob(unmodifiableSet(x), y);
+ frob(synchronizedSet(x), y);
+ frob(x, synchronizedSet(y));
+ frob(checkedSet(x, Integer.class), y);
+ frob(x, checkedSet(y, Integer.class));
+ }
+
+ for (List<Integer> x : newLists())
+ for (List<Integer> y : newConcurrentLists()) {
+ describe(List.class, x, y);
+ frob(x, y);
+ frob(unmodifiableList(x), y);
+ frob(synchronizedList(x), y);
+ frob(x, synchronizedList(y));
+ frob(checkedList(x, Integer.class), y);
+ frob(x, checkedList(y, Integer.class));
+ }
+
+ for (Queue<Integer> x : newQueues())
+ for (Queue<Integer> y : newConcurrentQueues()) {
+ describe(Queue.class, x, y);
+ frob(x, y);
+ }
+
+ for (Deque<Integer> x : newDeques())
+ for (Deque<Integer> y : newConcurrentDeques()) {
+ describe(Deque.class, x, y);
+ frob(asLifoQueue(x), y);
+ frob(x, asLifoQueue(y));
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static String toString(Object x) {
+ return ((x instanceof Collection) || (x instanceof Map)) ?
+ x.getClass().getName() : x.toString();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(toString(x) + " not equal to " + toString(y));}
+ static void notEqual(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y))
+ fail(toString(x) + " equal to " + toString(y));
+ else pass();}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ private abstract static class CheckedThread extends Thread {
+ abstract void realRun() throws Throwable;
+ public void run() {
+ try { realRun(); } catch (Throwable t) { unexpected(t); }}}
+}
diff --git a/ojluni/src/test/java/util/Collections/ReplaceAll.java b/ojluni/src/test/java/util/Collections/ReplaceAll.java
new file mode 100644
index 00000000000..75ab1917be9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ReplaceAll.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4323074
+ * @summary Basic test for new replaceAll algorithm
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+
+public class ReplaceAll {
+ static final int SIZE = 20;
+
+ public static void main(String[] args) throws Exception {
+ List[] a = {new ArrayList(), new LinkedList(), new Vector()};
+
+ for (int i=0; i<a.length; i++) {
+ List lst = a[i];
+ for (int j=1; j<=SIZE; j++)
+ lst.add(new Integer(j % 3));
+ List goal = Collections.nCopies(SIZE, "*");
+
+ for (int j=0; j<3; j++) {
+ List before = new ArrayList(lst);
+ if (!Collections.replaceAll(lst, new Integer(j), "*"))
+ throw new Exception("False return value: "+i+", "+j);
+ if (lst.equals(before))
+ throw new Exception("Unchanged: "+i+", "+j+", "+": "+lst);
+ if (lst.equals(goal) != (j==2))
+ throw new Exception("Wrong change:"+i+", "+j);
+ }
+ if (Collections.replaceAll(lst, "love", "hate"))
+ throw new Exception("True return value: "+i);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/ReverseOrder.java b/ojluni/src/test/java/util/Collections/ReverseOrder.java
new file mode 100644
index 00000000000..c43abd13700
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ReverseOrder.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4593209 8001667
+ * @summary Reverse comparator was subtly broken
+ * @author Josh Bloch
+ */
+
+package test.java.util.Collections;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class ReverseOrder {
+ static byte[] serialBytes(Object o) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(o);
+ oos.flush();
+ oos.close();
+ return bos.toByteArray();
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> T serialClone(T o) {
+ try {
+ ObjectInputStream ois = new ObjectInputStream
+ (new ByteArrayInputStream(serialBytes(o)));
+ T clone = (T) ois.readObject();
+ return clone;
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Foo[] a = { new Foo(2), new Foo(3), new Foo(1) };
+ List list = Arrays.asList(a);
+ Comparator cmp = Collections.reverseOrder();
+ Collections.sort(list, cmp);
+
+ Foo[] golden = { new Foo(3), new Foo(2), new Foo(1) };
+ List goldenList = Arrays.asList(golden);
+ if (!list.equals(goldenList))
+ throw new Exception(list.toString());
+
+ Comparator clone = serialClone(cmp);
+ List list2 = Arrays.asList(a);
+ Collections.sort(list2, clone);
+ if (!list2.equals(goldenList))
+ throw new Exception(list.toString());
+ }
+}
+
+class Foo implements Comparable {
+ int val;
+ Foo(int i) { val = i; }
+
+ public int compareTo(Object o) {
+ Foo f = (Foo)o;
+ return (val < f.val ? Integer.MIN_VALUE : (val == f.val ? 0 : 1));
+ }
+
+ public boolean equals(Object o) {
+ return o instanceof Foo && ((Foo)o).val == val;
+ }
+
+ public int hashCode() { return val; }
+
+ public String toString() { return Integer.toString(val); }
+}
diff --git a/ojluni/src/test/java/util/Collections/ReverseOrder2.java b/ojluni/src/test/java/util/Collections/ReverseOrder2.java
new file mode 100644
index 00000000000..ddfdb0018a2
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ReverseOrder2.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4809442 6366832 4974878 6372554 4890211 6483125
+ * @summary Basic test for Collections.reverseOrder
+ * @author Josh Bloch, Martin Buchholz
+ */
+
+package test.java.util.Collections;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ReverseOrder2 {
+ static final int N = 100;
+
+ static void realMain(String[] args) throws Throwable {
+ check(Collections.reverseOrder()
+ == Collections.reverseOrder(null));
+
+ check(Collections.reverseOrder()
+ == reincarnate(Collections.reverseOrder()));
+
+ check(Collections.reverseOrder(Collections.reverseOrder(cmp))
+ == cmp);
+
+ equal(Collections.reverseOrder(cmp),
+ Collections.reverseOrder(cmp));
+
+ equal(Collections.reverseOrder(cmp).hashCode(),
+ Collections.reverseOrder(cmp).hashCode());
+
+ check(Collections.reverseOrder(cmp).hashCode() !=
+ cmp.hashCode());
+
+ test(new ArrayList<String>());
+ test(new LinkedList<String>());
+ test2(new ArrayList<Integer>());
+ test2(new LinkedList<Integer>());
+ }
+
+ static void test(List<String> list) {
+ for (int i = 0; i < N; i++)
+ list.add(String.valueOf(i));
+ Collections.shuffle(list);
+ Collections.sort(list, Collections.reverseOrder(cmp));
+ equal(list, golden);
+ }
+
+ private static Comparator<String> cmp = new Comparator<>() {
+ public int compare(String s1, String s2) {
+ int i1 = Integer.parseInt(s1);
+ int i2 = Integer.parseInt(s2);
+ return (i1 < i2 ? Integer.MIN_VALUE : (i1 == i2 ? 0 : 1));
+ }
+ };
+
+ private static final List<String> golden = new ArrayList<>(N);
+ static {
+ for (int i = N-1; i >= 0; i--)
+ golden.add(String.valueOf(i));
+ }
+
+ static void test2(List<Integer> list) {
+ for (int i = 0; i < N; i++)
+ list.add(i);
+ Collections.shuffle(list);
+ Collections.sort(list, Collections.reverseOrder(null));
+ equal(list, golden2);
+ }
+
+ private static final List<Integer> golden2 = new ArrayList<>(N);
+ static {
+ for (int i = N-1; i >= 0; i--)
+ golden2.add(i);
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ static byte[] serializedForm(Object obj) {
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ new ObjectOutputStream(baos).writeObject(obj);
+ return baos.toByteArray();
+ } catch (IOException e) {throw new RuntimeException(e);}}
+ static Object readObject(byte[] bytes)
+ throws IOException, ClassNotFoundException {
+ InputStream is = new ByteArrayInputStream(bytes);
+ return new ObjectInputStream(is).readObject();}
+ @SuppressWarnings("unchecked")
+ static <T> T reincarnate(T obj) {
+ try {return (T) readObject(serializedForm(obj));}
+ catch (Exception e) {throw new RuntimeException(e);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/Rotate.java b/ojluni/src/test/java/util/Collections/Rotate.java
new file mode 100644
index 00000000000..77b2d45f0c2
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Rotate.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4323074
+ * @summary Basic test for new rotate algorithm
+ * @key randomness
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+public class Rotate {
+ // Should have lots of distinct factors and be > ROTATE_THRESHOLD
+ static final int SIZE = 120;
+
+ static Random rnd = new Random();
+
+ public static void main(String[] args) throws Exception {
+ List[] a = {new ArrayList(), new LinkedList(), new Vector()};
+
+ for (int i=0; i<a.length; i++) {
+ List lst = a[i];
+ for (int j=0; j<SIZE; j++)
+ lst.add(new Integer(j));
+ int totalDist = 0;
+
+ for (int j=0; j<10000; j++) {
+ int dist = rnd.nextInt(200) - 100;
+ Collections.rotate(lst, dist);
+
+ // Check that things are as they should be
+ totalDist = (totalDist + dist) % SIZE;
+ if (totalDist < 0)
+ totalDist += SIZE;
+ int index =0;
+ for (int k=totalDist; k<SIZE; k++, index++)
+ if (((Integer)lst.get(k)).intValue() != index)
+ throw new Exception("j: "+j+", lst["+k+"]="+lst.get(k)+
+ ", should be "+index);
+ for (int k=0; k<totalDist; k++, index++)
+ if (((Integer)lst.get(k)).intValue() != index)
+ throw new Exception("j: "+j+", lst["+k+"]="+lst.get(k)+
+ ", should be "+index);
+ }
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/RotateEmpty.java b/ojluni/src/test/java/util/Collections/RotateEmpty.java
new file mode 100644
index 00000000000..eaf671946db
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/RotateEmpty.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4389747
+ * @summary Collections.rotate(...) returns ArithmeticException
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class RotateEmpty {
+
+ public static void main(String[] args) throws Exception {
+ List l = new ArrayList();
+ Collections.rotate(l, 1);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/Ser.java b/ojluni/src/test/java/util/Collections/Ser.java
new file mode 100644
index 00000000000..5ee8b0eb8ad
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Ser.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4190323
+ * @summary EMPTY_SET, EMPTY_LIST, and the collections returned by
+ * nCopies and singleton were spec'd to be serializable, but weren't.
+ */
+
+package test.java.util.Collections;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class Ser {
+ public static void main(String[] args) throws Exception {
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(Collections.EMPTY_SET);
+ out.flush();
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray()));
+
+ if (!Collections.EMPTY_SET.equals(in.readObject()))
+ throw new RuntimeException("empty set Ser/Deser failure.");
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to serialize empty set:" + e);
+ }
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(Collections.EMPTY_LIST);
+ out.flush();
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray()));
+
+ if (!Collections.EMPTY_LIST.equals(in.readObject()))
+ throw new RuntimeException("empty list Ser/Deser failure.");
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to serialize empty list:" + e);
+ }
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ Set gumby = Collections.singleton("gumby");
+ out.writeObject(gumby);
+ out.flush();
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray()));
+
+ if (!gumby.equals(in.readObject()))
+ throw new RuntimeException("Singleton Ser/Deser failure.");
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to serialize singleton:" + e);
+ }
+
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ List gumbies = Collections.nCopies(50, "gumby");
+ out.writeObject(gumbies);
+ out.flush();
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray()));
+
+ if (!gumbies.equals(in.readObject()))
+ throw new RuntimeException("nCopies Ser/Deser failure.");
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to serialize nCopies:" + e);
+ }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/SetFromMap.java b/ojluni/src/test/java/util/Collections/SetFromMap.java
new file mode 100644
index 00000000000..651944b9508
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/SetFromMap.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6301089
+ * @summary test Collections.newSetFromMap
+ * @author Martin Buchholz
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class SetFromMap {
+ static volatile int passed = 0, failed = 0;
+ static void pass() { passed++; }
+ static void fail() { failed++; Thread.dumpStack(); }
+ static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
+ static void check(boolean cond) { if (cond) pass(); else fail(); }
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else {System.out.println(x + " not equal to " + y); fail(); }}
+
+ public static void main(String[] args) throws Throwable {
+ try { realMain(); } catch (Throwable t) { unexpected(t); }
+
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new Exception("Some tests failed");
+ }
+
+ private static void realMain() throws Throwable {
+ try {
+ Map<String,Boolean> m = new IdentityHashMap<>();
+ Set<String> s = Collections.newSetFromMap(m);
+ String foo1 = new String("foo");
+ String foo2 = new String("foo");
+ String bar = new String("bar");
+ check(s.add(foo1));
+ check(s.add(foo2));
+ check(s.add(bar));
+ equal(s.size(), 3);
+ check(s.contains(foo1));
+ check(s.contains(foo2));
+ check(! s.contains(new String(foo1)));
+ } catch (Throwable t) { unexpected(t); }
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/SingletonIterator.java b/ojluni/src/test/java/util/Collections/SingletonIterator.java
new file mode 100644
index 00000000000..c38909cb64a
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/SingletonIterator.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024500 8166446
+ * @run testng SingletonIterator
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+@Test(groups = "unit")
+public class SingletonIterator {
+ static void assertIteratorExhausted(Iterator<?> it) {
+ assertFalse(it.hasNext());
+ try {
+ it.next();
+ fail("should have thrown NoSuchElementException");
+ } catch (NoSuchElementException success) { }
+ it.forEachRemaining(e -> { throw new AssertionError("action called incorrectly"); });
+ }
+
+ public void testForEachRemaining() {
+ Iterator<String> it = Collections.singleton("TheOne").iterator();
+ AtomicInteger cnt = new AtomicInteger(0);
+
+ it.forEachRemaining(s -> {
+ assertEquals("TheOne", s);
+ cnt.incrementAndGet();
+ });
+
+ assertEquals(cnt.get(), 1);
+ assertIteratorExhausted(it);
+ }
+
+ static class SingletonException extends RuntimeException { }
+
+ public void testThrowFromForEachRemaining() {
+ Iterator<String> it = Collections.singleton("TheOne").iterator();
+
+ try {
+ it.forEachRemaining(s -> { throw new SingletonException(); });
+ } catch (SingletonException ignore) { }
+
+ assertIteratorExhausted(it);
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/Swap.java b/ojluni/src/test/java/util/Collections/Swap.java
new file mode 100644
index 00000000000..3beec42b800
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Swap.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4323074
+ * @summary Basic test for newly public swap algorithm
+ * @author Josh Bloch
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class Swap {
+ static final int SIZE = 100;
+
+ public static void main(String[] args) throws Exception {
+ List l = new ArrayList(Collections.nCopies(100, Boolean.FALSE));
+ l.set(0, Boolean.TRUE);
+ for (int i=0; i < SIZE-1; i++)
+ Collections.swap(l, i, i+1);
+
+ List l2 = new ArrayList(Collections.nCopies(100, Boolean.FALSE));
+ l2.set(SIZE-1, Boolean.TRUE);
+ if (!l.equals(l2))
+ throw new RuntimeException("Wrong result");
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/SyncSubMutexes.java b/ojluni/src/test/java/util/Collections/SyncSubMutexes.java
new file mode 100644
index 00000000000..2fcd3d65c7a
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/SyncSubMutexes.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.util.Collections;
+
+/**
+ * @test
+ * @bug 8048209
+ * @summary Check that Collections.synchronizedNavigableSet().tailSet() is using
+ * the same lock object as it's source.
+ * @modules java.base/java.util:open
+ * @run testng SyncSubMutexes
+ */
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.Set;
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertSame;
+
+public class SyncSubMutexes {
+
+ @Test(dataProvider = "Collections")
+ public void testCollections(Collection<String> instance) {
+ // nothing to test, no subset methods
+ }
+
+ @Test(dataProvider = "Lists")
+ public void testLists(List<String> instance) {
+ assertSame(getSyncCollectionMutex(instance.subList(0, 1)), getSyncCollectionMutex(instance));
+ }
+
+ @Test(dataProvider = "Sets")
+ public void testSets(Set<String> instance) {
+ // nothing to test, no subset methods
+
+ }
+
+ @Test(dataProvider = "SortedSets")
+ public void testSortedSets(SortedSet<String> instance) {
+ assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
+
+ }
+
+ @Test(dataProvider = "NavigableSets")
+ public void testNavigableSets(NavigableSet<String> instance) {
+ assertSame(getSyncCollectionMutex(instance.descendingSet()), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.headSet("Echo", true)), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.tailSet("Charlie", true)), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.subSet("Charlie", true, "Echo", true)), getSyncCollectionMutex(instance));
+ }
+
+ @Test(dataProvider = "Maps")
+ public void testMaps(Map<String, String> instance) {
+ assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
+ }
+
+ @Test(dataProvider = "SortedMaps")
+ public void testSortedMaps(SortedMap<String, String> instance) {
+ assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.subMap("Charlie", "Echo")), getSyncMapMutex(instance));
+ }
+
+ @Test(dataProvider = "NavigableMaps")
+ public void testNavigableMaps(NavigableMap<String, String> instance) {
+ assertSame(getSyncMapMutex(instance.descendingMap()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.descendingKeySet()), getSyncMapMutex(instance));
+ assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.headMap("Echo", true)), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.tailMap("Charlie", true)), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
+ assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
+ }
+
+ @DataProvider(name = "Collections", parallel = true)
+ public static Iterator<Object[]> collectionProvider() {
+ return makeCollections().iterator();
+ }
+
+ @DataProvider(name = "Lists", parallel = true)
+ public static Iterator<Object[]> listProvider() {
+ return makeLists().iterator();
+ }
+
+ @DataProvider(name = "Sets", parallel = true)
+ public static Iterator<Object[]> setProvider() {
+ return makeSets().iterator();
+ }
+
+ @DataProvider(name = "SortedSets", parallel = true)
+ public static Iterator<Object[]> sortedsetProvider() {
+ return makeSortedSets().iterator();
+ }
+
+ @DataProvider(name = "NavigableSets", parallel = true)
+ public static Iterator<Object[]> navigablesetProvider() {
+ return makeNavigableSets().iterator();
+ }
+
+ @DataProvider(name = "Maps", parallel = true)
+ public static Iterator<Object[]> mapProvider() {
+ return makeMaps().iterator();
+ }
+
+ @DataProvider(name = "SortedMaps", parallel = true)
+ public static Iterator<Object[]> sortedmapProvider() {
+ return makeSortedMaps().iterator();
+ }
+
+ @DataProvider(name = "NavigableMaps", parallel = true)
+ public static Iterator<Object[]> navigablemapProvider() {
+ return makeNavigableMaps().iterator();
+ }
+
+ private static final Collection<String> BASE_COLLECTION = Collections.unmodifiableCollection(
+ Arrays.asList("Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf")
+ );
+ private static final Map<String, String> BASE_MAP;
+
+ static {
+ Map<String, String> map = new HashMap<>();
+ for(String each : BASE_COLLECTION) {
+ map.put(each, "*" + each + "*");
+ }
+ BASE_MAP = Collections.unmodifiableMap(map);
+ }
+
+ public static Collection<Object[]> makeCollections() {
+ Collection<Object[]> instances = new ArrayList<>();
+ instances.add(new Object[] {Collections.synchronizedCollection(new ArrayList<>(BASE_COLLECTION))});
+ instances.addAll(makeLists());
+
+ return instances;
+ }
+
+ public static Collection<Object[]> makeLists() {
+ Collection<Object[]> instances = new ArrayList<>();
+ instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION))});
+ instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION)).subList(1, 2)});
+
+ return instances;
+ }
+
+ public static Collection<Object[]> makeSets() {
+ Collection<Object[]> instances = new ArrayList<>();
+
+ instances.add(new Object[] {Collections.synchronizedSet(new TreeSet<>(BASE_COLLECTION))});
+ instances.addAll(makeSortedSets());
+ return instances;
+ }
+
+ public static Collection<Object[]> makeSortedSets() {
+ Collection<Object[]> instances = new ArrayList<>();
+ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION))});
+ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
+ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
+ instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
+ instances.addAll(makeNavigableSets());
+
+ return instances;
+ }
+
+ public static Collection<Object[]> makeNavigableSets() {
+ Collection<Object[]> instances = new ArrayList<>();
+
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION))});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).descendingSet().descendingSet()});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot", true)});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo", true)});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
+ instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", true, "Foxtrot", true)});
+
+ return instances;
+ }
+
+ public static Collection<Object[]> makeMaps() {
+ Collection<Object[]> instances = new ArrayList<>();
+
+ instances.add(new Object[] {Collections.synchronizedMap(new HashMap<>(BASE_MAP))});
+ instances.addAll(makeSortedMaps());
+
+ return instances;
+ }
+
+ public static Collection<Object[]> makeSortedMaps() {
+ Collection<Object[]> instances = new ArrayList<>();
+
+ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP))});
+ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
+ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
+ instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
+ instances.addAll(makeNavigableMaps());
+
+ return instances;
+ }
+
+ public static Collection<Object[]> makeNavigableMaps() {
+ Collection<Object[]> instances = new ArrayList<>();
+
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP))});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP).descendingMap().descendingMap())});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot", true)});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo", true)});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
+ instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", true, "Foxtrot", true)});
+
+ return instances;
+ }
+
+ private static Object getSyncCollectionMutex(Collection<?> from) {
+ try {
+ Class<?> synchronizedCollectionClazz = Class.forName("java.util.Collections$SynchronizedCollection");
+ Field f = synchronizedCollectionClazz.getDeclaredField("mutex");
+ f.setAccessible(true);
+ return f.get(from);
+ } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException("Unable to get mutex field.", e);
+ }
+ }
+
+ private static Object getSyncMapMutex(Map<?,?> from) {
+ try {
+ Class<?> synchronizedMapClazz = Class.forName("java.util.Collections$SynchronizedMap");
+ Field f = synchronizedMapClazz.getDeclaredField("mutex");
+ f.setAccessible(true);
+ return f.get(from);
+ } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException("Unable to get mutex field.", e);
+ }
+ }
+
+}
diff --git a/ojluni/src/test/java/util/Collections/T6433170.java b/ojluni/src/test/java/util/Collections/T6433170.java
new file mode 100644
index 00000000000..df54c8b32b3
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/T6433170.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6433170
+ * @summary CheckedCollection.addAll should be all-or-nothing
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Vector;
+
+import static java.util.Collections.checkedCollection;
+import static java.util.Collections.checkedList;
+import static java.util.Collections.checkedSet;
+
+@SuppressWarnings("unchecked")
+public class T6433170 {
+ private void checkEmpty(Collection x) {
+ check(x.isEmpty());
+ check(x.size() == 0);
+ check(x.toArray().length == 0);
+ }
+
+ void test(String[] args) throws Throwable {
+ test(checkedList(
+ checkedList(new ArrayList(), String.class),
+ Object.class));
+ test(checkedSet(
+ checkedSet(new HashSet(), String.class),
+ Object.class));
+ test(checkedCollection(
+ checkedCollection(new Vector(), String.class),
+ Object.class));
+ }
+
+ void test(final Collection checked) {
+ checkEmpty(checked);
+ final List mixedList = Arrays.asList("1", 2, "3");
+ THROWS(ClassCastException.class,
+ new F(){void f(){ checked.addAll(mixedList); }});
+ checkEmpty(checked);
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new T6433170().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ abstract class F {abstract void f() throws Throwable;}
+ void THROWS(Class<? extends Throwable> k, F... fs) {
+ for (F f : fs)
+ try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java b/ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java
new file mode 100644
index 00000000000..36940a118e9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @run testng UnmodifiableMapEntrySet
+ * @summary Unit tests for wrapping classes should delegate to default methods
+ */
+
+package test.java.util.Collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.TreeMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+import static org.testng.Assert.assertEquals;
+
+@Test(groups = "unit")
+public class UnmodifiableMapEntrySet {
+ static Object[][] collections;
+
+ static <M extends Map<Integer, Integer>> M fillMap(int size, M m) {
+ for (int i = 0; i < size; i++) {
+ m.put(i, i);
+ }
+ return m;
+ }
+
+ @DataProvider(name="maps")
+ static Object[][] mapCases() {
+ if (collections != null) {
+ return collections;
+ }
+
+ List<Object[]> cases = new ArrayList<>();
+ for (int size : new int[] {1, 2, 16}) {
+ cases.add(new Object[] {
+ String.format("new HashMap(%d)", size),
+ (Supplier<Map<Integer, Integer>>)
+ () -> Collections.unmodifiableMap(fillMap(size, new HashMap<>())) });
+ cases.add(new Object[] {
+ String.format("new TreeMap(%d)", size),
+ (Supplier<Map<Integer, Integer>>)
+ () -> Collections.unmodifiableSortedMap(fillMap(size, new TreeMap<>())) });
+ }
+
+ return cases.toArray(new Object[0][]);
+ }
+
+ static class EntryConsumer implements Consumer<Map.Entry<Integer, Integer>> {
+ int updates;
+ @Override
+ public void accept(Map.Entry<Integer, Integer> me) {
+ try {
+ me.setValue(Integer.MAX_VALUE);
+ updates++;
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ void assertNoUpdates() {
+ assertEquals(updates, 0, "Updates to entries");
+ }
+ }
+
+ void testWithEntryConsumer(Consumer<EntryConsumer> c) {
+ EntryConsumer ec = new EntryConsumer();
+ c.accept(ec);
+ ec.assertNoUpdates();
+ }
+
+ @Test(dataProvider = "maps")
+ public void testForEach(String d, Supplier<Map<Integer, Integer>> ms) {
+ testWithEntryConsumer(
+ ec -> ms.get().entrySet().forEach(ec));
+ }
+
+ @Test(dataProvider = "maps")
+ public void testIteratorForEachRemaining(String d, Supplier<Map<Integer, Integer>> ms) {
+ testWithEntryConsumer(
+ ec -> ms.get().entrySet().iterator().forEachRemaining(ec));
+ }
+
+ @Test(dataProvider = "maps")
+ public void testIteratorNext(String d, Supplier<Map<Integer, Integer>> ms) {
+ testWithEntryConsumer(ec -> {
+ for (Map.Entry<Integer, Integer> me : ms.get().entrySet()) {
+ ec.accept(me);
+ }
+ });
+ }
+
+ @Test(dataProvider = "maps")
+ public void testSpliteratorForEachRemaining(String d, Supplier<Map<Integer, Integer>> ms) {
+ testSpliterator(
+ ms.get().entrySet()::spliterator,
+ // Higher order function returning a consumer that
+ // traverses all spliterator elements using an EntryConsumer
+ s -> ec -> s.forEachRemaining(ec));
+ }
+
+ @Test(dataProvider = "maps")
+ public void testSpliteratorTryAdvance(String d, Supplier<Map<Integer, Integer>> ms) {
+ testSpliterator(
+ ms.get().entrySet()::spliterator,
+ // Higher order function returning a consumer that
+ // traverses all spliterator elements using an EntryConsumer
+ s -> ec -> { while (s.tryAdvance(ec)); });
+ }
+
+ void testSpliterator(Supplier<Spliterator<Map.Entry<Integer, Integer>>> ss,
+ // Higher order function that given a spliterator returns a
+ // consumer for that spliterator which traverses elements
+ // using an EntryConsumer
+ Function<Spliterator<Map.Entry<Integer, Integer>>, Consumer<EntryConsumer>> sc) {
+ testWithEntryConsumer(sc.apply(ss.get()));
+
+ Spliterator<Map.Entry<Integer, Integer>> s = ss.get();
+ Spliterator<Map.Entry<Integer, Integer>> split = s.trySplit();
+ if (split != null) {
+ testWithEntryConsumer(sc.apply(split));
+ testWithEntryConsumer(sc.apply(s));
+ }
+ }
+
+ @Test(dataProvider = "maps")
+ public void testStreamForEach(String d, Supplier<Map<Integer, Integer>> ms) {
+ testWithEntryConsumer(ec -> ms.get().entrySet().stream().forEach(ec));
+ }
+
+ @Test(dataProvider = "maps")
+ public void testParallelStreamForEach(String d, Supplier<Map<Integer, Integer>> ms) {
+ testWithEntryConsumer(ec -> ms.get().entrySet().parallelStream().forEach(ec));
+ }
+}
+
diff --git a/ojluni/src/test/java/util/Collections/ViewSynch.java b/ojluni/src/test/java/util/Collections/ViewSynch.java
new file mode 100644
index 00000000000..9c7b3ae3b9e
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ViewSynch.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4268780
+ * @summary Collection-views of submap-views of synchronized-views of
+ * SortedMap objects do not synchronize on the correct object.
+ * (Got that?)
+ */
+
+package test.java.util.Collections;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class ViewSynch {
+ static final Integer ZERO = new Integer(0);
+ static final Int INT_ZERO = new Int(0);
+ static final Int INT_ONE = new Int(1);
+ static SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
+ static Map m2 = m.tailMap(ZERO);
+ static Collection c = m2.values();
+
+ public static void main(String[] args) {
+ for (int i=0; i<10000; i++)
+ m.put(new Integer(i), INT_ZERO);
+
+ new Thread() {
+ public void run() {
+ for (int i=0; i<100; i++) {
+ Thread.yield();
+ m.remove(ZERO);
+ m.put(ZERO, INT_ZERO);
+ }
+ }
+ }.start();
+
+ c.contains(INT_ONE);
+ }
+}
+
+/**
+ * Like Integer, except yields while doing equals comparison, to allow
+ * for interleaving.
+ */
+class Int {
+ Integer x;
+ Int(int i) {x = new Integer(i);}
+
+ public boolean equals(Object o) {
+ Thread.yield();
+ Int i = (Int)o;
+ return x.equals(i.x);
+ }
+
+ public int hashCode() {return x.hashCode();}
+}
diff --git a/ojluni/src/test/java/util/Collections/WrappedNull.java b/ojluni/src/test/java/util/Collections/WrappedNull.java
new file mode 100644
index 00000000000..418412e9cd5
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/WrappedNull.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4189641
+ * @summary Wrapping a null collection/array should blow up sooner
+ * rather than later
+ */
+
+package test.java.util.Collections;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+public class WrappedNull {
+ public static void main(String[] args) throws Exception {
+ boolean testSucceeded = false;
+ try {
+ List l = Arrays.asList(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("Arrays.asList");
+
+ testSucceeded = false;
+ try {
+ Collection c = Collections.unmodifiableCollection(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("unmodifiableCollection");
+
+ testSucceeded = false;
+ try {
+ Set c = Collections.unmodifiableSet(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("unmodifiableSet");
+
+ testSucceeded = false;
+ try {
+ List c = Collections.unmodifiableList(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("unmodifiableList");
+
+ testSucceeded = false;
+ try {
+ Map c = Collections.unmodifiableMap(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("unmodifiableMap");
+
+ testSucceeded = false;
+ try {
+ SortedSet c = Collections.unmodifiableSortedSet(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("unmodifiableSortedSet");
+
+ testSucceeded = false;
+ try {
+ SortedMap c = Collections.unmodifiableSortedMap(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("unmodifiableSortedMap");
+
+ testSucceeded = false;
+ try {
+ Collection c = Collections.synchronizedCollection(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("synchronizedCollection");
+
+ testSucceeded = false;
+ try {
+ Set c = Collections.synchronizedSet(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("synchronizedSet");
+
+ testSucceeded = false;
+ try {
+ List c = Collections.synchronizedList(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("synchronizedList");
+
+ testSucceeded = false;
+ try {
+ Map c = Collections.synchronizedMap(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("synchronizedMap");
+
+ testSucceeded = false;
+ try {
+ SortedSet c = Collections.synchronizedSortedSet(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("synchronizedSortedSet");
+
+ testSucceeded = false;
+ try {
+ SortedMap c = Collections.synchronizedSortedMap(null);
+ }
+ catch (NullPointerException e) {
+ testSucceeded = true;
+ }
+ if (!testSucceeded)
+ throw new Exception("synchronizedSortedMap");
+
+ // Make sure that non-null arguments don't throw exc.
+ List l = Arrays.asList(new Object[0]);
+ Collection c = Collections.unmodifiableCollection(
+ Collections.EMPTY_SET);
+ Set s = Collections.unmodifiableSet(Collections.EMPTY_SET);
+ l = Collections.unmodifiableList(Collections.EMPTY_LIST);
+ Map m = Collections.unmodifiableMap(Collections.EMPTY_MAP);
+ SortedSet ss = Collections.unmodifiableSortedSet(new TreeSet());
+ SortedMap sm = Collections.unmodifiableSortedMap(new TreeMap());
+
+ c = Collections.synchronizedCollection(Collections.EMPTY_SET);
+ s = Collections.synchronizedSet(Collections.EMPTY_SET);
+ l = Collections.synchronizedList(Collections.EMPTY_LIST);
+ m = Collections.synchronizedMap(Collections.EMPTY_MAP);
+ ss = Collections.synchronizedSortedSet(new TreeSet());
+ sm = Collections.synchronizedSortedMap(new TreeMap());
+ }
+}
diff --git a/ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java b/ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java
new file mode 100644
index 00000000000..b991d0b6c57
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6323374
+ * @run testng WrappedUnmodifiableCollections
+ */
+
+package test.java.util.Collections;
+
+import java.util.*;
+import java.util.function.Function;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+
+@Test
+public class WrappedUnmodifiableCollections {
+
+ private static <T,E extends T> void testWrapping(T collection, Function<T,E> wrapper) {
+ var collection1 = wrapper.apply(collection);
+ var collection2 = wrapper.apply(collection1);
+ assertNotSame(collection, collection2);
+ assertSame(collection1, collection2);
+ }
+
+ public void testUnmodifiableListsDontWrap() {
+ List<List<?>> lists = List.of(List.of(), List.of(1,2,3), List.of(1),
+ List.of(1,2,3,4,5,6),
+ List.of(1,2,3).subList(0,1),
+ new LinkedList<>(List.of(1,2,3)),
+ new ArrayList<>(List.of(1,2,3)));
+
+ for(List<?> list : lists) {
+ testWrapping(list, Collections::unmodifiableList);
+ }
+ }
+
+ public void testUnmodifiableCollectionsDontWrap() {
+ Collection<?> list = List.of();
+ testWrapping(list, Collections::unmodifiableCollection);
+ }
+
+ public void testUnmodifiableSetsDontWrap() {
+
+ List<Set<?>> sets = List.of(new TreeSet<>(),
+ Set.of(1, 2),
+ Set.of(1,2,3,4,5,6));
+
+ for (Set<?> set : sets) {
+ testWrapping(set, Collections::unmodifiableSet);
+ }
+
+ TreeSet<?> treeSet = new TreeSet<>();
+
+ //Collections.UnmodifiableSortedSet
+ testWrapping((SortedSet<?>) treeSet, Collections::unmodifiableSortedSet);
+
+ //Collections.UnmodifiableNavigableSet
+ testWrapping((NavigableSet<?>) treeSet, Collections::unmodifiableNavigableSet);
+
+ }
+
+ public void testUnmodifiableMapsDontWrap() {
+ TreeMap<?,?> treeMap = new TreeMap<>();
+
+ List<Map<?,?>> maps = List.of(treeMap,
+ Map.of(1,1),
+ Map.of(1, 1, 2, 2, 3, 3, 4, 4));
+
+ for (Map<?,?> map : maps) {
+ testWrapping(map, Collections::unmodifiableMap);
+ }
+
+ //Collections.UnModifiableSortedMap
+ testWrapping((SortedMap<?,?>) treeMap, Collections::unmodifiableSortedMap);
+
+ //Collections.UnModifiableNavigableMap
+ testWrapping((NavigableMap<?,?>) treeMap, Collections::unmodifiableNavigableMap);
+
+ }
+
+}
diff --git a/ojluni/src/test/java/util/Collections/Wrappers.java b/ojluni/src/test/java/util/Collections/Wrappers.java
new file mode 100644
index 00000000000..5b8aff4d3f7
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Wrappers.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @run testng Wrappers
+ * @summary Ensure Collections wrapping classes provide non-default implementations
+ */
+
+package test.java.util.Collections;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+import static org.testng.Assert.assertFalse;
+
+@Test(groups = "unit")
+public class Wrappers {
+ static Object[][] collections;
+
+ @DataProvider(name="collections")
+ public static Object[][] collectionCases() {
+ if (collections != null) {
+ return collections;
+ }
+
+ List<Object[]> cases = new ArrayList<>();
+ LinkedList<Integer> seedList = new LinkedList<>();
+ ArrayList<Integer> seedRandomAccess = new ArrayList<>();
+ TreeSet<Integer> seedSet = new TreeSet<>();
+ TreeMap<Integer, Integer> seedMap = new TreeMap<>();
+
+ for (int i = 1; i <= 10; i++) {
+ seedList.add(i);
+ seedRandomAccess.add(i);
+ seedSet.add(i);
+ seedMap.put(i, i);
+ }
+
+ cases.add(new Object[] { Collections.unmodifiableCollection(seedList) });
+ cases.add(new Object[] { Collections.unmodifiableList(seedList) });
+ cases.add(new Object[] { Collections.unmodifiableList(seedRandomAccess) });
+ cases.add(new Object[] { Collections.unmodifiableSet(seedSet) });
+ cases.add(new Object[] { Collections.unmodifiableSortedSet(seedSet) });
+ cases.add(new Object[] { Collections.unmodifiableNavigableSet(seedSet) });
+
+ // As sets from map also need to be unmodifiable, thus a wrapping
+ // layer exist and should not have default methods
+ cases.add(new Object[] { Collections.unmodifiableMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.unmodifiableMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.unmodifiableMap(seedMap).values() });
+ cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).values() });
+ cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).values() });
+
+ // Synchronized
+ cases.add(new Object[] { Collections.synchronizedCollection(seedList) });
+ cases.add(new Object[] { Collections.synchronizedList(seedList) });
+ cases.add(new Object[] { Collections.synchronizedList(seedRandomAccess) });
+ cases.add(new Object[] { Collections.synchronizedSet(seedSet) });
+ cases.add(new Object[] { Collections.synchronizedSortedSet(seedSet) });
+ cases.add(new Object[] { Collections.synchronizedNavigableSet(seedSet) });
+
+ // As sets from map also need to be synchronized on the map, thus a
+ // wrapping layer exist and should not have default methods
+ cases.add(new Object[] { Collections.synchronizedMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.synchronizedMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.synchronizedMap(seedMap).values() });
+ cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).values() });
+ cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).values() });
+
+ // Checked
+ cases.add(new Object[] { Collections.checkedCollection(seedList, Integer.class) });
+ cases.add(new Object[] { Collections.checkedList(seedList, Integer.class) });
+ cases.add(new Object[] { Collections.checkedList(seedRandomAccess, Integer.class) });
+ cases.add(new Object[] { Collections.checkedSet(seedSet, Integer.class) });
+ cases.add(new Object[] { Collections.checkedSortedSet(seedSet, Integer.class) });
+ cases.add(new Object[] { Collections.checkedNavigableSet(seedSet, Integer.class) });
+ cases.add(new Object[] { Collections.checkedQueue(seedList, Integer.class) });
+
+ // asLifoQueue is another wrapper
+ cases.add(new Object[] { Collections.asLifoQueue(seedList) });
+
+ collections = cases.toArray(new Object[0][]);
+ return collections;
+ }
+
+ static Method[] defaultMethods;
+
+ static {
+ List<Method> list = new ArrayList<>();
+ Method[] methods = Collection.class.getMethods();
+ for (Method m: methods) {
+ if (m.isDefault()) {
+ list.add(m);
+ }
+ }
+ defaultMethods = list.toArray(new Method[0]);
+ }
+
+ @Test(dataProvider = "collections")
+ public static void testAllDefaultMethodsOverridden(Collection c) throws NoSuchMethodException {
+ Class cls = c.getClass();
+ for (Method m: defaultMethods) {
+ Method m2 = cls.getMethod(m.getName(), m.getParameterTypes());
+ // default had been override
+ assertFalse(m2.isDefault(), cls.getCanonicalName());
+ }
+ }
+}
+
diff --git a/ojluni/src/test/java/util/HexFormat/HexFormatTest.java b/ojluni/src/test/java/util/HexFormat/HexFormatTest.java
index ce9dc42375e..4009a9f9fac 100644
--- a/ojluni/src/test/java/util/HexFormat/HexFormatTest.java
+++ b/ojluni/src/test/java/util/HexFormat/HexFormatTest.java
@@ -48,6 +48,8 @@ import static org.testng.Assert.expectThrows;
*/
@Test
+// Android-changed: test methods are changed to public. static package private methods
+// are not picked by the test runner.
public class HexFormatTest {
static final Class<NullPointerException> NPE = NullPointerException.class;
@@ -140,7 +142,7 @@ public class HexFormatTest {
}
@Test
- static void testToHex() {
+ public void testToHex() {
HexFormat hex = HexFormat.of();
for (int i = 0; i < 32; i++) {
char c = hex.toLowHexDigit((byte)i);
@@ -150,7 +152,7 @@ public class HexFormatTest {
}
@Test
- static void testToHexDigits() {
+ public void testToHexDigits() {
HexFormat hex = HexFormat.of();
for (int i = 0; i < 256; i++) {
String actual = hex.toHexDigits((byte)i);
@@ -164,7 +166,7 @@ public class HexFormatTest {
}
@Test
- static void testIsHexDigit() {
+ public void testIsHexDigit() {
for (int i = 0; i < 0x3ff; i++) {
boolean actual = HexFormat.isHexDigit(i);
boolean expected = Character.digit(i, 16) >= 0;
@@ -173,7 +175,7 @@ public class HexFormatTest {
}
@Test
- static void testFromHexDigit() {
+ public void testFromHexDigit() {
String chars = "0123456789ABCDEF0123456789abcdef";
for (int i = 0; i < chars.length(); i++) {
int v = HexFormat.fromHexDigit(chars.charAt(i));
@@ -182,7 +184,7 @@ public class HexFormatTest {
}
@Test
- static void testFromHexInvalid() {
+ public void testFromHexInvalid() {
for (int i = 0; i < 65536; i++) {
char ch = (char)i;
if (ch > 0xff || Character.digit(ch, 16) < 0) {
@@ -195,7 +197,7 @@ public class HexFormatTest {
}
@Test
- static void testAppendHexByteWithStringBuilder() {
+ public void testAppendHexByteWithStringBuilder() {
HexFormat hex = HexFormat.of();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 256; i++) {
@@ -223,7 +225,7 @@ public class HexFormatTest {
}
@Test
- static void testAppendHexByteWithCharArrayWriter() {
+ public void testAppendHexByteWithCharArrayWriter() {
HexFormat hex = HexFormat.of();
CharArrayWriter caw = new CharArrayWriter();
for (int i = 1; i <= 128; i++) {
@@ -234,7 +236,7 @@ public class HexFormatTest {
}
@Test
- static void testFromHexPairInvalid() {
+ public void testFromHexPairInvalid() {
HexFormat hex = HexFormat.of();
// An assortment of invalid characters
@@ -248,7 +250,7 @@ public class HexFormatTest {
}
@Test(dataProvider = "HexStringsThrowing")
- static void testToBytesThrowing(String value, String sep, String prefix, String suffix) {
+ public void testToBytesThrowing(String value, String sep, String prefix, String suffix) {
HexFormat hex = HexFormat.ofDelimiter(sep).withPrefix(prefix).withSuffix(suffix);
Throwable ex = expectThrows(IllegalArgumentException.class,
() -> {
@@ -260,7 +262,7 @@ public class HexFormatTest {
}
@Test
- static void testFactoryNPE() {
+ public void testFactoryNPE() {
assertThrows(NPE, () -> HexFormat.ofDelimiter(null));
assertThrows(NPE, () -> HexFormat.of().withDelimiter(null));
assertThrows(NPE, () -> HexFormat.of().withPrefix(null));
@@ -268,7 +270,7 @@ public class HexFormatTest {
}
@Test
- static void testFormatHexNPE() {
+ public void testFormatHexNPE() {
assertThrows(NPE, () -> HexFormat.of().formatHex(null));
assertThrows(NPE, () -> HexFormat.of().formatHex(null, 0, 1));
assertThrows(NPE, () -> HexFormat.of().formatHex(null, null));
@@ -279,14 +281,14 @@ public class HexFormatTest {
}
@Test
- static void testParseHexNPE() {
+ public void testParseHexNPE() {
assertThrows(NPE, () -> HexFormat.of().parseHex(null));
assertThrows(NPE, () -> HexFormat.of().parseHex((String)null, 0, 0));
assertThrows(NPE, () -> HexFormat.of().parseHex((char[])null, 0, 0));
}
@Test
- static void testFromHexNPE() {
+ public void testFromHexNPE() {
assertThrows(NPE, () -> HexFormat.fromHexDigits(null));
assertThrows(NPE, () -> HexFormat.fromHexDigits(null, 0, 0));
assertThrows(NPE, () -> HexFormat.fromHexDigitsToLong(null));
@@ -294,12 +296,12 @@ public class HexFormatTest {
}
@Test
- static void testToHexDigitsNPE() {
+ public void testToHexDigitsNPE() {
assertThrows(NPE, () -> HexFormat.of().toHexDigits(null, (byte)0));
}
@Test(dataProvider = "BadParseHexThrowing")
- static void badParseHex(String string, int offset, int length,
+ public void badParseHex(String string, int offset, int length,
Class<? extends Throwable> exClass) {
assertThrows(exClass,
() -> HexFormat.of().parseHex(string, offset, length));
@@ -309,7 +311,7 @@ public class HexFormatTest {
}
@Test(dataProvider = "BadFromHexDigitsThrowing")
- static void badFromHexDigits(String string, int fromIndex, int toIndex,
+ public void badFromHexDigits(String string, int fromIndex, int toIndex,
Class<? extends Throwable> exClass) {
assertThrows(exClass,
() -> HexFormat.fromHexDigits(string, fromIndex, toIndex));
@@ -320,7 +322,7 @@ public class HexFormatTest {
// Verify IAE for strings that are too long for the target primitive type
// or the number of requested digits is too large.
@Test
- static void wrongNumberDigits() {
+ public void wrongNumberDigits() {
assertThrows(IllegalArgumentException.class,
() -> HexFormat.fromHexDigits("9876543210"));
assertThrows(IllegalArgumentException.class,
@@ -332,7 +334,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatter(String delimiter, String prefix, String suffix,
+ public void testFormatter(String delimiter, String prefix, String suffix,
boolean uppercase,
HexFormat hex) {
byte[] expected = genBytes('A', 15);
@@ -367,7 +369,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatHexString(String unused1, String unused2, String unused3,
+ public void testFormatHexString(String unused1, String unused2, String unused3,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
String s = hex.formatHex(expected);
@@ -380,7 +382,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testParseHexStringRange(String delimiter, String prefix, String suffix,
+ public void testParseHexStringRange(String delimiter, String prefix, String suffix,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
String s = hex.formatHex(expected);
@@ -401,7 +403,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testParseHexEmptyString(String delimiter, String prefix, String suffix,
+ public void testParseHexEmptyString(String delimiter, String prefix, String suffix,
boolean unused4, HexFormat hex) {
byte[] actual = hex.parseHex("");
assertEquals(actual.length, 0, "empty string parse");
@@ -412,7 +414,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatHexRangeString(String unused1, String unused2, String unused3,
+ public void testFormatHexRangeString(String unused1, String unused2, String unused3,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
int low = 1;
@@ -427,7 +429,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatHexAppendable(String unused1, String unused2, String unused3,
+ public void testFormatHexAppendable(String unused1, String unused2, String unused3,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
StringBuilder sb = new StringBuilder();
@@ -442,7 +444,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatHexRangeAppendable(String unused1, String unused2, String unused3,
+ public void testFormatHexRangeAppendable(String unused1, String unused2, String unused3,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
int low = 1;
@@ -464,7 +466,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatHexCharArray(String unused1, String unused2, String unused3,
+ public void testFormatHexCharArray(String unused1, String unused2, String unused3,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
String s = hex.formatHex(expected);
@@ -478,7 +480,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatHexCharArrayIndexed(String delimiter, String prefix, String suffix,
+ public void testFormatHexCharArrayIndexed(String delimiter, String prefix, String suffix,
boolean unused4, HexFormat hex) {
byte[] expected = genBytes('A', 15);
String s = hex.formatHex(expected);
@@ -502,7 +504,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatterToString(String delimiter, String prefix, String suffix,
+ public void testFormatterToString(String delimiter, String prefix, String suffix,
boolean uppercase,
HexFormat hex) {
String actual = String.format(
@@ -513,7 +515,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatterParameterMethods(String delimiter, String prefix, String suffix,
+ public void testFormatterParameterMethods(String delimiter, String prefix, String suffix,
boolean uppercase,
HexFormat hex) {
assertEquals(hex.delimiter(), delimiter);
@@ -523,7 +525,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testFormatterTestEquals(String delimiter, String prefix, String suffix,
+ public void testFormatterTestEquals(String delimiter, String prefix, String suffix,
boolean uppercase,
HexFormat expected) {
HexFormat actual = HexFormat.of()
@@ -544,7 +546,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testZeroLength(String delimiter, String prefix, String suffix, boolean uppercase,
+ public void testZeroLength(String delimiter, String prefix, String suffix, boolean uppercase,
HexFormat hex) {
// Test formatting of zero length byte arrays, should produce no output
StringBuilder sb = new StringBuilder();
@@ -563,7 +565,7 @@ public class HexFormatTest {
}
@Test
- static void testfromHexDigitsToInt() {
+ public void testfromHexDigitsToInt() {
HexFormat hex = HexFormat.of();
String allHex = "76543210";
@@ -580,7 +582,7 @@ public class HexFormatTest {
}
@Test
- static void testfromHexDigitsToLong() {
+ public void testfromHexDigitsToLong() {
HexFormat hex = HexFormat.of();
String allHex = "fedcba9876543210";
@@ -597,7 +599,7 @@ public class HexFormatTest {
}
@Test
- static void testToHexDigitsLong() {
+ public void testToHexDigitsLong() {
HexFormat hex = HexFormat.of();
String allHex = "fedcba9876543210";
@@ -610,7 +612,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testIOException(String delimiter, String prefix, String suffix, boolean uppercase,
+ public void testIOException(String delimiter, String prefix, String suffix, boolean uppercase,
HexFormat hex) {
Appendable throwingAppendable = new ThrowingAppendable();
assertThrows(UncheckedIOException.class,
@@ -622,7 +624,7 @@ public class HexFormatTest {
}
@Test(dataProvider="HexFormattersParsers")
- static void testOOME(String delimiter, String prefix, String suffix, boolean uppercase,
+ public void testOOME(String delimiter, String prefix, String suffix, boolean uppercase,
HexFormat hex) {
// compute the size of byte array that will exceed the buffer
long valueChars = prefix.length() + 2 + suffix.length();
@@ -656,7 +658,7 @@ public class HexFormatTest {
* The additional TestNG asserts verify the correctness of the same code.
*/
@Test
- private static void samples() {
+ public void samples() {
{
// Primitive formatting and parsing.
HexFormat hex = HexFormat.of();
diff --git a/ojluni/src/test/java/util/PriorityQueue/AddNonComparable.java b/ojluni/src/test/java/util/PriorityQueue/AddNonComparable.java
index 3adf7f3255e..1b22ac0f74e 100644
--- a/ojluni/src/test/java/util/PriorityQueue/AddNonComparable.java
+++ b/ojluni/src/test/java/util/PriorityQueue/AddNonComparable.java
@@ -46,6 +46,11 @@ import java.util.function.Supplier;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import android.compat.Compatibility;
+
+import dalvik.annotation.compat.VersionCodes;
+import dalvik.system.VMRuntime;
+
public class AddNonComparable {
static <E> void test(Queue<E> queue, Supplier<E> supplier,
@@ -58,11 +63,23 @@ public class AddNonComparable {
@Test
public void queues() {
- test(new PriorityQueue<>(), NonComparable::new,
- (q, e) -> {
- assertEquals(q.size(), 0);
- assertTrue(e instanceof ClassCastException);
- });
+ // Android-added: test old behavior in < U.
+ boolean testPreAndroidUBehavior = VMRuntime.getSdkVersion() < VersionCodes.UPSIDE_DOWN_CAKE
+ || !Compatibility.isChangeEnabled(PriorityQueue.PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT);
+
+ if (testPreAndroidUBehavior) {
+ test(new PriorityQueue<>(), NonComparable::new,
+ (q, e) -> {
+ assertEquals(q.size(), 1);
+ assertTrue(e == null);
+ });
+ } else {
+ test(new PriorityQueue<>(), NonComparable::new,
+ (q, e) -> {
+ assertEquals(q.size(), 0);
+ assertTrue(e instanceof ClassCastException);
+ });
+ }
test(new PriorityQueue<>(), AComparable::new,
(q, e) -> {
assertEquals(q.size(), 1);
diff --git a/ojluni/src/test/java/util/WeakHashMap/GCDuringIteration.java b/ojluni/src/test/java/util/WeakHashMap/GCDuringIteration.java
new file mode 100644
index 00000000000..ad9a55ba1d7
--- /dev/null
+++ b/ojluni/src/test/java/util/WeakHashMap/GCDuringIteration.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6499848
+ * @library /test/lib
+ * @build jdk.test.lib.RandomFactory
+ * @run main GCDuringIteration
+ * @summary Check that iterators work properly in the presence of
+ * concurrent finalization and removal of elements.
+ * @key randomness
+ */
+
+package test.java.util.WeakHashMap;
+
+import jdk.test.lib.RandomFactory;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.WeakHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.BooleanSupplier;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class GCDuringIteration {
+
+ /** No guarantees, but effective in practice. */
+ static void forceFullGc() {
+ long timeoutMillis = 1000L;
+ CountDownLatch finalized = new CountDownLatch(1);
+ ReferenceQueue<Object> queue = new ReferenceQueue<>();
+ WeakReference<Object> ref = new WeakReference<>(
+ new Object() { protected void finalize() { finalized.countDown(); }},
+ queue);
+ try {
+ for (int tries = 3; tries--> 0; ) {
+ // Android-changed: Runtime.getRuntime().gc() requires more iterations and
+ // takes significantly longer to finish.
+ // System.gc();
+ Runtime.getRuntime().gc();
+ if (finalized.await(timeoutMillis, MILLISECONDS)
+ && queue.remove(timeoutMillis) != null
+ && ref.get() == null) {
+ System.runFinalization(); // try to pick up stragglers
+ return;
+ }
+ timeoutMillis *= 4;
+ }
+ } catch (InterruptedException unexpected) {
+ throw new AssertionError("unexpected InterruptedException");
+ }
+ throw new AssertionError("failed to do a \"full\" gc");
+ }
+
+ static void gcAwait(BooleanSupplier s) {
+ for (int i = 0; i < 10; i++) {
+ if (s.getAsBoolean())
+ return;
+ forceFullGc();
+ }
+ throw new AssertionError("failed to satisfy condition");
+ }
+
+ // A class with the traditional pessimal hashCode implementation,
+ // to ensure that all instances end up in the same bucket.
+ static class Foo { public int hashCode() { return 42; }}
+
+ <K,V> void put(Map<K,V> map, K k, V v) {
+ check(! map.containsKey(k));
+ equal(map.get(k), null);
+ equal(map.put(k, v), null);
+ equal(map.get(k), v);
+ check(map.containsKey(k));
+ equal(map.put(k, v), v);
+ equal(map.get(k), v);
+ check(map.containsKey(k));
+ check(! map.isEmpty());
+ equal(map.keySet().iterator().next(), k);
+ equal(map.values().iterator().next(), v);
+ }
+
+ static final Random rnd = RandomFactory.getRandom();
+
+ void checkIterator(final Iterator<Map.Entry<Foo, Integer>> it, int first) {
+ for (int i = first; i >= 0; --i) {
+ if (rnd.nextBoolean()) check(it.hasNext());
+ equal(it.next().getValue(), i);
+ }
+ if (rnd.nextBoolean()) {
+ try {
+ it.next();
+ throw new AssertionError("should throw");
+ } catch (NoSuchElementException success) {}
+ }
+
+ if (rnd.nextBoolean())
+ check(! it.hasNext());
+ }
+
+ <K,V> V firstValue(Map<K,V> map) {
+ return map.values().iterator().next();
+ }
+
+ void test(String[] args) throws Throwable {
+ final int n = 10;
+ // Create array of strong refs
+ final Foo[] foos = new Foo[2*n];
+ final Map<Foo,Integer> map = new WeakHashMap<>(foos.length);
+ check(map.isEmpty());
+ equal(map.size(), 0);
+
+ for (int i = 0; i < foos.length; i++) {
+ Foo foo = new Foo();
+ foos[i] = foo;
+ put(map, foo, i);
+ }
+ equal(map.size(), foos.length);
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ foos[first] = null;
+ gcAwait(() -> map.size() == first);
+ checkIterator(it, first-1);
+ equal(map.size(), first);
+ equal(firstValue(map), first-1);
+ }
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ it.next(); // protects first entry
+ System.out.println(map.values());
+ int oldSize = map.size();
+ foos[first] = null;
+ forceFullGc();
+ equal(map.size(), oldSize);
+ System.out.println(map.values());
+ checkIterator(it, first-1);
+ // first entry no longer protected
+ gcAwait(() -> map.size() == first);
+ equal(firstValue(map), first-1);
+ }
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ it.next(); // protects first entry
+ System.out.println(map.values());
+ foos[first] = foos[first-1] = null;
+ gcAwait(() -> map.size() == first);
+ equal(firstValue(map), first);
+ System.out.println(map.values());
+ checkIterator(it, first-2);
+ // first entry no longer protected
+ gcAwait(() -> map.size() == first-1);
+ equal(firstValue(map), first-2);
+ }
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ it.next(); // protects first entry
+ it.hasNext(); // protects second entry
+ System.out.println(map.values());
+ int oldSize = map.size();
+ foos[first] = foos[first-1] = null;
+ forceFullGc();
+ equal(map.size(), oldSize);
+ equal(firstValue(map), first);
+ System.out.println(map.values());
+ checkIterator(it, first-1);
+ // first entry no longer protected
+ gcAwait(() -> map.size() == first-1);
+ equal(firstValue(map), first-2);
+ }
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ it.next(); // protects first entry
+ System.out.println(map.values());
+ equal(map.size(), first+1);
+ foos[first] = foos[first-1] = null;
+ gcAwait(() -> map.size() == first);
+ it.remove();
+ equal(firstValue(map), first-2);
+ equal(map.size(), first-1);
+ System.out.println(map.values());
+ checkIterator(it, first-2);
+ // first entry no longer protected
+ gcAwait(() -> map.size() == first-1);
+ equal(firstValue(map), first-2);
+ }
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ it.next(); // protects first entry
+ it.remove();
+ it.hasNext(); // protects second entry
+ System.out.println(map.values());
+ equal(map.size(), first);
+ foos[first] = foos[first-1] = null;
+ forceFullGc();
+ equal(firstValue(map), first-1);
+ equal(map.size(), first);
+ System.out.println(map.values());
+ checkIterator(it, first-1);
+ gcAwait(() -> map.size() == first-1);
+ equal(firstValue(map), first-2);
+ }
+
+ {
+ int first = firstValue(map);
+ final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
+ it.hasNext(); // protects first entry
+ Arrays.fill(foos, null);
+ gcAwait(() -> map.size() == 1);
+ System.out.println(map.values());
+ equal(it.next().getValue(), first);
+ check(! it.hasNext());
+ gcAwait(() -> map.size() == 0);
+ check(map.isEmpty());
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new GCDuringIteration().instanceMain(args);}
+ void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/ojluni/src/test/java/util/WeakHashMap/Iteration.java b/ojluni/src/test/java/util/WeakHashMap/Iteration.java
new file mode 100644
index 00000000000..309e7cd15c5
--- /dev/null
+++ b/ojluni/src/test/java/util/WeakHashMap/Iteration.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4236533 4416923
+ * @summary Tests to see that memory leak no longer exists.
+ * @author Josh Bloch
+ */
+
+package test.java.util.WeakHashMap;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+public class Iteration {
+ public static void main(String[] args) {
+ String s = "iatrogenic";
+ Map m = new WeakHashMap();
+ m.put(s, "cucumber");
+ Iterator i = m.keySet().iterator();
+ if (i.hasNext() != i.hasNext())
+ throw new RuntimeException("hasNext advances iterator");
+ }
+}
diff --git a/ojluni/src/test/java/util/WeakHashMap/ZeroInitCap.java b/ojluni/src/test/java/util/WeakHashMap/ZeroInitCap.java
new file mode 100644
index 00000000000..92b4ebdec18
--- /dev/null
+++ b/ojluni/src/test/java/util/WeakHashMap/ZeroInitCap.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.java.util.WeakHashMap;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/*
+ * @test
+ * @bug 4503146
+ * @summary Zero initial capacity should be legal
+ * @author Josh Bloch
+ */
+
+public class ZeroInitCap {
+ public static void main(String[] args) {
+ Map map = new WeakHashMap(0);
+ map.put("a","b");
+ }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java b/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java
index 2f3943ab7bd..8ec9b01afa5 100644
--- a/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java
+++ b/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java
@@ -48,6 +48,10 @@ public class CollectionTest extends JSR166TestCase {
}
public static Test testSuite(CollectionImplementation impl) {
+ // Android-changed: Ignore CollectionTest. http://b/285113029
+ // This method apparently creates a new test suite without a test case,
+ // e.g. testCollectionDebugFail() is commented out.
+ /*
return newTestSuite
(parameterizedTestSuite(CollectionTest.class,
CollectionImplementation.class,
@@ -55,6 +59,9 @@ public class CollectionTest extends JSR166TestCase {
jdk8ParameterizedTestSuite(CollectionTest.class,
CollectionImplementation.class,
impl));
+
+ */
+ return null;
}
// public void testCollectionDebugFail() {
diff --git a/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java b/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
index 475edf9b871..62d293cc87b 100644
--- a/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
+++ b/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
@@ -426,6 +426,11 @@ public class JSR166TestCase extends TestCase {
public static TestSuite newTestSuite(Object... suiteOrClasses) {
TestSuite suite = new TestSuite();
for (Object suiteOrClass : suiteOrClasses) {
+ // Android-added: Ignore null and CollectionTest. http://b/285113029
+ if (suiteOrClass == null) {
+ continue;
+ }
+
if (suiteOrClass instanceof TestSuite)
suite.addTest((TestSuite) suiteOrClass);
else if (suiteOrClass instanceof Class)
diff --git a/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java
index 072abac2188..b7f2e9fc23c 100644
--- a/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java
+++ b/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java
@@ -45,6 +45,11 @@ import java.util.Queue;
import junit.framework.Test;
import junit.framework.TestSuite;
+import android.compat.Compatibility;
+
+import dalvik.annotation.compat.VersionCodes;
+import dalvik.system.VMRuntime;
+
public class PriorityQueueTest extends JSR166TestCase {
public static void main(String[] args) {
main(suite(), args);
@@ -226,10 +231,16 @@ public class PriorityQueueTest extends JSR166TestCase {
*/
public void testOfferNonComparable() {
PriorityQueue q = new PriorityQueue(1);
+ // Android-added: test old behavior in < U.
+ boolean preAndroidUBehavior = VMRuntime.getSdkVersion() < VersionCodes.UPSIDE_DOWN_CAKE
+ || !Compatibility.isChangeEnabled(PriorityQueue.PRIORITY_QUEUE_OFFER_NON_COMPARABLE_ONE_ELEMENT);
try {
q.offer(new Object());
- shouldThrow();
+ if (!preAndroidUBehavior) {
+ shouldThrow();
+ }
} catch (ClassCastException success) {
+ assertFalse(preAndroidUBehavior);
assertTrue(q.isEmpty());
assertEquals(0, q.size());
assertNull(q.poll());
diff --git a/ojluni/src/test/java/util/regex/PatternStreamTest.java b/ojluni/src/test/java/util/regex/PatternStreamTest.java
index edbd0541c98..5a6d06b3dbb 100644
--- a/ojluni/src/test/java/util/regex/PatternStreamTest.java
+++ b/ojluni/src/test/java/util/regex/PatternStreamTest.java
@@ -32,9 +32,11 @@
package test.java.util.regex;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+import android.compat.Compatibility;
+import dalvik.annotation.compat.VersionCodes;
+import dalvik.system.VMRuntime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -50,15 +52,8 @@ import java.util.stream.Stream;
import org.openjdk.testlib.java.util.stream.LambdaTestHelpers;
import org.openjdk.testlib.java.util.stream.OpTestCase;
import org.openjdk.testlib.java.util.stream.TestData;
-
-import static org.testng.Assert.*;
-
-import static java.util.regex.Pattern.SPLIT_AS_STREAM_RETURNS_SINGLE_EMPTY_STRING;
-
-import android.compat.Compatibility;
-
-import dalvik.annotation.compat.VersionCodes;
-import dalvik.system.VMRuntime;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
@Test
public class PatternStreamTest extends OpTestCase {
@@ -147,11 +142,11 @@ public class PatternStreamTest extends OpTestCase {
// Derive expected result from pattern.split
List<String> expected = Arrays.asList(pattern.split(input));
- // Android-added: Keep old behavior on Android 13 or below. http://b/286499139
- if(input.isEmpty()
- && !(VMRuntime.getSdkVersion() >= VersionCodes.UPSIDE_DOWN_CAKE
- && Compatibility.isChangeEnabled(
- Pattern.SPLIT_AS_STREAM_RETURNS_SINGLE_EMPTY_STRING))) {
+ // Android-added: Keep old behavior on Android 13 or below. http://b/286499139
+ if (input.isEmpty()
+ && !(VMRuntime.getSdkVersion() > VersionCodes.TIRAMISU
+ && Compatibility.isChangeEnabled(
+ Pattern.SPLIT_AS_STREAM_RETURNS_SINGLE_EMPTY_STRING))) {
expected = Collections.emptyList();
}
diff --git a/ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorOfIntDataBuilder.java b/ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorOfIntDataBuilder.java
new file mode 100644
index 00000000000..9c1866c737f
--- /dev/null
+++ b/ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorOfIntDataBuilder.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.testlib.java.util;
+
+import java.util.function.Supplier;
+import java.util.*;
+
+public class SpliteratorOfIntDataBuilder {
+ List<Object[]> data;
+
+ List<Integer> exp;
+
+ public SpliteratorOfIntDataBuilder(List<Object[]> data, List<Integer> exp) {
+ this.data = data;
+ this.exp = exp;
+ }
+
+ public void add(String description, List<Integer> expected, Supplier<Spliterator.OfInt> s) {
+ description = joiner(description).toString();
+ data.add(new Object[]{description, expected, s});
+ }
+
+ public void add(String description, Supplier<Spliterator.OfInt> s) {
+ add(description, exp, s);
+ }
+
+ StringBuilder joiner(String description) {
+ return new StringBuilder(description).
+ append(" {").
+ append("size=").append(exp.size()).
+ append("}");
+ }
+ }
+
diff --git a/ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorTestHelper.java b/ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorTestHelper.java
new file mode 100644
index 00000000000..fd3f0b2e2fe
--- /dev/null
+++ b/ojluni/src/test/java/util/stream/testlib/org/openjdk/testlib/java/util/SpliteratorTestHelper.java
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.testlib.java.util;
+
+import java.util.function.*;
+import org.openjdk.testlib.java.util.stream.LambdaTestHelpers;
+import java.util.*;
+
+import static org.testng.Assert.*;
+
+/**
+ * Assertion methods for spliterators, to be called from other tests
+ */
+public class SpliteratorTestHelper {
+
+ public interface ContentAsserter<T> {
+ void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered);
+ }
+
+ private static ContentAsserter<Object> DEFAULT_CONTENT_ASSERTER
+ = SpliteratorTestHelper::assertContents;
+
+ @SuppressWarnings("unchecked")
+ private static <T> ContentAsserter<T> defaultContentAsserter() {
+ return (ContentAsserter<T>) DEFAULT_CONTENT_ASSERTER;
+ }
+
+ public static void testSpliterator(Supplier<Spliterator<Integer>> supplier) {
+ testSpliterator(supplier, defaultContentAsserter());
+ }
+
+ public static void testSpliterator(Supplier<Spliterator<Integer>> supplier,
+ ContentAsserter<Integer> asserter) {
+ testSpliterator(supplier, (Consumer<Integer> b) -> b, asserter);
+ }
+
+ public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier) {
+ testIntSpliterator(supplier, defaultContentAsserter());
+ }
+
+ public static void testIntSpliterator(Supplier<Spliterator.OfInt> supplier,
+ ContentAsserter<Integer> asserter) {
+ testSpliterator(supplier, intBoxingConsumer(), asserter);
+ }
+
+ public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier) {
+ testLongSpliterator(supplier, defaultContentAsserter());
+ }
+
+ public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier,
+ ContentAsserter<Long> asserter) {
+ testSpliterator(supplier, longBoxingConsumer(), asserter);
+ }
+
+ public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier) {
+ testDoubleSpliterator(supplier, defaultContentAsserter());
+ }
+
+ public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier,
+ ContentAsserter<Double> asserter) {
+ testSpliterator(supplier, doubleBoxingConsumer(), asserter);
+ }
+
+ public static UnaryOperator<Consumer<Integer>> intBoxingConsumer() {
+ class BoxingAdapter implements Consumer<Integer>, IntConsumer {
+ private final Consumer<Integer> b;
+
+ BoxingAdapter(Consumer<Integer> b) {
+ this.b = b;
+ }
+
+ @Override
+ public void accept(Integer value) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void accept(int value) {
+ b.accept(value);
+ }
+ }
+
+ return b -> new BoxingAdapter(b);
+ }
+
+ public static UnaryOperator<Consumer<Long>> longBoxingConsumer() {
+ class BoxingAdapter implements Consumer<Long>, LongConsumer {
+ private final Consumer<Long> b;
+
+ BoxingAdapter(Consumer<Long> b) {
+ this.b = b;
+ }
+
+ @Override
+ public void accept(Long value) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void accept(long value) {
+ b.accept(value);
+ }
+ }
+
+ return b -> new BoxingAdapter(b);
+ }
+
+ public static UnaryOperator<Consumer<Double>> doubleBoxingConsumer() {
+ class BoxingAdapter implements Consumer<Double>, DoubleConsumer {
+ private final Consumer<Double> b;
+
+ BoxingAdapter(Consumer<Double> b) {
+ this.b = b;
+ }
+
+ @Override
+ public void accept(Double value) {
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public void accept(double value) {
+ b.accept(value);
+ }
+ }
+
+ return b -> new BoxingAdapter(b);
+ }
+
+ public static <T, S extends Spliterator<T>> void testSpliterator(Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ ArrayList<T> fromForEach = new ArrayList<>();
+ Spliterator<T> spliterator = supplier.get();
+ Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+ spliterator.forEachRemaining(addToFromForEach);
+
+ Collection<T> exp = Collections.unmodifiableList(fromForEach);
+
+ testNullPointerException(supplier);
+ testForEach(exp, supplier, boxingAdapter, asserter);
+ testTryAdvance(exp, supplier, boxingAdapter, asserter);
+ testMixedTryAdvanceForEach(exp, supplier, boxingAdapter, asserter);
+ testMixedTraverseAndSplit(exp, supplier, boxingAdapter, asserter);
+ testSplitAfterFullTraversal(supplier, boxingAdapter);
+ testSplitOnce(exp, supplier, boxingAdapter, asserter);
+ testSplitSixDeep(exp, supplier, boxingAdapter, asserter);
+ testSplitUntilNull(exp, supplier, boxingAdapter, asserter);
+ }
+
+ public static <T, S extends Spliterator<T>> void testForEach(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testForEach(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ public static <T, S extends Spliterator<T>> void testTryAdvance(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testTryAdvance(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ public static <T, S extends Spliterator<T>> void testMixedTryAdvanceForEach(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testMixedTryAdvanceForEach(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ public static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testMixedTraverseAndSplit(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ public static <T, S extends Spliterator<T>> void testSplitOnce(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testSplitOnce(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ public static <T, S extends Spliterator<T>> void testSplitSixDeep(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testSplitSixDeep(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ public static <T, S extends Spliterator<T>> void testSplitUntilNull(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ testSplitUntilNull(exp, supplier, boxingAdapter, defaultContentAsserter());
+ }
+
+ private static <T, S extends Spliterator<T>> void testNullPointerException(Supplier<S> s) {
+ S sp = s.get();
+ // Have to check instances and use casts to avoid tripwire messages and
+ // directly test the primitive methods
+ if (sp instanceof Spliterator.OfInt) {
+ Spliterator.OfInt psp = (Spliterator.OfInt) sp;
+ assertThrowsNPE(() -> psp.forEachRemaining((IntConsumer) null));
+ assertThrowsNPE(() -> psp.tryAdvance((IntConsumer) null));
+ }
+ else if (sp instanceof Spliterator.OfLong) {
+ Spliterator.OfLong psp = (Spliterator.OfLong) sp;
+ assertThrowsNPE(() -> psp.forEachRemaining((LongConsumer) null));
+ assertThrowsNPE(() -> psp.tryAdvance((LongConsumer) null));
+ }
+ else if (sp instanceof Spliterator.OfDouble) {
+ Spliterator.OfDouble psp = (Spliterator.OfDouble) sp;
+ assertThrowsNPE(() -> psp.forEachRemaining((DoubleConsumer) null));
+ assertThrowsNPE(() -> psp.tryAdvance((DoubleConsumer) null));
+ }
+ else {
+ assertThrowsNPE(() -> sp.forEachRemaining(null));
+ assertThrowsNPE(() -> sp.tryAdvance(null));
+ }
+ }
+
+ private static <T, S extends Spliterator<T>> void testForEach(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ S spliterator = supplier.get();
+ long sizeIfKnown = spliterator.getExactSizeIfKnown();
+ boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+ ArrayList<T> fromForEach = new ArrayList<>();
+ spliterator = supplier.get();
+ Consumer<T> addToFromForEach = boxingAdapter.apply(fromForEach::add);
+ spliterator.forEachRemaining(addToFromForEach);
+
+ // Assert that forEach now produces no elements
+ spliterator.forEachRemaining(boxingAdapter.apply(
+ e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+ // Assert that tryAdvance now produce no elements
+ spliterator.tryAdvance(boxingAdapter.apply(
+ e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+ // assert that size, tryAdvance, and forEach are consistent
+ if (sizeIfKnown >= 0) {
+ assertEquals(sizeIfKnown, exp.size());
+ }
+ if (exp.contains(null)) {
+ assertTrue(fromForEach.contains(null));
+ }
+ assertEquals(fromForEach.size(), exp.size());
+
+ asserter.assertContents(fromForEach, exp, isOrdered);
+ }
+
+ private static <T, S extends Spliterator<T>> void testTryAdvance(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ S spliterator = supplier.get();
+ long sizeIfKnown = spliterator.getExactSizeIfKnown();
+ boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+ spliterator = supplier.get();
+ ArrayList<T> fromTryAdvance = new ArrayList<>();
+ Consumer<T> addToFromTryAdvance = boxingAdapter.apply(fromTryAdvance::add);
+ while (spliterator.tryAdvance(addToFromTryAdvance)) { }
+
+ // Assert that forEach now produces no elements
+ spliterator.forEachRemaining(boxingAdapter.apply(
+ e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+ // Assert that tryAdvance now produce no elements
+ spliterator.tryAdvance(boxingAdapter.apply(
+ e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+ // assert that size, tryAdvance, and forEach are consistent
+ if (sizeIfKnown >= 0) {
+ assertEquals(sizeIfKnown, exp.size());
+ }
+ assertEquals(fromTryAdvance.size(), exp.size());
+
+ asserter.assertContents(fromTryAdvance, exp, isOrdered);
+ }
+
+ private static <T, S extends Spliterator<T>> void testMixedTryAdvanceForEach(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ S spliterator = supplier.get();
+ long sizeIfKnown = spliterator.getExactSizeIfKnown();
+ boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+ // tryAdvance first few elements, then forEach rest
+ ArrayList<T> dest = new ArrayList<>();
+ spliterator = supplier.get();
+ Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+ for (int i = 0; i < 10 && spliterator.tryAdvance(addToDest); i++) { }
+ spliterator.forEachRemaining(addToDest);
+
+ // Assert that forEach now produces no elements
+ spliterator.forEachRemaining(boxingAdapter.apply(
+ e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+ // Assert that tryAdvance now produce no elements
+ spliterator.tryAdvance(boxingAdapter.apply(
+ e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+ if (sizeIfKnown >= 0) {
+ assertEquals(sizeIfKnown, dest.size());
+ }
+ assertEquals(dest.size(), exp.size());
+
+ asserter.assertContents(dest, exp, isOrdered);
+ }
+
+ private static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ S spliterator = supplier.get();
+ long sizeIfKnown = spliterator.getExactSizeIfKnown();
+ boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+ // tryAdvance first few elements, then forEach rest
+ ArrayList<T> dest = new ArrayList<>();
+ spliterator = supplier.get();
+ Consumer<T> b = boxingAdapter.apply(dest::add);
+
+ Spliterator<T> spl1, spl2, spl3;
+ spliterator.tryAdvance(b);
+ spl2 = spliterator.trySplit();
+ if (spl2 != null) {
+ spl2.tryAdvance(b);
+ spl1 = spl2.trySplit();
+ if (spl1 != null) {
+ spl1.tryAdvance(b);
+ spl1.forEachRemaining(b);
+ }
+ spl2.tryAdvance(b);
+ spl2.forEachRemaining(b);
+ }
+ spliterator.tryAdvance(b);
+ spl3 = spliterator.trySplit();
+ if (spl3 != null) {
+ spl3.tryAdvance(b);
+ spl3.forEachRemaining(b);
+ }
+ spliterator.tryAdvance(b);
+ spliterator.forEachRemaining(b);
+
+ if (sizeIfKnown >= 0) {
+ assertEquals(sizeIfKnown, dest.size());
+ }
+ assertEquals(dest.size(), exp.size());
+
+ asserter.assertContents(dest, exp, isOrdered);
+ }
+
+ public static <T, S extends Spliterator<T>> void testSplitAfterFullTraversal(
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter) {
+ // Full traversal using tryAdvance
+ Spliterator<T> spliterator = supplier.get();
+ while (spliterator.tryAdvance(boxingAdapter.apply(e -> { }))) { }
+ Spliterator<T> split = spliterator.trySplit();
+ assertNull(split);
+
+ // Full traversal using forEach
+ spliterator = supplier.get();
+ spliterator.forEachRemaining(boxingAdapter.apply(e -> { }));
+ split = spliterator.trySplit();
+ assertNull(split);
+
+ // Full traversal using tryAdvance then forEach
+ spliterator = supplier.get();
+ spliterator.tryAdvance(boxingAdapter.apply(e -> { }));
+ spliterator.forEachRemaining(boxingAdapter.apply(e -> { }));
+ split = spliterator.trySplit();
+ assertNull(split);
+ }
+
+ private static <T, S extends Spliterator<T>> void testSplitOnce(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ S spliterator = supplier.get();
+ long sizeIfKnown = spliterator.getExactSizeIfKnown();
+ boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+ ArrayList<T> fromSplit = new ArrayList<>();
+ Spliterator<T> s1 = supplier.get();
+ Spliterator<T> s2 = s1.trySplit();
+ long s1Size = s1.getExactSizeIfKnown();
+ long s2Size = (s2 != null) ? s2.getExactSizeIfKnown() : 0;
+ Consumer<T> addToFromSplit = boxingAdapter.apply(fromSplit::add);
+ if (s2 != null)
+ s2.forEachRemaining(addToFromSplit);
+ s1.forEachRemaining(addToFromSplit);
+
+ if (sizeIfKnown >= 0) {
+ assertEquals(sizeIfKnown, fromSplit.size());
+ if (s1Size >= 0 && s2Size >= 0)
+ assertEquals(sizeIfKnown, s1Size + s2Size);
+ }
+
+ asserter.assertContents(fromSplit, exp, isOrdered);
+ }
+
+ private static <T, S extends Spliterator<T>> void testSplitSixDeep(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ S spliterator = supplier.get();
+ boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+ for (int depth=0; depth < 6; depth++) {
+ List<T> dest = new ArrayList<>();
+ spliterator = supplier.get();
+
+ assertSpliterator(spliterator);
+
+ // verify splitting with forEach
+ splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false);
+ asserter.assertContents(dest, exp, isOrdered);
+
+ // verify splitting with tryAdvance
+ dest.clear();
+ spliterator = supplier.get();
+ splitSixDeepVisitor(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), true);
+ asserter.assertContents(dest, exp, isOrdered);
+ }
+ }
+
+ private static <T, S extends Spliterator<T>>
+ void splitSixDeepVisitor(int depth, int curLevel,
+ List<T> dest, S spliterator, UnaryOperator<Consumer<T>> boxingAdapter,
+ int rootCharacteristics, boolean useTryAdvance) {
+ if (curLevel < depth) {
+ long beforeSize = spliterator.getExactSizeIfKnown();
+ Spliterator<T> split = spliterator.trySplit();
+ if (split != null) {
+ assertSpliterator(split, rootCharacteristics);
+ assertSpliterator(spliterator, rootCharacteristics);
+
+ if ((rootCharacteristics & Spliterator.SUBSIZED) != 0 &&
+ (rootCharacteristics & Spliterator.SIZED) != 0) {
+ assertEquals(beforeSize, split.estimateSize() + spliterator.estimateSize());
+ }
+ splitSixDeepVisitor(depth, curLevel + 1, dest, split, boxingAdapter, rootCharacteristics, useTryAdvance);
+ }
+ splitSixDeepVisitor(depth, curLevel + 1, dest, spliterator, boxingAdapter, rootCharacteristics, useTryAdvance);
+ }
+ else {
+ long sizeIfKnown = spliterator.getExactSizeIfKnown();
+ if (useTryAdvance) {
+ Consumer<T> addToDest = boxingAdapter.apply(dest::add);
+ int count = 0;
+ while (spliterator.tryAdvance(addToDest)) {
+ ++count;
+ }
+
+ if (sizeIfKnown >= 0)
+ assertEquals(sizeIfKnown, count);
+
+ // Assert that forEach now produces no elements
+ spliterator.forEachRemaining(boxingAdapter.apply(
+ e -> fail("Spliterator.forEach produced an element after spliterator exhausted: " + e)));
+
+ Spliterator<T> split = spliterator.trySplit();
+ assertNull(split);
+ }
+ else {
+ List<T> leafDest = new ArrayList<>();
+ Consumer<T> addToLeafDest = boxingAdapter.apply(leafDest::add);
+ spliterator.forEachRemaining(addToLeafDest);
+
+ if (sizeIfKnown >= 0)
+ assertEquals(sizeIfKnown, leafDest.size());
+
+ // Assert that forEach now produces no elements
+ spliterator.tryAdvance(boxingAdapter.apply(
+ e -> fail("Spliterator.tryAdvance produced an element after spliterator exhausted: " + e)));
+
+ Spliterator<T> split = spliterator.trySplit();
+ assertNull(split);
+
+ dest.addAll(leafDest);
+ }
+ }
+ }
+
+ private static <T, S extends Spliterator<T>> void testSplitUntilNull(
+ Collection<T> exp,
+ Supplier<S> supplier,
+ UnaryOperator<Consumer<T>> boxingAdapter,
+ ContentAsserter<T> asserter) {
+ Spliterator<T> s = supplier.get();
+ boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED);
+ assertSpliterator(s);
+
+ List<T> splits = new ArrayList<>();
+ Consumer<T> c = boxingAdapter.apply(splits::add);
+
+ testSplitUntilNull(new SplitNode<T>(c, s));
+ asserter.assertContents(splits, exp, isOrdered);
+ }
+
+ private static class SplitNode<T> {
+ // Constant for every node
+ final Consumer<T> c;
+ final int rootCharacteristics;
+
+ final Spliterator<T> s;
+
+ SplitNode(Consumer<T> c, Spliterator<T> s) {
+ this(c, s.characteristics(), s);
+ }
+
+ private SplitNode(Consumer<T> c, int rootCharacteristics, Spliterator<T> s) {
+ this.c = c;
+ this.rootCharacteristics = rootCharacteristics;
+ this.s = s;
+ }
+
+ SplitNode<T> fromSplit(Spliterator<T> split) {
+ return new SplitNode<>(c, rootCharacteristics, split);
+ }
+ }
+
+ /**
+ * Set the maximum stack capacity to 0.25MB. This should be more than enough to detect a bad spliterator
+ * while not unduly disrupting test infrastructure given the test data sizes that are used are small.
+ * Note that j.u.c.ForkJoinPool sets the max queue size to 64M (1 << 26).
+ */
+ private static final int MAXIMUM_STACK_CAPACITY = 1 << 18; // 0.25MB
+
+ private static <T> void testSplitUntilNull(SplitNode<T> e) {
+ // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
+ // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
+ // for a spliterator that is badly behaved.
+ Deque<SplitNode<T>> stack = new ArrayDeque<>();
+ stack.push(e);
+
+ int iteration = 0;
+ while (!stack.isEmpty()) {
+ assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");
+
+ e = stack.pop();
+ Spliterator<T> parentAndRightSplit = e.s;
+
+ long parentEstimateSize = parentAndRightSplit.estimateSize();
+ assertTrue(parentEstimateSize >= 0,
+ String.format("Split size estimate %d < 0", parentEstimateSize));
+
+ long parentSize = parentAndRightSplit.getExactSizeIfKnown();
+ Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
+ if (leftSplit == null) {
+ parentAndRightSplit.forEachRemaining(e.c);
+ continue;
+ }
+
+ assertSpliterator(leftSplit, e.rootCharacteristics);
+ assertSpliterator(parentAndRightSplit, e.rootCharacteristics);
+
+ if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0
+ && parentAndRightSplit.estimateSize() > 0) {
+ assertTrue(leftSplit.estimateSize() < parentEstimateSize,
+ String.format("Left split size estimate %d >= parent split size estimate %d",
+ leftSplit.estimateSize(), parentEstimateSize));
+ assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
+ String.format("Right split size estimate %d >= parent split size estimate %d",
+ leftSplit.estimateSize(), parentEstimateSize));
+ }
+ else {
+ assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
+ String.format("Left split size estimate %d > parent split size estimate %d",
+ leftSplit.estimateSize(), parentEstimateSize));
+ assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
+ String.format("Right split size estimate %d > parent split size estimate %d",
+ leftSplit.estimateSize(), parentEstimateSize));
+ }
+
+ long leftSize = leftSplit.getExactSizeIfKnown();
+ long rightSize = parentAndRightSplit.getExactSizeIfKnown();
+ if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
+ assertEquals(parentSize, leftSize + rightSize,
+ String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
+ leftSize, rightSize, parentSize));
+
+ // Add right side to stack first so left side is popped off first
+ stack.push(e.fromSplit(parentAndRightSplit));
+ stack.push(e.fromSplit(leftSplit));
+ }
+ }
+
+ private static void assertSpliterator(Spliterator<?> s, int rootCharacteristics) {
+ if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) {
+ assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED),
+ "Child split is not SUBSIZED when root split is SUBSIZED");
+ }
+ assertSpliterator(s);
+ }
+
+ private static void assertSpliterator(Spliterator<?> s) {
+ if (s.hasCharacteristics(Spliterator.SUBSIZED)) {
+ assertTrue(s.hasCharacteristics(Spliterator.SIZED));
+ }
+ if (s.hasCharacteristics(Spliterator.SIZED)) {
+ assertTrue(s.estimateSize() != Long.MAX_VALUE);
+ assertTrue(s.getExactSizeIfKnown() >= 0);
+ }
+ try {
+ s.getComparator();
+ assertTrue(s.hasCharacteristics(Spliterator.SORTED));
+ } catch (IllegalStateException e) {
+ assertFalse(s.hasCharacteristics(Spliterator.SORTED));
+ }
+ }
+
+ private static<T> void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
+ if (isOrdered) {
+ assertEquals(actual, expected);
+ }
+ else {
+ LambdaTestHelpers.assertContentsUnordered(actual, expected);
+ }
+ }
+
+ public static void assertThrowsNPE(ThrowingRunnable r) {
+ assertThrows(NullPointerException.class, r);
+ }
+
+ public static<U> void mixedTraverseAndSplit(Consumer<U> b, Spliterator<U> splTop) {
+ Spliterator<U> spl1, spl2, spl3;
+ splTop.tryAdvance(b);
+ spl2 = splTop.trySplit();
+ if (spl2 != null) {
+ spl2.tryAdvance(b);
+ spl1 = spl2.trySplit();
+ if (spl1 != null) {
+ spl1.tryAdvance(b);
+ spl1.forEachRemaining(b);
+ }
+ spl2.tryAdvance(b);
+ spl2.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ spl3 = splTop.trySplit();
+ if (spl3 != null) {
+ spl3.tryAdvance(b);
+ spl3.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ splTop.forEachRemaining(b);
+ }
+
+ public static void mixedTraverseAndSplit(IntConsumer b, Spliterator.OfInt splTop) {
+ Spliterator.OfInt spl1, spl2, spl3;
+ splTop.tryAdvance(b);
+ spl2 = splTop.trySplit();
+ if (spl2 != null) {
+ spl2.tryAdvance(b);
+ spl1 = spl2.trySplit();
+ if (spl1 != null) {
+ spl1.tryAdvance(b);
+ spl1.forEachRemaining(b);
+ }
+ spl2.tryAdvance(b);
+ spl2.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ spl3 = splTop.trySplit();
+ if (spl3 != null) {
+ spl3.tryAdvance(b);
+ spl3.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ splTop.forEachRemaining(b);
+ }
+
+ public static void mixedTraverseAndSplit(LongConsumer b, Spliterator.OfLong splTop) {
+ Spliterator.OfLong spl1, spl2, spl3;
+ splTop.tryAdvance(b);
+ spl2 = splTop.trySplit();
+ if (spl2 != null) {
+ spl2.tryAdvance(b);
+ spl1 = spl2.trySplit();
+ if (spl1 != null) {
+ spl1.tryAdvance(b);
+ spl1.forEachRemaining(b);
+ }
+ spl2.tryAdvance(b);
+ spl2.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ spl3 = splTop.trySplit();
+ if (spl3 != null) {
+ spl3.tryAdvance(b);
+ spl3.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ splTop.forEachRemaining(b);
+ }
+
+ public static void mixedTraverseAndSplit(DoubleConsumer b, Spliterator.OfDouble splTop) {
+ Spliterator.OfDouble spl1, spl2, spl3;
+ splTop.tryAdvance(b);
+ spl2 = splTop.trySplit();
+ if (spl2 != null) {
+ spl2.tryAdvance(b);
+ spl1 = spl2.trySplit();
+ if (spl1 != null) {
+ spl1.tryAdvance(b);
+ spl1.forEachRemaining(b);
+ }
+ spl2.tryAdvance(b);
+ spl2.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ spl3 = splTop.trySplit();
+ if (spl3 != null) {
+ spl3.tryAdvance(b);
+ spl3.forEachRemaining(b);
+ }
+ splTop.tryAdvance(b);
+ splTop.forEachRemaining(b);
+ }
+
+}
diff --git a/openjdk_java_files.bp b/openjdk_java_files.bp
index 804da6b1d70..ababa26682e 100644
--- a/openjdk_java_files.bp
+++ b/openjdk_java_files.bp
@@ -799,13 +799,11 @@ filegroup {
"ojluni/src/main/java/java/text/EntryPair.java",
"ojluni/src/main/java/java/text/FieldPosition.java",
"ojluni/src/main/java/java/text/Format.java",
- "ojluni/src/main/java/java/text/MergeCollation.java",
"ojluni/src/main/java/java/text/MessageFormat.java",
"ojluni/src/main/java/java/text/Normalizer.java",
"ojluni/src/main/java/java/text/NumberFormat.java",
"ojluni/src/main/java/java/text/ParseException.java",
"ojluni/src/main/java/java/text/ParsePosition.java",
- "ojluni/src/main/java/java/text/PatternEntry.java",
"ojluni/src/main/java/java/text/IcuIteratorWrapper.java",
"ojluni/src/main/java/java/text/RuleBasedCollator.java",
"ojluni/src/main/java/java/text/SimpleDateFormat.java",
diff --git a/test-rules/src/main/java/libcore/test/reasons/NonMtsReasons.java b/test-rules/src/main/java/libcore/test/reasons/NonMtsReasons.java
new file mode 100644
index 00000000000..cbe9f40bc7c
--- /dev/null
+++ b/test-rules/src/main/java/libcore/test/reasons/NonMtsReasons.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.test.reasons;
+
+/**
+ * Reasons for {@link libcore.test.annotation.NonMts}.
+ */
+public class NonMtsReasons {
+
+ /**
+ * If the test depends on a new API from ICU, and version-specific API behavior or locale data,
+ * you can use this reason.
+ */
+ public static final String ICU_VERSION_DEPENDENCY = "The test depends on a "
+ + "specific ICU version.";
+
+ /**
+ * If the test asserts a new behavior not tested in CTS, OEMs have the right to customize the
+ * behavior, but impossible to revert the behavior without system image OTA. Thus, we disable
+ * the test in MTS until it's tested in the dessert CTS.
+ */
+ public static final String OEM_CUSTOMIZATION = "The test doesn't pass with certain " +
+ "customizations from AOSP.";
+
+ private NonMtsReasons() {}
+}
diff --git a/tools/checkstyle/ojluni-src-test-header.xml b/tools/checkstyle/ojluni-src-test-header.xml
index 58832e2e3e5..6ba83969123 100644
--- a/tools/checkstyle/ojluni-src-test-header.xml
+++ b/tools/checkstyle/ojluni-src-test-header.xml
@@ -22,19 +22,6 @@
<property name="multiLines" value="1,2,3,9,10" />
</module>
- <!-- Google contributed OpenJDK tests -->
- <module name="BeforeExecutionExclusionFileFilter">
- <property name="fileNamePattern"
- value="ojluni/src/test/java/lang/StringBuffer/Capacity.java" />
- </module>
- <module name="BeforeExecutionExclusionFileFilter">
- <property name="fileNamePattern"
- value="ojluni/src/test/java/util/ArrayList/ArrayManagement.java" />
- </module>
- <module name="BeforeExecutionExclusionFileFilter">
- <property name="fileNamePattern"
- value="ojluni/src/test/java/util/Vector/ArrayManagement.java"/>
- </module>
<!-- One-off Android test that is present for MTS reasons (see https://r.android.com/1987987). -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern"
diff --git a/tools/checkstyle/openjdk-gplv2-copyright.pattern b/tools/checkstyle/openjdk-gplv2-copyright.pattern
index 9a61d2314b9..03fffea89a9 100644
--- a/tools/checkstyle/openjdk-gplv2-copyright.pattern
+++ b/tools/checkstyle/openjdk-gplv2-copyright.pattern
@@ -1,5 +1,5 @@
^(/\*)?$
-/* Copyright.*Android.*
+/* Copyright.*(Android|Google|Red Hat|SAP SE|Azul Systems|Goldman Sachs).*
[ /][*o] Copyright \(c\) \d\d\d\d,( ?\d\d\d\d,?)? Oracle and/or its affiliates\. All rights reserved\.
\* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER\.
\*
diff --git a/tools/checkstyle/openjdk-gplv2-plus-classpath-copyright.pattern b/tools/checkstyle/openjdk-gplv2-plus-classpath-copyright.pattern
index de71d8e9d83..b73521a5dc4 100644
--- a/tools/checkstyle/openjdk-gplv2-plus-classpath-copyright.pattern
+++ b/tools/checkstyle/openjdk-gplv2-plus-classpath-copyright.pattern
@@ -1,7 +1,7 @@
/\*.*
\*.*Android.*
\* Copyright \(c\) \d\d\d\d,( ?\d\d\d\d,?)? Oracle and/or its affiliates\. All rights reserved\.
- \*.*(Android|Google|Red Hat|SAP SE).*
+ \*.*(Android|Google|Red Hat|SAP SE|Azul Systems).*
\*$
\* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER\.
\*