Mercurial > hg > openjdk > lambda > jdk
changeset 10517:c0a2094aaafd
Merge
author | jlaskey |
---|---|
date | Wed, 24 Jul 2013 08:22:32 -0300 |
parents | 3b464e13a776 (current diff) 012996e9259f (diff) |
children | 528fc8f4281b |
files | src/share/classes/javax/security/auth/callback/package.html src/share/classes/javax/security/auth/kerberos/package.html src/share/classes/javax/security/auth/login/package.html src/share/classes/javax/security/auth/package.html src/share/classes/javax/security/auth/spi/package.html src/share/classes/javax/security/auth/x500/package.html src/share/classes/javax/security/cert/package.html src/share/classes/javax/security/sasl/package.html |
diffstat | 243 files changed, 10951 insertions(+), 4882 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Jul 16 09:09:09 2013 -0300 +++ b/.hgtags Wed Jul 24 08:22:32 2013 -0300 @@ -219,3 +219,4 @@ 42aa9f1828852bb8b77e98ec695211493ae0759d jdk8-b95 4a5d3cf2b3af1660db0237e8da324c140e534fa4 jdk8-b96 978a95239044f26dcc8a6d59246be07ad6ca6be2 jdk8-b97 +c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98
--- a/src/macosx/native/sun/awt/AWTEvent.m Tue Jul 16 09:09:09 2013 -0300 +++ b/src/macosx/native/sun/awt/AWTEvent.m Wed Jul 24 08:22:32 2013 -0300 @@ -382,7 +382,7 @@ { TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); - if (uchr == nil) { return; } + if (uchr == nil) { return 0; } const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); // Carbon modifiers should be used instead of NSEvent modifiers UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF;
--- a/src/share/classes/java/io/DataInput.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/io/DataInput.java Wed Jul 24 08:22:32 2013 -0300 @@ -48,132 +48,87 @@ * may be thrown if the input stream has been * closed. * - * <h4><a name="modified-utf-8">Modified UTF-8</a></h4> + * <h3><a name="modified-utf-8">Modified UTF-8</a></h3> * <p> * Implementations of the DataInput and DataOutput interfaces represent * Unicode strings in a format that is a slight modification of UTF-8. * (For information regarding the standard UTF-8 format, see section * <i>3.9 Unicode Encoding Forms</i> of <i>The Unicode Standard, Version * 4.0</i>). - * Note that in the following tables, the most significant bit appears in the + * Note that in the following table, the most significant bit appears in the * far left-hand column. - * <p> - * All characters in the range {@code '\u005Cu0001'} to - * {@code '\u005Cu007F'} are represented by a single byte: * * <blockquote> - * <table border="1" cellspacing="0" cellpadding="8" width="50%" + * <table border="1" cellspacing="0" cellpadding="8" * summary="Bit values and bytes"> * <tr> + * <th colspan="9"><span style="font-weight:normal"> + * All characters in the range {@code '\u005Cu0001'} to + * {@code '\u005Cu007F'} are represented by a single byte:</span></th> + * </tr> + * <tr> * <td></td> - * <th id="bit_a">Bit Values</th> + * <th colspan="8" id="bit_a">Bit Values</th> * </tr> * <tr> * <th id="byte1_a">Byte 1</th> - * <td> - * <table border="1" cellspacing="0" width="100%"> - * <tr> - * <td width="12%"><center>0</center> - * <td colspan="7"><center>bits 6-0</center> - * </tr> - * </table> - * </td> + * <td><center>0</center> + * <td colspan="7"><center>bits 6-0</center> * </tr> - * </table> - * </blockquote> - * - * <p> - * The null character {@code '\u005Cu0000'} and characters in the - * range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are - * represented by a pair of bytes: - * - * <blockquote> - * <table border="1" cellspacing="0" cellpadding="8" width="50%" - * summary="Bit values and bytes"> + * <tr> + * <th colspan="9"><span style="font-weight:normal"> + * The null character {@code '\u005Cu0000'} and characters + * in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are + * represented by a pair of bytes:</span></th> + * </tr> * <tr> * <td></td> - * <th id="bit_b">Bit Values</th> + * <th colspan="8" id="bit_b">Bit Values</th> * </tr> * <tr> * <th id="byte1_b">Byte 1</th> - * <td> - * <table border="1" cellspacing="0" width="100%"> - * <tr> - * <td width="12%"><center>1</center> - * <td width="13%"><center>1</center> - * <td width="12%"><center>0</center> - * <td colspan="5"><center>bits 10-6</center> - * </tr> - * </table> - * </td> + * <td><center>1</center> + * <td><center>1</center> + * <td><center>0</center> + * <td colspan="5"><center>bits 10-6</center> * </tr> * <tr> * <th id="byte2_a">Byte 2</th> - * <td> - * <table border="1" cellspacing="0" width="100%"> - * <tr> - * <td width="12%"><center>1</center> - * <td width="13%"><center>0</center> - * <td colspan="6"><center>bits 5-0</center> - * </tr> - * </table> - * </td> + * <td><center>1</center> + * <td><center>0</center> + * <td colspan="6"><center>bits 5-0</center> * </tr> - * </table> - * </blockquote> - * - * <br> - * {@code char} values in the range {@code '\u005Cu0800'} to - * {@code '\u005CuFFFF'} are represented by three bytes: - * - * <blockquote> - * <table border="1" cellspacing="0" cellpadding="8" width="50%" - * summary="Bit values and bytes"> + * <tr> + * <th colspan="9"><span style="font-weight:normal"> + * {@code char} values in the range {@code '\u005Cu0800'} + * to {@code '\u005CuFFFF'} are represented by three bytes:</span></th> + * </tr> * <tr> * <td></td> - * <th id="bit_c">Bit Values</th> + * <th colspan="8"id="bit_c">Bit Values</th> * </tr> * <tr> * <th id="byte1_c">Byte 1</th> - * <td> - * <table border="1" cellspacing="0" width="100%"> - * <tr> - * <td width="12%"><center>1</center> - * <td width="13%"><center>1</center> - * <td width="12%"><center>1</center> - * <td width="13%"><center>0</center> - * <td colspan="4"><center>bits 15-12</center> - * </tr> - * </table> - * </td> + * <td><center>1</center> + * <td><center>1</center> + * <td><center>1</center> + * <td><center>0</center> + * <td colspan="4"><center>bits 15-12</center> * </tr> * <tr> * <th id="byte2_b">Byte 2</th> - * <td> - * <table border="1" cellspacing="0" width="100%"> - * <tr> - * <td width="12%"><center>1</center> - * <td width="13%"><center>0</center> - * <td colspan="6"><center>bits 11-6</center> - * </tr> - * </table> - * </td> + * <td><center>1</center> + * <td><center>0</center> + * <td colspan="6"><center>bits 11-6</center> * </tr> * <tr> * <th id="byte3">Byte 3</th> - * <td> - * <table border="1" cellspacing="0" width="100%"> - * <tr> - * <td width="12%"><center>1</center> - * <td width="13%"><center>0</center> - * <td colspan="6"><center>bits 5-0</center> - * </tr> - * </table> - * </td> + * <td><center>1</center> + * <td><center>0</center> + * <td colspan="6"><center>bits 5-0</center> * </tr> * </table> - * </blockquote> - * + * </blockquote> * <p> * The differences between this format and the * standard UTF-8 format are the following:
--- a/src/share/classes/java/io/File.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/io/File.java Wed Jul 24 08:22:32 2013 -0300 @@ -129,7 +129,7 @@ * created, the abstract pathname represented by a <code>File</code> object * will never change. * - * <h4>Interoperability with {@code java.nio.file} package</h4> + * <h3>Interoperability with {@code java.nio.file} package</h3> * * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a> * package defines interfaces and classes for the Java virtual machine to access
--- a/src/share/classes/java/io/ObjectStreamField.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/io/ObjectStreamField.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -240,6 +240,8 @@ * Returns boolean value indicating whether or not the serializable field * represented by this ObjectStreamField instance is unshared. * + * @return {@code true} if this field is unshared + * * @since 1.4 */ public boolean isUnshared() {
--- a/src/share/classes/java/io/RandomAccessFile.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/io/RandomAccessFile.java Wed Jul 24 08:22:32 2013 -0300 @@ -128,7 +128,7 @@ * meanings are: * * <table summary="Access mode permitted values and meanings"> - * <tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr> + * <tr><th align="left">Value</th><th align="left">Meaning</th></tr> * <tr><td valign="top"><tt>"r"</tt></td> * <td> Open for reading only. Invoking any of the <tt>write</tt> * methods of the resulting object will cause an {@link
--- a/src/share/classes/java/lang/Class.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/Class.java Wed Jul 24 08:22:32 2013 -0300 @@ -157,10 +157,10 @@ * * The string is formatted as a list of type modifiers, if any, * followed by the kind of type (empty string for primitive types - * and {@code class}, {@code enum}, {@code interface}, or {@code - * @interface}, as appropriate), followed by the type's name, - * followed by an angle-bracketed comma-separated list of the - * type's type parameters, if any. + * and {@code class}, {@code enum}, {@code interface}, or + * <code>@</code>{@code interface}, as appropriate), followed + * by the type's name, followed by an angle-bracketed + * comma-separated list of the type's type parameters, if any. * * A space is used to separate modifiers from one another and to * separate any modifiers from the kind of type. The modifiers
--- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Wed Jul 24 08:22:32 2013 -0300 @@ -24,24 +24,23 @@ */ package java.lang.invoke; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import sun.invoke.util.Wrapper; -import static sun.invoke.util.Wrapper.*; + +import static sun.invoke.util.Wrapper.forPrimitiveType; +import static sun.invoke.util.Wrapper.forWrapperType; +import static sun.invoke.util.Wrapper.isWrapperType; /** - * Abstract implementation of a lambda metafactory which provides parameter unrolling and input validation. + * Abstract implementation of a lambda metafactory which provides parameter + * unrolling and input validation. * * @see LambdaMetafactory */ /* package */ abstract class AbstractValidatingLambdaMetafactory { /* - * For context, the comments for the following fields are marked in quotes with their values, given this program: + * For context, the comments for the following fields are marked in quotes + * with their values, given this program: * interface II<T> { Object foo(T x); } * interface JJ<R extends Number> extends II<R> { } * class CC { String impl(int i) { return "impl:"+i; }} @@ -54,9 +53,7 @@ final Class<?> targetClass; // The class calling the meta-factory via invokedynamic "class X" final MethodType invokedType; // The type of the invoked method "(CC)II" final Class<?> samBase; // The type of the returned instance "interface JJ" - final MethodHandle samMethod; // Raw method handle for the functional interface method - final MethodHandleInfo samInfo; // Info about the SAM method handle "MethodHandleInfo[9 II.foo(Object)Object]" - final Class<?> samClass; // Interface containing the SAM method "interface II" + final String samMethodName; // Name of the SAM method "foo" final MethodType samMethodType; // Type of the SAM method "(Object)Object" final MethodHandle implMethod; // Raw method handle for the implementation method final MethodHandleInfo implInfo; // Info about the implementation method handle "MethodHandleInfo[5 CC.impl(int)String]" @@ -67,44 +64,64 @@ final MethodType instantiatedMethodType; // Instantiated erased functional interface method type "(Integer)Object" final boolean isSerializable; // Should the returned instance be serializable final Class<?>[] markerInterfaces; // Additional marker interfaces to be implemented + final MethodType[] additionalBridges; // Signatures of additional methods to bridge /** * Meta-factory constructor. * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param samMethod The primary method in the functional interface to which the lambda or method reference is - * being converted, represented as a method handle. - * @param implMethod The implementation method which should be called (with suitable adaptation of argument - * types, return types, and adjustment for captured arguments) when methods of the resulting - * functional interface instance are invoked. - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. In + * the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param samMethodName Name of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a String. + * @param samMethodType Type of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a MethodType. + * @param implMethod The implementation method which should be called + * (with suitable adaptation of argument types, return + * types, and adjustment for captured arguments) when + * methods of the resulting functional interface instance + * are invoked. + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables are + * substituted with their instantiation from + * the capture site + * @param isSerializable Should the lambda be made serializable? If set, + * either the target type or one of the additional SAM + * types must extend {@code Serializable}. + * @param markerInterfaces Additional interfaces which the lambda object + * should implement. + * @param additionalBridges Method types for additional signatures to be + * bridged to the implementation method * @throws ReflectiveOperationException - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller, MethodType invokedType, - MethodHandle samMethod, + String samMethodName, + MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, - int flags, - Class<?>[] markerInterfaces) + boolean isSerializable, + Class<?>[] markerInterfaces, + MethodType[] additionalBridges) throws ReflectiveOperationException, LambdaConversionException { this.targetClass = caller.lookupClass(); this.invokedType = invokedType; this.samBase = invokedType.returnType(); - this.samMethod = samMethod; - this.samInfo = new MethodHandleInfo(samMethod); - this.samClass = samInfo.getDeclaringClass(); - this.samMethodType = samInfo.getMethodType(); + this.samMethodName = samMethodName; + this.samMethodType = samMethodType; this.implMethod = implMethod; this.implInfo = new MethodHandleInfo(implMethod); @@ -118,32 +135,24 @@ implKind == MethodHandleInfo.REF_invokeInterface; this.implDefiningClass = implInfo.getDeclaringClass(); this.implMethodType = implInfo.getMethodType(); + this.instantiatedMethodType = instantiatedMethodType; + this.isSerializable = isSerializable; + this.markerInterfaces = markerInterfaces; + this.additionalBridges = additionalBridges; - this.instantiatedMethodType = instantiatedMethodType; - - if (!samClass.isInterface()) { + if (!samBase.isInterface()) { throw new LambdaConversionException(String.format( "Functional interface %s is not an interface", - samClass.getName())); + samBase.getName())); } - boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(samBase); for (Class<?> c : markerInterfaces) { if (!c.isInterface()) { throw new LambdaConversionException(String.format( "Marker interface %s is not an interface", c.getName())); } - foundSerializableSupertype |= Serializable.class.isAssignableFrom(c); } - this.isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0) - || foundSerializableSupertype; - - if (isSerializable && !foundSerializableSupertype) { - markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1); - markerInterfaces[markerInterfaces.length-1] = Serializable.class; - } - this.markerInterfaces = markerInterfaces; } /** @@ -153,20 +162,14 @@ * functional interface * @throws ReflectiveOperationException */ - abstract CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException; + abstract CallSite buildCallSite() + throws ReflectiveOperationException, LambdaConversionException; /** * Check the meta-factory arguments for errors * @throws LambdaConversionException if there are improper conversions */ void validateMetafactoryArgs() throws LambdaConversionException { - // Check target type is a subtype of class where SAM method is defined - if (!samClass.isAssignableFrom(samBase)) { - throw new LambdaConversionException( - String.format("Invalid target type %s for lambda conversion; not a subtype of functional interface %s", - samBase.getName(), samClass.getName())); - } - switch (implKind) { case MethodHandleInfo.REF_invokeInterface: case MethodHandleInfo.REF_invokeVirtual: @@ -265,9 +268,9 @@ } /** - * Check type adaptability - * @param fromType - * @param toType + * Check type adaptability for parameter types. + * @param fromType Type to convert from + * @param toType Type to convert to * @param strict If true, do strict checks, else allow that fromType may be parameterized * @return True if 'fromType' can be passed to an argument of 'toType' */ @@ -299,15 +302,14 @@ } } else { // both are reference types: fromType should be a superclass of toType. - return strict? toType.isAssignableFrom(fromType) : true; + return !strict || toType.isAssignableFrom(fromType); } } } /** - * Check type adaptability for return types -- special handling of void type) and parameterized fromType - * @param fromType - * @param toType + * Check type adaptability for return types -- + * special handling of void type) and parameterized fromType * @return True if 'fromType' can be converted to 'toType' */ private boolean isAdaptableToAsReturn(Class<?> fromType, Class<?> toType) { @@ -338,89 +340,4 @@ } ***********************/ - /** - * Find the functional interface method and corresponding abstract methods - * which should be bridged. The functional interface method and those to be - * bridged will have the same name and number of parameters. Check for - * matching default methods (non-abstract), the VM will create bridges for - * default methods; We don't have enough readily available type information - * to distinguish between where the functional interface method should be - * bridged and where the default method should be bridged; This situation is - * flagged. - */ - class MethodAnalyzer { - private final Method[] methods = samBase.getMethods(); - - private Method samMethod = null; - private final List<Method> methodsToBridge = new ArrayList<>(methods.length); - private boolean conflictFoundBetweenDefaultAndBridge = false; - - MethodAnalyzer() { - String samMethodName = samInfo.getName(); - Class<?>[] samParamTypes = samMethodType.parameterArray(); - int samParamLength = samParamTypes.length; - Class<?> samReturnType = samMethodType.returnType(); - Class<?> objectClass = Object.class; - List<Method> defaultMethods = new ArrayList<>(methods.length); - - for (Method m : methods) { - if (m.getName().equals(samMethodName) && m.getDeclaringClass() != objectClass) { - Class<?>[] mParamTypes = m.getParameterTypes(); - if (mParamTypes.length == samParamLength) { - // Method matches name and parameter length -- and is not Object - if (Modifier.isAbstract(m.getModifiers())) { - // Method is abstract - if (m.getReturnType().equals(samReturnType) - && Arrays.equals(mParamTypes, samParamTypes)) { - // Exact match, this is the SAM method signature - samMethod = m; - } else if (!hasMatchingBridgeSignature(m)) { - // Record bridges, exclude methods with duplicate signatures - methodsToBridge.add(m); - } - } else { - // Record default methods for conflict testing - defaultMethods.add(m); - } - } - } - } - for (Method dm : defaultMethods) { - if (hasMatchingBridgeSignature(dm)) { - conflictFoundBetweenDefaultAndBridge = true; - break; - } - } - } - - Method getSamMethod() { - return samMethod; - } - - List<Method> getMethodsToBridge() { - return methodsToBridge; - } - - boolean conflictFoundBetweenDefaultAndBridge() { - return conflictFoundBetweenDefaultAndBridge; - } - - /** - * Search the list of previously found bridge methods to determine if there is a method with the same signature - * (return and parameter types) as the specified method. - * - * @param m The method to match - * @return True if the method was found, False otherwise - */ - private boolean hasMatchingBridgeSignature(Method m) { - Class<?>[] ptypes = m.getParameterTypes(); - Class<?> rtype = m.getReturnType(); - for (Method md : methodsToBridge) { - if (md.getReturnType().equals(rtype) && Arrays.equals(ptypes, md.getParameterTypes())) { - return true; - } - } - return false; - } - } }
--- a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,26 @@ package java.lang.invoke; +import jdk.internal.org.objectweb.asm.*; +import sun.misc.Unsafe; + import java.lang.reflect.Constructor; -import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.concurrent.atomic.AtomicInteger; -import jdk.internal.org.objectweb.asm.*; + import static jdk.internal.org.objectweb.asm.Opcodes.*; -import sun.misc.Unsafe; -import java.security.AccessController; -import java.security.PrivilegedAction; /** - * Lambda metafactory implementation which dynamically creates an inner-class-like class per lambda callsite. + * Lambda metafactory implementation which dynamically creates an + * inner-class-like class per lambda callsite. * * @see LambdaMetafactory */ /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + private static final int CLASSFILE_VERSION = 51; private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE); private static final String NAME_MAGIC_ACCESSOR_IMPL = "java/lang/invoke/MagicLambdaImpl"; @@ -54,7 +58,7 @@ private static final String DESCR_CTOR_SERIALIZED_LAMBDA = MethodType.methodType(void.class, Class.class, - int.class, String.class, String.class, String.class, + String.class, String.class, String.class, int.class, String.class, String.class, String.class, String.class, Object[].class).toMethodDescriptorString(); @@ -77,36 +81,56 @@ private final Type[] instantiatedArgumentTypes; // ASM types for the functional interface arguments /** - * General meta-factory constructor, standard cases and allowing for uncommon options such as serialization. + * General meta-factory constructor, supporting both standard cases and + * allowing for uncommon options such as serialization or bridging. * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param samMethod The primary method in the functional interface to which the lambda or method reference is - * being converted, represented as a method handle. - * @param implMethod The implementation method which should be called (with suitable adaptation of argument - * types, return types, and adjustment for captured arguments) when methods of the resulting - * functional interface instance are invoked. - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site - * @param flags A bitmask containing flags that may influence the translation of this lambda expression. Defined - * fields include FLAG_SERIALIZABLE. - * @param markerInterfaces Additional interfaces which the lambda object should implement. + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. In + * the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param samMethodName Name of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a String. + * @param samMethodType Type of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a MethodType. + * @param implMethod The implementation method which should be called (with + * suitable adaptation of argument types, return types, + * and adjustment for captured arguments) when methods of + * the resulting functional interface instance are invoked. + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables are + * substituted with their instantiation from + * the capture site + * @param isSerializable Should the lambda be made serializable? If set, + * either the target type or one of the additional SAM + * types must extend {@code Serializable}. + * @param markerInterfaces Additional interfaces which the lambda object + * should implement. + * @param additionalBridges Method types for additional signatures to be + * bridged to the implementation method * @throws ReflectiveOperationException - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ public InnerClassLambdaMetafactory(MethodHandles.Lookup caller, MethodType invokedType, - MethodHandle samMethod, + String samMethodName, + MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, - int flags, - Class<?>[] markerInterfaces) + boolean isSerializable, + Class<?>[] markerInterfaces, + MethodType[] additionalBridges) throws ReflectiveOperationException, LambdaConversionException { - super(caller, invokedType, samMethod, implMethod, instantiatedMethodType, flags, markerInterfaces); + super(caller, invokedType, samMethodName, samMethodType, + implMethod, instantiatedMethodType, + isSerializable, markerInterfaces, additionalBridges); implMethodClassName = implDefiningClass.getName().replace('.', '/'); implMethodName = implInfo.getName(); implMethodDesc = implMethodType.toMethodDescriptorString(); @@ -124,7 +148,8 @@ for (int i = 0; i < argTypes.length; i++) { argNames[i] = "arg$" + (i + 1); } - instantiatedArgumentTypes = Type.getArgumentTypes(instantiatedMethodType.toMethodDescriptorString()); + instantiatedArgumentTypes = Type.getArgumentTypes( + instantiatedMethodType.toMethodDescriptorString()); } /** @@ -136,7 +161,8 @@ * @return a CallSite, which, when invoked, will return an instance of the * functional interface * @throws ReflectiveOperationException - * @throws LambdaConversionException If properly formed functional interface is not found + * @throws LambdaConversionException If properly formed functional interface + * is not found */ @Override CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException { @@ -167,8 +193,8 @@ } else { return new ConstantCallSite( MethodHandles.Lookup.IMPL_LOOKUP - .findConstructor(innerClass, constructorType) - .asType(constructorType.changeReturnType(samBase))); + .findConstructor(innerClass, constructorType) + .asType(constructorType.changeReturnType(samBase))); } } @@ -176,13 +202,20 @@ * Generate a class file which implements the functional * interface, define and return the class. * + * @implNote The class that is generated does not include signature + * information for exceptions that may be present on the SAM method. + * This is to reduce classfile size, and is harmless as checked exceptions + * are erased anyway, no one will ever compile against this classfile, + * and we make no guarantees about the reflective properties of lambda + * objects. + * * @return a Class which implements the functional interface - * @throws LambdaConversionException If properly formed functional interface is not found + * @throws LambdaConversionException If properly formed functional interface + * is not found */ private Class<?> spinInnerClass() throws LambdaConversionException { - String samName = samBase.getName().replace('.', '/'); String[] interfaces = new String[markerInterfaces.length + 1]; - interfaces[0] = samName; + interfaces[0] = samBase.getName().replace('.', '/'); for (int i=0; i<markerInterfaces.length; i++) { interfaces[i+1] = markerInterfaces[i].getName().replace('.', '/'); } @@ -192,35 +225,33 @@ // Generate final fields to be filled in by constructor for (int i = 0; i < argTypes.length; i++) { - FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, argNames[i], argTypes[i].getDescriptor(), + FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, + argNames[i], + argTypes[i].getDescriptor(), null, null); fv.visitEnd(); } generateConstructor(); - MethodAnalyzer ma = new MethodAnalyzer(); - // Forward the SAM method - if (ma.getSamMethod() == null) { - throw new LambdaConversionException(String.format("Functional interface method not found: %s", samMethodType)); - } else { - generateForwardingMethod(ma.getSamMethod(), false); - } + String methodDescriptor = samMethodType.toMethodDescriptorString(); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName, + methodDescriptor, null, null); + new ForwardingMethodGenerator(mv).generate(methodDescriptor); // Forward the bridges - // @@@ The commented-out code is temporary, pending the VM's ability to bridge all methods on request - // @@@ Once the VM can do fail-over, uncomment the !ma.wasDefaultMethodFound() test, and emit the appropriate - // @@@ classfile attribute to request custom bridging. See 8002092. - if (!ma.getMethodsToBridge().isEmpty() /* && !ma.conflictFoundBetweenDefaultAndBridge() */ ) { - for (Method m : ma.getMethodsToBridge()) { - generateForwardingMethod(m, true); + if (additionalBridges != null) { + for (MethodType mt : additionalBridges) { + methodDescriptor = mt.toMethodDescriptorString(); + mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName, + methodDescriptor, null, null); + new ForwardingMethodGenerator(mv).generate(methodDescriptor); } } - if (isSerializable) { + if (isSerializable) generateWriteReplace(); - } cw.visitEnd(); @@ -229,11 +260,14 @@ final byte[] classBytes = cw.toByteArray(); /*** Uncomment to dump the generated file - System.out.printf("Loaded: %s (%d bytes) %n", lambdaClassName, classBytes.length); - try (FileOutputStream fos = new FileOutputStream(lambdaClassName.replace('/', '.') + ".class")) { + System.out.printf("Loaded: %s (%d bytes) %n", lambdaClassName, + classBytes.length); + try (FileOutputStream fos = new FileOutputStream(lambdaClassName + .replace('/', '.') + ".class")) { fos.write(classBytes); } catch (IOException ex) { - PlatformLogger.getLogger(InnerClassLambdaMetafactory.class.getName()).severe(ex.getMessage(), ex); + PlatformLogger.getLogger(InnerClassLambdaMetafactory.class + .getName()).severe(ex.getMessage(), ex); } ***/ @@ -249,8 +283,9 @@ } ); - return (Class<?>) Unsafe.getUnsafe().defineClass(lambdaClassName, classBytes, 0, classBytes.length, - loader, pd); + return UNSAFE.defineClass(lambdaClassName, + classBytes, 0, classBytes.length, + loader, pd); } /** @@ -258,19 +293,23 @@ */ private void generateConstructor() { // Generate constructor - MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR, constructorDesc, null, null); + MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR, + constructorDesc, null, null); ctor.visitCode(); ctor.visitVarInsn(ALOAD, 0); - ctor.visitMethodInsn(INVOKESPECIAL, NAME_MAGIC_ACCESSOR_IMPL, NAME_CTOR, METHOD_DESCRIPTOR_VOID); + ctor.visitMethodInsn(INVOKESPECIAL, NAME_MAGIC_ACCESSOR_IMPL, NAME_CTOR, + METHOD_DESCRIPTOR_VOID); int lvIndex = 0; for (int i = 0; i < argTypes.length; i++) { ctor.visitVarInsn(ALOAD, 0); ctor.visitVarInsn(argTypes[i].getOpcode(ILOAD), lvIndex + 1); lvIndex += argTypes[i].getSize(); - ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor()); + ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], + argTypes[i].getDescriptor()); } ctor.visitInsn(RETURN); - ctor.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + ctor.visitMaxs(-1, -1); ctor.visitEnd(); } @@ -279,18 +318,18 @@ */ private void generateWriteReplace() { TypeConvertingMethodAdapter mv - = new TypeConvertingMethodAdapter(cw.visitMethod(ACC_PRIVATE + ACC_FINAL, - NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE, - null, null)); + = new TypeConvertingMethodAdapter( + cw.visitMethod(ACC_PRIVATE + ACC_FINAL, + NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE, + null, null)); mv.visitCode(); mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA); - mv.visitInsn(DUP);; + mv.visitInsn(DUP); mv.visitLdcInsn(Type.getType(targetClass)); - mv.visitLdcInsn(samInfo.getReferenceKind()); mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/')); - mv.visitLdcInsn(samInfo.getName()); - mv.visitLdcInsn(samInfo.getMethodType().toMethodDescriptorString()); + mv.visitLdcInsn(samMethodName); + mv.visitLdcInsn(samMethodType.toMethodDescriptorString()); mv.visitLdcInsn(implInfo.getReferenceKind()); mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/')); mv.visitLdcInsn(implInfo.getName()); @@ -303,36 +342,20 @@ mv.visitInsn(DUP); mv.iconst(i); mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor()); + mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], + argTypes[i].getDescriptor()); mv.boxIfTypePrimitive(argTypes[i]); mv.visitInsn(AASTORE); } mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR, DESCR_CTOR_SERIALIZED_LAMBDA); mv.visitInsn(ARETURN); - mv.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + mv.visitMaxs(-1, -1); mv.visitEnd(); } /** - * Generate a method which calls the lambda implementation method, - * converting arguments, as needed. - * @param m The method whose signature should be generated - * @param isBridge True if this methods should be flagged as a bridge - */ - private void generateForwardingMethod(Method m, boolean isBridge) { - Class<?>[] exceptionTypes = m.getExceptionTypes(); - String[] exceptionNames = new String[exceptionTypes.length]; - for (int i = 0; i < exceptionTypes.length; i++) { - exceptionNames[i] = exceptionTypes[i].getName().replace('.', '/'); - } - String methodDescriptor = Type.getMethodDescriptor(m); - int access = isBridge? ACC_PUBLIC | ACC_BRIDGE : ACC_PUBLIC; - MethodVisitor mv = cw.visitMethod(access, m.getName(), methodDescriptor, null, exceptionNames); - new ForwardingMethodGenerator(mv).generate(m); - } - - /** * This class generates a method body which calls the lambda implementation * method, converting arguments, as needed. */ @@ -342,36 +365,39 @@ super(mv); } - void generate(Method m) throws InternalError { + void generate(String methodDescriptor) { visitCode(); if (implKind == MethodHandleInfo.REF_newInvokeSpecial) { visitTypeInsn(NEW, implMethodClassName); - visitInsn(DUP);; + visitInsn(DUP); } for (int i = 0; i < argTypes.length; i++) { visitVarInsn(ALOAD, 0); - visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor()); + visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], + argTypes[i].getDescriptor()); } - convertArgumentTypes(Type.getArgumentTypes(m)); + convertArgumentTypes(Type.getArgumentTypes(methodDescriptor)); // Invoke the method we want to forward to visitMethodInsn(invocationOpcode(), implMethodClassName, implMethodName, implMethodDesc); // Convert the return value (if any) and return it - // Note: if adapting from non-void to void, the 'return' instruction will pop the unneeded result - Type samReturnType = Type.getReturnType(m); + // Note: if adapting from non-void to void, the 'return' + // instruction will pop the unneeded result + Type samReturnType = Type.getReturnType(methodDescriptor); convertType(implMethodReturnType, samReturnType, samReturnType); visitInsn(samReturnType.getOpcode(Opcodes.IRETURN)); - - visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + // Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored + visitMaxs(-1, -1); visitEnd(); } private void convertArgumentTypes(Type[] samArgumentTypes) { int lvIndex = 0; - boolean samIncludesReceiver = implIsInstanceMethod && argTypes.length == 0; + boolean samIncludesReceiver = implIsInstanceMethod && + argTypes.length == 0; int samReceiverLength = samIncludesReceiver ? 1 : 0; if (samIncludesReceiver) { // push receiver @@ -395,7 +421,9 @@ } private void convertType(Type argType, Type targetType, Type functionalType) { - convertType(argType.getDescriptor(), targetType.getDescriptor(), functionalType.getDescriptor()); + convertType(argType.getDescriptor(), + targetType.getDescriptor(), + functionalType.getDescriptor()); } private int invocationOpcode() throws InternalError {
--- a/src/share/classes/java/lang/invoke/LambdaConversionException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/invoke/LambdaConversionException.java Wed Jul 24 08:22:32 2013 -0300 @@ -29,6 +29,8 @@ * LambdaConversionException */ public class LambdaConversionException extends Exception { + private static final long serialVersionUID = 292L + 8L; + /** * Constructs a {@code LambdaConversionException}. */
--- a/src/share/classes/java/lang/invoke/LambdaMetafactory.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/invoke/LambdaMetafactory.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,6 +25,9 @@ package java.lang.invoke; +import java.io.Serializable; +import java.util.Arrays; + /** * <p>Bootstrap methods for converting lambda expressions and method references to functional interface objects.</p> * @@ -44,16 +47,11 @@ * * <p>When parameterized types are used, the instantiated type of the functional interface method may be different * from that in the functional interface. For example, consider - * <code>interface I<T> { int m(T x); }</code> if this functional interface type is used in a lambda - * <code>I<Byte> v = ...</code>, we need both the actual functional interface method which has the signature - * <code>(Object)int</code> and the erased instantiated type of the functional interface method (or simply + * {@code interface I<T> { int m(T x); }} if this functional interface type is used in a lambda + * {@code I<Byte>; v = ...}, we need both the actual functional interface method which has the signature + * {@code (Object)int} and the erased instantiated type of the functional interface method (or simply * <I>instantiated method type</I>), which has signature - * <code>(Byte)int</code>. - * - * <p>While functional interfaces only have a single abstract method from the language perspective (concrete - * methods in Object are and default methods may be present), at the bytecode level they may actually have multiple - * methods because of the need for bridge methods. Invoking any of these methods on the lambda object will result - * in invoking the implementation method. + * {@code (Byte)int}. * * <p>The argument list of the implementation method and the argument list of the functional interface method(s) * may differ in several ways. The implementation methods may have additional arguments to accommodate arguments @@ -137,108 +135,147 @@ * </tr> * </table> * - * The default bootstrap ({@link #metaFactory}) represents the common cases and uses an optimized protocol. - * Alternate bootstraps (e.g., {@link #altMetaFactory}) exist to support uncommon cases such as serialization + * The default bootstrap ({@link #metafactory}) represents the common cases and uses an optimized protocol. + * Alternate bootstraps (e.g., {@link #altMetafactory}) exist to support uncommon cases such as serialization * or additional marker superinterfaces. * */ public class LambdaMetafactory { - /** Flag for alternate metafactories indicating the lambda object is must to be serializable */ + /** Flag for alternate metafactories indicating the lambda object is + * must to be serializable */ public static final int FLAG_SERIALIZABLE = 1 << 0; /** - * Flag for alternate metafactories indicating the lambda object implements other marker interfaces + * Flag for alternate metafactories indicating the lambda object implements + * other marker interfaces * besides Serializable */ public static final int FLAG_MARKERS = 1 << 1; + /** + * Flag for alternate metafactories indicating the lambda object requires + * additional bridge methods + */ + public static final int FLAG_BRIDGES = 1 << 2; + private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0]; + private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0]; /** - * Standard meta-factory for conversion of lambda expressions or method references to functional interfaces. + * Standard meta-factory for conversion of lambda expressions or method + * references to functional interfaces. * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site. - * Currently unused. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param samMethod The primary method in the functional interface to which the lambda or method reference is - * being converted, represented as a method handle. - * @param implMethod The implementation method which should be called (with suitable adaptation of argument - * types, return types, and adjustment for captured arguments) when methods of the resulting - * functional interface instance are invoked. - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site - * @return a CallSite, which, when invoked, will return an instance of the functional interface - * @throws ReflectiveOperationException if the caller is not able to reconstruct one of the method handles - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedName Stacked automatically by VM; the name of the invoked + * method as it appears at the call site. + * Used as the name of the functional interface method + * to which the lambda or method reference is being + * converted. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. + * In the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param samMethodType MethodType of the method in the functional interface + * to which the lambda or method reference is being + * converted, represented as a MethodType. + * @param implMethod The implementation method which should be called + * (with suitable adaptation of argument types, return + * types, and adjustment for captured arguments) when + * methods of the resulting functional interface instance + * are invoked. + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables + * are substituted with their instantiation + * from the capture site + * @return a CallSite, which, when invoked, will return an instance of the + * functional interface + * @throws ReflectiveOperationException if the caller is not able to + * reconstruct one of the method handles + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ - public static CallSite metaFactory(MethodHandles.Lookup caller, + public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, - MethodHandle samMethod, + MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType) throws ReflectiveOperationException, LambdaConversionException { AbstractValidatingLambdaMetafactory mf; - mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType, - 0, EMPTY_CLASS_ARRAY); + mf = new InnerClassLambdaMetafactory(caller, invokedType, + invokedName, samMethodType, + implMethod, instantiatedMethodType, + false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY); mf.validateMetafactoryArgs(); return mf.buildCallSite(); } /** - * Alternate meta-factory for conversion of lambda expressions or method references to functional interfaces, - * which supports serialization and other uncommon options. + * Alternate meta-factory for conversion of lambda expressions or method + * references to functional interfaces, which supports serialization and + * other uncommon options. * * The declared argument list for this method is: * - * CallSite altMetaFactory(MethodHandles.Lookup caller, + * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, * Object... args) * * but it behaves as if the argument list is: * - * CallSite altMetaFactory(MethodHandles.Lookup caller, + * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, - * MethodHandle samMethod + * MethodType samMethodType * MethodHandle implMethod, * MethodType instantiatedMethodType, * int flags, * int markerInterfaceCount, // IF flags has MARKERS set * Class... markerInterfaces // IF flags has MARKERS set + * int bridgeCount, // IF flags has BRIDGES set + * MethodType... bridges // IF flags has BRIDGES set * ) * * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site. - * Currently unused. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes thefu - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param args argument to pass, flags, marker interface count, and marker interfaces as described above - * @return a CallSite, which, when invoked, will return an instance of the functional interface - * @throws ReflectiveOperationException if the caller is not able to reconstruct one of the method handles - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedName Stacked automatically by VM; the name of the invoked + * method as it appears at the call site. + * Used as the name of the functional interface method + * to which the lambda or method reference is being + * converted. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. + * In the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param args flags and optional arguments, as described above + * @return a CallSite, which, when invoked, will return an instance of the + * functional interface + * @throws ReflectiveOperationException if the caller is not able to + * reconstruct one of the method handles + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ - public static CallSite altMetaFactory(MethodHandles.Lookup caller, + public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws ReflectiveOperationException, LambdaConversionException { - MethodHandle samMethod = (MethodHandle)args[0]; + MethodType samMethodType = (MethodType)args[0]; MethodHandle implMethod = (MethodHandle)args[1]; MethodType instantiatedMethodType = (MethodType)args[2]; int flags = (Integer) args[3]; Class<?>[] markerInterfaces; + MethodType[] bridges; int argIndex = 4; if ((flags & FLAG_MARKERS) != 0) { int markerCount = (Integer) args[argIndex++]; @@ -248,9 +285,33 @@ } else markerInterfaces = EMPTY_CLASS_ARRAY; - AbstractValidatingLambdaMetafactory mf; - mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType, - flags, markerInterfaces); + if ((flags & FLAG_BRIDGES) != 0) { + int bridgeCount = (Integer) args[argIndex++]; + bridges = new MethodType[bridgeCount]; + System.arraycopy(args, argIndex, bridges, 0, bridgeCount); + argIndex += bridgeCount; + } + else + bridges = EMPTY_MT_ARRAY; + + boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType()); + for (Class<?> c : markerInterfaces) + foundSerializableSupertype |= Serializable.class.isAssignableFrom(c); + boolean isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0) + || foundSerializableSupertype; + + if (isSerializable && !foundSerializableSupertype) { + markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1); + markerInterfaces[markerInterfaces.length-1] = Serializable.class; + } + + AbstractValidatingLambdaMetafactory mf + = new InnerClassLambdaMetafactory(caller, invokedType, + invokedName, samMethodType, + implMethod, + instantiatedMethodType, + isSerializable, + markerInterfaces, bridges); mf.validateMetafactoryArgs(); return mf.buildCallSite(); }
--- a/src/share/classes/java/lang/invoke/SerializedLambda.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/invoke/SerializedLambda.java Wed Jul 24 08:22:32 2013 -0300 @@ -44,7 +44,6 @@ private final String functionalInterfaceClass; private final String functionalInterfaceMethodName; private final String functionalInterfaceMethodSignature; - private final int functionalInterfaceMethodKind; private final String implClass; private final String implMethodName; private final String implMethodSignature; @@ -53,28 +52,32 @@ private final Object[] capturedArgs; /** - * Create a {@code SerializedLambda} from the low-level information present at the lambda factory site. + * Create a {@code SerializedLambda} from the low-level information present + * at the lambda factory site. * * @param capturingClass The class in which the lambda expression appears - * @param functionalInterfaceMethodKind Method handle kind (see {@link MethodHandleInfo}) for the - * functional interface method handle present at the lambda factory site - * @param functionalInterfaceClass Name, in slash-delimited form, for the functional interface class present at the - * lambda factory site - * @param functionalInterfaceMethodName Name of the primary method for the functional interface present at the + * @param functionalInterfaceClass Name, in slash-delimited form, of static + * type of the returned lambda object + * @param functionalInterfaceMethodName Name of the functional interface + * method for the present at the * lambda factory site - * @param functionalInterfaceMethodSignature Signature of the primary method for the functional interface present - * at the lambda factory site + * @param functionalInterfaceMethodSignature Signature of the functional + * interface method present at + * the lambda factory site * @param implMethodKind Method handle kind for the implementation method - * @param implClass Name, in slash-delimited form, for the class holding the implementation method + * @param implClass Name, in slash-delimited form, for the class holding + * the implementation method * @param implMethodName Name of the implementation method * @param implMethodSignature Signature of the implementation method - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site - * @param capturedArgs The dynamic arguments to the lambda factory site, which represent variables captured by + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables + * are substituted with their instantiation + * from the capture site + * @param capturedArgs The dynamic arguments to the lambda factory site, + * which represent variables captured by * the lambda */ public SerializedLambda(Class<?> capturingClass, - int functionalInterfaceMethodKind, String functionalInterfaceClass, String functionalInterfaceMethodName, String functionalInterfaceMethodSignature, @@ -85,7 +88,6 @@ String instantiatedMethodType, Object[] capturedArgs) { this.capturingClass = capturingClass; - this.functionalInterfaceMethodKind = functionalInterfaceMethodKind; this.functionalInterfaceClass = functionalInterfaceClass; this.functionalInterfaceMethodName = functionalInterfaceMethodName; this.functionalInterfaceMethodSignature = functionalInterfaceMethodSignature; @@ -106,10 +108,10 @@ } /** - * Get the name of the functional interface class to which this + * Get the name of the invoked type to which this * lambda has been converted - * @return the name of the functional interface this lambda has - * been converted to + * @return the name of the functional interface class to which + * this lambda has been converted */ public String getFunctionalInterfaceClass() { return functionalInterfaceClass; @@ -135,17 +137,6 @@ } /** - * Get the method handle kind (see {@link MethodHandleInfo}) of - * the primary method for the functional interface to which this - * lambda has been converted - * @return the method handle kind of the primary method of - * functional interface - */ - public int getFunctionalInterfaceMethodKind() { - return functionalInterfaceMethodKind; - } - - /** * Get the name of the class containing the implementation * method. * @return the name of the class containing the implementation @@ -234,11 +225,17 @@ @Override public String toString() { - return String.format("SerializedLambda[capturingClass=%s, functionalInterfaceMethod=%s %s.%s:%s, " + - "implementation=%s %s.%s:%s, instantiatedMethodType=%s, numCaptured=%d]", - capturingClass, MethodHandleInfo.getReferenceKindString(functionalInterfaceMethodKind), - functionalInterfaceClass, functionalInterfaceMethodName, functionalInterfaceMethodSignature, - MethodHandleInfo.getReferenceKindString(implMethodKind), implClass, implMethodName, - implMethodSignature, instantiatedMethodType, capturedArgs.length); + String implKind=MethodHandleInfo.getReferenceKindString(implMethodKind); + return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " + + "%s=%s %s.%s:%s, %s=%s, %s=%d]", + "capturingClass", capturingClass, + "functionalInterfaceMethod", functionalInterfaceClass, + functionalInterfaceMethodName, + functionalInterfaceMethodSignature, + "implementation", + implKind, + implClass, implMethodName, implMethodSignature, + "instantiatedMethodType", instantiatedMethodType, + "numCaptured", capturedArgs.length); } }
--- a/src/share/classes/java/lang/reflect/Parameter.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/lang/reflect/Parameter.java Wed Jul 24 08:22:32 2013 -0300 @@ -162,7 +162,7 @@ /** * Returns the name of the parameter. If the parameter's name is - * {@linkplain isNamePresent() present}, then this method returns + * {@linkplain #isNamePresent() present}, then this method returns * the name provided by the class file. Otherwise, this method * synthesizes a name of the form argN, where N is the index of * the parameter in the descriptor of the method which declares
--- a/src/share/classes/java/nio/channels/package-info.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/nio/channels/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -31,7 +31,7 @@ * <a name="channels"></a> * * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists channels and their descriptions"> - * <tr><th><p align="left">Channels</p></th><th><p align="left">Description</p></th></tr> + * <tr><th align="left">Channels</th><th align="left">Description</th></tr> * <tr><td valign=top><tt><i>{@link java.nio.channels.Channel}</i></tt></td> * <td>A nexus for I/O operations</td></tr> * <tr><td valign=top><tt> <i>{@link java.nio.channels.ReadableByteChannel}</i></tt></td> @@ -110,7 +110,7 @@ * write them to a given writable byte channel. * * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists file channels and their descriptions"> - * <tr><th><p align="left">File channels</p></th><th><p align="left">Description</p></th></tr> + * <tr><th align="left">File channels</th><th align="left">Description</th></tr> * <tr><td valign=top><tt>{@link java.nio.channels.FileChannel}</tt></td> * <td>Reads, writes, maps, and manipulates files</td></tr> * <tr><td valign=top><tt>{@link java.nio.channels.FileLock}</tt></td> @@ -138,7 +138,7 @@ * * <a name="multiplex"></a> * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists multiplexed, non-blocking channels and their descriptions"> - * <tr><th><p align="left">Multiplexed, non-blocking I/O</p></th><th><p align="left">Description</p></th></tr> + * <tr><th align="left">Multiplexed, non-blocking I/O</th><th align="left"><p>Description</th></tr> * <tr><td valign=top><tt>{@link java.nio.channels.SelectableChannel}</tt></td> * <td>A channel that can be multiplexed</td></tr> * <tr><td valign=top><tt> {@link java.nio.channels.DatagramChannel}</tt></td> @@ -225,7 +225,7 @@ * <a name="async"></a> * * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists asynchronous channels and their descriptions"> - * <tr><th><p align="left">Asynchronous I/O</p></th><th><p align="left">Description</p></th></tr> + * <tr><th align="left">Asynchronous I/O</th><th align="left">Description</th></tr> * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousFileChannel}</tt></td> * <td>An asynchronous channel for reading, writing, and manipulating a file</td></tr> * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousSocketChannel}</tt></td>
--- a/src/share/classes/java/nio/charset/Charset.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/nio/charset/Charset.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -65,7 +65,7 @@ * concurrent threads. * * - * <a name="names"><a name="charenc"> + * <a name="names"></a><a name="charenc"></a> * <h2>Charset names</h2> * * <p> Charsets are named by strings composed of the following characters: @@ -111,21 +111,17 @@ * The aliases of a charset are returned by the {@link #aliases() aliases} * method. * - * <a name="hn"> - * - * <p> Some charsets have an <i>historical name</i> that is defined for - * compatibility with previous versions of the Java platform. A charset's + * <p><a name="hn">Some charsets have an <i>historical name</i> that is defined for + * compatibility with previous versions of the Java platform.</a> A charset's * historical name is either its canonical name or one of its aliases. The * historical name is returned by the <tt>getEncoding()</tt> methods of the * {@link java.io.InputStreamReader#getEncoding InputStreamReader} and {@link * java.io.OutputStreamWriter#getEncoding OutputStreamWriter} classes. * - * <a name="iana"> - * - * <p> If a charset listed in the <a + * <p><a name="iana">If a charset listed in the <a * href="http://www.iana.org/assignments/character-sets"><i>IANA Charset * Registry</i></a> is supported by an implementation of the Java platform then - * its canonical name must be the name listed in the registry. Many charsets + * its canonical name must be the name listed in the registry.</a> Many charsets * are given more than one name in the registry, in which case the registry * identifies one of the names as <i>MIME-preferred</i>. If a charset has more * than one registry name then its canonical name must be the MIME-preferred @@ -142,15 +138,15 @@ * * <h2>Standard charsets</h2> * - * <a name="standard"> + * * - * <p> Every implementation of the Java platform is required to support the - * following standard charsets. Consult the release documentation for your + * <p><a name="standard">Every implementation of the Java platform is required to support the + * following standard charsets.</a> Consult the release documentation for your * implementation to see if any other charsets are supported. The behavior * of such optional charsets may differ between implementations. * * <blockquote><table width="80%" summary="Description of standard charsets"> - * <tr><th><p align="left">Charset</p></th><th><p align="left">Description</p></th></tr> + * <tr><th align="left">Charset</th><th align="left">Description</th></tr> * <tr><td valign=top><tt>US-ASCII</tt></td> * <td>Seven-bit ASCII, a.k.a. <tt>ISO646-US</tt>, * a.k.a. the Basic Latin block of the Unicode character set</td></tr>
--- a/src/share/classes/java/nio/charset/MalformedInputException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/nio/charset/MalformedInputException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -42,14 +42,27 @@ private int inputLength; + /** + * Constructs an {@code MalformedInputException} with the given + * length. + * @param inputLength the length of the input + */ public MalformedInputException(int inputLength) { this.inputLength = inputLength; } + /** + * Returns the length of the input. + * @return the length of the input + */ public int getInputLength() { return inputLength; } + /** + * Returns the message. + * @return the message + */ public String getMessage() { return "Input length = " + inputLength; }
--- a/src/share/classes/java/nio/charset/UnmappableCharacterException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/nio/charset/UnmappableCharacterException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -42,14 +42,27 @@ private int inputLength; + /** + * Constructs an {@code UnmappableCharacterException} with the + * given length. + * @param inputLength the length of the input + */ public UnmappableCharacterException(int inputLength) { this.inputLength = inputLength; } + /** + * Returns the length of the input. + * @return the length of the input + */ public int getInputLength() { return inputLength; } + /** + * Returns the message. + * @return the message + */ public String getMessage() { return "Input length = " + inputLength; }
--- a/src/share/classes/java/nio/file/attribute/package-info.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/nio/file/attribute/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -27,7 +27,7 @@ * Interfaces and classes providing access to file and file system attributes. * * <blockquote><table cellspacing=1 cellpadding=0 summary="Attribute views"> - * <tr><th><p align="left">Attribute views</p></th><th><p align="left">Description</p></th></tr> + * <tr><th align="left">Attribute views</th><th align="left">Description</th></tr> * <tr><td valign=top><tt><i>{@link java.nio.file.attribute.AttributeView}</i></tt></td> * <td>Can read or update non-opaque values associated with objects in a file system</td></tr> * <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.FileAttributeView}</i></tt></td> @@ -38,7 +38,7 @@ * <td>Can read or update POSIX defined file attributes</td></tr> * <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.DosFileAttributeView} </i></tt></td> * <td>Can read or update FAT file attributes</td></tr> - * <tr><td valign=top><tt>  <i>{@link java.nio.file.attribute.FileOwnerAttributeView} </i></tt></td> + * <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.FileOwnerAttributeView} </i></tt></td> * <td>Can read or update the owner of a file</td></tr> * <tr><td valign=top><tt> <i>{@link java.nio.file.attribute.AclFileAttributeView} </i></tt></td> * <td>Can read or update Access Control Lists</td></tr> @@ -86,14 +86,14 @@ * * <ul> * - * <p><li> The {@link java.nio.file.attribute.UserPrincipal} and + * <li> The {@link java.nio.file.attribute.UserPrincipal} and * {@link java.nio.file.attribute.GroupPrincipal} interfaces represent an * identity or group identity. </li> * - * <p><li> The {@link java.nio.file.attribute.UserPrincipalLookupService} + * <li> The {@link java.nio.file.attribute.UserPrincipalLookupService} * interface defines methods to lookup user or group principals. </li> * - * <p><li> The {@link java.nio.file.attribute.FileAttribute} interface + * <li> The {@link java.nio.file.attribute.FileAttribute} interface * represents the value of an attribute for cases where the attribute value is * required to be set atomically when creating an object in the file system. </li> *
--- a/src/share/classes/java/nio/file/package-info.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/nio/file/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -33,8 +33,8 @@ * package is used by service provider implementors wishing to extend the * platform default provider, or to construct other provider implementations. </p> * - * <a name="links"><h3>Symbolic Links</h3></a> - * Many operating systems and file systems support for <em>symbolic links</em>. + * <h3><a name="links">Symbolic Links</a></h3> + * <p> Many operating systems and file systems support for <em>symbolic links</em>. * A symbolic link is a special file that serves as a reference to another file. * For the most part, symbolic links are transparent to applications and * operations on symbolic links are automatically redirected to the <em>target</em> @@ -45,8 +45,8 @@ * that are semantically close but support for these other types of links is * not included in this package. </p> * - * <a name="interop"><h3>Interoperability</h3></a> - * The {@link java.io.File} class defines the {@link java.io.File#toPath + * <h3><a name="interop">Interoperability</a></h3> + * <p> The {@link java.io.File} class defines the {@link java.io.File#toPath * toPath} method to construct a {@link java.nio.file.Path} by converting * the abstract path represented by the {@code java.io.File} object. The resulting * {@code Path} can be used to operate on the same file as the {@code File} @@ -55,7 +55,7 @@ * and {@code java.io.File} objects. </p> * * <h3>Visibility</h3> - * The view of the files and file system provided by classes in this package are + * <p> The view of the files and file system provided by classes in this package are * guaranteed to be consistent with other views provided by other instances in the * same Java virtual machine. The view may or may not, however, be consistent with * the view of the file system as seen by other concurrently running programs due @@ -65,8 +65,8 @@ * or on some other machine. The exact nature of any such inconsistencies are * system-dependent and are therefore unspecified. </p> * - * <a name="integrity"><h3>Synchronized I/O File Integrity</h3></a> - * The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link + * <h3><a name="integrity">Synchronized I/O File Integrity</a></h3> + * <p> The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link * java.nio.file.StandardOpenOption#DSYNC DSYNC} options are used when opening a file * to require that updates to the file are written synchronously to the underlying * storage device. In the case of the default provider, and the file resides on @@ -83,7 +83,7 @@ * specific. </p> * * <h3>General Exceptions</h3> - * Unless otherwise noted, passing a {@code null} argument to a constructor + * <p> Unless otherwise noted, passing a {@code null} argument to a constructor * or method of any class or interface in this package will cause a {@link * java.lang.NullPointerException NullPointerException} to be thrown. Additionally, * invoking a method with a collection containing a {@code null} element will
--- a/src/share/classes/java/time/DayOfWeek.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/DayOfWeek.java Wed Jul 24 08:22:32 2013 -0300 @@ -61,7 +61,6 @@ */ package java.time; -import java.time.temporal.UnsupportedTemporalTypeException; import static java.time.temporal.ChronoField.DAY_OF_WEEK; import static java.time.temporal.ChronoUnit.DAYS; @@ -73,6 +72,7 @@ import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.time.temporal.WeekFields; import java.util.Locale; @@ -339,7 +339,7 @@ if (field == DAY_OF_WEEK) { return getValue(); } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); }
--- a/src/share/classes/java/time/Duration.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/Duration.java Wed Jul 24 08:22:32 2013 -0300 @@ -459,9 +459,9 @@ */ public static Duration between(Temporal startInclusive, Temporal endExclusive) { try { - return ofNanos(startInclusive.periodUntil(endExclusive, NANOS)); + return ofNanos(startInclusive.until(endExclusive, NANOS)); } catch (DateTimeException | ArithmeticException ex) { - long secs = startInclusive.periodUntil(endExclusive, SECONDS); + long secs = startInclusive.until(endExclusive, SECONDS); long nanos; try { nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND); @@ -523,7 +523,7 @@ } else if (unit == NANOS) { return nanos; } else { - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } }
--- a/src/share/classes/java/time/Instant.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/Instant.java Wed Jul 24 08:22:32 2013 -0300 @@ -69,6 +69,7 @@ import static java.time.temporal.ChronoField.MICRO_OF_SECOND; import static java.time.temporal.ChronoField.MILLI_OF_SECOND; import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.NANOS; import java.io.DataInput; @@ -418,8 +419,9 @@ * Checks if the specified field is supported. * <p> * This checks if this instant can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -448,6 +450,44 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code NANOS} + * <li>{@code MICROS} + * <li>{@code MILLIS} + * <li>{@code SECONDS} + * <li>{@code MINUTES} + * <li>{@code HOURS} + * <li>{@code HALF_DAYS} + * <li>{@code DAYS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isTimeBased() || unit == DAYS; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -511,7 +551,7 @@ case MILLI_OF_SECOND: return nanos / 1000_000; case INSTANT_SECONDS: INSTANT_SECONDS.checkValidIntValue(seconds); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return range(field).checkValidIntValue(field.getFrom(this), field); } @@ -548,7 +588,7 @@ case MILLI_OF_SECOND: return nanos / 1000_000; case INSTANT_SECONDS: return seconds; } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -665,7 +705,7 @@ case NANO_OF_SECOND: return (newValue != nanos ? create(seconds, (int) newValue) : this); case INSTANT_SECONDS: return (newValue != seconds ? create(newValue, nanos) : this); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -807,7 +847,7 @@ case HALF_DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY / 2)); case DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -1053,14 +1093,14 @@ * complete units between the two instants. * The {@code Temporal} passed to this method must be an {@code Instant}. * For example, the amount in days between two dates can be calculated - * using {@code startInstant.periodUntil(endInstant, SECONDS)}. + * using {@code startInstant.until(endInstant, SECONDS)}. * <p> * There are two equivalent ways of using this method. * The first is to invoke this method. * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, SECONDS); + * amount = start.until(end, SECONDS); * amount = SECONDS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1085,7 +1125,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endInstant, TemporalUnit unit) { + public long until(Temporal endInstant, TemporalUnit unit) { if (endInstant instanceof Instant == false) { Objects.requireNonNull(endInstant, "endInstant"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1103,7 +1143,7 @@ case HALF_DAYS: return secondsUntil(end) / (12 * SECONDS_PER_HOUR); case DAYS: return secondsUntil(end) / (SECONDS_PER_DAY); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endInstant); }
--- a/src/share/classes/java/time/LocalDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/LocalDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -127,7 +127,7 @@ * @since 1.8 */ public final class LocalDate - implements Temporal, TemporalAdjuster, ChronoLocalDate<LocalDate>, Serializable { + implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable { /** * The minimum supported {@code LocalDate}, '-999999999-01-01'. @@ -466,8 +466,9 @@ * Checks if the specified field is supported. * <p> * This checks if this date can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -502,6 +503,41 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code DAYS} + * <li>{@code WEEKS} + * <li>{@code MONTHS} + * <li>{@code YEARS} + * <li>{@code DECADES} + * <li>{@code CENTURIES} + * <li>{@code MILLENNIA} + * <li>{@code ERAS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + return ChronoLocalDate.super.isSupported(unit); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -538,7 +574,7 @@ } return field.range(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -631,7 +667,7 @@ case YEAR: return year; case ERA: return (year >= 1 ? 1 : 0); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } private long getProlepticMonth() { @@ -988,7 +1024,7 @@ case YEAR: return withYear((int) newValue); case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year)); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -1187,7 +1223,7 @@ case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -1497,7 +1533,7 @@ * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code LocalDate}. * For example, the amount in days between two dates can be calculated - * using {@code startDate.periodUntil(endDate, DAYS)}. + * using {@code startDate.until(endDate, DAYS)}. * <p> * The calculation returns a whole number, representing the number of * complete units between the two dates. @@ -1509,7 +1545,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MONTHS); + * amount = start.until(end, MONTHS); * amount = MONTHS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1534,7 +1570,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDate, TemporalUnit unit) { + public long until(Temporal endDate, TemporalUnit unit) { Objects.requireNonNull(unit, "unit"); if (endDate instanceof LocalDate == false) { Objects.requireNonNull(endDate, "endDate"); @@ -1552,7 +1588,7 @@ case MILLENNIA: return monthsUntil(end) / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endDate); } @@ -1591,7 +1627,7 @@ * The second is to use {@link Period#between(LocalDate, LocalDate)}: * <pre> * // these two lines are equivalent - * period = start.periodUntil(end); + * period = start.until(end); * period = Period.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1600,7 +1636,7 @@ * @return the period between this date and the end date, not null */ @Override - public Period periodUntil(ChronoLocalDate<?> endDate) { + public Period until(ChronoLocalDate endDate) { LocalDate end = LocalDate.from(endDate); long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe int days = end.day - this.day; @@ -1803,7 +1839,7 @@ * @return the comparator value, negative if less, positive if greater */ @Override // override for Javadoc and performance - public int compareTo(ChronoLocalDate<?> other) { + public int compareTo(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other); } @@ -1843,7 +1879,7 @@ * @return true if this date is after the specified date */ @Override // override for Javadoc and performance - public boolean isAfter(ChronoLocalDate<?> other) { + public boolean isAfter(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other) > 0; } @@ -1872,7 +1908,7 @@ * @return true if this date is before the specified date */ @Override // override for Javadoc and performance - public boolean isBefore(ChronoLocalDate<?> other) { + public boolean isBefore(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other) < 0; } @@ -1901,7 +1937,7 @@ * @return true if this date is equal to the specified date */ @Override // override for Javadoc and performance - public boolean isEqual(ChronoLocalDate<?> other) { + public boolean isEqual(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other) == 0; }
--- a/src/share/classes/java/time/LocalDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/LocalDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -515,8 +515,9 @@ * Checks if the specified field is supported. * <p> * This checks if this date-time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -570,6 +571,48 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code NANOS} + * <li>{@code MICROS} + * <li>{@code MILLIS} + * <li>{@code SECONDS} + * <li>{@code MINUTES} + * <li>{@code HOURS} + * <li>{@code HALF_DAYS} + * <li>{@code DAYS} + * <li>{@code WEEKS} + * <li>{@code MONTHS} + * <li>{@code YEARS} + * <li>{@code DECADES} + * <li>{@code CENTURIES} + * <li>{@code MILLENNIA} + * <li>{@code ERAS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + return ChronoLocalDateTime.super.isSupported(unit); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -1570,7 +1613,7 @@ * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code LocalDateTime}. * For example, the amount in days between two date-times can be calculated - * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. + * using {@code startDateTime.until(endDateTime, DAYS)}. * <p> * The calculation returns a whole number, representing the number of * complete units between the two date-times. @@ -1582,7 +1625,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MONTHS); + * amount = start.until(end, MONTHS); * amount = MONTHS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1609,18 +1652,17 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof LocalDateTime == false) { Objects.requireNonNull(endDateTime, "endDateTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } LocalDateTime end = (LocalDateTime) endDateTime; if (unit instanceof ChronoUnit) { - ChronoUnit f = (ChronoUnit) unit; - if (f.isTimeUnit()) { + if (unit.isTimeBased()) { long amount = date.daysUntil(end.date); if (amount == 0) { - return time.periodUntil(end.time, unit); + return time.until(end.time, unit); } long timePart = end.time.toNanoOfDay() - time.toNanoOfDay(); if (amount > 0) { @@ -1630,7 +1672,7 @@ amount++; // safe timePart -= NANOS_PER_DAY; // safe } - switch (f) { + switch ((ChronoUnit) unit) { case NANOS: amount = Math.multiplyExact(amount, NANOS_PER_DAY); break; @@ -1667,7 +1709,7 @@ } else if (endDate.isBefore(date) && end.time.isAfter(time)) { endDate = endDate.plusDays(1); } - return date.periodUntil(endDate, unit); + return date.until(endDate, unit); } return unit.between(this, endDateTime); }
--- a/src/share/classes/java/time/LocalTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/LocalTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -470,8 +470,9 @@ * Checks if the specified field is supported. * <p> * This checks if this time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -511,6 +512,43 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code NANOS} + * <li>{@code MICROS} + * <li>{@code MILLIS} + * <li>{@code SECONDS} + * <li>{@code MINUTES} + * <li>{@code HOURS} + * <li>{@code HALF_DAYS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isTimeBased(); + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -628,7 +666,7 @@ case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour); case AMPM_OF_DAY: return hour / 12; } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } //----------------------------------------------------------------------- @@ -803,7 +841,7 @@ case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue)); case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -995,8 +1033,7 @@ @Override public LocalTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { - ChronoUnit f = (ChronoUnit) unit; - switch (f) { + switch ((ChronoUnit) unit) { case NANOS: return plusNanos(amountToAdd); case MICROS: return plusNanos((amountToAdd % MICROS_PER_DAY) * 1000); case MILLIS: return plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000); @@ -1005,7 +1042,7 @@ case HOURS: return plusHours(amountToAdd); case HALF_DAYS: return plusHours((amountToAdd % 2) * 12); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -1295,7 +1332,7 @@ * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code LocalTime}. * For example, the amount in hours between two times can be calculated - * using {@code startTime.periodUntil(endTime, HOURS)}. + * using {@code startTime.until(endTime, HOURS)}. * <p> * The calculation returns a whole number, representing the number of * complete units between the two times. @@ -1307,7 +1344,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MINUTES); + * amount = start.until(end, MINUTES); * amount = MINUTES.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1332,7 +1369,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endTime, TemporalUnit unit) { + public long until(Temporal endTime, TemporalUnit unit) { if (endTime instanceof LocalTime == false) { Objects.requireNonNull(endTime, "endTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1349,7 +1386,7 @@ case HOURS: return nanosUntil / NANOS_PER_HOUR; case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endTime); }
--- a/src/share/classes/java/time/Month.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/Month.java Wed Jul 24 08:22:32 2013 -0300 @@ -61,7 +61,6 @@ */ package java.time; -import java.time.temporal.UnsupportedTemporalTypeException; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoUnit.MONTHS; @@ -75,6 +74,7 @@ import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.util.Locale; @@ -370,7 +370,7 @@ if (field == MONTH_OF_YEAR) { return getValue(); } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); }
--- a/src/share/classes/java/time/MonthDay.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/MonthDay.java Wed Jul 24 08:22:32 2013 -0300 @@ -438,7 +438,7 @@ case DAY_OF_MONTH: return day; case MONTH_OF_YEAR: return month; } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); }
--- a/src/share/classes/java/time/OffsetDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/OffsetDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -65,6 +65,7 @@ import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.NANO_OF_DAY; import static java.time.temporal.ChronoField.OFFSET_SECONDS; +import static java.time.temporal.ChronoUnit.FOREVER; import static java.time.temporal.ChronoUnit.NANOS; import java.io.IOException; @@ -137,25 +138,40 @@ public static final OffsetDateTime MAX = LocalDateTime.MAX.atOffset(ZoneOffset.MIN); /** - * Comparator for two {@code OffsetDateTime} instances based solely on the instant. + * Gets a comparator that compares two {@code OffsetDateTime} instances + * based solely on the instant. * <p> * This method differs from the comparison in {@link #compareTo} in that it * only compares the underlying instant. * + * @return a comparator that compares in time-line order + * * @see #isAfter * @see #isBefore * @see #isEqual */ - public static final Comparator<OffsetDateTime> INSTANT_COMPARATOR = new Comparator<OffsetDateTime>() { - @Override - public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) { - int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); - if (cmp == 0) { - cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay()); - } - return cmp; + public static Comparator<OffsetDateTime> timeLineOrder() { + return OffsetDateTime::compareInstant; + } + + /** + * Compares this {@code OffsetDateTime} to another date-time. + * The comparison is based on the instant. + * + * @param datetime1 the first date-time to compare, not null + * @param datetime2 the other date-time to compare to, not null + * @return the comparator value, negative if less, positive if greater + */ + private static int compareInstant(OffsetDateTime datetime1, OffsetDateTime datetime2) { + if (datetime1.getOffset().equals(datetime2.getOffset())) { + return datetime1.toLocalDateTime().compareTo(datetime2.toLocalDateTime()); } - }; + int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); + if (cmp == 0) { + cmp = datetime1.toLocalTime().getNano() - datetime2.toLocalTime().getNano(); + } + return cmp; + } /** * Serialization version. @@ -406,8 +422,9 @@ * Checks if the specified field is supported. * <p> * This checks if this date-time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -459,6 +476,51 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code NANOS} + * <li>{@code MICROS} + * <li>{@code MILLIS} + * <li>{@code SECONDS} + * <li>{@code MINUTES} + * <li>{@code HOURS} + * <li>{@code HALF_DAYS} + * <li>{@code DAYS} + * <li>{@code WEEKS} + * <li>{@code MONTHS} + * <li>{@code YEARS} + * <li>{@code DECADES} + * <li>{@code CENTURIES} + * <li>{@code MILLENNIA} + * <li>{@code ERAS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit != FOREVER; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -1528,7 +1590,7 @@ * The start and end points are {@code this} and the specified date-time. * The result will be negative if the end is before the start. * For example, the period in days between two date-times can be calculated - * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. + * using {@code startDateTime.until(endDateTime, DAYS)}. * <p> * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}. * If the offset differs between the two date-times, the specified @@ -1544,7 +1606,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MONTHS); + * amount = start.until(end, MONTHS); * amount = MONTHS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1571,7 +1633,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof OffsetDateTime == false) { Objects.requireNonNull(endDateTime, "endDateTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1579,7 +1641,7 @@ if (unit instanceof ChronoUnit) { OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(offset); - return dateTime.periodUntil(end.dateTime, unit); + return dateTime.until(end.dateTime, unit); } return unit.between(this, endDateTime); } @@ -1724,15 +1786,9 @@ */ @Override public int compareTo(OffsetDateTime other) { - if (getOffset().equals(other.getOffset())) { - return toLocalDateTime().compareTo(other.toLocalDateTime()); - } - int cmp = Long.compare(toEpochSecond(), other.toEpochSecond()); + int cmp = compareInstant(this, other); if (cmp == 0) { - cmp = toLocalTime().getNano() - other.toLocalTime().getNano(); - if (cmp == 0) { - cmp = toLocalDateTime().compareTo(other.toLocalDateTime()); - } + cmp = toLocalDateTime().compareTo(other.toLocalDateTime()); } return cmp; }
--- a/src/share/classes/java/time/OffsetTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/OffsetTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -348,8 +348,9 @@ * Checks if the specified field is supported. * <p> * This checks if this time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -390,6 +391,43 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code NANOS} + * <li>{@code MICROS} + * <li>{@code MILLIS} + * <li>{@code SECONDS} + * <li>{@code MINUTES} + * <li>{@code HOURS} + * <li>{@code HALF_DAYS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isTimeBased(); + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -1084,7 +1122,7 @@ * The start and end points are {@code this} and the specified time. * The result will be negative if the end is before the start. * For example, the period in hours between two times can be calculated - * using {@code startTime.periodUntil(endTime, HOURS)}. + * using {@code startTime.until(endTime, HOURS)}. * <p> * The {@code Temporal} passed to this method must be an {@code OffsetTime}. * If the offset differs between the two times, then the specified @@ -1100,7 +1138,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MINUTES); + * amount = start.until(end, MINUTES); * amount = MINUTES.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -1125,7 +1163,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endTime, TemporalUnit unit) { + public long until(Temporal endTime, TemporalUnit unit) { if (endTime instanceof OffsetTime == false) { Objects.requireNonNull(endTime, "endTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1142,7 +1180,7 @@ case HOURS: return nanosUntil / NANOS_PER_HOUR; case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endTime); }
--- a/src/share/classes/java/time/Period.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/Period.java Wed Jul 24 08:22:32 2013 -0300 @@ -139,7 +139,7 @@ * The pattern for parsing. */ private final static Pattern PATTERN = - Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); + Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); /** * The set of supported units. */ @@ -187,6 +187,20 @@ } /** + * Obtains a {@code Period} representing a number of weeks. + * <p> + * The resulting period will be day-based, with the amount of days + * equal to the number of weeks multiplied by 7. + * The years and months units will be zero. + * + * @param weeks the number of weeks, positive or negative + * @return the period, with the input weeks converted to days, not null + */ + public static Period ofWeeks(int weeks) { + return create(0, 0, Math.multiplyExact(weeks, 7)); + } + + /** * Obtains a {@code Period} representing a number of days. * <p> * The resulting period will have the specified days. @@ -257,22 +271,36 @@ * Obtains a {@code Period} from a text string such as {@code PnYnMnD}. * <p> * This will parse the string produced by {@code toString()} which is - * based on the ISO-8601 period format {@code PnYnMnD}. + * based on the ISO-8601 period formats {@code PnYnMnD} and {@code PnW}. * <p> * The string starts with an optional sign, denoted by the ASCII negative * or positive symbol. If negative, the whole period is negated. * The ASCII letter "P" is next in upper or lower case. - * There are then three sections, each consisting of a number and a suffix. - * At least one of the three sections must be present. - * The sections have suffixes in ASCII of "Y", "M" and "D" for - * years, months and days, accepted in upper or lower case. + * There are then four sections, each consisting of a number and a suffix. + * At least one of the four sections must be present. + * The sections have suffixes in ASCII of "Y", "M", "W" and "D" for + * years, months, weeks and days, accepted in upper or lower case. * The suffixes must occur in order. * The number part of each section must consist of ASCII digits. * The number may be prefixed by the ASCII negative or positive symbol. * The number must parse to an {@code int}. * <p> * The leading plus/minus sign, and negative values for other units are - * not part of the ISO-8601 standard. + * not part of the ISO-8601 standard. In addition, ISO-8601 does not + * permit mixing between the {@code PnYnMnD} and {@code PnW} formats. + * Any week-based input is multiplied by 7 and treated as a number of days. + * <p> + * For example, the following are valid inputs: + * <pre> + * "P2Y" -- Period.ofYears(2) + * "P3M" -- Period.ofMonths(3) + * "P4W" -- Period.ofWeeks(4) + * "P5D" -- Period.ofDays(5) + * "P1Y2M3D" -- Period.of(1, 2, 3) + * "P1Y2M3W4D" -- Period.of(1, 2, 25) + * "P-1Y2M" -- Period.of(-1, 2, 0) + * "-P1Y2M" -- Period.of(-1, -2, 0) + * </pre> * * @param text the text to parse, not null * @return the parsed period, not null @@ -285,14 +313,18 @@ int negate = ("-".equals(matcher.group(1)) ? -1 : 1); String yearMatch = matcher.group(2); String monthMatch = matcher.group(3); - String dayMatch = matcher.group(4); - if (yearMatch != null || monthMatch != null || dayMatch != null) { + String weekMatch = matcher.group(4); + String dayMatch = matcher.group(5); + if (yearMatch != null || monthMatch != null || dayMatch != null || weekMatch != null) { try { - return create(parseNumber(text, yearMatch, negate), - parseNumber(text, monthMatch, negate), - parseNumber(text, dayMatch, negate)); + int years = parseNumber(text, yearMatch, negate); + int months = parseNumber(text, monthMatch, negate); + int weeks = parseNumber(text, weekMatch, negate); + int days = parseNumber(text, dayMatch, negate); + days = Math.addExact(days, Math.multiplyExact(weeks, 7)); + return create(years, months, days); } catch (NumberFormatException ex) { - throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex); + throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0, ex); } } } @@ -307,7 +339,7 @@ try { return Math.multiplyExact(val, negate); } catch (ArithmeticException ex) { - throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex); + throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0, ex); } } @@ -329,10 +361,10 @@ * @param startDate the start date, inclusive, not null * @param endDate the end date, exclusive, not null * @return the period between this date and the end date, not null - * @see ChronoLocalDate#periodUntil(ChronoLocalDate) + * @see ChronoLocalDate#until(ChronoLocalDate) */ public static Period between(LocalDate startDate, LocalDate endDate) { - return startDate.periodUntil(endDate); + return startDate.until(endDate); } //----------------------------------------------------------------------- @@ -386,7 +418,7 @@ } else if (unit == ChronoUnit.DAYS) { return getDays(); } else { - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } }
--- a/src/share/classes/java/time/Year.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/Year.java Wed Jul 24 08:22:32 2013 -0300 @@ -64,6 +64,10 @@ import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.YEARS; import java.io.DataInput; @@ -329,8 +333,9 @@ * Checks if the specified field is supported. * <p> * This checks if this year can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -358,6 +363,41 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code YEARS} + * <li>{@code DECADES} + * <li>{@code CENTURIES} + * <li>{@code MILLENNIA} + * <li>{@code ERAS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -450,7 +490,7 @@ case YEAR: return year; case ERA: return (year < 1 ? 0 : 1); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -575,7 +615,7 @@ case YEAR: return Year.of((int) newValue); case ERA: return (getLong(ERA) == newValue ? this : Year.of(1 - year)); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -664,7 +704,7 @@ case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -821,7 +861,7 @@ * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code Year}. * For example, the period in decades between two year can be calculated - * using {@code startYear.periodUntil(endYear, DECADES)}. + * using {@code startYear.until(endYear, DECADES)}. * <p> * The calculation returns a whole number, representing the number of * complete units between the two years. @@ -833,7 +873,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, YEARS); + * amount = start.until(end, YEARS); * amount = YEARS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -858,7 +898,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endYear, TemporalUnit unit) { + public long until(Temporal endYear, TemporalUnit unit) { if (endYear instanceof Year == false) { Objects.requireNonNull(endYear, "endYear"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -873,7 +913,7 @@ case MILLENNIA: return yearsUntil / 1000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endYear); }
--- a/src/share/classes/java/time/YearMonth.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/YearMonth.java Wed Jul 24 08:22:32 2013 -0300 @@ -66,7 +66,12 @@ import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.YEARS; import java.io.DataInput; import java.io.DataOutput; @@ -313,8 +318,9 @@ * Checks if the specified field is supported. * <p> * This checks if this year-month can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -345,6 +351,42 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code MONTHS} + * <li>{@code YEARS} + * <li>{@code DECADES} + * <li>{@code CENTURIES} + * <li>{@code MILLENNIA} + * <li>{@code ERAS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit == MONTHS || unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -440,7 +482,7 @@ case YEAR: return year; case ERA: return (year < 1 ? 0 : 1); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -639,7 +681,7 @@ case YEAR: return withYear((int) newValue); case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year)); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -761,7 +803,7 @@ case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -952,7 +994,7 @@ * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code YearMonth}. * For example, the period in years between two year-months can be calculated - * using {@code startYearMonth.periodUntil(endYearMonth, YEARS)}. + * using {@code startYearMonth.until(endYearMonth, YEARS)}. * <p> * The calculation returns a whole number, representing the number of * complete units between the two year-months. @@ -964,7 +1006,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MONTHS); + * amount = start.until(end, MONTHS); * amount = MONTHS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -989,7 +1031,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endYearMonth, TemporalUnit unit) { + public long until(Temporal endYearMonth, TemporalUnit unit) { if (endYearMonth instanceof YearMonth == false) { Objects.requireNonNull(endYearMonth, "endYearMonth"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1005,7 +1047,7 @@ case MILLENNIA: return monthsUntil / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endYearMonth); }
--- a/src/share/classes/java/time/ZoneId.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/ZoneId.java Wed Jul 24 08:22:32 2013 -0300 @@ -401,6 +401,36 @@ } /** + * Obtains an instance of {@code ZoneId} wrapping an offset. + * <p> + * If the prefix is "GMT", "UTC", or "UT" a {@code ZoneId} + * with the prefix and the non-zero offset is returned. + * If the prefix is empty {@code ""} the {@code ZoneOffset} is returned. + * + * @param prefix the time-zone ID, not null + * @param offset the offset, not null + * @return the zone ID, not null + * @throws IllegalArgumentException if the prefix is not one of + * "GMT", "UTC", or "UT", or "" + */ + public static ZoneId ofOffset(String prefix, ZoneOffset offset) { + Objects.requireNonNull(prefix, "prefix"); + Objects.requireNonNull(offset, "offset"); + if (prefix.length() == 0) { + return offset; + } + + if (!prefix.equals("GMT") && !prefix.equals("UTC") && !prefix.equals("UT")) { + throw new IllegalArgumentException("prefix should be GMT, UTC or UT, is: " + prefix); + } + + if (offset.getTotalSeconds() != 0) { + prefix = prefix.concat(offset.getId()); + } + return new ZoneRegion(prefix, offset.getRules()); + } + + /** * Parses the ID, taking a flag to indicate whether {@code ZoneRulesException} * should be thrown or not, used in deserialization. * @@ -433,7 +463,7 @@ private static ZoneId ofWithPrefix(String zoneId, int prefixLength, boolean checkAvailable) { String prefix = zoneId.substring(0, prefixLength); if (zoneId.length() == prefixLength) { - return ZoneRegion.ofPrefixedOffset(prefix, ZoneOffset.UTC); + return ofOffset(prefix, ZoneOffset.UTC); } if (zoneId.charAt(prefixLength) != '+' && zoneId.charAt(prefixLength) != '-') { return ZoneRegion.ofId(zoneId, checkAvailable); // drop through to ZoneRulesProvider @@ -441,9 +471,9 @@ try { ZoneOffset offset = ZoneOffset.of(zoneId.substring(prefixLength)); if (offset == ZoneOffset.UTC) { - return ZoneRegion.ofPrefixedOffset(prefix, offset); + return ofOffset(prefix, offset); } - return ZoneRegion.ofPrefixedOffset(prefix + offset.toString(), offset); + return ofOffset(prefix, offset); } catch (DateTimeException ex) { throw new DateTimeException("Invalid ID for offset-based ZoneId: " + zoneId, ex); }
--- a/src/share/classes/java/time/ZoneOffset.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/ZoneOffset.java Wed Jul 24 08:22:32 2013 -0300 @@ -61,7 +61,6 @@ */ package java.time; -import java.time.temporal.UnsupportedTemporalTypeException; import static java.time.LocalTime.MINUTES_PER_HOUR; import static java.time.LocalTime.SECONDS_PER_HOUR; import static java.time.LocalTime.SECONDS_PER_MINUTE; @@ -79,6 +78,7 @@ import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.time.zone.ZoneRules; import java.util.Objects; @@ -581,7 +581,7 @@ if (field == OFFSET_SECONDS) { return totalSeconds; } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return range(field).checkValidIntValue(getLong(field), field); } @@ -613,7 +613,7 @@ if (field == OFFSET_SECONDS) { return totalSeconds; } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); }
--- a/src/share/classes/java/time/ZoneRegion.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/ZoneRegion.java Wed Jul 24 08:22:32 2013 -0300 @@ -66,7 +66,6 @@ import java.time.zone.ZoneRulesException; import java.time.zone.ZoneRulesProvider; import java.util.Objects; -import java.util.regex.Pattern; /** * A geographical region where the same time-zone rules apply. @@ -153,19 +152,6 @@ } } - /** - * Obtains an instance of {@code ZoneId} wrapping an offset. - * <p> - * For example, zone IDs like 'UTC', 'GMT', 'UT' and 'UTC+01:30' will be setup here. - * - * @param zoneId the time-zone ID, not null - * @param offset the offset, not null - * @return the zone ID, not null - */ - static ZoneRegion ofPrefixedOffset(String zoneId, ZoneOffset offset) { - return new ZoneRegion(zoneId, offset.getRules()); - } - //------------------------------------------------------------------------- /** * Constructor.
--- a/src/share/classes/java/time/ZonedDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/ZonedDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -642,8 +642,9 @@ * Checks if the specified field is supported. * <p> * This checks if this date-time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. * <p> * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -695,6 +696,48 @@ } /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + * <ul> + * <li>{@code NANOS} + * <li>{@code MICROS} + * <li>{@code MILLIS} + * <li>{@code SECONDS} + * <li>{@code MINUTES} + * <li>{@code HOURS} + * <li>{@code HALF_DAYS} + * <li>{@code DAYS} + * <li>{@code WEEKS} + * <li>{@code MONTHS} + * <li>{@code YEARS} + * <li>{@code DECADES} + * <li>{@code CENTURIES} + * <li>{@code MILLENNIA} + * <li>{@code ERAS} + * </ul> + * All other {@code ChronoUnit} instances will return false. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + return ChronoZonedDateTime.super.isSupported(unit); + } + + //----------------------------------------------------------------------- + /** * Gets the range of valid values for the specified field. * <p> * The range object expresses the minimum and maximum valid values for a field. @@ -1540,8 +1583,7 @@ @Override public ZonedDateTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { - ChronoUnit u = (ChronoUnit) unit; - if (u.isDateUnit()) { + if (unit.isDateBased()) { return resolveLocal(dateTime.plus(amountToAdd, unit)); } else { return resolveInstant(dateTime.plus(amountToAdd, unit)); @@ -1990,7 +2032,7 @@ * The start and end points are {@code this} and the specified date-time. * The result will be negative if the end is before the start. * For example, the period in days between two date-times can be calculated - * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. + * using {@code startDateTime.until(endDateTime, DAYS)}. * <p> * The {@code Temporal} passed to this method must be a {@code ZonedDateTime}. * If the time-zone differs between the two zoned date-times, the specified @@ -2006,7 +2048,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MONTHS); + * amount = start.until(end, MONTHS); * amount = MONTHS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -2047,7 +2089,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ZonedDateTime == false) { Objects.requireNonNull(endDateTime, "endDateTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -2055,11 +2097,10 @@ if (unit instanceof ChronoUnit) { ZonedDateTime end = (ZonedDateTime) endDateTime; end = end.withZoneSameInstant(zone); - ChronoUnit u = (ChronoUnit) unit; - if (u.isDateUnit()) { - return dateTime.periodUntil(end.dateTime, unit); + if (unit.isDateBased()) { + return dateTime.until(end.dateTime, unit); } else { - return toOffsetDateTime().periodUntil(end.toOffsetDateTime(), unit); + return toOffsetDateTime().until(end.toOffsetDateTime(), unit); } } return unit.between(this, endDateTime);
--- a/src/share/classes/java/time/chrono/ChronoDateImpl.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ChronoDateImpl.java Wed Jul 24 08:22:32 2013 -0300 @@ -67,6 +67,8 @@ import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalField; import java.time.temporal.TemporalUnit; import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; @@ -96,12 +98,12 @@ * // Enumerate the list of available calendars and print today for each * Set<Chronology> chronos = Chronology.getAvailableChronologies(); * for (Chronology chrono : chronos) { - * ChronoLocalDate<?> date = chrono.dateNow(); + * ChronoLocalDate date = chrono.dateNow(); * System.out.printf(" %20s: %s%n", chrono.getID(), date.toString()); * } * * // Print the Hijrah date and calendar - * ChronoLocalDate<?> date = Chronology.of("Hijrah").dateNow(); + * ChronoLocalDate date = Chronology.of("Hijrah").dateNow(); * int day = date.get(ChronoField.DAY_OF_MONTH); * int dow = date.get(ChronoField.DAY_OF_WEEK); * int month = date.get(ChronoField.MONTH_OF_YEAR); @@ -110,10 +112,10 @@ * dow, day, month, year); * // Print today's date and the last day of the year - * ChronoLocalDate<?> now1 = Chronology.of("Hijrah").dateNow(); - * ChronoLocalDate<?> first = now1.with(ChronoField.DAY_OF_MONTH, 1) + * ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow(); + * ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1) * .with(ChronoField.MONTH_OF_YEAR, 1); - * ChronoLocalDate<?> last = first.plus(1, ChronoUnit.YEARS) + * ChronoLocalDate last = first.plus(1, ChronoUnit.YEARS) * .minus(1, ChronoUnit.DAYS); * System.out.printf(" Today is %s: start: %s; end: %s%n", last.getChronology().getID(), * first, last); @@ -138,8 +140,8 @@ * @param <D> the ChronoLocalDate of this date-time * @since 1.8 */ -abstract class ChronoDateImpl<D extends ChronoLocalDate<D>> - implements ChronoLocalDate<D>, Temporal, TemporalAdjuster, Serializable { +abstract class ChronoDateImpl<D extends ChronoLocalDate> + implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable { /** * Serialization version. @@ -147,13 +149,52 @@ private static final long serialVersionUID = 6282433883239719096L; /** + * Casts the {@code Temporal} to {@code ChronoLocalDate} ensuring it bas the specified chronology. + * + * @param chrono the chronology to check for, not null + * @param temporal a date-time to cast, not null + * @return the date-time checked and cast to {@code ChronoLocalDate}, not null + * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate + * or the chronology is not equal this Chronology + */ + static <D extends ChronoLocalDate> D ensureValid(Chronology chrono, Temporal temporal) { + @SuppressWarnings("unchecked") + D other = (D) temporal; + if (chrono.equals(other.getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + other.getChronology().getId()); + } + return other; + } + + //----------------------------------------------------------------------- + /** * Creates an instance. */ ChronoDateImpl() { } + @Override + @SuppressWarnings("unchecked") + public D with(TemporalAdjuster adjuster) { + return (D) ChronoLocalDate.super.with(adjuster); + } + + @Override + @SuppressWarnings("unchecked") + public D with(TemporalField field, long value) { + return (D) ChronoLocalDate.super.with(field, value); + } + //----------------------------------------------------------------------- @Override + @SuppressWarnings("unchecked") + public D plus(TemporalAmount amount) { + return (D) ChronoLocalDate.super.plus(amount); + } + + //----------------------------------------------------------------------- + @Override + @SuppressWarnings("unchecked") public D plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { ChronoUnit f = (ChronoUnit) unit; @@ -167,9 +208,21 @@ case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return ChronoLocalDate.super.plus(amountToAdd, unit); + return (D) ChronoLocalDate.super.plus(amountToAdd, unit); + } + + @Override + @SuppressWarnings("unchecked") + public D minus(TemporalAmount amount) { + return (D) ChronoLocalDate.super.minus(amount); + } + + @Override + @SuppressWarnings("unchecked") + public D minus(long amountToSubtract, TemporalUnit unit) { + return (D) ChronoLocalDate.super.minus(amountToSubtract, unit); } //----------------------------------------------------------------------- @@ -254,6 +307,7 @@ * @return a date based on this one with the years subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusYears(long yearsToSubtract) { return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract)); } @@ -274,6 +328,7 @@ * @return a date based on this one with the months subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusMonths(long monthsToSubtract) { return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract)); } @@ -293,6 +348,7 @@ * @return a date based on this one with the weeks subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusWeeks(long weeksToSubtract) { return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract)); } @@ -310,6 +366,7 @@ * @return a date based on this one with the days subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusDays(long daysToSubtract) { return (daysToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract)); } @@ -321,13 +378,13 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { Objects.requireNonNull(endDateTime, "endDateTime"); Objects.requireNonNull(unit, "unit"); if (endDateTime instanceof ChronoLocalDate == false) { throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } - ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime; + ChronoLocalDate end = (ChronoLocalDate) endDateTime; if (getChronology().equals(end.getChronology()) == false) { throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); } @@ -342,16 +399,16 @@ case MILLENNIA: return monthsUntil(end) / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endDateTime); } - private long daysUntil(ChronoLocalDate<?> end) { + private long daysUntil(ChronoLocalDate end) { return end.toEpochDay() - toEpochDay(); // no overflow } - private long monthsUntil(ChronoLocalDate<?> end) { + private long monthsUntil(ChronoLocalDate end) { ValueRange range = getChronology().range(MONTH_OF_YEAR); if (range.getMaximum() != 12) { throw new IllegalStateException("ChronoDateImpl only supports Chronologies with 12 months per year"); @@ -367,7 +424,7 @@ return true; } if (obj instanceof ChronoLocalDate) { - return compareTo((ChronoLocalDate<?>) obj) == 0; + return compareTo((ChronoLocalDate) obj) == 0; } return false; }
--- a/src/share/classes/java/time/chrono/ChronoLocalDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ChronoLocalDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -242,11 +242,10 @@ * Additional calendar systems may be added to the system. * See {@link Chronology} for more details. * - * @param <D> the concrete type for the date * @since 1.8 */ -public interface ChronoLocalDate<D extends ChronoLocalDate<D>> - extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate<?>> { +public interface ChronoLocalDate + extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDate> { /** * Gets a comparator that compares {@code ChronoLocalDate} in @@ -263,7 +262,7 @@ * @see #isBefore * @see #isEqual */ - static Comparator<ChronoLocalDate<?>> timeLineOrder() { + static Comparator<ChronoLocalDate> timeLineOrder() { return Chronology.DATE_ORDER; } @@ -289,9 +288,9 @@ * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate} * @see Chronology#date(TemporalAccessor) */ - static ChronoLocalDate<?> from(TemporalAccessor temporal) { + static ChronoLocalDate from(TemporalAccessor temporal) { if (temporal instanceof ChronoLocalDate) { - return (ChronoLocalDate<?>) temporal; + return (ChronoLocalDate) temporal; } Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { @@ -367,6 +366,25 @@ return (isLeapYear() ? 366 : 365); } + /** + * Checks if the specified field is supported. + * <p> + * This checks if the specified field can be queried on this date. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. + * <p> + * The set of supported fields is defined by the chronology and normally includes + * all {@code ChronoField} date fields. + * <p> + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field can be queried, false if not + */ @Override default boolean isSupported(TemporalField field) { if (field instanceof ChronoField) { @@ -375,6 +393,32 @@ return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to or subtracted from this date. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * The set of supported units is defined by the chronology and normally includes + * all {@code ChronoUnit} date units except {@code FOREVER}. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + default boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isDateBased(); + } + return unit != null && unit.isSupportedBy(this); + } + //----------------------------------------------------------------------- // override for covariant return type /** @@ -383,8 +427,8 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - default D with(TemporalAdjuster adjuster) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster)); + default ChronoLocalDate with(TemporalAdjuster adjuster) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -394,11 +438,11 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - default D with(TemporalField field, long newValue) { + default ChronoLocalDate with(TemporalField field, long newValue) { if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } - return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue)); + return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); } /** @@ -407,8 +451,8 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - default D plus(TemporalAmount amount) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount)); + default ChronoLocalDate plus(TemporalAmount amount) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -417,11 +461,11 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - default D plus(long amountToAdd, TemporalUnit unit) { + default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd)); + return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); } /** @@ -430,8 +474,8 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - default D minus(TemporalAmount amount) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount)); + default ChronoLocalDate minus(TemporalAmount amount) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -441,8 +485,8 @@ * @throws ArithmeticException {@inheritDoc} */ @Override - default D minus(long amountToSubtract, TemporalUnit unit) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit)); + default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- @@ -522,14 +566,14 @@ * The calculation returns a whole number, representing the number of * complete units between the two dates. * For example, the amount in days between two dates can be calculated - * using {@code startDate.periodUntil(endDate, DAYS)}. + * using {@code startDate.until(endDate, DAYS)}. * <p> * There are two equivalent ways of using this method. * The first is to invoke this method. * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * amount = start.periodUntil(end, MONTHS); + * amount = start.until(end, MONTHS); * amount = MONTHS.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -555,7 +599,7 @@ * @throws ArithmeticException if numeric overflow occurs */ @Override // override for Javadoc - long periodUntil(Temporal endDate, TemporalUnit unit); + long until(Temporal endDate, TemporalUnit unit); /** * Calculates the period between this date and another date as a {@code Period}. @@ -575,7 +619,7 @@ * @throws DateTimeException if the period cannot be calculated * @throws ArithmeticException if numeric overflow occurs */ - Period periodUntil(ChronoLocalDate<?> endDate); + Period until(ChronoLocalDate endDate); /** * Formats this date using the specified formatter. @@ -606,8 +650,9 @@ * @param localTime the local time to use, not null * @return the local date-time formed from this date and the specified time, not null */ - default ChronoLocalDateTime<D> atTime(LocalTime localTime) { - return (ChronoLocalDateTime<D>)ChronoLocalDateTimeImpl.of(this, localTime); + @SuppressWarnings("unchecked") + default ChronoLocalDateTime<?> atTime(LocalTime localTime) { + return ChronoLocalDateTimeImpl.of(this, localTime); } //----------------------------------------------------------------------- @@ -656,7 +701,7 @@ * @return the comparator value, negative if less, positive if greater */ @Override - default int compareTo(ChronoLocalDate<?> other) { + default int compareTo(ChronoLocalDate other) { int cmp = Long.compare(toEpochDay(), other.toEpochDay()); if (cmp == 0) { cmp = getChronology().compareTo(other.getChronology()); @@ -678,7 +723,7 @@ * @param other the other date to compare to, not null * @return true if this is after the specified date */ - default boolean isAfter(ChronoLocalDate<?> other) { + default boolean isAfter(ChronoLocalDate other) { return this.toEpochDay() > other.toEpochDay(); } @@ -696,7 +741,7 @@ * @param other the other date to compare to, not null * @return true if this is before the specified date */ - default boolean isBefore(ChronoLocalDate<?> other) { + default boolean isBefore(ChronoLocalDate other) { return this.toEpochDay() < other.toEpochDay(); } @@ -714,7 +759,7 @@ * @param other the other date to compare to, not null * @return true if the underlying date is equal to the specified date */ - default boolean isEqual(ChronoLocalDate<?> other) { + default boolean isEqual(ChronoLocalDate other) { return this.toEpochDay() == other.toEpochDay(); }
--- a/src/share/classes/java/time/chrono/ChronoLocalDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ChronoLocalDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -63,6 +63,7 @@ import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.NANO_OF_DAY; +import static java.time.temporal.ChronoUnit.FOREVER; import static java.time.temporal.ChronoUnit.NANOS; import java.time.DateTimeException; @@ -73,6 +74,7 @@ import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; @@ -114,7 +116,7 @@ * @param <D> the concrete type for the date of this date-time * @since 1.8 */ -public interface ChronoLocalDateTime<D extends ChronoLocalDate<D>> +public interface ChronoLocalDateTime<D extends ChronoLocalDate> extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> { /** @@ -191,9 +193,54 @@ */ LocalTime toLocalTime(); - @Override // Override to provide javadoc + /** + * Checks if the specified field is supported. + * <p> + * This checks if the specified field can be queried on this date-time. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. + * <p> + * The set of supported fields is defined by the chronology and normally includes + * all {@code ChronoField} date and time fields. + * <p> + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field can be queried, false if not + */ + @Override boolean isSupported(TemporalField field); + /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to or subtracted from this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * The set of supported units is defined by the chronology and normally includes + * all {@code ChronoUnit} units except {@code FOREVER}. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + default boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit != FOREVER; + } + return unit != null && unit.isSupportedBy(this); + } + //----------------------------------------------------------------------- // override for covariant return type /** @@ -203,7 +250,7 @@ */ @Override default ChronoLocalDateTime<D> with(TemporalAdjuster adjuster) { - return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.with(adjuster))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); } /** @@ -221,7 +268,7 @@ */ @Override default ChronoLocalDateTime<D> plus(TemporalAmount amount) { - return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.plus(amount))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); } /** @@ -239,7 +286,7 @@ */ @Override default ChronoLocalDateTime<D> minus(TemporalAmount amount) { - return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amount))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); } /** @@ -249,7 +296,7 @@ */ @Override default ChronoLocalDateTime<D> minus(long amountToSubtract, TemporalUnit unit) { - return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amountToSubtract, unit))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //-----------------------------------------------------------------------
--- a/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java Wed Jul 24 08:22:32 2013 -0300 @@ -98,7 +98,7 @@ * @param <D> the concrete type for the date of this date-time * @since 1.8 */ -final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate<D>> +final class ChronoLocalDateTimeImpl<D extends ChronoLocalDate> implements ChronoLocalDateTime<D>, Temporal, TemporalAdjuster, Serializable { /** @@ -171,9 +171,27 @@ * @param time the local time, not null * @return the local date-time, not null */ - @SuppressWarnings("rawtypes") - static ChronoLocalDateTimeImpl<?> of(ChronoLocalDate<?> date, LocalTime time) { - return new ChronoLocalDateTimeImpl(date, time); + static <R extends ChronoLocalDate> ChronoLocalDateTimeImpl<R> of(R date, LocalTime time) { + return new ChronoLocalDateTimeImpl<>(date, time); + } + + /** + * Casts the {@code Temporal} to {@code ChronoLocalDateTime} ensuring it bas the specified chronology. + * + * @param chrono the chronology to check for, not null + * @param temporal a date-time to cast, not null + * @return the date-time checked and cast to {@code ChronoLocalDateTime}, not null + * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDateTimeImpl + * or the chronology is not equal this Chronology + */ + static <R extends ChronoLocalDate> ChronoLocalDateTimeImpl<R> ensureValid(Chronology chrono, Temporal temporal) { + @SuppressWarnings("unchecked") + ChronoLocalDateTimeImpl<R> other = (ChronoLocalDateTimeImpl<R>) temporal; + if (chrono.equals(other.toLocalDate().getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() + + ", actual: " + other.toLocalDate().getChronology().getId()); + } + return other; } /** @@ -202,7 +220,7 @@ return this; } // Validate that the new Temporal is a ChronoLocalDate (and not something else) - D cd = (D) date.getChronology().ensureChronoLocalDate(newDate); + D cd = ChronoDateImpl.ensureValid(date.getChronology(), newDate); return new ChronoLocalDateTimeImpl<>(cd, newTime); } @@ -260,13 +278,13 @@ public ChronoLocalDateTimeImpl<D> with(TemporalAdjuster adjuster) { if (adjuster instanceof ChronoLocalDate) { // The Chronology is checked in with(date,time) - return with((ChronoLocalDate<D>) adjuster, time); + return with((ChronoLocalDate) adjuster, time); } else if (adjuster instanceof LocalTime) { return with(date, (LocalTime) adjuster); } else if (adjuster instanceof ChronoLocalDateTimeImpl) { - return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl<?>) adjuster)); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), (ChronoLocalDateTimeImpl<?>) adjuster); } - return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl<?>) adjuster.adjustInto(this))); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), (ChronoLocalDateTimeImpl<?>) adjuster.adjustInto(this)); } @Override @@ -279,7 +297,7 @@ return with(date.with(field, newValue), time); } } - return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime(field.adjustInto(this, newValue))); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), field.adjustInto(this, newValue)); } //----------------------------------------------------------------------- @@ -298,7 +316,7 @@ } return with(date.plus(amountToAdd, unit), time); } - return (ChronoLocalDateTimeImpl<D>)(date.getChronology().ensureChronoLocalDateTime(unit.addTo(this, amountToAdd))); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), unit.addTo(this, amountToAdd)); } private ChronoLocalDateTimeImpl<D> plusDays(long days) { @@ -322,7 +340,7 @@ } //----------------------------------------------------------------------- - private ChronoLocalDateTimeImpl<D> plusWithOverflow(ChronoLocalDate<?> newDate, long hours, long minutes, long seconds, long nanos) { + private ChronoLocalDateTimeImpl<D> plusWithOverflow(D newDate, long hours, long minutes, long seconds, long nanos) { // 9223372036854775808 long, 2147483648 int if ((hours | minutes | seconds | nanos) == 0) { return with(newDate, time); @@ -351,7 +369,7 @@ //----------------------------------------------------------------------- @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoLocalDateTime == false) { throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } @@ -361,10 +379,9 @@ throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); } if (unit instanceof ChronoUnit) { - ChronoUnit f = (ChronoUnit) unit; - if (f.isTimeUnit()) { + if (unit.isTimeBased()) { long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY); - switch (f) { + switch ((ChronoUnit) unit) { case NANOS: amount = Math.multiplyExact(amount, NANOS_PER_DAY); break; case MICROS: amount = Math.multiplyExact(amount, MICROS_PER_DAY); break; case MILLIS: amount = Math.multiplyExact(amount, MILLIS_PER_DAY); break; @@ -373,13 +390,13 @@ case HOURS: amount = Math.multiplyExact(amount, HOURS_PER_DAY); break; case HALF_DAYS: amount = Math.multiplyExact(amount, 2); break; } - return Math.addExact(amount, time.periodUntil(end.toLocalTime(), unit)); + return Math.addExact(amount, time.until(end.toLocalTime(), unit)); } - D endDate = end.toLocalDate(); + ChronoLocalDate endDate = end.toLocalDate(); if (end.toLocalTime().isBefore(time)) { endDate = endDate.minus(1, ChronoUnit.DAYS); } - return date.periodUntil(endDate, unit); + return date.until(endDate, unit); } return unit.between(this, endDateTime); } @@ -404,7 +421,7 @@ } static ChronoLocalDateTime<?> readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - ChronoLocalDate<?> date = (ChronoLocalDate<?>) in.readObject(); + ChronoLocalDate date = (ChronoLocalDate) in.readObject(); LocalTime time = (LocalTime) in.readObject(); return date.atTime(time); }
--- a/src/share/classes/java/time/chrono/ChronoZonedDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ChronoZonedDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -63,6 +63,7 @@ import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.OFFSET_SECONDS; +import static java.time.temporal.ChronoUnit.FOREVER; import static java.time.temporal.ChronoUnit.NANOS; import java.time.DateTimeException; @@ -73,6 +74,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; @@ -115,7 +117,7 @@ * @param <D> the concrete type for the date of this date-time * @since 1.8 */ -public interface ChronoZonedDateTime<D extends ChronoLocalDate<D>> +public interface ChronoZonedDateTime<D extends ChronoLocalDate> extends Temporal, Comparable<ChronoZonedDateTime<?>> { /** @@ -338,9 +340,54 @@ */ ChronoZonedDateTime<D> withZoneSameInstant(ZoneId zone); - @Override // Override to provide javadoc + /** + * Checks if the specified field is supported. + * <p> + * This checks if the specified field can be queried on this date-time. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. + * <p> + * The set of supported fields is defined by the chronology and normally includes + * all {@code ChronoField} fields. + * <p> + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field can be queried, false if not + */ + @Override boolean isSupported(TemporalField field); + /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to or subtracted from this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * <p> + * The set of supported units is defined by the chronology and normally includes + * all {@code ChronoUnit} units except {@code FOREVER}. + * <p> + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + default boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit != FOREVER; + } + return unit != null && unit.isSupportedBy(this); + } + //----------------------------------------------------------------------- // override for covariant return type /** @@ -350,7 +397,7 @@ */ @Override default ChronoZonedDateTime<D> with(TemporalAdjuster adjuster) { - return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.with(adjuster))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); } /** @@ -368,7 +415,7 @@ */ @Override default ChronoZonedDateTime<D> plus(TemporalAmount amount) { - return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.plus(amount))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); } /** @@ -386,7 +433,7 @@ */ @Override default ChronoZonedDateTime<D> minus(TemporalAmount amount) { - return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amount))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); } /** @@ -396,7 +443,7 @@ */ @Override default ChronoZonedDateTime<D> minus(long amountToSubtract, TemporalUnit unit) { - return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amountToSubtract, unit))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //-----------------------------------------------------------------------
--- a/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java Wed Jul 24 08:22:32 2013 -0300 @@ -101,7 +101,7 @@ * @param <D> the concrete type for the date of this date-time * @since 1.8 */ -final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate<D>> +final class ChronoZonedDateTimeImpl<D extends ChronoLocalDate> implements ChronoZonedDateTime<D>, Serializable { /** @@ -131,7 +131,7 @@ * @param preferredOffset the zone offset, null if no preference * @return the zoned date-time, not null */ - static <R extends ChronoLocalDate<R>> ChronoZonedDateTime<R> ofBest( + static <R extends ChronoLocalDate> ChronoZonedDateTime<R> ofBest( ChronoLocalDateTimeImpl<R> localDateTime, ZoneId zone, ZoneOffset preferredOffset) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(zone, "zone"); @@ -167,14 +167,13 @@ * @param zone the zone identifier, not null * @return the zoned date-time, not null */ - @SuppressWarnings("rawtypes") static ChronoZonedDateTimeImpl<?> ofInstant(Chronology chrono, Instant instant, ZoneId zone) { ZoneRules rules = zone.getRules(); ZoneOffset offset = rules.getOffset(instant); Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset); - ChronoLocalDateTimeImpl<?> cldt = (ChronoLocalDateTimeImpl<?>) chrono.localDateTime(ldt); - return new ChronoZonedDateTimeImpl(cldt, offset, zone); + ChronoLocalDateTimeImpl<?> cldt = (ChronoLocalDateTimeImpl<?>)chrono.localDateTime(ldt); + return new ChronoZonedDateTimeImpl<>(cldt, offset, zone); } /** @@ -184,10 +183,30 @@ * @param zone the time-zone to use, validated not null * @return the zoned date-time, validated not null */ + @SuppressWarnings("unchecked") private ChronoZonedDateTimeImpl<D> create(Instant instant, ZoneId zone) { return (ChronoZonedDateTimeImpl<D>)ofInstant(toLocalDate().getChronology(), instant, zone); } + /** + * Casts the {@code Temporal} to {@code ChronoZonedDateTimeImpl} ensuring it bas the specified chronology. + * + * @param chrono the chronology to check for, not null + * @param temporal a date-time to cast, not null + * @return the date-time checked and cast to {@code ChronoZonedDateTimeImpl}, not null + * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl + * or the chronology is not equal this Chronology + */ + static <R extends ChronoLocalDate> ChronoZonedDateTimeImpl<R> ensureValid(Chronology chrono, Temporal temporal) { + @SuppressWarnings("unchecked") + ChronoZonedDateTimeImpl<R> other = (ChronoZonedDateTimeImpl<R>) temporal; + if (chrono.equals(other.toLocalDate().getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() + + ", actual: " + other.toLocalDate().getChronology().getId()); + } + return other; + } + //----------------------------------------------------------------------- /** * Constructor. @@ -271,7 +290,7 @@ } return ofBest(dateTime.with(field, newValue), zone, offset); } - return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(field.adjustInto(this, newValue))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), field.adjustInto(this, newValue)); } //----------------------------------------------------------------------- @@ -280,12 +299,12 @@ if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit)); } - return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(unit.addTo(this, amountToAdd))); /// TODO: Generics replacement Risk! + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! } //----------------------------------------------------------------------- @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoZonedDateTime == false) { throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } @@ -296,7 +315,7 @@ } if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); - return dateTime.periodUntil(end.toLocalDateTime(), unit); + return dateTime.until(end.toLocalDateTime(), unit); } return unit.between(this, endDateTime); }
--- a/src/share/classes/java/time/chrono/Chronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/Chronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -74,6 +74,9 @@ import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.TemporalAdjuster.nextOrSame; import java.io.DataInput; @@ -88,14 +91,16 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; +import java.time.Month; +import java.time.Year; import java.time.ZoneId; import java.time.format.DateTimeFormatterBuilder; import java.time.format.ResolverStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; -import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; import java.time.temporal.UnsupportedTemporalTypeException; @@ -188,8 +193,8 @@ /** * ChronoLocalDate order constant. */ - static final Comparator<ChronoLocalDate<?>> DATE_ORDER = - (Comparator<ChronoLocalDate<?>> & Serializable) (date1, date2) -> { + static final Comparator<ChronoLocalDate> DATE_ORDER = + (Comparator<ChronoLocalDate> & Serializable) (date1, date2) -> { return Long.compare(date1.toEpochDay(), date2.toEpochDay()); }; /** @@ -482,60 +487,6 @@ //----------------------------------------------------------------------- /** - * Casts the {@code Temporal} to {@code ChronoLocalDate} with the same chronology. - * - * @param temporal a date-time to cast, not null - * @return the date-time checked and cast to {@code ChronoLocalDate}, not null - * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate - * or the chronology is not equal this Chronology - */ - ChronoLocalDate<?> ensureChronoLocalDate(Temporal temporal) { - @SuppressWarnings("unchecked") - ChronoLocalDate<?> other = (ChronoLocalDate<?>) temporal; - if (this.equals(other.getChronology()) == false) { - throw new ClassCastException("Chronology mismatch, expected: " + getId() + ", actual: " + other.getChronology().getId()); - } - return other; - } - - /** - * Casts the {@code Temporal} to {@code ChronoLocalDateTime} with the same chronology. - * - * @param temporal a date-time to cast, not null - * @return the date-time checked and cast to {@code ChronoLocalDateTime}, not null - * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDateTimeImpl - * or the chronology is not equal this Chronology - */ - ChronoLocalDateTimeImpl<?> ensureChronoLocalDateTime(Temporal temporal) { - @SuppressWarnings("unchecked") - ChronoLocalDateTimeImpl<?> other = (ChronoLocalDateTimeImpl<?>) temporal; - if (this.equals(other.toLocalDate().getChronology()) == false) { - throw new ClassCastException("Chronology mismatch, required: " + getId() - + ", supplied: " + other.toLocalDate().getChronology().getId()); - } - return other; - } - - /** - * Casts the {@code Temporal} to {@code ChronoZonedDateTimeImpl} with the same chronology. - * - * @param temporal a date-time to cast, not null - * @return the date-time checked and cast to {@code ChronoZonedDateTimeImpl}, not null - * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl - * or the chronology is not equal this Chronology - */ - ChronoZonedDateTimeImpl<?> ensureChronoZonedDateTime(Temporal temporal) { - @SuppressWarnings("unchecked") - ChronoZonedDateTimeImpl<?> other = (ChronoZonedDateTimeImpl<?>) temporal; - if (this.equals(other.toLocalDate().getChronology()) == false) { - throw new ClassCastException("Chronology mismatch, required: " + getId() - + ", supplied: " + other.toLocalDate().getChronology().getId()); - } - return other; - } - - //----------------------------------------------------------------------- - /** * Gets the ID of the chronology. * <p> * The ID uniquely identifies the {@code Chronology}. @@ -574,7 +525,7 @@ * @throws DateTimeException if unable to create the date * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public ChronoLocalDate<?> date(Era era, int yearOfEra, int month, int dayOfMonth) { + public ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { return date(prolepticYear(era, yearOfEra), month, dayOfMonth); } @@ -588,7 +539,7 @@ * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate<?> date(int prolepticYear, int month, int dayOfMonth); + public abstract ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); /** * Obtains a local date in this chronology from the era, year-of-era and @@ -601,7 +552,7 @@ * @throws DateTimeException if unable to create the date * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public ChronoLocalDate<?> dateYearDay(Era era, int yearOfEra, int dayOfYear) { + public ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear); } @@ -614,7 +565,7 @@ * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate<?> dateYearDay(int prolepticYear, int dayOfYear); + public abstract ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); /** * Obtains a local date in this chronology from the epoch-day. @@ -626,7 +577,7 @@ * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate<?> dateEpochDay(long epochDay); + public abstract ChronoLocalDate dateEpochDay(long epochDay); //----------------------------------------------------------------------- /** @@ -643,7 +594,7 @@ * @return the current local date using the system clock and default time-zone, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate<?> dateNow() { + public ChronoLocalDate dateNow() { return dateNow(Clock.systemDefaultZone()); } @@ -660,7 +611,7 @@ * @return the current local date using the system clock, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate<?> dateNow(ZoneId zone) { + public ChronoLocalDate dateNow(ZoneId zone) { return dateNow(Clock.system(zone)); } @@ -675,7 +626,7 @@ * @return the current local date, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate<?> dateNow(Clock clock) { + public ChronoLocalDate dateNow(Clock clock) { Objects.requireNonNull(clock, "clock"); return date(LocalDate.now(clock)); } @@ -699,7 +650,7 @@ * @throws DateTimeException if unable to create the date * @see ChronoLocalDate#from(TemporalAccessor) */ - public abstract ChronoLocalDate<?> date(TemporalAccessor temporal); + public abstract ChronoLocalDate date(TemporalAccessor temporal); /** * Obtains a local date-time in this chronology from another temporal object. @@ -722,7 +673,7 @@ * @throws DateTimeException if unable to create the date-time * @see ChronoLocalDateTime#from(TemporalAccessor) */ - public ChronoLocalDateTime<?> localDateTime(TemporalAccessor temporal) { + public ChronoLocalDateTime<? extends ChronoLocalDate> localDateTime(TemporalAccessor temporal) { try { return date(temporal).atTime(LocalTime.from(temporal)); } catch (DateTimeException ex) { @@ -754,7 +705,7 @@ * @throws DateTimeException if unable to create the date-time * @see ChronoZonedDateTime#from(TemporalAccessor) */ - public ChronoZonedDateTime<?> zonedDateTime(TemporalAccessor temporal) { + public ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(TemporalAccessor temporal) { try { ZoneId zone = ZoneId.from(temporal); try { @@ -762,8 +713,7 @@ return zonedDateTime(instant, zone); } catch (DateTimeException ex1) { - @SuppressWarnings("rawtypes") - ChronoLocalDateTimeImpl cldt = ensureChronoLocalDateTime(localDateTime(temporal)); + ChronoLocalDateTimeImpl<?> cldt = ChronoLocalDateTimeImpl.ensureValid(this, localDateTime(temporal)); return ChronoZonedDateTimeImpl.ofBest(cldt, zone, null); } } catch (DateTimeException ex) { @@ -781,7 +731,7 @@ * @return the zoned date-time, not null * @throws DateTimeException if the result exceeds the supported range */ - public ChronoZonedDateTime<?> zonedDateTime(Instant instant, ZoneId zone) { + public ChronoZonedDateTime<? extends ChronoLocalDate> zonedDateTime(Instant instant, ZoneId zone) { return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone); } @@ -929,11 +879,82 @@ * As such, {@code ChronoField} date fields are resolved here in the * context of a specific chronology. * <p> + * {@code ChronoField} instances are resolved by this method, which may + * be overridden in subclasses. + * <ul> + * <li>{@code EPOCH_DAY} - If present, this is converted to a date and + * all other date fields are then cross-checked against the date. + * <li>{@code PROLEPTIC_MONTH} - If present, then it is split into the + * {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart + * then the field is validated. + * <li>{@code YEAR_OF_ERA} and {@code ERA} - If both are present, then they + * are combined to form a {@code YEAR}. In lenient mode, the {@code YEAR_OF_ERA} + * range is not validated, in smart and strict mode it is. The {@code ERA} is + * validated for range in all three modes. If only the {@code YEAR_OF_ERA} is + * present, and the mode is smart or lenient, then the last available era + * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is + * left untouched. If only the {@code ERA} is present, then it is left untouched. + * <li>{@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} - + * If all three are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is smart or strict, then the month and day are validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the first month in the requested year, + * then adding the difference in months, then the difference in days. + * If the mode is smart, and the day-of-month is greater than the maximum for + * the year-month, then the day-of-month is adjusted to the last day-of-month. + * If the mode is strict, then the three fields must form a valid date. + * <li>{@code YEAR} and {@code DAY_OF_YEAR} - + * If both are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the difference in days. + * If the mode is smart or strict, then the two fields must form a valid date. + * <li>{@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and + * {@code ALIGNED_DAY_OF_WEEK_IN_MONTH} - + * If all four are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the first month in the requested year, then adding + * the difference in months, then the difference in weeks, then in days. + * If the mode is smart or strict, then the all four fields are validated to + * their outer ranges. The date is then combined in a manner equivalent to + * creating a date on the first day of the requested year and month, then adding + * the amount in weeks and days to reach their values. If the mode is strict, + * the date is additionally validated to check that the day and week adjustment + * did not change the month. + * <li>{@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and + * {@code DAY_OF_WEEK} - If all four are present, then they are combined to + * form a date. The approach is the same as described above for + * years, months and weeks in {@code ALIGNED_DAY_OF_WEEK_IN_MONTH}. + * The day-of-week is adjusted as the next or same matching day-of-week once + * the years, months and weeks have been handled. + * <li>{@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code ALIGNED_DAY_OF_WEEK_IN_YEAR} - + * If all three are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the difference in weeks, then in days. + * If the mode is smart or strict, then the all three fields are validated to + * their outer ranges. The date is then combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the amount in weeks and days to reach their values. If the mode is strict, + * the date is additionally validated to check that the day and week adjustment + * did not change the year. + * <li>{@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code DAY_OF_WEEK} - + * If all three are present, then they are combined to form a date. + * The approach is the same as described above for years and weeks in + * {@code ALIGNED_DAY_OF_WEEK_IN_YEAR}. The day-of-week is adjusted as the + * next or same matching day-of-week once the years and weeks have been handled. + * </ul> + * <p> * The default implementation is suitable for most calendar systems. * If {@link ChronoField#YEAR_OF_ERA} is found without an {@link ChronoField#ERA} * then the last era in {@link #eras()} is used. * The implementation assumes a 7 day week, that the first day-of-month - * has the value 1, and that first day-of-year has the value 1. + * has the value 1, that first day-of-year has the value 1, and that the + * first of the month and year always exists. * * @param fieldValues the map of fields to values, which can be updated, not null * @param resolverStyle the requested type of resolve, not null @@ -941,99 +962,214 @@ * @throws DateTimeException if the date cannot be resolved, typically * because of a conflict in the input data */ - public ChronoLocalDate<?> resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + public ChronoLocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { // check epoch-day before inventing era if (fieldValues.containsKey(EPOCH_DAY)) { return dateEpochDay(fieldValues.remove(EPOCH_DAY)); } // fix proleptic month before inventing era - Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); - if (pMonth != null) { - // first day-of-month is likely to be safest for setting proleptic-month - // cannot add to year zero, as not all chronologies have a year zero - ChronoLocalDate<?> chronoDate = dateNow() - .with(DAY_OF_MONTH, 1).with(PROLEPTIC_MONTH, pMonth); - addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); - addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); - } + resolveProlepticMonth(fieldValues, resolverStyle); // invent era if necessary to resolve year-of-era - Long yoeLong = fieldValues.remove(YEAR_OF_ERA); - if (yoeLong != null) { - Long eraLong = fieldValues.remove(ERA); - int yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); - if (eraLong != null) { - Era eraObj = eraOf(Math.toIntExact(eraLong)); - addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); - } else if (fieldValues.containsKey(YEAR)) { - int year = range(YEAR).checkValidIntValue(fieldValues.get(YEAR), YEAR); - ChronoLocalDate<?> chronoDate = dateYearDay(year, 1); - addFieldValue(fieldValues, YEAR, prolepticYear(chronoDate.getEra(), yoe)); - } else { - List<Era> eras = eras(); - if (eras.isEmpty()) { - addFieldValue(fieldValues, YEAR, yoe); - } else { - Era eraObj = eras.get(eras.size() - 1); - addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); - } - } + ChronoLocalDate resolved = resolveYearOfEra(fieldValues, resolverStyle); + if (resolved != null) { + return resolved; } // build date if (fieldValues.containsKey(YEAR)) { if (fieldValues.containsKey(MONTH_OF_YEAR)) { if (fieldValues.containsKey(DAY_OF_MONTH)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); - return date(y, moy, dom); + return resolveYMD(fieldValues, resolverStyle); } if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); - int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); - ChronoLocalDate<?> chronoDate = date(y, moy, 1); - return chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); + return resolveYMAA(fieldValues, resolverStyle); } if (fieldValues.containsKey(DAY_OF_WEEK)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); - int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); - ChronoLocalDate<?> chronoDate = date(y, moy, 1); - return chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); + return resolveYMAD(fieldValues, resolverStyle); } } } if (fieldValues.containsKey(DAY_OF_YEAR)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); - return dateYearDay(y, doy); + return resolveYD(fieldValues, resolverStyle); } if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); - int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); - ChronoLocalDate<?> chronoDate = dateYearDay(y, 1); - return chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); + return resolveYAA(fieldValues, resolverStyle); } if (fieldValues.containsKey(DAY_OF_WEEK)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); - int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); - ChronoLocalDate<?> chronoDate = dateYearDay(y, 1); - return chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); + return resolveYAD(fieldValues, resolverStyle); } } } return null; } + void resolveProlepticMonth(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); + if (pMonth != null) { + if (resolverStyle != ResolverStyle.LENIENT) { + PROLEPTIC_MONTH.checkValidValue(pMonth); + } + // first day-of-month is likely to be safest for setting proleptic-month + // cannot add to year zero, as not all chronologies have a year zero + ChronoLocalDate chronoDate = dateNow() + .with(DAY_OF_MONTH, 1).with(PROLEPTIC_MONTH, pMonth); + addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); + addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); + } + } + + ChronoLocalDate resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + Long yoeLong = fieldValues.remove(YEAR_OF_ERA); + if (yoeLong != null) { + Long eraLong = fieldValues.remove(ERA); + int yoe; + if (resolverStyle != ResolverStyle.LENIENT) { + yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); + } else { + yoe = Math.toIntExact(yoeLong); + } + if (eraLong != null) { + Era eraObj = eraOf(range(ERA).checkValidIntValue(eraLong, ERA)); + addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); + } else { + if (fieldValues.containsKey(YEAR)) { + int year = range(YEAR).checkValidIntValue(fieldValues.get(YEAR), YEAR); + ChronoLocalDate chronoDate = dateYearDay(year, 1); + addFieldValue(fieldValues, YEAR, prolepticYear(chronoDate.getEra(), yoe)); + } else if (resolverStyle == ResolverStyle.STRICT) { + // do not invent era if strict + // reinstate the field removed earlier, no cross-check issues + fieldValues.put(YEAR_OF_ERA, yoeLong); + } else { + List<Era> eras = eras(); + if (eras.isEmpty()) { + addFieldValue(fieldValues, YEAR, yoe); + } else { + Era eraObj = eras.get(eras.size() - 1); + addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); + } + } + } + } else if (fieldValues.containsKey(ERA)) { + range(ERA).checkValidValue(fieldValues.get(ERA), ERA); // always validated + } + return null; + } + + ChronoLocalDate resolveYMD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + ValueRange domRange = range(DAY_OF_MONTH); + int dom = domRange.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); + if (resolverStyle == ResolverStyle.SMART) { // previous valid + try { + return date(y, moy, dom); + } catch (DateTimeException ex) { + return date(y, moy, 1).with(TemporalAdjuster.lastDayOfMonth()); + } + } + return date(y, moy, dom); + } + + ChronoLocalDate resolveYD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); + return dateYearDay(y, 1).plus(days, DAYS); + } + int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); + return dateYearDay(y, doy); // smart is same as strict + } + + ChronoLocalDate resolveYMAA(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); + long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(weeks, WEEKS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); + int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); + ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + return date; + } + + ChronoLocalDate resolveYMAD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); + long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); + return resolveAligned(date(y, 1, 1), months, weeks, dow); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); + int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); + ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); + if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + return date; + } + + ChronoLocalDate resolveYAA(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1); + return dateYearDay(y, 1).plus(weeks, WEEKS).plus(days, DAYS); + } + int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); + int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); + ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + return date; + } + + ChronoLocalDate resolveYAD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); + long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); + return resolveAligned(dateYearDay(y, 1), 0, weeks, dow); + } + int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); + int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); + ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); + if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + return date; + } + + ChronoLocalDate resolveAligned(ChronoLocalDate base, long months, long weeks, long dow) { + ChronoLocalDate date = base.plus(months, MONTHS).plus(weeks, WEEKS); + if (dow > 7) { + date = date.plus((dow - 1) / 7, WEEKS); + dow = ((dow - 1) % 7) + 1; + } else if (dow < 1) { + date = date.plus(Math.subtractExact(dow, 7) / 7, WEEKS); + dow = ((dow + 6) % 7) + 1; + } + return date.with(nextOrSame(DayOfWeek.of((int) dow))); + } + /** * Adds a field-value pair to the map, checking for conflicts. * <p>
--- a/src/share/classes/java/time/chrono/Era.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/Era.java Wed Jul 24 08:22:32 2013 -0300 @@ -238,7 +238,7 @@ if (field == ERA) { return getValue(); } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); }
--- a/src/share/classes/java/time/chrono/HijrahChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/HijrahChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -71,8 +71,10 @@ import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.HashMap; @@ -115,7 +117,7 @@ * <tr class="altColor"> * <td>Hijrah-umalqura</td> * <td>islamic-umalqura</td> - * <td>ca-islamic-cv-umalqura</td> + * <td>ca-islamic-umalqura</td> * <td>Islamic - Umm Al-Qura calendar of Saudi Arabia</td> * </tr> * </tbody> @@ -126,10 +128,10 @@ * <p> * Selecting the chronology from the locale uses {@link Chronology#ofLocale} * to find the Chronology based on Locale supported BCP 47 extension mechanism - * to request a specific calendar ("ca") and variant ("cv"). For example, + * to request a specific calendar ("ca"). For example, * </p> * <pre> - * Locale locale = Locale.forLanguageTag("en-US-u-ca-islamic-cv-umalqura"); + * Locale locale = Locale.forLanguageTag("en-US-u-ca-islamic-umalqura"); * Chronology chrono = Chronology.ofLocale(locale); * </pre> * @@ -472,11 +474,16 @@ * @param prolepticYear the proleptic-year * @param dayOfYear the day-of-year * @return the Hijrah local date, not null - * @throws DateTimeException if unable to create the date + * @throws DateTimeException if the value of the year is out of range, + * or if the day-of-year is invalid for the year */ @Override public HijrahDate dateYearDay(int prolepticYear, int dayOfYear) { - return HijrahDate.of(this, prolepticYear, 1, 1).plusDays(dayOfYear - 1); // TODO better + HijrahDate date = HijrahDate.of(this, prolepticYear, 1, 1); + if (dayOfYear > date.lengthOfYear()) { + throw new DateTimeException("Invalid dayOfYear: " + dayOfYear); + } + return date.plusDays(dayOfYear - 1); } /** @@ -515,16 +522,19 @@ } @Override + @SuppressWarnings("unchecked") public ChronoLocalDateTime<HijrahDate> localDateTime(TemporalAccessor temporal) { return (ChronoLocalDateTime<HijrahDate>) super.localDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime<HijrahDate> zonedDateTime(TemporalAccessor temporal) { return (ChronoZonedDateTime<HijrahDate>) super.zonedDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime<HijrahDate> zonedDateTime(Instant instant, ZoneId zone) { return (ChronoZonedDateTime<HijrahDate>) super.zonedDateTime(instant, zone); } @@ -550,7 +560,7 @@ } @Override - public Era eraOf(int eraValue) { + public HijrahEra eraOf(int eraValue) { switch (eraValue) { case 1: return HijrahEra.AH; @@ -580,6 +590,8 @@ case YEAR: case YEAR_OF_ERA: return ValueRange.of(getMinimumYear(), getMaximumYear()); + case ERA: + return ValueRange.of(1, 1); default: return field.range(); } @@ -587,6 +599,13 @@ return field.range(); } + //----------------------------------------------------------------------- + @Override // override for return type + public HijrahDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + return (HijrahDate) super.resolveDate(fieldValues, resolverStyle); + } + + //----------------------------------------------------------------------- /** * Check the validity of a year. *
--- a/src/share/classes/java/time/chrono/HijrahDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/HijrahDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -109,7 +109,7 @@ */ public final class HijrahDate extends ChronoDateImpl<HijrahDate> - implements ChronoLocalDate<HijrahDate>, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -204,7 +204,7 @@ * @throws DateTimeException if the current date cannot be obtained */ public static HijrahDate now(Clock clock) { - return HijrahChronology.INSTANCE.date(LocalDate.now(clock)); + return HijrahDate.ofEpochDay(HijrahChronology.INSTANCE, LocalDate.now(clock).toEpochDay()); } /** @@ -349,7 +349,7 @@ } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -372,7 +372,7 @@ case YEAR: return prolepticYear; case ERA: return getEraValue(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -393,7 +393,7 @@ case ALIGNED_DAY_OF_WEEK_IN_MONTH: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH)); case ALIGNED_DAY_OF_WEEK_IN_YEAR: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR)); case DAY_OF_MONTH: return resolvePreviousValid(prolepticYear, monthOfYear, nvalue); - case DAY_OF_YEAR: return resolvePreviousValid(prolepticYear, ((nvalue - 1) / 30) + 1, ((nvalue - 1) % 30) + 1); + case DAY_OF_YEAR: return plusDays(Math.min(nvalue, lengthOfYear()) - getDayOfYear()); case EPOCH_DAY: return new HijrahDate(chrono, newValue); case ALIGNED_WEEK_OF_MONTH: return plusDays((newValue - getLong(ALIGNED_WEEK_OF_MONTH)) * 7); case ALIGNED_WEEK_OF_YEAR: return plusDays((newValue - getLong(ALIGNED_WEEK_OF_YEAR)) * 7); @@ -403,9 +403,9 @@ case YEAR: return resolvePreviousValid(nvalue, monthOfYear, dayOfMonth); case ERA: return resolvePreviousValid(1 - prolepticYear, monthOfYear, dayOfMonth); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } private HijrahDate resolvePreviousValid(int prolepticYear, int month, int day) { @@ -479,7 +479,7 @@ * @return the day-of-year */ private int getDayOfYear() { - return chrono.getDayOfYear(prolepticYear, monthOfYear); + return chrono.getDayOfYear(prolepticYear, monthOfYear) + dayOfMonth; } /** @@ -575,12 +575,13 @@ } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime<HijrahDate> atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime<HijrahDate>)super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate<?> endDate) { + public Period until(ChronoLocalDate endDate) { // TODO: untested HijrahDate end = getChronology().date(endDate); long totalMonths = (end.prolepticYear - this.prolepticYear) * 12 + (end.monthOfYear - this.monthOfYear); // safe @@ -622,7 +623,7 @@ return this; } - static ChronoLocalDate<HijrahDate> readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + static HijrahDate readExternal(ObjectInput in) throws IOException, ClassNotFoundException { HijrahChronology chrono = (HijrahChronology) in.readObject(); int year = in.readInt(); int month = in.readByte();
--- a/src/share/classes/java/time/chrono/IsoChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/IsoChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -61,25 +61,16 @@ */ package java.time.chrono; -import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; -import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static java.time.temporal.ChronoField.DAY_OF_MONTH; -import static java.time.temporal.ChronoField.DAY_OF_WEEK; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; -import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; -import static java.time.temporal.TemporalAdjuster.nextOrSame; import java.io.Serializable; import java.time.Clock; import java.time.DateTimeException; -import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; @@ -398,7 +389,7 @@ } @Override - public Era eraOf(int eraValue) { + public IsoEra eraOf(int eraValue) { return IsoEra.of(eraValue); } @@ -421,7 +412,7 @@ * as follows. * <ul> * <li>{@code EPOCH_DAY} - If present, this is converted to a {@code LocalDate} - * all other date fields are then cross-checked against the date + * and all other date fields are then cross-checked against the date. * <li>{@code PROLEPTIC_MONTH} - If present, then it is split into the * {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart * then the field is validated. @@ -430,7 +421,7 @@ * range is not validated, in smart and strict mode it is. The {@code ERA} is * validated for range in all three modes. If only the {@code YEAR_OF_ERA} is * present, and the mode is smart or lenient, then the current era (CE/AD) - * is assumed. In strict mode, no ers is assumed and the {@code YEAR_OF_ERA} is + * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is * left untouched. If only the {@code ERA} is present, then it is left untouched. * <li>{@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} - * If all three are present, then they are combined to form a {@code LocalDate}. @@ -495,48 +486,11 @@ */ @Override // override for performance public LocalDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { - // check epoch-day before inventing era - if (fieldValues.containsKey(EPOCH_DAY)) { - return LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY)); - } - - // fix proleptic month before inventing era - resolveProlepticMonth(fieldValues, resolverStyle); - - // invent era if necessary to resolve year-of-era - resolveYearOfEra(fieldValues, resolverStyle); - - // build date - if (fieldValues.containsKey(YEAR)) { - if (fieldValues.containsKey(MONTH_OF_YEAR)) { - if (fieldValues.containsKey(DAY_OF_MONTH)) { - return resolveYMD(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { - if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { - return resolveYMAA(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(DAY_OF_WEEK)) { - return resolveYMAD(fieldValues, resolverStyle); - } - } - } - if (fieldValues.containsKey(DAY_OF_YEAR)) { - return resolveYD(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { - if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { - return resolveYAA(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(DAY_OF_WEEK)) { - return resolveYAD(fieldValues, resolverStyle); - } - } - } - return null; + return (LocalDate) super.resolveDate(fieldValues, resolverStyle); } - private void resolveProlepticMonth(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + @Override // override for better proleptic algorithm + void resolveProlepticMonth(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); if (pMonth != null) { if (resolverStyle != ResolverStyle.LENIENT) { @@ -547,7 +501,8 @@ } } - private void resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + @Override // override for enhanced behaviour + LocalDate resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { Long yoeLong = fieldValues.remove(YEAR_OF_ERA); if (yoeLong != null) { if (resolverStyle != ResolverStyle.LENIENT) { @@ -575,10 +530,14 @@ } else { throw new DateTimeException("Invalid value for era: " + era); } + } else if (fieldValues.containsKey(ERA)) { + ERA.checkValidValue(fieldValues.get(ERA)); // always validated } + return null; } - private LocalDate resolveYMD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + @Override // override for performance + LocalDate resolveYMD(Map <TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); if (resolverStyle == ResolverStyle.LENIENT) { long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); @@ -598,96 +557,6 @@ return LocalDate.of(y, moy, dom); } - private LocalDate resolveYD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); - return LocalDate.of(y, 1, 1).plusDays(days); - } - int doy = DAY_OF_YEAR.checkValidIntValue(fieldValues.remove(DAY_OF_YEAR)); - return LocalDate.ofYearDay(y, doy); // smart is same as strict - } - - private LocalDate resolveYMAA(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); - long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1); - return LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks).plusDays(days); - } - int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); - int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); - int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); - LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1)); - if (resolverStyle == ResolverStyle.STRICT && date.getMonthValue() != moy) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); - } - return date; - } - - private LocalDate resolveYMAD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); - long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); - return resolveAligned(y, months, weeks, dow); - } - int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); - int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); - int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK)); - LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); - if (resolverStyle == ResolverStyle.STRICT && date.getMonthValue() != moy) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); - } - return date; - } - - private LocalDate resolveYAA(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); - long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1); - return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days); - } - int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); - int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); - LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); - if (resolverStyle == ResolverStyle.STRICT && date.getYear() != y) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); - } - return date; - } - - private LocalDate resolveYAD(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); - long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); - return resolveAligned(y, 0, weeks, dow); - } - int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); - int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK)); - LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); - if (resolverStyle == ResolverStyle.STRICT && date.getYear() != y) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); - } - return date; - } - - private LocalDate resolveAligned(int y, long months, long weeks, long dow) { - LocalDate date = LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks); - if (dow > 7) { - date = date.plusWeeks((dow - 1) / 7); - dow = ((dow - 1) % 7) + 1; - } else if (dow < 1) { - date = date.plusWeeks(Math.subtractExact(dow, 7) / 7); - dow = ((dow + 6) % 7) + 1; - } - return date.with(nextOrSame(DayOfWeek.of((int) dow))); - } - //----------------------------------------------------------------------- @Override public ValueRange range(ChronoField field) {
--- a/src/share/classes/java/time/chrono/JapaneseChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/JapaneseChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -56,6 +56,15 @@ */ package java.time.chrono; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.ERA; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; + import java.io.Serializable; import java.time.Clock; import java.time.DateTimeException; @@ -63,13 +72,18 @@ import java.time.LocalDate; import java.time.Year; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Locale; +import java.util.Map; import sun.util.calendar.CalendarSystem; import sun.util.calendar.LocalGregorianCalendar; @@ -82,8 +96,22 @@ * The Japanese Imperial calendar system is the same as the ISO calendar system * apart from the era-based year numbering. * <p> - * Only Meiji (1865-04-07 - 1868-09-07) and later eras are supported. - * Older eras are handled as an unknown era where the year-of-era is the ISO year. + * Japan introduced the Gregorian calendar starting with Meiji 6. + * Only Meiji and later eras are supported; + * dates before Meiji 6, January 1 are not supported. + * <p> + * The supported {@code ChronoField} instances are: + * <ul> + * <li>{@code DAY_OF_WEEK} + * <li>{@code DAY_OF_MONTH} + * <li>{@code DAY_OF_YEAR} + * <li>{@code EPOCH_DAY} + * <li>{@code MONTH_OF_YEAR} + * <li>{@code PROLEPTIC_MONTH} + * <li>{@code YEAR_OF_ERA} + * <li>{@code YEAR} + * <li>{@code ERA} + * </ul> * * @implSpec * This class is immutable and thread-safe. @@ -91,7 +119,6 @@ * @since 1.8 */ public final class JapaneseChronology extends Chronology implements Serializable { - // TODO: definition for unknown era may break requirement that year-of-era >= 1 static final LocalGregorianCalendar JCAL = (LocalGregorianCalendar) CalendarSystem.forName("japanese"); @@ -152,6 +179,16 @@ /** * Obtains a local date in Japanese calendar system from the * era, year-of-era, month-of-year and day-of-month fields. + * <p> + * The Japanese month and day-of-month are the same as those in the + * ISO calendar system. They are not reset when the era changes. + * For example: + * <pre> + * 6th Jan Showa 64 = ISO 1989-01-06 + * 7th Jan Showa 64 = ISO 1989-01-07 + * 8th Jan Heisei 1 = ISO 1989-01-08 + * 9th Jan Heisei 1 = ISO 1989-01-09 + * </pre> * * @param era the Japanese era, not null * @param yearOfEra the year-of-era @@ -172,6 +209,9 @@ /** * Obtains a local date in Japanese calendar system from the * proleptic-year, month-of-year and day-of-month fields. + * <p> + * The Japanese proleptic year, month and day-of-month are the same as those + * in the ISO calendar system. They are not reset when the era changes. * * @param prolepticYear the proleptic-year * @param month the month-of-year @@ -187,6 +227,17 @@ /** * Obtains a local date in Japanese calendar system from the * era, year-of-era and day-of-year fields. + * <p> + * The day-of-year in this factory is expressed relative to the start of the year-of-era. + * This definition changes the normal meaning of day-of-year only in those years + * where the year-of-era is reset to one due to a change in the era. + * For example: + * <pre> + * 6th Jan Showa 64 = day-of-year 6 + * 7th Jan Showa 64 = day-of-year 7 + * 8th Jan Heisei 1 = day-of-year 1 + * 9th Jan Heisei 1 = day-of-year 2 + * </pre> * * @param era the Japanese era, not null * @param yearOfEra the year-of-era @@ -203,6 +254,10 @@ /** * Obtains a local date in Japanese calendar system from the * proleptic-year and day-of-year fields. + * <p> + * The day-of-year in this factory is expressed relative to the start of the proleptic year. + * The Japanese proleptic year and day-of-year are the same as those in the ISO calendar system. + * They are not reset when the era changes. * * @param prolepticYear the proleptic-year * @param dayOfYear the day-of-year @@ -211,8 +266,7 @@ */ @Override public JapaneseDate dateYearDay(int prolepticYear, int dayOfYear) { - LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear); - return date(prolepticYear, date.getMonthValue(), date.getDayOfMonth()); + return new JapaneseDate(LocalDate.ofYearDay(prolepticYear, dayOfYear)); } /** @@ -290,15 +344,6 @@ throw new ClassCastException("Era must be JapaneseEra"); } - if (era == JapaneseEra.SEIREKI) { - JapaneseEra nextEra = JapaneseEra.values()[1]; - int nextEraYear = nextEra.getPrivateEra().getSinceDate().getYear(); - if (yearOfEra >= nextEraYear || yearOfEra < Year.MIN_VALUE) { - throw new DateTimeException("Invalid yearOfEra value"); - } - return yearOfEra; - } - JapaneseEra jera = (JapaneseEra) era; int gregorianYear = jera.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1; if (yearOfEra == 1) { @@ -320,14 +365,13 @@ * See the description of each Era for the numeric values of: * {@link JapaneseEra#HEISEI}, {@link JapaneseEra#SHOWA},{@link JapaneseEra#TAISHO}, * {@link JapaneseEra#MEIJI}), only Meiji and later eras are supported. - * Prior to Meiji {@link JapaneseEra#SEIREKI} is used. * * @param eraValue the era value * @return the Japanese {@code Era} for the given numeric era value * @throws DateTimeException if {@code eraValue} is invalid */ @Override - public Era eraOf(int eraValue) { + public JapaneseEra eraOf(int eraValue) { return JapaneseEra.of(eraValue); } @@ -346,49 +390,117 @@ @Override public ValueRange range(ChronoField field) { switch (field) { - case YEAR: - case DAY_OF_MONTH: - case DAY_OF_WEEK: - case MICRO_OF_DAY: - case MICRO_OF_SECOND: - case HOUR_OF_DAY: - case HOUR_OF_AMPM: - case MINUTE_OF_DAY: - case MINUTE_OF_HOUR: - case SECOND_OF_DAY: - case SECOND_OF_MINUTE: - case MILLI_OF_DAY: - case MILLI_OF_SECOND: - case NANO_OF_DAY: - case NANO_OF_SECOND: - case CLOCK_HOUR_OF_DAY: - case CLOCK_HOUR_OF_AMPM: - case EPOCH_DAY: - case PROLEPTIC_MONTH: - case MONTH_OF_YEAR: - return field.range(); - case ERA: - return ValueRange.of(JapaneseEra.SEIREKI.getValue(), - getCurrentEra().getValue()); - } - Calendar jcal = Calendar.getInstance(LOCALE); - int fieldIndex; - switch (field) { + case ALIGNED_DAY_OF_WEEK_IN_MONTH: + case ALIGNED_DAY_OF_WEEK_IN_YEAR: + case ALIGNED_WEEK_OF_MONTH: + case ALIGNED_WEEK_OF_YEAR: + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); case YEAR_OF_ERA: { + Calendar jcal = Calendar.getInstance(LOCALE); int startYear = getCurrentEra().getPrivateEra().getSinceDate().getYear(); - return ValueRange.of(Year.MIN_VALUE, jcal.getGreatestMinimum(Calendar.YEAR), + return ValueRange.of(1, jcal.getGreatestMinimum(Calendar.YEAR), jcal.getLeastMaximum(Calendar.YEAR) + 1, // +1 due to the different definitions Year.MAX_VALUE - startYear); } - case DAY_OF_YEAR: - fieldIndex = Calendar.DAY_OF_YEAR; - break; + case DAY_OF_YEAR: { + Calendar jcal = Calendar.getInstance(LOCALE); + int fieldIndex = Calendar.DAY_OF_YEAR; + return ValueRange.of(jcal.getMinimum(fieldIndex), jcal.getGreatestMinimum(fieldIndex), + jcal.getLeastMaximum(fieldIndex), jcal.getMaximum(fieldIndex)); + } + case YEAR: + return ValueRange.of(JapaneseDate.MEIJI_6_ISODATE.getYear(), Year.MAX_VALUE); + case ERA: + return ValueRange.of(JapaneseEra.MEIJI.getValue(), getCurrentEra().getValue()); default: - // TODO: review the remaining fields - throw new UnsupportedOperationException("Unimplementable field: " + field); + return field.range(); + } + } + + //----------------------------------------------------------------------- + @Override // override for return type + public JapaneseDate resolveDate(Map <TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + return (JapaneseDate) super.resolveDate(fieldValues, resolverStyle); + } + + @Override // override for special Japanese behavior + ChronoLocalDate resolveYearOfEra(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + // validate era and year-of-era + Long eraLong = fieldValues.get(ERA); + JapaneseEra era = null; + if (eraLong != null) { + era = eraOf(range(ERA).checkValidIntValue(eraLong, ERA)); // always validated + } + Long yoeLong = fieldValues.get(YEAR_OF_ERA); + int yoe = 0; + if (yoeLong != null) { + yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); // always validated + } + // if only year-of-era and no year then invent era unless strict + if (era == null && yoeLong != null && fieldValues.containsKey(YEAR) == false && resolverStyle != ResolverStyle.STRICT) { + era = JapaneseEra.values()[JapaneseEra.values().length - 1]; + } + // if both present, then try to create date + if (yoeLong != null && era != null) { + if (fieldValues.containsKey(MONTH_OF_YEAR)) { + if (fieldValues.containsKey(DAY_OF_MONTH)) { + return resolveYMD(era, yoe, fieldValues, resolverStyle); + } + } + if (fieldValues.containsKey(DAY_OF_YEAR)) { + return resolveYD(era, yoe, fieldValues, resolverStyle); + } } - return ValueRange.of(jcal.getMinimum(fieldIndex), jcal.getGreatestMinimum(fieldIndex), - jcal.getLeastMaximum(fieldIndex), jcal.getMaximum(fieldIndex)); + return null; + } + + private int prolepticYearLenient(JapaneseEra era, int yearOfEra) { + return era.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1; + } + + private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map<TemporalField,Long> fieldValues, ResolverStyle resolverStyle) { + fieldValues.remove(ERA); + fieldValues.remove(YEAR_OF_ERA); + if (resolverStyle == ResolverStyle.LENIENT) { + int y = prolepticYearLenient(era, yoe); + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); + if (resolverStyle == ResolverStyle.SMART) { // previous valid + if (yoe < 1) { + throw new DateTimeException("Invalid YearOfEra: " + yoe); + } + int y = prolepticYearLenient(era, yoe); + JapaneseDate result; + try { + result = date(y, moy, dom); + } catch (DateTimeException ex) { + result = date(y, moy, 1).with(TemporalAdjuster.lastDayOfMonth()); + } + // handle the era being changed + // only allow if the new date is in the same Jan-Dec as the era change + // determine by ensuring either original yoe or result yoe is 1 + if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) { + throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe); + } + return result; + } + return date(era, yoe, moy, dom); + } + + private ChronoLocalDate resolveYD(JapaneseEra era, int yoe, Map <TemporalField,Long> fieldValues, ResolverStyle resolverStyle) { + fieldValues.remove(ERA); + fieldValues.remove(YEAR_OF_ERA); + if (resolverStyle == ResolverStyle.LENIENT) { + int y = prolepticYearLenient(era, yoe); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); + return dateYearDay(y, 1).plus(days, DAYS); + } + int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); + return dateYearDay(era, yoe, doy); // smart is same as strict } }
--- a/src/share/classes/java/time/chrono/JapaneseDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/JapaneseDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -56,9 +56,15 @@ */ package java.time.chrono; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; import java.io.DataInput; import java.io.DataOutput; @@ -96,6 +102,10 @@ * apart from the era-based year numbering. The proleptic-year is defined to be * equal to the ISO proleptic-year. * <p> + * Japan introduced the Gregorian calendar starting with Meiji 6. + * Only Meiji and later eras are supported; + * dates before Meiji 6, January 1 are not supported. + * <p> * For example, the Japanese year "Heisei 24" corresponds to ISO year "2012".<br> * Calling {@code japaneseDate.get(YEAR_OF_ERA)} will return 24.<br> * Calling {@code japaneseDate.get(YEAR)} will return 2012.<br> @@ -109,7 +119,7 @@ */ public final class JapaneseDate extends ChronoDateImpl<JapaneseDate> - implements ChronoLocalDate<JapaneseDate>, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -129,6 +139,11 @@ */ private transient int yearOfEra; + /** + * The first day supported by the JapaneseChronology is Meiji 6, January 1st. + */ + final static LocalDate MEIJI_6_ISODATE = LocalDate.of(1873, 1, 1); + //----------------------------------------------------------------------- /** * Obtains the current {@code JapaneseDate} from the system clock in the default time-zone. @@ -173,7 +188,7 @@ * @throws DateTimeException if the current date cannot be obtained */ public static JapaneseDate now(Clock clock) { - return JapaneseChronology.INSTANCE.date(LocalDate.now(clock)); + return new JapaneseDate(LocalDate.now(clock)); } /** @@ -182,6 +197,16 @@ * <p> * This returns a {@code JapaneseDate} with the specified fields. * The day must be valid for the year and month, otherwise an exception will be thrown. + * <p> + * The Japanese month and day-of-month are the same as those in the + * ISO calendar system. They are not reset when the era changes. + * For example: + * <pre> + * 6th Jan Showa 64 = ISO 1989-01-06 + * 7th Jan Showa 64 = ISO 1989-01-07 + * 8th Jan Heisei 1 = ISO 1989-01-08 + * 9th Jan Heisei 1 = ISO 1989-01-09 + * </pre> * * @param era the Japanese era, not null * @param yearOfEra the Japanese year-of-era @@ -192,11 +217,15 @@ * or if the day-of-month is invalid for the month-year, * or if the date is not a Japanese era */ - public static JapaneseDate of(Era era, int yearOfEra, int month, int dayOfMonth) { - if (era instanceof JapaneseEra == false) { - throw new ClassCastException("Era must be JapaneseEra"); + public static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) { + Objects.requireNonNull(era, "era"); + LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null); + jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth); + if (!JapaneseChronology.JCAL.validate(jdate)) { + throw new DateTimeException("year, month, and day not valid for Era"); } - return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth); + LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth); + return new JapaneseDate(era, yearOfEra, date); } /** @@ -205,6 +234,9 @@ * <p> * This returns a {@code JapaneseDate} with the specified fields. * The day must be valid for the year and month, otherwise an exception will be thrown. + * <p> + * The Japanese proleptic year, month and day-of-month are the same as those + * in the ISO calendar system. They are not reset when the era changes. * * @param prolepticYear the Japanese proleptic-year * @param month the Japanese month-of-year, from 1 to 12 @@ -219,23 +251,31 @@ /** * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar - * system from the proleptic-year and day-of-year fields. + * system from the era, year-of-era and day-of-year fields. * <p> * This returns a {@code JapaneseDate} with the specified fields. * The day must be valid for the year, otherwise an exception will be thrown. + * <p> + * The day-of-year in this factory is expressed relative to the start of the year-of-era. + * This definition changes the normal meaning of day-of-year only in those years + * where the year-of-era is reset to one due to a change in the era. + * For example: + * <pre> + * 6th Jan Showa 64 = day-of-year 6 + * 7th Jan Showa 64 = day-of-year 7 + * 8th Jan Heisei 1 = day-of-year 1 + * 9th Jan Heisei 1 = day-of-year 2 + * </pre> * - * @param prolepticYear the chronology proleptic-year + * @param era the Japanese era, not null + * @param yearOfEra the Japanese year-of-era * @param dayOfYear the chronology day-of-year, from 1 to 366 * @return the date in Japanese calendar system, not null * @throws DateTimeException if the value of any field is out of range, * or if the day-of-year is invalid for the year */ - public static JapaneseDate ofYearDay(int prolepticYear, int dayOfYear) { - LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear); - return of(prolepticYear, date.getMonthValue(), date.getDayOfMonth()); - } - static JapaneseDate ofYearDay(JapaneseEra era, int yearOfEra, int dayOfYear) { + Objects.requireNonNull(era, "era"); CalendarDate firstDay = era.getPrivateEra().getSinceDate(); LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null); jdate.setEra(era.getPrivateEra()); @@ -254,32 +294,6 @@ } /** - * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar - * system from the era, year-of-era, month-of-year and day-of-month fields. - * <p> - * This returns a {@code JapaneseDate} with the specified fields. - * The day must be valid for the year and month, otherwise an exception will be thrown. - * - * @param era the Japanese era, not null - * @param yearOfEra the Japanese year-of-era - * @param month the Japanese month-of-year, from 1 to 12 - * @param dayOfMonth the Japanese day-of-month, from 1 to 31 - * @return the date in Japanese calendar system, not null - * @throws DateTimeException if the value of any field is out of range, - * or if the day-of-month is invalid for the month-year - */ - static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) { - Objects.requireNonNull(era, "era"); - LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null); - jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth); - if (!JapaneseChronology.JCAL.validate(jdate)) { - throw new DateTimeException("year, month, and day not valid for Era"); - } - LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth); - return new JapaneseDate(era, yearOfEra, date); - } - - /** * Obtains a {@code JapaneseDate} from a temporal object. * <p> * This obtains a date in the Japanese calendar system based on the specified temporal. @@ -307,6 +321,9 @@ * @param isoDate the standard local date, validated not null */ JapaneseDate(LocalDate isoDate) { + if (isoDate.isBefore(MEIJI_6_ISODATE)) { + throw new DateTimeException("JapaneseDate before Meiji 6 is not supported"); + } LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate); this.era = JapaneseEra.toJapaneseEra(jdate.getEra()); this.yearOfEra = jdate.getYear(); @@ -322,6 +339,9 @@ * @param isoDate the standard local date, validated not null */ JapaneseDate(JapaneseEra era, int year, LocalDate isoDate) { + if (isoDate.isBefore(MEIJI_6_ISODATE)) { + throw new DateTimeException("JapaneseDate before Meiji 6 is not supported"); + } this.era = era; this.yearOfEra = year; this.isoDate = isoDate; @@ -366,55 +386,99 @@ return isoDate.lengthOfMonth(); } + @Override + public int lengthOfYear() { + Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); + jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); + jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); + return jcal.getActualMaximum(Calendar.DAY_OF_YEAR); + } + //----------------------------------------------------------------------- + /** + * Checks if the specified field is supported. + * <p> + * This checks if this date can be queried for the specified field. + * If false, then calling the {@link #range(TemporalField) range} and + * {@link #get(TemporalField) get} methods will throw an exception. + * <p> + * If the field is a {@link ChronoField} then the query is implemented here. + * The supported fields are: + * <ul> + * <li>{@code DAY_OF_WEEK} + * <li>{@code DAY_OF_MONTH} + * <li>{@code DAY_OF_YEAR} + * <li>{@code EPOCH_DAY} + * <li>{@code MONTH_OF_YEAR} + * <li>{@code PROLEPTIC_MONTH} + * <li>{@code YEAR_OF_ERA} + * <li>{@code YEAR} + * <li>{@code ERA} + * </ul> + * All other {@code ChronoField} instances will return false. + * <p> + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field is supported on this date, false if not + */ + @Override + public boolean isSupported(TemporalField field) { + if (field == ALIGNED_DAY_OF_WEEK_IN_MONTH || field == ALIGNED_DAY_OF_WEEK_IN_YEAR || + field == ALIGNED_WEEK_OF_MONTH || field == ALIGNED_WEEK_OF_YEAR) { + return false; + } + return ChronoLocalDate.super.isSupported(field); + } + @Override public ValueRange range(TemporalField field) { if (field instanceof ChronoField) { if (isSupported(field)) { ChronoField f = (ChronoField) field; switch (f) { - case DAY_OF_MONTH: - case ALIGNED_WEEK_OF_MONTH: - return isoDate.range(field); - case DAY_OF_YEAR: - return actualRange(Calendar.DAY_OF_YEAR); - case YEAR_OF_ERA: - return actualRange(Calendar.YEAR); + case DAY_OF_MONTH: return ValueRange.of(1, lengthOfMonth()); + case DAY_OF_YEAR: return ValueRange.of(1, lengthOfYear()); + case YEAR_OF_ERA: { + Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); + jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); + jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); + return ValueRange.of(1, jcal.getActualMaximum(Calendar.YEAR)); + } } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } - private ValueRange actualRange(int calendarField) { - Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); - jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); // TODO: cannot calculate this way for SEIREKI - jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); - return ValueRange.of(jcal.getActualMinimum(calendarField), - jcal.getActualMaximum(calendarField)); - } - @Override public long getLong(TemporalField field) { if (field instanceof ChronoField) { // same as ISO: - // DAY_OF_WEEK, ALIGNED_DAY_OF_WEEK_IN_MONTH, DAY_OF_MONTH, EPOCH_DAY, - // ALIGNED_WEEK_OF_MONTH, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR + // DAY_OF_WEEK, DAY_OF_MONTH, EPOCH_DAY, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR // // calendar specific fields - // ALIGNED_DAY_OF_WEEK_IN_YEAR, DAY_OF_YEAR, ALIGNED_WEEK_OF_YEAR, YEAR_OF_ERA, ERA + // DAY_OF_YEAR, YEAR_OF_ERA, ERA switch ((ChronoField) field) { + case ALIGNED_DAY_OF_WEEK_IN_MONTH: + case ALIGNED_DAY_OF_WEEK_IN_YEAR: + case ALIGNED_WEEK_OF_MONTH: + case ALIGNED_WEEK_OF_YEAR: + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); case YEAR_OF_ERA: return yearOfEra; case ERA: return era.getValue(); - case DAY_OF_YEAR: { - LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate); - return JapaneseChronology.JCAL.getDayOfYear(jdate); - } - // TODO: ALIGNED_DAY_OF_WEEK_IN_YEAR and ALIGNED_WEEK_OF_YEAR ??? + case DAY_OF_YEAR: + Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); + jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); + jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); + return jcal.get(Calendar.DAY_OF_YEAR); } return isoDate.getLong(field); } @@ -444,7 +508,7 @@ public JapaneseDate with(TemporalField field, long newValue) { if (field instanceof ChronoField) { ChronoField f = (ChronoField) field; - if (getLong(f) == newValue) { + if (getLong(f) == newValue) { // getLong() validates for supported fields return this; } switch (f) { @@ -464,10 +528,9 @@ } } // YEAR, PROLEPTIC_MONTH and others are same as ISO - // TODO: review other fields, such as WEEK_OF_YEAR return with(isoDate.with(field, newValue)); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } /** @@ -592,13 +655,14 @@ } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime<JapaneseDate> atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime<JapaneseDate>)super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate<?> endDate) { - return isoDate.periodUntil(endDate); + public Period until(ChronoLocalDate endDate) { + return isoDate.until(endDate); } @Override // override for performance @@ -624,14 +688,6 @@ return getChronology().getId().hashCode() ^ isoDate.hashCode(); } - @Override - public String toString() { - if (era == JapaneseEra.SEIREKI) { - return getChronology().getId() + " " + isoDate.toString(); - } - return super.toString(); - } - //----------------------------------------------------------------------- private Object writeReplace() { return new Ser(Ser.JAPANESE_DATE_TYPE, this);
--- a/src/share/classes/java/time/chrono/JapaneseEra.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/JapaneseEra.java Wed Jul 24 08:22:32 2013 -0300 @@ -61,6 +61,7 @@ */ package java.time.chrono; +import static java.time.chrono.JapaneseDate.MEIJI_6_ISODATE; import static java.time.temporal.ChronoField.ERA; import java.io.DataInput; @@ -84,12 +85,9 @@ * An era in the Japanese Imperial calendar system. * <p> * This class defines the valid eras for the Japanese chronology. - * Only Meiji (1868-09-08 - 1912-07-29) and later eras are supported. - * Japan introduced the Gregorian calendar since Meiji 6. The dates - * between Meiji 1 - 5 are not historically correct. - * The older eras are recognized as Seireki (Western calendar) era, - * and the year of era of Seireki is proleptic Gregorian year. - * (The Julian to Gregorian transition is not supported.) + * Japan introduced the Gregorian calendar starting with Meiji 6. + * Only Meiji and later eras are supported; + * dates before Meiji 6, January 1 are not supported. * * @implSpec * This class is immutable and thread-safe. @@ -100,17 +98,12 @@ implements Era, Serializable { // The offset value to 0-based index from the era value. - // i.e., getValue() + ERA_OFFSET == 0-based index; except that -999 is mapped to zero + // i.e., getValue() + ERA_OFFSET == 0-based index static final int ERA_OFFSET = 2; static final sun.util.calendar.Era[] ERA_CONFIG; /** - * The singleton instance for the before Meiji era ( - 1868-09-07) - * which has the value -999. - */ - public static final JapaneseEra SEIREKI = new JapaneseEra(-999, LocalDate.MIN); - /** * The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29) * which has the value -1. */ @@ -144,17 +137,13 @@ private static final JapaneseEra[] KNOWN_ERAS; static { - sun.util.calendar.Era[] sunEras = JapaneseChronology.JCAL.getEras(); - ERA_CONFIG = new sun.util.calendar.Era[sunEras.length + 1]; - for (int i = 1; i < ERA_CONFIG.length; i++) { - ERA_CONFIG[i] = sunEras[i - 1]; - } + ERA_CONFIG = JapaneseChronology.JCAL.getEras(); + KNOWN_ERAS = new JapaneseEra[ERA_CONFIG.length]; - KNOWN_ERAS[0] = SEIREKI; - KNOWN_ERAS[1] = MEIJI; - KNOWN_ERAS[2] = TAISHO; - KNOWN_ERAS[3] = SHOWA; - KNOWN_ERAS[4] = HEISEI; + KNOWN_ERAS[0] = MEIJI; + KNOWN_ERAS[1] = TAISHO; + KNOWN_ERAS[2] = SHOWA; + KNOWN_ERAS[3] = HEISEI; for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) { CalendarDate date = ERA_CONFIG[i].getSinceDate(); LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth()); @@ -203,10 +192,8 @@ //----------------------------------------------------------------------- /** * Returns the Sun private Era instance corresponding to this {@code JapaneseEra}. - * SEIREKI doesn't have its corresponding one. * - * @return the Sun private Era instance for this {@code JapaneseEra}, - * or null for SEIREKI. + * @return the Sun private Era instance for this {@code JapaneseEra}. */ sun.util.calendar.Era getPrivateEra() { return ERA_CONFIG[ordinal(eraValue)]; @@ -218,16 +205,14 @@ * <p> * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1 * Later era is numbered 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}), - * -1 ({@link #MEIJI}), only Meiji and later eras are supported. The prior to Meiji, - * {@link #SEIREKI} is used. + * -1 ({@link #MEIJI}), only Meiji and later eras are supported. * * @param japaneseEra the era to represent * @return the {@code JapaneseEra} singleton, not null * @throws DateTimeException if the value is invalid */ public static JapaneseEra of(int japaneseEra) { - if (japaneseEra != SEIREKI.eraValue && - (japaneseEra < MEIJI.eraValue || japaneseEra > HEISEI.eraValue)) { + if (japaneseEra < MEIJI.eraValue || japaneseEra > HEISEI.eraValue) { throw new DateTimeException("Invalid era: " + japaneseEra); } return KNOWN_ERAS[ordinal(japaneseEra)]; @@ -276,22 +261,25 @@ * @return the Era singleton, never null */ static JapaneseEra from(LocalDate date) { + if (date.isBefore(MEIJI_6_ISODATE)) { + throw new DateTimeException("JapaneseDate before Meiji 6 are not supported"); + } for (int i = KNOWN_ERAS.length - 1; i > 0; i--) { JapaneseEra era = KNOWN_ERAS[i]; if (date.compareTo(era.since) >= 0) { return era; } } - return SEIREKI; + return null; } static JapaneseEra toJapaneseEra(sun.util.calendar.Era privateEra) { - for (int i = ERA_CONFIG.length - 1; i > 0; i--) { + for (int i = ERA_CONFIG.length - 1; i >= 0; i--) { if (ERA_CONFIG[i].equals(privateEra)) { return KNOWN_ERAS[i]; } } - return SEIREKI; + return null; } static sun.util.calendar.Era privateEraFrom(LocalDate isoDate) { @@ -306,13 +294,13 @@ /** * Returns the index into the arrays from the Era value. - * the eraValue is a valid Era number, -999, -1..2. + * the eraValue is a valid Era number, -1..2. * * @param eraValue the era value to convert to the index * @return the index of the current Era */ private static int ordinal(int eraValue) { - return (eraValue == SEIREKI.eraValue) ? 0 : eraValue + ERA_OFFSET; + return eraValue + ERA_OFFSET - 1; } //----------------------------------------------------------------------- @@ -321,7 +309,7 @@ * <p> * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1. * Later eras are numbered from 2 ({@link #HEISEI}). - * Earlier eras are numbered 0 ({@link #TAISHO}), -1 ({@link #MEIJI}), and -999 ({@link #SEIREKI}). + * Earlier eras are numbered 0 ({@link #TAISHO}), -1 ({@link #MEIJI})). * * @return the era value */ @@ -374,11 +362,7 @@ } String getName() { - int index = ordinal(getValue()); - if (index == 0) { - return "Seireki"; - } - return ERA_CONFIG[index].getName(); + return ERA_CONFIG[ordinal(getValue())].getName(); } @Override
--- a/src/share/classes/java/time/chrono/MinguoChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/MinguoChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -65,12 +65,15 @@ import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Map; /** * The Minguo calendar system. @@ -253,16 +256,19 @@ } @Override + @SuppressWarnings("unchecked") public ChronoLocalDateTime<MinguoDate> localDateTime(TemporalAccessor temporal) { return (ChronoLocalDateTime<MinguoDate>)super.localDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime<MinguoDate> zonedDateTime(TemporalAccessor temporal) { return (ChronoZonedDateTime<MinguoDate>)super.zonedDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime<MinguoDate> zonedDateTime(Instant instant, ZoneId zone) { return (ChronoZonedDateTime<MinguoDate>)super.zonedDateTime(instant, zone); } @@ -292,7 +298,7 @@ } @Override - public Era eraOf(int eraValue) { + public MinguoEra eraOf(int eraValue) { return MinguoEra.of(eraValue); } @@ -321,4 +327,10 @@ return field.range(); } + //----------------------------------------------------------------------- + @Override // override for return type + public MinguoDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + return (MinguoDate) super.resolveDate(fieldValues, resolverStyle); + } + }
--- a/src/share/classes/java/time/chrono/MinguoDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/MinguoDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -96,7 +96,7 @@ */ public final class MinguoDate extends ChronoDateImpl<MinguoDate> - implements ChronoLocalDate<MinguoDate>, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -152,7 +152,7 @@ * @throws DateTimeException if the current date cannot be obtained */ public static MinguoDate now(Clock clock) { - return MinguoChronology.INSTANCE.date(LocalDate.now(clock)); + return new MinguoDate(LocalDate.now(clock)); } /** @@ -264,7 +264,7 @@ } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -325,7 +325,7 @@ } return with(isoDate.with(field, newValue)); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } /** @@ -370,6 +370,11 @@ } @Override + MinguoDate plusWeeks(long weeksToAdd) { + return super.plusWeeks(weeksToAdd); + } + + @Override MinguoDate plusDays(long days) { return with(isoDate.plusDays(days)); } @@ -385,11 +390,6 @@ } @Override - MinguoDate plusWeeks(long weeksToAdd) { - return super.plusWeeks(weeksToAdd); - } - - @Override MinguoDate minusYears(long yearsToSubtract) { return super.minusYears(yearsToSubtract); } @@ -414,13 +414,14 @@ } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime<MinguoDate> atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime<MinguoDate>)super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate<?> endDate) { - return isoDate.periodUntil(endDate); + public Period until(ChronoLocalDate endDate) { + return isoDate.until(endDate); } @Override // override for performance @@ -458,7 +459,7 @@ out.writeByte(get(DAY_OF_MONTH)); } - static ChronoLocalDate<?> readExternal(DataInput in) throws IOException { + static MinguoDate readExternal(DataInput in) throws IOException { int year = in.readInt(); int month = in.readByte(); int dayOfMonth = in.readByte();
--- a/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -65,13 +65,16 @@ import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; /** * The Thai Buddhist calendar system. @@ -289,16 +292,19 @@ } @Override + @SuppressWarnings("unchecked") public ChronoLocalDateTime<ThaiBuddhistDate> localDateTime(TemporalAccessor temporal) { return (ChronoLocalDateTime<ThaiBuddhistDate>)super.localDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(TemporalAccessor temporal) { return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime<ThaiBuddhistDate> zonedDateTime(Instant instant, ZoneId zone) { return (ChronoZonedDateTime<ThaiBuddhistDate>)super.zonedDateTime(instant, zone); } @@ -328,7 +334,7 @@ } @Override - public Era eraOf(int eraValue) { + public ThaiBuddhistEra eraOf(int eraValue) { return ThaiBuddhistEra.of(eraValue); } @@ -357,4 +363,10 @@ return field.range(); } + //----------------------------------------------------------------------- + @Override // override for return type + public ThaiBuddhistDate resolveDate(Map<TemporalField, Long> fieldValues, ResolverStyle resolverStyle) { + return (ThaiBuddhistDate) super.resolveDate(fieldValues, resolverStyle); + } + }
--- a/src/share/classes/java/time/chrono/ThaiBuddhistDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/ThaiBuddhistDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -96,7 +96,7 @@ */ public final class ThaiBuddhistDate extends ChronoDateImpl<ThaiBuddhistDate> - implements ChronoLocalDate<ThaiBuddhistDate>, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -152,7 +152,7 @@ * @throws DateTimeException if the current date cannot be obtained */ public static ThaiBuddhistDate now(Clock clock) { - return ThaiBuddhistChronology.INSTANCE.date(LocalDate.now(clock)); + return new ThaiBuddhistDate(LocalDate.now(clock)); } /** @@ -264,7 +264,7 @@ } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -325,7 +325,7 @@ } return with(isoDate.with(field, newValue)); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } /** @@ -414,13 +414,14 @@ } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime<ThaiBuddhistDate> atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime<ThaiBuddhistDate>) super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate<?> endDate) { - return isoDate.periodUntil(endDate); + public Period until(ChronoLocalDate endDate) { + return isoDate.until(endDate); } @Override // override for performance
--- a/src/share/classes/java/time/chrono/package-info.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/chrono/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -103,7 +103,7 @@ * // Enumerate the list of available calendars and print todays date for each. * Set<Chronology> chronos = Chronology.getAvailableChronologies(); * for (Chronology chrono : chronos) { - * ChronoLocalDate<?> date = chrono.dateNow(); + * ChronoLocalDate date = chrono.dateNow(); * System.out.printf(" %20s: %s%n", chrono.getId(), date.toString()); * } * </pre> @@ -113,7 +113,7 @@ * </p> * <pre> * // Print the Thai Buddhist date - * ChronoLocalDate<?> now1 = Chronology.of("ThaiBuddhist").dateNow(); + * ChronoLocalDate now1 = Chronology.of("ThaiBuddhist").dateNow(); * int day = now1.get(ChronoField.DAY_OF_MONTH); * int dow = now1.get(ChronoField.DAY_OF_WEEK); * int month = now1.get(ChronoField.MONTH_OF_YEAR); @@ -121,10 +121,10 @@ * System.out.printf(" Today is %s %s %d-%s-%d%n", now1.getChronology().getId(), * dow, day, month, year); * // Print today's date and the last day of the year for the Thai Buddhist Calendar. - * ChronoLocalDate<?> first = now1 + * ChronoLocalDate first = now1 * .with(ChronoField.DAY_OF_MONTH, 1) * .with(ChronoField.MONTH_OF_YEAR, 1); - * ChronoLocalDate<?> last = first + * ChronoLocalDate last = first * .plus(1, ChronoUnit.YEARS) * .minus(1, ChronoUnit.DAYS); * System.out.printf(" %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(),
--- a/src/share/classes/java/time/format/DateTimeFormatter.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/format/DateTimeFormatter.java Wed Jul 24 08:22:32 2013 -0300 @@ -265,7 +265,7 @@ * <p> * For example: * <blockquote><pre> - * DateTimeFormatter formatter = DateTimeFormatter.pattern("yyyy MM dd"); + * DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd"); * String text = date.toString(formatter); * LocalDate date = LocalDate.parse(text, formatter); * </pre></blockquote> @@ -460,7 +460,7 @@ * <li>The {@code ChronoField} time fields are resolved. * This is documented on {@link ChronoField} and is the same for all chronologies. * <li>Any fields that are not {@code ChronoField} are processed. - * This is achieved using {@link TemporalField#resolve(TemporalAccessor, long, ResolverStyle)}. + * This is achieved using {@link TemporalField#resolve(Map, Chronology, ZoneId, ResolverStyle)}. * Documentation about field resolution is located in the implementation * of {@code TemporalField}. * <li>The {@code ChronoField} date and time fields are re-resolved.
--- a/src/share/classes/java/time/format/DateTimeFormatterBuilder.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/format/DateTimeFormatterBuilder.java Wed Jul 24 08:22:32 2013 -0300 @@ -77,7 +77,6 @@ import java.math.RoundingMode; import java.text.ParsePosition; import java.time.DateTimeException; -import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -962,12 +961,9 @@ * <pre> * "Europe/London" -- ZoneId.of("Europe/London") * "Z" -- ZoneOffset.UTC - * "UT" -- ZoneOffset.UTC - * "UTC" -- ZoneOffset.UTC - * "GMT" -- ZoneOffset.UTC - * "UT0" -- ZoneOffset.UTC - * "UTC0" -- ZoneOffset.UTC - * "GMT0" -- ZoneOffset.UTC + * "UT" -- ZoneId.of("UT") + * "UTC" -- ZoneId.of("UTC") + * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") * "UT+01:30" -- ZoneOffset.of("+01:30") * "UTC+01:30" -- ZoneOffset.of("+01:30") @@ -1016,12 +1012,9 @@ * <pre> * "Europe/London" -- ZoneId.of("Europe/London") * "Z" -- ZoneOffset.UTC - * "UT" -- ZoneOffset.UTC - * "UTC" -- ZoneOffset.UTC - * "GMT" -- ZoneOffset.UTC - * "UT0" -- ZoneOffset.UTC - * "UTC0" -- ZoneOffset.UTC - * "GMT0" -- ZoneOffset.UTC + * "UT" -- ZoneId.of("UT") + * "UTC" -- ZoneId.of("UTC") + * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") * "UT+01:30" -- ZoneOffset.of("+01:30") * "UTC+01:30" -- ZoneOffset.of("+01:30") @@ -1077,16 +1070,13 @@ * <pre> * "Europe/London" -- ZoneId.of("Europe/London") * "Z" -- ZoneOffset.UTC - * "UT" -- ZoneOffset.UTC - * "UTC" -- ZoneOffset.UTC - * "GMT" -- ZoneOffset.UTC - * "UT0" -- ZoneOffset.UTC - * "UTC0" -- ZoneOffset.UTC - * "GMT0" -- ZoneOffset.UTC + * "UT" -- ZoneId.of("UT") + * "UTC" -- ZoneId.of("UTC") + * "GMT" -- ZoneId.of("GMT") * "+01:30" -- ZoneOffset.of("+01:30") - * "UT+01:30" -- ZoneOffset.of("+01:30") - * "UTC+01:30" -- ZoneOffset.of("+01:30") - * "GMT+01:30" -- ZoneOffset.of("+01:30") + * "UT+01:30" -- ZoneOffset.of("UT+01:30") + * "UTC+01:30" -- ZoneOffset.of("UTC+01:30") + * "GMT+01:30" -- ZoneOffset.of("GMT+01:30") * </pre> * <p> * Note that this method is is identical to {@code appendZoneId()} except @@ -2530,7 +2520,7 @@ DecimalStyle decimalStyle = context.getDecimalStyle(); String str = (value == Long.MIN_VALUE ? "9223372036854775808" : Long.toString(Math.abs(value))); if (str.length() > maxWidth) { - throw new DateTimeException("Field " + field.getName() + + throw new DateTimeException("Field " + field + " cannot be printed as the value " + value + " exceeds the maximum print width of " + maxWidth); } @@ -2555,7 +2545,7 @@ buf.append(decimalStyle.getNegativeSign()); break; case NOT_NEGATIVE: - throw new DateTimeException("Field " + field.getName() + + throw new DateTimeException("Field " + field + " cannot be printed as the value " + value + " cannot be negative according to the SignStyle"); } @@ -2699,12 +2689,12 @@ @Override public String toString() { if (minWidth == 1 && maxWidth == 19 && signStyle == SignStyle.NORMAL) { - return "Value(" + field.getName() + ")"; + return "Value(" + field + ")"; } if (minWidth == maxWidth && signStyle == SignStyle.NOT_NEGATIVE) { - return "Value(" + field.getName() + "," + minWidth + ")"; + return "Value(" + field + "," + minWidth + ")"; } - return "Value(" + field.getName() + "," + minWidth + "," + maxWidth + "," + signStyle + ")"; + return "Value(" + field + "," + minWidth + "," + maxWidth + "," + signStyle + ")"; } } @@ -2817,7 +2807,7 @@ @Override public String toString() { - return "ReducedValue(" + field.getName() + "," + minWidth + "," + maxWidth + "," + baseValue + ")"; + return "ReducedValue(" + field + "," + minWidth + "," + maxWidth + "," + baseValue + ")"; } } @@ -2842,7 +2832,7 @@ FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { Objects.requireNonNull(field, "field"); if (field.range().isFixed() == false) { - throw new IllegalArgumentException("Field must have a fixed set of values: " + field.getName()); + throw new IllegalArgumentException("Field must have a fixed set of values: " + field); } if (minWidth < 0 || minWidth > 9) { throw new IllegalArgumentException("Minimum width must be from 0 to 9 inclusive but was " + minWidth); @@ -2984,7 +2974,7 @@ @Override public String toString() { String decimal = (decimalPoint ? ",DecimalPoint" : ""); - return "Fraction(" + field.getName() + "," + minWidth + "," + maxWidth + decimal + ")"; + return "Fraction(" + field + "," + minWidth + "," + maxWidth + decimal + ")"; } } @@ -3079,9 +3069,9 @@ @Override public String toString() { if (textStyle == TextStyle.FULL) { - return "Text(" + field.getName() + ")"; + return "Text(" + field + ")"; } - return "Text(" + field.getName() + "," + textStyle + ")"; + return "Text(" + field + "," + textStyle + ")"; } } @@ -3756,17 +3746,17 @@ // handle fixed time-zone IDs char nextChar = text.charAt(position); if (nextChar == '+' || nextChar == '-') { - return parseOffsetBased(context, text, position, OffsetIdPrinterParser.INSTANCE_ID_Z); + return parseOffsetBased(context, text, position, position, OffsetIdPrinterParser.INSTANCE_ID_Z); } else if (length >= position + 2) { char nextNextChar = text.charAt(position + 1); if (context.charEquals(nextChar, 'U') && context.charEquals(nextNextChar, 'T')) { if (length >= position + 3 && context.charEquals(text.charAt(position + 2), 'C')) { - return parseOffsetBased(context, text, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); + return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } - return parseOffsetBased(context, text, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO); + return parseOffsetBased(context, text, position, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } else if (context.charEquals(nextChar, 'G') && length >= position + 3 && context.charEquals(nextNextChar, 'M') && context.charEquals(text.charAt(position + 2), 'T')) { - return parseOffsetBased(context, text, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); + return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } } @@ -3785,20 +3775,49 @@ return ppos.getIndex(); } - private int parseOffsetBased(DateTimeParseContext context, CharSequence text, int position, OffsetIdPrinterParser parser) { + /** + * Parse an offset following a prefix and set the ZoneId if it is valid. + * To matching the parsing of ZoneId.of the values are not normalized + * to ZoneOffsets. + * + * @param context the parse context + * @param text the input text + * @param prefixPos start of the prefix + * @param position start of text after the prefix + * @param parser parser for the value after the prefix + * @return the position after the parse + */ + private int parseOffsetBased(DateTimeParseContext context, CharSequence text, int prefixPos, int position, OffsetIdPrinterParser parser) { + String prefix = text.toString().substring(prefixPos, position).toUpperCase(); + if (position >= text.length()) { + context.setParsed(ZoneId.of(prefix)); + return position; + } + + // '0' or 'Z' after prefix is not part of a valid ZoneId; use bare prefix + if (text.charAt(position) == '0' || + context.charEquals(text.charAt(position), 'Z')) { + context.setParsed(ZoneId.of(prefix)); + return position; + } + DateTimeParseContext newContext = context.copy(); int endPos = parser.parse(newContext, text, position); - if (endPos < 0) { - if (parser == OffsetIdPrinterParser.INSTANCE_ID_Z) { - return ~position; + try { + if (endPos < 0) { + if (parser == OffsetIdPrinterParser.INSTANCE_ID_Z) { + return ~prefixPos; + } + context.setParsed(ZoneId.of(prefix)); + return position; } - context.setParsed(ZoneOffset.UTC); - return position; + int offset = (int) newContext.getParsed(OFFSET_SECONDS).longValue(); + ZoneOffset zoneOffset = ZoneOffset.ofTotalSeconds(offset); + context.setParsed(ZoneId.ofOffset(prefix, zoneOffset)); + return endPos; + } catch (DateTimeException dte) { + return ~prefixPos; } - int offset = (int) newContext.getParsed(OFFSET_SECONDS).longValue(); - ZoneId zone = ZoneOffset.ofTotalSeconds(offset); - context.setParsed(zone); - return endPos; } @Override
--- a/src/share/classes/java/time/format/DateTimePrintContext.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/format/DateTimePrintContext.java Wed Jul 24 08:22:32 2013 -0300 @@ -157,7 +157,7 @@ } } final ZoneId effectiveZone = (overrideZone != null ? overrideZone : temporalZone); - final ChronoLocalDate<?> effectiveDate; + final ChronoLocalDate effectiveDate; if (overrideChrono != null) { if (temporal.isSupported(EPOCH_DAY)) { effectiveDate = effectiveChrono.date(temporal);
--- a/src/share/classes/java/time/format/Parsed.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/format/Parsed.java Wed Jul 24 08:22:32 2013 -0300 @@ -143,7 +143,7 @@ /** * The resolved date. */ - private ChronoLocalDate<?> date; + private ChronoLocalDate date; /** * The resolved time. */ @@ -197,7 +197,7 @@ return time.getLong(field); } if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -255,42 +255,34 @@ // if any other fields, handle them // any lenient date resolution should return epoch-day if (fieldValues.size() > 0) { - boolean changed = false; + int changedCount = 0; outer: - while (true) { + while (changedCount < 50) { for (Map.Entry<TemporalField, Long> entry : fieldValues.entrySet()) { TemporalField targetField = entry.getKey(); - Map<TemporalField, Long> changes = targetField.resolve(this, entry.getValue(), resolverStyle); - if (changes != null) { - changed = true; - resolveFieldsMakeChanges(targetField, changes); - fieldValues.remove(targetField); // helps avoid infinite loops + ChronoLocalDate resolvedDate = targetField.resolve(fieldValues, chrono, zone, resolverStyle); + if (resolvedDate != null) { + updateCheckConflict(resolvedDate); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } else if (fieldValues.containsKey(targetField) == false) { + changedCount++; continue outer; // have to restart to avoid concurrent modification } } break; } + if (changedCount == 50) { // catch infinite loops + throw new DateTimeException("One of the parsed fields has an incorrectly implemented resolve method"); + } // if something changed then have to redo ChronoField resolve - if (changed) { + if (changedCount > 0) { resolveDateFields(); resolveTimeFields(); } } } - private void resolveFieldsMakeChanges(TemporalField targetField, Map<TemporalField, Long> changes) { - for (Map.Entry<TemporalField, Long> change : changes.entrySet()) { - TemporalField changeField = change.getKey(); - Long changeValue = change.getValue(); - Objects.requireNonNull(changeField, "changeField"); - if (changeValue != null) { - updateCheckConflict(targetField, changeField, changeValue); - } else { - fieldValues.remove(changeField); - } - } - } - private void updateCheckConflict(TemporalField targetField, TemporalField changeField, Long changeValue) { Long old = fieldValues.put(changeField, changeValue); if (old != null && old.longValue() != changeValue.longValue()) { @@ -305,7 +297,7 @@ updateCheckConflict(chrono.resolveDate(fieldValues, resolverStyle)); } - private void updateCheckConflict(ChronoLocalDate<?> cld) { + private void updateCheckConflict(ChronoLocalDate cld) { if (date != null) { if (cld != null && date.equals(cld) == false) { throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld);
--- a/src/share/classes/java/time/temporal/ChronoField.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/ChronoField.java Wed Jul 24 08:22:32 2013 -0300 @@ -403,6 +403,12 @@ * Non-ISO calendar systems should implement this field using the most recognized * day-of-year values for users of the calendar system. * Normally, this is a count of days from 1 to the length of the year. + * <p> + * Note that a non-ISO calendar system may have year numbering system that changes + * at a different point to the natural reset in the month numbering. An example + * of this is the Japanese calendar system where a change of era, which resets + * the year number to 1, can happen on any date. The era and year reset also cause + * the day-of-year to be reset to 1, but not the month-of-year or day-of-month. */ DAY_OF_YEAR("DayOfYear", DAYS, YEARS, ValueRange.of(1, 365, 366)), /** @@ -559,12 +565,11 @@ * <p> * This represents the concept of the sequential count of seconds where * 1970-01-01T00:00Z (ISO) is zero. - * This field may be used with {@link #NANO_OF_DAY} to represent the fraction of the day. + * This field may be used with {@link #NANO_OF_SECOND} to represent the fraction of the second. * <p> * An {@link Instant} represents an instantaneous point on the time-line. - * On their own they have no elements which allow a local date-time to be obtained. - * Only when paired with an offset or time-zone can the local date or time be found. - * This field allows the seconds part of the instant to be queried. + * On their own, an instant has insufficient information to allow a local date-time to be obtained. + * Only when paired with an offset or time-zone can the local date or time be calculated. * <p> * This field is strictly defined to have the same meaning in all calendar systems. * This is necessary to ensure interoperation between calendars. @@ -608,24 +613,18 @@ this.displayNameKey = displayNameKey; } - //----------------------------------------------------------------------- - @Override - public String getName() { - return name; - } - @Override public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); if (displayNameKey == null) { - return getName(); + return name; } LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() .getLocaleResources(locale); ResourceBundle rb = lr.getJavaTimeFormatData(); String key = "field." + displayNameKey; - return rb.containsKey(key) ? rb.getString(key) : getName(); + return rb.containsKey(key) ? rb.getString(key) : name; } @Override @@ -748,7 +747,7 @@ //----------------------------------------------------------------------- @Override public String toString() { - return getName(); + return name; } }
--- a/src/share/classes/java/time/temporal/ChronoUnit.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/ChronoUnit.java Wed Jul 24 08:22:32 2013 -0300 @@ -57,9 +57,6 @@ package java.time.temporal; import java.time.Duration; -import java.time.chrono.ChronoLocalDate; -import java.time.chrono.ChronoLocalDateTime; -import java.time.chrono.ChronoZonedDateTime; /** * A standard set of date periods units. @@ -201,12 +198,6 @@ } //----------------------------------------------------------------------- - @Override - public String getName() { - return name; - } - - //----------------------------------------------------------------------- /** * Gets the estimated duration of this unit in the ISO calendar system. * <p> @@ -233,41 +224,40 @@ */ @Override public boolean isDurationEstimated() { - return isDateUnit(); + return this.compareTo(DAYS) >= 0; } //----------------------------------------------------------------------- /** * Checks if this unit is a date unit. + * <p> + * All units from days to eras inclusive are date-based. + * Time-based units and {@code FOREVER} return false. * * @return true if a date unit, false if a time unit */ - public boolean isDateUnit() { - return this.compareTo(DAYS) >= 0; + @Override + public boolean isDateBased() { + return this.compareTo(DAYS) >= 0 && this != FOREVER; } /** * Checks if this unit is a time unit. + * <p> + * All units from nanos to half-days inclusive are time-based. + * Date-based units and {@code FOREVER} return false. * * @return true if a time unit, false if a date unit */ - public boolean isTimeUnit() { + @Override + public boolean isTimeBased() { return this.compareTo(DAYS) < 0; } //----------------------------------------------------------------------- @Override public boolean isSupportedBy(Temporal temporal) { - if (this == FOREVER) { - return false; - } - if (temporal instanceof ChronoLocalDate) { - return isDateUnit(); - } - if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) { - return true; - } - return TemporalUnit.super.isSupportedBy(temporal); + return temporal.isSupported(this); } @SuppressWarnings("unchecked") @@ -279,13 +269,13 @@ //----------------------------------------------------------------------- @Override public long between(Temporal temporal1, Temporal temporal2) { - return temporal1.periodUntil(temporal2, this); + return temporal1.until(temporal2, this); } //----------------------------------------------------------------------- @Override public String toString() { - return getName(); + return name; } }
--- a/src/share/classes/java/time/temporal/IsoFields.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/IsoFields.java Wed Jul 24 08:22:32 2013 -0300 @@ -71,6 +71,8 @@ import java.time.Duration; import java.time.LocalDate; +import java.time.ZoneId; +import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.chrono.IsoChronology; import java.time.format.ResolverStyle; @@ -289,10 +291,6 @@ private static enum Field implements TemporalField { DAY_OF_QUARTER { @Override - public String getName() { - return "DayOfQuarter"; - } - @Override public TemporalUnit getBaseUnit() { return DAYS; } @@ -344,17 +342,21 @@ return (R) temporal.with(DAY_OF_YEAR, temporal.getLong(DAY_OF_YEAR) + (newValue - curValue)); } @Override - public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long doq, ResolverStyle resolverStyle) { - if ((temporal.isSupported(YEAR) && temporal.isSupported(QUARTER_OF_YEAR)) == false) { + public ChronoLocalDate resolve( + Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Long yearLong = fieldValues.get(YEAR); + Long qoyLong = fieldValues.get(QUARTER_OF_YEAR); + if (yearLong == null || qoyLong == null) { return null; } - int y = temporal.get(YEAR); // validated + int y = YEAR.checkValidIntValue(yearLong); // always validate + long doq = fieldValues.get(DAY_OF_QUARTER); LocalDate date; if (resolverStyle == ResolverStyle.LENIENT) { - long qoy = temporal.getLong(QUARTER_OF_YEAR); // unvalidated - date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3)); + date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3)); + doq = Math.subtractExact(doq, 1); } else { - int qoy = temporal.get(QUARTER_OF_YEAR); // validated + int qoy = QUARTER_OF_YEAR.range().checkValidIntValue(qoyLong, QUARTER_OF_YEAR); // validated date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1); if (doq < 1 || doq > 90) { if (resolverStyle == ResolverStyle.STRICT) { @@ -363,21 +365,20 @@ range().checkValidValue(doq, this); // allow 1-92 rolling into next quarter } } + doq--; } - long epochDay = Math.addExact(date.toEpochDay(), Math.subtractExact(doq, 1)); - Map<TemporalField, Long> result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, epochDay); - result.put(YEAR, null); - result.put(QUARTER_OF_YEAR, null); - return result; + fieldValues.remove(this); + fieldValues.remove(YEAR); + fieldValues.remove(QUARTER_OF_YEAR); + return date.plusDays(doq); + } + @Override + public String toString() { + return "DayOfQuarter"; } }, QUARTER_OF_YEAR { @Override - public String getName() { - return "QuarterOfYear"; - } - @Override public TemporalUnit getBaseUnit() { return QUARTER_YEARS; } @@ -409,20 +410,19 @@ range().checkValidValue(newValue, this); // strictly check from 1 to 4 return (R) temporal.with(MONTH_OF_YEAR, temporal.getLong(MONTH_OF_YEAR) + (newValue - curValue) * 3); } + @Override + public String toString() { + return "QuarterOfYear"; + } }, WEEK_OF_WEEK_BASED_YEAR { @Override - public String getName() { - return "WeekOfWeekBasedYear"; - } - - @Override public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() .getLocaleResources(locale); ResourceBundle rb = lr.getJavaTimeFormatData(); - return rb.containsKey("field.week") ? rb.getString("field.week") : getName(); + return rb.containsKey("field.week") ? rb.getString("field.week") : toString(); } @Override @@ -463,14 +463,18 @@ return (R) temporal.plus(Math.subtractExact(newValue, getFrom(temporal)), WEEKS); } @Override - public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long wowby, ResolverStyle resolverStyle) { - if ((temporal.isSupported(WEEK_BASED_YEAR) && temporal.isSupported(DAY_OF_WEEK)) == false) { + public ChronoLocalDate resolve( + Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Long wbyLong = fieldValues.get(WEEK_BASED_YEAR); + Long dowLong = fieldValues.get(DAY_OF_WEEK); + if (wbyLong == null || dowLong == null) { return null; } - int wby = temporal.get(WEEK_BASED_YEAR); // validated + int wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR); // always validate + long wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR); LocalDate date = LocalDate.of(wby, 1, 4); if (resolverStyle == ResolverStyle.LENIENT) { - long dow = temporal.getLong(DAY_OF_WEEK); // unvalidated + long dow = dowLong; // unvalidated if (dow > 7) { date = date.plusWeeks((dow - 1) / 7); dow = ((dow - 1) % 7) + 1; @@ -480,7 +484,7 @@ } date = date.plusWeeks(Math.subtractExact(wowby, 1)).with(DAY_OF_WEEK, dow); } else { - int dow = temporal.get(DAY_OF_WEEK); // validated + int dow = DAY_OF_WEEK.checkValidIntValue(dowLong); // validated if (wowby < 1 || wowby > 52) { if (resolverStyle == ResolverStyle.STRICT) { getWeekRange(date).checkValidValue(wowby, this); // only allow exact range @@ -490,19 +494,18 @@ } date = date.plusWeeks(wowby - 1).with(DAY_OF_WEEK, dow); } - Map<TemporalField, Long> result = new HashMap<>(2, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(WEEK_BASED_YEAR, null); - result.put(DAY_OF_WEEK, null); - return result; + fieldValues.remove(this); + fieldValues.remove(WEEK_BASED_YEAR); + fieldValues.remove(DAY_OF_WEEK); + return date; + } + @Override + public String toString() { + return "WeekOfWeekBasedYear"; } }, WEEK_BASED_YEAR { @Override - public String getName() { - return "WeekBasedYear"; - } - @Override public TemporalUnit getBaseUnit() { return WEEK_BASED_YEARS; } @@ -537,6 +540,10 @@ date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week); return (R) date.with(date); } + @Override + public String toString() { + return "WeekBasedYear"; + } }; @Override @@ -545,13 +552,13 @@ } @Override - public ValueRange rangeRefinedBy(TemporalAccessor temporal) { - return range(); + public boolean isTimeBased() { + return false; } @Override - public String toString() { - return getName(); + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + return range(); } //------------------------------------------------------------------------- @@ -636,11 +643,6 @@ } @Override - public String getName() { - return name; - } - - @Override public Duration getDuration() { return duration; } @@ -651,6 +653,16 @@ } @Override + public boolean isDateBased() { + return true; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(Temporal temporal) { return temporal.isSupported(EPOCH_DAY); } @@ -658,7 +670,7 @@ @SuppressWarnings("unchecked") @Override public <R extends Temporal> R addTo(R temporal, long amount) { - switch(this) { + switch (this) { case WEEK_BASED_YEARS: return (R) temporal.with(WEEK_BASED_YEAR, Math.addExact(temporal.get(WEEK_BASED_YEAR), amount)); @@ -678,7 +690,7 @@ return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR), temporal1.getLong(WEEK_BASED_YEAR)); case QUARTER_YEARS: - return temporal1.periodUntil(temporal2, MONTHS) / 3; + return temporal1.until(temporal2, MONTHS) / 3; default: throw new IllegalStateException("Unreachable"); } @@ -686,8 +698,7 @@ @Override public String toString() { - return getName(); - + return name; } } }
--- a/src/share/classes/java/time/temporal/JulianFields.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/JulianFields.java Wed Jul 24 08:22:32 2013 -0300 @@ -66,6 +66,9 @@ import static java.time.temporal.ChronoUnit.FOREVER; import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Collections; import java.util.Map; @@ -233,11 +236,6 @@ //----------------------------------------------------------------------- @Override - public String getName() { - return name; - } - - @Override public TemporalUnit getBaseUnit() { return baseUnit; } @@ -253,6 +251,11 @@ } @Override + public boolean isTimeBased() { + return false; + } + + @Override public ValueRange range() { return range; } @@ -287,15 +290,14 @@ //----------------------------------------------------------------------- @Override - public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value, ResolverStyle resolverStyle) { - long epochDay; + public ChronoLocalDate resolve( + Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + long value = fieldValues.remove(this); if (resolverStyle == ResolverStyle.LENIENT) { - epochDay = Math.subtractExact(value, offset); - } else { - range().checkValidValue(value, this); - epochDay = value - offset; + return chronology.dateEpochDay(Math.subtractExact(value, offset)); } - return Collections.<TemporalField, Long>singletonMap(EPOCH_DAY, epochDay); + range().checkValidValue(value, this); + return chronology.dateEpochDay(value - offset); } //-----------------------------------------------------------------------
--- a/src/share/classes/java/time/temporal/Temporal.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/Temporal.java Wed Jul 24 08:22:32 2013 -0300 @@ -62,7 +62,6 @@ package java.time.temporal; import java.time.DateTimeException; -import java.time.ZoneId; /** * Framework-level interface defining read-write access to a temporal object, @@ -81,7 +80,8 @@ * See {@link ChronoField} for the standard set of fields. * <p> * Two pieces of date/time information cannot be represented by numbers, - * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}. + * the {@linkplain java.time.chrono.Chronology chronology} and the + * {@linkplain java.time.ZoneId time-zone}. * These can be accessed via {@link #query(TemporalQuery) queries} using * the static methods defined on {@link TemporalQuery}. * <p> @@ -129,6 +129,29 @@ public interface Temporal extends TemporalAccessor { /** + * Checks if the specified unit is supported. + * <p> + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * + * @implSpec + * Implementations must check and handle all units defined in {@link ChronoUnit}. + * If the unit is supported, then true must be returned, otherwise false must be returned. + * <p> + * If the field is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * <p> + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + boolean isSupported(TemporalUnit unit); + + /** * Returns an adjusted object of the same type as this object with the adjustment made. * <p> * This adjusts this date-time according to the rules of the specified adjuster. @@ -352,7 +375,7 @@ * The start and end points are {@code this} and the specified temporal. * The result will be negative if the end is before the start. * For example, the period in hours between two temporal objects can be - * calculated using {@code startTime.periodUntil(endTime, HOURS)}. + * calculated using {@code startTime.until(endTime, HOURS)}. * <p> * The calculation returns a whole number, representing the number of * complete units between the two temporals. @@ -364,7 +387,7 @@ * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: * <pre> * // these two lines are equivalent - * temporal = start.periodUntil(end, unit); + * temporal = start.until(end, unit); * temporal = unit.between(start, end); * </pre> * The choice should be made based on which makes the code more readable. @@ -372,7 +395,7 @@ * For example, this method allows the number of days between two dates to * be calculated: * <pre> - * long daysBetween = start.periodUntil(end, DAYS); + * long daysBetween = start.until(end, DAYS); * // or alternatively * long daysBetween = DAYS.between(start, end); * </pre> @@ -399,7 +422,8 @@ * return unit.between(this, endTemporal); * </pre> * <p> - * Neither this object, nor the specified temporal, may be altered. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param endTemporal the end temporal, of the same type as this object, not null * @param unit the unit to measure the amount in, not null @@ -410,6 +434,6 @@ * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ - long periodUntil(Temporal endTemporal, TemporalUnit unit); + long until(Temporal endTemporal, TemporalUnit unit); }
--- a/src/share/classes/java/time/temporal/TemporalAccessor.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/TemporalAccessor.java Wed Jul 24 08:22:32 2013 -0300 @@ -62,7 +62,6 @@ package java.time.temporal; import java.time.DateTimeException; -import java.time.ZoneId; import java.util.Objects; /** @@ -80,7 +79,8 @@ * See {@link ChronoField} for the standard set of fields. * <p> * Two pieces of date/time information cannot be represented by numbers, - * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}. + * the {@linkplain java.time.chrono.Chronology chronology} and the + * {@linkplain java.time.ZoneId time-zone}. * These can be accessed via {@linkplain #query(TemporalQuery) queries} using * the static methods defined on {@link TemporalQuery}. * <p> @@ -111,13 +111,14 @@ * * @implSpec * Implementations must check and handle all fields defined in {@link ChronoField}. - * If the field is supported, then true is returned, otherwise false + * If the field is supported, then true must be returned, otherwise false must be returned. * <p> * If the field is not a {@code ChronoField}, then the result of this method * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} * passing {@code this} as the argument. * <p> - * Implementations must not alter either this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param field the field to check, null returns false * @return true if this date-time can be queried for the field, false if not @@ -146,7 +147,8 @@ * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessorl)} * passing {@code this} as the argument. * <p> - * Implementations must not alter either this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * <p> * The default implementation must behave equivalent to this code: * <pre> @@ -154,7 +156,7 @@ * if (isSupported(field)) { * return field.range(); * } - * throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + * throw new UnsupportedTemporalTypeException("Unsupported field: " + field); * } * return field.rangeRefinedBy(this); * </pre> @@ -169,7 +171,7 @@ if (isSupported(field)) { return field.range(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } Objects.requireNonNull(field, "field"); return field.rangeRefinedBy(this); @@ -193,7 +195,8 @@ * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} * passing {@code this} as the argument. * <p> - * Implementations must not alter this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * <p> * The default implementation must behave equivalent to this code: * <pre> @@ -240,7 +243,8 @@ * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} * passing {@code this} as the argument. * <p> - * Implementations must not alter either this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param field the field to get, not null * @return the value for the field @@ -291,6 +295,9 @@ * } * return TemporalAccessor.super.query(query); * </pre> + * <p> + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param <R> the type of the result * @param query the query to invoke, not null
--- a/src/share/classes/java/time/temporal/TemporalField.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/TemporalField.java Wed Jul 24 08:22:32 2013 -0300 @@ -62,6 +62,9 @@ package java.time.temporal; import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Locale; import java.util.Map; @@ -93,29 +96,19 @@ public interface TemporalField { /** - * Gets a descriptive name for the field. - * <p> - * The should be of the format 'BaseOfRange', such as 'MonthOfYear', - * unless the field has a range of {@code FOREVER}, when only - * the base unit is mentioned, such as 'Year' or 'Era'. - * - * @return the name, not null - */ - String getName(); - - /** * Gets the display name for the field in the requested locale. * <p> - * If there is no display name for the locale the value of {@code getName} - * is returned. + * If there is no display name for the locale then a suitable default must be returned. + * <p> + * The default implementation must check the locale is not null + * and return {@code toString()}. * * @param locale the locale to use, not null - * @return the display name for the locale or the value of {@code getName}, - * not null + * @return the display name for the locale or a suitable default, not null */ default String getDisplayName(Locale locale) { - Objects.requireNonNull(locale, "local"); - return getName(); + Objects.requireNonNull(locale, "locale"); + return toString(); } /** @@ -164,28 +157,24 @@ * <p> * A field is date-based if it can be derived from * {@link ChronoField#EPOCH_DAY EPOCH_DAY}. - * <p> - * The default implementation must return false. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a field like minute-of-week. * * @return true if this field is a component of a date */ - default boolean isDateBased() { - return false; - } + boolean isDateBased(); /** * Checks if this field represents a component of a time. * <p> * A field is time-based if it can be derived from * {@link ChronoField#NANO_OF_DAY NANO_OF_DAY}. - * <p> - * The default implementation must return false. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a field like minute-of-week. * * @return true if this field is a component of a time */ - default boolean isTimeBased() { - return false; - } + boolean isTimeBased(); //----------------------------------------------------------------------- /** @@ -319,45 +308,79 @@ <R extends Temporal> R adjustInto(R temporal, long newValue); /** - * Resolves this field to provide a simpler alternative. + * Resolves this field to provide a simpler alternative or a date. * <p> * This method is invoked during the resolve phase of parsing. * It is designed to allow application defined fields to be simplified into - * more standard fields, such as those on {@code ChronoField}. - * <p> - * The method will only be invoked if the specified temporal supports this field. - * The value of this field is provided. + * more standard fields, such as those on {@code ChronoField}, or into a date. * <p> - * The temporal must be queried using the methods of {@code TemporalAccessor}, - * not using {@code getFrom}, {@code isSupportedBy} or {@code rangeRefinedBy}. - * Before querying any field, implementations must ensure it is supported, as - * exceptions of this type would negatively affect the calculation of a parsed result. + * Applications should not normally invoke this method directly. + * + * @implSpec + * If an implementation represents a field that can be simplified, or + * combined with others, then this method must be implemented. + * <p> + * The specified map contains the current state of the parse. + * The map is mutable and must be mutated to resolve the field and + * any related fields. This method will only be invoked during parsing + * if the map contains this field, and implementations should therefore + * assume this field is present. * <p> - * If this field can resolve, it must return a map, if not it must return null. - * The returned map contains the changes to be made to the temporal, expressed - * as field-value pairs. If the value for a field is null, the field is to be - * removed from the temporal. A null key must not be added to the result map. + * Resolving a field will consist of looking at the value of this field, + * and potentially other fields, and either updating the map with a + * simpler value, such as a {@code ChronoField}, or returning a + * complete {@code ChronoLocalDate}. If a resolve is successful, + * the code must remove all the fields that were resolved from the map, + * including this field. + * <p> + * For example, the {@code IsoFields} class contains the quarter-of-year + * and day-of-quarter fields. The implementation of this method in that class + * resolves the two fields plus the {@link ChronoField#YEAR YEAR} into a + * complete {@code LocalDate}. The resolve method will remove all three + * fields from the map before returning the {@code LocalDate}. * <p> - * If the result is non-null, this field will be removed from the temporal. - * This field should not be added to the result map. + * If resolution should be possible, but the data is invalid, the resolver + * style should be used to determine an appropriate level of leniency, which + * may require throwing a {@code DateTimeException} or {@code ArithmeticException}. + * If no resolution is possible, the resolve method must return null. * <p> - * The {@link ResolverStyle} should be used by implementations to determine - * how to perform the resolve. + * When resolving time fields, the map will be altered and null returned. + * When resolving date fields, the date is normally returned from the method, + * with the map altered to remove the resolved fields. However, it would also + * be acceptable for the date fields to be resolved into other {@code ChronoField} + * instances that can produce a date, such as {@code EPOCH_DAY}. + * <p> + * The zone is not normally required for resolution, but is provided for completeness. * <p> * The default implementation must return null. * - * @param temporal the temporal to resolve, not null - * @param value the value of this field + * @param fieldValues the map of fields to values, which can be updated, not null + * @param chronology the effective chronology, not null + * @param zone the effective zone, not null * @param resolverStyle the requested type of resolve, not null - * @return a map of fields to update in the temporal, with a mapping to null - * indicating a deletion. The whole map must be null if no resolving occurred + * @return the resolved date; null if resolving only changed the map, + * or no resolve occurred + * @throws ArithmeticException if numeric overflow occurs * @throws DateTimeException if resolving results in an error. This must not be thrown * by querying a field on the temporal without first checking if it is supported - * @throws ArithmeticException if numeric overflow occurs */ - default Map<TemporalField, Long> resolve( - TemporalAccessor temporal, long value, ResolverStyle resolverStyle) { + default ChronoLocalDate resolve( + Map<TemporalField, Long> fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { return null; } + /** + * Gets a descriptive name for the field. + * <p> + * The should be of the format 'BaseOfRange', such as 'MonthOfYear', + * unless the field has a range of {@code FOREVER}, when only + * the base unit is mentioned, such as 'Year' or 'Era'. + * + * @return the name of the field, not null + */ + @Override + String toString(); + + }
--- a/src/share/classes/java/time/temporal/TemporalUnit.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/TemporalUnit.java Wed Jul 24 08:22:32 2013 -0300 @@ -63,7 +63,11 @@ import java.time.DateTimeException; import java.time.Duration; +import java.time.LocalTime; import java.time.Period; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; /** * A unit of date-time, such as Days or Hours. @@ -93,15 +97,6 @@ public interface TemporalUnit { /** - * Gets a descriptive name for the unit. - * <p> - * This should be in the plural and upper-first camel case, such as 'Days' or 'Minutes'. - * - * @return the name, not null - */ - String getName(); - - /** * Gets the duration of this unit, which may be an estimate. * <p> * All units return a duration measured in standard nanoseconds from this method. @@ -132,6 +127,33 @@ //----------------------------------------------------------------------- /** + * Checks if this unit represents a component of a date. + * <p> + * A date is time-based if it can be used to imply meaning from a date. + * It must have a {@linkplain #getDuration() duration} that is an integral + * multiple of the length of a standard day. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a unit like 36 hours. + * + * @return true if this unit is a component of a date + */ + boolean isDateBased(); + + /** + * Checks if this unit represents a component of a time. + * <p> + * A unit is time-based if it can be used to imply meaning from a time. + * It must have a {@linkplain #getDuration() duration} that divides into + * the length of a standard day without remainder. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a unit like 36 hours. + * + * @return true if this unit is a component of a time + */ + boolean isTimeBased(); + + //----------------------------------------------------------------------- + /** * Checks if this unit is supported by the specified temporal object. * <p> * This checks that the implementing date-time can add/subtract this unit. @@ -144,6 +166,15 @@ * @return true if the unit is supported */ default boolean isSupportedBy(Temporal temporal) { + if (temporal instanceof LocalTime) { + return isTimeBased(); + } + if (temporal instanceof ChronoLocalDate) { + return isDateBased(); + } + if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) { + return true; + } try { temporal.plus(1, this); return true; @@ -212,11 +243,11 @@ * <p> * There are two equivalent ways of using this method. * The first is to invoke this method directly. - * The second is to use {@link Temporal#periodUntil(Temporal, TemporalUnit)}: + * The second is to use {@link Temporal#until(Temporal, TemporalUnit)}: * <pre> * // these two lines are equivalent * between = thisUnit.between(start, end); - * between = start.periodUntil(end, thisUnit); + * between = start.until(end, thisUnit); * </pre> * The choice should be made based on which makes the code more readable. * <p> @@ -225,7 +256,7 @@ * <pre> * long daysBetween = DAYS.between(start, end); * // or alternatively - * long daysBetween = start.periodUntil(end, DAYS); + * long daysBetween = start.until(end, DAYS); * </pre> * <p> * Implementations should perform any queries or calculations using the units @@ -245,7 +276,9 @@ //----------------------------------------------------------------------- /** - * Outputs this unit as a {@code String} using the name. + * Gets a descriptive name for the unit. + * <p> + * This should be in the plural and upper-first camel case, such as 'Days' or 'Minutes'. * * @return the name of this unit, not null */
--- a/src/share/classes/java/time/temporal/ValueRange.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/ValueRange.java Wed Jul 24 08:22:32 2013 -0300 @@ -331,7 +331,7 @@ private String genInvalidFieldMessage(TemporalField field, long value) { if (field != null) { - return "Invalid value for " + field.getName() + " (valid values " + this + "): " + value; + return "Invalid value for " + field + " (valid values " + this + "): " + value; } else { return "Invalid value (valid values " + this + "): " + value; }
--- a/src/share/classes/java/time/temporal/WeekFields.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/time/temporal/WeekFields.java Wed Jul 24 08:22:32 2013 -0300 @@ -75,7 +75,9 @@ import java.io.InvalidObjectException; import java.io.Serializable; +import java.time.DateTimeException; import java.time.DayOfWeek; +import java.time.ZoneId; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.format.ResolverStyle; @@ -395,6 +397,11 @@ * <p> * For example, if the first day-of-week is Sunday, then that will have the * value 1, with other days ranging from Monday as 2 to Saturday as 7. + * <p> + * In the resolving phase of parsing, a localized day-of-week will be converted + * to a standardized {@code ChronoField} day-of-week. + * The day-of-week must be in the valid range 1 to 7. + * Other fields in this class build dates using the standardized day-of-week. * * @return a field providing access to the day-of-week with localized numbering, not null */ @@ -421,6 +428,26 @@ * - if the 5th day of the month is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br> * <p> * This field can be used with any calendar system. + * <p> + * In the resolving phase of parsing, a date can be created from a year, + * week-of-month, month-of-year and day-of-week. + * <p> + * In {@linkplain ResolverStyle#STRICT strict mode}, all four fields are + * validated against their range of valid values. The week-of-month field + * is validated to ensure that the resulting month is the month requested. + * <p> + * In {@linkplain ResolverStyle#SMART smart mode}, all four fields are + * validated against their range of valid values. The week-of-month field + * is validated from 0 to 6, meaning that the resulting date can be in a + * different month to that specified. + * <p> + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following four stage approach. + * First, create a date on the first day of the first week of January in the requested year. + * Then take the month-of-year, subtract one, and add the amount in months to the date. + * Then take the week-of-month, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-of-month, not null */ @@ -447,6 +474,25 @@ * - if the 5th day of the year is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br> * <p> * This field can be used with any calendar system. + * <p> + * In the resolving phase of parsing, a date can be created from a year, + * week-of-year and day-of-week. + * <p> + * In {@linkplain ResolverStyle#STRICT strict mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated to ensure that the resulting year is the year requested. + * <p> + * In {@linkplain ResolverStyle#SMART smart mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated from 0 to 54, meaning that the resulting date can be in a + * different year to that specified. + * <p> + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following three stage approach. + * First, create a date on the first day of the first week in the requested year. + * Then take the week-of-year, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-of-year, not null */ @@ -477,6 +523,26 @@ * the 1st to 4th is in week one<br> * <p> * This field can be used with any calendar system. + * <p> + * In the resolving phase of parsing, a date can be created from a week-based-year, + * week-of-year and day-of-week. + * <p> + * In {@linkplain ResolverStyle#STRICT strict mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated to ensure that the resulting week-based-year is the + * week-based-year requested. + * <p> + * In {@linkplain ResolverStyle#SMART smart mode}, all three fields are + * validated against their range of valid values. The week-of-week-based-year field + * is validated from 1 to 53, meaning that the resulting date can be in the + * following week-based-year to that specified. + * <p> + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following three stage approach. + * First, create a date on the first day of the first week in the requested week-based-year. + * Then take the week-of-week-based-year, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-of-week-based-year, not null */ @@ -499,6 +565,26 @@ * is in the last week of the previous year. * <p> * This field can be used with any calendar system. + * <p> + * In the resolving phase of parsing, a date can be created from a week-based-year, + * week-of-year and day-of-week. + * <p> + * In {@linkplain ResolverStyle#STRICT strict mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated to ensure that the resulting week-based-year is the + * week-based-year requested. + * <p> + * In {@linkplain ResolverStyle#SMART smart mode}, all three fields are + * validated against their range of valid values. The week-of-week-based-year field + * is validated from 1 to 53, meaning that the resulting date can be in the + * following week-based-year to that specified. + * <p> + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following three stage approach. + * First, create a date on the first day of the first week in the requested week-based-year. + * Then take the week-of-week-based-year, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-based-year, not null */ @@ -615,9 +701,9 @@ * @param dow the day of the week * @return a ChronoLocalDate for the requested year, week of year, and day of week */ - private ChronoLocalDate<?> ofWeekBasedYear(Chronology chrono, + private ChronoLocalDate ofWeekBasedYear(Chronology chrono, int yowby, int wowby, int dow) { - ChronoLocalDate<?> date = chrono.date(yowby, 1, 1); + ChronoLocalDate date = chrono.date(yowby, 1, 1); int ldow = localizedDayOfWeek(date); int offset = startOfWeekOffset(1, ldow); @@ -671,6 +757,11 @@ return Math.floorMod(isoDow - sow, 7) + 1; } + private int localizedDayOfWeek(int isoDow) { + int sow = weekDef.getFirstDayOfWeek().getValue(); + return Math.floorMod(isoDow - sow, 7) + 1; + } + private long localizedWeekOfMonth(TemporalAccessor temporal) { int dow = localizedDayOfWeek(temporal); int dom = temporal.get(DAY_OF_MONTH); @@ -800,75 +891,121 @@ } @Override - public Map<TemporalField, Long> resolve(TemporalAccessor temporal, long value, ResolverStyle resolverStyle) { - int newValue = range.checkValidIntValue(value, this); - int sow = weekDef.getFirstDayOfWeek().getValue(); + public ChronoLocalDate resolve( + Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + final long value = fieldValues.get(this); + final int newValue = Math.toIntExact(value); // broad limit makes overflow checking lighter + // first convert localized day-of-week to ISO day-of-week + // doing this first handles case where both ISO and localized were parsed and might mismatch + // day-of-week is always strict as two different day-of-week values makes lenient complex if (rangeUnit == WEEKS) { // day-of-week - int isoDow = Math.floorMod((sow - 1) + (newValue - 1), 7) + 1; - return Collections.<TemporalField, Long>singletonMap(DAY_OF_WEEK, (long) isoDow); - } - if (temporal.isSupported(DAY_OF_WEEK) == false) { + final int checkedValue = range.checkValidIntValue(value, this); // no leniency as too complex + final int startDow = weekDef.getFirstDayOfWeek().getValue(); + long isoDow = Math.floorMod((startDow - 1) + (checkedValue - 1), 7) + 1; + fieldValues.remove(this); + fieldValues.put(DAY_OF_WEEK, isoDow); return null; } - Chronology chrono = Chronology.from(temporal); // defaults to ISO - int dow = localizedDayOfWeek(temporal); - if (temporal.isSupported(YEAR)) { - int year = temporal.get(YEAR); - if (rangeUnit == MONTHS) { // week-of-month - if (temporal.isSupported(MONTH_OF_YEAR) == false) { - return null; - } - int month = temporal.get(ChronoField.MONTH_OF_YEAR); - @SuppressWarnings("rawtypes") - ChronoLocalDate date = chrono.date(year, month, 1); - int dateDow = localizedDayOfWeek(date); - long weeks = newValue - localizedWeekOfMonth(date); - int days = dow - dateDow; - date = date.plus(weeks * 7 + days, DAYS); - Map<TemporalField, Long> result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(YEAR, null); - result.put(MONTH_OF_YEAR, null); - result.put(DAY_OF_WEEK, null); - return result; - } else if (rangeUnit == YEARS) { // week-of-year - @SuppressWarnings("rawtypes") - ChronoLocalDate date = chrono.date(year, 1, 1); - int dateDow = localizedDayOfWeek(date); - long weeks = newValue - localizedWeekOfYear(date); - int days = dow - dateDow; - date = date.plus(weeks * 7 + days, DAYS); - Map<TemporalField, Long> result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(YEAR, null); - result.put(DAY_OF_WEEK, null); - return result; + + // can only build date if ISO day-of-week is present + if (fieldValues.containsKey(DAY_OF_WEEK) == false) { + return null; + } + int isoDow = DAY_OF_WEEK.checkValidIntValue(fieldValues.get(DAY_OF_WEEK)); + int dow = localizedDayOfWeek(isoDow); + + // build date + if (fieldValues.containsKey(YEAR)) { + int year = YEAR.checkValidIntValue(fieldValues.get(YEAR)); // validate + if (rangeUnit == MONTHS && fieldValues.containsKey(MONTH_OF_YEAR)) { // week-of-month + long month = fieldValues.get(MONTH_OF_YEAR); // not validated yet + return resolveWoM(fieldValues, chronology, year, month, newValue, dow, resolverStyle); } - } else if (rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) { - if (temporal.isSupported(weekDef.weekBasedYear) && - temporal.isSupported(weekDef.weekOfWeekBasedYear)) { - // week-of-week-based-year and year-of-week-based-year - int yowby = temporal.get(weekDef.weekBasedYear); - int wowby = temporal.get(weekDef.weekOfWeekBasedYear); - ChronoLocalDate<?> date = ofWeekBasedYear(Chronology.from(temporal), yowby, wowby, dow); - - Map<TemporalField, Long> result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(DAY_OF_WEEK, null); - result.put(weekDef.weekOfWeekBasedYear, null); - result.put(weekDef.weekBasedYear, null); - return result; + if (rangeUnit == YEARS) { // week-of-year + return resolveWoY(fieldValues, chronology, year, newValue, dow, resolverStyle); } + } else if ((rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) && + fieldValues.containsKey(weekDef.weekBasedYear) && + fieldValues.containsKey(weekDef.weekOfWeekBasedYear)) { // week-of-week-based-year and year-of-week-based-year + return resolveWBY(fieldValues, chronology, dow, resolverStyle); } return null; } - //----------------------------------------------------------------------- - @Override - public String getName() { - return name; + private ChronoLocalDate resolveWoM( + Map<TemporalField, Long> fieldValues, Chronology chrono, int year, long month, long wom, int localDow, ResolverStyle resolverStyle) { + ChronoLocalDate date; + if (resolverStyle == ResolverStyle.LENIENT) { + date = chrono.date(year, 1, 1).plus(Math.subtractExact(month, 1), MONTHS); + long weeks = Math.subtractExact(wom, localizedWeekOfMonth(date)); + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(Math.addExact(Math.multiplyExact(weeks, 7), days), DAYS); + } else { + int monthValid = MONTH_OF_YEAR.checkValidIntValue(month); // validate + date = chrono.date(year, monthValid, 1); + int womInt = range.checkValidIntValue(wom, this); // validate + int weeks = (int) (womInt - localizedWeekOfMonth(date)); // safe from overflow + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(weeks * 7 + days, DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.getLong(MONTH_OF_YEAR) != month) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + } + fieldValues.remove(this); + fieldValues.remove(YEAR); + fieldValues.remove(MONTH_OF_YEAR); + fieldValues.remove(DAY_OF_WEEK); + return date; } + private ChronoLocalDate resolveWoY( + Map<TemporalField, Long> fieldValues, Chronology chrono, int year, long woy, int localDow, ResolverStyle resolverStyle) { + ChronoLocalDate date = chrono.date(year, 1, 1); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(woy, localizedWeekOfYear(date)); + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(Math.addExact(Math.multiplyExact(weeks, 7), days), DAYS); + } else { + int womInt = range.checkValidIntValue(woy, this); // validate + int weeks = (int) (womInt - localizedWeekOfYear(date)); // safe from overflow + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(weeks * 7 + days, DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.getLong(YEAR) != year) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + } + fieldValues.remove(this); + fieldValues.remove(YEAR); + fieldValues.remove(DAY_OF_WEEK); + return date; + } + + private ChronoLocalDate resolveWBY( + Map<TemporalField, Long> fieldValues, Chronology chrono, int localDow, ResolverStyle resolverStyle) { + int yowby = weekDef.weekBasedYear.range().checkValidIntValue( + fieldValues.get(weekDef.weekBasedYear), weekDef.weekBasedYear); + ChronoLocalDate date; + if (resolverStyle == ResolverStyle.LENIENT) { + date = ofWeekBasedYear(chrono, yowby, 1, localDow); + long wowby = fieldValues.get(weekDef.weekOfWeekBasedYear); + long weeks = Math.subtractExact(wowby, 1); + date = date.plus(weeks, WEEKS); + } else { + int wowby = weekDef.weekOfWeekBasedYear.range().checkValidIntValue( + fieldValues.get(weekDef.weekOfWeekBasedYear), weekDef.weekOfWeekBasedYear); // validate + date = ofWeekBasedYear(chrono, yowby, wowby, localDow); + if (resolverStyle == ResolverStyle.STRICT && localizedWeekBasedYear(date) != yowby) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different week-based-year"); + } + } + fieldValues.remove(this); + fieldValues.remove(weekDef.weekBasedYear); + fieldValues.remove(weekDef.weekOfWeekBasedYear); + fieldValues.remove(DAY_OF_WEEK); + return date; + } + + //----------------------------------------------------------------------- @Override public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); @@ -876,9 +1013,9 @@ LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() .getLocaleResources(locale); ResourceBundle rb = lr.getJavaTimeFormatData(); - return rb.containsKey("field.week") ? rb.getString("field.week") : getName(); + return rb.containsKey("field.week") ? rb.getString("field.week") : name; } - return getName(); + return name; } @Override @@ -897,6 +1034,11 @@ } @Override + public boolean isTimeBased() { + return false; + } + + @Override public ValueRange range() { return range; } @@ -988,7 +1130,7 @@ //----------------------------------------------------------------------- @Override public String toString() { - return getName() + "[" + weekDef.toString() + "]"; + return name + "[" + weekDef.toString() + "]"; } } }
--- a/src/share/classes/java/util/PriorityQueue.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/PriorityQueue.java Wed Jul 24 08:22:32 2013 -0300 @@ -136,6 +136,19 @@ } /** + * Creates a {@code PriorityQueue} with the default initial capacity + * that orders its elements according to the specified comparator. + * + * @param comparator the comparator that will be used to order this + * priority queue. If {@code null}, the {@linkplain Comparable + * natural ordering} of the elements will be used. + * @since 1.8 + */ + public PriorityQueue(Comparator<? super E> comparator) { + this(DEFAULT_INITIAL_CAPACITY, comparator); + } + + /** * Creates a {@code PriorityQueue} with the specified initial capacity * that orders its elements according to the specified comparator. *
--- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jul 24 08:22:32 2013 -0300 @@ -265,7 +265,8 @@ * @param <K> the type of keys maintained by this map * @param <V> the type of mapped values */ -public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, Serializable { +public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> + implements ConcurrentMap<K,V>, Serializable { private static final long serialVersionUID = 7249069246763182397L; /* @@ -439,16 +440,18 @@ * related operations (which is the main reason we cannot use * existing collections such as TreeMaps). TreeBins contain * Comparable elements, but may contain others, as well as - * elements that are Comparable but not necessarily Comparable - * for the same T, so we cannot invoke compareTo among them. To - * handle this, the tree is ordered primarily by hash value, then - * by Comparable.compareTo order if applicable. On lookup at a - * node, if elements are not comparable or compare as 0 then both - * left and right children may need to be searched in the case of - * tied hash values. (This corresponds to the full list search - * that would be necessary if all elements were non-Comparable and - * had tied hashes.) The red-black balancing code is updated from - * pre-jdk-collections + * elements that are Comparable but not necessarily Comparable for + * the same T, so we cannot invoke compareTo among them. To handle + * this, the tree is ordered primarily by hash value, then by + * Comparable.compareTo order if applicable. On lookup at a node, + * if elements are not comparable or compare as 0 then both left + * and right children may need to be searched in the case of tied + * hash values. (This corresponds to the full list search that + * would be necessary if all elements were non-Comparable and had + * tied hashes.) On insertion, to keep a total ordering (or as + * close as is required here) across rebalancings, we compare + * classes and identityHashCodes as tie-breakers. The red-black + * balancing code is updated from pre-jdk-collections * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) * based in turn on Cormen, Leiserson, and Rivest "Introduction to * Algorithms" (CLR). @@ -478,6 +481,10 @@ * unused "Segment" class that is instantiated in minimal form * only when serializing. * + * Also, solely for compatibility with previous versions of this + * class, it extends AbstractMap, even though all of its methods + * are overridden, so it is just useless baggage. + * * This file is organized to make things a little easier to follow * while reading than they might otherwise: First the main static * declarations and utilities, then fields, then main public @@ -1352,6 +1359,7 @@ * Saves the state of the {@code ConcurrentHashMap} instance to a * stream (i.e., serializes it). * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData * the key (Object) and value (Object) * for each key-value mapping, followed by a null pair. @@ -1394,6 +1402,9 @@ /** * Reconstitutes the instance from a stream (that is, deserializes it). * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -2080,6 +2091,7 @@ * Creates a new {@link Set} backed by a ConcurrentHashMap * from the given type to {@code Boolean.TRUE}. * + * @param <K> the element type of the returned set * @return the new set * @since 1.8 */ @@ -2094,9 +2106,10 @@ * * @param initialCapacity The implementation performs internal * sizing to accommodate this many elements. + * @param <K> the element type of the returned set + * @return the new set * @throws IllegalArgumentException if the initial capacity of * elements is negative - * @return the new set * @since 1.8 */ public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) { @@ -2643,19 +2656,18 @@ p = pr; else if ((pk = p.key) == k || (pk != null && k.equals(pk))) return p; - else if (pl == null && pr == null) - break; + else if (pl == null) + p = pr; + else if (pr == null) + p = pl; else if ((kc != null || (kc = comparableClassFor(k)) != null) && (dir = compareComparables(kc, k, pk)) != 0) p = (dir < 0) ? pl : pr; - else if (pl == null) - p = pr; - else if (pr == null || - (q = pr.findTreeNode(h, k, kc)) == null) + else if ((q = pr.findTreeNode(h, k, kc)) != null) + return q; + else p = pl; - else - return q; } while (p != null); } return null; @@ -2682,6 +2694,23 @@ static final int READER = 4; // increment value for setting read lock /** + * Tie-breaking utility for ordering insertions when equal + * hashCodes and non-comparable. We don't require a total + * order, just a consistent insertion rule to maintain + * equivalence across rebalancings. Tie-breaking further than + * necessary simplifies testing a bit. + */ + static int tieBreakOrder(Object a, Object b) { + int d; + if (a == null || b == null || + (d = a.getClass().getName(). + compareTo(b.getClass().getName())) == 0) + d = (System.identityHashCode(a) <= System.identityHashCode(b) ? + -1 : 1); + return d; + } + + /** * Creates bin with initial set of nodes headed by b. */ TreeBin(TreeNode<K,V> b) { @@ -2697,21 +2726,21 @@ r = x; } else { - Object key = x.key; - int hash = x.hash; + K k = x.key; + int h = x.hash; Class<?> kc = null; for (TreeNode<K,V> p = r;;) { int dir, ph; - if ((ph = p.hash) > hash) + K pk = p.key; + if ((ph = p.hash) > h) dir = -1; - else if (ph < hash) + else if (ph < h) dir = 1; - else if ((kc != null || - (kc = comparableClassFor(key)) != null)) - dir = compareComparables(kc, key, p.key); - else - dir = 0; - TreeNode<K,V> xp = p; + else if ((kc == null && + (kc = comparableClassFor(k)) == null) || + (dir = compareComparables(kc, k, pk)) == 0) + dir = tieBreakOrder(k, pk); + TreeNode<K,V> xp = p; if ((p = (dir <= 0) ? p.left : p.right) == null) { x.parent = xp; if (dir <= 0) @@ -2725,6 +2754,7 @@ } } this.root = r; + assert checkInvariants(root); } /** @@ -2805,8 +2835,9 @@ */ final TreeNode<K,V> putTreeVal(int h, K k, V v) { Class<?> kc = null; + boolean searched = false; for (TreeNode<K,V> p = root;;) { - int dir, ph; K pk; TreeNode<K,V> q, pr; + int dir, ph; K pk; if (p == null) { first = root = new TreeNode<K,V>(h, k, v, null, null); break; @@ -2820,21 +2851,25 @@ else if ((kc == null && (kc = comparableClassFor(k)) == null) || (dir = compareComparables(kc, k, pk)) == 0) { - if (p.left == null) - dir = 1; - else if ((pr = p.right) == null || - (q = pr.findTreeNode(h, k, kc)) == null) - dir = -1; - else - return q; + if (!searched) { + TreeNode<K,V> q, ch; + searched = true; + if (((ch = p.left) != null && + (q = ch.findTreeNode(h, k, kc)) != null) || + ((ch = p.right) != null && + (q = ch.findTreeNode(h, k, kc)) != null)) + return q; + } + dir = tieBreakOrder(k, pk); } + TreeNode<K,V> xp = p; - if ((p = (dir < 0) ? p.left : p.right) == null) { + if ((p = (dir <= 0) ? p.left : p.right) == null) { TreeNode<K,V> x, f = first; first = x = new TreeNode<K,V>(h, k, v, f, xp); if (f != null) f.prev = x; - if (dir < 0) + if (dir <= 0) xp.left = x; else xp.right = x; @@ -3546,6 +3581,7 @@ * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param <U> the return type of the transformer * @since 1.8 */ public <U> void forEach(long parallelismThreshold, @@ -3569,6 +3605,7 @@ * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param <U> the return type of the search function * @return a non-null result from applying the given search * function on each (key, value), or null if none * @since 1.8 @@ -3592,6 +3629,7 @@ * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param <U> the return type of the transformer * @return the result of accumulating the given transformation * of all (key, value) pairs * @since 1.8 @@ -3710,6 +3748,7 @@ * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param <U> the return type of the transformer * @since 1.8 */ public <U> void forEachKey(long parallelismThreshold, @@ -3733,6 +3772,7 @@ * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param <U> the return type of the search function * @return a non-null result from applying the given search * function on each key, or null if none * @since 1.8 @@ -3775,6 +3815,7 @@ * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param <U> the return type of the transformer * @return the result of accumulating the given transformation * of all keys * @since 1.8 @@ -3894,6 +3935,7 @@ * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param <U> the return type of the transformer * @since 1.8 */ public <U> void forEachValue(long parallelismThreshold, @@ -3917,6 +3959,7 @@ * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param <U> the return type of the search function * @return a non-null result from applying the given search * function on each value, or null if none * @since 1.8 @@ -3958,6 +4001,7 @@ * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param <U> the return type of the transformer * @return the result of accumulating the given transformation * of all values * @since 1.8 @@ -4075,6 +4119,7 @@ * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param <U> the return type of the transformer * @since 1.8 */ public <U> void forEachEntry(long parallelismThreshold, @@ -4098,6 +4143,7 @@ * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param <U> the return type of the search function * @return a non-null result from applying the given search * function on each entry, or null if none * @since 1.8 @@ -4139,6 +4185,7 @@ * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param <U> the return type of the transformer * @return the result of accumulating the given transformation * of all entries * @since 1.8
--- a/src/share/classes/java/util/function/BiConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/BiConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,13 +27,16 @@ import java.util.Objects; /** - * An operation which accepts two input arguments and returns no result. This is - * the two-arity specialization of {@link Consumer}. Unlike most other - * functional interfaces, {@code BiConsumer} is expected to operate via - * side-effects. + * Represents an operation that accepts two input arguments and returns no + * result. This is the two-arity specialization of {@link Consumer}. + * Unlike most other functional interfaces, {@code BiConsumer} is expected + * to operate via side-effects. * - * @param <T> the type of the first argument to the {@code accept} operation - * @param <U> the type of the second argument to the {@code accept} operation + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(Object, Object)}. + * + * @param <T> the type of the first argument to the operation + * @param <U> the type of the second argument to the operation * * @see Consumer * @since 1.8 @@ -42,35 +45,31 @@ public interface BiConsumer<T, U> { /** - * Performs operations upon the provided objects which may modify those - * objects and/or external state. + * Performs this operation on the given arguments. * - * @param t an input object - * @param u an input object + * @param t the first input argument + * @param u the second input argument */ void accept(T t, U u); /** - * Returns a {@code BiConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * the other {@code BiConsumer}. - * - * <p>Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. + * Returns a composed {@code BiConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - * @param other a BiConsumer which will be chained after this BiConsumer - * @return a BiConsumer which performs in sequence the {@code accept} method - * of this BiConsumer and the {@code accept} method of the specified - * BiConsumer operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code BiConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default BiConsumer<T, U> chain(BiConsumer<? super T, ? super U> other) { - Objects.requireNonNull(other); + default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) { + Objects.requireNonNull(after); return (l, r) -> { accept(l, r); - other.accept(l, r); + after.accept(l, r); }; } }
--- a/src/share/classes/java/util/function/BiFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/BiFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,14 +27,15 @@ import java.util.Objects; /** - * Apply a function to the input arguments, yielding an appropriate result. This - * is the two-arity specialization of {@link Function}. A function may - * variously provide a mapping between types, object instances or keys and - * values or any other form of transformation upon the input. + * Represents a function that accepts two arguments and produces a result. + * This is the two-arity specialization of {@link Function}. * - * @param <T> the type of the first argument to the {@code apply} operation - * @param <U> the type of the second argument to the {@code apply} operation - * @param <R> the type of results returned by the {@code apply} operation + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(Object, Object)}. + * + * @param <T> the type of the first argument to the function + * @param <U> the type of the second argument to the function + * @param <R> the type of the result of the function * * @see Function * @since 1.8 @@ -43,25 +44,25 @@ public interface BiFunction<T, U, R> { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object + * @param t the first function argument + * @param u the second function argument * @return the function result */ R apply(T t, U u); /** - * Returns a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed function that first applies this function to + * its input, and then applies the {@code after} function to the result. + * If evaluation of either function throws an exception, it is relayed to + * the caller of the composed function. * - * @param <V> Type of output objects to the combined function. May be the - * same type as {@code <T>}, {@code <U>} or {@code <R>} - * @param after An additional function to be applied after this function is - * applied - * @return A function which performs this function followed by the provided - * function + * @param <V> the type of output of the {@code after} function, and of the + * composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then + * applies the {@code after} function * @throws NullPointerException if after is null */ default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
--- a/src/share/classes/java/util/function/BiPredicate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/BiPredicate.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,11 +27,14 @@ import java.util.Objects; /** - * Determines if the input objects match some criteria. This is the two-arity - * specialization of {@link Predicate}. + * Represents a predicate (boolean-valued function) of two arguments. This is + * the two-arity specialization of {@link Predicate}. * - * @param <T> the type of the first argument to {@code test} - * @param <U> the type of the second argument to {@code test} + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #test(Object, Object)}. + * + * @param <T> the type of the first argument to the predicate + * @param <U> the type of the second argument the predicate * * @see Predicate * @since 1.8 @@ -40,34 +43,41 @@ public interface BiPredicate<T, U> { /** - * Return {@code true} if the inputs match some criteria. + * Evaluates this predicate on the given arguments. * - * @param t an input object - * @param u an input object - * @return {@code true} if the inputs match some criteria + * @param t the first input argument + * @param u the second input argument + * @return {@code true} if the input arguments match the predicate, + * otherwise {@code false} */ boolean test(T t, U u); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. + * + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> p) { - Objects.requireNonNull(p); - return (T t, U u) -> test(t, u) && p.test(t, u); + default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other) { + Objects.requireNonNull(other); + return (T t, U u) -> test(t, u) && other.test(t, u); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default BiPredicate<T, U> negate() { @@ -75,18 +85,23 @@ } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. + * + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> p) { - Objects.requireNonNull(p); - return (T t, U u) -> test(t, u) || p.test(t, u); + default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other) { + Objects.requireNonNull(other); + return (T t, U u) -> test(t, u) || other.test(t, u); } }
--- a/src/share/classes/java/util/function/BinaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/BinaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -28,42 +28,48 @@ import java.util.Comparator; /** - * An operation upon two operands yielding a result. This is a specialization of - * {@code BiFunction} where the operands and the result are all of the same type. + * Represents an operation upon two operands of the same type, producing a result + * of the same type as the operands. This is a specialization of + * {@link BiFunction} for the case where the operands and the result are all of + * the same type. * - * @param <T> the type of operands to {@code apply} and of the result + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(Object, Object)}. + * + * @param <T> the type of the operands and result of the operator * * @see BiFunction + * @see UnaryOperator * @since 1.8 */ @FunctionalInterface public interface BinaryOperator<T> extends BiFunction<T,T,T> { /** * Returns a {@link BinaryOperator} which returns the lesser of two elements - * according to the specified {@code Comparator} + * according to the specified {@code Comparator}. * - * @param <T> the type of values to be compared and returned - * @param comparator a {@code Comparator} for comparing the two values + * @param <T> the type of the input arguments of the comparator + * @param comparator a {@code Comparator} for comparing the two values * @return a {@code BinaryOperator} which returns the lesser of its operands, * according to the supplied {@code Comparator} * @throws NullPointerException if the argument is null */ - public static<T> BinaryOperator<T> minBy(Comparator<? super T> comparator) { + public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; } /** * Returns a {@link BinaryOperator} which returns the greater of two elements - * according to the specified {@code Comparator} + * according to the specified {@code Comparator}. * - * @param <T> the type of values to be compared and returned - * @param comparator a {@code Comparator} for comparing the two values + * @param <T> the type of the input arguments of the comparator + * @param comparator a {@code Comparator} for comparing the two values * @return a {@code BinaryOperator} which returns the greater of its operands, * according to the supplied {@code Comparator} * @throws NullPointerException if the argument is null */ - public static<T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) { + public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; }
--- a/src/share/classes/java/util/function/BooleanSupplier.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/BooleanSupplier.java Wed Jul 24 08:22:32 2013 -0300 @@ -26,8 +26,14 @@ /** - * A supplier of {@code boolean} values. This is the {@code boolean}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code boolean}-valued results. This is the + * {@code boolean}-producing primitive specialization of {@link Supplier}. + * + * <p>There is no requirement that a new or distinct result be returned each + * time the supplier is invoked. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #getAsBoolean()}. * * @see Supplier * @since 1.8 @@ -36,9 +42,9 @@ public interface BooleanSupplier { /** - * Returns a {@code boolean} value. + * Gets a result. * - * @return a {@code boolean} value + * @return a result */ boolean getAsBoolean(); }
--- a/src/share/classes/java/util/function/Consumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/Consumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,11 +27,14 @@ import java.util.Objects; /** - * An operation which accepts a single input argument and returns no result. - * Unlike most other functional interfaces, {@code Consumer} is expected to - * operate via side-effects. + * Represents an operation that accepts a single input argument and returns no + * result. Unlike most other functional interfaces, {@code Consumer} is expected + * to operate via side-effects. * - * @param <T> The type of input objects to {@code accept} + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(Object)}. + * + * @param <T> the type of the input to the operation * * @since 1.8 */ @@ -39,29 +42,26 @@ public interface Consumer<T> { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param t the input object + * @param t the input argument */ void accept(T t); /** - * Returns a {@code Consumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * the other {@code Consumer}. - * - * <p>Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. + * Returns a composed {@code Consumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - * @param other a Consumer which will be chained after this Consumer - * @return a Consumer which performs in sequence the {@code accept} method - * of this Consumer and the {@code accept} method of the specified Consumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code Consumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default Consumer<T> chain(Consumer<? super T> other) { - Objects.requireNonNull(other); - return (T t) -> { accept(t); other.accept(t); }; + default Consumer<T> andThen(Consumer<? super T> after) { + Objects.requireNonNull(after); + return (T t) -> { accept(t); after.accept(t); }; } }
--- a/src/share/classes/java/util/function/DoubleBinaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleBinaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,23 +25,25 @@ package java.util.function; /** - * An operation on two {@code double} operands yielding a {@code double} result. - * This is the primitive type specialization of {@link BinaryOperator} for - * {@code double}. + * Represents an operation upon two {@code double}-valued operands and producing a + * {@code double}-valued result. This is the primitive type specialization of + * {@link BinaryOperator} for {@code double}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsDouble(double, double)}. * * @see BinaryOperator + * @see DoubleUnaryOperator * @since 1.8 */ @FunctionalInterface public interface DoubleBinaryOperator { /** - * Returns the {@code double} result of the operation upon the - * {@code double} operands. The parameters are named {@code left} and - * {@code right} for operations where the order of parameters matters. + * Applies this operator to the given operands. * - * @param left the left operand value - * @param right the right operand value - * @return the result of the operation + * @param left the first operand + * @param right the second operand + * @return the operator result */ double applyAsDouble(double left, double right); }
--- a/src/share/classes/java/util/function/DoubleConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,11 +27,14 @@ import java.util.Objects; /** - * An operation which accepts a single double argument and returns no result. - * This is the primitive type specialization of {@link Consumer} for - * {@code double}. Unlike most other functional interfaces, + * Represents an operation that accepts a single {@code double}-valued argument and + * returns no result. This is the primitive type specialization of + * {@link Consumer} for {@code double}. Unlike most other functional interfaces, * {@code DoubleConsumer} is expected to operate via side-effects. * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(double)}. + * * @see Consumer * @since 1.8 */ @@ -39,30 +42,26 @@ public interface DoubleConsumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param value the input value + * @param value the input argument */ void accept(double value); /** - * Returns a {@code DoubleConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * another {@code DoubleConsumer}. - * - * <p>Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. + * Returns a composed {@code DoubleConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - * @param other a DoubleConsumer which will be chained after this - * DoubleConsumer - * @return an DoubleConsumer which performs in sequence the {@code accept} method - * of this DoubleConsumer and the {@code accept} method of the specified IntConsumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code DoubleConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default DoubleConsumer chain(DoubleConsumer other) { - Objects.requireNonNull(other); - return (double t) -> { accept(t); other.accept(t); }; + default DoubleConsumer andThen(DoubleConsumer after) { + Objects.requireNonNull(after); + return (double t) -> { accept(t); after.accept(t); }; } }
--- a/src/share/classes/java/util/function/DoubleFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,11 +25,14 @@ package java.util.function; /** - * Apply a function to the double-valued input argument, yielding an appropriate - * result. This is the {@code double}-consuming primitive specialization for + * Represents a function that accepts a double-valued argument and produces a + * result. This is the {@code double}-consuming primitive specialization for * {@link Function}. * - * @param <R> the type of output objects from the function + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(double)}. + * + * @param <R> the type of the result of the function * * @see Function * @since 1.8 @@ -38,9 +41,9 @@ public interface DoubleFunction<R> { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param value the input value + * @param value the function argument * @return the function result */ R apply(double value);
--- a/src/share/classes/java/util/function/DoublePredicate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoublePredicate.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,9 +27,12 @@ import java.util.Objects; /** - * Determines if the {@code double} input value matches some criteria. This is - * the {@code double}-consuming primitive type specialization of - * {@link Predicate}. + * Represents a predicate (boolean-valued function) of one {@code double}-valued + * argument. This is the {@code double}-consuming primitive type specialization + * of {@link Predicate}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #test(double)}. * * @see Predicate * @since 1.8 @@ -38,38 +41,40 @@ public interface DoublePredicate { /** - * Returns {@code true} if the input value matches some criteria. + * Evaluates this predicate on the given argument. * - * @param value the value to be tested - * @return {@code true} if the input value matches some criteria, otherwise - * {@code false} + * @param value the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(double value); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default DoublePredicate and(DoublePredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) && p.test(value); + default DoublePredicate and(DoublePredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) && other.test(value); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default DoublePredicate negate() { @@ -77,22 +82,23 @@ } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default DoublePredicate or(DoublePredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) || p.test(value); + default DoublePredicate or(DoublePredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) || other.test(value); } }
--- a/src/share/classes/java/util/function/DoubleSupplier.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleSupplier.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,8 +25,14 @@ package java.util.function; /** - * A supplier of {@code double} values. This is the {@code double}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code double}-valued results. This is the + * {@code double}-producing primitive specialization of {@link Supplier}. + * + * <p>There is no requirement that a distinct result be returned each + * time the supplier is invoked. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #getAsDouble()}. * * @see Supplier * @since 1.8 @@ -35,9 +41,9 @@ public interface DoubleSupplier { /** - * Returns a {@code double} value. + * Gets a result. * - * @return a {@code double} value + * @return a result */ double getAsDouble(); }
--- a/src/share/classes/java/util/function/DoubleToIntFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleToIntFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code double}-to-{@code int} specialization for {@link Function}. + * Represents a function that accepts a double-valued argument and produces an + * int-valued result. This is the {@code double}-to-{@code int} primitive + * specialization for {@link Function}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsInt(double)}. * * @see Function - * @see IntToDoubleFunction - * @see LongToIntFunction * @since 1.8 */ @FunctionalInterface public interface DoubleToIntFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ int applyAsInt(double value); }
--- a/src/share/classes/java/util/function/DoubleToLongFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleToLongFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code double}-to-{@code long} specialization for {@link Function}. + * Represents a function that accepts a double-valued argument and produces a + * long-valued result. This is the {@code double}-to-{@code long} primitive + * specialization for {@link Function}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsLong(double)}. * * @see Function - * @see LongToDoubleFunction - * @see IntToLongFunction * @since 1.8 */ @FunctionalInterface public interface DoubleToLongFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ long applyAsLong(double value); }
--- a/src/share/classes/java/util/function/DoubleUnaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/DoubleUnaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,9 +27,12 @@ import java.util.Objects; /** - * An operation on a {@code double} operand yielding a {@code double} - * result. This is the primitive type specialization of {@link UnaryOperator} - * for {@code double}. + * Represents an operation on a single {@code double}-valued operand that produces + * a {@code double}-valued result. This is the primitive type specialization of + * {@link UnaryOperator} for {@code double}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsDouble(double)}. * * @see UnaryOperator * @since 1.8 @@ -38,24 +41,25 @@ public interface DoubleUnaryOperator { /** - * Returns the {@code double} result of the operation upon the - * {@code double} operand. + * Applies this operator to the given operand. * - * @param operand the operand value - * @return the operation result value + * @param operand the operand + * @return the operator result */ double applyAsDouble(double operand); /** - * Compose a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies the {@code before} + * operator to its input, and then applies this operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param before An additional function to be applied before this function - * is applied - * @return A function which performs the provided function followed by this - * function + * @param before the operator to apply before this operator is applied + * @return a composed operator that first applies the {@code before} + * operator and then applies this operator * @throws NullPointerException if before is null + * + * @see #andThen(DoubleUnaryOperator) */ default DoubleUnaryOperator compose(DoubleUnaryOperator before) { Objects.requireNonNull(before); @@ -63,15 +67,17 @@ } /** - * Compose a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies this operator to + * its input, and then applies the {@code after} operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param after An additional function to be applied after this function is - * applied - * @return A function which performs this function followed by the provided - * function followed + * @param after the operator to apply after this operator is applied + * @return a composed operator that first applies this operator and then + * applies the {@code after} operator * @throws NullPointerException if after is null + * + * @see #compose(DoubleUnaryOperator) */ default DoubleUnaryOperator andThen(DoubleUnaryOperator after) { Objects.requireNonNull(after); @@ -79,9 +85,9 @@ } /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @return a unary operator that provides its input value as the result + * @return a unary operator that always returns its input argument */ static DoubleUnaryOperator identity() { return t -> t;
--- a/src/share/classes/java/util/function/Function.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/Function.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,12 +27,13 @@ import java.util.Objects; /** - * Apply a function to the input argument, yielding an appropriate result. A - * function may variously provide a mapping between types, object instances or - * keys and values or any other form of transformation upon the input. + * Represents a function that accepts one argument and produces a result. * - * @param <T> the type of the input to the {@code apply} operation - * @param <R> the type of the result of the {@code apply} operation + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(Object)}. + * + * @param <T> the type of the input to the function + * @param <R> the type of the result of the function * * @since 1.8 */ @@ -40,25 +41,27 @@ public interface Function<T, R> { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param t the input object + * @param t the function argument * @return the function result */ R apply(T t); /** - * Returns a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed function that first applies the {@code before} + * function to its input, and then applies this function to the result. + * If evaluation of either function throws an exception, it is relayed to + * the caller of the composed function. * - * @param <V> type of input objects to the combined function. May be the - * same type as {@code <T>} or {@code <R>} - * @param before an additional function to be applied before this function - * is applied - * @return a function which performs the provided function followed by this - * function + * @param <V> the type of input to the {@code before} function, and to the + * composed function + * @param before the function to apply before this function is applied + * @return a composed function that first applies the {@code before} + * function and then applies this function * @throws NullPointerException if before is null + * + * @see #andThen(Function) */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); @@ -66,17 +69,19 @@ } /** - * Returns a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed function that first applies this function to + * its input, and then applies the {@code after} function to the result. + * If evaluation of either function throws an exception, it is relayed to + * the caller of the composed function. * - * @param <V> type of output objects to the combined function. May be the - * same type as {@code <T>} or {@code <R>} - * @param after an additional function to be applied after this function is - * applied - * @return a function which performs this function followed by the provided - * function + * @param <V> the type of output of the {@code after} function, and of the + * composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then + * applies the {@code after} function * @throws NullPointerException if after is null + * + * @see #compose(Function) */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); @@ -84,10 +89,10 @@ } /** - * Returns a {@code Function} whose {@code apply} method returns its input. + * Returns a function that always returns its input argument. * * @param <T> the type of the input and output objects to the function - * @return a {@code Function} whose {@code apply} method returns its input + * @return a function that always returns its input argument */ static <T> Function<T, T> identity() { return t -> t;
--- a/src/share/classes/java/util/function/IntBinaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntBinaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,24 +25,26 @@ package java.util.function; /** - * An operation on two {@code int} operands yielding an {@code int} result. - * This is the primitive type specialization of {@link BinaryOperator} for - * {@code int}. + * Represents an operation upon two {@code int}-valued operands and producing an + * {@code int}-valued result. This is the primitive type specialization of + * {@link BinaryOperator} for {@code int}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsInt(int, int)}. * * @see BinaryOperator + * @see IntUnaryOperator * @since 1.8 */ @FunctionalInterface public interface IntBinaryOperator { /** - * Returns the {@code int} result of the operation upon the {@code int} - * operands. The parameters are named {@code left} and {@code right} for - * operations where the order of parameters matters. + * Applies this operator to the given operands. * - * @param left the left operand value - * @param right the right operand value - * @return the result of the operation + * @param left the first operand + * @param right the second operand + * @return the operator result */ int applyAsInt(int left, int right); }
--- a/src/share/classes/java/util/function/IntConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,10 +27,13 @@ import java.util.Objects; /** - * An operation which accepts a single integer argument and returns no result. - * This is the primitive type specialization of {@link Consumer} for {@code int}. - * Unlike most other functional interfaces, {@code IntConsumer} is expected to - * operate via side-effects. + * Represents an operation that accepts a single {@code int}-valued argument and + * returns no result. This is the primitive type specialization of + * {@link Consumer} for {@code int}. Unlike most other functional interfaces, + * {@code IntConsumer} is expected to operate via side-effects. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(int)}. * * @see Consumer * @since 1.8 @@ -39,30 +42,26 @@ public interface IntConsumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param value the input value + * @param value the input argument */ void accept(int value); /** - * Returns an {@code IntConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * another {@code IntConsumer}. - * - * <p>Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. + * Returns a composed {@code IntConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - * @param other an IntConsumer which will be chained after this - * IntConsumer - * @return an IntConsumer which performs in sequence the {@code accept} method - * of this IntConsumer and the {@code accept} method of the specified IntConsumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code IntConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default IntConsumer chain(IntConsumer other) { - Objects.requireNonNull(other); - return (int t) -> { accept(t); other.accept(t); }; + default IntConsumer andThen(IntConsumer after) { + Objects.requireNonNull(after); + return (int t) -> { accept(t); after.accept(t); }; } }
--- a/src/share/classes/java/util/function/IntFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,11 +25,14 @@ package java.util.function; /** - * Apply a function to the integer-valued input argument, yielding an - * appropriate result. This is the {@code int}-consuming primitive - * specialization for {@link Function}. + * Represents a function that accepts an int-valued argument and produces a + * result. This is the {@code int}-consuming primitive specialization for + * {@link Function}. * - * @param <R> the type of output objects from the function + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(int)}. + * + * @param <R> the type of the result of the function * * @see Function * @since 1.8 @@ -38,9 +41,9 @@ public interface IntFunction<R> { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param value the input value + * @param value the function argument * @return the function result */ R apply(int value);
--- a/src/share/classes/java/util/function/IntPredicate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntPredicate.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,8 +27,12 @@ import java.util.Objects; /** - * Determines if the {@code int} input value matches some criteria. This is the - * {@code int}-consuming primitive type specialization of {@link Predicate}. + * Represents a predicate (boolean-valued function) of one {@code int}-valued + * argument. This is the {@code int}-consuming primitive type specialization of + * {@link Predicate}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #test(int)}. * * @see Predicate * @since 1.8 @@ -37,38 +41,40 @@ public interface IntPredicate { /** - * Returns {@code true} if the input value matches some criteria. + * Evaluates this predicate on the given argument. * - * @param value the value to be tested - * @return {@code true} if the input value matches some criteria, otherwise - * {@code false} + * @param value the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(int value); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default IntPredicate and(IntPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) && p.test(value); + default IntPredicate and(IntPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) && other.test(value); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default IntPredicate negate() { @@ -76,22 +82,23 @@ } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default IntPredicate or(IntPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) || p.test(value); + default IntPredicate or(IntPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) || other.test(value); } }
--- a/src/share/classes/java/util/function/IntSupplier.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntSupplier.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,8 +25,14 @@ package java.util.function; /** - * A supplier of {@code int} values. This is the {@code int}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code int}-valued results. This is the + * {@code int}-producing primitive specialization of {@link Supplier}. + * + * <p>There is no requirement that a distinct result be returned each + * time the supplier is invoked. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #getAsInt()}. * * @see Supplier * @since 1.8 @@ -35,9 +41,9 @@ public interface IntSupplier { /** - * Returns an {@code int} value. + * Gets a result. * - * @return an {@code int} value + * @return a result */ int getAsInt(); }
--- a/src/share/classes/java/util/function/IntToDoubleFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntToDoubleFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code int}-to-{@code double} specialization for {@link Function}. + * Represents a function that accepts an int-valued argument and produces a + * double-valued result. This is the {@code int}-to-{@code double} primitive + * specialization for {@link Function}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsDouble(int)}. * * @see Function - * @see DoubleToIntFunction - * @see LongToDoubleFunction * @since 1.8 */ @FunctionalInterface public interface IntToDoubleFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ double applyAsDouble(int value); }
--- a/src/share/classes/java/util/function/IntToLongFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntToLongFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code int}-to-{@code long} specialization for {@link Function}. + * Represents a function that accepts an int-valued argument and produces a + * long-valued result. This is the {@code int}-to-{@code long} primitive + * specialization for {@link Function}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsLong(int)}. * * @see Function - * @see LongToIntFunction - * @see DoubleToLongFunction * @since 1.8 */ @FunctionalInterface public interface IntToLongFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ long applyAsLong(int value); }
--- a/src/share/classes/java/util/function/IntUnaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/IntUnaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,9 +27,12 @@ import java.util.Objects; /** - * An operation on a single {@code int} operand yielding an {@code int} result. - * This is the primitive type specialization of {@link UnaryOperator} for - * {@code int}. + * Represents an operation on a single {@code int}-valued operand that produces + * an {@code int}-valued result. This is the primitive type specialization of + * {@link UnaryOperator} for {@code int}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsInt(int)}. * * @see UnaryOperator * @since 1.8 @@ -38,24 +41,25 @@ public interface IntUnaryOperator { /** - * Returns the {@code int} value result of the operation upon the - * {@code int} operand. + * Applies this operator to the given operand. * - * @param operand the operand value - * @return the operation result value + * @param operand the operand + * @return the operator result */ int applyAsInt(int operand); /** - * Compose a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies the {@code before} + * operator to its input, and then applies this operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param before an additional function to be applied before this function - * is applied - * @return a function which performs the provided function followed by this - * function + * @param before the operator to apply before this operator is applied + * @return a composed operator that first applies the {@code before} + * operator and then applies this operator * @throws NullPointerException if before is null + * + * @see #andThen(IntUnaryOperator) */ default IntUnaryOperator compose(IntUnaryOperator before) { Objects.requireNonNull(before); @@ -63,15 +67,17 @@ } /** - * Compose a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies this operator to + * its input, and then applies the {@code after} operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param after an additional function to be applied after this function is - * applied - * @return a function which performs this function followed by the provided - * function followed + * @param after the operator to apply after this operator is applied + * @return a composed operator that first applies this operator and then + * applies the {@code after} operator * @throws NullPointerException if after is null + * + * @see #compose(IntUnaryOperator) */ default IntUnaryOperator andThen(IntUnaryOperator after) { Objects.requireNonNull(after); @@ -79,9 +85,9 @@ } /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @return a unary operator that provides its input value as the result + * @return a unary operator that always returns its input argument */ static IntUnaryOperator identity() { return t -> t;
--- a/src/share/classes/java/util/function/LongBinaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongBinaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,24 +25,26 @@ package java.util.function; /** - * An operation on two {@code long} operands yielding a {@code long} result. - * This is the primitive type specialization of {@link BinaryOperator} for - * {@code long}. + * Represents an operation upon two {@code long}-valued operands and producing a + * {@code long}-valued result. This is the primitive type specialization of + * {@link BinaryOperator} for {@code long}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsLong(long, long)}. * * @see BinaryOperator + * @see LongUnaryOperator * @since 1.8 */ @FunctionalInterface public interface LongBinaryOperator { /** - * Returns the {@code long} result of the operation upon the {@code long} - * operands. The parameters are named {@code left} and {@code right} for - * operations where the order of parameters matters. + * Applies this operator to the given operands. * - * @param left the left operand value - * @param right the right operand value - * @return the result of the operation + * @param left the first operand + * @param right the second operand + * @return the operator result */ long applyAsLong(long left, long right); }
--- a/src/share/classes/java/util/function/LongConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,10 +27,13 @@ import java.util.Objects; /** - * An operation which accepts a single long argument and returns no result. - * This is the {@code long}-consuming primitive type specialization of - * {@link Consumer}. Unlike most other functional interfaces, {@code LongConsumer} - * is expected to operate via side-effects. + * Represents an operation that accepts a single {@code long}-valued argument and + * returns no result. This is the primitive type specialization of + * {@link Consumer} for {@code long}. Unlike most other functional interfaces, + * {@code LongConsumer} is expected to operate via side-effects. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(long)}. * * @see Consumer * @since 1.8 @@ -39,30 +42,26 @@ public interface LongConsumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param value the input value + * @param value the input argument */ void accept(long value); /** - * Returns a {@code LongConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * another {@code LongConsumer}. - * - * <p>Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. + * Returns a composed {@code LongConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - * @param other a LongConsumer which will be chained after this - * LongConsumer - * @return a LongConsumer which performs in sequence the {@code accept} method - * of this LongConsumer and the {@code accept} method of the specified LongConsumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code LongConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default LongConsumer chain(LongConsumer other) { - Objects.requireNonNull(other); - return (long t) -> { accept(t); other.accept(t); }; + default LongConsumer andThen(LongConsumer after) { + Objects.requireNonNull(after); + return (long t) -> { accept(t); after.accept(t); }; } }
--- a/src/share/classes/java/util/function/LongFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,11 +25,14 @@ package java.util.function; /** - * Apply a function to the long-valued input argument, yielding an appropriate - * result. This is the {@code long}-consuming primitive specialization for + * Represents a function that accepts a long-valued argument and produces a + * result. This is the {@code long}-consuming primitive specialization for * {@link Function}. * - * @param <R> the type of output objects from the function + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(long)}. + * + * @param <R> the type of the result of the function * * @see Function * @since 1.8 @@ -38,9 +41,9 @@ public interface LongFunction<R> { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param value the input value + * @param value the function argument * @return the function result */ R apply(long value);
--- a/src/share/classes/java/util/function/LongPredicate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongPredicate.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,8 +27,12 @@ import java.util.Objects; /** - * Determines if the {@code long} input value matches some criteria. This is the - * {@code long}-consuming primitive type specialization of {@link Predicate}. + * Represents a predicate (boolean-valued function) of one {@code long}-valued + * argument. This is the {@code long}-consuming primitive type specialization of + * {@link Predicate}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #test(long)}. * * @see Predicate * @since 1.8 @@ -37,37 +41,40 @@ public interface LongPredicate { /** - * Returns {@code true} if the input value matches some criteria. + * Evaluates this predicate on the given argument. * - * @param value the value to be tested - * @return {@code true} if the input value matches some criteria, otherwise - * {@code false} + * @param value the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(long value); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. + * + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. - * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default LongPredicate and(LongPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) && p.test(value); + default LongPredicate and(LongPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) && other.test(value); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default LongPredicate negate() { @@ -75,22 +82,23 @@ } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default LongPredicate or(LongPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) || p.test(value); + default LongPredicate or(LongPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) || other.test(value); } }
--- a/src/share/classes/java/util/function/LongSupplier.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongSupplier.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,8 +25,14 @@ package java.util.function; /** - * A supplier of {@code long} values. This is the {@code long}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code long}-valued results. This is the + * {@code long}-producing primitive specialization of {@link Supplier}. + * + * <p>There is no requirement that a distinct result be returned each + * time the supplier is invoked. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #getAsLong()}. * * @see Supplier * @since 1.8 @@ -35,9 +41,9 @@ public interface LongSupplier { /** - * Returns a {@code long} value. + * Gets a result. * - * @return a {@code long} value + * @return a result */ long getAsLong(); }
--- a/src/share/classes/java/util/function/LongToDoubleFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongToDoubleFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code long}-to-{@code double} specialization for {@link Function}. + * Represents a function that accepts a long-valued argument and produces a + * double-valued result. This is the {@code long}-to-{@code double} primitive + * specialization for {@link Function}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsDouble(long)}. * * @see Function - * @see DoubleToLongFunction - * @see IntToDoubleFunction * @since 1.8 */ @FunctionalInterface public interface LongToDoubleFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ double applyAsDouble(long value); }
--- a/src/share/classes/java/util/function/LongToIntFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongToIntFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code long}-to-{@code int} specialization for {@link Function}. + * Represents a function that accepts a long-valued argument and produces an + * int-valued result. This is the {@code long}-to-{@code int} primitive + * specialization for {@link Function}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsInt(long)}. * * @see Function - * @see IntToLongFunction - * @see DoubleToIntFunction * @since 1.8 */ @FunctionalInterface public interface LongToIntFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ int applyAsInt(long value); }
--- a/src/share/classes/java/util/function/LongUnaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/LongUnaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,9 +27,12 @@ import java.util.Objects; /** - * An operation on a single {@code long} operand yielding a {@code long} result. - * This is the primitive type specialization of {@link UnaryOperator} for - * {@code long}. + * Represents an operation on a single {@code long}-valued operand that produces + * a {@code long}-valued result. This is the primitive type specialization of + * {@link UnaryOperator} for {@code long}. + * + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsLong(long)}. * * @see UnaryOperator * @since 1.8 @@ -38,24 +41,25 @@ public interface LongUnaryOperator { /** - * Returns the {@code long} result of the operation upon the {@code long} - * operand. + * Applies this operator to the given operand. * - * @param operand the operand value - * @return the operation result value + * @param operand the operand + * @return the operator result */ long applyAsLong(long operand); /** - * Compose a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies the {@code before} + * operator to its input, and then applies this operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param before An additional function to be applied before this function - * is applied - * @return A function which performs the provided function followed by this - * function + * @param before the operator to apply before this operator is applied + * @return a composed operator that first applies the {@code before} + * operator and then applies this operator * @throws NullPointerException if before is null + * + * @see #andThen(LongUnaryOperator) */ default LongUnaryOperator compose(LongUnaryOperator before) { Objects.requireNonNull(before); @@ -63,15 +67,17 @@ } /** - * Compose a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies this operator to + * its input, and then applies the {@code after} operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param after An additional function to be applied after this function is - * applied - * @return A function which performs this function followed by the provided - * function followed + * @param after the operator to apply after this operator is applied + * @return a composed operator that first applies this operator and then + * applies the {@code after} operator * @throws NullPointerException if after is null + * + * @see #compose(LongUnaryOperator) */ default LongUnaryOperator andThen(LongUnaryOperator after) { Objects.requireNonNull(after); @@ -79,9 +85,9 @@ } /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @return a unary operator that provides its input value as the result + * @return a unary operator that always returns its input argument */ static LongUnaryOperator identity() { return t -> t;
--- a/src/share/classes/java/util/function/ObjDoubleConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ObjDoubleConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,12 +25,16 @@ package java.util.function; /** - * An operation which accepts an object reference and a double, and returns no - * result. This is the {@code (reference, double)} specialization of - * {@link BiConsumer}. Unlike most other functional interfaces, - * {@code ObjDoubleConsumer} is expected to operate via side-effects. + * Represents an operation that accepts an object-valued and a + * {@code double}-valued argument, and returns no result. This is the + * {@code (reference, double)} specialization of {@link BiConsumer}. + * Unlike most other functional interfaces, {@code ObjDoubleConsumer} is + * expected to operate via side-effects. * - * @param <T> Type of reference argument to {@code accept()}. + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(Object, double)}. + * + * @param <T> the type of the object argument to the operation * * @see BiConsumer * @since 1.8 @@ -39,10 +43,10 @@ public interface ObjDoubleConsumer<T> { /** - * Accept a set of input values. + * Performs this operation on the given arguments. * - * @param t an input object - * @param value an input value + * @param t the first input argument + * @param value the second input argument */ void accept(T t, double value); }
--- a/src/share/classes/java/util/function/ObjIntConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ObjIntConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,12 +25,16 @@ package java.util.function; /** - * An operation which accepts an object reference and an int, and returns no - * result. This is the {@code (reference, int)} specialization of - * {@link BiConsumer}. Unlike most other functional interfaces, - * {@code ObjIntConsumer} is expected to operate via side-effects. + * Represents an operation that accepts an object-valued and a + * {@code int}-valued argument, and returns no result. This is the + * {@code (reference, int)} specialization of {@link BiConsumer}. + * Unlike most other functional interfaces, {@code ObjIntConsumer} is + * expected to operate via side-effects. * - * @param <T> Type of reference argument to {@code accept()} + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(Object, int)}. + * + * @param <T> the type of the object argument to the operation * * @see BiConsumer * @since 1.8 @@ -39,10 +43,10 @@ public interface ObjIntConsumer<T> { /** - * Accept a set of input values. + * Performs this operation on the given arguments. * - * @param t an input object - * @param value an input value + * @param t the first input argument + * @param value the second input argument */ void accept(T t, int value); }
--- a/src/share/classes/java/util/function/ObjLongConsumer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ObjLongConsumer.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,12 +25,16 @@ package java.util.function; /** - * An operation which accepts an object reference and a long, and returns no - * result. This is the {@code (reference, long)} specialization of - * {@link BiConsumer}. Unlike most other functional interfaces, - * {@code ObjLongConsumer} is expected to operate via side-effects. + * Represents an operation that accepts an object-valued and a + * {@code long}-valued argument, and returns no result. This is the + * {@code (reference, long)} specialization of {@link BiConsumer}. + * Unlike most other functional interfaces, {@code ObjLongConsumer} is + * expected to operate via side-effects. * - * @param <T> Type of reference argument to {@code accept()} + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #accept(Object, long)}. + * + * @param <T> the type of the object argument to the operation * * @see BiConsumer * @since 1.8 @@ -39,10 +43,10 @@ public interface ObjLongConsumer<T> { /** - * Accept a set of input values. + * Performs this operation on the given arguments. * - * @param t an input object - * @param value an input value + * @param t the first input argument + * @param value the second input argument */ void accept(T t, long value); }
--- a/src/share/classes/java/util/function/Predicate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/Predicate.java Wed Jul 24 08:22:32 2013 -0300 @@ -27,9 +27,12 @@ import java.util.Objects; /** - * Determines if the input object matches some criteria. + * Represents a predicate (boolean-valued function) of one argument. * - * @param <T> the type of argument to {@code test} + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #test(Object)}. + * + * @param <T> the type of the input to the predicate * * @since 1.8 */ @@ -37,76 +40,80 @@ public interface Predicate<T> { /** - * Returns {@code true} if the input object matches some criteria. + * Evaluates this predicate on the given argument. * - * @param t the input object - * @return {@code true} if the input object matches some criteria, otherwise - * {@code false} + * @param t the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(T t); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default Predicate<T> and(Predicate<? super T> p) { - Objects.requireNonNull(p); - return (t) -> test(t) && p.test(t); + default Predicate<T> and(Predicate<? super T> other) { + Objects.requireNonNull(other); + return (t) -> test(t) && other.test(t); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this - * predicate. + * @return a predicate that represents the logical negation of this + * predicate */ default Predicate<T> negate() { return (t) -> !test(t); } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - * <p>Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + * <p>Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default Predicate<T> or(Predicate<? super T> p) { - Objects.requireNonNull(p); - return (t) -> test(t) || p.test(t); + default Predicate<T> or(Predicate<? super T> other) { + Objects.requireNonNull(other); + return (t) -> test(t) || other.test(t); } /** - * Returns a predicate who's result matches - * {@code Objects.equals(target, t)}. + * Returns a predicate that tests if two arguments are equal according + * to {@link Objects#equals(Object, Object)}. * - * @param <T> the type of values evaluated by the predicate - * @param target the target value to be compared for equality - * @return a predicate who's result matches - * {@code Objects.equals(target, t)} + * @param <T> the type of arguments to the predicate + * @param targetRef the object reference with which to compare for equality, + * which may be {@code null} + * @return a predicate that tests if two arguments are equal according + * to {@link Objects#equals(Object, Object)} */ - static <T> Predicate<T> isEqual(Object target) { - return (null == target) + static <T> Predicate<T> isEqual(Object targetRef) { + return (null == targetRef) ? Objects::isNull - : object -> target.equals(object); + : object -> targetRef.equals(object); } }
--- a/src/share/classes/java/util/function/Supplier.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/Supplier.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,10 +25,15 @@ package java.util.function; /** - * A supplier of objects. The result objects are either created during the - * invocation of {@link #get} or by some prior action. + * Represents a supplier of results. + * + * <p>There is no requirement that a new or distinct result be returned each + * time the supplier is invoked. * - * @param <T> The type of objects returned by {@code get} + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #get()}. + * + * @param <T> the type of results supplied by this supplier * * @since 1.8 */ @@ -36,9 +41,9 @@ public interface Supplier<T> { /** - * Returns an object. + * Gets a result. * - * @return an object + * @return a result */ T get(); }
--- a/src/share/classes/java/util/function/ToDoubleBiFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ToDoubleBiFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,13 +25,15 @@ package java.util.function; /** - * Apply a function to the input arguments, yielding an appropriate result. - * This is the {@code double}-bearing specialization for {@link BiFunction}. + * Represents a function that accepts two arguments and produces a double-valued + * result. This is the {@code double}-producing primitive specialization for + * {@link BiFunction}. * - * @param <T> the type of the first argument to the {@code applyAsDouble} - * operation. - * @param <U> the type of the second argument to the {@code applyAsDouble} - * operation. + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsDouble(Object, Object)}. + * + * @param <T> the type of the first argument to the function + * @param <U> the type of the second argument to the function * * @see BiFunction * @since 1.8 @@ -40,11 +42,11 @@ public interface ToDoubleBiFunction<T, U> { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object - * @return the function result value + * @param t the first function argument + * @param u the second function argument + * @return the function result */ double applyAsDouble(T t, U u); }
--- a/src/share/classes/java/util/function/ToDoubleFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ToDoubleFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,10 +25,13 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code double}-bearing specialization for {@link Function}. + * Represents a function that produces a double-valued result. This is the + * {@code double}-producing primitive specialization for {@link Function}. * - * @param <T> the type of input objects to the function + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsDouble(Object)}. + * + * @param <T> the type of the input to the function * * @see Function * @since 1.8 @@ -37,10 +40,10 @@ public interface ToDoubleFunction<T> { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param t the input object - * @return the function result value + * @param value the function argument + * @return the function result */ - double applyAsDouble(T t); + double applyAsDouble(T value); }
--- a/src/share/classes/java/util/function/ToIntBiFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ToIntBiFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,13 +25,15 @@ package java.util.function; /** - * Apply a function to the input arguments, yielding an appropriate result. - * This is the {@code int}-bearing specialization for {@link BiFunction}. + * Represents a function that accepts two arguments and produces an int-valued + * result. This is the {@code int}-producing primitive specialization for + * {@link BiFunction}. * - * @param <T> the type of the first argument to the {@code applyAsInt} - * operation - * @param <U> the type of the second argument to the {@code applyAsInt} - * operation + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsInt(Object, Object)}. + * + * @param <T> the type of the first argument to the function + * @param <U> the type of the second argument to the function * * @see BiFunction * @since 1.8 @@ -40,11 +42,11 @@ public interface ToIntBiFunction<T, U> { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object - * @return the function result value + * @param t the first function argument + * @param u the second function argument + * @return the function result */ int applyAsInt(T t, U u); }
--- a/src/share/classes/java/util/function/ToIntFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ToIntFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,10 +25,13 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code int}-bearing specialization for {@link Function}. + * Represents a function that produces an int-valued result. This is the + * {@code int}-producing primitive specialization for {@link Function}. * - * @param <T> the type of input objects to the function + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsInt(Object)}. + * + * @param <T> the type of the input to the function * * @see Function * @since 1.8 @@ -37,10 +40,10 @@ public interface ToIntFunction<T> { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given argument. * - * @param t the input object - * @return the function result value + * @param value the function argument + * @return the function result */ - int applyAsInt(T t); + int applyAsInt(T value); }
--- a/src/share/classes/java/util/function/ToLongBiFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ToLongBiFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,13 +25,15 @@ package java.util.function; /** - * Apply a function to the input arguments, yielding an appropriate result. - * This is the {@code long}-bearing specialization for {@link BiFunction}. + * Represents a function that accepts two arguments and produces a long-valued + * result. This is the {@code long}-producing primitive specialization for + * {@link BiFunction}. * - * @param <T> the type of the first argument to the {@code applyAsLong} - * operation. - * @param <U> the type of the second argument to the {@code applyAsLong} - * operation. + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsLong(Object, Object)}. + * + * @param <T> the type of the first argument to the function + * @param <U> the type of the second argument to the function * * @see BiFunction * @since 1.8 @@ -40,11 +42,11 @@ public interface ToLongBiFunction<T, U> { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object - * @return the function result value + * @param t the first function argument + * @param u the second function argument + * @return the function result */ long applyAsLong(T t, U u); }
--- a/src/share/classes/java/util/function/ToLongFunction.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/ToLongFunction.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,10 +25,13 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code long}-bearing specialization for {@link Function}. + * Represents a function that produces a long-valued result. This is the + * {@code long}-producing primitive specialization for {@link Function}. * - * @param <T> the type of input objects to the function + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #applyAsLong(Object)}. + * + * @param <T> the type of the input to the function * * @see Function * @since 1.8 @@ -37,10 +40,10 @@ public interface ToLongFunction<T> { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param t the input object - * @return the function result value + * @param value the function argument + * @return the function result */ - long applyAsLong(T t); + long applyAsLong(T value); }
--- a/src/share/classes/java/util/function/UnaryOperator.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/UnaryOperator.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,11 +25,14 @@ package java.util.function; /** - * An operation upon a single operand yielding a result. The operand and the - * result are of the same type. This is a specialization of {@code Function} for + * Represents an operation on a single operand that produces a result of the + * same type as its operand. This is a specialization of {@code Function} for * the case where the operand and result are of the same type. * - * @param <T> the type of operand to {@code apply} and of the result + * <p>This is a <a href="package-summary.html">functional interface</a> + * whose functional method is {@link #apply(Object)}. + * + * @param <T> the type of the operand and result of the operator * * @see Function * @since 1.8 @@ -38,10 +41,10 @@ public interface UnaryOperator<T> extends Function<T, T> { /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @param <T> the type of the input and output objects to the function - * @return a unary operator that provides its input value as the result + * @param <T> the type of the input and output of the operator + * @return a unary operator that always returns its input argument */ static <T> UnaryOperator<T> identity() { return t -> t;
--- a/src/share/classes/java/util/function/package-info.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/java/util/function/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -25,56 +25,82 @@ /** * <em>Functional interfaces</em> provide target types for lambda expressions - * and method references. Each functional interface has a single abstract method + * and method references. Each functional interface has a single abstract + * method, called the <em>functional method</em> for that functional interface, * to which the lambda expression's parameter and return types are matched or - * adapted. Functional interfaces can provide a target type in multiple contexts, - * such as assignment context, method invocation, or cast context: + * adapted. Functional interfaces can provide a target type in multiple + * contexts, such as assignment context, method invocation, or cast context: * - * <pre> - * Predicate<String> p = String::isEmpty; + * <pre>{@code + * // Assignment context + * Predicate<String> p = String::isEmpty; * + * // Method invocation context * stream.filter(e -> e.getSize() > 10)... * + * // Cast context * stream.map((ToIntFunction) e -> e.getSize())... - * </pre> + * }</pre> * - * <p>The interfaces in this package are functional interfaces used by the JDK, - * and are available to be used by user code as well. While they do not identify - * a complete set of function shapes to which lambda expressions might be adapted, - * they provide enough to cover common requirements. + * <p>The interfaces in this package are general purpose functional interfaces + * used by the JDK, and are available to be used by user code as well. While + * they do not identify a complete set of function shapes to which lambda + * expressions might be adapted, they provide enough to cover common + * requirements. Other functional interfaces provided for specific purposes, + * such as {@link java.io.FileFilter}, are defined in the packages where they + * are used. * - * <p>The interfaces in this package are annotated with @{link FunctionalInterface}. - * This annotation is not a requirement for the compiler to recognize an interface - * as a functional interface, but merely an aid to capture design intent and enlist the - * help of the compiler in identifying accidental violations of design intent. + * <p>The interfaces in this package are annotated with + * {@link java.lang.FunctionalInterface}. This annotation is not a requirement + * for the compiler to recognize an interface as a functional interface, but + * merely an aid to capture design intent and enlist the help of the compiler in + * identifying accidental violations of design intent. * - * <p>The functional interfaces in this package follow an extensible naming convention, - * as follows: + * <p>Functional interfaces often represent abstract concepts like functions, + * actions, or predicates. In documenting functional interfaces, or referring + * to variables typed as functional interfaces, it is common to refer directly + * to those abstract concepts, for example using "this function" instead of + * "the function represented by this object". + * + * <p>The functional interfaces in this package follow an extensible naming + * convention, as follows: * * <ul> - * <li>There are several basic function shapes, including {@link java.util.function.Function} ({@code T -> R}), - * {@link java.util.function.Consumer} ({@code T -> void}), - * {@link java.util.function.Predicate} ({@code T -> boolean}), - * and {@link java.util.function.Supplier} ({@code () -> T}). + * <li>There are several basic function shapes, including + * {@link java.util.function.Function} (unary function from {@code T} to {@code R}), + * {@link java.util.function.Consumer} (unary function from {@code T} to {@code void}), + * {@link java.util.function.Predicate} (unary function from {@code T} to {@code boolean}), + * and {@link java.util.function.Supplier} (nilary function to {@code R}). * </li> - * <li>Function shapes have a natural arity based on how they are most commonly used. - * The basic shapes can be modified by an arity prefix to indicate a different arity, - * such as {@link java.util.function.BiFunction} ({@code (T, U) -> R}). + * + * <li>Function shapes have a natural arity based on how they are most + * commonly used. The basic shapes can be modified by an arity prefix to + * indicate a different arity, such as + * {@link java.util.function.BiFunction} (binary function from {@code T} and + * {@code U} to {@code R}). * </li> - * <li>There are additional derived function shapes which extend the basic function - * shapes, including {@link java.util.function.UnaryOperator} (extends {@code Function}) and - * {@link java.util.function.BinaryOperator} (extends {@code BiFunction}). + * + * <li>There are additional derived function shapes which extend the basic + * function shapes, including {@link java.util.function.UnaryOperator} + * (extends {@code Function}) and {@link java.util.function.BinaryOperator} + * (extends {@code BiFunction}). * </li> - * <li>Type parameters of functional interfaces can be specialized to primitives with - * additional type prefixes. To specialize the return type for a type that has both - * generic return type and generic arguments, we prefix {@code ToXxx}, as in - * {@link java.util.function.ToIntFunction}. Otherwise, type arguments are specialized left-to-right, - * as in {@link java.util.function.DoubleConsumer} or {@link java.util.function.ObjIntConsumer}. - * (The type prefix {@code Obj} is used to indicate that we don't want to specialize this parameter, - * but want to move on to the next parameter.) These schemes can be combined as in {@code IntToDoubleFunction}. + * + * <li>Type parameters of functional interfaces can be specialized to + * primitives with additional type prefixes. To specialize the return type + * for a type that has both generic return type and generic arguments, we + * prefix {@code ToXxx}, as in {@link java.util.function.ToIntFunction}. + * Otherwise, type arguments are specialized left-to-right, as in + * {@link java.util.function.DoubleConsumer} + * or {@link java.util.function.ObjIntConsumer}. + * (The type prefix {@code Obj} is used to indicate that we don't want to + * specialize this parameter, but want to move on to the next parameter, + * as in {@link java.util.function.ObjIntConsumer}.) + * These schemes can be combined, as in {@code IntToDoubleFunction}. * </li> - * <li>If there are specialization prefixes for all arguments, the arity prefix may be left - * out (as in {@link java.util.function.ObjIntConsumer}). + * + * <li>If there are specialization prefixes for all arguments, the arity + * prefix may be left out (as in {@link java.util.function.ObjIntConsumer}). * </li> * </ul> *
--- a/src/share/classes/javax/security/auth/AuthPermission.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/AuthPermission.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -41,10 +41,10 @@ * * <pre> * doAs - allow the caller to invoke the - * <code>Subject.doAs</code> methods. + * {@code Subject.doAs} methods. * * doAsPrivileged - allow the caller to invoke the - * <code>Subject.doAsPrivileged</code> methods. + * {@code Subject.doAsPrivileged} methods. * * getSubject - allow for the retrieval of the * Subject(s) associated with the @@ -52,39 +52,39 @@ * * getSubjectFromDomainCombiner - allow for the retrieval of the * Subject associated with the - * a <code>SubjectDomainCombiner</code>. + * a {@code SubjectDomainCombiner}. * * setReadOnly - allow the caller to set a Subject * to be read-only. * - * modifyPrincipals - allow the caller to modify the <code>Set</code> + * modifyPrincipals - allow the caller to modify the {@code Set} * of Principals associated with a - * <code>Subject</code> + * {@code Subject} * * modifyPublicCredentials - allow the caller to modify the - * <code>Set</code> of public credentials - * associated with a <code>Subject</code> + * {@code Set} of public credentials + * associated with a {@code Subject} * * modifyPrivateCredentials - allow the caller to modify the - * <code>Set</code> of private credentials - * associated with a <code>Subject</code> + * {@code Set} of private credentials + * associated with a {@code Subject} * - * refreshCredential - allow code to invoke the <code>refresh</code> + * refreshCredential - allow code to invoke the {@code refresh} * method on a credential which implements - * the <code>Refreshable</code> interface. + * the {@code Refreshable} interface. * - * destroyCredential - allow code to invoke the <code>destroy</code> - * method on a credential <code>object</code> - * which implements the <code>Destroyable</code> + * destroyCredential - allow code to invoke the {@code destroy} + * method on a credential {@code object} + * which implements the {@code Destroyable} * interface. * * createLoginContext.{name} - allow code to instantiate a - * <code>LoginContext</code> with the + * {@code LoginContext} with the * specified <i>name</i>. <i>name</i> * is used as the index into the installed login - * <code>Configuration</code> + * {@code Configuration} * (that returned by - * <code>Configuration.getConfiguration()</code>). + * {@code Configuration.getConfiguration()}). * <i>name</i> can be wildcarded (set to '*') * to allow for any name. * @@ -93,7 +93,7 @@ * * createLoginConfiguration.{type} - allow code to obtain a Configuration * object via - * <code>Configuration.getInstance</code>. + * {@code Configuration.getInstance}. * * setLoginConfiguration - allow for the setting of the system-wide * login Configuration. @@ -103,15 +103,15 @@ * </pre> * * <p> The following target name has been deprecated in favor of - * <code>createLoginContext.{name}</code>. + * {@code createLoginContext.{name}}. * * <pre> * createLoginContext - allow code to instantiate a - * <code>LoginContext</code>. + * {@code LoginContext}. * </pre> * - * <p> <code>javax.security.auth.Policy</code> has been - * deprecated in favor of <code>java.security.Policy</code>. + * <p> {@code javax.security.auth.Policy} has been + * deprecated in favor of {@code java.security.Policy}. * Therefore, the following target names have also been deprecated: * * <pre> @@ -139,8 +139,8 @@ * * @param name the name of the AuthPermission * - * @throws NullPointerException if <code>name</code> is <code>null</code>. - * @throws IllegalArgumentException if <code>name</code> is empty. + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. */ public AuthPermission(String name) { // for backwards compatibility -- @@ -160,8 +160,8 @@ * * @param actions should be null. * - * @throws NullPointerException if <code>name</code> is <code>null</code>. - * @throws IllegalArgumentException if <code>name</code> is empty. + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. */ public AuthPermission(String name, String actions) { // for backwards compatibility --
--- a/src/share/classes/javax/security/auth/DestroyFailedException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/DestroyFailedException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -26,10 +26,10 @@ package javax.security.auth; /** - * Signals that a <code>destroy</code> operation failed. + * Signals that a {@code destroy} operation failed. * * <p> This exception is thrown by credentials implementing - * the <code>Destroyable</code> interface when the <code>destroy</code> + * the {@code Destroyable} interface when the {@code destroy} * method fails. * */
--- a/src/share/classes/javax/security/auth/Destroyable.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/Destroyable.java Wed Jul 24 08:22:32 2013 -0300 @@ -34,12 +34,12 @@ public interface Destroyable { /** - * Destroy this <code>Object</code>. + * Destroy this {@code Object}. * - * <p> Sensitive information associated with this <code>Object</code> + * <p> Sensitive information associated with this {@code Object} * is destroyed or cleared. Subsequent calls to certain methods - * on this <code>Object</code> will result in an - * <code>IllegalStateException</code> being thrown. + * on this {@code Object} will result in an + * {@code IllegalStateException} being thrown. * * <p> * The default implementation throws {@code DestroyFailedException}. @@ -47,19 +47,19 @@ * @exception DestroyFailedException if the destroy operation fails. <p> * * @exception SecurityException if the caller does not have permission - * to destroy this <code>Object</code>. + * to destroy this {@code Object}. */ public default void destroy() throws DestroyFailedException { throw new DestroyFailedException(); } /** - * Determine if this <code>Object</code> has been destroyed. + * Determine if this {@code Object} has been destroyed. * * <p> * The default implementation returns false. * - * @return true if this <code>Object</code> has been destroyed, + * @return true if this {@code Object} has been destroyed, * false otherwise. */ public default boolean isDestroyed() {
--- a/src/share/classes/javax/security/auth/Policy.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/Policy.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -32,11 +32,11 @@ * <p> This is an abstract class for representing the system policy for * Subject-based authorization. A subclass implementation * of this class provides a means to specify a Subject-based - * access control <code>Policy</code>. + * access control {@code Policy}. * - * <p> A <code>Policy</code> object can be queried for the set of + * <p> A {@code Policy} object can be queried for the set of * Permissions granted to code running as a - * <code>Principal</code> in the following manner: + * {@code Principal} in the following manner: * * <pre> * policy = Policy.getPolicy(); @@ -44,20 +44,20 @@ * codeSource); * </pre> * - * The <code>Policy</code> object consults the local policy and returns - * and appropriate <code>Permissions</code> object with the + * The {@code Policy} object consults the local policy and returns + * and appropriate {@code Permissions} object with the * Permissions granted to the Principals associated with the * provided <i>subject</i>, and granted to the code specified * by the provided <i>codeSource</i>. * - * <p> A <code>Policy</code> contains the following information. + * <p> A {@code Policy} contains the following information. * Note that this example only represents the syntax for the default - * <code>Policy</code> implementation. Subclass implementations of this class + * {@code Policy} implementation. Subclass implementations of this class * may implement alternative syntaxes and may retrieve the - * <code>Policy</code> from any source such as files, databases, + * {@code Policy} from any source such as files, databases, * or servers. * - * <p> Each entry in the <code>Policy</code> is represented as + * <p> Each entry in the {@code Policy} is represented as * a <b><i>grant</i></b> entry. Each <b><i>grant</i></b> entry * specifies a codebase, code signers, and Principals triplet, * as well as the Permissions granted to that triplet. @@ -84,23 +84,23 @@ * </pre> * * This <b><i>grant</i></b> entry specifies that code from "foo.com", - * signed by "foo', and running as a <code>SolarisPrincipal</code> with the - * name, duke, has one <code>Permission</code>. This <code>Permission</code> + * signed by "foo', and running as a {@code SolarisPrincipal} with the + * name, duke, has one {@code Permission}. This {@code Permission} * permits the executing code to read and write files in the directory, * "/home/duke". * - * <p> To "run" as a particular <code>Principal</code>, - * code invokes the <code>Subject.doAs(subject, ...)</code> method. + * <p> To "run" as a particular {@code Principal}, + * code invokes the {@code Subject.doAs(subject, ...)} method. * After invoking that method, the code runs as all the Principals - * associated with the specified <code>Subject</code>. - * Note that this <code>Policy</code> (and the Permissions - * granted in this <code>Policy</code>) only become effective - * after the call to <code>Subject.doAs</code> has occurred. + * associated with the specified {@code Subject}. + * Note that this {@code Policy} (and the Permissions + * granted in this {@code Policy}) only become effective + * after the call to {@code Subject.doAs} has occurred. * * <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry. * All the Principals in the grant entry must be associated with - * the <code>Subject</code> provided to <code>Subject.doAs</code> - * for that <code>Subject</code> to be granted the specified Permissions. + * the {@code Subject} provided to {@code Subject.doAs} + * for that {@code Subject} to be granted the specified Permissions. * * <pre> * grant Principal com.sun.security.auth.SolarisPrincipal "duke", @@ -115,7 +115,7 @@ * as well as permission to make socket connections to "duke.com". * * <p> Note that non Principal-based grant entries are not permitted - * in this <code>Policy</code>. Therefore, grant entries such as: + * in this {@code Policy}. Therefore, grant entries such as: * * <pre> * grant CodeBase "foo.com", Signedby "foo" { @@ -124,7 +124,7 @@ * </pre> * * are rejected. Such permission must be listed in the - * <code>java.security.Policy</code>. + * {@code java.security.Policy}. * * <p> The default {@code Policy} implementation can be changed by * setting the value of the {@code auth.policy.provider} security property to @@ -179,14 +179,14 @@ /** * Returns the installed Policy object. * This method first calls - * <code>SecurityManager.checkPermission</code> with the - * <code>AuthPermission("getPolicy")</code> permission + * {@code SecurityManager.checkPermission} with the + * {@code AuthPermission("getPolicy")} permission * to ensure the caller has permission to get the Policy object. * * <p> * * @return the installed Policy. The return value cannot be - * <code>null</code>. + * {@code null}. * * @exception java.lang.SecurityException if the current thread does not * have permission to get the Policy object. @@ -252,8 +252,8 @@ /** * Sets the system-wide Policy object. This method first calls - * <code>SecurityManager.checkPermission</code> with the - * <code>AuthPermission("setPolicy")</code> + * {@code SecurityManager.checkPermission} with the + * {@code AuthPermission("setPolicy")} * permission to ensure the caller has permission to set the Policy. * * <p> @@ -313,25 +313,25 @@ /** * Retrieve the Permissions granted to the Principals associated with - * the specified <code>CodeSource</code>. + * the specified {@code CodeSource}. * * <p> * - * @param subject the <code>Subject</code> + * @param subject the {@code Subject} * whose associated Principals, * in conjunction with the provided - * <code>CodeSource</code>, determines the Permissions + * {@code CodeSource}, determines the Permissions * returned by this method. This parameter - * may be <code>null</code>. <p> + * may be {@code null}. <p> * - * @param cs the code specified by its <code>CodeSource</code> + * @param cs the code specified by its {@code CodeSource} * that determines, in conjunction with the provided - * <code>Subject</code>, the Permissions + * {@code Subject}, the Permissions * returned by this method. This parameter may be - * <code>null</code>. + * {@code null}. * * @return the Collection of Permissions granted to all the - * <code>Subject</code> and code specified in + * {@code Subject} and code specified in * the provided <i>subject</i> and <i>cs</i> * parameters. */ @@ -345,7 +345,7 @@ * <p>This method causes this object to refresh/reload its current * Policy. This is implementation-dependent. * For example, if the Policy object is stored in - * a file, calling <code>refresh</code> will cause the file to be re-read. + * a file, calling {@code refresh} will cause the file to be re-read. * * <p> *
--- a/src/share/classes/javax/security/auth/PrivateCredentialPermission.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/PrivateCredentialPermission.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -34,10 +34,10 @@ /** * This class is used to protect access to private Credentials - * belonging to a particular <code>Subject</code>. The <code>Subject</code> + * belonging to a particular {@code Subject}. The {@code Subject} * is represented by a Set of Principals. * - * <p> The target name of this <code>Permission</code> specifies + * <p> The target name of this {@code Permission} specifies * a Credential class name, and a Set of Principals. * The only valid value for this Permission's actions is, "read". * The target name must abide by the following syntax: @@ -65,12 +65,12 @@ * * If CredentialClass is "*", then access is granted to * all private Credentials belonging to the specified - * <code>Subject</code>. + * {@code Subject}. * If "PrincipalName" is "*", then access is granted to the - * specified Credential owned by any <code>Subject</code> that has the - * specified <code>Principal</code> (the actual PrincipalName doesn't matter). + * specified Credential owned by any {@code Subject} that has the + * specified {@code Principal} (the actual PrincipalName doesn't matter). * For example, the following grants access to the - * a.b.Credential owned by any <code>Subject</code> that has + * a.b.Credential owned by any {@code Subject} that has * an a.b.Principal. * * <pre> @@ -83,7 +83,7 @@ * * If both the PrincipalClass and "PrincipalName" are "*", * then access is granted to the specified Credential owned by - * any <code>Subject</code>. + * any {@code Subject}. * * <p> In addition, the PrincipalClass/PrincipalName pairing may be repeated: * @@ -96,7 +96,7 @@ * </pre> * * The above grants access to the private Credential, "a.b.Credential", - * belonging to a <code>Subject</code> with at least two associated Principals: + * belonging to a {@code Subject} with at least two associated Principals: * "a.b.Principal" with the name, "duke", and "c.d.Principal", with the name, * "dukette". * @@ -115,7 +115,7 @@ /** * @serial The Principals associated with this permission. * The set contains elements of type, - * <code>PrivateCredentialPermission.CredOwner</code>. + * {@code PrivateCredentialPermission.CredOwner}. */ private Set<Principal> principals; // ignored - kept around for compatibility private transient CredOwner[] credOwners; @@ -126,8 +126,8 @@ private boolean testing = false; /** - * Create a new <code>PrivateCredentialPermission</code> - * with the specified <code>credentialClass</code> and Principals. + * Create a new {@code PrivateCredentialPermission} + * with the specified {@code credentialClass} and Principals. */ PrivateCredentialPermission(String credentialClass, Set<Principal> principals) { @@ -153,19 +153,19 @@ } /** - * Creates a new <code>PrivateCredentialPermission</code> - * with the specified <code>name</code>. The <code>name</code> - * specifies both a Credential class and a <code>Principal</code> Set. + * Creates a new {@code PrivateCredentialPermission} + * with the specified {@code name}. The {@code name} + * specifies both a Credential class and a {@code Principal} Set. * * <p> * * @param name the name specifying the Credential class and - * <code>Principal</code> Set. <p> + * {@code Principal} Set. <p> * * @param actions the actions specifying that the Credential can be read. * - * @throws IllegalArgumentException if <code>name</code> does not conform - * to the correct syntax or if <code>actions</code> is not "read". + * @throws IllegalArgumentException if {@code name} does not conform + * to the correct syntax or if {@code actions} is not "read". */ public PrivateCredentialPermission(String name, String actions) { super(name); @@ -178,34 +178,34 @@ /** * Returns the Class name of the Credential associated with this - * <code>PrivateCredentialPermission</code>. + * {@code PrivateCredentialPermission}. * * <p> * * @return the Class name of the Credential associated with this - * <code>PrivateCredentialPermission</code>. + * {@code PrivateCredentialPermission}. */ public String getCredentialClass() { return credentialClass; } /** - * Returns the <code>Principal</code> classes and names - * associated with this <code>PrivateCredentialPermission</code>. + * Returns the {@code Principal} classes and names + * associated with this {@code PrivateCredentialPermission}. * The information is returned as a two-dimensional array (array[x][y]). - * The 'x' value corresponds to the number of <code>Principal</code> + * The 'x' value corresponds to the number of {@code Principal} * class and name pairs. When (y==0), it corresponds to - * the <code>Principal</code> class value, and when (y==1), - * it corresponds to the <code>Principal</code> name value. + * the {@code Principal} class value, and when (y==1), + * it corresponds to the {@code Principal} name value. * For example, array[0][0] corresponds to the class name of - * the first <code>Principal</code> in the array. array[0][1] - * corresponds to the <code>Principal</code> name of the - * first <code>Principal</code> in the array. + * the first {@code Principal} in the array. array[0][1] + * corresponds to the {@code Principal} name of the + * first {@code Principal} in the array. * * <p> * - * @return the <code>Principal</code> class and names associated - * with this <code>PrivateCredentialPermission</code>. + * @return the {@code Principal} class and names associated + * with this {@code PrivateCredentialPermission}. */ public String[][] getPrincipals() { @@ -222,8 +222,8 @@ } /** - * Checks if this <code>PrivateCredentialPermission</code> implies - * the specified <code>Permission</code>. + * Checks if this {@code PrivateCredentialPermission} implies + * the specified {@code Permission}. * * <p> * @@ -241,10 +241,10 @@ * * <p> * - * @param p the <code>Permission</code> to check against. + * @param p the {@code Permission} to check against. * - * @return true if this <code>PrivateCredentialPermission</code> implies - * the specified <code>Permission</code>, false if not. + * @return true if this {@code PrivateCredentialPermission} implies + * the specified {@code Permission}, false if not. */ public boolean implies(Permission p) { @@ -260,9 +260,9 @@ } /** - * Checks two <code>PrivateCredentialPermission</code> objects for + * Checks two {@code PrivateCredentialPermission} objects for * equality. Checks that <i>obj</i> is a - * <code>PrivateCredentialPermission</code>, + * {@code PrivateCredentialPermission}, * and has the same credential class as this object, * as well as the same Principals as this object. * The order of the Principals in the respective Permission's @@ -272,7 +272,7 @@ * * @param obj the object we are testing for equality with this object. * - * @return true if obj is a <code>PrivateCredentialPermission</code>, + * @return true if obj is a {@code PrivateCredentialPermission}, * has the same credential class as this object, * and has the same Principals as this object. */ @@ -311,9 +311,9 @@ /** * Return a homogeneous collection of PrivateCredentialPermissions - * in a <code>PermissionCollection</code>. - * No such <code>PermissionCollection</code> is defined, - * so this method always returns <code>null</code>. + * in a {@code PermissionCollection}. + * No such {@code PermissionCollection} is defined, + * so this method always returns {@code null}. * * <p> *
--- a/src/share/classes/javax/security/auth/RefreshFailedException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/RefreshFailedException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -26,10 +26,10 @@ package javax.security.auth; /** - * Signals that a <code>refresh</code> operation failed. + * Signals that a {@code refresh} operation failed. * * <p> This exception is thrown by credentials implementing - * the <code>Refreshable</code> interface when the <code>refresh</code> + * the {@code Refreshable} interface when the {@code refresh} * method fails. * */
--- a/src/share/classes/javax/security/auth/Refreshable.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/Refreshable.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -37,24 +37,24 @@ public interface Refreshable { /** - * Determine if this <code>Object</code> is current. + * Determine if this {@code Object} is current. * * <p> * - * @return true if this <code>Object</code> is currently current, + * @return true if this {@code Object} is currently current, * false otherwise. */ boolean isCurrent(); /** * Update or extend the validity period for this - * <code>Object</code>. + * {@code Object}. * * <p> * * @exception SecurityException if the caller does not have permission * to update or extend the validity period for this - * <code>Object</code>. <p> + * {@code Object}. <p> * * @exception RefreshFailedException if the refresh attempt failed. */
--- a/src/share/classes/javax/security/auth/Subject.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/Subject.java Wed Jul 24 08:22:32 2013 -0300 @@ -42,39 +42,39 @@ import sun.security.util.ResourcesMgr; /** - * <p> A <code>Subject</code> represents a grouping of related information + * <p> A {@code Subject} represents a grouping of related information * for a single entity, such as a person. * Such information includes the Subject's identities as well as * its security-related attributes * (passwords and cryptographic keys, for example). * * <p> Subjects may potentially have multiple identities. - * Each identity is represented as a <code>Principal</code> - * within the <code>Subject</code>. Principals simply bind names to a - * <code>Subject</code>. For example, a <code>Subject</code> that happens + * Each identity is represented as a {@code Principal} + * within the {@code Subject}. Principals simply bind names to a + * {@code Subject}. For example, a {@code Subject} that happens * to be a person, Alice, might have two Principals: * one which binds "Alice Bar", the name on her driver license, - * to the <code>Subject</code>, and another which binds, + * to the {@code Subject}, and another which binds, * "999-99-9999", the number on her student identification card, - * to the <code>Subject</code>. Both Principals refer to the same - * <code>Subject</code> even though each has a different name. + * to the {@code Subject}. Both Principals refer to the same + * {@code Subject} even though each has a different name. * - * <p> A <code>Subject</code> may also own security-related attributes, + * <p> A {@code Subject} may also own security-related attributes, * which are referred to as credentials. * Sensitive credentials that require special protection, such as * private cryptographic keys, are stored within a private credential - * <code>Set</code>. Credentials intended to be shared, such as + * {@code Set}. Credentials intended to be shared, such as * public key certificates or Kerberos server tickets are stored - * within a public credential <code>Set</code>. Different permissions + * within a public credential {@code Set}. Different permissions * are required to access and modify the different credential Sets. * - * <p> To retrieve all the Principals associated with a <code>Subject</code>, - * invoke the <code>getPrincipals</code> method. To retrieve - * all the public or private credentials belonging to a <code>Subject</code>, - * invoke the <code>getPublicCredentials</code> method or - * <code>getPrivateCredentials</code> method, respectively. - * To modify the returned <code>Set</code> of Principals and credentials, - * use the methods defined in the <code>Set</code> class. + * <p> To retrieve all the Principals associated with a {@code Subject}, + * invoke the {@code getPrincipals} method. To retrieve + * all the public or private credentials belonging to a {@code Subject}, + * invoke the {@code getPublicCredentials} method or + * {@code getPrivateCredentials} method, respectively. + * To modify the returned {@code Set} of Principals and credentials, + * use the methods defined in the {@code Set} class. * For example: * <pre> * Subject subject; @@ -86,13 +86,13 @@ * subject.getPublicCredentials().add(credential); * </pre> * - * <p> This <code>Subject</code> class implements <code>Serializable</code>. - * While the Principals associated with the <code>Subject</code> are serialized, - * the credentials associated with the <code>Subject</code> are not. - * Note that the <code>java.security.Principal</code> class - * does not implement <code>Serializable</code>. Therefore all concrete - * <code>Principal</code> implementations associated with Subjects - * must implement <code>Serializable</code>. + * <p> This {@code Subject} class implements {@code Serializable}. + * While the Principals associated with the {@code Subject} are serialized, + * the credentials associated with the {@code Subject} are not. + * Note that the {@code java.security.Principal} class + * does not implement {@code Serializable}. Therefore all concrete + * {@code Principal} implementations associated with Subjects + * must implement {@code Serializable}. * * @see java.security.Principal * @see java.security.DomainCombiner @@ -102,14 +102,14 @@ private static final long serialVersionUID = -8308522755600156056L; /** - * A <code>Set</code> that provides a view of all of this + * A {@code Set} that provides a view of all of this * Subject's Principals * * <p> * * @serial Each element in this set is a - * <code>java.security.Principal</code>. - * The set is a <code>Subject.SecureSet</code>. + * {@code java.security.Principal}. + * The set is a {@code Subject.SecureSet}. */ Set<Principal> principals; @@ -135,21 +135,21 @@ = new ProtectionDomain[0]; /** - * Create an instance of a <code>Subject</code> - * with an empty <code>Set</code> of Principals and empty + * Create an instance of a {@code Subject} + * with an empty {@code Set} of Principals and empty * Sets of public and private credentials. * - * <p> The newly constructed Sets check whether this <code>Subject</code> + * <p> The newly constructed Sets check whether this {@code Subject} * has been set read-only before permitting subsequent modifications. * The newly created Sets also prevent illegal modifications * by ensuring that callers have sufficient permissions. * * <p> To modify the Principals Set, the caller must have - * <code>AuthPermission("modifyPrincipals")</code>. + * {@code AuthPermission("modifyPrincipals")}. * To modify the public credential Set, the caller must have - * <code>AuthPermission("modifyPublicCredentials")</code>. + * {@code AuthPermission("modifyPublicCredentials")}. * To modify the private credential Set, the caller must have - * <code>AuthPermission("modifyPrivateCredentials")</code>. + * {@code AuthPermission("modifyPrivateCredentials")}. */ public Subject() { @@ -162,39 +162,39 @@ } /** - * Create an instance of a <code>Subject</code> with + * Create an instance of a {@code Subject} with * Principals and credentials. * * <p> The Principals and credentials from the specified Sets * are copied into newly constructed Sets. - * These newly created Sets check whether this <code>Subject</code> + * These newly created Sets check whether this {@code Subject} * has been set read-only before permitting subsequent modifications. * The newly created Sets also prevent illegal modifications * by ensuring that callers have sufficient permissions. * * <p> To modify the Principals Set, the caller must have - * <code>AuthPermission("modifyPrincipals")</code>. + * {@code AuthPermission("modifyPrincipals")}. * To modify the public credential Set, the caller must have - * <code>AuthPermission("modifyPublicCredentials")</code>. + * {@code AuthPermission("modifyPublicCredentials")}. * To modify the private credential Set, the caller must have - * <code>AuthPermission("modifyPrivateCredentials")</code>. + * {@code AuthPermission("modifyPrivateCredentials")}. * <p> * - * @param readOnly true if the <code>Subject</code> is to be read-only, + * @param readOnly true if the {@code Subject} is to be read-only, * and false otherwise. <p> * - * @param principals the <code>Set</code> of Principals - * to be associated with this <code>Subject</code>. <p> + * @param principals the {@code Set} of Principals + * to be associated with this {@code Subject}. <p> * - * @param pubCredentials the <code>Set</code> of public credentials - * to be associated with this <code>Subject</code>. <p> + * @param pubCredentials the {@code Set} of public credentials + * to be associated with this {@code Subject}. <p> * - * @param privCredentials the <code>Set</code> of private credentials - * to be associated with this <code>Subject</code>. + * @param privCredentials the {@code Set} of private credentials + * to be associated with this {@code Subject}. * * @exception NullPointerException if the specified - * <code>principals</code>, <code>pubCredentials</code>, - * or <code>privCredentials</code> are <code>null</code>. + * {@code principals}, {@code pubCredentials}, + * or {@code privCredentials} are {@code null}. */ public Subject(boolean readOnly, Set<? extends Principal> principals, Set<?> pubCredentials, Set<?> privCredentials) @@ -216,24 +216,24 @@ } /** - * Set this <code>Subject</code> to be read-only. + * Set this {@code Subject} to be read-only. * * <p> Modifications (additions and removals) to this Subject's - * <code>Principal</code> <code>Set</code> and + * {@code Principal} {@code Set} and * credential Sets will be disallowed. - * The <code>destroy</code> operation on this Subject's credentials will + * The {@code destroy} operation on this Subject's credentials will * still be permitted. * - * <p> Subsequent attempts to modify the Subject's <code>Principal</code> + * <p> Subsequent attempts to modify the Subject's {@code Principal} * and credential Sets will result in an - * <code>IllegalStateException</code> being thrown. - * Also, once a <code>Subject</code> is read-only, + * {@code IllegalStateException} being thrown. + * Also, once a {@code Subject} is read-only, * it can not be reset to being writable again. * * <p> * * @exception SecurityException if the caller does not have permission - * to set this <code>Subject</code> to be read-only. + * to set this {@code Subject} to be read-only. */ public void setReadOnly() { java.lang.SecurityManager sm = System.getSecurityManager(); @@ -245,40 +245,40 @@ } /** - * Query whether this <code>Subject</code> is read-only. + * Query whether this {@code Subject} is read-only. * * <p> * - * @return true if this <code>Subject</code> is read-only, false otherwise. + * @return true if this {@code Subject} is read-only, false otherwise. */ public boolean isReadOnly() { return this.readOnly; } /** - * Get the <code>Subject</code> associated with the provided - * <code>AccessControlContext</code>. + * Get the {@code Subject} associated with the provided + * {@code AccessControlContext}. * - * <p> The <code>AccessControlContext</code> may contain many - * Subjects (from nested <code>doAs</code> calls). - * In this situation, the most recent <code>Subject</code> associated - * with the <code>AccessControlContext</code> is returned. + * <p> The {@code AccessControlContext} may contain many + * Subjects (from nested {@code doAs} calls). + * In this situation, the most recent {@code Subject} associated + * with the {@code AccessControlContext} is returned. * * <p> * - * @param acc the <code>AccessControlContext</code> from which to retrieve - * the <code>Subject</code>. + * @param acc the {@code AccessControlContext} from which to retrieve + * the {@code Subject}. * - * @return the <code>Subject</code> associated with the provided - * <code>AccessControlContext</code>, or <code>null</code> - * if no <code>Subject</code> is associated - * with the provided <code>AccessControlContext</code>. + * @return the {@code Subject} associated with the provided + * {@code AccessControlContext}, or {@code null} + * if no {@code Subject} is associated + * with the provided {@code AccessControlContext}. * * @exception SecurityException if the caller does not have permission - * to get the <code>Subject</code>. <p> + * to get the {@code Subject}. <p> * * @exception NullPointerException if the provided - * <code>AccessControlContext</code> is <code>null</code>. + * {@code AccessControlContext} is {@code null}. */ public static Subject getSubject(final AccessControlContext acc) { @@ -306,36 +306,36 @@ } /** - * Perform work as a particular <code>Subject</code>. + * Perform work as a particular {@code Subject}. * * <p> This method first retrieves the current Thread's - * <code>AccessControlContext</code> via - * <code>AccessController.getContext</code>, - * and then instantiates a new <code>AccessControlContext</code> + * {@code AccessControlContext} via + * {@code AccessController.getContext}, + * and then instantiates a new {@code AccessControlContext} * using the retrieved context along with a new - * <code>SubjectDomainCombiner</code> (constructed using - * the provided <code>Subject</code>). - * Finally, this method invokes <code>AccessController.doPrivileged</code>, - * passing it the provided <code>PrivilegedAction</code>, - * as well as the newly constructed <code>AccessControlContext</code>. + * {@code SubjectDomainCombiner} (constructed using + * the provided {@code Subject}). + * Finally, this method invokes {@code AccessController.doPrivileged}, + * passing it the provided {@code PrivilegedAction}, + * as well as the newly constructed {@code AccessControlContext}. * * <p> * - * @param subject the <code>Subject</code> that the specified - * <code>action</code> will run as. This parameter - * may be <code>null</code>. <p> + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}. <p> * * @param <T> the type of the value returned by the PrivilegedAction's * {@code run} method. * * @param action the code to be run as the specified - * <code>Subject</code>. <p> + * {@code Subject}. <p> * * @return the value returned by the PrivilegedAction's - * <code>run</code> method. + * {@code run} method. * - * @exception NullPointerException if the <code>PrivilegedAction</code> - * is <code>null</code>. <p> + * @exception NullPointerException if the {@code PrivilegedAction} + * is {@code null}. <p> * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -362,41 +362,41 @@ } /** - * Perform work as a particular <code>Subject</code>. + * Perform work as a particular {@code Subject}. * * <p> This method first retrieves the current Thread's - * <code>AccessControlContext</code> via - * <code>AccessController.getContext</code>, - * and then instantiates a new <code>AccessControlContext</code> + * {@code AccessControlContext} via + * {@code AccessController.getContext}, + * and then instantiates a new {@code AccessControlContext} * using the retrieved context along with a new - * <code>SubjectDomainCombiner</code> (constructed using - * the provided <code>Subject</code>). - * Finally, this method invokes <code>AccessController.doPrivileged</code>, - * passing it the provided <code>PrivilegedExceptionAction</code>, - * as well as the newly constructed <code>AccessControlContext</code>. + * {@code SubjectDomainCombiner} (constructed using + * the provided {@code Subject}). + * Finally, this method invokes {@code AccessController.doPrivileged}, + * passing it the provided {@code PrivilegedExceptionAction}, + * as well as the newly constructed {@code AccessControlContext}. * * <p> * - * @param subject the <code>Subject</code> that the specified - * <code>action</code> will run as. This parameter - * may be <code>null</code>. <p> + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}. <p> * * @param <T> the type of the value returned by the * PrivilegedExceptionAction's {@code run} method. * * @param action the code to be run as the specified - * <code>Subject</code>. <p> + * {@code Subject}. <p> * * @return the value returned by the - * PrivilegedExceptionAction's <code>run</code> method. + * PrivilegedExceptionAction's {@code run} method. * * @exception PrivilegedActionException if the - * <code>PrivilegedExceptionAction.run</code> + * {@code PrivilegedExceptionAction.run} * method throws a checked exception. <p> * * @exception NullPointerException if the specified - * <code>PrivilegedExceptionAction</code> is - * <code>null</code>. <p> + * {@code PrivilegedExceptionAction} is + * {@code null}. <p> * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -424,36 +424,36 @@ } /** - * Perform privileged work as a particular <code>Subject</code>. + * Perform privileged work as a particular {@code Subject}. * - * <p> This method behaves exactly as <code>Subject.doAs</code>, + * <p> This method behaves exactly as {@code Subject.doAs}, * except that instead of retrieving the current Thread's - * <code>AccessControlContext</code>, it uses the provided - * <code>AccessControlContext</code>. If the provided - * <code>AccessControlContext</code> is <code>null</code>, - * this method instantiates a new <code>AccessControlContext</code> + * {@code AccessControlContext}, it uses the provided + * {@code AccessControlContext}. If the provided + * {@code AccessControlContext} is {@code null}, + * this method instantiates a new {@code AccessControlContext} * with an empty collection of ProtectionDomains. * * <p> * - * @param subject the <code>Subject</code> that the specified - * <code>action</code> will run as. This parameter - * may be <code>null</code>. <p> + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}. <p> * * @param <T> the type of the value returned by the PrivilegedAction's * {@code run} method. * * @param action the code to be run as the specified - * <code>Subject</code>. <p> + * {@code Subject}. <p> * - * @param acc the <code>AccessControlContext</code> to be tied to the + * @param acc the {@code AccessControlContext} to be tied to the * specified <i>subject</i> and <i>action</i>. <p> * * @return the value returned by the PrivilegedAction's - * <code>run</code> method. + * {@code run} method. * - * @exception NullPointerException if the <code>PrivilegedAction</code> - * is <code>null</code>. <p> + * @exception NullPointerException if the {@code PrivilegedAction} + * is {@code null}. <p> * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -485,41 +485,41 @@ } /** - * Perform privileged work as a particular <code>Subject</code>. + * Perform privileged work as a particular {@code Subject}. * - * <p> This method behaves exactly as <code>Subject.doAs</code>, + * <p> This method behaves exactly as {@code Subject.doAs}, * except that instead of retrieving the current Thread's - * <code>AccessControlContext</code>, it uses the provided - * <code>AccessControlContext</code>. If the provided - * <code>AccessControlContext</code> is <code>null</code>, - * this method instantiates a new <code>AccessControlContext</code> + * {@code AccessControlContext}, it uses the provided + * {@code AccessControlContext}. If the provided + * {@code AccessControlContext} is {@code null}, + * this method instantiates a new {@code AccessControlContext} * with an empty collection of ProtectionDomains. * * <p> * - * @param subject the <code>Subject</code> that the specified - * <code>action</code> will run as. This parameter - * may be <code>null</code>. <p> + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}. <p> * * @param <T> the type of the value returned by the * PrivilegedExceptionAction's {@code run} method. * * @param action the code to be run as the specified - * <code>Subject</code>. <p> + * {@code Subject}. <p> * - * @param acc the <code>AccessControlContext</code> to be tied to the + * @param acc the {@code AccessControlContext} to be tied to the * specified <i>subject</i> and <i>action</i>. <p> * * @return the value returned by the - * PrivilegedExceptionAction's <code>run</code> method. + * PrivilegedExceptionAction's {@code run} method. * * @exception PrivilegedActionException if the - * <code>PrivilegedExceptionAction.run</code> + * {@code PrivilegedExceptionAction.run} * method throws a checked exception. <p> * * @exception NullPointerException if the specified - * <code>PrivilegedExceptionAction</code> is - * <code>null</code>. <p> + * {@code PrivilegedExceptionAction} is + * {@code null}. <p> * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -568,19 +568,19 @@ } /** - * Return the <code>Set</code> of Principals associated with this - * <code>Subject</code>. Each <code>Principal</code> represents - * an identity for this <code>Subject</code>. + * Return the {@code Set} of Principals associated with this + * {@code Subject}. Each {@code Principal} represents + * an identity for this {@code Subject}. * - * <p> The returned <code>Set</code> is backed by this Subject's - * internal <code>Principal</code> <code>Set</code>. Any modification - * to the returned <code>Set</code> affects the internal - * <code>Principal</code> <code>Set</code> as well. + * <p> The returned {@code Set} is backed by this Subject's + * internal {@code Principal} {@code Set}. Any modification + * to the returned {@code Set} affects the internal + * {@code Principal} {@code Set} as well. * * <p> * - * @return The <code>Set</code> of Principals associated with this - * <code>Subject</code>. + * @return The {@code Set} of Principals associated with this + * {@code Subject}. */ public Set<Principal> getPrincipals() { @@ -590,28 +590,28 @@ } /** - * Return a <code>Set</code> of Principals associated with this - * <code>Subject</code> that are instances or subclasses of the specified - * <code>Class</code>. + * Return a {@code Set} of Principals associated with this + * {@code Subject} that are instances or subclasses of the specified + * {@code Class}. * - * <p> The returned <code>Set</code> is not backed by this Subject's - * internal <code>Principal</code> <code>Set</code>. A new - * <code>Set</code> is created and returned for each method invocation. - * Modifications to the returned <code>Set</code> - * will not affect the internal <code>Principal</code> <code>Set</code>. + * <p> The returned {@code Set} is not backed by this Subject's + * internal {@code Principal} {@code Set}. A new + * {@code Set} is created and returned for each method invocation. + * Modifications to the returned {@code Set} + * will not affect the internal {@code Principal} {@code Set}. * * <p> * * @param <T> the type of the class modeled by {@code c} * - * @param c the returned <code>Set</code> of Principals will all be + * @param c the returned {@code Set} of Principals will all be * instances of this class. * - * @return a <code>Set</code> of Principals that are instances of the - * specified <code>Class</code>. + * @return a {@code Set} of Principals that are instances of the + * specified {@code Class}. * - * @exception NullPointerException if the specified <code>Class</code> - * is <code>null</code>. + * @exception NullPointerException if the specified {@code Class} + * is {@code null}. */ public <T extends Principal> Set<T> getPrincipals(Class<T> c) { @@ -625,18 +625,18 @@ } /** - * Return the <code>Set</code> of public credentials held by this - * <code>Subject</code>. + * Return the {@code Set} of public credentials held by this + * {@code Subject}. * - * <p> The returned <code>Set</code> is backed by this Subject's - * internal public Credential <code>Set</code>. Any modification - * to the returned <code>Set</code> affects the internal public - * Credential <code>Set</code> as well. + * <p> The returned {@code Set} is backed by this Subject's + * internal public Credential {@code Set}. Any modification + * to the returned {@code Set} affects the internal public + * Credential {@code Set} as well. * * <p> * - * @return A <code>Set</code> of public credentials held by this - * <code>Subject</code>. + * @return A {@code Set} of public credentials held by this + * {@code Subject}. */ public Set<Object> getPublicCredentials() { @@ -646,29 +646,29 @@ } /** - * Return the <code>Set</code> of private credentials held by this - * <code>Subject</code>. + * Return the {@code Set} of private credentials held by this + * {@code Subject}. * - * <p> The returned <code>Set</code> is backed by this Subject's - * internal private Credential <code>Set</code>. Any modification - * to the returned <code>Set</code> affects the internal private - * Credential <code>Set</code> as well. + * <p> The returned {@code Set} is backed by this Subject's + * internal private Credential {@code Set}. Any modification + * to the returned {@code Set} affects the internal private + * Credential {@code Set} as well. * * <p> A caller requires permissions to access the Credentials - * in the returned <code>Set</code>, or to modify the - * <code>Set</code> itself. A <code>SecurityException</code> + * in the returned {@code Set}, or to modify the + * {@code Set} itself. A {@code SecurityException} * is thrown if the caller does not have the proper permissions. * - * <p> While iterating through the <code>Set</code>, - * a <code>SecurityException</code> is thrown + * <p> While iterating through the {@code Set}, + * a {@code SecurityException} is thrown * if the caller does not have permission to access a - * particular Credential. The <code>Iterator</code> - * is nevertheless advanced to next element in the <code>Set</code>. + * particular Credential. The {@code Iterator} + * is nevertheless advanced to next element in the {@code Set}. * * <p> * - * @return A <code>Set</code> of private credentials held by this - * <code>Subject</code>. + * @return A {@code Set} of private credentials held by this + * {@code Subject}. */ public Set<Object> getPrivateCredentials() { @@ -686,28 +686,28 @@ } /** - * Return a <code>Set</code> of public credentials associated with this - * <code>Subject</code> that are instances or subclasses of the specified - * <code>Class</code>. + * Return a {@code Set} of public credentials associated with this + * {@code Subject} that are instances or subclasses of the specified + * {@code Class}. * - * <p> The returned <code>Set</code> is not backed by this Subject's - * internal public Credential <code>Set</code>. A new - * <code>Set</code> is created and returned for each method invocation. - * Modifications to the returned <code>Set</code> - * will not affect the internal public Credential <code>Set</code>. + * <p> The returned {@code Set} is not backed by this Subject's + * internal public Credential {@code Set}. A new + * {@code Set} is created and returned for each method invocation. + * Modifications to the returned {@code Set} + * will not affect the internal public Credential {@code Set}. * * <p> * * @param <T> the type of the class modeled by {@code c} * - * @param c the returned <code>Set</code> of public credentials will all be + * @param c the returned {@code Set} of public credentials will all be * instances of this class. * - * @return a <code>Set</code> of public credentials that are instances - * of the specified <code>Class</code>. + * @return a {@code Set} of public credentials that are instances + * of the specified {@code Class}. * - * @exception NullPointerException if the specified <code>Class</code> - * is <code>null</code>. + * @exception NullPointerException if the specified {@code Class} + * is {@code null}. */ public <T> Set<T> getPublicCredentials(Class<T> c) { @@ -721,32 +721,32 @@ } /** - * Return a <code>Set</code> of private credentials associated with this - * <code>Subject</code> that are instances or subclasses of the specified - * <code>Class</code>. + * Return a {@code Set} of private credentials associated with this + * {@code Subject} that are instances or subclasses of the specified + * {@code Class}. * * <p> The caller must have permission to access all of the - * requested Credentials, or a <code>SecurityException</code> + * requested Credentials, or a {@code SecurityException} * will be thrown. * - * <p> The returned <code>Set</code> is not backed by this Subject's - * internal private Credential <code>Set</code>. A new - * <code>Set</code> is created and returned for each method invocation. - * Modifications to the returned <code>Set</code> - * will not affect the internal private Credential <code>Set</code>. + * <p> The returned {@code Set} is not backed by this Subject's + * internal private Credential {@code Set}. A new + * {@code Set} is created and returned for each method invocation. + * Modifications to the returned {@code Set} + * will not affect the internal private Credential {@code Set}. * * <p> * * @param <T> the type of the class modeled by {@code c} * - * @param c the returned <code>Set</code> of private credentials will all be + * @param c the returned {@code Set} of private credentials will all be * instances of this class. * - * @return a <code>Set</code> of private credentials that are instances - * of the specified <code>Class</code>. + * @return a {@code Set} of private credentials that are instances + * of the specified {@code Class}. * - * @exception NullPointerException if the specified <code>Class</code> - * is <code>null</code>. + * @exception NullPointerException if the specified {@code Class} + * is {@code null}. */ public <T> Set<T> getPrivateCredentials(Class<T> c) { @@ -768,25 +768,25 @@ } /** - * Compares the specified Object with this <code>Subject</code> + * Compares the specified Object with this {@code Subject} * for equality. Returns true if the given object is also a Subject - * and the two <code>Subject</code> instances are equivalent. - * More formally, two <code>Subject</code> instances are - * equal if their <code>Principal</code> and <code>Credential</code> + * and the two {@code Subject} instances are equivalent. + * More formally, two {@code Subject} instances are + * equal if their {@code Principal} and {@code Credential} * Sets are equal. * * <p> * * @param o Object to be compared for equality with this - * <code>Subject</code>. + * {@code Subject}. * * @return true if the specified Object is equal to this - * <code>Subject</code>. + * {@code Subject}. * * @exception SecurityException if the caller does not have permission - * to access the private credentials for this <code>Subject</code>, + * to access the private credentials for this {@code Subject}, * or if the caller does not have permission to access the - * private credentials for the provided <code>Subject</code>. + * private credentials for the provided {@code Subject}. */ public boolean equals(Object o) { @@ -833,11 +833,11 @@ } /** - * Return the String representation of this <code>Subject</code>. + * Return the String representation of this {@code Subject}. * * <p> * - * @return the String representation of this <code>Subject</code>. + * @return the String representation of this {@code Subject}. */ public String toString() { return toString(true); @@ -894,11 +894,11 @@ } /** - * Returns a hashcode for this <code>Subject</code>. + * Returns a hashcode for this {@code Subject}. * * <p> * - * @return a hashcode for this <code>Subject</code>. + * @return a hashcode for this {@code Subject}. * * @exception SecurityException if the caller does not have permission * to access this Subject's private credentials. @@ -910,10 +910,10 @@ * hashcodes of this Subject's Principals and credentials. * * If a particular credential was destroyed - * (<code>credential.hashCode()</code> throws an - * <code>IllegalStateException</code>), + * ({@code credential.hashCode()} throws an + * {@code IllegalStateException}), * the hashcode for that credential is derived via: - * <code>credential.getClass().toString().hashCode()</code>. + * {@code credential.getClass().toString().hashCode()}. */ int hashCode = 0; @@ -964,7 +964,7 @@ s.defaultReadObject(); - // The Credential <code>Set</code> is not serialized, but we do not + // The Credential {@code Set} is not serialized, but we do not // want the default deserialization routine to set it to null. this.pubCredentials = Collections.synchronizedSet (new SecureSet<Object>(this, PUB_CREDENTIAL_SET)); @@ -998,13 +998,13 @@ /** * @serial An integer identifying the type of objects contained - * in this set. If <code>which == 1</code>, + * in this set. If {@code which == 1}, * this is a Principal set and all the elements are - * of type <code>java.security.Principal</code>. - * If <code>which == 2</code>, this is a public credential - * set and all the elements are of type <code>Object</code>. - * If <code>which == 3</code>, this is a private credential - * set and all the elements are of type <code>Object</code>. + * of type {@code java.security.Principal}. + * If {@code which == 2}, this is a public credential + * set and all the elements are of type {@code Object}. + * If {@code which == 3}, this is a private credential + * set and all the elements are of type {@code Object}. */ private int which; @@ -1321,7 +1321,7 @@ } /** - * This class implements a <code>Set</code> which returns only + * This class implements a {@code Set} which returns only * members that are an instance of a specified Class. */ private class ClassSet<T> extends AbstractSet<T> {
--- a/src/share/classes/javax/security/auth/SubjectDomainCombiner.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/SubjectDomainCombiner.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -39,9 +39,9 @@ import java.lang.ref.WeakReference; /** - * A <code>SubjectDomainCombiner</code> updates ProtectionDomains - * with Principals from the <code>Subject</code> associated with this - * <code>SubjectDomainCombiner</code>. + * A {@code SubjectDomainCombiner} updates ProtectionDomains + * with Principals from the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * */ public class SubjectDomainCombiner implements java.security.DomainCombiner { @@ -66,13 +66,13 @@ (useJavaxPolicy && cachePolicy()); /** - * Associate the provided <code>Subject</code> with this - * <code>SubjectDomainCombiner</code>. + * Associate the provided {@code Subject} with this + * {@code SubjectDomainCombiner}. * * <p> * - * @param subject the <code>Subject</code> to be associated with - * with this <code>SubjectDomainCombiner</code>. + * @param subject the {@code Subject} to be associated with + * with this {@code SubjectDomainCombiner}. */ public SubjectDomainCombiner(Subject subject) { this.subject = subject; @@ -85,19 +85,19 @@ } /** - * Get the <code>Subject</code> associated with this - * <code>SubjectDomainCombiner</code>. + * Get the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * * <p> * - * @return the <code>Subject</code> associated with this - * <code>SubjectDomainCombiner</code>, or <code>null</code> - * if no <code>Subject</code> is associated with this - * <code>SubjectDomainCombiner</code>. + * @return the {@code Subject} associated with this + * {@code SubjectDomainCombiner}, or {@code null} + * if no {@code Subject} is associated with this + * {@code SubjectDomainCombiner}. * * @exception SecurityException if the caller does not have permission - * to get the <code>Subject</code> associated with this - * <code>SubjectDomainCombiner</code>. + * to get the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. */ public Subject getSubject() { java.lang.SecurityManager sm = System.getSecurityManager(); @@ -110,18 +110,18 @@ /** * Update the relevant ProtectionDomains with the Principals - * from the <code>Subject</code> associated with this - * <code>SubjectDomainCombiner</code>. + * from the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * - * <p> A new <code>ProtectionDomain</code> instance is created - * for each <code>ProtectionDomain</code> in the - * <i>currentDomains</i> array. Each new <code>ProtectionDomain</code> - * instance is created using the <code>CodeSource</code>, - * <code>Permission</code>s and <code>ClassLoader</code> - * from the corresponding <code>ProtectionDomain</code> in + * <p> A new {@code ProtectionDomain} instance is created + * for each {@code ProtectionDomain} in the + * <i>currentDomains</i> array. Each new {@code ProtectionDomain} + * instance is created using the {@code CodeSource}, + * {@code Permission}s and {@code ClassLoader} + * from the corresponding {@code ProtectionDomain} in * <i>currentDomains</i>, as well as with the Principals from - * the <code>Subject</code> associated with this - * <code>SubjectDomainCombiner</code>. + * the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * * <p> All of the newly instantiated ProtectionDomains are * combined into a new array. The ProtectionDomains from the @@ -136,23 +136,23 @@ * * @param currentDomains the ProtectionDomains associated with the * current execution Thread, up to the most recent - * privileged <code>ProtectionDomain</code>. + * privileged {@code ProtectionDomain}. * The ProtectionDomains are are listed in order of execution, - * with the most recently executing <code>ProtectionDomain</code> + * with the most recently executing {@code ProtectionDomain} * residing at the beginning of the array. This parameter may - * be <code>null</code> if the current execution Thread + * be {@code null} if the current execution Thread * has no associated ProtectionDomains.<p> * * @param assignedDomains the ProtectionDomains inherited from the * parent Thread, or the ProtectionDomains from the * privileged <i>context</i>, if a call to * AccessController.doPrivileged(..., <i>context</i>) - * had occurred This parameter may be <code>null</code> + * had occurred This parameter may be {@code null} * if there were no ProtectionDomains inherited from the * parent Thread, or from the privileged <i>context</i>. * * @return a new array consisting of the updated ProtectionDomains, - * or <code>null</code>. + * or {@code null}. */ public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, ProtectionDomain[] assignedDomains) {
--- a/src/share/classes/javax/security/auth/callback/Callback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/Callback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -28,14 +28,14 @@ /** * <p> Implementations of this interface are passed to a - * <code>CallbackHandler</code>, allowing underlying security services + * {@code CallbackHandler}, allowing underlying security services * the ability to interact with a calling application to retrieve specific * authentication data such as usernames and passwords, or to display * certain information, such as error and warning messages. * - * <p> <code>Callback</code> implementations do not retrieve or + * <p> {@code Callback} implementations do not retrieve or * display the information requested by underlying security services. - * <code>Callback</code> implementations simply provide the means + * {@code Callback} implementations simply provide the means * to pass such requests to applications, and for applications, * if appropriate, to return requested information back to the * underlying security services.
--- a/src/share/classes/javax/security/auth/callback/CallbackHandler.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/CallbackHandler.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -26,7 +26,7 @@ package javax.security.auth.callback; /** - * <p> An application implements a <code>CallbackHandler</code> and passes + * <p> An application implements a {@code CallbackHandler} and passes * it to underlying security services so that they may interact with * the application to retrieve specific authentication data, * such as usernames and passwords, or to display certain information, @@ -40,12 +40,12 @@ * * <p> Underlying security services make requests for different types * of information by passing individual Callbacks to the - * <code>CallbackHandler</code>. The <code>CallbackHandler</code> + * {@code CallbackHandler}. The {@code CallbackHandler} * implementation decides how to retrieve and display information * depending on the Callbacks passed to it. For example, * if the underlying service needs a username and password to - * authenticate a user, it uses a <code>NameCallback</code> and - * <code>PasswordCallback</code>. The <code>CallbackHandler</code> + * authenticate a user, it uses a {@code NameCallback} and + * {@code PasswordCallback}. The {@code CallbackHandler} * can then choose to prompt for a username and password serially, * or to prompt for both in a single window. * @@ -54,10 +54,10 @@ * {@code auth.login.defaultCallbackHandler} security property. * * <p> If the security property is set to the fully qualified name of a - * <code>CallbackHandler</code> implementation class, - * then a <code>LoginContext</code> will load the specified - * <code>CallbackHandler</code> and pass it to the underlying LoginModules. - * The <code>LoginContext</code> only loads the default handler + * {@code CallbackHandler} implementation class, + * then a {@code LoginContext} will load the specified + * {@code CallbackHandler} and pass it to the underlying LoginModules. + * The {@code LoginContext} only loads the default handler * if it was not provided one. * * <p> All default handler implementations must provide a public @@ -71,11 +71,11 @@ * <p> Retrieve or display the information requested in the * provided Callbacks. * - * <p> The <code>handle</code> method implementation checks the - * instance(s) of the <code>Callback</code> object(s) passed in + * <p> The {@code handle} method implementation checks the + * instance(s) of the {@code Callback} object(s) passed in * to retrieve or display the requested information. * The following example is provided to help demonstrate what an - * <code>handle</code> method implementation might look like. + * {@code handle} method implementation might look like. * This example code is for guidance only. Many details, * including proper error handling, are left out for simplicity. * @@ -135,7 +135,7 @@ * } * }</pre> * - * @param callbacks an array of <code>Callback</code> objects provided + * @param callbacks an array of {@code Callback} objects provided * by an underlying security service which contains * the information requested to be retrieved or displayed. * @@ -143,7 +143,7 @@ * * @exception UnsupportedCallbackException if the implementation of this * method does not support one or more of the Callbacks - * specified in the <code>callbacks</code> parameter. + * specified in the {@code callbacks} parameter. */ void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException;
--- a/src/share/classes/javax/security/auth/callback/ChoiceCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/ChoiceCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -27,8 +27,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>ChoiceCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to display a list of choices + * {@code ChoiceCallback} to the {@code handle} + * method of a {@code CallbackHandler} to display a list of choices * and to retrieve the selected choice(s). * * @see javax.security.auth.callback.CallbackHandler @@ -60,13 +60,13 @@ private boolean multipleSelectionsAllowed; /** * @serial the selected choices, represented as indexes into the - * <code>choices</code> list. + * {@code choices} list. * @since 1.4 */ private int[] selections; /** - * Construct a <code>ChoiceCallback</code> with a prompt, + * Construct a {@code ChoiceCallback} with a prompt, * a list of choices, a default choice, and a boolean specifying * whether or not multiple selections from the list of choices are allowed. * @@ -79,21 +79,21 @@ * @param defaultChoice the choice to be used as the default choice * when the list of choices are displayed. This value * is represented as an index into the - * <code>choices</code> array. <p> + * {@code choices} array. <p> * * @param multipleSelectionsAllowed boolean specifying whether or * not multiple selections can be made from the * list of choices. * - * @exception IllegalArgumentException if <code>prompt</code> is null, - * if <code>prompt</code> has a length of 0, - * if <code>choices</code> is null, - * if <code>choices</code> has a length of 0, - * if any element from <code>choices</code> is null, - * if any element from <code>choices</code> - * has a length of 0 or if <code>defaultChoice</code> + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, + * if {@code choices} is null, + * if {@code choices} has a length of 0, + * if any element from {@code choices} is null, + * if any element from {@code choices} + * has a length of 0 or if {@code defaultChoice} * does not fall within the array boundaries of - * <code>choices</code>. + * {@code choices}. */ public ChoiceCallback(String prompt, String[] choices, int defaultChoice, boolean multipleSelectionsAllowed) { @@ -142,7 +142,7 @@ * <p> * * @return the defaultChoice, represented as an index into - * the <code>choices</code> list. + * the {@code choices} list. */ public int getDefaultChoice() { return defaultChoice; @@ -150,7 +150,7 @@ /** * Get the boolean determining whether multiple selections from - * the <code>choices</code> list are allowed. + * the {@code choices} list are allowed. * * <p> * @@ -166,7 +166,7 @@ * <p> * * @param selection the selection represented as an index into the - * <code>choices</code> list. + * {@code choices} list. * * @see #getSelectedIndexes */ @@ -181,11 +181,11 @@ * <p> * * @param selections the selections represented as indexes into the - * <code>choices</code> list. + * {@code choices} list. * * @exception UnsupportedOperationException if multiple selections are * not allowed, as determined by - * <code>allowMultipleSelections</code>. + * {@code allowMultipleSelections}. * * @see #getSelectedIndexes */ @@ -201,7 +201,7 @@ * <p> * * @return the selected choices, represented as indexes into the - * <code>choices</code> list. + * {@code choices} list. * * @see #setSelectedIndexes */
--- a/src/share/classes/javax/security/auth/callback/ConfirmationCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/ConfirmationCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -27,8 +27,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>ConfirmationCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to ask for YES/NO, + * {@code ConfirmationCallback} to the {@code handle} + * method of a {@code CallbackHandler} to ask for YES/NO, * OK/CANCEL, YES/NO/CANCEL or other similar confirmations. * * @see javax.security.auth.callback.CallbackHandler @@ -40,9 +40,9 @@ /** * Unspecified option type. * - * <p> The <code>getOptionType</code> method returns this - * value if this <code>ConfirmationCallback</code> was instantiated - * with <code>options</code> instead of an <code>optionType</code>. + * <p> The {@code getOptionType} method returns this + * value if this {@code ConfirmationCallback} was instantiated + * with {@code options} instead of an {@code optionType}. */ public static final int UNSPECIFIED_OPTION = -1; @@ -50,9 +50,9 @@ * YES/NO confirmation option. * * <p> An underlying security service specifies this as the - * <code>optionType</code> to a <code>ConfirmationCallback</code> + * {@code optionType} to a {@code ConfirmationCallback} * constructor if it requires a confirmation which can be answered - * with either <code>YES</code> or <code>NO</code>. + * with either {@code YES} or {@code NO}. */ public static final int YES_NO_OPTION = 0; @@ -60,9 +60,9 @@ * YES/NO/CANCEL confirmation confirmation option. * * <p> An underlying security service specifies this as the - * <code>optionType</code> to a <code>ConfirmationCallback</code> + * {@code optionType} to a {@code ConfirmationCallback} * constructor if it requires a confirmation which can be answered - * with either <code>YES</code>, <code>NO</code> or <code>CANCEL</code>. + * with either {@code YES}, {@code NO} or {@code CANCEL}. */ public static final int YES_NO_CANCEL_OPTION = 1; @@ -70,45 +70,45 @@ * OK/CANCEL confirmation confirmation option. * * <p> An underlying security service specifies this as the - * <code>optionType</code> to a <code>ConfirmationCallback</code> + * {@code optionType} to a {@code ConfirmationCallback} * constructor if it requires a confirmation which can be answered - * with either <code>OK</code> or <code>CANCEL</code>. + * with either {@code OK} or {@code CANCEL}. */ public static final int OK_CANCEL_OPTION = 2; /** * YES option. * - * <p> If an <code>optionType</code> was specified to this - * <code>ConfirmationCallback</code>, this option may be specified as a - * <code>defaultOption</code> or returned as the selected index. + * <p> If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int YES = 0; /** * NO option. * - * <p> If an <code>optionType</code> was specified to this - * <code>ConfirmationCallback</code>, this option may be specified as a - * <code>defaultOption</code> or returned as the selected index. + * <p> If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int NO = 1; /** * CANCEL option. * - * <p> If an <code>optionType</code> was specified to this - * <code>ConfirmationCallback</code>, this option may be specified as a - * <code>defaultOption</code> or returned as the selected index. + * <p> If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int CANCEL = 2; /** * OK option. * - * <p> If an <code>optionType</code> was specified to this - * <code>ConfirmationCallback</code>, this option may be specified as a - * <code>defaultOption</code> or returned as the selected index. + * <p> If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int OK = 3; @@ -152,7 +152,7 @@ private int selection; /** - * Construct a <code>ConfirmationCallback</code> with a + * Construct a {@code ConfirmationCallback} with a * message type, an option type and a default option. * * <p> Underlying security services use this constructor if @@ -161,27 +161,27 @@ * * <p> * - * @param messageType the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). <p> + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). <p> * - * @param optionType the option type (<code>YES_NO_OPTION</code>, - * <code>YES_NO_CANCEL_OPTION</code> or - * <code>OK_CANCEL_OPTION</code>). <p> + * @param optionType the option type ({@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION} or + * {@code OK_CANCEL_OPTION}). <p> * * @param defaultOption the default option - * from the provided optionType (<code>YES</code>, - * <code>NO</code>, <code>CANCEL</code> or - * <code>OK</code>). + * from the provided optionType ({@code YES}, + * {@code NO}, {@code CANCEL} or + * {@code OK}). * * @exception IllegalArgumentException if messageType is not either - * <code>INFORMATION</code>, <code>WARNING</code>, - * or <code>ERROR</code>, if optionType is not either - * <code>YES_NO_OPTION</code>, - * <code>YES_NO_CANCEL_OPTION</code>, or - * <code>OK_CANCEL_OPTION</code>, - * or if <code>defaultOption</code> + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if optionType is not either + * {@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION}, or + * {@code OK_CANCEL_OPTION}, + * or if {@code defaultOption} * does not correspond to one of the options in - * <code>optionType</code>. + * {@code optionType}. */ public ConfirmationCallback(int messageType, int optionType, int defaultOption) { @@ -212,35 +212,35 @@ } /** - * Construct a <code>ConfirmationCallback</code> with a + * Construct a {@code ConfirmationCallback} with a * message type, a list of options and a default option. * * <p> Underlying security services use this constructor if * they require a confirmation different from the available preset * confirmations provided (for example, CONTINUE/ABORT or STOP/GO). - * The confirmation options are listed in the <code>options</code> array, - * and are displayed by the <code>CallbackHandler</code> implementation + * The confirmation options are listed in the {@code options} array, + * and are displayed by the {@code CallbackHandler} implementation * in a manner consistent with the way preset options are displayed. * * <p> * - * @param messageType the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). <p> + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). <p> * * @param options the list of confirmation options. <p> * * @param defaultOption the default option, represented as an index - * into the <code>options</code> array. + * into the {@code options} array. * * @exception IllegalArgumentException if messageType is not either - * <code>INFORMATION</code>, <code>WARNING</code>, - * or <code>ERROR</code>, if <code>options</code> is null, - * if <code>options</code> has a length of 0, - * if any element from <code>options</code> is null, - * if any element from <code>options</code> - * has a length of 0, or if <code>defaultOption</code> + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if {@code options} is null, + * if {@code options} has a length of 0, + * if any element from {@code options} is null, + * if any element from {@code options} + * has a length of 0, or if {@code defaultOption} * does not lie within the array boundaries of - * <code>options</code>. + * {@code options}. */ public ConfirmationCallback(int messageType, String[] options, int defaultOption) { @@ -261,7 +261,7 @@ } /** - * Construct a <code>ConfirmationCallback</code> with a prompt, + * Construct a {@code ConfirmationCallback} with a prompt, * message type, an option type and a default option. * * <p> Underlying security services use this constructor if @@ -272,29 +272,29 @@ * * @param prompt the prompt used to describe the list of options. <p> * - * @param messageType the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). <p> + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). <p> * - * @param optionType the option type (<code>YES_NO_OPTION</code>, - * <code>YES_NO_CANCEL_OPTION</code> or - * <code>OK_CANCEL_OPTION</code>). <p> + * @param optionType the option type ({@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION} or + * {@code OK_CANCEL_OPTION}). <p> * * @param defaultOption the default option - * from the provided optionType (<code>YES</code>, - * <code>NO</code>, <code>CANCEL</code> or - * <code>OK</code>). + * from the provided optionType ({@code YES}, + * {@code NO}, {@code CANCEL} or + * {@code OK}). * - * @exception IllegalArgumentException if <code>prompt</code> is null, - * if <code>prompt</code> has a length of 0, + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, * if messageType is not either - * <code>INFORMATION</code>, <code>WARNING</code>, - * or <code>ERROR</code>, if optionType is not either - * <code>YES_NO_OPTION</code>, - * <code>YES_NO_CANCEL_OPTION</code>, or - * <code>OK_CANCEL_OPTION</code>, - * or if <code>defaultOption</code> + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if optionType is not either + * {@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION}, or + * {@code OK_CANCEL_OPTION}, + * or if {@code defaultOption} * does not correspond to one of the options in - * <code>optionType</code>. + * {@code optionType}. */ public ConfirmationCallback(String prompt, int messageType, int optionType, int defaultOption) { @@ -327,39 +327,39 @@ } /** - * Construct a <code>ConfirmationCallback</code> with a prompt, + * Construct a {@code ConfirmationCallback} with a prompt, * message type, a list of options and a default option. * * <p> Underlying security services use this constructor if * they require a confirmation different from the available preset * confirmations provided (for example, CONTINUE/ABORT or STOP/GO). - * The confirmation options are listed in the <code>options</code> array, - * and are displayed by the <code>CallbackHandler</code> implementation + * The confirmation options are listed in the {@code options} array, + * and are displayed by the {@code CallbackHandler} implementation * in a manner consistent with the way preset options are displayed. * * <p> * * @param prompt the prompt used to describe the list of options. <p> * - * @param messageType the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). <p> + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). <p> * * @param options the list of confirmation options. <p> * * @param defaultOption the default option, represented as an index - * into the <code>options</code> array. + * into the {@code options} array. * - * @exception IllegalArgumentException if <code>prompt</code> is null, - * if <code>prompt</code> has a length of 0, + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, * if messageType is not either - * <code>INFORMATION</code>, <code>WARNING</code>, - * or <code>ERROR</code>, if <code>options</code> is null, - * if <code>options</code> has a length of 0, - * if any element from <code>options</code> is null, - * if any element from <code>options</code> - * has a length of 0, or if <code>defaultOption</code> + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if {@code options} is null, + * if {@code options} has a length of 0, + * if any element from {@code options} is null, + * if any element from {@code options} + * has a length of 0, or if {@code defaultOption} * does not lie within the array boundaries of - * <code>options</code>. + * {@code options}. */ public ConfirmationCallback(String prompt, int messageType, String[] options, int defaultOption) { @@ -386,8 +386,8 @@ * * <p> * - * @return the prompt, or null if this <code>ConfirmationCallback</code> - * was instantiated without a <code>prompt</code>. + * @return the prompt, or null if this {@code ConfirmationCallback} + * was instantiated without a {@code prompt}. */ public String getPrompt() { return prompt; @@ -398,8 +398,8 @@ * * <p> * - * @return the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). + * @return the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). */ public int getMessageType() { return messageType; @@ -408,20 +408,20 @@ /** * Get the option type. * - * <p> If this method returns <code>UNSPECIFIED_OPTION</code>, then this - * <code>ConfirmationCallback</code> was instantiated with - * <code>options</code> instead of an <code>optionType</code>. - * In this case, invoke the <code>getOptions</code> method + * <p> If this method returns {@code UNSPECIFIED_OPTION}, then this + * {@code ConfirmationCallback} was instantiated with + * {@code options} instead of an {@code optionType}. + * In this case, invoke the {@code getOptions} method * to determine which confirmation options to display. * * <p> * - * @return the option type (<code>YES_NO_OPTION</code>, - * <code>YES_NO_CANCEL_OPTION</code> or - * <code>OK_CANCEL_OPTION</code>), or - * <code>UNSPECIFIED_OPTION</code> if this - * <code>ConfirmationCallback</code> was instantiated with - * <code>options</code> instead of an <code>optionType</code>. + * @return the option type ({@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION} or + * {@code OK_CANCEL_OPTION}), or + * {@code UNSPECIFIED_OPTION} if this + * {@code ConfirmationCallback} was instantiated with + * {@code options} instead of an {@code optionType}. */ public int getOptionType() { return optionType; @@ -433,8 +433,8 @@ * <p> * * @return the list of confirmation options, or null if this - * <code>ConfirmationCallback</code> was instantiated with - * an <code>optionType</code> instead of <code>options</code>. + * {@code ConfirmationCallback} was instantiated with + * an {@code optionType} instead of {@code options}. */ public String[] getOptions() { return options; @@ -446,14 +446,14 @@ * <p> * * @return the default option, represented as - * <code>YES</code>, <code>NO</code>, <code>OK</code> or - * <code>CANCEL</code> if an <code>optionType</code> + * {@code YES}, {@code NO}, {@code OK} or + * {@code CANCEL} if an {@code optionType} * was specified to the constructor of this - * <code>ConfirmationCallback</code>. + * {@code ConfirmationCallback}. * Otherwise, this method returns the default option as * an index into the - * <code>options</code> array specified to the constructor - * of this <code>ConfirmationCallback</code>. + * {@code options} array specified to the constructor + * of this {@code ConfirmationCallback}. */ public int getDefaultOption() { return defaultOption; @@ -464,13 +464,13 @@ * * <p> * - * @param selection the selection represented as <code>YES</code>, - * <code>NO</code>, <code>OK</code> or <code>CANCEL</code> - * if an <code>optionType</code> was specified to the constructor - * of this <code>ConfirmationCallback</code>. + * @param selection the selection represented as {@code YES}, + * {@code NO}, {@code OK} or {@code CANCEL} + * if an {@code optionType} was specified to the constructor + * of this {@code ConfirmationCallback}. * Otherwise, the selection represents the index into the - * <code>options</code> array specified to the constructor - * of this <code>ConfirmationCallback</code>. + * {@code options} array specified to the constructor + * of this {@code ConfirmationCallback}. * * @see #getSelectedIndex */ @@ -484,14 +484,14 @@ * <p> * * @return the selected confirmation option represented as - * <code>YES</code>, <code>NO</code>, <code>OK</code> or - * <code>CANCEL</code> if an <code>optionType</code> + * {@code YES}, {@code NO}, {@code OK} or + * {@code CANCEL} if an {@code optionType} * was specified to the constructor of this - * <code>ConfirmationCallback</code>. + * {@code ConfirmationCallback}. * Otherwise, this method returns the selected confirmation * option as an index into the - * <code>options</code> array specified to the constructor - * of this <code>ConfirmationCallback</code>. + * {@code options} array specified to the constructor + * of this {@code ConfirmationCallback}. * * @see #setSelectedIndex */
--- a/src/share/classes/javax/security/auth/callback/LanguageCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/LanguageCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -29,8 +29,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>LanguageCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to retrieve the <code>Locale</code> + * {@code LanguageCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve the {@code Locale} * used for localizing text. * * @see javax.security.auth.callback.CallbackHandler @@ -46,16 +46,16 @@ private Locale locale; /** - * Construct a <code>LanguageCallback</code>. + * Construct a {@code LanguageCallback}. */ public LanguageCallback() { } /** - * Set the retrieved <code>Locale</code>. + * Set the retrieved {@code Locale}. * * <p> * - * @param locale the retrieved <code>Locale</code>. + * @param locale the retrieved {@code Locale}. * * @see #getLocale */ @@ -64,12 +64,12 @@ } /** - * Get the retrieved <code>Locale</code>. + * Get the retrieved {@code Locale}. * * <p> * - * @return the retrieved <code>Locale</code>, or null - * if no <code>Locale</code> could be retrieved. + * @return the retrieved {@code Locale}, or null + * if no {@code Locale} could be retrieved. * * @see #setLocale */
--- a/src/share/classes/javax/security/auth/callback/NameCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/NameCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -27,8 +27,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>NameCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to retrieve name information. + * {@code NameCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve name information. * * @see javax.security.auth.callback.CallbackHandler */ @@ -53,14 +53,14 @@ private String inputName; /** - * Construct a <code>NameCallback</code> with a prompt. + * Construct a {@code NameCallback} with a prompt. * * <p> * * @param prompt the prompt used to request the name. * - * @exception IllegalArgumentException if <code>prompt</code> is null - * or if <code>prompt</code> has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null + * or if {@code prompt} has a length of 0. */ public NameCallback(String prompt) { if (prompt == null || prompt.length() == 0) @@ -69,7 +69,7 @@ } /** - * Construct a <code>NameCallback</code> with a prompt + * Construct a {@code NameCallback} with a prompt * and default name. * * <p> @@ -79,10 +79,10 @@ * @param defaultName the name to be used as the default name displayed * with the prompt. * - * @exception IllegalArgumentException if <code>prompt</code> is null, - * if <code>prompt</code> has a length of 0, - * if <code>defaultName</code> is null, - * or if <code>defaultName</code> has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, + * if {@code defaultName} is null, + * or if {@code defaultName} has a length of 0. */ public NameCallback(String prompt, String defaultName) { if (prompt == null || prompt.length() == 0 || @@ -109,8 +109,8 @@ * * <p> * - * @return the default name, or null if this <code>NameCallback</code> - * was not instantiated with a <code>defaultName</code>. + * @return the default name, or null if this {@code NameCallback} + * was not instantiated with a {@code defaultName}. */ public String getDefaultName() { return defaultName;
--- a/src/share/classes/javax/security/auth/callback/PasswordCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/PasswordCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -27,8 +27,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>PasswordCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to retrieve password information. + * {@code PasswordCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve password information. * * @see javax.security.auth.callback.CallbackHandler */ @@ -53,7 +53,7 @@ private char[] inputPassword; /** - * Construct a <code>PasswordCallback</code> with a prompt + * Construct a {@code PasswordCallback} with a prompt * and a boolean specifying whether the password should be displayed * as it is being typed. * @@ -64,8 +64,8 @@ * @param echoOn true if the password should be displayed * as it is being typed. * - * @exception IllegalArgumentException if <code>prompt</code> is null or - * if <code>prompt</code> has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null or + * if {@code prompt} has a length of 0. */ public PasswordCallback(String prompt, boolean echoOn) { if (prompt == null || prompt.length() == 0)
--- a/src/share/classes/javax/security/auth/callback/TextInputCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/TextInputCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -27,8 +27,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>TextInputCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to retrieve generic text + * {@code TextInputCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve generic text * information. * * @see javax.security.auth.callback.CallbackHandler @@ -54,14 +54,14 @@ private String inputText; /** - * Construct a <code>TextInputCallback</code> with a prompt. + * Construct a {@code TextInputCallback} with a prompt. * * <p> * * @param prompt the prompt used to request the information. * - * @exception IllegalArgumentException if <code>prompt</code> is null - * or if <code>prompt</code> has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null + * or if {@code prompt} has a length of 0. */ public TextInputCallback(String prompt) { if (prompt == null || prompt.length() == 0) @@ -70,7 +70,7 @@ } /** - * Construct a <code>TextInputCallback</code> with a prompt + * Construct a {@code TextInputCallback} with a prompt * and default input value. * * <p> @@ -80,10 +80,10 @@ * @param defaultText the text to be used as the default text displayed * with the prompt. * - * @exception IllegalArgumentException if <code>prompt</code> is null, - * if <code>prompt</code> has a length of 0, - * if <code>defaultText</code> is null - * or if <code>defaultText</code> has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, + * if {@code defaultText} is null + * or if {@code defaultText} has a length of 0. */ public TextInputCallback(String prompt, String defaultText) { if (prompt == null || prompt.length() == 0 || @@ -110,8 +110,8 @@ * * <p> * - * @return the default text, or null if this <code>TextInputCallback</code> - * was not instantiated with <code>defaultText</code>. + * @return the default text, or null if this {@code TextInputCallback} + * was not instantiated with {@code defaultText}. */ public String getDefaultText() { return defaultText;
--- a/src/share/classes/javax/security/auth/callback/TextOutputCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/TextOutputCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -27,8 +27,8 @@ /** * <p> Underlying security services instantiate and pass a - * <code>TextOutputCallback</code> to the <code>handle</code> - * method of a <code>CallbackHandler</code> to display information messages, + * {@code TextOutputCallback} to the {@code handle} + * method of a {@code CallbackHandler} to display information messages, * warning messages and error messages. * * @see javax.security.auth.callback.CallbackHandler @@ -61,16 +61,16 @@ * * <p> * - * @param messageType the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). <p> + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). <p> * * @param message the message to be displayed. <p> * - * @exception IllegalArgumentException if <code>messageType</code> - * is not either <code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>, - * if <code>message</code> is null, - * or if <code>message</code> has a length of 0. + * @exception IllegalArgumentException if {@code messageType} + * is not either {@code INFORMATION}, + * {@code WARNING} or {@code ERROR}, + * if {@code message} is null, + * or if {@code message} has a length of 0. */ public TextOutputCallback(int messageType, String message) { if ((messageType != INFORMATION && @@ -87,8 +87,8 @@ * * <p> * - * @return the message type (<code>INFORMATION</code>, - * <code>WARNING</code> or <code>ERROR</code>). + * @return the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). */ public int getMessageType() { return messageType;
--- a/src/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -26,8 +26,8 @@ package javax.security.auth.callback; /** - * Signals that a <code>CallbackHandler</code> does not - * recognize a particular <code>Callback</code>. + * Signals that a {@code CallbackHandler} does not + * recognize a particular {@code Callback}. * */ public class UnsupportedCallbackException extends Exception { @@ -40,12 +40,12 @@ private Callback callback; /** - * Constructs a <code>UnsupportedCallbackException</code> + * Constructs a {@code UnsupportedCallbackException} * with no detail message. * * <p> * - * @param callback the unrecognized <code>Callback</code>. + * @param callback the unrecognized {@code Callback}. */ public UnsupportedCallbackException(Callback callback) { super(); @@ -59,7 +59,7 @@ * * <p> * - * @param callback the unrecognized <code>Callback</code>. <p> + * @param callback the unrecognized {@code Callback}. <p> * * @param msg the detail message. */ @@ -69,11 +69,11 @@ } /** - * Get the unrecognized <code>Callback</code>. + * Get the unrecognized {@code Callback}. * * <p> * - * @return the unrecognized <code>Callback</code>. + * @return the unrecognized {@code Callback}. */ public Callback getCallback() { return callback;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/auth/callback/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000, 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. 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. + */ + +/** + * This package provides the classes necessary for services + * to interact with applications in order to retrieve + * information (authentication data including usernames + * or passwords, for example) or to display information + * (error and warning messages, for example). + * + * @since JDK1.4 + */ +package javax.security.auth.callback;
--- a/src/share/classes/javax/security/auth/callback/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -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. 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. ---> - -</head> -<body bgcolor="white"> - - This package provides the classes necessary for services - to interact with applications in order to retrieve - information (authentication data including usernames - or passwords, for example) or to display information - (error and warning messages, for example). - -<!-- -<h2>Package Specification</h2> - -##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### -<ul> - <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> -</ul> - -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since JDK1.4 -</body> -</html>
--- a/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -38,7 +38,7 @@ * This class is used to restrict the usage of the Kerberos * delegation model, ie: forwardable and proxiable tickets. * <p> - * The target name of this <code>Permission</code> specifies a pair of + * The target name of this {@code Permission} specifies a pair of * kerberos service principals. The first is the subordinate service principal * being entrusted to use the TGT. The second service principal designates * the target service the subordinate service principal is to @@ -71,15 +71,15 @@ private transient String subordinate, service; /** - * Create a new <code>DelegationPermission</code> + * Create a new {@code DelegationPermission} * with the specified subordinate and target principals. * * <p> * * @param principals the name of the subordinate and target principals * - * @throws NullPointerException if <code>principals</code> is <code>null</code>. - * @throws IllegalArgumentException if <code>principals</code> is empty. + * @throws NullPointerException if {@code principals} is {@code null}. + * @throws IllegalArgumentException if {@code principals} is empty. */ public DelegationPermission(String principals) { super(principals); @@ -87,7 +87,7 @@ } /** - * Create a new <code>DelegationPermission</code> + * Create a new {@code DelegationPermission} * with the specified subordinate and target principals. * <p> * @@ -95,8 +95,8 @@ * <p> * @param actions should be null. * - * @throws NullPointerException if <code>principals</code> is <code>null</code>. - * @throws IllegalArgumentException if <code>principals</code> is empty. + * @throws NullPointerException if {@code principals} is {@code null}. + * @throws IllegalArgumentException if {@code principals} is empty. */ public DelegationPermission(String principals, String actions) { super(principals, actions); @@ -134,7 +134,7 @@ * Checks if this Kerberos delegation permission object "implies" the * specified permission. * <P> - * If none of the above are true, <code>implies</code> returns false. + * If none of the above are true, {@code implies} returns false. * @param p the permission to check against. * * @return true if the specified permission is implied by this object,
--- a/src/share/classes/javax/security/auth/kerberos/KerberosKey.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/KerberosKey.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -76,7 +76,7 @@ private int versionNum; /** - * <code>KeyImpl</code> is serialized by writing out the ASN1 Encoded bytes + * {@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes * of the encryption key. * The ASN1 encoding is defined in RFC4120 and as follows: * <pre> @@ -241,7 +241,7 @@ /** * Returns a hashcode for this KerberosKey. * - * @return a hashCode() for the <code>KerberosKey</code> + * @return a hashCode() for the {@code KerberosKey} * @since 1.6 */ public int hashCode() { @@ -260,8 +260,8 @@ /** * Compares the specified Object with this KerberosKey for equality. * Returns true if the given object is also a - * <code>KerberosKey</code> and the two - * <code>KerberosKey</code> instances are equivalent. + * {@code KerberosKey} and the two + * {@code KerberosKey} instances are equivalent. * * @param other the Object to compare to * @return true if the specified object is equal to this KerberosKey,
--- a/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -181,11 +181,11 @@ /** * Returns a hashcode for this principal. The hash code is defined to * be the result of the following calculation: - * <pre><code> + * <pre>{@code * hashCode = getName().hashCode(); - * </code></pre> + * }</pre> * - * @return a hashCode() for the <code>KerberosPrincipal</code> + * @return a hashCode() for the {@code KerberosPrincipal} */ public int hashCode() { return getName().hashCode(); @@ -194,11 +194,11 @@ /** * Compares the specified Object with this Principal for equality. * Returns true if the given object is also a - * <code>KerberosPrincipal</code> and the two - * <code>KerberosPrincipal</code> instances are equivalent. - * More formally two <code>KerberosPrincipal</code> instances are equal - * if the values returned by <code>getName()</code> are equal and the - * values returned by <code>getNameType()</code> are equal. + * {@code KerberosPrincipal} and the two + * {@code KerberosPrincipal} instances are equivalent. + * More formally two {@code KerberosPrincipal} instances are equal + * if the values returned by {@code getName()} are equal and the + * values returned by {@code getNameType()} are equal. * * @param other the Object to compare to * @return true if the Object passed in represents the same principal @@ -225,7 +225,7 @@ /** * Save the KerberosPrincipal object to a stream * - * @serialData this <code>KerberosPrincipal</code> is serialized + * @serialData this {@code KerberosPrincipal} is serialized * by writing out the PrincipalName and the * realm in their DER-encoded form as specified in Section 5.2.2 of * <a href=http://www.ietf.org/rfc/rfc4120.txt> RFC4120</a>.
--- a/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -103,7 +103,7 @@ private byte[] asn1Encoding; /** - *<code>KeyImpl</code> is serialized by writing out the ASN1 Encoded bytes + *{@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes * of the encryption key. The ASN1 encoding is defined in RFC4120 and as * follows: * <pre> @@ -667,7 +667,7 @@ /** * Returns a hashcode for this KerberosTicket. * - * @return a hashCode() for the <code>KerberosTicket</code> + * @return a hashCode() for the {@code KerberosTicket} * @since 1.6 */ public int hashCode() { @@ -704,8 +704,8 @@ /** * Compares the specified Object with this KerberosTicket for equality. * Returns true if the given object is also a - * <code>KerberosTicket</code> and the two - * <code>KerberosTicket</code> instances are equivalent. + * {@code KerberosTicket} and the two + * {@code KerberosTicket} instances are equivalent. * * @param other the Object to compare to * @return true if the specified object is equal to this KerberosTicket,
--- a/src/share/classes/javax/security/auth/kerberos/KeyImpl.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/KeyImpl.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -166,7 +166,7 @@ } /** - * @serialData this <code>KeyImpl</code> is serialized by + * @serialData this {@code KeyImpl} is serialized by * writing out the ASN1 Encoded bytes of the encryption key. * The ASN1 encoding is defined in RFC4120 and as follows: * EncryptionKey ::= SEQUENCE {
--- a/src/share/classes/javax/security/auth/kerberos/KeyTab.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/KeyTab.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -312,7 +312,7 @@ /** * Returns a hashcode for this KeyTab. * - * @return a hashCode() for the <code>KeyTab</code> + * @return a hashCode() for the {@code KeyTab} */ public int hashCode() { return Objects.hash(file, princ, bound); @@ -321,8 +321,8 @@ /** * Compares the specified Object with this KeyTab for equality. * Returns true if the given object is also a - * <code>KeyTab</code> and the two - * <code>KeyTab</code> instances are equivalent. + * {@code KeyTab} and the two + * {@code KeyTab} instances are equivalent. * * @param other the Object to compare to * @return true if the specified object is equal to this KeyTab
--- a/src/share/classes/javax/security/auth/kerberos/ServicePermission.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/kerberos/ServicePermission.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -50,7 +50,7 @@ * used within. * <p> * The service principal name is the canonical name of the - * <code>KereberosPrincipal</code> supplying the service, that is + * {@code KereberosPrincipal} supplying the service, that is * the KerberosPrincipal represents a Kerberos service * principal. This name is treated in a case sensitive manner. * An asterisk may appear by itself, to signify any service principal. @@ -135,9 +135,9 @@ // created and re-used in the getAction function. /** - * Create a new <code>ServicePermission</code> - * with the specified <code>servicePrincipal</code> - * and <code>action</code>. + * Create a new {@code ServicePermission} + * with the specified {@code servicePrincipal} + * and {@code action}. * * @param servicePrincipal the name of the service principal. * An asterisk may appear by itself, to signify any service principal. @@ -169,7 +169,7 @@ * Checks if this Kerberos service permission object "implies" the * specified permission. * <P> - * If none of the above are true, <code>implies</code> returns false. + * If none of the above are true, {@code implies} returns false. * @param p the permission to check against. * * @return true if the specified permission is implied by this object,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/auth/kerberos/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2001, 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. 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. + */ + +/** + * This package contains utility classes related to the Kerberos network + * authentication protocol. They do not provide much Kerberos support + * themselves.<p> + * + * The Kerberos network authentication protocol is defined in + * <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>. The Java + * platform contains support for the client side of Kerberos via the + * {@link org.ietf.jgss} package. There might also be + * a login module that implements + * {@link javax.security.auth.spi.LoginModule LoginModule} to authenticate + * Kerberos principals.<p> + * + * You can provide the name of your default realm and Key Distribution + * Center (KDC) host for that realm using the system properties + * {@code java.security.krb5.realm} and {@code java.security.krb5.kdc}. + * Both properties must be set. + * Alternatively, the {@code java.security.krb5.conf} system property can + * be set to the location of an MIT style {@code krb5.conf} configuration + * file. If none of these system properties are set, the {@code krb5.conf} + * file is searched for in an implementation-specific manner. Typically, + * an implementation will first look for a {@code krb5.conf} file in + * {@code <java-home>/lib/security} and failing that, in an OS-specific + * location.<p> + * + * @since JDK1.4 + */ +package javax.security.auth.kerberos;
--- a/src/share/classes/javax/security/auth/kerberos/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -Copyright (c) 2001, 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. 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. ---> - -</head> -<body bgcolor="white"> - - This package contains utility classes related to the Kerberos network - authentication protocol. They do not provide much Kerberos support - themselves.<p> - - The Kerberos network authentication protocol is defined in - <a href=http://www.ietf.org/rfc/rfc4120.txt>RFC 4120</a>. The Java - platform contains support for the client side of Kerberos via the - {@link org.ietf.jgss} package. There might also be - a login module that implements - {@link javax.security.auth.spi.LoginModule LoginModule} to authenticate - Kerberos principals.<p> - - You can provide the name of your default realm and Key Distribution - Center (KDC) host for that realm using the system properties - {@code java.security.krb5.realm} and {@code java.security.krb5.kdc}. - Both properties must be set. - Alternatively, the {@code java.security.krb5.conf} system property can - be set to the location of an MIT style {@code krb5.conf} configuration - file. If none of these system properties are set, the {@code krb5.conf} - file is searched for in an implementation-specific manner. Typically, - an implementation will first look for a {@code krb5.conf} file in - {@code <java-home>/lib/security} and failing that, in an OS-specific - location.<p> -<!-- -<h2>Package Specification</h2> - -##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### -<ul> - <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> -</ul> - -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since JDK1.4 -</body> -</html>
--- a/src/share/classes/javax/security/auth/login/AccountExpiredException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/AccountExpiredException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -29,9 +29,9 @@ * Signals that a user account has expired. * * <p> This exception is thrown by LoginModules when they determine - * that an account has expired. For example, a <code>LoginModule</code>, + * that an account has expired. For example, a {@code LoginModule}, * after successfully authenticating a user, may determine that the - * user's account has expired. In this case the <code>LoginModule</code> + * user's account has expired. In this case the {@code LoginModule} * throws this exception to notify the application. The application can * then take the appropriate steps to notify the user. *
--- a/src/share/classes/javax/security/auth/login/AppConfigurationEntry.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/AppConfigurationEntry.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -29,14 +29,14 @@ import java.util.Collections; /** - * This class represents a single <code>LoginModule</code> entry + * This class represents a single {@code LoginModule} entry * configured for the application specified in the - * <code>getAppConfigurationEntry(String appName)</code> - * method in the <code>Configuration</code> class. Each respective - * <code>AppConfigurationEntry</code> contains a <code>LoginModule</code> name, - * a control flag (specifying whether this <code>LoginModule</code> is + * {@code getAppConfigurationEntry(String appName)} + * method in the {@code Configuration} class. Each respective + * {@code AppConfigurationEntry} contains a {@code LoginModule} name, + * a control flag (specifying whether this {@code LoginModule} is * REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL), and LoginModule-specific - * options. Please refer to the <code>Configuration</code> class for + * options. Please refer to the {@code Configuration} class for * more information on the different control flags and their semantics. * * @see javax.security.auth.login.Configuration @@ -50,25 +50,25 @@ /** * Default constructor for this class. * - * <p> This entry represents a single <code>LoginModule</code> + * <p> This entry represents a single {@code LoginModule} * entry configured for the application specified in the - * <code>getAppConfigurationEntry(String appName)</code> - * method from the <code>Configuration</code> class. + * {@code getAppConfigurationEntry(String appName)} + * method from the {@code Configuration} class. * * @param loginModuleName String representing the class name of the - * <code>LoginModule</code> configured for the + * {@code LoginModule} configured for the * specified application. <p> * * @param controlFlag either REQUIRED, REQUISITE, SUFFICIENT, * or OPTIONAL. <p> * - * @param options the options configured for this <code>LoginModule</code>. + * @param options the options configured for this {@code LoginModule}. * - * @exception IllegalArgumentException if <code>loginModuleName</code> - * is null, if <code>LoginModuleName</code> - * has a length of 0, if <code>controlFlag</code> + * @exception IllegalArgumentException if {@code loginModuleName} + * is null, if {@code LoginModuleName} + * has a length of 0, if {@code controlFlag} * is not either REQUIRED, REQUISITE, SUFFICIENT - * or OPTIONAL, or if <code>options</code> is null. + * or OPTIONAL, or if {@code options} is null. */ public AppConfigurationEntry(String loginModuleName, LoginModuleControlFlag controlFlag, @@ -88,9 +88,9 @@ } /** - * Get the class name of the configured <code>LoginModule</code>. + * Get the class name of the configured {@code LoginModule}. * - * @return the class name of the configured <code>LoginModule</code> as + * @return the class name of the configured {@code LoginModule} as * a String. */ public String getLoginModuleName() { @@ -100,28 +100,28 @@ /** * Return the controlFlag * (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL) - * for this <code>LoginModule</code>. + * for this {@code LoginModule}. * * @return the controlFlag * (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL) - * for this <code>LoginModule</code>. + * for this {@code LoginModule}. */ public LoginModuleControlFlag getControlFlag() { return controlFlag; } /** - * Get the options configured for this <code>LoginModule</code>. + * Get the options configured for this {@code LoginModule}. * - * @return the options configured for this <code>LoginModule</code> - * as an unmodifiable <code>Map</code>. + * @return the options configured for this {@code LoginModule} + * as an unmodifiable {@code Map}. */ public Map<String,?> getOptions() { return options; } /** - * This class represents whether or not a <code>LoginModule</code> + * This class represents whether or not a {@code LoginModule} * is REQUIRED, REQUISITE, SUFFICIENT or OPTIONAL. */ public static class LoginModuleControlFlag { @@ -129,25 +129,25 @@ private String controlFlag; /** - * Required <code>LoginModule</code>. + * Required {@code LoginModule}. */ public static final LoginModuleControlFlag REQUIRED = new LoginModuleControlFlag("required"); /** - * Requisite <code>LoginModule</code>. + * Requisite {@code LoginModule}. */ public static final LoginModuleControlFlag REQUISITE = new LoginModuleControlFlag("requisite"); /** - * Sufficient <code>LoginModule</code>. + * Sufficient {@code LoginModule}. */ public static final LoginModuleControlFlag SUFFICIENT = new LoginModuleControlFlag("sufficient"); /** - * Optional <code>LoginModule</code>. + * Optional {@code LoginModule}. */ public static final LoginModuleControlFlag OPTIONAL = new LoginModuleControlFlag("optional");
--- a/src/share/classes/javax/security/auth/login/Configuration.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/Configuration.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -49,9 +49,9 @@ * * <p> A login configuration contains the following information. * Note that this example only represents the default syntax for the - * <code>Configuration</code>. Subclass implementations of this class + * {@code Configuration}. Subclass implementations of this class * may implement alternative syntaxes and may retrieve the - * <code>Configuration</code> from any source such as files, databases, + * {@code Configuration} from any source such as files, databases, * or servers. * * <pre> @@ -70,9 +70,9 @@ * }; * </pre> * - * <p> Each entry in the <code>Configuration</code> is indexed via an + * <p> Each entry in the {@code Configuration} is indexed via an * application name, <i>Name</i>, and contains a list of - * LoginModules configured for that application. Each <code>LoginModule</code> + * LoginModules configured for that application. Each {@code LoginModule} * is specified via its fully qualified class name. * Authentication proceeds down the module list in the exact order specified. * If an application does not have specific entry, @@ -83,55 +83,55 @@ * valid values for <i>Flag</i> and their respective semantics: * * <pre> - * 1) Required - The <code>LoginModule</code> is required to succeed. + * 1) Required - The {@code LoginModule} is required to succeed. * If it succeeds or fails, authentication still continues - * to proceed down the <code>LoginModule</code> list. + * to proceed down the {@code LoginModule} list. * - * 2) Requisite - The <code>LoginModule</code> is required to succeed. + * 2) Requisite - The {@code LoginModule} is required to succeed. * If it succeeds, authentication continues down the - * <code>LoginModule</code> list. If it fails, + * {@code LoginModule} list. If it fails, * control immediately returns to the application * (authentication does not proceed down the - * <code>LoginModule</code> list). + * {@code LoginModule} list). * - * 3) Sufficient - The <code>LoginModule</code> is not required to + * 3) Sufficient - The {@code LoginModule} is not required to * succeed. If it does succeed, control immediately * returns to the application (authentication does not - * proceed down the <code>LoginModule</code> list). + * proceed down the {@code LoginModule} list). * If it fails, authentication continues down the - * <code>LoginModule</code> list. + * {@code LoginModule} list. * - * 4) Optional - The <code>LoginModule</code> is not required to + * 4) Optional - The {@code LoginModule} is not required to * succeed. If it succeeds or fails, * authentication still continues to proceed down the - * <code>LoginModule</code> list. + * {@code LoginModule} list. * </pre> * * <p> The overall authentication succeeds only if all <i>Required</i> and * <i>Requisite</i> LoginModules succeed. If a <i>Sufficient</i> - * <code>LoginModule</code> is configured and succeeds, + * {@code LoginModule} is configured and succeeds, * then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to - * that <i>Sufficient</i> <code>LoginModule</code> need to have succeeded for + * that <i>Sufficient</i> {@code LoginModule} need to have succeeded for * the overall authentication to succeed. If no <i>Required</i> or * <i>Requisite</i> LoginModules are configured for an application, * then at least one <i>Sufficient</i> or <i>Optional</i> - * <code>LoginModule</code> must succeed. + * {@code LoginModule} must succeed. * * <p> <i>ModuleOptions</i> is a space separated list of - * <code>LoginModule</code>-specific values which are passed directly to + * {@code LoginModule}-specific values which are passed directly to * the underlying LoginModules. Options are defined by the - * <code>LoginModule</code> itself, and control the behavior within it. - * For example, a <code>LoginModule</code> may define options to support + * {@code LoginModule} itself, and control the behavior within it. + * For example, a {@code LoginModule} may define options to support * debugging/testing capabilities. The correct way to specify options in the - * <code>Configuration</code> is by using the following key-value pairing: + * {@code Configuration} is by using the following key-value pairing: * <i>debug="true"</i>. The key and value should be separated by an * 'equals' symbol, and the value should be surrounded by double quotes. * If a String in the form, ${system.property}, occurs in the value, * it will be expanded to the value of the system property. * Note that there is no limit to the number of - * options a <code>LoginModule</code> may define. + * options a {@code LoginModule} may define. * - * <p> The following represents an example <code>Configuration</code> entry + * <p> The following represents an example {@code Configuration} entry * based on the syntax above: * * <pre> @@ -143,7 +143,7 @@ * }; * </pre> * - * <p> This <code>Configuration</code> specifies that an application named, + * <p> This {@code Configuration} specifies that an application named, * "Login", requires users to first authenticate to the * <i>com.sun.security.auth.module.UnixLoginModule</i>, which is * required to succeed. Even if the <i>UnixLoginModule</i> @@ -165,11 +165,11 @@ * * <p> There is only one Configuration object installed in the runtime at any * given time. A Configuration object can be installed by calling the - * <code>setConfiguration</code> method. The installed Configuration object - * can be obtained by calling the <code>getConfiguration</code> method. + * {@code setConfiguration} method. The installed Configuration object + * can be obtained by calling the {@code getConfiguration} method. * * <p> If no Configuration object has been installed in the runtime, a call to - * <code>getConfiguration</code> installs an instance of the default + * {@code getConfiguration} installs an instance of the default * Configuration implementation (a default subclass implementation of this * abstract class). * The default Configuration implementation can be changed by setting the value @@ -178,7 +178,7 @@ * * <p> Application code can directly subclass Configuration to provide a custom * implementation. In addition, an instance of a Configuration object can be - * constructed by invoking one of the <code>getInstance</code> factory methods + * constructed by invoking one of the {@code getInstance} factory methods * with a standard type. The default policy type is "JavaLoginConfig". * See the Configuration section in the <a href= * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration"> @@ -222,7 +222,7 @@ * <p> * * @return the login Configuration. If a Configuration object was set - * via the <code>Configuration.setConfiguration</code> method, + * via the {@code Configuration.setConfiguration} method, * then that object is returned. Otherwise, a default * Configuration object is returned. * @@ -286,14 +286,14 @@ } /** - * Set the login <code>Configuration</code>. + * Set the login {@code Configuration}. * * <p> * - * @param configuration the new <code>Configuration</code> + * @param configuration the new {@code Configuration} * * @exception SecurityException if the current thread does not have - * Permission to set the <code>Configuration</code>. + * Permission to set the {@code Configuration}. * * @see #getConfiguration */ @@ -505,7 +505,7 @@ * Return the Provider of this Configuration. * * <p> This Configuration instance will only have a Provider if it - * was obtained via a call to <code>Configuration.getInstance</code>. + * was obtained via a call to {@code Configuration.getInstance}. * Otherwise this method returns null. * * @return the Provider of this Configuration, or null. @@ -520,7 +520,7 @@ * Return the type of this Configuration. * * <p> This Configuration instance will only have a type if it - * was obtained via a call to <code>Configuration.getInstance</code>. + * was obtained via a call to {@code Configuration.getInstance}. * Otherwise this method returns null. * * @return the type of this Configuration, or null. @@ -535,7 +535,7 @@ * Return Configuration parameters. * * <p> This Configuration instance will only have parameters if it - * was obtained via a call to <code>Configuration.getInstance</code>. + * was obtained via a call to {@code Configuration.getInstance}. * Otherwise this method returns null. * * @return Configuration parameters, or null. @@ -567,7 +567,7 @@ * <p> This method causes this Configuration object to refresh/reload its * contents in an implementation-dependent manner. * For example, if this Configuration object stores its entries in a file, - * calling <code>refresh</code> may cause the file to be re-read. + * calling {@code refresh} may cause the file to be re-read. * * <p> The default implementation of this method does nothing. * This method should be overridden if a refresh operation is supported
--- a/src/share/classes/javax/security/auth/login/ConfigurationSpi.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/ConfigurationSpi.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -28,15 +28,15 @@ /** * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) - * for the <code>Configuration</code> class. + * for the {@code Configuration} class. * All the abstract methods in this class must be implemented by each * service provider who wishes to supply a Configuration implementation. * * <p> Subclass implementations of this abstract class must provide - * a public constructor that takes a <code>Configuration.Parameters</code> + * a public constructor that takes a {@code Configuration.Parameters} * object as an input parameter. This constructor also must throw * an IllegalArgumentException if it does not understand the - * <code>Configuration.Parameters</code> input. + * {@code Configuration.Parameters} input. * * * @since 1.6 @@ -62,7 +62,7 @@ * <p> This method causes this Configuration object to refresh/reload its * contents in an implementation-dependent manner. * For example, if this Configuration object stores its entries in a file, - * calling <code>refresh</code> may cause the file to be re-read. + * calling {@code refresh} may cause the file to be re-read. * * <p> The default implementation of this method does nothing. * This method should be overridden if a refresh operation is supported
--- a/src/share/classes/javax/security/auth/login/CredentialExpiredException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/CredentialExpiredException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -26,14 +26,14 @@ package javax.security.auth.login; /** - * Signals that a <code>Credential</code> has expired. + * Signals that a {@code Credential} has expired. * * <p> This exception is thrown by LoginModules when they determine - * that a <code>Credential</code> has expired. - * For example, a <code>LoginModule</code> authenticating a user - * in its <code>login</code> method may determine that the user's + * that a {@code Credential} has expired. + * For example, a {@code LoginModule} authenticating a user + * in its {@code login} method may determine that the user's * password, although entered correctly, has expired. In this case - * the <code>LoginModule</code> throws this exception to notify + * the {@code LoginModule} throws this exception to notify * the application. The application can then take the appropriate * steps to assist the user in updating the password. *
--- a/src/share/classes/javax/security/auth/login/FailedLoginException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/FailedLoginException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -29,7 +29,7 @@ * Signals that user authentication failed. * * <p> This exception is thrown by LoginModules if authentication failed. - * For example, a <code>LoginModule</code> throws this exception if + * For example, a {@code LoginModule} throws this exception if * the user entered an incorrect password. * */
--- a/src/share/classes/javax/security/auth/login/LoginContext.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/login/LoginContext.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -41,11 +41,11 @@ import sun.security.util.ResourcesMgr; /** - * <p> The <code>LoginContext</code> class describes the basic methods used + * <p> The {@code LoginContext} class describes the basic methods used * to authenticate Subjects and provides a way to develop an * application independent of the underlying authentication technology. - * A <code>Configuration</code> specifies the authentication technology, or - * <code>LoginModule</code>, to be used with a particular application. + * A {@code Configuration} specifies the authentication technology, or + * {@code LoginModule}, to be used with a particular application. * Different LoginModules can be plugged in under an application * without requiring any modifications to the application itself. * @@ -57,36 +57,36 @@ * LoginModule under an application. * * <p> A typical caller instantiates a LoginContext with - * a <i>name</i> and a <code>CallbackHandler</code>. + * a <i>name</i> and a {@code CallbackHandler}. * LoginContext uses the <i>name</i> as the index into a * Configuration to determine which LoginModules should be used, * and which ones must succeed in order for the overall authentication to - * succeed. The <code>CallbackHandler</code> is passed to the underlying + * succeed. The {@code CallbackHandler} is passed to the underlying * LoginModules so they may communicate and interact with users * (prompting for a username and password via a graphical user interface, * for example). * * <p> Once the caller has instantiated a LoginContext, - * it invokes the <code>login</code> method to authenticate - * a <code>Subject</code>. The <code>login</code> method invokes + * it invokes the {@code login} method to authenticate + * a {@code Subject}. The {@code login} method invokes * the configured modules to perform their respective types of authentication * (username/password, smart card pin verification, etc.). * Note that the LoginModules will not attempt authentication retries nor * introduce delays if the authentication fails. * Such tasks belong to the LoginContext caller. * - * <p> If the <code>login</code> method returns without + * <p> If the {@code login} method returns without * throwing an exception, then the overall authentication succeeded. * The caller can then retrieve * the newly authenticated Subject by invoking the - * <code>getSubject</code> method. Principals and Credentials associated + * {@code getSubject} method. Principals and Credentials associated * with the Subject may be retrieved by invoking the Subject's - * respective <code>getPrincipals</code>, <code>getPublicCredentials</code>, - * and <code>getPrivateCredentials</code> methods. + * respective {@code getPrincipals}, {@code getPublicCredentials}, + * and {@code getPrivateCredentials} methods. * * <p> To logout the Subject, the caller calls - * the <code>logout</code> method. As with the <code>login</code> - * method, this <code>logout</code> method invokes the <code>logout</code> + * the {@code logout} method. As with the {@code login} + * method, this {@code logout} method invokes the {@code logout} * method for the configured modules. * * <p> A LoginContext should not be used to authenticate @@ -96,14 +96,14 @@ * <p> The following documentation applies to all LoginContext constructors: * <ol> * - * <li> <code>Subject</code> + * <li> {@code Subject} * <ul> * <li> If the constructor has a Subject * input parameter, the LoginContext uses the caller-specified * Subject object. * <p> - * <li> If the caller specifies a <code>null</code> Subject - * and a <code>null</code> value is permitted, + * <li> If the caller specifies a {@code null} Subject + * and a {@code null} value is permitted, * the LoginContext instantiates a new Subject. * <p> * <li> If the constructor does <b>not</b> have a Subject @@ -111,14 +111,14 @@ * <p> * </ul> * - * <li> <code>Configuration</code> + * <li> {@code Configuration} * <ul> * <li> If the constructor has a Configuration * input parameter and the caller specifies a non-null Configuration, * the LoginContext uses the caller-specified Configuration. * <p> * If the constructor does <b>not</b> have a Configuration - * input parameter, or if the caller specifies a <code>null</code> + * input parameter, or if the caller specifies a {@code null} * Configuration object, the constructor uses the following call to * get the installed Configuration: * <pre> @@ -126,42 +126,42 @@ * </pre> * For both cases, * the <i>name</i> argument given to the constructor is passed to the - * <code>Configuration.getAppConfigurationEntry</code> method. + * {@code Configuration.getAppConfigurationEntry} method. * If the Configuration has no entries for the specified <i>name</i>, - * then the <code>LoginContext</code> calls - * <code>getAppConfigurationEntry</code> with the name, "<i>other</i>" + * then the {@code LoginContext} calls + * {@code getAppConfigurationEntry} with the name, "<i>other</i>" * (the default entry name). If there is no entry for "<i>other</i>", - * then a <code>LoginException</code> is thrown. + * then a {@code LoginException} is thrown. * <p> * <li> When LoginContext uses the installed Configuration, the caller * requires the createLoginContext.<em>name</em> and possibly * createLoginContext.other AuthPermissions. Furthermore, the * LoginContext will invoke configured modules from within an - * <code>AccessController.doPrivileged</code> call so that modules that + * {@code AccessController.doPrivileged} call so that modules that * perform security-sensitive tasks (such as connecting to remote hosts, * and updating the Subject) will require the respective permissions, but * the callers of the LoginContext will not require those permissions. * <p> * <li> When LoginContext uses a caller-specified Configuration, the caller * does not require any createLoginContext AuthPermission. The LoginContext - * saves the <code>AccessControlContext</code> for the caller, + * saves the {@code AccessControlContext} for the caller, * and invokes the configured modules from within an - * <tt>AccessController.doPrivileged</tt> call constrained by that context. + * {@code AccessController.doPrivileged} call constrained by that context. * This means the caller context (stored when the LoginContext was created) * must have sufficient permissions to perform any security-sensitive tasks * that the modules may perform. * <p> * </ul> * - * <li> <code>CallbackHandler</code> + * <li> {@code CallbackHandler} * <ul> * <li> If the constructor has a CallbackHandler * input parameter, the LoginContext uses the caller-specified * CallbackHandler object. * <p> * <li> If the constructor does <b>not</b> have a CallbackHandler - * input parameter, or if the caller specifies a <code>null</code> - * CallbackHandler object (and a <code>null</code> value is permitted), + * input parameter, or if the caller specifies a {@code null} + * CallbackHandler object (and a {@code null} value is permitted), * the LoginContext queries the * {@code auth.login.defaultCallbackHandler} security property for the * fully qualified class name of a default handler @@ -177,10 +177,10 @@ * then this LoginContext must wrap any * caller-specified or default CallbackHandler implementation * in a new CallbackHandler implementation - * whose <code>handle</code> method implementation invokes the - * specified CallbackHandler's <code>handle</code> method in a - * <code>java.security.AccessController.doPrivileged</code> call - * constrained by the caller's current <code>AccessControlContext</code>. + * whose {@code handle} method implementation invokes the + * specified CallbackHandler's {@code handle} method in a + * {@code java.security.AccessController.doPrivileged} call + * constrained by the caller's current {@code AccessControlContext}. * </ul> * </ol> * @@ -317,14 +317,14 @@ } /** - * Instantiate a new <code>LoginContext</code> object with a name. + * Instantiate a new {@code LoginContext} object with a name. * * @param name the name used as the index into the - * <code>Configuration</code>. + * {@code Configuration}. * - * @exception LoginException if the caller-specified <code>name</code> - * does not appear in the <code>Configuration</code> - * and there is no <code>Configuration</code> entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "<i>other</i>", or if the * <i>auth.login.defaultCallbackHandler</i> * security property was set, but the implementation @@ -343,21 +343,21 @@ } /** - * Instantiate a new <code>LoginContext</code> object with a name - * and a <code>Subject</code> object. + * Instantiate a new {@code LoginContext} object with a name + * and a {@code Subject} object. * * <p> * * @param name the name used as the index into the - * <code>Configuration</code>. <p> + * {@code Configuration}. <p> * - * @param subject the <code>Subject</code> to authenticate. + * @param subject the {@code Subject} to authenticate. * - * @exception LoginException if the caller-specified <code>name</code> - * does not appear in the <code>Configuration</code> - * and there is no <code>Configuration</code> entry - * for "<i>other</i>", if the caller-specified <code>subject</code> - * is <code>null</code>, or if the + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry + * for "<i>other</i>", if the caller-specified {@code subject} + * is {@code null}, or if the * <i>auth.login.defaultCallbackHandler</i> * security property was set, but the implementation * class could not be loaded. @@ -381,22 +381,22 @@ } /** - * Instantiate a new <code>LoginContext</code> object with a name - * and a <code>CallbackHandler</code> object. + * Instantiate a new {@code LoginContext} object with a name + * and a {@code CallbackHandler} object. * * <p> * * @param name the name used as the index into the - * <code>Configuration</code>. <p> + * {@code Configuration}. <p> * - * @param callbackHandler the <code>CallbackHandler</code> object used by + * @param callbackHandler the {@code CallbackHandler} object used by * LoginModules to communicate with the user. * - * @exception LoginException if the caller-specified <code>name</code> - * does not appear in the <code>Configuration</code> - * and there is no <code>Configuration</code> entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "<i>other</i>", or if the caller-specified - * <code>callbackHandler</code> is <code>null</code>. + * {@code callbackHandler} is {@code null}. * <p> * @exception SecurityException if a SecurityManager is set and * the caller does not have @@ -417,27 +417,27 @@ } /** - * Instantiate a new <code>LoginContext</code> object with a name, - * a <code>Subject</code> to be authenticated, and a - * <code>CallbackHandler</code> object. + * Instantiate a new {@code LoginContext} object with a name, + * a {@code Subject} to be authenticated, and a + * {@code CallbackHandler} object. * * <p> * * @param name the name used as the index into the - * <code>Configuration</code>. <p> + * {@code Configuration}. <p> * - * @param subject the <code>Subject</code> to authenticate. <p> + * @param subject the {@code Subject} to authenticate. <p> * - * @param callbackHandler the <code>CallbackHandler</code> object used by + * @param callbackHandler the {@code CallbackHandler} object used by * LoginModules to communicate with the user. * - * @exception LoginException if the caller-specified <code>name</code> - * does not appear in the <code>Configuration</code> - * and there is no <code>Configuration</code> entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "<i>other</i>", or if the caller-specified - * <code>subject</code> is <code>null</code>, + * {@code subject} is {@code null}, * or if the caller-specified - * <code>callbackHandler</code> is <code>null</code>. + * {@code callbackHandler} is {@code null}. * <p> * @exception SecurityException if a SecurityManager is set and * the caller does not have @@ -458,34 +458,34 @@ } /** - * Instantiate a new <code>LoginContext</code> object with a name, - * a <code>Subject</code> to be authenticated, - * a <code>CallbackHandler</code> object, and a login - * <code>Configuration</code>. + * Instantiate a new {@code LoginContext} object with a name, + * a {@code Subject} to be authenticated, + * a {@code CallbackHandler} object, and a login + * {@code Configuration}. * * <p> * * @param name the name used as the index into the caller-specified - * <code>Configuration</code>. <p> + * {@code Configuration}. <p> * - * @param subject the <code>Subject</code> to authenticate, - * or <code>null</code>. <p> + * @param subject the {@code Subject} to authenticate, + * or {@code null}. <p> * - * @param callbackHandler the <code>CallbackHandler</code> object used by - * LoginModules to communicate with the user, or <code>null</code>. + * @param callbackHandler the {@code CallbackHandler} object used by + * LoginModules to communicate with the user, or {@code null}. * <p> * - * @param config the <code>Configuration</code> that lists the + * @param config the {@code Configuration} that lists the * login modules to be called to perform the authentication, - * or <code>null</code>. + * or {@code null}. * - * @exception LoginException if the caller-specified <code>name</code> - * does not appear in the <code>Configuration</code> - * and there is no <code>Configuration</code> entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "<i>other</i>". * <p> * @exception SecurityException if a SecurityManager is set, - * <i>config</i> is <code>null</code>, + * <i>config</i> is {@code null}, * and either the caller does not have * AuthPermission("createLoginContext.<i>name</i>"), * or if a configuration entry for <i>name</i> does not exist and @@ -522,46 +522,46 @@ /** * Perform the authentication. * - * <p> This method invokes the <code>login</code> method for each + * <p> This method invokes the {@code login} method for each * LoginModule configured for the <i>name</i> specified to the - * <code>LoginContext</code> constructor, as determined by the login - * <code>Configuration</code>. Each <code>LoginModule</code> + * {@code LoginContext} constructor, as determined by the login + * {@code Configuration}. Each {@code LoginModule} * then performs its respective type of authentication * (username/password, smart card pin verification, etc.). * * <p> This method completes a 2-phase authentication process by - * calling each configured LoginModule's <code>commit</code> method + * calling each configured LoginModule's {@code commit} method * if the overall authentication succeeded (the relevant REQUIRED, * REQUISITE, SUFFICIENT, and OPTIONAL LoginModules succeeded), - * or by calling each configured LoginModule's <code>abort</code> method + * or by calling each configured LoginModule's {@code abort} method * if the overall authentication failed. If authentication succeeded, - * each successful LoginModule's <code>commit</code> method associates - * the relevant Principals and Credentials with the <code>Subject</code>. - * If authentication failed, each LoginModule's <code>abort</code> method + * each successful LoginModule's {@code commit} method associates + * the relevant Principals and Credentials with the {@code Subject}. + * If authentication failed, each LoginModule's {@code abort} method * removes/destroys any previously stored state. * - * <p> If the <code>commit</code> phase of the authentication process + * <p> If the {@code commit} phase of the authentication process * fails, then the overall authentication fails and this method - * invokes the <code>abort</code> method for each configured - * <code>LoginModule</code>. + * invokes the {@code abort} method for each configured + * {@code LoginModule}. * - * <p> If the <code>abort</code> phase + * <p> If the {@code abort} phase * fails for any reason, then this method propagates the - * original exception thrown either during the <code>login</code> phase - * or the <code>commit</code> phase. In either case, the overall + * original exception thrown either during the {@code login} phase + * or the {@code commit} phase. In either case, the overall * authentication fails. * * <p> In the case where multiple LoginModules fail, * this method propagates the exception raised by the first - * <code>LoginModule</code> which failed. + * {@code LoginModule} which failed. * - * <p> Note that if this method enters the <code>abort</code> phase - * (either the <code>login</code> or <code>commit</code> phase failed), + * <p> Note that if this method enters the {@code abort} phase + * (either the {@code login} or {@code commit} phase failed), * this method invokes all LoginModules configured for the - * application regardless of their respective <code>Configuration</code> - * flag parameters. Essentially this means that <code>Requisite</code> - * and <code>Sufficient</code> semantics are ignored during the - * <code>abort</code> phase. This guarantees that proper cleanup + * application regardless of their respective {@code Configuration} + * flag parameters. Essentially this means that {@code Requisite} + * and {@code Sufficient} semantics are ignored during the + * {@code abort} phase. This guarantees that proper cleanup * and state restoration can take place. * * <p> @@ -602,19 +602,19 @@ } /** - * Logout the <code>Subject</code>. + * Logout the {@code Subject}. * - * <p> This method invokes the <code>logout</code> method for each - * <code>LoginModule</code> configured for this <code>LoginContext</code>. - * Each <code>LoginModule</code> performs its respective logout procedure + * <p> This method invokes the {@code logout} method for each + * {@code LoginModule} configured for this {@code LoginContext}. + * Each {@code LoginModule} performs its respective logout procedure * which may include removing/destroying - * <code>Principal</code> and <code>Credential</code> information - * from the <code>Subject</code> and state cleanup. + * {@code Principal} and {@code Credential} information + * from the {@code Subject} and state cleanup. * * <p> Note that this method invokes all LoginModules configured for the * application regardless of their respective - * <code>Configuration</code> flag parameters. Essentially this means - * that <code>Requisite</code> and <code>Sufficient</code> semantics are + * {@code Configuration} flag parameters. Essentially this means + * that {@code Requisite} and {@code Sufficient} semantics are * ignored for this method. This guarantees that proper cleanup * and state restoration can take place. *
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/auth/login/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000, 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. 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. + */ + +/** + * This package provides a pluggable authentication framework. + * <h2>Package Specification</h2> + * + * <ul> + * <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html"> + * <b>Java™ + * Cryptography Architecture Standard Algorithm Name + * Documentation</b></a></li> + * </ul> + * + * @since 1.4 + */ +package javax.security.auth.login;
--- a/src/share/classes/javax/security/auth/login/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -Copyright (c) 2000, 2011, 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. ---> - -</head> -<body bgcolor="white"> - - This package provides a pluggable authentication framework. -<h2>Package Specification</h2> - -<ul> - <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html"> - <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT> - Cryptography Architecture Standard Algorithm Name - Documentation</b></a></li> -</ul> - -<!-- -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since 1.4 -</body> -</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/auth/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000, 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. 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. + */ + +/** + * This package provides a framework for authentication and + * authorization. The framework allows + * authentication to be performed in pluggable fashion. Different + * authentication modules can be plugged under an application without + * requiring modifications to the application itself. The + * authorization component allows specification of access controls + * based on code location, code signers and code executors + * (Subjects). + * + * @since JDK1.4 + */ +package javax.security.auth;
--- a/src/share/classes/javax/security/auth/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -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. 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. ---> - -</head> -<body bgcolor="white"> - - This package provides a framework for authentication and - authorization. The framework allows - authentication to be performed in pluggable fashion. Different - authentication modules can be plugged under an application without - requiring modifications to the application itself. The - authorization component allows specification of access controls - based on code location, code signers and code executors - (Subjects). - - -<!-- -<h2>Package Specification</h2> - -##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### -<ul> - <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> -</ul> - -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since JDK1.4 -</body> -</html>
--- a/src/share/classes/javax/security/auth/spi/LoginModule.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/spi/LoginModule.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -32,95 +32,95 @@ import java.util.Map; /** - * <p> <code>LoginModule</code> describes the interface + * <p> {@code LoginModule} describes the interface * implemented by authentication technology providers. LoginModules * are plugged in under applications to provide a particular type of * authentication. * - * <p> While applications write to the <code>LoginContext</code> API, + * <p> While applications write to the {@code LoginContext} API, * authentication technology providers implement the - * <code>LoginModule</code> interface. - * A <code>Configuration</code> specifies the LoginModule(s) + * {@code LoginModule} interface. + * A {@code Configuration} specifies the LoginModule(s) * to be used with a particular login application. Therefore different * LoginModules can be plugged in under the application without * requiring any modifications to the application itself. * - * <p> The <code>LoginContext</code> is responsible for reading the - * <code>Configuration</code> and instantiating the appropriate - * LoginModules. Each <code>LoginModule</code> is initialized with - * a <code>Subject</code>, a <code>CallbackHandler</code>, shared - * <code>LoginModule</code> state, and LoginModule-specific options. + * <p> The {@code LoginContext} is responsible for reading the + * {@code Configuration} and instantiating the appropriate + * LoginModules. Each {@code LoginModule} is initialized with + * a {@code Subject}, a {@code CallbackHandler}, shared + * {@code LoginModule} state, and LoginModule-specific options. * - * The <code>Subject</code> represents the - * <code>Subject</code> currently being authenticated and is updated + * The {@code Subject} represents the + * {@code Subject} currently being authenticated and is updated * with relevant Credentials if authentication succeeds. - * LoginModules use the <code>CallbackHandler</code> to - * communicate with users. The <code>CallbackHandler</code> may be + * LoginModules use the {@code CallbackHandler} to + * communicate with users. The {@code CallbackHandler} may be * used to prompt for usernames and passwords, for example. - * Note that the <code>CallbackHandler</code> may be null. LoginModules - * which absolutely require a <code>CallbackHandler</code> to authenticate - * the <code>Subject</code> may throw a <code>LoginException</code>. + * Note that the {@code CallbackHandler} may be null. LoginModules + * which absolutely require a {@code CallbackHandler} to authenticate + * the {@code Subject} may throw a {@code LoginException}. * LoginModules optionally use the shared state to share information * or data among themselves. * * <p> The LoginModule-specific options represent the options - * configured for this <code>LoginModule</code> by an administrator or user - * in the login <code>Configuration</code>. - * The options are defined by the <code>LoginModule</code> itself + * configured for this {@code LoginModule} by an administrator or user + * in the login {@code Configuration}. + * The options are defined by the {@code LoginModule} itself * and control the behavior within it. For example, a - * <code>LoginModule</code> may define options to support debugging/testing + * {@code LoginModule} may define options to support debugging/testing * capabilities. Options are defined using a key-value syntax, - * such as <i>debug=true</i>. The <code>LoginModule</code> - * stores the options as a <code>Map</code> so that the values may + * such as <i>debug=true</i>. The {@code LoginModule} + * stores the options as a {@code Map} so that the values may * be retrieved using the key. Note that there is no limit to the number - * of options a <code>LoginModule</code> chooses to define. + * of options a {@code LoginModule} chooses to define. * * <p> The calling application sees the authentication process as a single * operation. However, the authentication process within the - * <code>LoginModule</code> proceeds in two distinct phases. + * {@code LoginModule} proceeds in two distinct phases. * In the first phase, the LoginModule's - * <code>login</code> method gets invoked by the LoginContext's - * <code>login</code> method. The <code>login</code> - * method for the <code>LoginModule</code> then performs + * {@code login} method gets invoked by the LoginContext's + * {@code login} method. The {@code login} + * method for the {@code LoginModule} then performs * the actual authentication (prompt for and verify a password for example) * and saves its authentication status as private state - * information. Once finished, the LoginModule's <code>login</code> - * method either returns <code>true</code> (if it succeeded) or - * <code>false</code> (if it should be ignored), or throws a - * <code>LoginException</code> to specify a failure. - * In the failure case, the <code>LoginModule</code> must not retry the + * information. Once finished, the LoginModule's {@code login} + * method either returns {@code true} (if it succeeded) or + * {@code false} (if it should be ignored), or throws a + * {@code LoginException} to specify a failure. + * In the failure case, the {@code LoginModule} must not retry the * authentication or introduce delays. The responsibility of such tasks * belongs to the application. If the application attempts to retry - * the authentication, the LoginModule's <code>login</code> method will be + * the authentication, the LoginModule's {@code login} method will be * called again. * * <p> In the second phase, if the LoginContext's overall authentication * succeeded (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL - * LoginModules succeeded), then the <code>commit</code> - * method for the <code>LoginModule</code> gets invoked. - * The <code>commit</code> method for a <code>LoginModule</code> checks its + * LoginModules succeeded), then the {@code commit} + * method for the {@code LoginModule} gets invoked. + * The {@code commit} method for a {@code LoginModule} checks its * privately saved state to see if its own authentication succeeded. - * If the overall <code>LoginContext</code> authentication succeeded + * If the overall {@code LoginContext} authentication succeeded * and the LoginModule's own authentication succeeded, then the - * <code>commit</code> method associates the relevant + * {@code commit} method associates the relevant * Principals (authenticated identities) and Credentials (authentication data - * such as cryptographic keys) with the <code>Subject</code> - * located within the <code>LoginModule</code>. + * such as cryptographic keys) with the {@code Subject} + * located within the {@code LoginModule}. * * <p> If the LoginContext's overall authentication failed (the relevant * REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules did not succeed), - * then the <code>abort</code> method for each <code>LoginModule</code> - * gets invoked. In this case, the <code>LoginModule</code> removes/destroys + * then the {@code abort} method for each {@code LoginModule} + * gets invoked. In this case, the {@code LoginModule} removes/destroys * any authentication state originally saved. * - * <p> Logging out a <code>Subject</code> involves only one phase. - * The <code>LoginContext</code> invokes the LoginModule's <code>logout</code> - * method. The <code>logout</code> method for the <code>LoginModule</code> + * <p> Logging out a {@code Subject} involves only one phase. + * The {@code LoginContext} invokes the LoginModule's {@code logout} + * method. The {@code logout} method for the {@code LoginModule} * then performs the logout procedures, such as removing Principals or - * Credentials from the <code>Subject</code> or logging session information. + * Credentials from the {@code Subject} or logging session information. * - * <p> A <code>LoginModule</code> implementation must have a constructor with - * no arguments. This allows classes which load the <code>LoginModule</code> + * <p> A {@code LoginModule} implementation must have a constructor with + * no arguments. This allows classes which load the {@code LoginModule} * to instantiate it. * * @see javax.security.auth.login.LoginContext @@ -131,38 +131,38 @@ /** * Initialize this LoginModule. * - * <p> This method is called by the <code>LoginContext</code> - * after this <code>LoginModule</code> has been instantiated. + * <p> This method is called by the {@code LoginContext} + * after this {@code LoginModule} has been instantiated. * The purpose of this method is to initialize this - * <code>LoginModule</code> with the relevant information. - * If this <code>LoginModule</code> does not understand - * any of the data stored in <code>sharedState</code> or - * <code>options</code> parameters, they can be ignored. + * {@code LoginModule} with the relevant information. + * If this {@code LoginModule} does not understand + * any of the data stored in {@code sharedState} or + * {@code options} parameters, they can be ignored. * * <p> * - * @param subject the <code>Subject</code> to be authenticated. <p> + * @param subject the {@code Subject} to be authenticated. <p> * - * @param callbackHandler a <code>CallbackHandler</code> for communicating + * @param callbackHandler a {@code CallbackHandler} for communicating * with the end user (prompting for usernames and * passwords, for example). <p> * * @param sharedState state shared with other configured LoginModules. <p> * * @param options options specified in the login - * <code>Configuration</code> for this particular - * <code>LoginModule</code>. + * {@code Configuration} for this particular + * {@code LoginModule}. */ void initialize(Subject subject, CallbackHandler callbackHandler, Map<String,?> sharedState, Map<String,?> options); /** - * Method to authenticate a <code>Subject</code> (phase 1). + * Method to authenticate a {@code Subject} (phase 1). * * <p> The implementation of this method authenticates - * a <code>Subject</code>. For example, it may prompt for - * <code>Subject</code> information such + * a {@code Subject}. For example, it may prompt for + * {@code Subject} information such * as a username and password and then attempt to verify the password. * This method saves the result of the authentication attempt * as private state within the LoginModule. @@ -172,7 +172,7 @@ * @exception LoginException if the authentication fails * * @return true if the authentication succeeded, or false if this - * <code>LoginModule</code> should be ignored. + * {@code LoginModule} should be ignored. */ boolean login() throws LoginException; @@ -186,9 +186,9 @@ * * <p> If this LoginModule's own authentication attempt * succeeded (checked by retrieving the private state saved by the - * <code>login</code> method), then this method associates relevant - * Principals and Credentials with the <code>Subject</code> located in the - * <code>LoginModule</code>. If this LoginModule's own + * {@code login} method), then this method associates relevant + * Principals and Credentials with the {@code Subject} located in the + * {@code LoginModule}. If this LoginModule's own * authentication attempted failed, then this method removes/destroys * any state that was originally saved. * @@ -197,7 +197,7 @@ * @exception LoginException if the commit fails * * @return true if this method succeeded, or false if this - * <code>LoginModule</code> should be ignored. + * {@code LoginModule} should be ignored. */ boolean commit() throws LoginException; @@ -211,7 +211,7 @@ * * <p> If this LoginModule's own authentication attempt * succeeded (checked by retrieving the private state saved by the - * <code>login</code> method), then this method cleans up any state + * {@code login} method), then this method cleans up any state * that was originally saved. * * <p> @@ -219,12 +219,12 @@ * @exception LoginException if the abort fails * * @return true if this method succeeded, or false if this - * <code>LoginModule</code> should be ignored. + * {@code LoginModule} should be ignored. */ boolean abort() throws LoginException; /** - * Method which logs out a <code>Subject</code>. + * Method which logs out a {@code Subject}. * * <p>An implementation of this method might remove/destroy a Subject's * Principals and Credentials. @@ -234,7 +234,7 @@ * @exception LoginException if the logout fails * * @return true if this method succeeded, or false if this - * <code>LoginModule</code> should be ignored. + * {@code LoginModule} should be ignored. */ boolean logout() throws LoginException; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/auth/spi/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000, 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. 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. + */ + +/** + * This package provides the interface to be used for + * implementing pluggable authentication modules. + * + * @since JDK1.4 + */ +package javax.security.auth.spi;
--- a/src/share/classes/javax/security/auth/spi/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -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. 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. ---> - -</head> -<body bgcolor="white"> - - This package provides the interface to be used for - implementing pluggable authentication modules. -<!-- -<h2>Package Specification</h2> - -##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### -<ul> - <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> -</ul> - -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since JDK1.4 -</body> -</html>
--- a/src/share/classes/javax/security/auth/x500/X500Principal.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/x500/X500Principal.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -33,8 +33,8 @@ import sun.security.util.*; /** - * <p> This class represents an X.500 <code>Principal</code>. - * <code>X500Principal</code>s are represented by distinguished names such as + * <p> This class represents an X.500 {@code Principal}. + * {@code X500Principal}s are represented by distinguished names such as * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US". * * <p> This class can be instantiated by using a string representation @@ -50,12 +50,12 @@ * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile</a>. * - * <p> The string representation for this <code>X500Principal</code> - * can be obtained by calling the <code>getName</code> methods. + * <p> The string representation for this {@code X500Principal} + * can be obtained by calling the {@code getName} methods. * - * <p> Note that the <code>getSubjectX500Principal</code> and - * <code>getIssuerX500Principal</code> methods of - * <code>X509Certificate</code> return X500Principals representing the + * <p> Note that the {@code getSubjectX500Principal} and + * {@code getIssuerX500Principal} methods of + * {@code X509Certificate} return X500Principals representing the * issuer and subject fields of the certificate. * * @see java.security.cert.X509Certificate @@ -97,7 +97,7 @@ } /** - * Creates an <code>X500Principal</code> from a string representation of + * Creates an {@code X500Principal} from a string representation of * an X.500 distinguished name (ex: * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"). * The distinguished name must be specified using the grammar defined in @@ -119,9 +119,9 @@ * <p>{@code numericoid = number 1*( DOT number ) } * * @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format - * @exception NullPointerException if the <code>name</code> - * is <code>null</code> - * @exception IllegalArgumentException if the <code>name</code> + * @exception NullPointerException if the {@code name} + * is {@code null} + * @exception IllegalArgumentException if the {@code name} * is improperly specified */ public X500Principal(String name) { @@ -129,7 +129,7 @@ } /** - * Creates an <code>X500Principal</code> from a string representation of + * Creates an {@code X500Principal} from a string representation of * an X.500 distinguished name (ex: * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"). * The distinguished name must be specified using the grammar defined in @@ -137,13 +137,13 @@ * * <p> This constructor recognizes the attribute type keywords specified * in {@link #X500Principal(String)} and also recognizes additional - * keywords that have entries in the <code>keywordMap</code> parameter. + * keywords that have entries in the {@code keywordMap} parameter. * Keyword entries in the keywordMap take precedence over the default - * keywords recognized by <code>X500Principal(String)</code>. Keywords + * keywords recognized by {@code X500Principal(String)}. Keywords * MUST be specified in all upper-case, otherwise they will be ignored. * Improperly specified keywords are ignored; however if a keyword in the * name maps to an improperly specified Object Identifier (OID), an - * <code>IllegalArgumentException</code> is thrown. It is permissible to + * {@code IllegalArgumentException} is thrown. It is permissible to * have 2 different keywords that map to the same OID. * * <p>This implementation enforces a more restrictive OID syntax than @@ -157,11 +157,11 @@ * @param keywordMap an attribute type keyword map, where each key is a * keyword String that maps to a corresponding object identifier in String * form (a sequence of nonnegative integers separated by periods). The map - * may be empty but never <code>null</code>. - * @exception NullPointerException if <code>name</code> or - * <code>keywordMap</code> is <code>null</code> - * @exception IllegalArgumentException if the <code>name</code> is - * improperly specified or a keyword in the <code>name</code> maps to an + * may be empty but never {@code null}. + * @exception NullPointerException if {@code name} or + * {@code keywordMap} is {@code null} + * @exception IllegalArgumentException if the {@code name} is + * improperly specified or a keyword in the {@code name} maps to an * OID that is not in the correct form * @since 1.6 */ @@ -188,10 +188,10 @@ } /** - * Creates an <code>X500Principal</code> from a distinguished name in + * Creates an {@code X500Principal} from a distinguished name in * ASN.1 DER encoded form. The ASN.1 notation for this structure is as * follows. - * <pre><code> + * <pre>{@code * Name ::= CHOICE { * RDNSequence } * @@ -214,7 +214,7 @@ * universalString UniversalString (SIZE (1..MAX)), * utf8String UTF8String (SIZE (1.. MAX)), * bmpString BMPString (SIZE (1..MAX)) } - * </code></pre> + * }</pre> * * @param name a byte array containing the distinguished name in ASN.1 * DER encoded form @@ -233,7 +233,7 @@ } /** - * Creates an <code>X500Principal</code> from an <code>InputStream</code> + * Creates an {@code X500Principal} from an {@code InputStream} * containing the distinguished name in ASN.1 DER encoded form. * The ASN.1 notation for this structure is supplied in the * documentation for @@ -242,11 +242,11 @@ * <p> The read position of the input stream is positioned * to the next available byte after the encoded distinguished name. * - * @param is an <code>InputStream</code> containing the distinguished + * @param is an {@code InputStream} containing the distinguished * name in ASN.1 DER encoded form * - * @exception NullPointerException if the <code>InputStream</code> - * is <code>null</code> + * @exception NullPointerException if the {@code InputStream} + * is {@code null} * @exception IllegalArgumentException if an encoding error occurs * (incorrect form for DN) */ @@ -284,9 +284,9 @@ * the format defined in RFC 2253. * * <p>This method is equivalent to calling - * <code>getName(X500Principal.RFC2253)</code>. + * {@code getName(X500Principal.RFC2253)}. * - * @return the distinguished name of this <code>X500Principal</code> + * @return the distinguished name of this {@code X500Principal} */ public String getName() { return getName(X500Principal.RFC2253); @@ -338,9 +338,9 @@ * those which section 2.4 of RFC 2253 states must be escaped * (they are escaped using a preceding backslash character) * <li> The entire name is converted to upper case - * using <code>String.toUpperCase(Locale.US)</code> + * using {@code String.toUpperCase(Locale.US)} * <li> The entire name is converted to lower case - * using <code>String.toLowerCase(Locale.US)</code> + * using {@code String.toLowerCase(Locale.US)} * <li> The name is finally normalized using normalization form KD, * as described in the Unicode Standard and UAX #15 * </ol> @@ -349,7 +349,7 @@ * * @param format the format to use * - * @return a string representation of this <code>X500Principal</code> + * @return a string representation of this {@code X500Principal} * using the specified format * @throws IllegalArgumentException if the specified format is invalid * or null @@ -371,16 +371,16 @@ * Returns a string representation of the X.500 distinguished name * using the specified format. Valid values for the format are * "RFC1779" and "RFC2253" (case insensitive). "CANONICAL" is not - * permitted and an <code>IllegalArgumentException</code> will be thrown. + * permitted and an {@code IllegalArgumentException} will be thrown. * * <p>This method returns Strings in the format as specified in * {@link #getName(String)} and also emits additional attribute type - * keywords for OIDs that have entries in the <code>oidMap</code> + * keywords for OIDs that have entries in the {@code oidMap} * parameter. OID entries in the oidMap take precedence over the default - * OIDs recognized by <code>getName(String)</code>. + * OIDs recognized by {@code getName(String)}. * Improperly specified OIDs are ignored; however if an OID * in the name maps to an improperly specified keyword, an - * <code>IllegalArgumentException</code> is thrown. + * {@code IllegalArgumentException} is thrown. * * <p> Additional standard formats may be introduced in the future. * @@ -393,12 +393,12 @@ * @param oidMap an OID map, where each key is an object identifier in * String form (a sequence of nonnegative integers separated by periods) * that maps to a corresponding attribute type keyword String. - * The map may be empty but never <code>null</code>. - * @return a string representation of this <code>X500Principal</code> + * The map may be empty but never {@code null}. + * @return a string representation of this {@code X500Principal} * using the specified format * @throws IllegalArgumentException if the specified format is invalid, * null, or an OID in the name maps to an improperly specified keyword - * @throws NullPointerException if <code>oidMap</code> is <code>null</code> + * @throws NullPointerException if {@code oidMap} is {@code null} * @since 1.6 */ public String getName(String format, Map<String, String> oidMap) { @@ -438,31 +438,31 @@ /** * Return a user-friendly string representation of this - * <code>X500Principal</code>. + * {@code X500Principal}. * - * @return a string representation of this <code>X500Principal</code> + * @return a string representation of this {@code X500Principal} */ public String toString() { return thisX500Name.toString(); } /** - * Compares the specified <code>Object</code> with this - * <code>X500Principal</code> for equality. + * Compares the specified {@code Object} with this + * {@code X500Principal} for equality. * - * <p> Specifically, this method returns <code>true</code> if - * the <code>Object</code> <i>o</i> is an <code>X500Principal</code> + * <p> Specifically, this method returns {@code true} if + * the {@code Object} <i>o</i> is an {@code X500Principal} * and if the respective canonical string representations - * (obtained via the <code>getName(X500Principal.CANONICAL)</code> method) + * (obtained via the {@code getName(X500Principal.CANONICAL)} method) * of this object and <i>o</i> are equal. * * <p> This implementation is compliant with the requirements of RFC 3280. * * @param o Object to be compared for equality with this - * <code>X500Principal</code> + * {@code X500Principal} * - * @return <code>true</code> if the specified <code>Object</code> is equal - * to this <code>X500Principal</code>, <code>false</code> otherwise + * @return {@code true} if the specified {@code Object} is equal + * to this {@code X500Principal}, {@code false} otherwise */ public boolean equals(Object o) { if (this == o) { @@ -476,12 +476,12 @@ } /** - * Return a hash code for this <code>X500Principal</code>. + * Return a hash code for this {@code X500Principal}. * * <p> The hash code is calculated via: - * <code>getName(X500Principal.CANONICAL).hashCode()</code> + * {@code getName(X500Principal.CANONICAL).hashCode()} * - * @return a hash code for this <code>X500Principal</code> + * @return a hash code for this {@code X500Principal} */ public int hashCode() { return thisX500Name.hashCode(); @@ -490,9 +490,9 @@ /** * Save the X500Principal object to a stream. * - * @serialData this <code>X500Principal</code> is serialized + * @serialData this {@code X500Principal} is serialized * by writing out its DER-encoded form - * (the value of <code>getEncoded</code> is serialized). + * (the value of {@code getEncoded} is serialized). */ private void writeObject(java.io.ObjectOutputStream s) throws IOException {
--- a/src/share/classes/javax/security/auth/x500/X500PrivateCredential.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/auth/x500/X500PrivateCredential.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -30,7 +30,7 @@ import javax.security.auth.Destroyable; /** - * <p> This class represents an <code>X500PrivateCredential</code>. + * <p> This class represents an {@code X500PrivateCredential}. * It associates an X.509 certificate, corresponding private key and the * KeyStore alias used to reference that exact key pair in the KeyStore. * This enables looking up the private credentials for an X.500 principal @@ -48,8 +48,8 @@ * <p> * @param cert X509Certificate * @param key PrivateKey for the certificate - * @exception IllegalArgumentException if either <code>cert</code> or - * <code>key</code> is null + * @exception IllegalArgumentException if either {@code cert} or + * {@code key} is null * */ @@ -68,8 +68,8 @@ * @param cert X509Certificate * @param key PrivateKey for the certificate * @param alias KeyStore alias - * @exception IllegalArgumentException if either <code>cert</code>, - * <code>key</code> or <code>alias</code> is null + * @exception IllegalArgumentException if either {@code cert}, + * {@code key} or {@code alias} is null * */ public X500PrivateCredential(X509Certificate cert, PrivateKey key,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/auth/x500/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000, 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. 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. + */ + +/** + * This package contains the classes that should be used to store + * X500 Principal and X500 Private Credentials in a + * <i>Subject</i>. + * + * <h2>Package Specification</h2> + * + * <ul> + * <li><a href="http://www.ietf.org/rfc/rfc1779.txt"> + * RFC 1779: A String Representation of Distinguished Names</a></li> + * <li><a href="http://www.ietf.org/rfc/rfc2253.txt"> + * RFC 2253: Lightweight Directory Access Protocol (v3): + * UTF-8 String Representation of Distinguished Names</a></li> + * <li><a href="http://www.ietf.org/rfc/rfc3280.txt"> + * RFC 3280: Internet X.509 Public Key Infrastructure + * Certificate and Certificate Revocation List (CRL) Profile</a></li> + * <li><a href="http://www.ietf.org/rfc/rfc4512.txt"> + * RFC 4512: Lightweight Directory Access Protocol (LDAP): + * Directory Information Models</a></li> + * </ul> + * + * @since JDK1.4 + */ +package javax.security.auth.x500;
--- a/src/share/classes/javax/security/auth/x500/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -Copyright (c) 2000, 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. 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. ---> - -</head> -<body bgcolor="white"> - - This package contains the classes that should be used to store - X500 Principal and X500 Private Credentials in a - <i>Subject</i>. - -<h2>Package Specification</h2> - -<ul> - <li><a href="http://www.ietf.org/rfc/rfc1779.txt"> - RFC 1779: A String Representation of Distinguished Names</a></li> - <li><a href="http://www.ietf.org/rfc/rfc2253.txt"> - RFC 2253: Lightweight Directory Access Protocol (v3): - UTF-8 String Representation of Distinguished Names</a></li> - <li><a href="http://www.ietf.org/rfc/rfc3280.txt"> - RFC 3280: Internet X.509 Public Key Infrastructure - Certificate and Certificate Revocation List (CRL) Profile</a></li> - <li><a href="http://www.ietf.org/rfc/rfc4512.txt"> - RFC 4512: Lightweight Directory Access Protocol (LDAP): - Directory Information Models</a></li> -</ul> - -<!-- -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since JDK1.4 -</body> -</html>
--- a/src/share/classes/javax/security/cert/Certificate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/Certificate.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -49,11 +49,11 @@ * sets of information, and they store and retrieve the information in * different ways. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @since 1.4 * @see X509Certificate @@ -64,8 +64,8 @@ /** * Compares this certificate for equality with the specified - * object. If the <code>other</code> object is an - * <code>instanceof</code> <code>Certificate</code>, then + * object. If the {@code other} object is an + * {@code instanceof} {@code Certificate}, then * its encoded form is retrieved and compared with the * encoded form of this certificate. *
--- a/src/share/classes/javax/security/cert/CertificateEncodingException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/CertificateEncodingException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -30,11 +30,11 @@ * Certificate Encoding Exception. This is thrown whenever an error * occurs whilst attempting to encode a certificate. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @since 1.4 * @author Hemma Prafullchandra
--- a/src/share/classes/javax/security/cert/CertificateException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/CertificateException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -29,11 +29,11 @@ /** * This exception indicates one of a variety of certificate problems. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @author Hemma Prafullchandra * @since 1.4
--- a/src/share/classes/javax/security/cert/CertificateExpiredException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/CertificateExpiredException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -28,15 +28,15 @@ /** * Certificate Expired Exception. This is thrown whenever the current - * <code>Date</code> or the specified <code>Date</code> is after the - * <code>notAfter</code> date/time specified in the validity period + * {@code Date} or the specified {@code Date} is after the + * {@code notAfter} date/time specified in the validity period * of the certificate. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @since 1.4 * @author Hemma Prafullchandra
--- a/src/share/classes/javax/security/cert/CertificateNotYetValidException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/CertificateNotYetValidException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -28,15 +28,15 @@ /** * Certificate is not yet valid exception. This is thrown whenever - * the current <code>Date</code> or the specified <code>Date</code> - * is before the <code>notBefore</code> date/time in the Certificate + * the current {@code Date} or the specified {@code Date} + * is before the {@code notBefore} date/time in the Certificate * validity period. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @since 1.4 * @author Hemma Prafullchandra
--- a/src/share/classes/javax/security/cert/CertificateParsingException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/CertificateParsingException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -31,11 +31,11 @@ * invalid DER encoded certificate is parsed or unsupported DER features * are found in the Certificate. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @since 1.4 * @author Hemma Prafullchandra
--- a/src/share/classes/javax/security/cert/X509Certificate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/cert/X509Certificate.java Wed Jul 24 08:22:32 2013 -0300 @@ -70,7 +70,7 @@ * CA certificates are either signed by themselves, or by some other * CA such as a "root" CA. * <p> - * The ASN.1 definition of <code>tbsCertificate</code> is: + * The ASN.1 definition of {@code tbsCertificate} is: * <pre> * TBSCertificate ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, @@ -113,11 +113,11 @@ * initialization time and will fallback on a default implementation if * the Security property is not accessible. * - * <p><em>Note: The classes in the package <code>javax.security.cert</code> + * <p><em>Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * <code>java.security.cert</code>.</em></p> + * {@code java.security.cert}.</em></p> * * @author Hemma Prafullchandra * @since 1.4 @@ -150,7 +150,7 @@ /** * Instantiates an X509Certificate object, and initializes it with - * the data read from the input stream <code>inStream</code>. + * the data read from the input stream {@code inStream}. * The implementation (X509Certificate is an abstract class) is * provided by the class specified as the value of the * {@code cert.provider.x509v1} security property. @@ -191,7 +191,7 @@ * @param certData a byte array containing the DER-encoded * certificate. * @return an X509Certificate object initialized with the data - * from <code>certData</code>. + * from {@code certData}. * @exception CertificateException if a class initialization * or certificate parsing error occurs. */ @@ -281,16 +281,16 @@ * @param date the Date to check against to see if this certificate * is valid at that date/time. * @exception CertificateExpiredException if the certificate has expired - * with respect to the <code>date</code> supplied. + * with respect to the {@code date} supplied. * @exception CertificateNotYetValidException if the certificate is not - * yet valid with respect to the <code>date</code> supplied. + * yet valid with respect to the {@code date} supplied. * @see #checkValidity() */ public abstract void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException; /** - * Gets the <code>version</code> (version number) value from the + * Gets the {@code version} (version number) value from the * certificate. The ASN.1 definition for this is: * <pre> * version [0] EXPLICIT Version DEFAULT v1 @@ -303,7 +303,7 @@ public abstract int getVersion(); /** - * Gets the <code>serialNumber</code> value from the certificate. + * Gets the {@code serialNumber} value from the certificate. * The serial number is an integer assigned by the certification * authority to each certificate. It must be unique for each * certificate issued by a given CA (i.e., the issuer name and @@ -320,7 +320,7 @@ public abstract BigInteger getSerialNumber(); /** - * Gets the <code>issuer</code> (issuer distinguished name) value from + * Gets the {@code issuer} (issuer distinguished name) value from * the certificate. The issuer name identifies the entity that signed (and * issued) the certificate. * @@ -341,27 +341,27 @@ * AttributeType ::= OBJECT IDENTIFIER * AttributeValue ::= ANY * </pre> - * The <code>Name</code> describes a hierarchical name composed of + * The {@code Name} describes a hierarchical name composed of * attributes, such as country name, and corresponding values, such as US. - * The type of the <code>AttributeValue</code> component is determined by - * the <code>AttributeType</code>; in general it will be a - * <code>directoryString</code>. A <code>directoryString</code> is usually - * one of <code>PrintableString</code>, - * <code>TeletexString</code> or <code>UniversalString</code>. + * The type of the {@code AttributeValue} component is determined by + * the {@code AttributeType}; in general it will be a + * {@code directoryString}. A {@code directoryString} is usually + * one of {@code PrintableString}, + * {@code TeletexString} or {@code UniversalString}. * * @return a Principal whose name is the issuer distinguished name. */ public abstract Principal getIssuerDN(); /** - * Gets the <code>subject</code> (subject distinguished name) value + * Gets the {@code subject} (subject distinguished name) value * from the certificate. * The ASN.1 definition for this is: * <pre> * subject Name * </pre> * - * <p>See {@link #getIssuerDN() getIssuerDN} for <code>Name</code> + * <p>See {@link #getIssuerDN() getIssuerDN} for {@code Name} * and other relevant definitions. * * @return a Principal whose name is the subject name. @@ -370,7 +370,7 @@ public abstract Principal getSubjectDN(); /** - * Gets the <code>notBefore</code> date from the validity period of + * Gets the {@code notBefore} date from the validity period of * the certificate. * The relevant ASN.1 definitions are: * <pre> @@ -391,7 +391,7 @@ public abstract Date getNotBefore(); /** - * Gets the <code>notAfter</code> date from the validity period of + * Gets the {@code notAfter} date from the validity period of * the certificate. See {@link #getNotBefore() getNotBefore} * for relevant ASN.1 definitions. * @@ -415,7 +415,7 @@ * -- algorithm object identifier value * </pre> * - * <p>The algorithm name is determined from the <code>algorithm</code> + * <p>The algorithm name is determined from the {@code algorithm} * OID string. * * @return the signature algorithm name.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/cert/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1999, 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. 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. + */ + +/** + * Provides classes for public key certificates. + * + * These classes include a simplified version of the + * java.security.cert package. These classes were developed + * as part of the Java Secure Socket + * Extension (JSSE). When JSSE was added to the J2SE version 1.4, this + * package was added for backward-compatibility reasons only. + * + * New applications should not use this package, but rather + * java.security.cert. + * + * @since 1.4 + */ +package javax.security.cert;
--- a/src/share/classes/javax/security/cert/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -Copyright (c) 1999, 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. 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. ---> - -</head> -<body bgcolor="white"> - -Provides classes for public key certificates. - -<P> - -These classes include a simplified version of the -java.security.cert package. These classes were developed -as part of the Java Secure Socket -Extension (JSSE). When JSSE was added to the J2SE version 1.4, this -package was added for backward-compatibility reasons only. - -<P> - -New applications should not use this package, but rather -java.security.cert. -<!-- -<h2>Package Specification</h2> - -##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT ##### -<ul> - <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a> -</ul> - -<h2>Related Documentation</h2> - -For overviews, tutorials, examples, guides, and tool documentation, please see: -<ul> - <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a> -</ul> - ---> - -@since 1.4 -</body> -</html>
--- a/src/share/classes/javax/security/sasl/AuthenticationException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/AuthenticationException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -45,7 +45,7 @@ */ public class AuthenticationException extends SaslException { /** - * Constructs a new instance of <tt>AuthenticationException</tt>. + * Constructs a new instance of {@code AuthenticationException}. * The root exception and the detailed message are null. */ public AuthenticationException () { @@ -53,7 +53,7 @@ } /** - * Constructs a new instance of <tt>AuthenticationException</tt> + * Constructs a new instance of {@code AuthenticationException} * with a detailed message. * The root exception is null. * @param detail A possibly null string containing details of the exception. @@ -65,7 +65,7 @@ } /** - * Constructs a new instance of <tt>AuthenticationException</tt> with a detailed message + * Constructs a new instance of {@code AuthenticationException} with a detailed message * and a root exception. * * @param detail A possibly null string containing details of the exception.
--- a/src/share/classes/javax/security/sasl/AuthorizeCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/AuthorizeCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -28,7 +28,7 @@ import javax.security.auth.callback.Callback; /** - * This callback is used by <tt>SaslServer</tt> to determine whether + * This callback is used by {@code SaslServer} to determine whether * one entity (identified by an authenticated authentication id) * can act on * behalf of another entity (identified by an authorization id). @@ -66,7 +66,7 @@ private boolean authorized; /** - * Constructs an instance of <tt>AuthorizeCallback</tt>. + * Constructs an instance of {@code AuthorizeCallback}. * * @param authnID The (authenticated) authentication id. * @param authzID The authorization id. @@ -96,7 +96,7 @@ * Determines whether the authentication id is allowed to * act on behalf of the authorization id. * - * @return <tt>true</tt> if authorization is allowed; <tt>false</tt> otherwise + * @return {@code true} if authorization is allowed; {@code false} otherwise * @see #setAuthorized(boolean) * @see #getAuthorizedID() */ @@ -106,7 +106,7 @@ /** * Sets whether the authorization is allowed. - * @param ok <tt>true</tt> if authorization is allowed; <tt>false</tt> otherwise + * @param ok {@code true} if authorization is allowed; {@code false} otherwise * @see #isAuthorized * @see #setAuthorizedID(java.lang.String) */ @@ -116,7 +116,7 @@ /** * Returns the id of the authorized user. - * @return The id of the authorized user. <tt>null</tt> means the + * @return The id of the authorized user. {@code null} means the * authorization failed. * @see #setAuthorized(boolean) * @see #setAuthorizedID(java.lang.String)
--- a/src/share/classes/javax/security/sasl/RealmCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/RealmCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -28,7 +28,7 @@ import javax.security.auth.callback.TextInputCallback; /** - * This callback is used by <tt>SaslClient</tt> and <tt>SaslServer</tt> + * This callback is used by {@code SaslClient} and {@code SaslServer} * to retrieve realm information. * * @since 1.5 @@ -39,10 +39,10 @@ public class RealmCallback extends TextInputCallback { /** - * Constructs a <tt>RealmCallback</tt> with a prompt. + * Constructs a {@code RealmCallback} with a prompt. * * @param prompt The non-null prompt to use to request the realm information. - * @throws IllegalArgumentException If <tt>prompt</tt> is null or + * @throws IllegalArgumentException If {@code prompt} is null or * the empty string. */ public RealmCallback(String prompt) { @@ -50,14 +50,14 @@ } /** - * Constructs a <tt>RealmCallback</tt> with a prompt and default + * Constructs a {@code RealmCallback} with a prompt and default * realm information. * * @param prompt The non-null prompt to use to request the realm information. * @param defaultRealmInfo The non-null default realm information to use. - * @throws IllegalArgumentException If <tt>prompt</tt> is null or + * @throws IllegalArgumentException If {@code prompt} is null or * the empty string, - * or if <tt>defaultRealm</tt> is empty or null. + * or if {@code defaultRealm} is empty or null. */ public RealmCallback(String prompt, String defaultRealmInfo) { super(prompt, defaultRealmInfo);
--- a/src/share/classes/javax/security/sasl/RealmChoiceCallback.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/RealmChoiceCallback.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -28,7 +28,7 @@ import javax.security.auth.callback.ChoiceCallback; /** - * This callback is used by <tt>SaslClient</tt> and <tt>SaslServer</tt> + * This callback is used by {@code SaslClient} and {@code SaslServer} * to obtain a realm given a list of realm choices. * * @since 1.5 @@ -39,19 +39,19 @@ public class RealmChoiceCallback extends ChoiceCallback { /** - * Constructs a <tt>RealmChoiceCallback</tt> with a prompt, a list of + * Constructs a {@code RealmChoiceCallback} with a prompt, a list of * choices and a default choice. * * @param prompt the non-null prompt to use to request the realm. * @param choices the non-null list of realms to choose from. * @param defaultChoice the choice to be used as the default choice * when the list of choices is displayed. It is an index into - * the <tt>choices</tt> arary. + * the {@code choices} arary. * @param multiple true if multiple choices allowed; false otherwise - * @throws IllegalArgumentException If <tt>prompt</tt> is null or the empty string, - * if <tt>choices</tt> has a length of 0, if any element from - * <tt>choices</tt> is null or empty, or if <tt>defaultChoice</tt> - * does not fall within the array boundary of <tt>choices</tt> + * @throws IllegalArgumentException If {@code prompt} is null or the empty string, + * if {@code choices} has a length of 0, if any element from + * {@code choices} is null or empty, or if {@code defaultChoice} + * does not fall within the array boundary of {@code choices} */ public RealmChoiceCallback(String prompt, String[]choices, int defaultChoice, boolean multiple) {
--- a/src/share/classes/javax/security/sasl/Sasl.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/Sasl.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -72,15 +72,15 @@ * of quality-of-protection values that the * client or server is willing to support. A qop value is one of * <ul> - * <li><tt>"auth"</tt> - authentication only</li> - * <li><tt>"auth-int"</tt> - authentication plus integrity protection</li> - * <li><tt>"auth-conf"</tt> - authentication plus integrity and confidentiality + * <li>{@code "auth"} - authentication only</li> + * <li>{@code "auth-int"} - authentication plus integrity protection</li> + * <li>{@code "auth-conf"} - authentication plus integrity and confidentiality * protection</li> * </ul> * * The order of the list specifies the preference order of the client or - * server. If this property is absent, the default qop is <tt>"auth"</tt>. - * The value of this constant is <tt>"javax.security.sasl.qop"</tt>. + * server. If this property is absent, the default qop is {@code "auth"}. + * The value of this constant is {@code "javax.security.sasl.qop"}. */ public static final String QOP = "javax.security.sasl.qop"; @@ -90,9 +90,9 @@ * of cipher strength values that * the client or server is willing to support. A strength value is one of * <ul> - * <li><tt>"low"</tt></li> - * <li><tt>"medium"</tt></li> - * <li><tt>"high"</tt></li> + * <li>{@code "low"}</li> + * <li>{@code "medium"}</li> + * <li>{@code "high"}</li> * </ul> * The order of the list specifies the preference order of the client or * server. An implementation should allow configuration of the meaning @@ -101,19 +101,19 @@ * cipher suites that match the strength values. * <BR> * If this property is absent, the default strength is - * <tt>"high,medium,low"</tt>. - * The value of this constant is <tt>"javax.security.sasl.strength"</tt>. + * {@code "high,medium,low"}. + * The value of this constant is {@code "javax.security.sasl.strength"}. */ public static final String STRENGTH = "javax.security.sasl.strength"; /** * The name of a property that specifies whether the * server must authenticate to the client. The property contains - * <tt>"true"</tt> if the server must - * authenticate the to client; <tt>"false"</tt> otherwise. - * The default is <tt>"false"</tt>. + * {@code "true"} if the server must + * authenticate the to client; {@code "false"} otherwise. + * The default is {@code "false"}. * <br>The value of this constant is - * <tt>"javax.security.sasl.server.authentication"</tt>. + * {@code "javax.security.sasl.server.authentication"}. */ public static final String SERVER_AUTH = "javax.security.sasl.server.authentication"; @@ -125,28 +125,28 @@ * The property contains the bound host name after the authentication * exchange has completed. It is only available on the server side. * <br>The value of this constant is - * <tt>"javax.security.sasl.bound.server.name"</tt>. + * {@code "javax.security.sasl.bound.server.name"}. */ public static final String BOUND_SERVER_NAME = "javax.security.sasl.bound.server.name"; /** * The name of a property that specifies the maximum size of the receive - * buffer in bytes of <tt>SaslClient</tt>/<tt>SaslServer</tt>. + * buffer in bytes of {@code SaslClient}/{@code SaslServer}. * The property contains the string representation of an integer. * <br>If this property is absent, the default size * is defined by the mechanism. - * <br>The value of this constant is <tt>"javax.security.sasl.maxbuffer"</tt>. + * <br>The value of this constant is {@code "javax.security.sasl.maxbuffer"}. */ public static final String MAX_BUFFER = "javax.security.sasl.maxbuffer"; /** * The name of a property that specifies the maximum size of the raw send - * buffer in bytes of <tt>SaslClient</tt>/<tt>SaslServer</tt>. + * buffer in bytes of {@code SaslClient}/{@code SaslServer}. * The property contains the string representation of an integer. * The value of this property is negotiated between the client and server * during the authentication exchange. - * <br>The value of this constant is <tt>"javax.security.sasl.rawsendsize"</tt>. + * <br>The value of this constant is {@code "javax.security.sasl.rawsendsize"}. */ public static final String RAW_SEND_SIZE = "javax.security.sasl.rawsendsize"; @@ -181,11 +181,11 @@ * The name of a property that specifies * whether mechanisms susceptible to simple plain passive attacks (e.g., * "PLAIN") are not permitted. The property - * contains <tt>"true"</tt> if such mechanisms are not permitted; - * <tt>"false"</tt> if such mechanisms are permitted. - * The default is <tt>"false"</tt>. + * contains {@code "true"} if such mechanisms are not permitted; + * {@code "false"} if such mechanisms are permitted. + * The default is {@code "false"}. * <br>The value of this constant is - * <tt>"javax.security.sasl.policy.noplaintext"</tt>. + * {@code "javax.security.sasl.policy.noplaintext"}. */ public static final String POLICY_NOPLAINTEXT = "javax.security.sasl.policy.noplaintext"; @@ -194,12 +194,12 @@ * The name of a property that specifies whether * mechanisms susceptible to active (non-dictionary) attacks * are not permitted. - * The property contains <tt>"true"</tt> + * The property contains {@code "true"} * if mechanisms susceptible to active attacks - * are not permitted; <tt>"false"</tt> if such mechanisms are permitted. - * The default is <tt>"false"</tt>. + * are not permitted; {@code "false"} if such mechanisms are permitted. + * The default is {@code "false"}. * <br>The value of this constant is - * <tt>"javax.security.sasl.policy.noactive"</tt>. + * {@code "javax.security.sasl.policy.noactive"}. */ public static final String POLICY_NOACTIVE = "javax.security.sasl.policy.noactive"; @@ -207,26 +207,26 @@ /** * The name of a property that specifies whether * mechanisms susceptible to passive dictionary attacks are not permitted. - * The property contains <tt>"true"</tt> + * The property contains {@code "true"} * if mechanisms susceptible to dictionary attacks are not permitted; - * <tt>"false"</tt> if such mechanisms are permitted. - * The default is <tt>"false"</tt>. + * {@code "false"} if such mechanisms are permitted. + * The default is {@code "false"}. *<br> * The value of this constant is - * <tt>"javax.security.sasl.policy.nodictionary"</tt>. + * {@code "javax.security.sasl.policy.nodictionary"}. */ public static final String POLICY_NODICTIONARY = "javax.security.sasl.policy.nodictionary"; /** * The name of a property that specifies whether mechanisms that accept - * anonymous login are not permitted. The property contains <tt>"true"</tt> + * anonymous login are not permitted. The property contains {@code "true"} * if mechanisms that accept anonymous login are not permitted; - * <tt>"false"</tt> - * if such mechanisms are permitted. The default is <tt>"false"</tt>. + * {@code "false"} + * if such mechanisms are permitted. The default is {@code "false"}. *<br> * The value of this constant is - * <tt>"javax.security.sasl.policy.noanonymous"</tt>. + * {@code "javax.security.sasl.policy.noanonymous"}. */ public static final String POLICY_NOANONYMOUS = "javax.security.sasl.policy.noanonymous"; @@ -237,12 +237,12 @@ * means that breaking into one session will not automatically * provide information for breaking into future sessions. * The property - * contains <tt>"true"</tt> if mechanisms that implement forward secrecy - * between sessions are required; <tt>"false"</tt> if such mechanisms - * are not required. The default is <tt>"false"</tt>. + * contains {@code "true"} if mechanisms that implement forward secrecy + * between sessions are required; {@code "false"} if such mechanisms + * are not required. The default is {@code "false"}. *<br> * The value of this constant is - * <tt>"javax.security.sasl.policy.forward"</tt>. + * {@code "javax.security.sasl.policy.forward"}. */ public static final String POLICY_FORWARD_SECRECY = "javax.security.sasl.policy.forward"; @@ -250,12 +250,12 @@ /** * The name of a property that specifies whether * mechanisms that pass client credentials are required. The property - * contains <tt>"true"</tt> if mechanisms that pass - * client credentials are required; <tt>"false"</tt> - * if such mechanisms are not required. The default is <tt>"false"</tt>. + * contains {@code "true"} if mechanisms that pass + * client credentials are required; {@code "false"} + * if such mechanisms are not required. The default is {@code "false"}. *<br> * The value of this constant is - * <tt>"javax.security.sasl.policy.credentials"</tt>. + * {@code "javax.security.sasl.policy.credentials"}. */ public static final String POLICY_PASS_CREDENTIALS = "javax.security.sasl.policy.credentials"; @@ -269,38 +269,38 @@ * supports delegated authentication. *<br> * The value of this constant is - * <tt>"javax.security.sasl.credentials"</tt>. + * {@code "javax.security.sasl.credentials"}. */ public static final String CREDENTIALS = "javax.security.sasl.credentials"; /** - * Creates a <tt>SaslClient</tt> using the parameters supplied. + * Creates a {@code SaslClient} using the parameters supplied. * * This method uses the <a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#Provider">JCA Security Provider Framework</a>, described in the * "Java Cryptography Architecture API Specification & Reference", for - * locating and selecting a <tt>SaslClient</tt> implementation. + * locating and selecting a {@code SaslClient} implementation. * * First, it - * obtains an ordered list of <tt>SaslClientFactory</tt> instances from + * obtains an ordered list of {@code SaslClientFactory} instances from * the registered security providers for the "SaslClientFactory" service * and the specified SASL mechanism(s). It then invokes - * <tt>createSaslClient()</tt> on each factory instance on the list - * until one produces a non-null <tt>SaslClient</tt> instance. It returns - * the non-null <tt>SaslClient</tt> instance, or null if the search fails - * to produce a non-null <tt>SaslClient</tt> instance. + * {@code createSaslClient()} on each factory instance on the list + * until one produces a non-null {@code SaslClient} instance. It returns + * the non-null {@code SaslClient} instance, or null if the search fails + * to produce a non-null {@code SaslClient} instance. *<p> * A security provider for SaslClientFactory registers with the * JCA Security Provider Framework keys of the form <br> - * <tt>SaslClientFactory.<em>mechanism_name</em></tt> + * {@code SaslClientFactory.}<em>{@code mechanism_name}</em> * <br> * and values that are class names of implementations of - * <tt>javax.security.sasl.SaslClientFactory</tt>. + * {@code javax.security.sasl.SaslClientFactory}. * * For example, a provider that contains a factory class, - * <tt>com.wiz.sasl.digest.ClientFactory</tt>, that supports the + * {@code com.wiz.sasl.digest.ClientFactory}, that supports the * "DIGEST-MD5" mechanism would register the following entry with the JCA: - * <tt>SaslClientFactory.DIGEST-MD5 com.wiz.sasl.digest.ClientFactory</tt> + * {@code SaslClientFactory.DIGEST-MD5 com.wiz.sasl.digest.ClientFactory} *<p> * See the * "Java Cryptography Architecture API Specification & Reference" @@ -325,9 +325,9 @@ * @param props The possibly null set of properties used to * select the SASL mechanism and to configure the authentication * exchange of the selected mechanism. - * For example, if <tt>props</tt> contains the - * <code>Sasl.POLICY_NOPLAINTEXT</code> property with the value - * <tt>"true"</tt>, then the selected + * For example, if {@code props} contains the + * {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the selected * SASL mechanism must not be susceptible to simple plain passive attacks. * In addition to the standard properties declared in this class, * other, possibly mechanism-specific, properties can be included. @@ -338,16 +338,16 @@ * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a <tt>NameCallback</tt>. - * The password is requested by using a <tt>PasswordCallback</tt>. - * The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list - * of realms to choose from, and by using a <tt>RealmCallback</tt> if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null <tt>SaslClient</tt> created using the parameters - * supplied. If null, cannot find a <tt>SaslClientFactory</tt> + *@return A possibly null {@code SaslClient} created using the parameters + * supplied. If null, cannot find a {@code SaslClientFactory} * that will produce one. - *@exception SaslException If cannot create a <tt>SaslClient</tt> because + *@exception SaslException If cannot create a {@code SaslClient} because * of an error. */ public static SaslClient createSaslClient( @@ -423,34 +423,34 @@ /** - * Creates a <tt>SaslServer</tt> for the specified mechanism. + * Creates a {@code SaslServer} for the specified mechanism. * * This method uses the <a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#Provider">JCA Security Provider Framework</a>, * described in the * "Java Cryptography Architecture API Specification & Reference", for - * locating and selecting a <tt>SaslServer</tt> implementation. + * locating and selecting a {@code SaslServer} implementation. * * First, it - * obtains an ordered list of <tt>SaslServerFactory</tt> instances from + * obtains an ordered list of {@code SaslServerFactory} instances from * the registered security providers for the "SaslServerFactory" service * and the specified mechanism. It then invokes - * <tt>createSaslServer()</tt> on each factory instance on the list - * until one produces a non-null <tt>SaslServer</tt> instance. It returns - * the non-null <tt>SaslServer</tt> instance, or null if the search fails - * to produce a non-null <tt>SaslServer</tt> instance. + * {@code createSaslServer()} on each factory instance on the list + * until one produces a non-null {@code SaslServer} instance. It returns + * the non-null {@code SaslServer} instance, or null if the search fails + * to produce a non-null {@code SaslServer} instance. *<p> * A security provider for SaslServerFactory registers with the * JCA Security Provider Framework keys of the form <br> - * <tt>SaslServerFactory.<em>mechanism_name</em></tt> + * {@code SaslServerFactory.}<em>{@code mechanism_name}</em> * <br> * and values that are class names of implementations of - * <tt>javax.security.sasl.SaslServerFactory</tt>. + * {@code javax.security.sasl.SaslServerFactory}. * * For example, a provider that contains a factory class, - * <tt>com.wiz.sasl.digest.ServerFactory</tt>, that supports the + * {@code com.wiz.sasl.digest.ServerFactory}, that supports the * "DIGEST-MD5" mechanism would register the following entry with the JCA: - * <tt>SaslServerFactory.DIGEST-MD5 com.wiz.sasl.digest.ServerFactory</tt> + * {@code SaslServerFactory.DIGEST-MD5 com.wiz.sasl.digest.ServerFactory} *<p> * See the * "Java Cryptography Architecture API Specification & Reference" @@ -463,14 +463,14 @@ * the authentication is being performed (e.g., "ldap"). * @param serverName The fully qualified host name of the server, or null * if the server is not bound to any specific host name. If the mechanism - * does not allow an unbound server, a <code>SaslException</code> will + * does not allow an unbound server, a {@code SaslException} will * be thrown. * @param props The possibly null set of properties used to * select the SASL mechanism and to configure the authentication * exchange of the selected mechanism. - * For example, if <tt>props</tt> contains the - * <code>Sasl.POLICY_NOPLAINTEXT</code> property with the value - * <tt>"true"</tt>, then the selected + * For example, if {@code props} contains the + * {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the selected * SASL mechanism must not be susceptible to simple plain passive attacks. * In addition to the standard properties declared in this class, * other, possibly mechanism-specific, properties can be included. @@ -481,16 +481,16 @@ * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a <tt>NameCallback</tt>. - * The password is requested by using a <tt>PasswordCallback</tt>. - * The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list - * of realms to choose from, and by using a <tt>RealmCallback</tt> if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null <tt>SaslServer</tt> created using the parameters - * supplied. If null, cannot find a <tt>SaslServerFactory</tt> + *@return A possibly null {@code SaslServer} created using the parameters + * supplied. If null, cannot find a {@code SaslServerFactory} * that will produce one. - *@exception SaslException If cannot create a <tt>SaslServer</tt> because + *@exception SaslException If cannot create a {@code SaslServer} because * of an error. **/ public static SaslServer @@ -533,11 +533,11 @@ } /** - * Gets an enumeration of known factories for producing <tt>SaslClient</tt>. + * Gets an enumeration of known factories for producing {@code SaslClient}. * This method uses the same algorithm for locating factories as - * <tt>createSaslClient()</tt>. + * {@code createSaslClient()}. * @return A non-null enumeration of known factories for producing - * <tt>SaslClient</tt>. + * {@code SaslClient}. * @see #createSaslClient */ public static Enumeration<SaslClientFactory> getSaslClientFactories() { @@ -554,11 +554,11 @@ } /** - * Gets an enumeration of known factories for producing <tt>SaslServer</tt>. + * Gets an enumeration of known factories for producing {@code SaslServer}. * This method uses the same algorithm for locating factories as - * <tt>createSaslServer()</tt>. + * {@code createSaslServer()}. * @return A non-null enumeration of known factories for producing - * <tt>SaslServer</tt>. + * {@code SaslServer}. * @see #createSaslServer */ public static Enumeration<SaslServerFactory> getSaslServerFactories() {
--- a/src/share/classes/javax/security/sasl/SaslClient.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/SaslClient.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -30,14 +30,14 @@ *<p> * A protocol library such as one for LDAP gets an instance of this * class in order to perform authentication defined by a specific SASL - * mechanism. Invoking methods on the <tt>SaslClient</tt> instance + * mechanism. Invoking methods on the {@code SaslClient} instance * process challenges and create responses according to the SASL - * mechanism implemented by the <tt>SaslClient</tt>. + * mechanism implemented by the {@code SaslClient}. * As the authentication proceeds, the instance * encapsulates the state of a SASL client's authentication exchange. *<p> - * Here's an example of how an LDAP library might use a <tt>SaslClient</tt>. - * It first gets an instance of a <tt>SaslClient</tt>: + * Here's an example of how an LDAP library might use a {@code SaslClient}. + * It first gets an instance of a {@code SaslClient}: *<blockquote><pre>{@code * SaslClient sc = Sasl.createSaslClient(mechanisms, * authorizationId, protocol, serverName, props, callbackHandler); @@ -77,16 +77,16 @@ *}</pre></blockquote> * * If the mechanism has an initial response, the library invokes - * <tt>evaluateChallenge()</tt> with an empty + * {@code evaluateChallenge()} with an empty * challenge and to get initial response. * Protocols such as IMAP4, which do not include an initial response with * their first authentication command to the server, initiates the - * authentication without first calling <tt>hasInitialResponse()</tt> - * or <tt>evaluateChallenge()</tt>. + * authentication without first calling {@code hasInitialResponse()} + * or {@code evaluateChallenge()}. * When the server responds to the command, it sends an initial challenge. * For a SASL mechanism in which the client sends data first, the server should * have issued a challenge with no data. This will then result in a call - * (on the client) to <tt>evaluateChallenge()</tt> with an empty challenge. + * (on the client) to {@code evaluateChallenge()} with an empty challenge. * * @since 1.5 * @@ -107,7 +107,7 @@ /** * Determines whether this mechanism has an optional initial response. - * If true, caller should call <tt>evaluateChallenge()</tt> with an + * If true, caller should call {@code evaluateChallenge()} with an * empty array to get the initial response. * * @return true if this mechanism has an initial response. @@ -148,22 +148,22 @@ /** * Unwraps a byte array received from the server. * This method can be called only after the authentication exchange has - * completed (i.e., when <tt>isComplete()</tt> returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy * as the quality of protection; otherwise, an - * <tt>IllegalStateException</tt> is thrown. + * {@code IllegalStateException} is thrown. *<p> - * <tt>incoming</tt> is the contents of the SASL buffer as defined in RFC 2222 + * {@code incoming} is the contents of the SASL buffer as defined in RFC 2222 * without the leading four octet field that represents the length. - * <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>incoming</tt> + * {@code offset} and {@code len} specify the portion of {@code incoming} * to use. * * @param incoming A non-null byte array containing the encoded bytes * from the server. - * @param offset The starting position at <tt>incoming</tt> of the bytes to use. - * @param len The number of bytes from <tt>incoming</tt> to use. + * @param offset The starting position at {@code incoming} of the bytes to use. + * @param len The number of bytes from {@code incoming} to use. * @return A non-null byte array containing the decoded bytes. - * @exception SaslException if <tt>incoming</tt> cannot be successfully + * @exception SaslException if {@code incoming} cannot be successfully * unwrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection @@ -175,22 +175,22 @@ /** * Wraps a byte array to be sent to the server. * This method can be called only after the authentication exchange has - * completed (i.e., when <tt>isComplete()</tt> returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy * as the quality of protection; otherwise, an - * <tt>IllegalStateException</tt> is thrown. + * {@code IllegalStateException} is thrown. *<p> * The result of this method will make up the contents of the SASL buffer * as defined in RFC 2222 without the leading four octet field that * represents the length. - * <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>outgoing</tt> + * {@code offset} and {@code len} specify the portion of {@code outgoing} * to use. * * @param outgoing A non-null byte array containing the bytes to encode. - * @param offset The starting position at <tt>outgoing</tt> of the bytes to use. - * @param len The number of bytes from <tt>outgoing</tt> to use. + * @param offset The starting position at {@code outgoing} of the bytes to use. + * @param len The number of bytes from {@code outgoing} to use. * @return A non-null byte array containing the encoded bytes. - * @exception SaslException if <tt>outgoing</tt> cannot be successfully + * @exception SaslException if {@code outgoing} cannot be successfully * wrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection @@ -202,8 +202,8 @@ /** * Retrieves the negotiated property. * This method can be called only after the authentication exchange has - * completed (i.e., when <tt>isComplete()</tt> returns true); otherwise, an - * <tt>IllegalStateException</tt> is thrown. + * completed (i.e., when {@code isComplete()} returns true); otherwise, an + * {@code IllegalStateException} is thrown. * * @param propName The non-null property name. * @return The value of the negotiated property. If null, the property was
--- a/src/share/classes/javax/security/sasl/SaslClientFactory.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/SaslClientFactory.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -29,16 +29,16 @@ import javax.security.auth.callback.CallbackHandler; /** - * An interface for creating instances of <tt>SaslClient</tt>. + * An interface for creating instances of {@code SaslClient}. * A class that implements this interface * must be thread-safe and handle multiple simultaneous * requests. It must also have a public constructor that accepts no * argument. *<p> * This interface is not normally accessed directly by a client, which will use the - * <tt>Sasl</tt> static methods + * {@code Sasl} static methods * instead. However, a particular environment may provide and install a - * new or different <tt>SaslClientFactory</tt>. + * new or different {@code SaslClientFactory}. * * @since 1.5 * @@ -66,7 +66,7 @@ * of the server to authenticate to. * @param props The possibly null set of properties used to select the SASL * mechanism and to configure the authentication exchange of the selected - * mechanism. See the <tt>Sasl</tt> class for a list of standard properties. + * mechanism. See the {@code Sasl} class for a list of standard properties. * Other, possibly mechanism-specific, properties can be included. * Properties not relevant to the selected mechanism are ignored, * including any map entries with non-String keys. @@ -75,16 +75,16 @@ * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a <tt>NameCallback</tt>. - * The password is requested by using a <tt>PasswordCallback</tt>. - * The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list - * of realms to choose from, and by using a <tt>RealmCallback</tt> if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null <tt>SaslClient</tt> created using the parameters - * supplied. If null, this factory cannot produce a <tt>SaslClient</tt> + *@return A possibly null {@code SaslClient} created using the parameters + * supplied. If null, this factory cannot produce a {@code SaslClient} * using the parameters supplied. - *@exception SaslException If cannot create a <tt>SaslClient</tt> because + *@exception SaslException If cannot create a {@code SaslClient} because * of an error. */ public abstract SaslClient createSaslClient( @@ -99,12 +99,12 @@ * Returns an array of names of mechanisms that match the specified * mechanism selection policies. * @param props The possibly null set of properties used to specify the - * security policy of the SASL mechanisms. For example, if <tt>props</tt> - * contains the <tt>Sasl.POLICY_NOPLAINTEXT</tt> property with the value - * <tt>"true"</tt>, then the factory must not return any SASL mechanisms + * security policy of the SASL mechanisms. For example, if {@code props} + * contains the {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the factory must not return any SASL mechanisms * that are susceptible to simple plain passive attacks. - * See the <tt>Sasl</tt> class for a complete list of policy properties. - * Non-policy related properties, if present in <tt>props</tt>, are ignored, + * See the {@code Sasl} class for a complete list of policy properties. + * Non-policy related properties, if present in {@code props}, are ignored, * including any map entries with non-String keys. * @return A non-null array containing a IANA-registered SASL mechanism names. */
--- a/src/share/classes/javax/security/sasl/SaslException.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/SaslException.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -45,7 +45,7 @@ private Throwable _exception; /** - * Constructs a new instance of <tt>SaslException</tt>. + * Constructs a new instance of {@code SaslException}. * The root exception and the detailed message are null. */ public SaslException () { @@ -53,7 +53,7 @@ } /** - * Constructs a new instance of <tt>SaslException</tt> with a detailed message. + * Constructs a new instance of {@code SaslException} with a detailed message. * The root exception is null. * @param detail A possibly null string containing details of the exception. * @@ -64,7 +64,7 @@ } /** - * Constructs a new instance of <tt>SaslException</tt> with a detailed message + * Constructs a new instance of {@code SaslException} with a detailed message * and a root exception. * For example, a SaslException might result from a problem with * the callback handler, which might throw a NoSuchCallbackException if
--- a/src/share/classes/javax/security/sasl/SaslServer.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/SaslServer.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -30,14 +30,14 @@ *<p> * A server such an LDAP server gets an instance of this * class in order to perform authentication defined by a specific SASL - * mechanism. Invoking methods on the <tt>SaslServer</tt> instance + * mechanism. Invoking methods on the {@code SaslServer} instance * generates challenges according to the SASL - * mechanism implemented by the <tt>SaslServer</tt>. + * mechanism implemented by the {@code SaslServer}. * As the authentication proceeds, the instance * encapsulates the state of a SASL server's authentication exchange. *<p> - * Here's an example of how an LDAP server might use a <tt>SaslServer</tt>. - * It first gets an instance of a <tt>SaslServer</tt> for the SASL mechanism + * Here's an example of how an LDAP server might use a {@code SaslServer}. + * It first gets an instance of a {@code SaslServer} for the SASL mechanism * requested by the client: *<blockquote><pre> * SaslServer ss = Sasl.createSaslServer(mechanism, @@ -104,8 +104,8 @@ * to the client. It is non-null if the authentication must be continued * by sending a challenge to the client, or if the authentication has * succeeded but challenge data needs to be processed by the client. - * <tt>isComplete()</tt> should be called - * after each call to <tt>evaluateResponse()</tt>,to determine if any further + * {@code isComplete()} should be called + * after each call to {@code evaluateResponse()},to determine if any further * response is needed from the client. * * @param response The non-null (but possibly empty) response sent @@ -123,7 +123,7 @@ /** * Determines whether the authentication exchange has completed. * This method is typically called after each invocation of - * <tt>evaluateResponse()</tt> to determine whether the + * {@code evaluateResponse()} to determine whether the * authentication has completed successfully or should be continued. * @return true if the authentication exchange has completed; false otherwise. */ @@ -141,22 +141,22 @@ /** * Unwraps a byte array received from the client. * This method can be called only after the authentication exchange has - * completed (i.e., when <tt>isComplete()</tt> returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy * as the quality of protection; otherwise, - * an <tt>IllegalStateException</tt> is thrown. + * an {@code IllegalStateException} is thrown. *<p> - * <tt>incoming</tt> is the contents of the SASL buffer as defined in RFC 2222 + * {@code incoming} is the contents of the SASL buffer as defined in RFC 2222 * without the leading four octet field that represents the length. - * <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>incoming</tt> + * {@code offset} and {@code len} specify the portion of {@code incoming} * to use. * * @param incoming A non-null byte array containing the encoded bytes * from the client. - * @param offset The starting position at <tt>incoming</tt> of the bytes to use. - * @param len The number of bytes from <tt>incoming</tt> to use. + * @param offset The starting position at {@code incoming} of the bytes to use. + * @param len The number of bytes from {@code incoming} to use. * @return A non-null byte array containing the decoded bytes. - * @exception SaslException if <tt>incoming</tt> cannot be successfully + * @exception SaslException if {@code incoming} cannot be successfully * unwrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection @@ -168,21 +168,21 @@ /** * Wraps a byte array to be sent to the client. * This method can be called only after the authentication exchange has - * completed (i.e., when <tt>isComplete()</tt> returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy - * as the quality of protection; otherwise, a <tt>SaslException</tt> is thrown. + * as the quality of protection; otherwise, a {@code SaslException} is thrown. *<p> * The result of this method * will make up the contents of the SASL buffer as defined in RFC 2222 * without the leading four octet field that represents the length. - * <tt>offset</tt> and <tt>len</tt> specify the portion of <tt>outgoing</tt> + * {@code offset} and {@code len} specify the portion of {@code outgoing} * to use. * * @param outgoing A non-null byte array containing the bytes to encode. - * @param offset The starting position at <tt>outgoing</tt> of the bytes to use. - * @param len The number of bytes from <tt>outgoing</tt> to use. + * @param offset The starting position at {@code outgoing} of the bytes to use. + * @param len The number of bytes from {@code outgoing} to use. * @return A non-null byte array containing the encoded bytes. - * @exception SaslException if <tt>outgoing</tt> cannot be successfully + * @exception SaslException if {@code outgoing} cannot be successfully * wrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection has @@ -194,8 +194,8 @@ /** * Retrieves the negotiated property. * This method can be called only after the authentication exchange has - * completed (i.e., when <tt>isComplete()</tt> returns true); otherwise, an - * <tt>IllegalStateException</tt> is thrown. + * completed (i.e., when {@code isComplete()} returns true); otherwise, an + * {@code IllegalStateException} is thrown. * * @param propName the property * @return The value of the negotiated property. If null, the property was
--- a/src/share/classes/javax/security/sasl/SaslServerFactory.java Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/classes/javax/security/sasl/SaslServerFactory.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -29,16 +29,16 @@ import javax.security.auth.callback.CallbackHandler; /** - * An interface for creating instances of <tt>SaslServer</tt>. + * An interface for creating instances of {@code SaslServer}. * A class that implements this interface * must be thread-safe and handle multiple simultaneous * requests. It must also have a public constructor that accepts no * argument. *<p> * This interface is not normally accessed directly by a server, which will use the - * <tt>Sasl</tt> static methods + * {@code Sasl} static methods * instead. However, a particular environment may provide and install a - * new or different <tt>SaslServerFactory</tt>. + * new or different {@code SaslServerFactory}. * * @since 1.5 * @@ -50,10 +50,10 @@ */ public abstract interface SaslServerFactory { /** - * Creates a <tt>SaslServer</tt> using the parameters supplied. + * Creates a {@code SaslServer} using the parameters supplied. * It returns null - * if no <tt>SaslServer</tt> can be created using the parameters supplied. - * Throws <tt>SaslException</tt> if it cannot create a <tt>SaslServer</tt> + * if no {@code SaslServer} can be created using the parameters supplied. + * Throws {@code SaslException} if it cannot create a {@code SaslServer} * because of an error. * * @param mechanism The non-null @@ -63,10 +63,10 @@ * @param serverName The fully qualified host name of the server to * authenticate to, or null if the server is not bound to any specific host * name. If the mechanism does not allow an unbound server, a - * <code>SaslException</code> will be thrown. + * {@code SaslException} will be thrown. * @param props The possibly null set of properties used to select the SASL * mechanism and to configure the authentication exchange of the selected - * mechanism. See the <tt>Sasl</tt> class for a list of standard properties. + * mechanism. See the {@code Sasl} class for a list of standard properties. * Other, possibly mechanism-specific, properties can be included. * Properties not relevant to the selected mechanism are ignored, * including any map entries with non-String keys. @@ -75,16 +75,16 @@ * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a <tt>NameCallback</tt>. - * The password is requested by using a <tt>PasswordCallback</tt>. - * The realm is requested by using a <tt>RealmChoiceCallback</tt> if there is a list - * of realms to choose from, and by using a <tt>RealmCallback</tt> if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null <tt>SaslServer</tt> created using the parameters - * supplied. If null, this factory cannot produce a <tt>SaslServer</tt> + *@return A possibly null {@code SaslServer} created using the parameters + * supplied. If null, this factory cannot produce a {@code SaslServer} * using the parameters supplied. - *@exception SaslException If cannot create a <tt>SaslServer</tt> because + *@exception SaslException If cannot create a {@code SaslServer} because * of an error. */ public abstract SaslServer createSaslServer( @@ -98,12 +98,12 @@ * Returns an array of names of mechanisms that match the specified * mechanism selection policies. * @param props The possibly null set of properties used to specify the - * security policy of the SASL mechanisms. For example, if <tt>props</tt> - * contains the <tt>Sasl.POLICY_NOPLAINTEXT</tt> property with the value - * <tt>"true"</tt>, then the factory must not return any SASL mechanisms + * security policy of the SASL mechanisms. For example, if {@code props} + * contains the {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the factory must not return any SASL mechanisms * that are susceptible to simple plain passive attacks. - * See the <tt>Sasl</tt> class for a complete list of policy properties. - * Non-policy related properties, if present in <tt>props</tt>, are ignored, + * See the {@code Sasl} class for a complete list of policy properties. + * Non-policy related properties, if present in {@code props}, are ignored, * including any map entries with non-String keys. * @return A non-null array containing a IANA-registered SASL mechanism names. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/javax/security/sasl/package-info.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1999, 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. 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. + */ + +/** + * Contains class and interfaces for supporting SASL. + * + * This package defines classes and interfaces for SASL mechanisms. + * It is used by developers to add authentication support for + * connection-based protocols that use SASL. + * + * <h3>SASL Overview</h3> + * + * Simple Authentication and Security Layer (SASL) specifies a + * challenge-response protocol in which data is exchanged between the + * client and the server for the purposes of + * authentication and (optional) establishment of a security layer on + * which to carry on subsequent communications. It is used with + * connection-based protocols such as LDAPv3 or IMAPv4. SASL is + * described in + * <A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>. + * + * + * There are various <em>mechanisms</em> defined for SASL. + * Each mechanism defines the data that must be exchanged between the + * client and server in order for the authentication to succeed. + * This data exchange required for a particular mechanism is referred to + * to as its <em>protocol profile</em>. + * The following are some examples of mechanisms that have been defined by + * the Internet standards community. + * <ul> + * <li>DIGEST-MD5 (<A HREF="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>). + * This mechanism defines how HTTP Digest Authentication can be used as a SASL + * mechanism. + * <li>Anonymous (<A HREF="http://www.ietf.org/rfc/rfc2245.txt">RFC 2245</a>). + * This mechanism is anonymous authentication in which no credentials are + * necessary. + * <li>External (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>). + * This mechanism obtains authentication information + * from an external source (such as TLS or IPsec). + * <li>S/Key (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>). + * This mechanism uses the MD4 digest algorithm to exchange data based on + * a shared secret. + * <li>GSSAPI (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>). + * This mechanism uses the + * <A HREF="http://www.ietf.org/rfc/rfc2078.txt">GSSAPI</A> + * for obtaining authentication information. + * </ul> + * + * Some of these mechanisms provide both authentication and establishment + * of a security layer, others only authentication. Anonymous and + * S/Key do not provide for any security layers. GSSAPI and DIGEST-MD5 + * allow negotiation of the security layer. For External, the + * security layer is determined by the external protocol. + * + * <h3>Usage</h3> + * + * Users of this API are typically developers who produce + * client library implementations for connection-based protocols, + * such as LDAPv3 and IMAPv4, + * and developers who write servers (such as LDAP servers and IMAP servers). + * Developers who write client libraries use the + * {@code SaslClient} and {@code SaslClientFactory} interfaces. + * Developers who write servers use the + * {@code SaslServer} and {@code SaslServerFactory} interfaces. + * + * Among these two groups of users, each can be further divided into two groups: + * those who <em>produce</em> the SASL mechanisms and those + * who <em>use</em> the SASL mechanisms. + * The producers of SASL mechanisms need to provide implementations + * for these interfaces, while users of the SASL mechanisms use + * the APIs in this package to access those implementations. + * + * <h2>Related Documentation</h2> + * + * Please refer to the + * <a href="../../../../technotes/guides/security/sasl/sasl-refguide.html">Java + * SASL Programming Guide</a> for information on how to use this API. + * + * @since 1.5 + */ +package javax.security.sasl;
--- a/src/share/classes/javax/security/sasl/package.html Tue Jul 16 09:09:09 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<!-- -Copyright (c) 1999, 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. 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. ---> -</head> -<body bgcolor="white"> - -Contains class and interfaces for supporting SASL. - -This package defines classes and interfaces for SASL mechanisms. -It is used by developers to add authentication support for -connection-based protocols that use SASL. - -<h4>SASL Overview</h4> -<p> - -Simple Authentication and Security Layer (SASL) specifies a -challenge-response protocol in which data is exchanged between the -client and the server for the purposes of -authentication and (optional) establishment of a security layer on -which to carry on subsequent communications. It is used with -connection-based protocols such as LDAPv3 or IMAPv4. SASL is -described in -<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>. - -<p> -There are various <em>mechanisms</em> defined for SASL. -Each mechanism defines the data that must be exchanged between the -client and server in order for the authentication to succeed. -This data exchange required for a particular mechanism is referred to -to as its <em>protocol profile</em>. -The following are some examples of mechanims that have been defined by -the Internet standards community. -<ul> -<li>DIGEST-MD5 (<A HREF="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>). -This mechanism defines how HTTP Digest Authentication can be used as a SASL -mechanism. -<li>Anonymous (<A HREF="http://www.ietf.org/rfc/rfc2245.txt">RFC 2245</a>). -This mechamism is anonymous authentication in which no credentials are -necessary. -<li>External (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>). -This mechanism obtains authentication information -from an external source (such as TLS or IPsec). -<li>S/Key (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>). -This mechanism uses the MD4 digest algorithm to exchange data based on -a shared secret. -<li>GSSAPI (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>). -This mechanism uses the -<A HREF="http://www.ietf.org/rfc/rfc2078.txt">GSSAPI</A> -for obtaining authentication information. -</ul> - -<p> -Some of these mechanisms provide both authentication and establishment -of a security layer, others only authentication. Anonymous and -S/Key do not provide for any security layers. GSSAPI and DIGEST-MD5 -allow negotiation of the security layer. For External, the -security layer is determined by the external protocol. - -<h4>Usage</h4> - -<p> -Users of this API are typically developers who produce -client library implementations for connection-based protocols, -such as LDAPv3 and IMAPv4, -and developers who write servers (such as LDAP servers and IMAP servers). -Developers who write client libraries use the -<tt>SaslClient</tt> and <tt>SaslClientFactory</tt> interfaces. -Developers who write servers use the -<tt>SaslServer</tt> and <tt>SaslServerFactory</tt> interfaces. -<p> -Among these two groups of users, each can be further divided into two groups: -those who <em>produce</em> the SASL mechanisms and those -who <em>use</em> the SASL mechanisms. -The producers of SASL mechanisms need to provide implementations -for these interfaces, while users of the SASL mechanisms use -the APIs in this package to access those implementations. - -<h2>Related Documentation</h2> - -Please refer to the -<a href="../../../../technotes/guides/security/sasl/sasl-refguide.html">Java -SASL Programming Guide</a> for information on how to use this API. - - -@since 1.5 - - -</body> -</html> -
--- a/src/share/lib/hijrah-config-umalqura.properties Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/lib/hijrah-config-umalqura.properties Wed Jul 24 08:22:32 2013 -0300 @@ -1,58 +1,369 @@ -# -# hijrah-config-umalqura.properties -# -# -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. -# -# This properties file defines a Hijrah calendar variant. -# -# Fields: -# -# <version> ::= 'version' '=' <version string> -# <id> ::= 'id' '=' <id string> -# <type> ::= 'type' '=' <type string> -# <iso-start> ::= 'iso-start' '=' <start date in the ISO calendar> -# <year> ::= <yyyy> '=' <nn nn nn nn nn nn nn nn nn nn nn nn> -# -# version ... (Required) -# -# id ... (Required) -# Identifies the Java Chronology -# -# type ... (Required) -# Identifies the type of calendar in the standard calendar ID scheme -# iso-start ... (Required) -# Specifies the corresponding ISO date to the first Hijrah day -# in the defined range of dates -# -# year ... (Required) -# Number of days for each month of a Hijrah year -# * Each line defines a year. The years must be in the chronological -# order and no gap is allowed. -# * Each line is in the form indicated above. <yyyy> is a Hijrah year and -# nn is the number of days for a month listed in the order of the months. -# * Each year must have 12 months. -# * Each month should be 29 or 30 days long. -# * There must be one or more space characters between the months. -# - -# indicates the version of this definition -version=1.8.0_1 - -# Java chronology ID -id=Hijrah-umalqura - -# Standard calendar type specification -type=islamic-umalqura - -# defines the corresponding ISO date to the earliest Hijrah date -iso-start=2010-12-07 - -# -# the data section; defines the dates with the number of days for each month -# -# Placeholder data until full Umm alQura data can be validated -1432=29 30 30 30 29 30 29 30 29 30 29 29 -1433=30 29 30 30 29 30 30 29 30 29 30 29 -1434=29 30 29 30 29 30 30 29 30 30 29 29 -1435=30 29 30 29 30 29 30 29 30 30 29 30 +# 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. 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. +# +# This properties file defines a Hijrah calendar variant. +# +# Fields: +# +# <version> ::= 'version' '=' <version string> +# <id> ::= 'id' '=' <id string> +# <type> ::= 'type' '=' <type string> +# <iso-start> ::= 'iso-start' '=' <start date in the ISO calendar> +# <year> ::= <yyyy> '=' <nn nn nn nn nn nn nn nn nn nn nn nn> +# +# version ... (Required) +# +# id ... (Required) +# Identifies the Java Chronology +# +# type ... (Required) +# Identifies the type of calendar in the standard calendar ID scheme +# iso-start ... (Required) +# Specifies the corresponding ISO date to the first Hijrah day +# in the defined range of dates +# +# year ... (Required) +# Number of days for each month of a Hijrah year +# * Each line defines a year. The years must be in chronological +# order and no gap is allowed. +# * Each line is in the form indicated above. <yyyy> is a Hijrah year and +# nn is the number of days for a month listed in the order of the months. +# * Each year must have 12 months. +# * Each month should be 29 or 30 days long. +# * There must be one or more space characters between the months. +# + +# Version of this definition +version=1.8.0_1 + +# Java chronology ID +id=Hijrah-umalqura + +# Standard calendar type specification +type=islamic-umalqura + +# defines the corresponding ISO date to the earliest Hijrah date +iso-start=1882-11-12 + +# 1 2 3 4 5 6 7 8 9 10 11 12 +1300=30 29 30 29 30 29 30 29 30 29 30 29 +1301=30 30 29 30 29 30 29 30 29 30 29 29 +1302=30 30 30 29 30 30 29 29 30 29 29 30 +1303=29 30 30 29 30 30 29 30 29 30 29 29 +1304=29 30 30 29 30 30 30 29 30 29 30 29 +1305=29 29 30 30 29 30 30 29 30 30 29 29 +1306=30 29 30 29 30 29 30 29 30 30 29 30 +1307=29 30 29 30 29 30 29 30 29 30 29 30 +1308=29 30 30 29 30 29 30 29 30 29 29 30 +1309=29 30 30 30 30 29 29 30 29 29 30 29 +1310=30 29 30 30 30 29 30 29 30 29 29 30 +1311=29 30 29 30 30 30 29 30 29 30 29 29 +1312=30 29 30 29 30 30 29 30 30 29 30 29 +1313=29 30 29 30 29 30 29 30 30 30 29 29 +1314=30 30 29 30 29 29 30 29 30 30 29 30 +1315=29 30 30 29 30 29 29 30 29 30 29 30 +1316=29 30 30 30 29 30 29 29 30 29 30 29 +1317=30 29 30 30 29 30 29 30 29 30 29 29 +1318=30 29 30 30 29 30 30 29 30 29 30 29 +1319=29 30 29 30 30 29 30 29 30 30 29 30 +1320=29 30 29 29 30 29 30 29 30 30 30 29 +1321=30 29 30 29 29 30 29 29 30 30 30 30 +1322=29 30 29 30 29 29 29 30 29 30 30 30 +1323=29 30 30 29 30 29 29 29 30 29 30 30 +1324=29 30 30 29 30 29 30 29 29 30 29 30 +1325=30 29 30 29 30 30 29 30 29 30 29 30 +1326=29 29 30 29 30 30 29 30 29 30 30 29 +1327=30 29 29 30 29 30 29 30 30 29 30 30 +1328=29 30 29 29 30 29 29 30 30 30 29 30 +1329=30 29 30 29 29 30 29 29 30 30 29 30 +1330=30 30 29 30 29 29 30 29 29 30 30 29 +1331=30 30 29 30 30 29 29 30 29 30 29 30 +1332=29 30 29 30 30 29 30 29 30 30 29 29 +1333=30 29 29 30 30 29 30 30 29 30 30 29 +1334=29 29 30 29 30 29 30 30 30 29 30 29 +1335=30 29 30 29 29 30 29 30 30 29 30 30 +1336=29 30 29 30 29 29 30 29 30 29 30 30 +1337=30 29 30 29 30 29 29 30 29 30 29 30 +1338=29 30 30 29 30 30 29 29 30 29 30 29 +1339=30 29 30 29 30 30 30 29 30 29 29 30 +1340=29 29 30 29 30 30 30 30 29 30 29 29 +1341=30 29 29 30 29 30 30 30 29 30 30 29 +1342=29 29 30 29 30 29 30 30 29 30 30 29 +1343=30 29 29 30 29 30 29 30 29 30 30 29 +1344=30 29 30 29 30 30 29 29 30 29 30 29 +1345=30 29 30 30 30 29 30 29 29 30 29 29 +1346=30 29 30 30 30 30 29 30 29 29 30 29 +1347=29 30 29 30 30 30 29 30 30 29 29 30 +1348=29 29 30 29 30 30 29 30 30 30 29 29 +1349=30 29 29 30 29 30 30 29 30 30 29 30 +1350=29 30 29 30 29 30 29 29 30 30 29 30 +1351=30 29 30 29 30 29 30 29 29 30 29 30 +1352=30 29 30 30 29 30 29 30 29 29 30 29 +1353=30 29 30 30 30 29 30 29 29 30 29 30 +1354=29 30 29 30 30 29 30 30 29 30 29 29 +1355=30 29 29 30 30 29 30 30 29 30 30 29 +1356=29 30 29 30 29 30 29 30 29 30 30 30 +1357=29 29 30 29 30 29 29 30 29 30 30 30 +1358=29 30 29 30 29 30 29 29 30 29 30 30 +1359=29 30 30 29 30 29 30 29 29 29 30 30 +1360=29 30 30 30 29 30 29 30 29 29 30 29 +1361=30 29 30 30 29 30 30 29 29 30 29 30 +1362=29 30 29 30 29 30 30 29 30 29 30 29 +1363=30 29 30 29 30 29 30 29 30 29 30 30 +1364=29 30 29 30 29 29 30 29 30 29 30 30 +1365=30 30 29 29 30 29 29 30 29 30 29 30 +1366=30 30 29 30 29 30 29 29 30 29 30 29 +1367=30 30 29 30 30 29 30 29 29 30 29 30 +1368=29 30 29 30 30 30 29 29 30 29 30 29 +1369=30 29 30 29 30 30 29 30 29 30 30 29 +1370=30 29 29 30 29 30 29 30 29 30 30 30 +1371=29 30 29 29 30 29 30 29 30 29 30 30 +1372=30 29 29 30 29 30 29 29 30 29 30 30 +1373=30 29 30 29 30 29 30 29 29 30 29 30 +1374=30 29 30 30 29 30 29 30 29 29 30 29 +1375=30 29 30 30 29 30 30 29 30 29 30 29 +1376=29 30 29 30 29 30 30 30 29 30 29 30 +1377=29 29 30 29 29 30 30 30 29 30 30 29 +1378=30 29 29 29 30 29 30 30 29 30 30 30 +1379=29 30 29 29 29 30 29 30 30 29 30 30 +1380=29 30 29 30 29 30 29 30 29 30 29 30 +1381=29 30 29 30 30 29 30 29 30 29 29 30 +1382=29 30 29 30 30 29 30 30 29 30 29 29 +1383=30 29 29 30 30 30 29 30 30 29 30 29 +1384=29 30 29 29 30 30 29 30 30 30 29 30 +1385=29 29 30 29 29 30 30 29 30 30 30 29 +1386=30 29 29 30 29 29 30 30 29 30 30 29 +1387=30 29 30 29 30 29 30 29 30 29 30 29 +1388=30 30 29 30 29 30 29 30 29 30 29 29 +1389=30 30 29 30 30 29 30 30 29 29 30 29 +1390=29 30 29 30 30 30 29 30 29 30 29 30 +1391=29 29 30 29 30 30 29 30 30 29 30 29 +1392=30 29 29 30 29 30 29 30 30 29 30 30 +1393=29 30 29 29 30 29 30 29 30 29 30 30 +1394=30 29 30 29 29 30 29 30 29 30 29 30 +1395=30 29 30 30 29 30 29 29 30 29 29 30 +1396=30 29 30 30 29 30 30 29 29 30 29 29 +1397=30 29 30 30 29 30 30 30 29 29 29 30 +1398=29 30 29 30 30 29 30 30 29 30 29 29 +1399=30 29 30 29 30 29 30 30 29 30 29 30 +1400=30 29 30 29 29 30 29 30 29 30 29 30 +1401=30 30 29 30 29 29 30 29 29 30 29 30 +1402=30 30 30 29 30 29 29 30 29 29 30 29 +1403=30 30 30 29 30 30 29 29 30 29 29 30 +1404=29 30 30 29 30 30 29 30 29 30 29 29 +1405=30 29 30 29 30 30 30 29 30 29 29 30 +1406=30 29 29 30 29 30 30 29 30 29 30 30 +1407=29 30 29 29 30 29 30 29 30 29 30 30 +1408=30 29 30 29 30 29 29 30 29 29 30 30 +1409=30 30 29 30 29 30 29 29 30 29 29 30 +1410=30 30 29 30 30 29 30 29 29 30 29 29 +1411=30 30 29 30 30 29 30 30 29 29 30 29 +1412=30 29 30 29 30 29 30 30 30 29 29 30 +1413=29 30 29 29 30 29 30 30 30 29 30 29 +1414=30 29 30 29 29 30 29 30 30 29 30 30 +1415=29 30 29 30 29 29 30 29 30 29 30 30 +1416=30 29 30 29 30 29 29 30 29 30 29 30 +1417=30 29 30 30 29 29 30 29 30 29 30 29 +1418=30 29 30 30 29 30 29 30 29 30 29 30 +1419=29 30 29 30 29 30 29 30 30 30 29 29 +1420=29 30 29 29 30 29 30 30 30 30 29 30 +1421=29 29 30 29 29 29 30 30 30 30 29 30 +1422=30 29 29 30 29 29 29 30 30 30 29 30 +1423=30 29 30 29 30 29 29 30 29 30 29 30 +1424=30 29 30 30 29 30 29 29 30 29 30 29 +1425=30 29 30 30 29 30 29 30 30 29 30 29 +1426=29 30 29 30 29 30 30 29 30 30 29 30 +1427=29 29 30 29 30 29 30 30 29 30 30 29 +1428=30 29 29 30 29 29 30 30 30 29 30 30 +1429=29 30 29 29 30 29 29 30 30 29 30 30 +1430=29 30 30 29 29 30 29 30 29 30 29 30 +1431=29 30 30 29 30 29 30 29 30 29 29 30 +1432=29 30 30 30 29 30 29 30 29 30 29 29 +1433=30 29 30 30 29 30 30 29 30 29 30 29 +1434=29 30 29 30 29 30 30 29 30 30 29 29 +1435=30 29 30 29 30 29 30 29 30 30 29 30 +1436=29 30 29 30 29 30 29 30 29 30 29 30 +1437=30 29 30 30 29 29 30 29 30 29 29 30 +1438=30 29 30 30 30 29 29 30 29 29 30 29 +1439=30 29 30 30 30 29 30 29 30 29 29 30 +1440=29 30 29 30 30 30 29 30 29 30 29 29 +1441=30 29 30 29 30 30 29 30 30 29 30 29 +1442=29 30 29 30 29 30 29 30 30 29 30 29 +1443=30 29 30 29 30 29 30 29 30 29 30 30 +1444=29 30 29 30 30 29 29 30 29 30 29 30 +1445=29 30 30 30 29 30 29 29 30 29 29 30 +1446=29 30 30 30 29 30 30 29 29 30 29 29 +1447=30 29 30 30 30 29 30 29 30 29 30 29 +1448=29 30 29 30 30 29 30 30 29 30 29 30 +1449=29 29 30 29 30 29 30 30 29 30 30 29 +1450=30 29 30 29 29 30 29 30 29 30 30 29 +1451=30 30 30 29 29 30 29 29 30 30 29 30 +1452=30 29 30 30 29 29 30 29 29 30 29 30 +1453=30 29 30 30 29 30 29 30 29 29 30 29 +1454=30 29 30 30 29 30 30 29 30 29 30 29 +1455=29 30 29 30 30 29 30 29 30 30 29 30 +1456=29 29 30 29 30 29 30 29 30 30 30 29 +1457=30 29 29 30 29 29 30 29 30 30 30 30 +1458=29 30 29 29 30 29 29 30 29 30 30 30 +1459=29 30 30 29 29 30 29 29 30 29 30 30 +1460=29 30 30 29 30 29 30 29 29 30 29 30 +1461=29 30 30 29 30 29 30 29 30 30 29 29 +1462=30 29 30 29 30 30 29 30 29 30 30 29 +1463=29 30 29 30 29 30 29 30 30 30 29 30 +1464=29 30 29 29 30 29 29 30 30 30 29 30 +1465=30 29 30 29 29 30 29 29 30 30 29 30 +1466=30 30 29 30 29 29 29 30 29 30 30 29 +1467=30 30 29 30 30 29 29 30 29 30 29 30 +1468=29 30 29 30 30 29 30 29 30 29 30 29 +1469=29 30 29 30 30 29 30 30 29 30 29 30 +1470=29 29 30 29 30 30 29 30 30 29 30 29 +1471=30 29 29 30 29 30 29 30 30 29 30 30 +1472=29 30 29 29 30 29 30 29 30 30 29 30 +1473=29 30 29 30 30 29 29 30 29 30 29 30 +1474=29 30 30 29 30 30 29 29 30 29 30 29 +1475=29 30 30 29 30 30 30 29 29 30 29 29 +1476=30 29 30 29 30 30 30 29 30 29 30 29 +1477=29 30 29 29 30 30 30 30 29 30 29 30 +1478=29 29 30 29 30 29 30 30 29 30 30 29 +1479=30 29 29 30 29 30 29 30 29 30 30 29 +1480=30 29 30 29 30 29 30 29 30 29 30 29 +1481=30 29 30 30 29 30 29 30 29 30 29 29 +1482=30 29 30 30 30 30 29 30 29 29 30 29 +1483=29 30 29 30 30 30 29 30 30 29 29 30 +1484=29 29 30 29 30 30 30 29 30 29 30 29 +1485=30 29 29 30 29 30 30 29 30 30 29 30 +1486=29 30 29 29 30 29 30 29 30 30 29 30 +1487=30 29 30 29 30 29 29 30 29 30 29 30 +1488=30 29 30 30 29 30 29 29 30 29 30 29 +1489=30 29 30 30 30 29 30 29 29 30 29 30 +1490=29 30 29 30 30 29 30 30 29 29 30 29 +1491=30 29 29 30 30 29 30 30 29 30 29 30 +1492=29 30 29 29 30 30 29 30 29 30 30 29 +1493=30 29 30 29 30 29 29 30 29 30 30 30 +1494=29 30 29 30 29 30 29 29 29 30 30 30 +1495=29 30 30 29 30 29 29 30 29 29 30 30 +1496=29 30 30 30 29 30 29 29 30 29 29 30 +1497=30 29 30 30 29 30 29 30 29 30 29 30 +1498=29 30 29 30 29 30 30 29 30 29 30 29 +1499=30 29 30 29 29 30 30 29 30 29 30 30 +1500=29 30 29 30 29 29 30 29 30 29 30 30 +1501=30 29 30 29 30 29 29 29 30 29 30 30 +1502=30 30 29 30 29 30 29 29 29 30 30 29 +1503=30 30 29 30 30 29 30 29 29 29 30 30 +1504=29 30 29 30 30 30 29 29 30 29 30 29 +1505=30 29 30 29 30 30 29 30 29 30 30 29 +1506=29 30 29 29 30 30 29 30 30 29 30 30 +1507=29 29 30 29 29 30 30 29 30 29 30 30 +1508=30 29 29 30 29 30 29 29 30 29 30 30 +1509=30 29 30 29 30 29 30 29 29 30 29 30 +1510=30 29 30 30 29 30 29 30 29 29 30 29 +1511=30 29 30 30 29 30 30 29 30 29 29 30 +1512=29 30 29 30 29 30 30 30 29 30 29 30 +1513=29 29 29 30 29 30 30 30 29 30 30 29 +1514=30 29 29 29 30 29 30 30 29 30 30 30 +1515=29 29 30 29 29 30 29 30 30 29 30 30 +1516=29 30 29 30 29 29 30 29 30 29 30 30 +1517=29 30 29 30 29 30 30 29 29 30 29 30 +1518=29 30 29 30 30 29 30 30 29 30 29 29 +1519=30 29 29 30 30 30 29 30 30 29 30 29 +1520=29 30 29 29 30 30 30 29 30 30 29 30 +1521=29 29 29 30 29 30 30 29 30 30 29 30 +1522=30 29 29 29 30 29 30 30 29 30 30 29 +1523=30 29 30 29 30 29 30 29 29 30 30 29 +1524=30 30 29 30 29 30 29 30 29 29 30 29 +1525=30 30 29 30 30 29 30 29 30 29 29 30 +1526=29 30 29 30 30 30 29 30 29 30 29 29 +1527=30 29 30 29 30 30 29 30 30 29 30 29 +1528=30 29 29 30 29 30 29 30 30 29 30 30 +1529=29 30 29 29 30 29 30 29 30 29 30 30 +1530=29 30 30 29 29 30 29 30 29 29 30 30 +1531=29 30 30 30 29 29 30 29 30 29 29 30 +1532=29 30 30 30 29 30 30 29 29 29 30 29 +1533=30 29 30 30 30 29 30 29 30 29 29 30 +1534=29 30 29 30 30 29 30 30 29 29 30 29 +1535=30 29 30 29 30 29 30 30 29 30 29 30 +1536=29 30 29 30 29 30 29 30 29 30 29 30 +1537=30 29 30 30 29 29 30 29 29 30 29 30 +1538=30 30 29 30 30 29 29 30 29 29 30 29 +1539=30 30 30 29 30 30 29 29 30 29 29 30 +1540=29 30 30 29 30 30 29 30 29 29 30 29 +1541=30 29 30 29 30 30 30 29 30 29 29 30 +1542=29 30 29 30 29 30 30 29 30 29 30 30 +1543=29 30 29 29 30 29 30 29 30 29 30 30 +1544=30 29 30 29 29 30 29 30 29 30 29 30 +1545=30 30 29 30 29 29 30 29 30 29 29 30 +1546=30 30 29 30 29 30 29 30 29 30 29 29 +1547=30 30 29 30 30 29 30 29 30 29 30 29 +1548=30 29 29 30 30 29 30 30 29 30 29 30 +1549=29 30 29 29 30 29 30 30 30 29 30 29 +1550=30 29 30 29 29 29 30 30 30 29 30 30 +1551=29 30 29 29 30 29 29 30 30 29 30 30 +1552=30 29 30 29 29 30 29 29 30 30 29 30 +1553=30 29 30 29 30 29 30 29 30 29 30 29 +1554=30 29 30 29 30 30 29 30 29 30 29 30 +1555=29 29 30 29 30 30 29 30 30 29 30 29 +1556=30 29 29 30 29 30 29 30 30 30 29 30 +1557=29 30 29 29 29 30 29 30 30 30 30 29 +1558=30 29 30 29 29 29 30 29 30 30 30 29 +1559=30 30 29 29 30 29 29 30 30 29 30 29 +1560=30 30 29 30 29 30 29 30 29 30 29 30 +1561=29 30 30 29 30 29 30 30 29 29 30 29 +1562=29 30 30 29 30 29 30 30 30 29 29 30 +1563=29 30 29 29 30 29 30 30 30 29 30 29 +1564=30 29 30 29 29 30 29 30 30 30 29 30 +1565=29 30 29 30 29 29 30 29 30 30 29 30 +1566=30 29 30 29 30 29 29 30 29 30 29 30 +1567=30 29 30 30 29 30 29 30 29 29 30 29 +1568=30 29 30 30 30 29 30 29 30 29 29 29 +1569=30 29 30 30 30 29 30 30 29 30 29 29 +1570=29 30 29 30 30 29 30 30 30 29 29 30 +1571=29 29 30 29 30 30 29 30 30 29 30 29 +1572=30 29 29 30 29 30 29 30 30 29 30 29 +1573=30 29 30 30 29 30 29 29 30 29 30 29 +1574=30 30 29 30 30 29 30 29 29 30 29 29 +1575=30 30 30 29 30 30 29 30 29 29 29 30 +1576=29 30 30 29 30 30 30 29 30 29 29 29 +1577=30 29 30 30 29 30 30 29 30 29 30 29 +1578=29 30 29 30 29 30 30 29 30 30 29 30 +1579=29 30 29 30 29 29 30 30 29 30 29 30 +1580=29 30 30 29 30 29 29 30 29 30 29 30 +1581=30 30 29 30 29 30 29 29 30 29 30 29 +1582=30 30 29 30 30 29 30 29 30 29 29 29 +1583=30 30 29 30 30 30 29 30 29 30 29 29 +1584=29 30 30 29 30 30 29 30 30 29 30 29 +1585=29 30 29 30 29 30 29 30 30 29 30 30 +1586=29 29 30 29 30 29 29 30 30 30 29 30 +1587=29 30 30 29 29 29 30 29 30 29 30 30 +1588=30 29 30 30 29 29 29 30 29 30 29 30 +1589=30 29 30 30 29 30 29 29 30 29 30 29 +1590=30 29 30 30 30 29 29 30 29 30 29 30 +1591=29 30 29 30 30 29 30 29 30 29 30 29 +1592=30 29 30 29 30 29 30 29 30 30 30 29 +1593=30 29 29 30 29 29 30 29 30 30 30 29 +1594=30 30 29 29 30 29 29 29 30 30 30 30 +1595=29 30 29 30 29 29 30 29 29 30 30 30 +1596=29 30 30 29 30 29 29 30 29 30 29 30 +1597=29 30 30 29 30 29 30 29 30 29 30 29 +1598=30 29 30 29 30 30 29 30 29 30 30 29 +1599=29 30 29 30 29 30 29 30 30 30 29 30 +1600=29 29 30 29 30 29 29 30 30 30 29 30
--- a/src/share/native/java/io/io_util.c Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/native/java/io/io_util.c Wed Jul 24 08:22:32 2013 -0300 @@ -211,7 +211,11 @@ n = getLastErrorString(buf, sizeof(buf)); if (n > 0) { +#ifdef WIN32 + why = (*env)->NewStringUTF(env, buf); +#else why = JNU_NewStringPlatform(env, buf); +#endif } x = JNU_NewObjectByName(env, "java/io/FileNotFoundException",
--- a/src/share/native/java/net/net_util.c Tue Jul 16 09:09:09 2013 -0300 +++ b/src/share/native/java/net/net_util.c Wed Jul 24 08:22:32 2013 -0300 @@ -75,7 +75,7 @@ static int initialized = 0; -void init(JNIEnv *env) { +static void initInetAddrs(JNIEnv *env) { if (!initialized) { Java_java_net_InetAddress_init(env, 0); Java_java_net_Inet4Address_init(env, 0); @@ -96,42 +96,43 @@ void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); (*env)->SetIntField(env, holder, iac_addressID, address); } void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); (*env)->SetIntField(env, holder, iac_familyID, family); } void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); (*env)->SetObjectField(env, holder, iac_hostNameID, host); } int getInetAddress_addr(JNIEnv *env, jobject iaObj) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); return (*env)->GetIntField(env, holder, iac_addressID); } int getInetAddress_family(JNIEnv *env, jobject iaObj) { jobject holder; - init(env); + + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); return (*env)->GetIntField(env, holder, iac_familyID); } jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); return (*env)->GetObjectField(env, holder, iac_hostNameID); } @@ -139,7 +140,7 @@ JNIEXPORT jobject JNICALL NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) { jobject iaObj; - init(env); + initInetAddrs(env); #ifdef AF_INET6 if (him->sa_family == AF_INET6) { jbyteArray ipaddress;
--- a/src/windows/native/java/io/io_util_md.c Tue Jul 16 09:09:09 2013 -0300 +++ b/src/windows/native/java/io/io_util_md.c Wed Jul 24 08:22:32 2013 -0300 @@ -29,6 +29,7 @@ #include "io_util.h" #include "io_util_md.h" #include <stdio.h> +#include <windows.h> #include <wchar.h> #include <io.h> @@ -40,6 +41,7 @@ #include <limits.h> #include <wincon.h> + static DWORD MAX_INPUT_EVENTS = 2000; /* If this returns NULL then an exception is pending */ @@ -569,42 +571,75 @@ } size_t -getLastErrorString(char *buf, size_t len) +getLastErrorString(char *utf8_jvmErrorMsg, size_t cbErrorMsg) { - DWORD errval; - if (len > 0) { - if ((errval = GetLastError()) != 0) { - // DOS error - size_t n = (size_t)FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - errval, - 0, - buf, - (DWORD)len, - NULL); - if (n > 3) { - // Drop final '.', CR, LF - if (buf[n - 1] == '\n') n--; - if (buf[n - 1] == '\r') n--; - if (buf[n - 1] == '.') n--; - buf[n] = '\0'; + size_t n = 0; + if (cbErrorMsg > 0) { + BOOLEAN noError = FALSE; + WCHAR *utf16_osErrorMsg = (WCHAR *)malloc(cbErrorMsg*sizeof(WCHAR)); + if (utf16_osErrorMsg == NULL) { + // OOM accident + strncpy(utf8_jvmErrorMsg, "Out of memory", cbErrorMsg); + // truncate if too long + utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0'; + n = strlen(utf8_jvmErrorMsg); + } else { + DWORD errval = GetLastError(); + if (errval != 0) { + // WIN32 error + n = (size_t)FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errval, + 0, + utf16_osErrorMsg, + (DWORD)cbErrorMsg, + NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (utf16_osErrorMsg[n - 1] == L'\n') --n; + if (utf16_osErrorMsg[n - 1] == L'\r') --n; + if (utf16_osErrorMsg[n - 1] == L'.') --n; + utf16_osErrorMsg[n] = L'\0'; + } + } else if (errno != 0) { + // C runtime error that has no corresponding WIN32 error code + const WCHAR *rtError = _wcserror(errno); + if (rtError != NULL) { + wcsncpy(utf16_osErrorMsg, rtError, cbErrorMsg); + // truncate if too long + utf16_osErrorMsg[cbErrorMsg - 1] = L'\0'; + n = wcslen(utf16_osErrorMsg); + } + } else + noError = TRUE; //OS has no error to report + + if (!noError) { + if (n > 0) { + n = WideCharToMultiByte( + CP_UTF8, + 0, + utf16_osErrorMsg, + n, + utf8_jvmErrorMsg, + cbErrorMsg, + NULL, + NULL); + + // no way to die + if (n > 0) + utf8_jvmErrorMsg[min(cbErrorMsg - 1, n)] = '\0'; + } + + if (n <= 0) { + strncpy(utf8_jvmErrorMsg, "Secondary error while OS message extraction", cbErrorMsg); + // truncate if too long + utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0'; + n = strlen(utf8_jvmErrorMsg); + } } - return n; - } - - if (errno != 0) { - // C runtime error that has no corresponding DOS error code - const char *err = strerror(errno); - size_t n = strlen(err); - if (n >= len) - n = len - 1; - - strncpy(buf, err, n); - buf[n] = '\0'; - return n; + free(utf16_osErrorMsg); } } - - return 0; + return n; }
--- a/src/windows/native/java/lang/ProcessImpl_md.c Tue Jul 16 09:09:09 2013 -0300 +++ b/src/windows/native/java/lang/ProcessImpl_md.c Wed Jul 24 08:22:32 2013 -0300 @@ -40,20 +40,70 @@ */ #define PIPE_SIZE (4096+24) +/* We have THREE locales in action: + * 1. Thread default locale - dictates UNICODE-to-8bit conversion + * 2. System locale that defines the message localization + * 3. The file name locale + * Each locale could be an extended locale, that means that text cannot be + * mapped to 8bit sequence without multibyte encoding. + * VM is ready for that, if text is UTF-8. + * Here we make the work right from the beginning. + */ +size_t os_error_message(int errnum, WCHAR* utf16_OSErrorMsg, size_t maxMsgLength) { + size_t n = (size_t)FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + (DWORD)errnum, + 0, + utf16_OSErrorMsg, + (DWORD)maxMsgLength, + NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (utf16_OSErrorMsg[n - 1] == L'\n') --n; + if (utf16_OSErrorMsg[n - 1] == L'\r') --n; + if (utf16_OSErrorMsg[n - 1] == L'.') --n; + utf16_OSErrorMsg[n] = L'\0'; + } + return n; +} + +#define MESSAGE_LENGTH (256 + 100) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) + static void -win32Error(JNIEnv *env, const char *functionName) +win32Error(JNIEnv *env, const WCHAR *functionName) { - static const char * const format = "%s error=%d, %s"; - static const char * const fallbackFormat = "%s failed, error=%d"; - char buf[256]; - char errmsg[sizeof(buf) + 100]; - const int errnum = GetLastError(); - const int n = JVM_GetLastErrorString(buf, sizeof(buf)); - if (n > 0) - sprintf(errmsg, format, functionName, errnum, buf); - else - sprintf(errmsg, fallbackFormat, functionName, errnum); - JNU_ThrowIOException(env, errmsg); + WCHAR utf16_OSErrorMsg[MESSAGE_LENGTH - 100]; + WCHAR utf16_javaMessage[MESSAGE_LENGTH]; + /*Good suggestion about 2-bytes-per-symbol in localized error reports*/ + char utf8_javaMessage[MESSAGE_LENGTH*2]; + const int errnum = (int)GetLastError(); + int n = os_error_message(errnum, utf16_OSErrorMsg, ARRAY_SIZE(utf16_OSErrorMsg)); + n = (n > 0) + ? swprintf(utf16_javaMessage, MESSAGE_LENGTH, L"%s error=%d, %s", functionName, errnum, utf16_OSErrorMsg) + : swprintf(utf16_javaMessage, MESSAGE_LENGTH, L"%s failed, error=%d", functionName, errnum); + + if (n > 0) /*terminate '\0' is not a part of conversion procedure*/ + n = WideCharToMultiByte( + CP_UTF8, + 0, + utf16_javaMessage, + n, /*by creation n <= MESSAGE_LENGTH*/ + utf8_javaMessage, + MESSAGE_LENGTH*2, + NULL, + NULL); + + /*no way to die*/ + { + const char *errorMessage = "Secondary error while OS message extraction"; + if (n > 0) { + utf8_javaMessage[min(MESSAGE_LENGTH*2 - 1, n)] = '\0'; + errorMessage = utf8_javaMessage; + } + JNU_ThrowIOException(env, errorMessage); + } } static void @@ -116,7 +166,7 @@ handles[0] = (jlong) -1; } else { if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { - win32Error(env, "CreatePipe"); + win32Error(env, L"CreatePipe"); goto Catch; } si.hStdInput = inRead; @@ -132,7 +182,7 @@ handles[1] = (jlong) -1; } else { if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { - win32Error(env, "CreatePipe"); + win32Error(env, L"CreatePipe"); goto Catch; } si.hStdOutput = outWrite; @@ -151,7 +201,7 @@ handles[2] = (jlong) -1; } else { if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { - win32Error(env, "CreatePipe"); + win32Error(env, L"CreatePipe"); goto Catch; } si.hStdError = errWrite; @@ -174,7 +224,7 @@ &si, /* (in) startup information */ &pi); /* (out) process information */ if (!ret) { - win32Error(env, "CreateProcess"); + win32Error(env, L"CreateProcess"); goto Catch; } @@ -210,7 +260,7 @@ { DWORD exit_code; if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0) - win32Error(env, "GetExitCodeProcess"); + win32Error(env, L"GetExitCodeProcess"); return exit_code; } @@ -231,7 +281,7 @@ FALSE, /* Wait for ANY event */ INFINITE) /* Wait forever */ == WAIT_FAILED) - win32Error(env, "WaitForMultipleObjects"); + win32Error(env, L"WaitForMultipleObjects"); } JNIEXPORT void JNICALL @@ -250,7 +300,7 @@ dwTimeout); /* Wait for dwTimeout */ if (result == WAIT_FAILED) - win32Error(env, "WaitForMultipleObjects"); + win32Error(env, L"WaitForMultipleObjects"); } JNIEXPORT void JNICALL @@ -263,7 +313,7 @@ Java_java_lang_ProcessImpl_isProcessAlive(JNIEnv *env, jclass ignored, jlong handle) { DWORD dwExitStatus; - GetExitCodeProcess(handle, &dwExitStatus); + GetExitCodeProcess((HANDLE) handle, &dwExitStatus); return dwExitStatus == STILL_ACTIVE; }
--- a/test/ProblemList.txt Tue Jul 16 09:09:09 2013 -0300 +++ b/test/ProblemList.txt Wed Jul 24 08:22:32 2013 -0300 @@ -137,6 +137,11 @@ # 8015780 java/lang/reflect/Method/GenericStringTest.java generic-all +# 8019845 due to memleak not related to the tested fix +java/lang/instrument/RedefineBigClass.sh linux-x64 +java/lang/instrument/RetransformBigClass.sh linux-x64 + + ############################################################################ # jdk_management
--- a/test/java/lang/instrument/RedefineBigClass.sh Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/lang/instrument/RedefineBigClass.sh Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -22,7 +22,7 @@ # # @test -# @bug 7121600 +# @bug 7121600 8016838 # @summary Redefine a big class. # @author Daniel D. Daugherty #
--- a/test/java/lang/instrument/RedefineBigClassApp.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/lang/instrument/RedefineBigClassApp.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -21,12 +21,21 @@ * questions. */ +import java.io.*; + public class RedefineBigClassApp { + /** + * Memory leak is assumed, if application consumes more than specified amount of memory during its execution. + * The number is given in Kb. + */ + private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb + public static void main(String[] args) throws Exception { System.out.println("Creating instance of " + RedefineBigClassAgent.clz); RedefineBigClassAgent.clz.newInstance(); + long vMemBefore = getVMemSize(); int count = 0; while (!RedefineBigClassAgent.doneRedefining) { System.out.println("App loop count: " + ++count); @@ -37,6 +46,39 @@ } System.out.println("App looped " + count + " times."); + long vMemAfter = getVMemSize(); + if (vMemBefore == 0 || vMemAfter == 0) { + System.err.println("WARNING: Cannot perform memory leak detection on this OS"); + } else { + long vMemDelta = vMemAfter - vMemBefore; + if (vMemDelta > MEM_LEAK_THRESHOLD) { + System.err.println("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + System.exit(1); + } + System.err.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + } System.exit(0); } + + /** + * Return size of virtual memory allocated to the process in Kb. + * Linux specific. On other platforms and in case of any errors return 0. + */ + private static long getVMemSize() { + + // Refer to the Linux proc(5) man page for details about /proc/self/stat file + // + // In short, this file contains status information about the current process + // written in one line. The fields are separated with spaces. + // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes' + + try (FileReader fileReader = new FileReader("/proc/self/stat"); + BufferedReader bufferedReader = new BufferedReader(fileReader)) { + String line = bufferedReader.readLine(); + return Long.parseLong(line.split(" ")[22]) / 1024; + } catch (Exception ex) {} + return 0; + } }
--- a/test/java/lang/instrument/RetransformBigClass.sh Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/lang/instrument/RetransformBigClass.sh Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -22,7 +22,7 @@ # # @test -# @bug 7122253 +# @bug 7122253 8016838 # @summary Retransform a big class. # @author Daniel D. Daugherty #
--- a/test/java/lang/instrument/RetransformBigClassApp.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/lang/instrument/RetransformBigClassApp.java Wed Jul 24 08:22:32 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -21,12 +21,21 @@ * questions. */ +import java.io.*; + public class RetransformBigClassApp { + /** + * Memory leak is assumed, if application consumes more than specified amount of memory during its execution. + * The number is given in Kb. + */ + private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb + public static void main(String[] args) throws Exception { System.out.println("Creating instance of " + RetransformBigClassAgent.clz); RetransformBigClassAgent.clz.newInstance(); + long vMemBefore = getVMemSize(); int count = 0; while (!RetransformBigClassAgent.doneRetransforming) { System.out.println("App loop count: " + ++count); @@ -37,6 +46,39 @@ } System.out.println("App looped " + count + " times."); + long vMemAfter = getVMemSize(); + if (vMemBefore == 0 || vMemAfter == 0) { + System.err.println("WARNING: Cannot perform memory leak detection on this OS"); + } else { + long vMemDelta = vMemAfter - vMemBefore; + if (vMemDelta > MEM_LEAK_THRESHOLD) { + System.err.println("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + System.exit(1); + } + System.err.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + } System.exit(0); } + + /** + * Return size of virtual memory allocated to the process in Kb. + * Linux specific. On other platforms and in case of any errors return 0. + */ + private static long getVMemSize() { + + // Refer to the Linux proc(5) man page for details about /proc/self/stat file + // + // In short, this file contains status information about the current process + // written in one line. The fields are separated with spaces. + // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes' + + try (FileReader fileReader = new FileReader("/proc/self/stat"); + BufferedReader bufferedReader = new BufferedReader(fileReader)) { + String line = bufferedReader.readLine(); + return Long.parseLong(line.split(" ")[22]) / 1024; + } catch (Exception ex) {} + return 0; + } }
--- a/test/java/time/tck/java/time/MockSimplePeriod.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/MockSimplePeriod.java Wed Jul 24 08:22:32 2013 -0300 @@ -176,7 +176,7 @@ @Override public String toString() { - return amount + " " + unit.getName(); + return amount + " " + unit; } }
--- a/test/java/time/tck/java/time/TCKClock_Fixed.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKClock_Fixed.java Wed Jul 24 08:22:32 2013 -0300 @@ -91,6 +91,7 @@ Clock test = Clock.fixed(INSTANT, PARIS); assertEquals(test.instant(), INSTANT); assertEquals(test.getZone(), PARIS); + assertEquals(test.instant().getEpochSecond()*1000, test.millis()); } @Test(expectedExceptions = NullPointerException.class)
--- a/test/java/time/tck/java/time/TCKDayOfWeek.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKDayOfWeek.java Wed Jul 24 08:22:32 2013 -0300 @@ -159,6 +159,44 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(DayOfWeek.THURSDAY.isSupported((TemporalField) null), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ERA), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test
--- a/test/java/time/tck/java/time/TCKInstant.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKInstant.java Wed Jul 24 08:22:32 2013 -0300 @@ -570,10 +570,6 @@ //----------------------------------------------------------------------- TemporalUnit NINETY_MINS = new TemporalUnit() { @Override - public String getName() { - return "NinetyMins"; - } - @Override public Duration getDuration() { return Duration.ofMinutes(90); } @@ -582,6 +578,49 @@ return false; } @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return true; + } + @Override + public boolean isSupportedBy(Temporal temporal) { + return false; + } + @Override + public <R extends Temporal> R addTo(R temporal, long amount) { + throw new UnsupportedOperationException(); + } + @Override + public long between(Temporal temporal1, Temporal temporal2) { + throw new UnsupportedOperationException(); + } + @Override + public String toString() { + return "NinetyMins"; + } + }; + + TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() { + @Override + public Duration getDuration() { + return Duration.ofMinutes(95); + } + @Override + public boolean isDurationEstimated() { + return false; + } + @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { return false; } @@ -593,33 +632,10 @@ public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException(); } - }; - - TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() { @Override - public String getName() { + public String toString() { return "NinetyFiveMins"; } - @Override - public Duration getDuration() { - return Duration.ofMinutes(95); - } - @Override - public boolean isDurationEstimated() { - return false; - } - @Override - public boolean isSupportedBy(Temporal temporal) { - return false; - } - @Override - public <R extends Temporal> R addTo(R temporal, long amount) { - throw new UnsupportedOperationException(); - } - @Override - public long between(Temporal temporal1, Temporal temporal2) { - throw new UnsupportedOperationException(); - } }; @DataProvider(name="truncatedToValid") @@ -1709,7 +1725,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1805,7 +1821,7 @@ public void test_periodUntil_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); - long amount = i1.periodUntil(i2, unit); + long amount = i1.until(i2, unit); assertEquals(amount, expected); } @@ -1813,23 +1829,23 @@ public void test_periodUntil_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); - long amount = i2.periodUntil(i1, unit); + long amount = i2.until(i1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_12345_123456789.periodUntil(TEST_12345_123456789, MONTHS); + TEST_12345_123456789.until(TEST_12345_123456789, MONTHS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_12345_123456789.periodUntil(null, HOURS); + TEST_12345_123456789.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_12345_123456789.periodUntil(TEST_12345_123456789, null); + TEST_12345_123456789.until(TEST_12345_123456789, null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKLocalDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKLocalDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -620,6 +620,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2007_07_15.isSupported((TemporalField) null), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2007_07_15.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.NANOS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MICROS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MILLIS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.SECONDS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MINUTES), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.HOURS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.HALF_DAYS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -1635,7 +1697,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1684,35 +1746,35 @@ @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { - long amount = date1.periodUntil(date2, unit); + long amount = date1.until(date2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { - long amount = date2.periodUntil(date1, unit); + long amount = date2.until(date1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_2007_07_15.periodUntil(TEST_2007_07_15, HOURS); + TEST_2007_07_15.until(TEST_2007_07_15, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2007_07_15.periodUntil(null, DAYS); + TEST_2007_07_15.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2007_07_15.periodUntil(TEST_2007_07_15, null); + TEST_2007_07_15.until(TEST_2007_07_15, null); } //----------------------------------------------------------------------- - // periodUntil(ChronoLocalDate) + // until(ChronoLocalDate) //----------------------------------------------------------------------- - @DataProvider(name="periodUntil") + @DataProvider(name="until") Object[][] data_periodUntil() { return new Object[][] { {2010, 1, 1, 2010, 1, 1, 0, 0, 0}, @@ -1799,11 +1861,11 @@ }; } - @Test(dataProvider="periodUntil") + @Test(dataProvider="until") public void test_periodUntil_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) { LocalDate start = LocalDate.of(y1, m1, d1); LocalDate end = LocalDate.of(y2, m2, d2); - Period test = start.periodUntil(end); + Period test = start.until(end); assertEquals(test.getYears(), ye); assertEquals(test.getMonths(), me); assertEquals(test.getDays(), de); @@ -1812,12 +1874,12 @@ @Test public void test_periodUntil_LocalDate_max() { int years = Math.toIntExact((long) Year.MAX_VALUE - (long) Year.MIN_VALUE); - assertEquals(LocalDate.MIN.periodUntil(LocalDate.MAX), Period.of(years, 11, 30)); + assertEquals(LocalDate.MIN.until(LocalDate.MAX), Period.of(years, 11, 30)); } @Test(expectedExceptions=NullPointerException.class) public void test_periodUntil_LocalDate_null() { - TEST_2007_07_15.periodUntil(null); + TEST_2007_07_15.until(null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKLocalDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKLocalDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -938,6 +938,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported((TemporalField) null), false); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -2717,7 +2779,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -2859,24 +2921,24 @@ @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { - long amount = dt1.periodUntil(dt2, unit); + long amount = dt1.until(dt2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { - long amount = dt2.periodUntil(dt1, unit); + long amount = dt2.until(dt1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2007_07_15_12_30_40_987654321.periodUntil(null, HOURS); + TEST_2007_07_15_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2007_07_15_12_30_40_987654321.periodUntil(TEST_2007_07_15_12_30_40_987654321, null); + TEST_2007_07_15_12_30_40_987654321.until(TEST_2007_07_15_12_30_40_987654321, null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKLocalTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKLocalTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -620,6 +620,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_12_30_40_987654321.isSupported((TemporalField) null), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ERA), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_12_30_40_987654321.isSupported((TemporalUnit) null), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.YEARS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DECADES), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.ERAS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -953,10 +1015,6 @@ //----------------------------------------------------------------------- TemporalUnit NINETY_MINS = new TemporalUnit() { @Override - public String getName() { - return "NinetyMins"; - } - @Override public Duration getDuration() { return Duration.ofMinutes(90); } @@ -965,6 +1023,49 @@ return false; } @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return true; + } + @Override + public boolean isSupportedBy(Temporal temporal) { + return false; + } + @Override + public <R extends Temporal> R addTo(R temporal, long amount) { + throw new UnsupportedOperationException(); + } + @Override + public long between(Temporal temporal1, Temporal temporal2) { + throw new UnsupportedOperationException(); + } + @Override + public String toString() { + return "NinetyMins"; + } + }; + + TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() { + @Override + public Duration getDuration() { + return Duration.ofMinutes(95); + } + @Override + public boolean isDurationEstimated() { + return false; + } + @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { return false; } @@ -976,33 +1077,10 @@ public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException(); } - }; - - TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() { @Override - public String getName() { + public String toString() { return "NinetyFiveMins"; } - @Override - public Duration getDuration() { - return Duration.ofMinutes(95); - } - @Override - public boolean isDurationEstimated() { - return false; - } - @Override - public boolean isSupportedBy(Temporal temporal) { - return false; - } - @Override - public <R extends Temporal> R addTo(R temporal, long amount) { - throw new UnsupportedOperationException(); - } - @Override - public long between(Temporal temporal1, Temporal temporal2) { - throw new UnsupportedOperationException(); - } }; @DataProvider(name="truncatedToValid") @@ -1922,7 +2000,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1962,29 +2040,29 @@ @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { - long amount = time1.periodUntil(time2, unit); + long amount = time1.until(time2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { - long amount = time2.periodUntil(time1, unit); + long amount = time2.until(time1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_12_30_40_987654321.periodUntil(TEST_12_30_40_987654321, DAYS); + TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_12_30_40_987654321.periodUntil(null, HOURS); + TEST_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_12_30_40_987654321.periodUntil(TEST_12_30_40_987654321, null); + TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKMonth.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKMonth.java Wed Jul 24 08:22:32 2013 -0300 @@ -151,6 +151,44 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(Month.AUGUST.isSupported((TemporalField) null), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(Month.AUGUST.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ERA), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test
--- a/test/java/time/tck/java/time/TCKMonthDay.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKMonthDay.java Wed Jul 24 08:22:32 2013 -0300 @@ -388,6 +388,44 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_07_15.isSupported((TemporalField) null), false); + assertEquals(TEST_07_15.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_07_15.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_07_15.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_07_15.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_07_15.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_07_15.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_07_15.isSupported(ChronoField.YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ERA), false); + assertEquals(TEST_07_15.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_07_15.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test
--- a/test/java/time/tck/java/time/TCKOffsetDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKOffsetDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -126,6 +126,7 @@ import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -555,6 +556,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported((TemporalField) null), false); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.INSTANT_SECONDS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.OFFSET_SECONDS), true); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -1203,6 +1266,7 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1214,6 +1278,7 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1225,6 +1290,7 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1236,6 +1302,7 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1247,6 +1314,7 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1258,6 +1326,7 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1269,6 +1338,14 @@ assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); + } + + @Test + public void test_compareTo_bothInstantComparator() { + OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 20, 40, 4, OFFSET_PTWO); + OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 10, 20, 40, 5, OFFSET_PONE); + assertEquals(a.compareTo(b), OffsetDateTime.timeLineOrder().compare(a,b), "for nano != nano, compareTo and timeLineOrder() should be the same"); } @Test
--- a/test/java/time/tck/java/time/TCKOffsetTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKOffsetTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -543,6 +543,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_11_30_59_500_PONE.isSupported((TemporalField) null), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ERA), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.OFFSET_SECONDS), true); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_11_30_59_500_PONE.isSupported((TemporalUnit) null), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MONTHS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.YEARS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.DECADES), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.CENTURIES), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MILLENNIA), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.ERAS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -1038,7 +1100,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1063,13 +1125,13 @@ @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { - long amount = offsetTime1.periodUntil(offsetTime2, unit); + long amount = offsetTime1.until(offsetTime2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { - long amount = offsetTime2.periodUntil(offsetTime1, unit); + long amount = offsetTime2.until(offsetTime1, unit); assertEquals(amount, -expected); } @@ -1077,14 +1139,14 @@ public void test_periodUntil_InvalidType() { OffsetTime offsetTime = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(1980, 2, 10)); - offsetTime.periodUntil(offsetDateTime, SECONDS); + offsetTime.until(offsetDateTime, SECONDS); } @Test(expectedExceptions=DateTimeException.class) public void test_periodUntil_InvalidTemporalUnit() { OffsetTime offsetTime1 = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); OffsetTime offsetTime2 = OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)); - offsetTime1.periodUntil(offsetTime2, MONTHS); + offsetTime1.until(offsetTime2, MONTHS); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKPeriod.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKPeriod.java Wed Jul 24 08:22:32 2013 -0300 @@ -121,10 +121,23 @@ } //----------------------------------------------------------------------- + // ofWeeks(int) + //----------------------------------------------------------------------- + @Test + public void factory_ofWeeks_int() { + assertPeriod(Period.ofWeeks(0), 0, 0, 0); + assertPeriod(Period.ofWeeks(1), 0, 0, 7); + assertPeriod(Period.ofWeeks(234), 0, 0, 234 * 7); + assertPeriod(Period.ofWeeks(-100), 0, 0, -100 * 7); + assertPeriod(Period.ofWeeks(Integer.MAX_VALUE / 7), 0, 0, (Integer.MAX_VALUE / 7) * 7); + assertPeriod(Period.ofWeeks(Integer.MIN_VALUE / 7), 0, 0, (Integer.MIN_VALUE / 7) * 7); + } + + //----------------------------------------------------------------------- // ofDays(int) //----------------------------------------------------------------------- @Test - public void factory_ofDay_int() { + public void factory_ofDays_int() { assertPeriod(Period.ofDays(0), 0, 0, 0); assertPeriod(Period.ofDays(1), 0, 0, 1); assertPeriod(Period.ofDays(234), 0, 0, 234); @@ -251,6 +264,18 @@ {"P" + Integer.MAX_VALUE + "M", Period.ofMonths(Integer.MAX_VALUE)}, {"P" + Integer.MIN_VALUE + "M", Period.ofMonths(Integer.MIN_VALUE)}, + {"P1W", Period.ofDays(1 * 7)}, + {"P12W", Period.ofDays(12 * 7)}, + {"P7654321W", Period.ofDays(7654321 * 7)}, + {"P+1W", Period.ofDays(1 * 7)}, + {"P+12W", Period.ofDays(12 * 7)}, + {"P+7654321W", Period.ofDays(7654321 * 7)}, + {"P+0W", Period.ofDays(0)}, + {"P0W", Period.ofDays(0)}, + {"P-0W", Period.ofDays(0)}, + {"P-25W", Period.ofDays(-25 * 7)}, + {"P-7654321W", Period.ofDays(-7654321 * 7)}, + {"P1D", Period.ofDays(1)}, {"P12D", Period.ofDays(12)}, {"P987654321D", Period.ofDays(987654321)}, @@ -274,6 +299,10 @@ {"P2Y-3M25D", Period.of(2, -3, 25)}, {"P2Y3M-25D", Period.of(2, 3, -25)}, {"P-2Y-3M-25D", Period.of(-2, -3, -25)}, + + {"P0Y0M0W0D", Period.of(0, 0, 0)}, + {"P2Y3M4W25D", Period.of(2, 3, 4 * 7 + 25)}, + {"P-2Y-3M-4W-25D", Period.of(-2, -3, -4 * 7 - 25)}, }; } @@ -334,6 +363,13 @@ {"P1Y2Y"}, {"PT1M+3S"}, + {"P1M2Y"}, + {"P1W2Y"}, + {"P1D2Y"}, + {"P1W2M"}, + {"P1D2M"}, + {"P1D2W"}, + {"PT1S1"}, {"PT1S."}, {"PT1SA"},
--- a/test/java/time/tck/java/time/TCKYear.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKYear.java Wed Jul 24 08:22:32 2013 -0300 @@ -348,6 +348,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2008.isSupported((TemporalField) null), false); + assertEquals(TEST_2008.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_2008.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_2008.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_2008.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_2008.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_2008.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_2008.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_2008.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2008.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2008.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2008.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2008.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2008.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.NANOS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MICROS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MILLIS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.SECONDS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MINUTES), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.HOURS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.HALF_DAYS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MONTHS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -829,7 +891,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -881,29 +943,29 @@ @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) { - long amount = year1.periodUntil(year2, unit); + long amount = year1.until(year2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) { - long amount = year2.periodUntil(year1, unit); + long amount = year2.until(year1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_2008.periodUntil(TEST_2008, MONTHS); + TEST_2008.until(TEST_2008, MONTHS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2008.periodUntil(null, DAYS); + TEST_2008.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2008.periodUntil(TEST_2008, null); + TEST_2008.until(TEST_2008, null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKYearMonth.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKYearMonth.java Wed Jul 24 08:22:32 2013 -0300 @@ -408,6 +408,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2008_06.isSupported((TemporalField) null), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2008_06.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.NANOS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MICROS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MILLIS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.SECONDS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MINUTES), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.HOURS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.HALF_DAYS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -1120,7 +1182,7 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1200,29 +1262,29 @@ @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { - long amount = ym1.periodUntil(ym2, unit); + long amount = ym1.until(ym2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { - long amount = ym2.periodUntil(ym1, unit); + long amount = ym2.until(ym1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_2008_06.periodUntil(TEST_2008_06, HOURS); + TEST_2008_06.until(TEST_2008_06, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2008_06.periodUntil(null, DAYS); + TEST_2008_06.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2008_06.periodUntil(TEST_2008_06, null); + TEST_2008_06.until(TEST_2008_06, null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKZoneId.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKZoneId.java Wed Jul 24 08:22:32 2013 -0300 @@ -465,6 +465,53 @@ } //----------------------------------------------------------------------- + @DataProvider(name="prefixValid") + Object[][] data_prefixValid() { + return new Object[][] { + {"GMT", "+01:00"}, + {"UTC", "+01:00"}, + {"UT", "+01:00"}, + {"", "+01:00"}, + }; + } + + @Test(dataProvider="prefixValid") + public void test_prefixOfOffset(String prefix, String offset) { + ZoneOffset zoff = ZoneOffset.of(offset); + ZoneId zoneId = ZoneId.ofOffset(prefix, zoff); + assertEquals(zoneId.getId(), prefix + zoff.getId(), "in correct id for : " + prefix + ", zoff: " + zoff); + + } + + //----------------------------------------------------------------------- + @DataProvider(name="prefixInvalid") + Object[][] data_prefixInvalid() { + return new Object[][] { + {"GM", "+01:00"}, + {"U", "+01:00"}, + {"UTC0", "+01:00"}, + {"A", "+01:00"}, + }; + } + + @Test(dataProvider="prefixInvalid", expectedExceptions=java.lang.IllegalArgumentException.class) + public void test_invalidPrefixOfOffset(String prefix, String offset) { + ZoneOffset zoff = ZoneOffset.of(offset); + ZoneId zoneId = ZoneId.ofOffset(prefix, zoff); + fail("should have thrown an exception for prefix: " + prefix); + } + + @Test(expectedExceptions=java.lang.NullPointerException.class) + public void test_nullPrefixOfOffset() { + ZoneId.ofOffset(null, ZoneOffset.ofTotalSeconds(1)); + } + + @Test(expectedExceptions=java.lang.NullPointerException.class) + public void test_nullOffsetOfOffset() { + ZoneId.ofOffset("GMT", null); + } + + //----------------------------------------------------------------------- @DataProvider(name="offsetBasedValidOther") Object[][] data_offsetBasedValidOther() { return new Object[][] {
--- a/test/java/time/tck/java/time/TCKZonedDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/TCKZonedDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -127,6 +127,7 @@ import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -723,10 +724,12 @@ public boolean isSupported(TemporalField field) { return TEST_DATE_TIME_PARIS.toLocalDateTime().isSupported(field); } + @Override public long getLong(TemporalField field) { return TEST_DATE_TIME_PARIS.toLocalDateTime().getLong(field); } + @SuppressWarnings("unchecked") @Override public <R> R query(TemporalQuery<R> query) { @@ -791,17 +794,18 @@ @DataProvider(name="parseAdditional") Object[][] data_parseAdditional() { return new Object[][] { - {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, - {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, - {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, + {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "GMT"}, + {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "UT"}, + {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "UTC"}, + {"2012-06-30T12:30:40+01:00[Z]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, {"2012-06-30T12:30:40+01:00[+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, - {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, - {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, - {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, + {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT+01:00"}, + {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT+01:00"}, + {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC+01:00"}, {"2012-06-30T12:30:40-01:00[-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, - {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, - {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, - {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, + {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT-01:00"}, + {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT-01:00"}, + {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC-01:00"}, {"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"}, }; } @@ -900,6 +904,68 @@ } //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_DATE_TIME.isSupported((TemporalField) null), false); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ERA), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.INSTANT_SECONDS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.OFFSET_SECONDS), true); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_DATE_TIME.isSupported((TemporalUnit) null), false); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.FOREVER), false); + } + + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @Test @@ -1977,37 +2043,37 @@ } //----------------------------------------------------------------------- - // periodUntil(Temporal,TemporalUnit) + // until(Temporal,TemporalUnit) //----------------------------------------------------------------------- // TODO: more tests for period between two different zones - // compare results to OffsetDateTime.periodUntil, especially wrt dates + // compare results to OffsetDateTime.until, especially wrt dates @Test(dataProvider="plusDays") public void test_periodUntil_days(ZonedDateTime base, long expected, ZonedDateTime end) { if (base.toLocalTime().equals(end.toLocalTime()) == false) { return; // avoid DST gap input values } - assertEquals(base.periodUntil(end, DAYS), expected); + assertEquals(base.until(end, DAYS), expected); } @Test(dataProvider="plusTime") public void test_periodUntil_hours(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, HOURS), expected); + assertEquals(base.until(end, HOURS), expected); } @Test(dataProvider="plusTime") public void test_periodUntil_minutes(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, MINUTES), expected * 60); + assertEquals(base.until(end, MINUTES), expected * 60); } @Test(dataProvider="plusTime") public void test_periodUntil_seconds(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, SECONDS), expected * 3600); + assertEquals(base.until(end, SECONDS), expected * 3600); } @Test(dataProvider="plusTime") public void test_periodUntil_nanos(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, NANOS), expected * 3600_000_000_000L); + assertEquals(base.until(end, NANOS), expected * 3600_000_000_000L); } @Test @@ -2017,13 +2083,13 @@ ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS); ZonedDateTime midnightParis2 = LocalDate.of(2012, 6, 30).atStartOfDay(ZONE_PARIS); - assertEquals(midnightLondon.periodUntil(midnightParis1, HOURS), 23); - assertEquals(midnightLondon.periodUntil(oneAm1, HOURS), 24); - assertEquals(midnightLondon.periodUntil(midnightParis2, HOURS), 23 + 24); + assertEquals(midnightLondon.until(midnightParis1, HOURS), 23); + assertEquals(midnightLondon.until(oneAm1, HOURS), 24); + assertEquals(midnightLondon.until(midnightParis2, HOURS), 23 + 24); - assertEquals(midnightLondon.periodUntil(midnightParis1, DAYS), 0); - assertEquals(midnightLondon.periodUntil(oneAm1, DAYS), 1); - assertEquals(midnightLondon.periodUntil(midnightParis2, DAYS), 1); + assertEquals(midnightLondon.until(midnightParis1, DAYS), 0); + assertEquals(midnightLondon.until(oneAm1, DAYS), 1); + assertEquals(midnightLondon.until(midnightParis2, DAYS), 1); } @Test @@ -2031,8 +2097,8 @@ ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); - assertEquals(before.periodUntil(after, HOURS), 23); - assertEquals(before.periodUntil(after, DAYS), 1); + assertEquals(before.until(after, HOURS), 23); + assertEquals(before.until(after, DAYS), 1); } @Test @@ -2040,23 +2106,23 @@ ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); - assertEquals(before.periodUntil(after, HOURS), 25); - assertEquals(before.periodUntil(after, DAYS), 1); + assertEquals(before.until(after, HOURS), 25); + assertEquals(before.until(after, DAYS), 1); } @Test(expectedExceptions=DateTimeException.class) public void test_periodUntil_differentType() { - TEST_DATE_TIME_PARIS.periodUntil(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS); + TEST_DATE_TIME_PARIS.until(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS); } @Test(expectedExceptions=NullPointerException.class) public void test_periodUntil_nullTemporal() { - TEST_DATE_TIME_PARIS.periodUntil(null, DAYS); + TEST_DATE_TIME_PARIS.until(null, DAYS); } @Test(expectedExceptions=NullPointerException.class) public void test_periodUntil_nullUnit() { - TEST_DATE_TIME_PARIS.periodUntil(TEST_DATE_TIME_PARIS, null); + TEST_DATE_TIME_PARIS.until(TEST_DATE_TIME_PARIS, null); } //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/chrono/CopticDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/CopticDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -87,7 +87,7 @@ * This class is immutable and thread-safe. */ public final class CopticDate - implements ChronoLocalDate<CopticDate>, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -202,7 +202,7 @@ } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -224,7 +224,7 @@ case YEAR: return prolepticYear; case ERA: return (prolepticYear >= 1 ? 1 : 0); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -249,7 +249,7 @@ case YEAR: return resolvePreviousValid(nvalue, month, day); case ERA: return resolvePreviousValid(1 - prolepticYear, month, day); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -268,7 +268,7 @@ case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100)); case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -297,22 +297,22 @@ } @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoLocalDate == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } - ChronoLocalDate<?> end = (ChronoLocalDate<?>) endDateTime; + ChronoLocalDate end = (ChronoLocalDate) endDateTime; if (getChronology().equals(end.getChronology()) == false) { throw new DateTimeException("Unable to calculate period between two different chronologies"); } if (unit instanceof ChronoUnit) { - return LocalDate.from(this).periodUntil(end, unit); // TODO: this is wrong + return LocalDate.from(this).until(end, unit); // TODO: this is wrong } return unit.between(this, endDateTime); } @Override - public Period periodUntil(ChronoLocalDate<?> endDate) { + public Period until(ChronoLocalDate endDate) { // TODO: untested CopticDate end = (CopticDate) getChronology().date(endDate); long totalMonths = (end.prolepticYear - this.prolepticYear) * 13 + (end.month - this.month); // safe
--- a/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -113,10 +113,10 @@ @Test(dataProvider="calendars") public void test_badWithAdjusterChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate<?> date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalAdjuster adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { @@ -127,7 +127,7 @@ } } else { // Same chronology, - ChronoLocalDate<?> result = date.with(adjuster); + ChronoLocalDate result = date.with(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -136,10 +136,10 @@ @Test(dataProvider="calendars") public void test_badPlusAdjusterChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate<?> date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalAmount adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { @@ -150,7 +150,7 @@ } } else { // Same chronology, - ChronoLocalDate<?> result = date.plus(adjuster); + ChronoLocalDate result = date.plus(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -159,10 +159,10 @@ @Test(dataProvider="calendars") public void test_badMinusAdjusterChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate<?> date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalAmount adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { @@ -173,7 +173,7 @@ } } else { // Same chronology, - ChronoLocalDate<?> result = date.minus(adjuster); + ChronoLocalDate result = date.minus(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -182,10 +182,10 @@ @Test(dataProvider="calendars") public void test_badPlusTemporalUnitChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate<?> date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalUnit adjuster = new FixedTemporalUnit(date2); if (chrono != chrono2) { try { @@ -197,7 +197,7 @@ } } else { // Same chronology, - ChronoLocalDate<?> result = date.plus(1, adjuster); + ChronoLocalDate result = date.plus(1, adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -206,10 +206,10 @@ @Test(dataProvider="calendars") public void test_badMinusTemporalUnitChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate<?> date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalUnit adjuster = new FixedTemporalUnit(date2); if (chrono != chrono2) { try { @@ -221,7 +221,7 @@ } } else { // Same chronology, - ChronoLocalDate<?> result = date.minus(1, adjuster); + ChronoLocalDate result = date.minus(1, adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -230,10 +230,10 @@ @Test(dataProvider="calendars") public void test_badTemporalFieldChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate<?> date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalField adjuster = new FixedTemporalField(date2); if (chrono != chrono2) { try { @@ -245,7 +245,7 @@ } } else { // Same chronology, - ChronoLocalDate<?> result = date.with(adjuster, 1); + ChronoLocalDate result = date.with(adjuster, 1); assertEquals(result, date2, "TemporalField doSet failed to replace date"); } } @@ -258,7 +258,7 @@ public void test_date_comparisons(Chronology chrono) { List<ChronoLocalDate> dates = new ArrayList<>(); - ChronoLocalDate<?> date = chrono.date(LocalDate.of(2013, 1, 1)); + ChronoLocalDate date = chrono.date(LocalDate.of(2013, 1, 1)); // Insert dates in order, no duplicates dates.add(date.minus(1, ChronoUnit.YEARS)); @@ -273,17 +273,17 @@ // Check these dates against the corresponding dates for every calendar for (Chronology[] clist : data_of_calendars()) { - List<ChronoLocalDate<?>> otherDates = new ArrayList<>(); + List<ChronoLocalDate> otherDates = new ArrayList<>(); Chronology chrono2 = clist[0]; - for (ChronoLocalDate<?> d : dates) { + for (ChronoLocalDate d : dates) { otherDates.add(chrono2.date(d)); } // Now compare the sequence of original dates with the sequence of converted dates for (int i = 0; i < dates.size(); i++) { - ChronoLocalDate<?> a = dates.get(i); + ChronoLocalDate a = dates.get(i); for (int j = 0; j < otherDates.size(); j++) { - ChronoLocalDate<?> b = otherDates.get(j); + ChronoLocalDate b = otherDates.get(j); int cmp = ChronoLocalDate.timeLineOrder().compare(a, b); if (i < j) { assertTrue(cmp < 0, a + " compare " + b); @@ -312,7 +312,7 @@ @Test( dataProvider="calendars") public void test_ChronoSerialization(Chronology chrono) throws Exception { LocalDate ref = LocalDate.of(2013, 1, 5); - ChronoLocalDate<?> orginal = chrono.date(ref); + ChronoLocalDate orginal = chrono.date(ref); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(orginal); @@ -320,7 +320,7 @@ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); @SuppressWarnings("unchecked") - ChronoLocalDate<?> ser = (ChronoLocalDate<?>) in.readObject(); + ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); assertEquals(ser, orginal, "deserialized date is wrong"); } @@ -328,12 +328,12 @@ @Test(dataProvider="calendars") public void test_from_TemporalAccessor(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate<?> date = chrono.date(refDate); - ChronoLocalDate<?> test1 = ChronoLocalDate.from(date); + ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate test1 = ChronoLocalDate.from(date); assertEquals(test1, date); - ChronoLocalDate<?> test2 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30))); + ChronoLocalDate test2 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30))); assertEquals(test2, date); - ChronoLocalDate<?> test3 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30)).atZone(ZoneOffset.UTC)); + ChronoLocalDate test3 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30)).atZone(ZoneOffset.UTC)); assertEquals(test3, date); } @@ -397,11 +397,6 @@ } @Override - public String getName() { - return "FixedTemporalUnit"; - } - - @Override public Duration getDuration() { throw new UnsupportedOperationException("Not supported yet."); } @@ -412,6 +407,16 @@ } @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(Temporal temporal) { throw new UnsupportedOperationException("Not supported yet."); } @@ -426,6 +431,11 @@ public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String toString() { + return "FixedTemporalUnit"; + } } /** @@ -439,11 +449,6 @@ } @Override - public String getName() { - return "FixedTemporalField"; - } - - @Override public TemporalUnit getBaseUnit() { throw new UnsupportedOperationException("Not supported yet."); } @@ -459,6 +464,16 @@ } @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(TemporalAccessor temporal) { throw new UnsupportedOperationException("Not supported yet."); } @@ -478,5 +493,10 @@ public <R extends Temporal> R adjustInto(R temporal, long newValue) { return (R) this.temporal; } + + @Override + public String toString() { + return "FixedTemporalField"; + } } }
--- a/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -411,11 +411,6 @@ } @Override - public String getName() { - return "FixedTemporalUnit"; - } - - @Override public Duration getDuration() { throw new UnsupportedOperationException("Not supported yet."); } @@ -426,6 +421,16 @@ } @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(Temporal temporal) { throw new UnsupportedOperationException("Not supported yet."); } @@ -440,6 +445,11 @@ public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String toString() { + return "FixedTemporalUnit"; + } } /** @@ -453,11 +463,6 @@ } @Override - public String getName() { - return "FixedTemporalField"; - } - - @Override public TemporalUnit getBaseUnit() { throw new UnsupportedOperationException("Not supported yet."); } @@ -473,6 +478,16 @@ } @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(TemporalAccessor temporal) { throw new UnsupportedOperationException("Not supported yet."); } @@ -492,5 +507,10 @@ public <R extends Temporal> R adjustInto(R temporal, long newValue) { return (R) this.temporal; } + + @Override + public String toString() { + return "FixedTemporalField"; + } } }
--- a/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java Wed Jul 24 08:22:32 2013 -0300 @@ -256,7 +256,7 @@ } //----------------------------------------------------------------------- - // isBefore, isAfter, isEqual, INSTANT_COMPARATOR test a Chronology against the other Chronos + // isBefore, isAfter, isEqual, timeLineOrder() test a Chronology against the other Chronos //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_zonedDateTime_comparisons(Chronology chrono) { @@ -413,11 +413,6 @@ } @Override - public String getName() { - return "FixedTemporalUnit"; - } - - @Override public Duration getDuration() { throw new UnsupportedOperationException("Not supported yet."); } @@ -428,6 +423,16 @@ } @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(Temporal temporal) { throw new UnsupportedOperationException("Not supported yet."); } @@ -442,6 +447,12 @@ public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String toString() { + return "FixedTemporalUnit"; + } + } /** @@ -455,11 +466,6 @@ } @Override - public String getName() { - return "FixedTemporalField"; - } - - @Override public TemporalUnit getBaseUnit() { throw new UnsupportedOperationException("Not supported yet."); } @@ -475,6 +481,16 @@ } @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + + @Override public boolean isSupportedBy(TemporalAccessor temporal) { throw new UnsupportedOperationException("Not supported yet."); } @@ -494,5 +510,10 @@ public <R extends Temporal> R adjustInto(R temporal, long newValue) { return (R) this.temporal; } + + @Override + public String toString() { + return "FixedTemporalField"; + } } }
--- a/test/java/time/tck/java/time/chrono/TCKChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -64,18 +64,27 @@ import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; +import java.util.Locale; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.time.ZoneId; +import java.time.Clock; import java.time.DateTimeException; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; +import java.time.chrono.HijrahEra; import java.time.chrono.IsoChronology; +import java.time.chrono.IsoEra; import java.time.chrono.JapaneseChronology; +import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoChronology; +import java.time.chrono.MinguoEra; import java.time.chrono.ThaiBuddhistChronology; +import java.time.chrono.ThaiBuddhistEra; +import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.util.Locale; import java.util.Set; @@ -133,15 +142,35 @@ + ", expected >= " + data_of_calendars().length); } + //----------------------------------------------------------------------- + // getDisplayName() + //----------------------------------------------------------------------- + @DataProvider(name = "calendarDisplayName") + Object[][] data_of_calendarDisplayNames() { + return new Object[][] { + {"Hijrah", "Hijrah-umalqura"}, + {"ISO", "ISO"}, + {"Japanese", "Japanese Calendar"}, + {"Minguo", "Minguo Calendar"}, + {"ThaiBuddhist", "Buddhist Calendar"}, + }; + } + + @Test(dataProvider = "calendarDisplayName") + public void test_getDisplayName(String chronoId, String calendarDisplayName) { + Chronology chrono = Chronology.of(chronoId); + assertEquals(chrono.getDisplayName(TextStyle.FULL, Locale.ENGLISH), calendarDisplayName); + } + /** * Compute the number of days from the Epoch and compute the date from the number of days. */ @Test(dataProvider = "calendarNameAndType") public void test_epoch(String name, String alias) { Chronology chrono = Chronology.of(name); // a chronology. In practice this is rarely hardcoded - ChronoLocalDate<?> date1 = chrono.dateNow(); + ChronoLocalDate date1 = chrono.dateNow(); long epoch1 = date1.getLong(ChronoField.EPOCH_DAY); - ChronoLocalDate<?> date2 = date1.with(ChronoField.EPOCH_DAY, epoch1); + ChronoLocalDate date2 = date1.with(ChronoField.EPOCH_DAY, epoch1); assertEquals(date1, date2, "Date from epoch day is not same date: " + date1 + " != " + date2); long epoch2 = date1.getLong(ChronoField.EPOCH_DAY); assertEquals(epoch1, epoch2, "Epoch day not the same: " + epoch1 + " != " + epoch2); @@ -150,9 +179,9 @@ @Test(dataProvider = "calendarNameAndType") public void test_dateEpochDay(String name, String alias) { Chronology chrono = Chronology.of(name); - ChronoLocalDate<?> date = chrono.dateNow(); + ChronoLocalDate date = chrono.dateNow(); long epochDay = date.getLong(ChronoField.EPOCH_DAY); - ChronoLocalDate<?> test = chrono.dateEpochDay(epochDay); + ChronoLocalDate test = chrono.dateEpochDay(epochDay); assertEquals(test, date); } @@ -184,6 +213,101 @@ assertEquals(Chronology.ofLocale(locale), chrono); } + //----------------------------------------------------------------------- + // dateNow() + //----------------------------------------------------------------------- + @Test + public void test_MinguoChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("Minguo"); + assertEquals(chrono.dateNow(), MinguoChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), MinguoChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), MinguoChronology.INSTANCE.dateNow(clock)); + } + + @Test + public void test_IsoChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("ISO"); + assertEquals(chrono.dateNow(), IsoChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), IsoChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), IsoChronology.INSTANCE.dateNow(clock)); + } + + @Test + public void test_JapaneseChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("Japanese"); + assertEquals(chrono.dateNow(), JapaneseChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), JapaneseChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), JapaneseChronology.INSTANCE.dateNow(clock)); + } + + @Test + public void test_ThaiBuddhistChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("ThaiBuddhist"); + assertEquals(chrono.dateNow(), ThaiBuddhistChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), ThaiBuddhistChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), ThaiBuddhistChronology.INSTANCE.dateNow(clock)); + } + + //----------------------------------------------------------------------- + // dateYearDay() and date() + //----------------------------------------------------------------------- + @Test + public void test_HijrahChronology_dateYearDay() { + Chronology chrono = Chronology.of("Hijrah"); + ChronoLocalDate date1 = chrono.dateYearDay(HijrahEra.AH, 1434, 178); + ChronoLocalDate date2 = chrono.date(HijrahEra.AH, 1434, 7, 1); + assertEquals(date1, HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178)); + assertEquals(date2, HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178)); + } + + @Test + public void test_MinguoChronology_dateYearDay() { + Chronology chrono = Chronology.of("Minguo"); + ChronoLocalDate date1 = chrono.dateYearDay(MinguoEra.ROC, 5, 60); + ChronoLocalDate date2 = chrono.date(MinguoEra.ROC, 5, 2, 29); + assertEquals(date1, MinguoChronology.INSTANCE.dateYearDay(MinguoEra.ROC, 5, 60)); + assertEquals(date2, MinguoChronology.INSTANCE.dateYearDay(MinguoEra.ROC, 5, 60)); + } + + @Test + public void test_IsoChronology_dateYearDay() { + Chronology chrono = Chronology.of("ISO"); + ChronoLocalDate date1 = chrono.dateYearDay(IsoEra.CE, 5, 60); + ChronoLocalDate date2 = chrono.date(IsoEra.CE, 5, 3, 1); + assertEquals(date1, IsoChronology.INSTANCE.dateYearDay(IsoEra.CE, 5, 60)); + assertEquals(date2, IsoChronology.INSTANCE.dateYearDay(IsoEra.CE, 5, 60)); + } + + @Test + public void test_JapaneseChronology_dateYearDay() { + Chronology chrono = Chronology.of("Japanese"); + ChronoLocalDate date1 = chrono.dateYearDay(JapaneseEra.HEISEI, 8, 60); + ChronoLocalDate date2 = chrono.date(JapaneseEra.HEISEI, 8, 2, 29); + assertEquals(date1, JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 8, 60)); + assertEquals(date2, JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 8, 60)); + } + + @Test + public void test_ThaiBuddhistChronology_dateYearDay() { + Chronology chrono = Chronology.of("ThaiBuddhist"); + ChronoLocalDate date1 = chrono.dateYearDay(ThaiBuddhistEra.BE, 2459, 60); + ChronoLocalDate date2 = chrono.date(ThaiBuddhistEra.BE, 2459, 2, 29); + assertEquals(date1, ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 2459, 60)); + assertEquals(date2, ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 2459, 60)); + } + /** * Test lookup by calendarType of each chronology. * Verify that the calendar can be found by {@link java.time.chrono.Chronology#ofLocale}.
--- a/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -56,18 +56,13 @@ */ package tck.java.time.chrono; -import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import java.time.Clock; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; -import java.time.Clock; import java.time.DateTimeException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.Month; -import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; @@ -77,11 +72,12 @@ import java.time.chrono.HijrahDate; import java.time.chrono.HijrahEra; import java.time.chrono.IsoChronology; -import java.time.chrono.MinguoChronology; -import java.time.chrono.MinguoDate; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAdjuster; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalField; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -106,49 +102,7 @@ Assert.assertEquals(test, c); } - //----------------------------------------------------------------------- - // creation, toLocalDate() - //----------------------------------------------------------------------- - @DataProvider(name="samples") - Object[][] data_samples() { - return new Object[][] { - //{HijrahChronology.INSTANCE.date(1320, 1, 1), LocalDate.of(1902, 4, 9)}, - //{HijrahChronology.INSTANCE.date(1320, 1, 2), LocalDate.of(1902, 4, 10)}, - //{HijrahChronology.INSTANCE.date(1320, 1, 3), LocalDate.of(1902, 4, 11)}, - - //{HijrahChronology.INSTANCE.date(1322, 1, 1), LocalDate.of(1904, 3, 18)}, - //{HijrahChronology.INSTANCE.date(1323, 1, 1), LocalDate.of(1905, 3, 7)}, - //{HijrahChronology.INSTANCE.date(1323, 12, 6), LocalDate.of(1906, 1, 30)}, - //{HijrahChronology.INSTANCE.date(1324, 1, 1), LocalDate.of(1906, 2, 24)}, - //{HijrahChronology.INSTANCE.date(1324, 7, 3), LocalDate.of(1906, 8, 23)}, - //{HijrahChronology.INSTANCE.date(1324, 7, 4), LocalDate.of(1906, 8, 24)}, - //{HijrahChronology.INSTANCE.date(1325, 1, 1), LocalDate.of(1907, 2, 13)}, - - {HijrahChronology.INSTANCE.date(1434, 7, 1), LocalDate.of(2013, 5, 11)}, - {HijrahChronology.INSTANCE.date(HijrahEra.AH, 1434, 7, 1), LocalDate.of(2013, 5, 11)}, - {HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178), LocalDate.of(2013, 5, 11)}, - {HijrahChronology.INSTANCE.dateYearDay(1434, 178), LocalDate.of(2013, 5, 11)}, - //{HijrahChronology.INSTANCE.date(1500, 3, 3), LocalDate.of(2079, 1, 5)}, - //{HijrahChronology.INSTANCE.date(1500, 10, 28), LocalDate.of(2079, 8, 25)}, - //{HijrahChronology.INSTANCE.date(1500, 10, 29), LocalDate.of(2079, 8, 26)}, - }; - } - - @Test(dataProvider="samples") - public void test_toLocalDate(ChronoLocalDate<?> hijrahDate, LocalDate iso) { - assertEquals(LocalDate.from(hijrahDate), iso); - } - - @Test(dataProvider="samples") - public void test_fromCalendrical(ChronoLocalDate<?> hijrahDate, LocalDate iso) { - assertEquals(HijrahChronology.INSTANCE.date(iso), hijrahDate); - } - - @Test(dataProvider="samples") - public void test_dayOfWeekEqualIsoDayOfWeek(ChronoLocalDate<?> hijrahDate, LocalDate iso) { - assertEquals(hijrahDate.get(DAY_OF_WEEK), iso.get(DAY_OF_WEEK), "Hijrah day of week should be same as ISO day of week"); - } - + // Tests for dateNow() method @Test public void test_dateNow(){ assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahDate.now()) ; @@ -169,31 +123,41 @@ assertEquals(HijrahChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), HijrahChronology.INSTANCE.dateNow(Clock.systemUTC())) ; } + // Sample invalid dates @DataProvider(name="badDates") Object[][] data_badDates() { return new Object[][] { - {1434, 0, 0}, - + {1299, 12, 29}, + {1320, 1, 29 + 1}, + {1320, 12, 29 + 1}, {1434, -1, 1}, + {1605, 1, 29}, {1434, 0, 1}, {1434, 14, 1}, {1434, 15, 1}, - {1434, 1, -1}, {1434, 1, 0}, {1434, 1, 32}, - {1434, 12, -1}, {1434, 12, 0}, {1434, 12, 32}, }; } + // This is a negative test to verify if the API throws exception if an invalid date is provided @Test(dataProvider="badDates", expectedExceptions=DateTimeException.class) public void test_badDates(int year, int month, int dom) { HijrahChronology.INSTANCE.date(year, month, dom); } + // Negative test or dateYearDay with day too large + @Test(expectedExceptions=java.time.DateTimeException.class) + public void test_ofYearDayTooLarge() { + int year = 1435; + int lengthOfYear = HijrahChronology.INSTANCE.dateYearDay(year, 1).lengthOfYear(); + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(year, lengthOfYear + 1); + } + //----------------------------------------------------------------------- // Bad Era for Chronology.date(era,...) and Chronology.prolepticYear(Era,...) //----------------------------------------------------------------------- @@ -213,7 +177,7 @@ ; // ignore expected exception } - /* TODO: Test for missing HijrahDate.of(Era, y, m, d) method. + /* TODO: Test for checking HijrahDate.of(Era, y, m, d) method if it is added. try { @SuppressWarnings("unused") HijrahDate jdate = HijrahDate.of(era, 1, 1, 1); @@ -233,102 +197,344 @@ } } } - //----------------------------------------------------------------------- - // with(WithAdjuster) + // Tests for HijrahChronology resolve //----------------------------------------------------------------------- - @Test - public void test_adjust1() { - ChronoLocalDate<?> base = HijrahChronology.INSTANCE.date(1434, 5, 15); - ChronoLocalDate<?> test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, HijrahChronology.INSTANCE.date(1434, 5, 29)); + @DataProvider(name = "resolve_styleByEra") + Object[][] data_resolve_styleByEra() { + Object[][] result = new Object[ResolverStyle.values().length * HijrahEra.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + for (HijrahEra era : HijrahEra.values()) { + result[i++] = new Object[] {style, era}; + } + } + return result; + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraOnly_valid(ResolverStyle style, HijrahEra era) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOfEraOnly_valid(ResolverStyle style, HijrahEra era) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), null); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1343L); + assertEquals(fieldValues.size(), 1); } - @Test - public void test_adjust2() { - ChronoLocalDate<?> base = HijrahChronology.INSTANCE.date(1434, 6, 2); - ChronoLocalDate<?> test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, HijrahChronology.INSTANCE.date(1434, 6, 30)); + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOnly_valid(ResolverStyle style, HijrahEra era) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1343L); + assertEquals(fieldValues.size(), 2); + } + + @DataProvider(name = "resolve_styles") + Object[][] data_resolve_styles() { + Object[][] result = new Object[ResolverStyle.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + result[i++] = new Object[] {style}; + } + return result; } - //----------------------------------------------------------------------- - // HijrahDate.with(Local*) - //----------------------------------------------------------------------- - @Test - public void test_adjust_toLocalDate() { - ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1435, 1, 4); - ChronoLocalDate<?> test = hijrahDate.with(LocalDate.of(2012, 7, 6)); - assertEquals(test, HijrahChronology.INSTANCE.date(1433, 8, 16)); + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraOnly_valid(ResolverStyle style) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (style != ResolverStyle.STRICT) ? null : (Long) 1343L); + assertEquals(fieldValues.get(ChronoField.YEAR), (style == ResolverStyle.STRICT) ? null : (Long) 1343L); + assertEquals(fieldValues.size(), 1); } - @Test(expectedExceptions=DateTimeException.class) - public void test_adjust_toMonth() { - ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1435, 1, 4); - hijrahDate.with(Month.APRIL); + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraAndYearOnly_valid(ResolverStyle style) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1343L); + fieldValues.put(ChronoField.YEAR, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), null); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1343L); + assertEquals(fieldValues.size(), 1); } //----------------------------------------------------------------------- - // LocalDate.with(HijrahDate) + // Sample Hijrah Calendar data; official data is in lib/hijrah-ummalqura.properties + // 1432=29 30 30 30 29 30 29 30 29 30 29 29 total = 354 + // 1433=30 29 30 30 29 30 30 29 30 29 30 29 total = 355 + // 1434=29 30 29 30 29 30 30 29 30 30 29 29 total = 354 + // 1435=30 29 30 29 30 29 30 29 30 30 29 30 total = 355 //----------------------------------------------------------------------- - @Test - public void test_LocalDate_adjustToHijrahDate() { - ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1434, 5, 15); - LocalDate test = LocalDate.MIN.with(hijrahDate); - assertEquals(test, LocalDate.of(2013, 3, 27)); + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + // Compute the number of days in various month and years so that test cases + // are not dependent on specific calendar data + // Month numbers are always 1..12 so they can be used literally + final int year = 1434; + final int yearP1 = year + 1; + final int yearP2 = year + 2; + final int yearM1 = year - 1; + final int yearM2 = year - 2; + final int lastDayInYear = dateYearDay(year, 1).lengthOfYear(); + final int lastDayInYearP1 = dateYearDay(yearP1, 1).lengthOfYear(); + final int lastDayInYearM1 = dateYearDay(yearM1, 1).lengthOfYear(); + final int lastDayInYearM2 = dateYearDay(yearM2, 1).lengthOfYear(); + final int lastDayInMonthM1 = date(yearM1, 12, 1).lengthOfMonth(); + final int lastDayInMonthM2 = date(yearM1, 11, 1).lengthOfMonth(); + final int lastDayInMonthM11 = date(yearM1, 2, 1).lengthOfMonth(); + + final int lastDayInMonth1 = date(year, 1, 1).lengthOfMonth(); + final int lastDayInMonth2 = date(year, 2, 1).lengthOfMonth(); + final int lastDayInMonth4 = date(year, 4, 1).lengthOfMonth(); + final int lastDayInMonth5 = date(year, 5, 1).lengthOfMonth(); + final int lastDayInMonth6 = date(year, 6, 1).lengthOfMonth(); + final int lastDayInMonth7 = date(year, 7, 1).lengthOfMonth(); + + return new Object[][] { + {year, 1, -lastDayInYearM1, dateYearDay(yearM2, lastDayInYearM2), false, false}, + {year, 1, -lastDayInYearM1 + 1, date(yearM1, 1, 1), false, false}, + {year, 1, -lastDayInMonthM1, date(yearM1, 11, lastDayInMonthM2), false, false}, + {year, 1, -lastDayInMonthM1 + 1, date(yearM1, 12, 1), false, false}, + {year, 1, -12, date(yearM1, 12, lastDayInMonthM1 - 12), false, false}, + {year, 1, 1, date(year, 1, 1), true, true}, + {year, 1, lastDayInMonth1 + lastDayInMonth2 - 1, date(year, 2, lastDayInMonth2 - 1), false, false}, + {year, 1, lastDayInMonth1 + lastDayInMonth2, date(year, 2, lastDayInMonth2), false, false}, + {year, 1, lastDayInMonth1 + lastDayInMonth2 + 1 , date(year, 3, 1), false, false}, + {year, 1, lastDayInYear, dateYearDay(year, lastDayInYear), false, false}, + {year, 1, lastDayInYear + 1, date(1435, 1, 1), false, false}, + {year, 1, lastDayInYear + lastDayInYearP1, dateYearDay(yearP1, lastDayInYearP1), false, false}, + {year, 1, lastDayInYear + lastDayInYearP1 + 1, date(yearP2, 1, 1), false, false}, + + {year, 2, 1, date(year, 2, 1), true, true}, + {year, 2, lastDayInMonth2 - 2, date(year, 2, lastDayInMonth2 - 2), true, true}, + {year, 2, lastDayInMonth2 - 1, date(year, 2, lastDayInMonth2 - 1), true, true}, + {year, 2, lastDayInMonth2, date(year, 2, lastDayInMonth2), date(year, 2, lastDayInMonth2), true}, + {year, 2, lastDayInMonth2 + 1, date(year, 3, 1), false, false}, + + {year, -12, 1, date(yearM2, 12, 1), false, false}, + {year, -11, 1, date(yearM1, 1, 1), false, false}, + {year, -1, 1, date(yearM1, 11, 1), false, false}, + {year, 0, 1, date(yearM1, 12, 1), false, false}, + {year, 1, 1, date(year, 1, 1), true, true}, + {year, 12, 1, date(year, 12, 1), true, true}, + {year, 13, 1, date(yearP1, 1, 1), false, false}, + {year, 24, 1, date(yearP1, 12, 1), false, false}, + {year, 25, 1, date(yearP2, 1, 1), false, false}, + + {year, 6, -lastDayInMonth5, date(year, 4, lastDayInMonth4), false, false}, + {year, 6, -lastDayInMonth5 + 1, date(year, 5, 1), false, false}, + {year, 6, -1, date(year, 5, lastDayInMonth5 - 1), false, false}, + {year, 6, 0, date(year, 5, lastDayInMonth5), false, false}, + {year, 6, 1, date(year, 6, 1), true, true}, + {year, 6, lastDayInMonth6 - 1 , date(year, 6, lastDayInMonth6 - 1), true, true}, + {year, 6, lastDayInMonth6, date(year, 6, lastDayInMonth6), date(year, 6, lastDayInMonth6), true}, + {year, 6, lastDayInMonth6 + 1, date(year, 7, 1), false, false}, + {year, 6, lastDayInMonth6 + lastDayInMonth7 , date(year, 7, lastDayInMonth7), false, false}, + {year, 6, lastDayInMonth6 + lastDayInMonth7 + 1, date(year, 8, 1), false, false}, + + {yearM1, 2, 1, date(yearM1, 2, 1), true, true}, + {yearM1, 2, lastDayInMonthM11 - 1, date(yearM1, 2, lastDayInMonthM11 - 1), true, true}, + {yearM1, 2, lastDayInMonthM11, date(yearM1, 2, lastDayInMonthM11), true, true}, + {yearM1, 2, lastDayInMonthM11 + 1, date(yearM1, 3, 1), date(yearM1, 2, lastDayInMonthM11), false}, + {yearM1, 2, lastDayInMonthM11 + 2, date(yearM1, 3, 2), false, false}, + // Bad dates + {1299, 12, 1, null, false, false}, + {1601, 1, 1, null, false, false}, + + }; } - @Test - public void test_LocalDateTime_adjustToHijrahDate() { - ChronoLocalDate<?> hijrahDate = HijrahChronology.INSTANCE.date(1435, 5, 15); - LocalDateTime test = LocalDateTime.MIN.with(hijrahDate); - assertEquals(test, LocalDateTime.of(2014, 3, 16, 0, 0)); + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, HijrahDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + + if (expected != null) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + fail("Should have failed, returned: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, HijrahDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof HijrahDate) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed, returned: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, HijrahDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected, "Resolved to incorrect date"); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed, returned: " + date); + } catch (DateTimeException ex) { + // expected + } + } } //----------------------------------------------------------------------- - // PeriodUntil() - //----------------------------------------------------------------------- - @Test - public void test_periodUntilDate() { - HijrahDate mdate1 = HijrahDate.of(1434, 1, 1); - HijrahDate mdate2 = HijrahDate.of(1435, 2, 2); - Period period = mdate1.periodUntil(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + // Compute the number of days in various month and years so that test cases + // are not dependent on specific calendar data + // Month numbers are always 1..12 so they can be used literally + final int year = 1343; + final int yearP1 = year + 1; + final int yearP2 = year + 2; + final int yearM1 = year - 1; + final int yearM2 = year - 2; + final int lastDayInYear = dateYearDay(year, 1).lengthOfYear(); + final int lastDayInYearP1 = dateYearDay(yearP1, 1).lengthOfYear(); + final int lastDayInYearM1 = dateYearDay(yearM1, 1).lengthOfYear(); + final int lastDayInYearM2 = dateYearDay(yearM2, 1).lengthOfYear(); + + final int lastDayInMonthM1 = date(yearM1, 12, 1).lengthOfMonth(); + final int lastDayInMonthM2 = date(yearM1, 11, 1).lengthOfMonth(); + final int lastDayInMonthM11 = date(yearM1, 2, 1).lengthOfMonth(); + + final int lastDayInMonth1 = date(year, 1, 1).lengthOfMonth(); + final int lastDayInMonth2 = date(year, 2, 1).lengthOfMonth(); + final int lastDayInMonth4 = date(year, 4, 1).lengthOfMonth(); + final int lastDayInMonth5 = date(year, 5, 1).lengthOfMonth(); + final int lastDayInMonth6 = date(year, 6, 1).lengthOfMonth(); + final int lastDayInMonth7 = date(year, 7, 1).lengthOfMonth(); + + return new Object[][] { + {year, -lastDayInYearM1, dateYearDay(yearM2, lastDayInYearM2), false, false}, + {year, -lastDayInYearM1 + 1, date(yearM1, 1, 1), false, false}, + {year, -lastDayInMonthM1, date(yearM1, 11, lastDayInMonthM2), false, false}, + {year, -lastDayInMonthM1 + 1, date(yearM1, 12, 1), false, false}, + {year, -12, date(yearM1, 12, lastDayInMonthM1 - 12), false, false}, + {year, -1, date(yearM1, 12, lastDayInMonthM1 - 1), false, false}, + {year, 0, date(yearM1, 12, lastDayInMonthM1), false, false}, + {year, 1, date(year, 1, 1), true, true}, + {year, 2, date(year, 1, 2), true, true}, + {year, lastDayInMonth1, date(year, 1, lastDayInMonth1), true, true}, + {year, lastDayInMonth1 + 1, date(year, 2, 1), true, true}, + {year, lastDayInMonth1 + lastDayInMonth2 - 1, date(year, 2, lastDayInMonth2 - 1), true, true}, + {year, lastDayInMonth1 + lastDayInMonth2, date(year, 2, lastDayInMonth2), true, true}, + {year, lastDayInMonth1 + lastDayInMonth2 + 1, date(year, 3, 1), true, true}, + {year, lastDayInYear - 1, dateYearDay(year, lastDayInYear - 1), true, true}, + {year, lastDayInYear, dateYearDay(year, lastDayInYear), true, true}, + {year, lastDayInYear + 1, date(yearP1, 1, 1), false, false}, + {year, lastDayInYear + lastDayInYearP1, dateYearDay(yearP1, lastDayInYearP1), false, false}, + {year, lastDayInYear + lastDayInYearP1 + 1, date(yearP2, 1, 1), false, false}, + }; } - @Test - public void test_periodUntilUnit() { - HijrahDate mdate1 = HijrahDate.of(1434, 1, 1); - HijrahDate mdate2 = HijrahDate.of(1435, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); - assertEquals(months, 13); + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, HijrahDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); } - @Test - public void test_periodUntilDiffChrono() { - HijrahDate mdate1 = HijrahDate.of(1434, 1, 1); - HijrahDate mdate2 = HijrahDate.of(1435, 2, 2); - MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, HijrahDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed, returned date: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, HijrahDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed, returned date: " + date); + } catch (DateTimeException ex) { + // expected + } + } } //----------------------------------------------------------------------- - // toString() - //----------------------------------------------------------------------- - @DataProvider(name="toString") - Object[][] data_toString() { - return new Object[][] { - //{HijrahChronology.INSTANCE.date(1320, 1, 1), "Hijrah AH 1320-01-01"}, - //{HijrahChronology.INSTANCE.date(1500, 10, 28), "Hijrah AH 1500-10-28"}, - //{HijrahChronology.INSTANCE.date(1500, 10, 29), "Hijrah AH 1500-10-29"}, - {HijrahChronology.INSTANCE.date(1434, 12, 5), "Hijrah-umalqura AH 1434-12-05"}, - {HijrahChronology.INSTANCE.date(1434, 12, 6), "Hijrah-umalqura AH 1434-12-06"}, - }; + private static HijrahDate date(int y, int m, int d) { + return HijrahDate.of(y, m, d); } - @Test(dataProvider="toString") - public void test_toString(ChronoLocalDate<?> hijrahDate, String expected) { - assertEquals(hijrahDate.toString(), expected); + private static HijrahDate dateYearDay(int y, int doy) { + return HijrahChronology.INSTANCE.dateYearDay(y, doy); } //----------------------------------------------------------------------- @@ -343,5 +549,4 @@ public void test_equals_false() { assertFalse(HijrahChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } - }
--- a/test/java/time/tck/java/time/chrono/TCKHijrahEra.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKHijrahEra.java Wed Jul 24 08:22:32 2013 -0300 @@ -85,6 +85,8 @@ @Test(dataProvider="HijrahEras") public void test_valueOf(HijrahEra era , String eraName, int eraValue) { assertEquals(era.getValue(), eraValue); + + assertEquals(HijrahChronology.INSTANCE.eraOf(eraValue), era); assertEquals(HijrahEra.of(eraValue), era); assertEquals(HijrahEra.valueOf(eraName), era); }
--- a/test/java/time/tck/java/time/chrono/TCKIsoChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKIsoChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -278,91 +278,88 @@ @DataProvider(name = "resolve_yearOfEra") Object[][] data_resolve_yearOfEra() { return new Object[][] { - {-1, 2012, null, null, false, false}, - {0, 2012, null, -2011, true, true}, - {1, 2012, null, 2012, true, true}, - {2, 2012, null, null, false, false}, + // era only + {ResolverStyle.STRICT, -1, null, null, null, null}, + {ResolverStyle.SMART, -1, null, null, null, null}, + {ResolverStyle.LENIENT, -1, null, null, null, null}, + + {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0}, + + {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1}, + + {ResolverStyle.STRICT, 2, null, null, null, null}, + {ResolverStyle.SMART, 2, null, null, null, null}, + {ResolverStyle.LENIENT, 2, null, null, null, null}, + + // era and year-of-era + {ResolverStyle.STRICT, -1, 2012, null, null, null}, + {ResolverStyle.SMART, -1, 2012, null, null, null}, + {ResolverStyle.LENIENT, -1, 2012, null, null, null}, + + {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012}, - {null, 2012, null, 2012, true, null}, - {null, 2012, 2012, 2012, true, true}, - {null, 2012, -2011, -2011, true, true}, - {null, 2012, 2013, null, false, false}, - {null, 2012, -2013, null, false, false}, + {ResolverStyle.STRICT, 2, 2012, null, null, null}, + {ResolverStyle.SMART, 2, 2012, null, null, null}, + {ResolverStyle.LENIENT, 2, 2012, null, null, null}, + + // year-of-era only + {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012}, + {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE}, + + // year-of-era and year + {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, null, 2012, 2013, null, null}, + {ResolverStyle.SMART, null, 2012, 2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, 2013, null, null}, + + {ResolverStyle.STRICT, null, 2012, -2013, null, null}, + {ResolverStyle.SMART, null, 2012, -2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, -2013, null, null}, }; } @Test(dataProvider = "resolve_yearOfEra") - public void test_resolve_yearOfEra_lenient(Integer e, int yoe, Integer y, Integer expected, boolean smart, Boolean strict) { + public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) { Map<TemporalField, Long> fieldValues = new HashMap<>(); if (e != null) { fieldValues.put(ChronoField.ERA, (long) e); } - fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); - if (y != null) { - fieldValues.put(ChronoField.YEAR, (long) y); + if (yoe != null) { + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); } - if (smart) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); - assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR), (Long) (long) expected); - assertEquals(fieldValues.size(), 1); - } else { - try { - IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); - fail("Should have failed"); - } catch (DateTimeException ex) { - // expected - } - } - } - - @Test(dataProvider = "resolve_yearOfEra") - public void test_resolve_yearOfEra_smart(Integer e, int yoe, Integer y, Integer expected, boolean smart, Boolean strict) { - Map<TemporalField, Long> fieldValues = new HashMap<>(); - if (e != null) { - fieldValues.put(ChronoField.ERA, (long) e); - } - fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); if (y != null) { fieldValues.put(ChronoField.YEAR, (long) y); } - if (smart) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + if (field != null) { + LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, style); assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR), (Long) (long) expected); + assertEquals(fieldValues.get(field), (Long) expected.longValue()); assertEquals(fieldValues.size(), 1); } else { try { - IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); - fail("Should have failed"); - } catch (DateTimeException ex) { - // expected - } - } - } - - @Test(dataProvider = "resolve_yearOfEra") - public void test_resolve_yearOfEra_strict(Integer e, int yoe, Integer y, Integer expected, boolean smart, Boolean strict) { - Map<TemporalField, Long> fieldValues = new HashMap<>(); - if (e != null) { - fieldValues.put(ChronoField.ERA, (long) e); - } - fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); - if (y != null) { - fieldValues.put(ChronoField.YEAR, (long) y); - } - if (strict == null) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); - assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) (long) yoe); - } else if (strict) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); - assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR), (Long) (long) expected); - assertEquals(fieldValues.size(), 1); - } else { - try { - IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + IsoChronology.INSTANCE.resolveDate(fieldValues, style); fail("Should have failed"); } catch (DateTimeException ex) { // expected @@ -381,6 +378,11 @@ {2012, 1, -30, date(2011, 12, 1), false, false}, {2012, 1, -12, date(2011, 12, 19), false, false}, {2012, 1, 1, date(2012, 1, 1), true, true}, + {2012, 1, 27, date(2012, 1, 27), true, true}, + {2012, 1, 28, date(2012, 1, 28), true, true}, + {2012, 1, 29, date(2012, 1, 29), true, true}, + {2012, 1, 30, date(2012, 1, 30), true, true}, + {2012, 1, 31, date(2012, 1, 31), true, true}, {2012, 1, 59, date(2012, 2, 28), false, false}, {2012, 1, 60, date(2012, 2, 29), false, false}, {2012, 1, 61, date(2012, 3, 1), false, false},
--- a/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -57,12 +57,15 @@ package tck.java.time.chrono; import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -84,10 +87,19 @@ import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.time.temporal.TemporalQuery; +import java.time.temporal.ValueRange; + +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -155,59 +167,145 @@ } //----------------------------------------------------------------------- - // creation, toLocalDate() + // creation and cross-checks //----------------------------------------------------------------------- - @DataProvider(name="samples") - Object[][] data_samples() { + @DataProvider(name="createByEra") + Object[][] data_createByEra() { return new Object[][] { - {JapaneseChronology.INSTANCE.date(1, 1, 1), LocalDate.of(1, 1, 1)}, - {JapaneseChronology.INSTANCE.date(1, 1, 2), LocalDate.of(1, 1, 2)}, - {JapaneseChronology.INSTANCE.date(1, 1, 3), LocalDate.of(1, 1, 3)}, - - {JapaneseChronology.INSTANCE.date(2, 1, 1), LocalDate.of(2, 1, 1)}, - {JapaneseChronology.INSTANCE.date(3, 1, 1), LocalDate.of(3, 1, 1)}, - {JapaneseChronology.INSTANCE.date(3, 12, 6), LocalDate.of(3, 12, 6)}, - {JapaneseChronology.INSTANCE.date(4, 1, 1), LocalDate.of(4, 1, 1)}, - {JapaneseChronology.INSTANCE.date(4, 7, 3), LocalDate.of(4, 7, 3)}, - {JapaneseChronology.INSTANCE.date(4, 7, 4), LocalDate.of(4, 7, 4)}, - {JapaneseChronology.INSTANCE.date(5, 1, 1), LocalDate.of(5, 1, 1)}, - {JapaneseChronology.INSTANCE.date(1662, 3, 3), LocalDate.of(1662, 3, 3)}, - {JapaneseChronology.INSTANCE.date(1728, 10, 28), LocalDate.of(1728, 10, 28)}, - {JapaneseChronology.INSTANCE.date(1728, 10, 29), LocalDate.of(1728, 10, 29)}, - - {JapaneseChronology.INSTANCE.date(JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29), LocalDate.of(1996, 2, 29)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29), LocalDate.of(2000, 2, 29)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.MEIJI, 1868 - YDIFF_MEIJI, 2, 29), LocalDate.of(1868, 2, 29)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 12, 25), LocalDate.of(1928, 12, 25)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.TAISHO, 1912 - YDIFF_TAISHO, 7, 30), LocalDate.of(1912, 7, 30)}, - - {JapaneseChronology.INSTANCE.dateYearDay(1996, 60), LocalDate.of(1996, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(1868, 60), LocalDate.of(1868, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(1928, 60), LocalDate.of(1928, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(1912, 60), LocalDate.of(1912, 2, 29)}, - - {JapaneseDate.ofYearDay(1996, 60), LocalDate.of(1996, 2, 29)}, - {JapaneseDate.ofYearDay(1868, 60), LocalDate.of(1868, 2, 29)}, - {JapaneseDate.ofYearDay(1928, 60), LocalDate.of(1928, 2, 29)}, - {JapaneseDate.ofYearDay(1912, 60), LocalDate.of(1912, 2, 29)}, - - {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 60), LocalDate.of(1996, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.MEIJI, 1868 - YDIFF_MEIJI, 60), LocalDate.of(1868, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 60), LocalDate.of(1928, 2, 29)}, -// {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.TAISHO, 1916 - YDIFF_TAISHO, 60), LocalDate.of(1912, 2, 29)}, + {JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(1996, 2, 29)}, + {JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(2000, 2, 29)}, + {JapaneseEra.MEIJI, 1874 - YDIFF_MEIJI, 2, 28, 59, LocalDate.of(1874, 2, 28)}, + {JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 12, 25, 360, LocalDate.of(1928, 12, 25)}, + {JapaneseEra.TAISHO, 1916 - YDIFF_TAISHO, 7, 30, 212, LocalDate.of(1916, 7, 30)}, + {JapaneseEra.MEIJI, 6, 1, 1, 1, LocalDate.of(1873, 1, 1)}, + {JapaneseEra.MEIJI, 45, 7, 29, 211, LocalDate.of(1912, 7, 29)}, + {JapaneseEra.TAISHO, 1, 7, 30, 1, LocalDate.of(1912, 7, 30)}, + {JapaneseEra.TAISHO, 15, 12, 24, 358, LocalDate.of(1926, 12, 24)}, + {JapaneseEra.SHOWA, 1, 12, 25, 1, LocalDate.of(1926, 12, 25)}, + {JapaneseEra.SHOWA, 64, 1, 7, 7, LocalDate.of(1989, 1, 7)}, + {JapaneseEra.HEISEI, 1, 1, 8, 1, LocalDate.of(1989, 1, 8)}, }; } - @Test(dataProvider="samples") - public void test_toLocalDate(JapaneseDate jdate, LocalDate iso) { - assertEquals(LocalDate.from(jdate), iso); + @Test(dataProvider="createByEra") + public void test_createEymd(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.date(era, yoe, moy, dom); + JapaneseDate dateByDateFactory = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); + } + + @Test(dataProvider="createByEra") + public void test_createEyd(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.dateYearDay(era, yoe, doy); + JapaneseDate dateByDateFactory = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_isEqual(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(test.isEqual(iso), true); + assertEquals(iso.isEqual(test), true); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_chronologyTemporalFactory(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(IsoChronology.INSTANCE.date(test), iso); + assertEquals(JapaneseChronology.INSTANCE.date(iso), test); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_dateFrom(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(LocalDate.from(test), iso); + assertEquals(JapaneseDate.from(iso), test); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_query(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(test.query(TemporalQuery.localDate()), iso); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_epochDay(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(test.getLong(EPOCH_DAY), iso.getLong(EPOCH_DAY)); + assertEquals(test.toEpochDay(), iso.toEpochDay()); } - @Test(dataProvider="samples") - public void test_fromCalendrical(JapaneseDate jdate, LocalDate iso) { - assertEquals(JapaneseChronology.INSTANCE.date(iso), jdate); + //----------------------------------------------------------------------- + @DataProvider(name="createByProleptic") + Object[][] data_createByProleptic() { + return new Object[][] { + {1928, 2, 28, 59, LocalDate.of(1928, 2, 28)}, + {1928, 2, 29, 60, LocalDate.of(1928, 2, 29)}, + + {1873, 9, 7, 250, LocalDate.of(1873, 9, 7)}, + {1873, 9, 8, 251, LocalDate.of(1873, 9, 8)}, + {1912, 7, 29, 211, LocalDate.of(1912, 7, 29)}, + {1912, 7, 30, 212, LocalDate.of(1912, 7, 30)}, + {1926, 12, 24, 358, LocalDate.of(1926, 12, 24)}, + {1926, 12, 25, 359, LocalDate.of(1926, 12, 25)}, + {1989, 1, 7, 7, LocalDate.of(1989, 1, 7)}, + {1989, 1, 8, 8, LocalDate.of(1989, 1, 8)}, + }; + } + + @Test(dataProvider="createByProleptic") + public void test_createYmd(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.date(y, moy, dom); + JapaneseDate dateByDateFactory = JapaneseDate.of(y, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); + } + + @Test(dataProvider="createByProleptic") + public void test_createYd(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.dateYearDay(y, doy); + JapaneseDate dateByDateFactory = JapaneseDate.of(y, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); } + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_isEqual(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(test.isEqual(iso), true); + assertEquals(iso.isEqual(test), true); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_chronologyTemporalFactory(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(IsoChronology.INSTANCE.date(test), iso); + assertEquals(JapaneseChronology.INSTANCE.date(iso), test); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_dateFrom(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(LocalDate.from(test), iso); + assertEquals(JapaneseDate.from(iso), test); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_query(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(test.query(TemporalQuery.localDate()), iso); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_epochDay(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(test.getLong(EPOCH_DAY), iso.getLong(EPOCH_DAY)); + assertEquals(test.toEpochDay(), iso.toEpochDay()); + } + + //----------------------------------------------------------------------- @Test public void test_dateNow(){ assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseDate.now()) ; @@ -228,27 +326,30 @@ assertEquals(JapaneseChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), JapaneseChronology.INSTANCE.dateNow(Clock.systemUTC())) ; } + //----------------------------------------------------------------------- @DataProvider(name="badDates") Object[][] data_badDates() { return new Object[][] { - {1728, 0, 0}, + {1928, 0, 0}, - {1728, -1, 1}, - {1728, 0, 1}, - {1728, 14, 1}, - {1728, 15, 1}, + {1928, -1, 1}, + {1928, 0, 1}, + {1928, 14, 1}, + {1928, 15, 1}, - {1728, 1, -1}, - {1728, 1, 0}, - {1728, 1, 32}, + {1928, 1, -1}, + {1928, 1, 0}, + {1928, 1, 32}, - {1728, 12, -1}, - {1728, 12, 0}, - {1728, 12, 32}, + {1928, 12, -1}, + {1928, 12, 0}, + {1928, 12, 32}, {1725, 2, 29}, {500, 2, 29}, {2100, 2, 29}, + + {1872, 12, 31}, // Last day of MEIJI 5 }; } @@ -266,8 +367,8 @@ {2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false}, {2, JapaneseEra.HEISEI, 100, 100 + YDIFF_HEISEI, true}, - {-1, JapaneseEra.MEIJI, 1, 1 + YDIFF_MEIJI, true}, - {-1, JapaneseEra.MEIJI, 4, 4 + YDIFF_MEIJI, false}, + {-1, JapaneseEra.MEIJI, 9, 9 + YDIFF_MEIJI, true}, + {-1, JapaneseEra.MEIJI, 10, 10 + YDIFF_MEIJI, false}, {1, JapaneseEra.SHOWA, 1, 1 + YDIFF_SHOWA, false}, {1, JapaneseEra.SHOWA, 7, 7 + YDIFF_SHOWA, true}, @@ -279,12 +380,24 @@ @Test(dataProvider="prolepticYear") public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { - Era eraObj = JapaneseChronology.INSTANCE.eraOf(eraValue) ; + Era eraObj = JapaneseChronology.INSTANCE.eraOf(eraValue); assertTrue(JapaneseChronology.INSTANCE.eras().contains(eraObj)); assertEquals(eraObj, era); assertEquals(JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); - assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; - assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear).isLeap()) ; + } + + @Test(dataProvider="prolepticYear") + public void test_isLeapYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear); + assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear).isLeap()); + + JapaneseDate jdate = JapaneseDate.now(); + jdate = jdate.with(ChronoField.YEAR, expectedProlepticYear).with(ChronoField.MONTH_OF_YEAR, 2); + if (isLeapYear) { + assertEquals(jdate.lengthOfMonth(), 29); + } else { + assertEquals(jdate.lengthOfMonth(), 28); + } } @DataProvider(name="prolepticYearError") @@ -327,15 +440,6 @@ } catch (ClassCastException cex) { ; // ignore expected exception } - - try { - @SuppressWarnings("unused") - JapaneseDate jdate = JapaneseDate.of(era, 1, 1, 1); - fail("JapaneseDate.of did not throw ClassCastException for Era: " + era); - } catch (ClassCastException cex) { - ; // ignore expected exception - } - try { @SuppressWarnings("unused") int year = JapaneseChronology.INSTANCE.prolepticYear(era, 1); @@ -388,16 +492,16 @@ //----------------------------------------------------------------------- @Test public void test_adjust1() { - JapaneseDate base = JapaneseChronology.INSTANCE.date(1728, 10, 29); + JapaneseDate base = JapaneseChronology.INSTANCE.date(1928, 10, 29); JapaneseDate test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, JapaneseChronology.INSTANCE.date(1728, 10, 31)); + assertEquals(test, JapaneseChronology.INSTANCE.date(1928, 10, 31)); } @Test public void test_adjust2() { - JapaneseDate base = JapaneseChronology.INSTANCE.date(1728, 12, 2); + JapaneseDate base = JapaneseChronology.INSTANCE.date(1928, 12, 2); JapaneseDate test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, JapaneseChronology.INSTANCE.date(1728, 12, 31)); + assertEquals(test, JapaneseChronology.INSTANCE.date(1928, 12, 31)); } //----------------------------------------------------------------------- @@ -405,14 +509,14 @@ //----------------------------------------------------------------------- @Test public void test_adjust_toLocalDate() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1726, 1, 4); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1926, 1, 4); JapaneseDate test = jdate.with(LocalDate.of(2012, 7, 6)); assertEquals(test, JapaneseChronology.INSTANCE.date(2012, 7, 6)); } @Test(expectedExceptions=DateTimeException.class) public void test_adjust_toMonth() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1726, 1, 4); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1926, 1, 4); jdate.with(Month.APRIL); } @@ -421,16 +525,16 @@ //----------------------------------------------------------------------- @Test public void test_LocalDate_adjustToJapaneseDate() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1728, 10, 29); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1928, 10, 29); LocalDate test = LocalDate.MIN.with(jdate); - assertEquals(test, LocalDate.of(1728, 10, 29)); + assertEquals(test, LocalDate.of(1928, 10, 29)); } @Test public void test_LocalDateTime_adjustToJapaneseDate() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1728, 10, 29); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1928, 10, 29); LocalDateTime test = LocalDateTime.MIN.with(jdate); - assertEquals(test, LocalDateTime.of(1728, 10, 29, 0, 0)); + assertEquals(test, LocalDateTime.of(1928, 10, 29, 0, 0)); } //----------------------------------------------------------------------- @@ -439,7 +543,6 @@ @DataProvider(name="japaneseEras") Object[][] data_japanseseEras() { return new Object[][] { - { JapaneseEra.SEIREKI, -999, "Seireki"}, { JapaneseEra.MEIJI, -1, "Meiji"}, { JapaneseEra.TAISHO, 0, "Taisho"}, { JapaneseEra.SHOWA, 1, "Showa"}, @@ -512,7 +615,7 @@ public void test_periodUntilDate() { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); - Period period = mdate1.periodUntil(mdate2); + Period period = mdate1.until(mdate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -520,7 +623,7 @@ public void test_periodUntilUnit() { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); + long months = mdate1.until(mdate2, ChronoUnit.MONTHS); assertEquals(months, 13); } @@ -529,22 +632,49 @@ JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); + Period period = mdate1.until(ldate2); assertEquals(period, Period.of(1, 1, 1)); } //----------------------------------------------------------------------- + // JapaneseChronology.dateYearDay, getDayOfYear + //----------------------------------------------------------------------- + @Test + public void test_getDayOfYear() { + // Test all the Eras + for (JapaneseEra era : JapaneseEra.values()) { + int firstYear = (era == JapaneseEra.MEIJI) ? 6 : 1; // Until Era supports range(YEAR_OF_ERA) + JapaneseDate hd1 = JapaneseChronology.INSTANCE.dateYearDay(era, firstYear, 1); + ValueRange range = hd1.range(DAY_OF_YEAR); + assertEquals(range.getMaximum(), hd1.lengthOfYear(), "lengthOfYear should match range.getMaximum()"); + + for (int i = 1; i <= hd1.lengthOfYear(); i++) { + JapaneseDate hd = JapaneseChronology.INSTANCE.dateYearDay(era, firstYear, i); + int doy = hd.get(DAY_OF_YEAR); + assertEquals(doy, i, "get(DAY_OF_YEAR) incorrect for " + i + ", of date: " + hd); + } + } + } + + @Test + public void test_withDayOfYear() { + JapaneseDate hd = JapaneseChronology.INSTANCE.dateYearDay(1990, 1); + for (int i = 1; i <= hd.lengthOfYear(); i++) { + JapaneseDate hd2 = hd.with(DAY_OF_YEAR, i); + int doy = hd2.get(DAY_OF_YEAR); + assertEquals(doy, i, "with(DAY_OF_YEAR) incorrect for " + i + " " + hd2); + } + } + + //----------------------------------------------------------------------- // toString() //----------------------------------------------------------------------- @DataProvider(name="toString") Object[][] data_toString() { return new Object[][] { - {JapaneseChronology.INSTANCE.date(0001, 1, 1), "Japanese 0001-01-01"}, - {JapaneseChronology.INSTANCE.date(1728, 10, 28), "Japanese 1728-10-28"}, - {JapaneseChronology.INSTANCE.date(1728, 10, 29), "Japanese 1728-10-29"}, - {JapaneseChronology.INSTANCE.date(1727, 12, 5), "Japanese 1727-12-05"}, - {JapaneseChronology.INSTANCE.date(1727, 12, 6), "Japanese 1727-12-06"}, - {JapaneseChronology.INSTANCE.date(1868, 9, 8), "Japanese Meiji 1-09-08"}, + {JapaneseChronology.INSTANCE.date(1873, 12, 5), "Japanese Meiji 6-12-05"}, + {JapaneseChronology.INSTANCE.date(1873, 12, 6), "Japanese Meiji 6-12-06"}, + {JapaneseChronology.INSTANCE.date(1873, 9, 8), "Japanese Meiji 6-09-08"}, {JapaneseChronology.INSTANCE.date(1912, 7, 29), "Japanese Meiji 45-07-29"}, {JapaneseChronology.INSTANCE.date(1912, 7, 30), "Japanese Taisho 1-07-30"}, {JapaneseChronology.INSTANCE.date(1926, 12, 24), "Japanese Taisho 15-12-24"}, @@ -573,4 +703,476 @@ assertFalse(JapaneseChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_styleByEra") + Object[][] data_resolve_styleByEra() { + Object[][] result = new Object[ResolverStyle.values().length * JapaneseEra.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + for (JapaneseEra era : JapaneseEra.values()) { + result[i++] = new Object[] {style, era}; + } + } + return result; + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraOnly_valid(ResolverStyle style, JapaneseEra era) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOfEraOnly_valid(ResolverStyle style, JapaneseEra era) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) 1L); + assertEquals(fieldValues.size(), 2); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOnly_valid(ResolverStyle style, JapaneseEra era) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR, 1L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1L); + assertEquals(fieldValues.size(), 2); + } + + @DataProvider(name = "resolve_styles") + Object[][] data_resolve_styles() { + Object[][] result = new Object[ResolverStyle.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + result[i++] = new Object[] {style}; + } + return result; + } + + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraOnly_valid(ResolverStyle style) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) 1L); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraAndYearOnly_valid(ResolverStyle style) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1L); + fieldValues.put(ChronoField.YEAR, 2012L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) 1L); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 2012L); + assertEquals(fieldValues.size(), 2); + } + + public void test_resolve_yearOfEra_eraOnly_invalidTooSmall() { + for (ResolverStyle style : ResolverStyle.values()) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, JapaneseEra.MEIJI.getValue() - 1L); + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed: " + style); + } catch (DateTimeException ex) { + // expected + } + } + } + + public void test_resolve_yearOfEra_eraOnly_invalidTooLarge() { + for (ResolverStyle style : ResolverStyle.values()) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, JapaneseEra.values()[JapaneseEra.values().length - 1].getValue() + 1L); + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed: " + style); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + return new Object[][] { + {2012, 1, -365, date(2010, 12, 31), false, false}, + {2012, 1, -364, date(2011, 1, 1), false, false}, + {2012, 1, -31, date(2011, 11, 30), false, false}, + {2012, 1, -30, date(2011, 12, 1), false, false}, + {2012, 1, -12, date(2011, 12, 19), false, false}, + {2012, 1, 1, date(2012, 1, 1), true, true}, + {2012, 1, 59, date(2012, 2, 28), false, false}, + {2012, 1, 60, date(2012, 2, 29), false, false}, + {2012, 1, 61, date(2012, 3, 1), false, false}, + {2012, 1, 365, date(2012, 12, 30), false, false}, + {2012, 1, 366, date(2012, 12, 31), false, false}, + {2012, 1, 367, date(2013, 1, 1), false, false}, + {2012, 1, 367 + 364, date(2013, 12, 31), false, false}, + {2012, 1, 367 + 365, date(2014, 1, 1), false, false}, + + {2012, 2, 1, date(2012, 2, 1), true, true}, + {2012, 2, 28, date(2012, 2, 28), true, true}, + {2012, 2, 29, date(2012, 2, 29), true, true}, + {2012, 2, 30, date(2012, 3, 1), date(2012, 2, 29), false}, + {2012, 2, 31, date(2012, 3, 2), date(2012, 2, 29), false}, + {2012, 2, 32, date(2012, 3, 3), false, false}, + + {2012, -12, 1, date(2010, 12, 1), false, false}, + {2012, -11, 1, date(2011, 1, 1), false, false}, + {2012, -1, 1, date(2011, 11, 1), false, false}, + {2012, 0, 1, date(2011, 12, 1), false, false}, + {2012, 1, 1, date(2012, 1, 1), true, true}, + {2012, 12, 1, date(2012, 12, 1), true, true}, + {2012, 13, 1, date(2013, 1, 1), false, false}, + {2012, 24, 1, date(2013, 12, 1), false, false}, + {2012, 25, 1, date(2014, 1, 1), false, false}, + + {2012, 6, -31, date(2012, 4, 30), false, false}, + {2012, 6, -30, date(2012, 5, 1), false, false}, + {2012, 6, -1, date(2012, 5, 30), false, false}, + {2012, 6, 0, date(2012, 5, 31), false, false}, + {2012, 6, 1, date(2012, 6, 1), true, true}, + {2012, 6, 30, date(2012, 6, 30), true, true}, + {2012, 6, 31, date(2012, 7, 1), date(2012, 6, 30), false}, + {2012, 6, 61, date(2012, 7, 31), false, false}, + {2012, 6, 62, date(2012, 8, 1), false, false}, + + {2011, 2, 1, date(2011, 2, 1), true, true}, + {2011, 2, 28, date(2011, 2, 28), true, true}, + {2011, 2, 29, date(2011, 3, 1), date(2011, 2, 28), false}, + {2011, 2, 30, date(2011, 3, 2), date(2011, 2, 28), false}, + {2011, 2, 31, date(2011, 3, 3), date(2011, 2, 28), false}, + {2011, 2, 32, date(2011, 3, 4), false, false}, + }; + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, JapaneseDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, JapaneseDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof JapaneseDate) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, JapaneseDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + return new Object[][] { + {2012, -365, date(2010, 12, 31), false, false}, + {2012, -364, date(2011, 1, 1), false, false}, + {2012, -31, date(2011, 11, 30), false, false}, + {2012, -30, date(2011, 12, 1), false, false}, + {2012, -12, date(2011, 12, 19), false, false}, + {2012, -1, date(2011, 12, 30), false, false}, + {2012, 0, date(2011, 12, 31), false, false}, + {2012, 1, date(2012, 1, 1), true, true}, + {2012, 2, date(2012, 1, 2), true, true}, + {2012, 31, date(2012, 1, 31), true, true}, + {2012, 32, date(2012, 2, 1), true, true}, + {2012, 59, date(2012, 2, 28), true, true}, + {2012, 60, date(2012, 2, 29), true, true}, + {2012, 61, date(2012, 3, 1), true, true}, + {2012, 365, date(2012, 12, 30), true, true}, + {2012, 366, date(2012, 12, 31), true, true}, + {2012, 367, date(2013, 1, 1), false, false}, + {2012, 367 + 364, date(2013, 12, 31), false, false}, + {2012, 367 + 365, date(2014, 1, 1), false, false}, + + {2011, 59, date(2011, 2, 28), true, true}, + {2011, 60, date(2011, 3, 1), true, true}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, JapaneseDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, JapaneseDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, JapaneseDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_eymd") + Object[][] data_resolve_eymd() { + return new Object[][] { + // lenient + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 1, 1, date(1989, 1, 1)}, // SHOWA, not HEISEI + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 1, 7, date(1989, 1, 7)}, // SHOWA, not HEISEI + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 1, 8, date(1989, 1, 8)}, + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 12, 31, date(1989, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 2, 1, 1, date(1990, 1, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 7, date(1989, 1, 7)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 8, date(1989, 1, 8)}, // HEISEI, not SHOWA + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 12, 31, date(1989, 12, 31)}, // HEISEI, not SHOWA + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 65, 1, 1, date(1990, 1, 1)}, // HEISEI, not SHOWA + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -366, date(1987, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -365, date(1988, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -31, date(1988, 11, 30)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -30, date(1988, 12, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 0, date(1988, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 27, date(1989, 1, 27)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 28, date(1989, 1, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 29, date(1989, 1, 29)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 30, date(1989, 1, 30)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 31, date(1989, 1, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 32, date(1989, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 58, date(1989, 2, 27)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 59, date(1989, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 60, date(1989, 3, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 365, date(1989, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 366, date(1990, 1, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 1, date(1988, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 31, date(1988, 1, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 32, date(1988, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 58, date(1988, 2, 27)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 59, date(1988, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 60, date(1988, 2, 29)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 61, date(1988, 3, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 2, 1, date(1989, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 2, 28, date(1989, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 2, 29, date(1989, 3, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 1, date(1988, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 28, date(1988, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 29, date(1988, 2, 29)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 30, date(1988, 3, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, -11, 1, date(1986, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, -1, 1, date(1986, 11, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, 0, 1, date(1986, 12, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, 13, 1, date(1988, 1, 1)}, + + // smart + {ResolverStyle.SMART, JapaneseEra.HEISEI, 0, 1, 1, null}, + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 1, 1, date(1989, 1, 1)}, // SHOWA, not HEISEI + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 1, 7, date(1989, 1, 7)}, // SHOWA, not HEISEI + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 1, 8, date(1989, 1, 8)}, + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 12, 31, date(1989, 12, 31)}, + {ResolverStyle.SMART, JapaneseEra.HEISEI, 2, 1, 1, date(1990, 1, 1)}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 1, 7, date(1989, 1, 7)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 1, 8, date(1989, 1, 8)}, // HEISEI, not SHOWA + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 12, 31, date(1989, 12, 31)}, // HEISEI, not SHOWA + {ResolverStyle.SMART, JapaneseEra.SHOWA, 65, 1, 1, null}, // HEISEI, not SHOWA + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 0, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 1, date(1987, 1, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 27, date(1987, 1, 27)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 28, date(1987, 1, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 29, date(1987, 1, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 30, date(1987, 1, 30)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 31, date(1987, 1, 31)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 32, null}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 0, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 1, date(1987, 2, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 27, date(1987, 2, 27)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 28, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 29, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 30, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 31, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 32, null}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 0, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 1, date(1988, 2, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 27, date(1988, 2, 27)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 28, date(1988, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 29, date(1988, 2, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 30, date(1988, 2, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 31, date(1988, 2, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 32, null}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, -12, 1, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, -1, 1, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 0, 1, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 13, 1, null}, + + // strict + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 0, 1, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 1, 1, null}, // SHOWA, not HEISEI + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 1, 7, null}, // SHOWA, not HEISEI + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 1, 8, date(1989, 1, 8)}, + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 12, 31, date(1989, 12, 31)}, + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 2, 1, 1, date(1990, 1, 1)}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 1, 7, date(1989, 1, 7)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 1, 8, null}, // HEISEI, not SHOWA + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 12, 31, null}, // HEISEI, not SHOWA + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 65, 1, 1, null}, // HEISEI, not SHOWA + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 0, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 1, date(1987, 1, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 27, date(1987, 1, 27)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 28, date(1987, 1, 28)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 29, date(1987, 1, 29)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 30, date(1987, 1, 30)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 31, date(1987, 1, 31)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 32, null}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 0, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 1, date(1987, 2, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 27, date(1987, 2, 27)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 28, date(1987, 2, 28)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 29, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 30, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 31, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 32, null}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 0, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 1, date(1988, 2, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 27, date(1988, 2, 27)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 28, date(1988, 2, 28)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 29, date(1988, 2, 29)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 30, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 31, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 32, null}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, -12, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, -1, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 0, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 13, 1, null}, + }; + } + + @Test(dataProvider = "resolve_eymd") + public void test_resolve_eymd(ResolverStyle style, JapaneseEra era, int yoe, int m, int d, JapaneseDate expected) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (expected != null) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static JapaneseDate date(int y, int m, int d) { + return JapaneseDate.of(y, m, d); + } + }
--- a/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java Wed Jul 24 08:22:32 2013 -0300 @@ -81,7 +81,6 @@ {JapaneseEra.SHOWA, "Showa", 1}, {JapaneseEra.TAISHO, "Taisho", 0}, {JapaneseEra.MEIJI, "Meiji", -1}, - {JapaneseEra.SEIREKI, "Seireki", -999}, }; } @@ -112,8 +111,8 @@ public void test_range() { // eras may be added after release for (JapaneseEra era : JapaneseEra.values()) { - assertEquals(era.range(ERA).getMinimum(), -999); - assertEquals(era.range(ERA).getLargestMinimum(), -999); + assertEquals(era.range(ERA).getMinimum(), -1); + assertEquals(era.range(ERA).getLargestMinimum(), -1); assertEquals(era.range(ERA).getSmallestMaximum(), era.range(ERA).getMaximum()); assertEquals(era.range(ERA).getMaximum() >= 2, true); }
--- a/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -58,6 +58,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -83,12 +84,19 @@ import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; import java.time.chrono.MinguoEra; +import java.time.chrono.MinguoChronology; +import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -162,6 +170,18 @@ @Test(dataProvider="samples") public void test_fromCalendrical(MinguoDate minguo, LocalDate iso) { assertEquals(MinguoChronology.INSTANCE.date(iso), minguo); + assertEquals(MinguoDate.from(iso), minguo); + } + + @Test(dataProvider="samples") + public void test_isEqual(MinguoDate minguo, LocalDate iso) { + assertTrue(minguo.isEqual(iso)); + } + + @Test(dataProvider="samples") + public void test_date_equals(MinguoDate minguo, LocalDate iso) { + assertFalse(minguo.equals(iso)); + assertNotEquals(minguo.hashCode(), iso.hashCode()); } @Test @@ -276,12 +296,24 @@ @Test(dataProvider="prolepticYear") public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { - Era eraObj = MinguoChronology.INSTANCE.eraOf(eraValue) ; + Era eraObj = MinguoChronology.INSTANCE.eraOf(eraValue); assertTrue(MinguoChronology.INSTANCE.eras().contains(eraObj)); assertEquals(eraObj, era); assertEquals(MinguoChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); - assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; - assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear + YDIFF).isLeap()) ; + } + + @Test(dataProvider="prolepticYear") + public void test_isLeapYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear); + assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear + YDIFF).isLeap()); + + MinguoDate minguo = MinguoDate.now(); + minguo = minguo.with(ChronoField.YEAR, expectedProlepticYear).with(ChronoField.MONTH_OF_YEAR, 2); + if (isLeapYear) { + assertEquals(minguo.lengthOfMonth(), 29); + } else { + assertEquals(minguo.lengthOfMonth(), 28); + } } //----------------------------------------------------------------------- @@ -467,7 +499,7 @@ public void test_periodUntilDate() { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); - Period period = mdate1.periodUntil(mdate2); + Period period = mdate1.until(mdate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -475,7 +507,7 @@ public void test_periodUntilUnit() { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); + long months = mdate1.until(mdate2, ChronoUnit.MONTHS); assertEquals(months, 13); } @@ -484,7 +516,7 @@ MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); ThaiBuddhistDate ldate2 = ThaiBuddhistChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); + Period period = mdate1.until(ldate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -520,4 +552,409 @@ assertFalse(MinguoChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yearOfEra") + Object[][] data_resolve_yearOfEra() { + return new Object[][] { + // era only + {ResolverStyle.STRICT, -1, null, null, null, null}, + {ResolverStyle.SMART, -1, null, null, null, null}, + {ResolverStyle.LENIENT, -1, null, null, null, null}, + + {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0}, + + {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1}, + + {ResolverStyle.STRICT, 2, null, null, null, null}, + {ResolverStyle.SMART, 2, null, null, null, null}, + {ResolverStyle.LENIENT, 2, null, null, null, null}, + + // era and year-of-era + {ResolverStyle.STRICT, -1, 2012, null, null, null}, + {ResolverStyle.SMART, -1, 2012, null, null, null}, + {ResolverStyle.LENIENT, -1, 2012, null, null, null}, + + {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, 2, 2012, null, null, null}, + {ResolverStyle.SMART, 2, 2012, null, null, null}, + {ResolverStyle.LENIENT, 2, 2012, null, null, null}, + + // year-of-era only + {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012}, + {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE}, + + // year-of-era and year + {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, null, 2012, 2013, null, null}, + {ResolverStyle.SMART, null, 2012, 2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, 2013, null, null}, + + {ResolverStyle.STRICT, null, 2012, -2013, null, null}, + {ResolverStyle.SMART, null, 2012, -2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, -2013, null, null}, + }; + } + + @Test(dataProvider = "resolve_yearOfEra") + public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + if (e != null) { + fieldValues.put(ChronoField.ERA, (long) e); + } + if (yoe != null) { + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + } + if (y != null) { + fieldValues.put(ChronoField.YEAR, (long) y); + } + if (field != null) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(field), (Long) expected.longValue()); + assertEquals(fieldValues.size(), 1); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + return new Object[][] { + {2012 - YDIFF, 1, -365, date(2010 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, -364, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, -31, date(2011 - YDIFF, 11, 30), false, false}, + {2012 - YDIFF, 1, -30, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, -12, date(2011 - YDIFF, 12, 19), false, false}, + {2012 - YDIFF, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 1, 27, date(2012 - YDIFF, 1, 27), true, true}, + {2012 - YDIFF, 1, 28, date(2012 - YDIFF, 1, 28), true, true}, + {2012 - YDIFF, 1, 29, date(2012 - YDIFF, 1, 29), true, true}, + {2012 - YDIFF, 1, 30, date(2012 - YDIFF, 1, 30), true, true}, + {2012 - YDIFF, 1, 31, date(2012 - YDIFF, 1, 31), true, true}, + {2012 - YDIFF, 1, 59, date(2012 - YDIFF, 2, 28), false, false}, + {2012 - YDIFF, 1, 60, date(2012 - YDIFF, 2, 29), false, false}, + {2012 - YDIFF, 1, 61, date(2012 - YDIFF, 3, 1), false, false}, + {2012 - YDIFF, 1, 365, date(2012 - YDIFF, 12, 30), false, false}, + {2012 - YDIFF, 1, 366, date(2012 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 367, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, 367 + 364, date(2013 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 367 + 365, date(2014 - YDIFF, 1, 1), false, false}, + + {2012 - YDIFF, 2, 1, date(2012 - YDIFF, 2, 1), true, true}, + {2012 - YDIFF, 2, 28, date(2012 - YDIFF, 2, 28), true, true}, + {2012 - YDIFF, 2, 29, date(2012 - YDIFF, 2, 29), true, true}, + {2012 - YDIFF, 2, 30, date(2012 - YDIFF, 3, 1), date(2012 - YDIFF, 2, 29), false}, + {2012 - YDIFF, 2, 31, date(2012 - YDIFF, 3, 2), date(2012 - YDIFF, 2, 29), false}, + {2012 - YDIFF, 2, 32, date(2012 - YDIFF, 3, 3), false, false}, + + {2012 - YDIFF, -12, 1, date(2010 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, -11, 1, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, -1, 1, date(2011 - YDIFF, 11, 1), false, false}, + {2012 - YDIFF, 0, 1, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 12, 1, date(2012 - YDIFF, 12, 1), true, true}, + {2012 - YDIFF, 13, 1, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 24, 1, date(2013 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 25, 1, date(2014 - YDIFF, 1, 1), false, false}, + + {2012 - YDIFF, 6, -31, date(2012 - YDIFF, 4, 30), false, false}, + {2012 - YDIFF, 6, -30, date(2012 - YDIFF, 5, 1), false, false}, + {2012 - YDIFF, 6, -1, date(2012 - YDIFF, 5, 30), false, false}, + {2012 - YDIFF, 6, 0, date(2012 - YDIFF, 5, 31), false, false}, + {2012 - YDIFF, 6, 1, date(2012 - YDIFF, 6, 1), true, true}, + {2012 - YDIFF, 6, 30, date(2012 - YDIFF, 6, 30), true, true}, + {2012 - YDIFF, 6, 31, date(2012 - YDIFF, 7, 1), date(2012 - YDIFF, 6, 30), false}, + {2012 - YDIFF, 6, 61, date(2012 - YDIFF, 7, 31), false, false}, + {2012 - YDIFF, 6, 62, date(2012 - YDIFF, 8, 1), false, false}, + + {2011 - YDIFF, 2, 1, date(2011 - YDIFF, 2, 1), true, true}, + {2011 - YDIFF, 2, 28, date(2011 - YDIFF, 2, 28), true, true}, + {2011 - YDIFF, 2, 29, date(2011 - YDIFF, 3, 1), date(2011 - YDIFF, 2, 28), false}, + {2011 - YDIFF, 2, 30, date(2011 - YDIFF, 3, 2), date(2011 - YDIFF, 2, 28), false}, + {2011 - YDIFF, 2, 31, date(2011 - YDIFF, 3, 3), date(2011 - YDIFF, 2, 28), false}, + {2011 - YDIFF, 2, 32, date(2011 - YDIFF, 3, 4), false, false}, + }; + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, MinguoDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, MinguoDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof MinguoDate) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, MinguoDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + return new Object[][] { + {2012 - YDIFF, -365, date(2010 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, -364, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, -31, date(2011 - YDIFF, 11, 30), false, false}, + {2012 - YDIFF, -30, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, -12, date(2011 - YDIFF, 12, 19), false, false}, + {2012 - YDIFF, -1, date(2011 - YDIFF, 12, 30), false, false}, + {2012 - YDIFF, 0, date(2011 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 2, date(2012 - YDIFF, 1, 2), true, true}, + {2012 - YDIFF, 31, date(2012 - YDIFF, 1, 31), true, true}, + {2012 - YDIFF, 32, date(2012 - YDIFF, 2, 1), true, true}, + {2012 - YDIFF, 59, date(2012 - YDIFF, 2, 28), true, true}, + {2012 - YDIFF, 60, date(2012 - YDIFF, 2, 29), true, true}, + {2012 - YDIFF, 61, date(2012 - YDIFF, 3, 1), true, true}, + {2012 - YDIFF, 365, date(2012 - YDIFF, 12, 30), true, true}, + {2012 - YDIFF, 366, date(2012 - YDIFF, 12, 31), true, true}, + {2012 - YDIFF, 367, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 367 + 364, date(2013 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 367 + 365, date(2014 - YDIFF, 1, 1), false, false}, + + {2011 - YDIFF, 59, date(2011 - YDIFF, 2, 28), true, true}, + {2011 - YDIFF, 60, date(2011 - YDIFF, 3, 1), true, true}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, MinguoDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, MinguoDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, MinguoDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymaa") + Object[][] data_resolve_ymaa() { + return new Object[][] { + {2012 - YDIFF, 1, 1, -365, date(2010 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 1, -364, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, 1, -31, date(2011 - YDIFF, 11, 30), false, false}, + {2012 - YDIFF, 1, 1, -30, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, 1, -12, date(2011 - YDIFF, 12, 19), false, false}, + {2012 - YDIFF, 1, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 1, 1, 59, date(2012 - YDIFF, 2, 28), false, false}, + {2012 - YDIFF, 1, 1, 60, date(2012 - YDIFF, 2, 29), false, false}, + {2012 - YDIFF, 1, 1, 61, date(2012 - YDIFF, 3, 1), false, false}, + {2012 - YDIFF, 1, 1, 365, date(2012 - YDIFF, 12, 30), false, false}, + {2012 - YDIFF, 1, 1, 366, date(2012 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 1, 367, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, 1, 367 + 364, date(2013 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 1, 367 + 365, date(2014 - YDIFF, 1, 1), false, false}, + + {2012 - YDIFF, 2, 0, 1, date(2012 - YDIFF, 1, 25), false, false}, + {2012 - YDIFF, 2, 0, 7, date(2012 - YDIFF, 1, 31), false, false}, + {2012 - YDIFF, 2, 1, 1, date(2012 - YDIFF, 2, 1), true, true}, + {2012 - YDIFF, 2, 1, 7, date(2012 - YDIFF, 2, 7), true, true}, + {2012 - YDIFF, 2, 2, 1, date(2012 - YDIFF, 2, 8), true, true}, + {2012 - YDIFF, 2, 2, 7, date(2012 - YDIFF, 2, 14), true, true}, + {2012 - YDIFF, 2, 3, 1, date(2012 - YDIFF, 2, 15), true, true}, + {2012 - YDIFF, 2, 3, 7, date(2012 - YDIFF, 2, 21), true, true}, + {2012 - YDIFF, 2, 4, 1, date(2012 - YDIFF, 2, 22), true, true}, + {2012 - YDIFF, 2, 4, 7, date(2012 - YDIFF, 2, 28), true, true}, + {2012 - YDIFF, 2, 5, 1, date(2012 - YDIFF, 2, 29), true, true}, + {2012 - YDIFF, 2, 5, 2, date(2012 - YDIFF, 3, 1), true, false}, + {2012 - YDIFF, 2, 5, 7, date(2012 - YDIFF, 3, 6), true, false}, + {2012 - YDIFF, 2, 6, 1, date(2012 - YDIFF, 3, 7), false, false}, + {2012 - YDIFF, 2, 6, 7, date(2012 - YDIFF, 3, 13), false, false}, + + {2012 - YDIFF, 12, 1, 1, date(2012 - YDIFF, 12, 1), true, true}, + {2012 - YDIFF, 12, 5, 1, date(2012 - YDIFF, 12, 29), true, true}, + {2012 - YDIFF, 12, 5, 2, date(2012 - YDIFF, 12, 30), true, true}, + {2012 - YDIFF, 12, 5, 3, date(2012 - YDIFF, 12, 31), true, true}, + {2012 - YDIFF, 12, 5, 4, date(2013 - YDIFF, 1, 1), true, false}, + {2012 - YDIFF, 12, 5, 7, date(2013 - YDIFF, 1, 4), true, false}, + + {2012 - YDIFF, -12, 1, 1, date(2010 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, -11, 1, 1, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, -1, 1, 1, date(2011 - YDIFF, 11, 1), false, false}, + {2012 - YDIFF, 0, 1, 1, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 12, 1, 1, date(2012 - YDIFF, 12, 1), true, true}, + {2012 - YDIFF, 13, 1, 1, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 24, 1, 1, date(2013 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 25, 1, 1, date(2014 - YDIFF, 1, 1), false, false}, + + {2011 - YDIFF, 2, 1, 1, date(2011 - YDIFF, 2, 1), true, true}, + {2011 - YDIFF, 2, 4, 7, date(2011 - YDIFF, 2, 28), true, true}, + {2011 - YDIFF, 2, 5, 1, date(2011 - YDIFF, 3, 1), true, false}, + }; + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_lenient(int y, int m, int w, int d, MinguoDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_smart(int y, int m, int w, int d, MinguoDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (smart) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_strict(int y, int m, int w, int d, MinguoDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (strict) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static MinguoDate date(int y, int m, int d) { + return MinguoDate.of(y, m, d); + } + }
--- a/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -63,6 +63,7 @@ import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -84,12 +85,16 @@ import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; import java.time.chrono.ThaiBuddhistEra; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -200,6 +205,18 @@ @Test(dataProvider="samples") public void test_fromCalendrical(ThaiBuddhistDate jdate, LocalDate iso) { assertEquals(ThaiBuddhistChronology.INSTANCE.date(iso), jdate); + assertEquals(ThaiBuddhistDate.from(iso), jdate); + } + + @Test(dataProvider="samples") + public void test_isEqual(ThaiBuddhistDate jdate, LocalDate iso) { + assertTrue(jdate.isEqual(iso)); + } + + @Test(dataProvider="samples") + public void test_date_equals(ThaiBuddhistDate jdate, LocalDate iso) { + assertFalse(jdate.equals(iso)); + assertNotEquals(jdate.hashCode(), iso.hashCode()); } @Test @@ -251,46 +268,58 @@ ThaiBuddhistChronology.INSTANCE.date(year, month, dom); } - //----------------------------------------------------------------------- - // prolepticYear() and is LeapYear() - //----------------------------------------------------------------------- - @DataProvider(name="prolepticYear") - Object[][] data_prolepticYear() { - return new Object[][] { - {1, ThaiBuddhistEra.BE, 4 + YDIFF, 4 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, 7 + YDIFF, 7 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, 8 + YDIFF, 8 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, 1000 + YDIFF, 1000 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, 2000 + YDIFF, 2000 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, 0, 0, false}, - {1, ThaiBuddhistEra.BE, -4 + YDIFF, -4 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, -7 + YDIFF, -7 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, -100 + YDIFF, -100 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, -800 + YDIFF, -800 + YDIFF, true}, + //----------------------------------------------------------------------- + // prolepticYear() and is LeapYear() + //----------------------------------------------------------------------- + @DataProvider(name="prolepticYear") + Object[][] data_prolepticYear() { + return new Object[][] { + {1, ThaiBuddhistEra.BE, 4 + YDIFF, 4 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, 7 + YDIFF, 7 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, 8 + YDIFF, 8 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, 1000 + YDIFF, 1000 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, 2000 + YDIFF, 2000 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, 0, 0, false}, + {1, ThaiBuddhistEra.BE, -4 + YDIFF, -4 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, -7 + YDIFF, -7 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, -100 + YDIFF, -100 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, -800 + YDIFF, -800 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, -3 - YDIFF, 4 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, -6 - YDIFF, 7 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, -7 - YDIFF, 8 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, -999 - YDIFF, 1000 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, -1999 - YDIFF, 2000 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, 1, 0, false}, - {0, ThaiBuddhistEra.BEFORE_BE, 5 - YDIFF, -4 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, 8 - YDIFF, -7 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, 101 - YDIFF, -100 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, 801 - YDIFF, -800 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, -3 - YDIFF, 4 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, -6 - YDIFF, 7 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, -7 - YDIFF, 8 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, -999 - YDIFF, 1000 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, -1999 - YDIFF, 2000 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, 1, 0, false}, + {0, ThaiBuddhistEra.BEFORE_BE, 5 - YDIFF, -4 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, 8 - YDIFF, -7 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, 101 - YDIFF, -100 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, 801 - YDIFF, -800 + YDIFF, true}, + + }; + } - }; - } + @Test(dataProvider="prolepticYear") + public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + Era eraObj = ThaiBuddhistChronology.INSTANCE.eraOf(eraValue); + assertTrue(ThaiBuddhistChronology.INSTANCE.eras().contains(eraObj)); + assertEquals(eraObj, era); + assertEquals(ThaiBuddhistChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); + } - @Test(dataProvider="prolepticYear") - public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { - Era eraObj = ThaiBuddhistChronology.INSTANCE.eraOf(eraValue) ; - assertTrue(ThaiBuddhistChronology.INSTANCE.eras().contains(eraObj)); - assertEquals(eraObj, era); - assertEquals(ThaiBuddhistChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); - assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; - assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear - YDIFF).isLeap()) ; - } + @Test(dataProvider="prolepticYear") + public void test_isLeapYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; + assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear - YDIFF).isLeap()); + + ThaiBuddhistDate jdate = ThaiBuddhistDate.now(); + jdate = jdate.with(ChronoField.YEAR, expectedProlepticYear).with(ChronoField.MONTH_OF_YEAR, 2); + if (isLeapYear) { + assertEquals(jdate.lengthOfMonth(), 29); + } else { + assertEquals(jdate.lengthOfMonth(), 28); + } + } //----------------------------------------------------------------------- // Bad Era for Chronology.date(era,...) and Chronology.prolepticYear(Era,...) @@ -429,7 +458,7 @@ public void test_periodUntilDate() { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); - Period period = mdate1.periodUntil(mdate2); + Period period = mdate1.until(mdate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -437,7 +466,7 @@ public void test_periodUntilUnit() { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); + long months = mdate1.until(mdate2, ChronoUnit.MONTHS); assertEquals(months, 13); } @@ -446,7 +475,7 @@ ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); + Period period = mdate1.until(ldate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -497,4 +526,409 @@ assertFalse(ThaiBuddhistChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yearOfEra") + Object[][] data_resolve_yearOfEra() { + return new Object[][] { + // era only + {ResolverStyle.STRICT, -1, null, null, null, null}, + {ResolverStyle.SMART, -1, null, null, null, null}, + {ResolverStyle.LENIENT, -1, null, null, null, null}, + + {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0}, + + {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1}, + + {ResolverStyle.STRICT, 2, null, null, null, null}, + {ResolverStyle.SMART, 2, null, null, null, null}, + {ResolverStyle.LENIENT, 2, null, null, null, null}, + + // era and year-of-era + {ResolverStyle.STRICT, -1, 2012, null, null, null}, + {ResolverStyle.SMART, -1, 2012, null, null, null}, + {ResolverStyle.LENIENT, -1, 2012, null, null, null}, + + {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, 2, 2012, null, null, null}, + {ResolverStyle.SMART, 2, 2012, null, null, null}, + {ResolverStyle.LENIENT, 2, 2012, null, null, null}, + + // year-of-era only + {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012}, + {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE}, + + // year-of-era and year + {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, null, 2012, 2013, null, null}, + {ResolverStyle.SMART, null, 2012, 2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, 2013, null, null}, + + {ResolverStyle.STRICT, null, 2012, -2013, null, null}, + {ResolverStyle.SMART, null, 2012, -2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, -2013, null, null}, + }; + } + + @Test(dataProvider = "resolve_yearOfEra") + public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + if (e != null) { + fieldValues.put(ChronoField.ERA, (long) e); + } + if (yoe != null) { + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + } + if (y != null) { + fieldValues.put(ChronoField.YEAR, (long) y); + } + if (field != null) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(field), (Long) expected.longValue()); + assertEquals(fieldValues.size(), 1); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + return new Object[][] { + {YDIFF + 2012, 1, -365, date(YDIFF + 2010, 12, 31), false, false}, + {YDIFF + 2012, 1, -364, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, 1, -31, date(YDIFF + 2011, 11, 30), false, false}, + {YDIFF + 2012, 1, -30, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, -12, date(YDIFF + 2011, 12, 19), false, false}, + {YDIFF + 2012, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 1, 27, date(YDIFF + 2012, 1, 27), true, true}, + {YDIFF + 2012, 1, 28, date(YDIFF + 2012, 1, 28), true, true}, + {YDIFF + 2012, 1, 29, date(YDIFF + 2012, 1, 29), true, true}, + {YDIFF + 2012, 1, 30, date(YDIFF + 2012, 1, 30), true, true}, + {YDIFF + 2012, 1, 31, date(YDIFF + 2012, 1, 31), true, true}, + {YDIFF + 2012, 1, 59, date(YDIFF + 2012, 2, 28), false, false}, + {YDIFF + 2012, 1, 60, date(YDIFF + 2012, 2, 29), false, false}, + {YDIFF + 2012, 1, 61, date(YDIFF + 2012, 3, 1), false, false}, + {YDIFF + 2012, 1, 365, date(YDIFF + 2012, 12, 30), false, false}, + {YDIFF + 2012, 1, 366, date(YDIFF + 2012, 12, 31), false, false}, + {YDIFF + 2012, 1, 367, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 1, 367 + 364, date(YDIFF + 2013, 12, 31), false, false}, + {YDIFF + 2012, 1, 367 + 365, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2012, 2, 1, date(YDIFF + 2012, 2, 1), true, true}, + {YDIFF + 2012, 2, 28, date(YDIFF + 2012, 2, 28), true, true}, + {YDIFF + 2012, 2, 29, date(YDIFF + 2012, 2, 29), true, true}, + {YDIFF + 2012, 2, 30, date(YDIFF + 2012, 3, 1), date(YDIFF + 2012, 2, 29), false}, + {YDIFF + 2012, 2, 31, date(YDIFF + 2012, 3, 2), date(YDIFF + 2012, 2, 29), false}, + {YDIFF + 2012, 2, 32, date(YDIFF + 2012, 3, 3), false, false}, + + {YDIFF + 2012, -12, 1, date(YDIFF + 2010, 12, 1), false, false}, + {YDIFF + 2012, -11, 1, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, -1, 1, date(YDIFF + 2011, 11, 1), false, false}, + {YDIFF + 2012, 0, 1, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 12, 1, date(YDIFF + 2012, 12, 1), true, true}, + {YDIFF + 2012, 13, 1, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 24, 1, date(YDIFF + 2013, 12, 1), false, false}, + {YDIFF + 2012, 25, 1, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2012, 6, -31, date(YDIFF + 2012, 4, 30), false, false}, + {YDIFF + 2012, 6, -30, date(YDIFF + 2012, 5, 1), false, false}, + {YDIFF + 2012, 6, -1, date(YDIFF + 2012, 5, 30), false, false}, + {YDIFF + 2012, 6, 0, date(YDIFF + 2012, 5, 31), false, false}, + {YDIFF + 2012, 6, 1, date(YDIFF + 2012, 6, 1), true, true}, + {YDIFF + 2012, 6, 30, date(YDIFF + 2012, 6, 30), true, true}, + {YDIFF + 2012, 6, 31, date(YDIFF + 2012, 7, 1), date(YDIFF + 2012, 6, 30), false}, + {YDIFF + 2012, 6, 61, date(YDIFF + 2012, 7, 31), false, false}, + {YDIFF + 2012, 6, 62, date(YDIFF + 2012, 8, 1), false, false}, + + {YDIFF + 2011, 2, 1, date(YDIFF + 2011, 2, 1), true, true}, + {YDIFF + 2011, 2, 28, date(YDIFF + 2011, 2, 28), true, true}, + {YDIFF + 2011, 2, 29, date(YDIFF + 2011, 3, 1), date(YDIFF + 2011, 2, 28), false}, + {YDIFF + 2011, 2, 30, date(YDIFF + 2011, 3, 2), date(YDIFF + 2011, 2, 28), false}, + {YDIFF + 2011, 2, 31, date(YDIFF + 2011, 3, 3), date(YDIFF + 2011, 2, 28), false}, + {YDIFF + 2011, 2, 32, date(YDIFF + 2011, 3, 4), false, false}, + }; + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, ThaiBuddhistDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, ThaiBuddhistDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof ThaiBuddhistDate) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, ThaiBuddhistDate expected, Object smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + return new Object[][] { + {YDIFF + 2012, -365, date(YDIFF + 2010, 12, 31), false, false}, + {YDIFF + 2012, -364, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, -31, date(YDIFF + 2011, 11, 30), false, false}, + {YDIFF + 2012, -30, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, -12, date(YDIFF + 2011, 12, 19), false, false}, + {YDIFF + 2012, -1, date(YDIFF + 2011, 12, 30), false, false}, + {YDIFF + 2012, 0, date(YDIFF + 2011, 12, 31), false, false}, + {YDIFF + 2012, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 2, date(YDIFF + 2012, 1, 2), true, true}, + {YDIFF + 2012, 31, date(YDIFF + 2012, 1, 31), true, true}, + {YDIFF + 2012, 32, date(YDIFF + 2012, 2, 1), true, true}, + {YDIFF + 2012, 59, date(YDIFF + 2012, 2, 28), true, true}, + {YDIFF + 2012, 60, date(YDIFF + 2012, 2, 29), true, true}, + {YDIFF + 2012, 61, date(YDIFF + 2012, 3, 1), true, true}, + {YDIFF + 2012, 365, date(YDIFF + 2012, 12, 30), true, true}, + {YDIFF + 2012, 366, date(YDIFF + 2012, 12, 31), true, true}, + {YDIFF + 2012, 367, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 367 + 364, date(YDIFF + 2013, 12, 31), false, false}, + {YDIFF + 2012, 367 + 365, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2011, 59, date(YDIFF + 2011, 2, 28), true, true}, + {YDIFF + 2011, 60, date(YDIFF + 2011, 3, 1), true, true}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymaa") + Object[][] data_resolve_ymaa() { + return new Object[][] { + {YDIFF + 2012, 1, 1, -365, date(YDIFF + 2010, 12, 31), false, false}, + {YDIFF + 2012, 1, 1, -364, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, 1, 1, -31, date(YDIFF + 2011, 11, 30), false, false}, + {YDIFF + 2012, 1, 1, -30, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, 1, -12, date(YDIFF + 2011, 12, 19), false, false}, + {YDIFF + 2012, 1, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 1, 1, 59, date(YDIFF + 2012, 2, 28), false, false}, + {YDIFF + 2012, 1, 1, 60, date(YDIFF + 2012, 2, 29), false, false}, + {YDIFF + 2012, 1, 1, 61, date(YDIFF + 2012, 3, 1), false, false}, + {YDIFF + 2012, 1, 1, 365, date(YDIFF + 2012, 12, 30), false, false}, + {YDIFF + 2012, 1, 1, 366, date(YDIFF + 2012, 12, 31), false, false}, + {YDIFF + 2012, 1, 1, 367, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 1, 1, 367 + 364, date(YDIFF + 2013, 12, 31), false, false}, + {YDIFF + 2012, 1, 1, 367 + 365, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2012, 2, 0, 1, date(YDIFF + 2012, 1, 25), false, false}, + {YDIFF + 2012, 2, 0, 7, date(YDIFF + 2012, 1, 31), false, false}, + {YDIFF + 2012, 2, 1, 1, date(YDIFF + 2012, 2, 1), true, true}, + {YDIFF + 2012, 2, 1, 7, date(YDIFF + 2012, 2, 7), true, true}, + {YDIFF + 2012, 2, 2, 1, date(YDIFF + 2012, 2, 8), true, true}, + {YDIFF + 2012, 2, 2, 7, date(YDIFF + 2012, 2, 14), true, true}, + {YDIFF + 2012, 2, 3, 1, date(YDIFF + 2012, 2, 15), true, true}, + {YDIFF + 2012, 2, 3, 7, date(YDIFF + 2012, 2, 21), true, true}, + {YDIFF + 2012, 2, 4, 1, date(YDIFF + 2012, 2, 22), true, true}, + {YDIFF + 2012, 2, 4, 7, date(YDIFF + 2012, 2, 28), true, true}, + {YDIFF + 2012, 2, 5, 1, date(YDIFF + 2012, 2, 29), true, true}, + {YDIFF + 2012, 2, 5, 2, date(YDIFF + 2012, 3, 1), true, false}, + {YDIFF + 2012, 2, 5, 7, date(YDIFF + 2012, 3, 6), true, false}, + {YDIFF + 2012, 2, 6, 1, date(YDIFF + 2012, 3, 7), false, false}, + {YDIFF + 2012, 2, 6, 7, date(YDIFF + 2012, 3, 13), false, false}, + + {YDIFF + 2012, 12, 1, 1, date(YDIFF + 2012, 12, 1), true, true}, + {YDIFF + 2012, 12, 5, 1, date(YDIFF + 2012, 12, 29), true, true}, + {YDIFF + 2012, 12, 5, 2, date(YDIFF + 2012, 12, 30), true, true}, + {YDIFF + 2012, 12, 5, 3, date(YDIFF + 2012, 12, 31), true, true}, + {YDIFF + 2012, 12, 5, 4, date(YDIFF + 2013, 1, 1), true, false}, + {YDIFF + 2012, 12, 5, 7, date(YDIFF + 2013, 1, 4), true, false}, + + {YDIFF + 2012, -12, 1, 1, date(YDIFF + 2010, 12, 1), false, false}, + {YDIFF + 2012, -11, 1, 1, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, -1, 1, 1, date(YDIFF + 2011, 11, 1), false, false}, + {YDIFF + 2012, 0, 1, 1, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 12, 1, 1, date(YDIFF + 2012, 12, 1), true, true}, + {YDIFF + 2012, 13, 1, 1, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 24, 1, 1, date(YDIFF + 2013, 12, 1), false, false}, + {YDIFF + 2012, 25, 1, 1, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2011, 2, 1, 1, date(YDIFF + 2011, 2, 1), true, true}, + {YDIFF + 2011, 2, 4, 7, date(YDIFF + 2011, 2, 28), true, true}, + {YDIFF + 2011, 2, 5, 1, date(YDIFF + 2011, 3, 1), true, false}, + }; + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_lenient(int y, int m, int w, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_smart(int y, int m, int w, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (smart) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_strict(int y, int m, int w, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map<TemporalField, Long> fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (strict) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static ThaiBuddhistDate date(int y, int m, int d) { + return ThaiBuddhistDate.of(y, m, d); + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/time/tck/java/time/format/TCKFormatStyle.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012, 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. 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.format; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.FormatStyle; +import java.time.temporal.Temporal; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKFormatStyle { + + private static final ZoneId ZONEID_PARIS = ZoneId.of("Europe/Paris"); + private static final ZoneId OFFSET_PTWO = ZoneOffset.of("+02:00"); + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (FormatStyle style : FormatStyle.values()) { + assertEquals(FormatStyle.valueOf(style.name()), style); + } + } + + @DataProvider(name="formatStyle") + Object[][] data_formatStyle() { + return new Object[][] { + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.FULL, "Tuesday, October 2, 2001 1:02:03 AM CEST Europe/Paris"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.LONG, "October 2, 2001 1:02:03 AM CEST Europe/Paris"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.MEDIUM, "Oct 2, 2001 1:02:03 AM Europe/Paris"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.SHORT, "10/2/01 1:02 AM Europe/Paris"}, + + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.FULL, "Tuesday, October 2, 2001 1:02:03 AM +02:00 +02:00"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.LONG, "October 2, 2001 1:02:03 AM +02:00 +02:00"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.MEDIUM, "Oct 2, 2001 1:02:03 AM +02:00"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.SHORT, "10/2/01 1:02 AM +02:00"}, + }; + } + + @Test(dataProvider = "formatStyle") + public void test_formatStyle(Temporal temporal, FormatStyle style, String formattedStr) { + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); + DateTimeFormatter formatter = builder.appendLocalized(style, style).appendLiteral(" ").appendZoneOrOffsetId().toFormatter(); + assertEquals(formatter.format(temporal), formattedStr); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/time/tck/java/time/format/TCKResolverStyle.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2012, 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. 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.format; + +import java.util.HashMap; +import java.util.Map; + +import java.time.DateTimeException; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAccessor; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKResolverStyle { + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (ResolverStyle style : ResolverStyle.values()) { + assertEquals(ResolverStyle.valueOf(style.name()), style); + } + } + + @DataProvider(name="resolverStyle") + Object[][] data_resolverStyle() { + return new Object[][] { + {"2000/15/30", ResolverStyle.LENIENT, null, 2001, 3, 30}, + {"2000/02/30", ResolverStyle.SMART, null, 2000, 2, 29}, + {"2000/02/29", ResolverStyle.STRICT, null, 2000, 2, 29}, + + {"2000/15/30 CE", ResolverStyle.LENIENT, null, 2001, 3, 30}, + {"2000/02/30 CE", ResolverStyle.SMART, null, 2000, 2, 29}, + {"5/02/29 BCE", ResolverStyle.STRICT, null, 5, 2, 29}, + + {"4/02/29 BCE", ResolverStyle.STRICT, DateTimeException.class, -1, -1, -1}, + {"2000/02/30 CE", ResolverStyle.STRICT, DateTimeException.class, -1, -1, -1}, + + }; + } + + @Test(dataProvider = "resolverStyle") + public void test_resolverStyle(String str, ResolverStyle style, Class<?> expectedEx, int year, int month, int day) { + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); + builder.appendValue(ChronoField.YEAR_OF_ERA); + builder.appendLiteral("/"); + builder.appendValue(ChronoField.MONTH_OF_YEAR); + builder.appendLiteral("/"); + builder.appendValue(ChronoField.DAY_OF_MONTH); + + Map<Long, String> eraMap = new HashMap<Long, String>(); + eraMap.put(1L, "CE"); + eraMap.put(0L, "BCE"); + DateTimeFormatter optionalFormatter = new DateTimeFormatterBuilder().appendLiteral(" ").appendText(ChronoField.ERA, eraMap).toFormatter(); + + DateTimeFormatter formatter = builder.appendOptional(optionalFormatter).toFormatter(); + formatter = formatter.withResolverStyle(style); + if (expectedEx == null) { + TemporalAccessor accessor = formatter.parse(str); + assertEquals(accessor.get(ChronoField.YEAR_OF_ERA), year); + assertEquals(accessor.get(ChronoField.MONTH_OF_YEAR), month); + assertEquals(accessor.get(ChronoField.DAY_OF_MONTH), day); + } else { + try { + formatter.parse(str); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/time/tck/java/time/format/TCKSignStyle.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012, 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. 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.format; + +import java.time.DateTimeException; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.SignStyle; +import java.time.temporal.ChronoField; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKSignStyle { + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (SignStyle style : SignStyle.values()) { + assertEquals(SignStyle.valueOf(style.name()), style); + } + } + + @DataProvider(name="signStyle") + Object[][] data_signStyle() { + return new Object[][] { + {LocalDate.of(0, 10, 2), SignStyle.ALWAYS, null, "+00"}, + {LocalDate.of(2001, 10, 2), SignStyle.ALWAYS, null, "+2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.ALWAYS, null, "-2001"}, + + {LocalDate.of(2001, 10, 2), SignStyle.NORMAL, null, "2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.NORMAL, null, "-2001"}, + + {LocalDate.of(2001, 10, 2), SignStyle.NEVER, null, "2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.NEVER, null, "2001"}, + + {LocalDate.of(2001, 10, 2), SignStyle.NOT_NEGATIVE, null, "2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.NOT_NEGATIVE, DateTimeException.class, ""}, + + {LocalDate.of(0, 10, 2), SignStyle.EXCEEDS_PAD, null, "00"}, + {LocalDate.of(1, 10, 2), SignStyle.EXCEEDS_PAD, null, "01"}, + {LocalDate.of(-1, 10, 2), SignStyle.EXCEEDS_PAD, null, "-01"}, + + {LocalDate.of(20001, 10, 2), SignStyle.ALWAYS, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.NORMAL, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.NEVER, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.EXCEEDS_PAD, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.NOT_NEGATIVE, DateTimeException.class, ""}, + }; + } + + @Test(dataProvider = "signStyle") + public void test_signStyle(LocalDate localDate, SignStyle style, Class<?> expectedEx, String expectedStr) { + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); + DateTimeFormatter formatter = builder.appendValue(ChronoField.YEAR, 2, 4, style) + .toFormatter(); + formatter = formatter.withZone(ZoneOffset.UTC); + if (expectedEx == null) { + String output = formatter.format(localDate); + assertEquals(output, expectedStr); + } else { + try { + formatter.format(localDate); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } + +}
--- a/test/java/time/tck/java/time/format/TCKTextStyle.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/format/TCKTextStyle.java Wed Jul 24 08:22:32 2013 -0300 @@ -91,4 +91,14 @@ assertTrue(!TextStyle.NARROW.isStandalone()); } + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (TextStyle style : TextStyle.values()) { + assertEquals(TextStyle.valueOf(style.name()), style); + } + } + }
--- a/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java Wed Jul 24 08:22:32 2013 -0300 @@ -60,16 +60,20 @@ package tck.java.time.format; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import java.text.ParsePosition; +import java.time.DateTimeException; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalQuery; import java.util.Locale; +import java.util.Objects; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; @@ -148,43 +152,44 @@ @DataProvider(name="parseSuccess") Object[][] data_parseSuccess() { return new Object[][] { - {"Z", 1, -1, ZoneOffset.UTC}, - {"UTC", 3, -1, ZoneOffset.UTC}, - {"UT", 2, -1, ZoneOffset.UTC}, - {"GMT", 3, -1, ZoneOffset.UTC}, - {"UTC0", 4, -1, ZoneOffset.UTC}, - {"UT0", 3, -1, ZoneOffset.UTC}, - {"GMT0", 4, -1, ZoneOffset.UTC}, + {"Z", 1, -1, ZoneId.of("Z")}, + {"UTC", 3, -1, ZoneId.of("UTC")}, + {"UT", 2, -1, ZoneId.of("UT")}, + {"GMT", 3, -1, ZoneId.of("GMT")}, {"+00:00", 6, -1, ZoneOffset.UTC}, - {"UTC+00:00", 9, -1, ZoneOffset.UTC}, - {"UT+00:00", 8, -1, ZoneOffset.UTC}, - {"GMT+00:00", 9, -1, ZoneOffset.UTC}, + {"UTC+00:00", 9, -1, ZoneId.of("UTC")}, + {"UT+00:00", 8, -1, ZoneId.of("UT")}, + {"GMT+00:00", 9, -1, ZoneId.of("GMT")}, {"-00:00", 6, -1, ZoneOffset.UTC}, - {"UTC-00:00", 9, -1, ZoneOffset.UTC}, - {"UT-00:00", 8, -1, ZoneOffset.UTC}, - {"GMT-00:00", 9, -1, ZoneOffset.UTC}, + {"UTC-00:00", 9, -1, ZoneId.of("UTC")}, + {"UT-00:00", 8, -1, ZoneId.of("UT")}, + {"GMT-00:00", 9, -1, ZoneId.of("GMT")}, {"+01:30", 6, -1, ZoneOffset.ofHoursMinutes(1, 30)}, - {"UTC+01:30", 9, -1, ZoneOffset.ofHoursMinutes(1, 30)}, - {"UT+02:30", 8, -1, ZoneOffset.ofHoursMinutes(2, 30)}, - {"GMT+03:30", 9, -1, ZoneOffset.ofHoursMinutes(3, 30)}, + {"UTC+01:30", 9, -1, ZoneId.of("UTC+01:30")}, + {"UT+02:30", 8, -1, ZoneId.of("UT+02:30")}, + {"GMT+03:30", 9, -1, ZoneId.of("GMT+03:30")}, {"-01:30", 6, -1, ZoneOffset.ofHoursMinutes(-1, -30)}, - {"UTC-01:30", 9, -1, ZoneOffset.ofHoursMinutes(-1, -30)}, - {"UT-02:30", 8, -1, ZoneOffset.ofHoursMinutes(-2, -30)}, - {"GMT-03:30", 9, -1, ZoneOffset.ofHoursMinutes(-3, -30)}, + {"UTC-01:30", 9, -1, ZoneId.of("UTC-01:30")}, + {"UT-02:30", 8, -1, ZoneId.of("UT-02:30")}, + {"GMT-03:30", 9, -1, ZoneId.of("GMT-03:30")}, // fallback to UTC - {"UTC-01:WW", 3, -1, ZoneOffset.UTC}, - {"UT-02:WW", 2, -1, ZoneOffset.UTC}, - {"GMT-03:WW", 3, -1, ZoneOffset.UTC}, + {"UTC-01:WW", 3, -1, ZoneId.of("UTC")}, + {"UT-02:WW", 2, -1, ZoneId.of("UT")}, + {"GMT-03:WW", 3, -1, ZoneId.of("GMT")}, {"Z0", 1, -1, ZoneOffset.UTC}, - {"UTC1", 3, -1, ZoneOffset.UTC}, + {"UTC1", 3, -1, ZoneId.of("UTC")}, // Z not parsed as zero - {"UTCZ", 3, -1, ZoneOffset.UTC}, - {"UTZ", 2, -1, ZoneOffset.UTC}, - {"GMTZ", 3, -1, ZoneOffset.UTC}, + {"UTCZ", 3, -1, ZoneId.of("UTC")}, + {"UTZ", 2, -1, ZoneId.of("UT")}, + {"GMTZ", 3, -1, ZoneId.of("GMT")}, + + // 0 not parsed + {"UTC0", 3, -1, ZoneId.of("UTC")}, + {"UT0", 2, -1, ZoneId.of("UT")}, // fail to parse {"", 0, 0, null}, @@ -206,12 +211,12 @@ public void test_parseSuccess_plain(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.appendZoneId(); TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + text); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + text); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + text); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + text); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + text); } else { assertEquals(parsed, null); } @@ -221,13 +226,14 @@ public void test_parseSuccess_prefix(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.appendZoneId(); pos.setIndex(3); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved("XXX" + text, pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex >= 0 ? expectedErrorIndex + 3 : expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex + 3); + String prefixText = "XXX" + text; + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(prefixText, pos); + assertEquals(pos.getErrorIndex(), expectedErrorIndex >= 0 ? expectedErrorIndex + 3 : expectedErrorIndex, "Incorrect error index parsing: " + prefixText); + assertEquals(pos.getIndex(), expectedIndex + 3, "Incorrect index parsing: " + prefixText); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + prefixText); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + prefixText); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + prefixText); } else { assertEquals(parsed, null); } @@ -236,13 +242,14 @@ @Test(dataProvider="parseSuccess") public void test_parseSuccess_suffix(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.appendZoneId(); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text + "XXX", pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex); + String suffixText = text + "XXX"; + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(suffixText, pos); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + suffixText); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + suffixText); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + suffixText); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + suffixText); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + suffixText); } else { assertEquals(parsed, null); } @@ -251,15 +258,16 @@ @Test(dataProvider="parseSuccess") public void test_parseSuccess_caseSensitive(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.parseCaseSensitive().appendZoneId(); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos); + String lcText = text.toLowerCase(Locale.ENGLISH); + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(lcText, pos); if (text.matches("[^A-Z]*[A-Z].*")) { // if input has letters assertEquals(pos.getErrorIndex() >= 0, true); assertEquals(pos.getIndex(), 0); assertEquals(parsed, null); } else { // case sensitive made no difference - assertEquals(pos.getIndex(), expectedIndex); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + lcText); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + lcText); if (expected != null) { assertEquals(parsed.query(TemporalQuery.zoneId()), expected); assertEquals(parsed.query(TemporalQuery.offset()), null); @@ -273,13 +281,15 @@ @Test(dataProvider="parseSuccess") public void test_parseSuccess_caseInsensitive(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.parseCaseInsensitive().appendZoneId(); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex); + String lcText = text.toLowerCase(Locale.ENGLISH); + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(lcText, pos); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + lcText); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + lcText); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + ZoneId zid = parsed.query(TemporalQuery.zoneId()); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + lcText); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + lcText); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + lcText); } else { assertEquals(parsed, null); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/time/tck/java/time/temporal/TCKChronoField.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2012, 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. 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal; + +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.temporal.ChronoField.AMPM_OF_DAY; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.MICRO_OF_DAY; +import static java.time.temporal.ChronoField.MICRO_OF_SECOND; +import static java.time.temporal.ChronoField.MILLI_OF_DAY; +import static java.time.temporal.ChronoField.MILLI_OF_SECOND; +import static java.time.temporal.ChronoField.MINUTE_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.NANO_OF_DAY; +import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; +import static java.time.temporal.ChronoField.SECOND_OF_DAY; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoField.ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.ChronoUnit.YEARS; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.ValueRange; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKChronoField { + + //----------------------------------------------------------------------- + // getBaseUnit() and getRangeUnit() + //----------------------------------------------------------------------- + @DataProvider(name="fieldUnit") + Object[][] data_fieldUnit() { + return new Object[][] { + {YEAR, YEARS, FOREVER}, + {MONTH_OF_YEAR, MONTHS, YEARS}, + {DAY_OF_MONTH, DAYS, MONTHS}, + {DAY_OF_WEEK, DAYS, WEEKS}, + {DAY_OF_YEAR, DAYS, YEARS}, + {HOUR_OF_DAY, HOURS, DAYS}, + {MINUTE_OF_DAY, MINUTES, DAYS}, + {MINUTE_OF_HOUR, MINUTES, HOURS}, + {SECOND_OF_DAY, SECONDS, DAYS}, + {SECOND_OF_MINUTE, SECONDS, MINUTES}, + {MILLI_OF_DAY, MILLIS, DAYS}, + {MILLI_OF_SECOND, MILLIS, SECONDS}, + {MICRO_OF_SECOND, MICROS, SECONDS}, + {MICRO_OF_DAY, MICROS, DAYS}, + {NANO_OF_SECOND, NANOS, SECONDS}, + {NANO_OF_DAY, NANOS, DAYS}, + + }; + } + + @Test(dataProvider = "fieldUnit") + public void test_getBaseUnit(ChronoField field, ChronoUnit baseUnit, ChronoUnit rangeUnit) { + assertEquals(field.getBaseUnit(), baseUnit); + assertEquals(field.getRangeUnit(), rangeUnit); + } + + //----------------------------------------------------------------------- + // isDateBased() and isTimeBased() + //----------------------------------------------------------------------- + @DataProvider(name="fieldBased") + Object[][] data_fieldBased() { + return new Object[][] { + {DAY_OF_WEEK, true, false}, + {ALIGNED_DAY_OF_WEEK_IN_MONTH, true, false}, + {ALIGNED_DAY_OF_WEEK_IN_YEAR, true, false}, + {DAY_OF_MONTH, true, false}, + {DAY_OF_YEAR, true, false}, + {EPOCH_DAY, true, false}, + {ALIGNED_WEEK_OF_MONTH, true, false}, + {ALIGNED_WEEK_OF_YEAR, true, false}, + {MONTH_OF_YEAR, true, false}, + {PROLEPTIC_MONTH, true, false}, + {YEAR_OF_ERA, true, false}, + {YEAR, true, false}, + {ERA, true, false}, + + {AMPM_OF_DAY, false, true}, + {CLOCK_HOUR_OF_DAY, false, true}, + {HOUR_OF_DAY, false, true}, + {CLOCK_HOUR_OF_AMPM, false, true}, + {HOUR_OF_AMPM, false, true}, + {MINUTE_OF_DAY, false, true}, + {MINUTE_OF_HOUR, false, true}, + {SECOND_OF_DAY, false, true}, + {SECOND_OF_MINUTE, false, true}, + {MILLI_OF_DAY, false, true}, + {MILLI_OF_SECOND, false, true}, + {MICRO_OF_DAY, false, true}, + {MICRO_OF_SECOND, false, true}, + {NANO_OF_DAY, false, true}, + {NANO_OF_SECOND, false, true}, + }; + } + + @Test(dataProvider = "fieldBased") + public void test_isDateBased(ChronoField field, boolean isDateBased, boolean isTimeBased) { + assertEquals(field.isDateBased(), isDateBased); + assertEquals(field.isTimeBased(), isTimeBased); + } + + //----------------------------------------------------------------------- + // isSupportedBy(TemporalAccessor temporal) and getFrom(TemporalAccessor temporal) + //----------------------------------------------------------------------- + @DataProvider(name="fieldAndAccessor") + Object[][] data_fieldAndAccessor() { + return new Object[][] { + {YEAR, LocalDate.of(2000, 2, 29), true, 2000}, + {YEAR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 2000}, + {MONTH_OF_YEAR, LocalDate.of(2000, 2, 29), true, 2}, + {MONTH_OF_YEAR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 2}, + {DAY_OF_MONTH, LocalDate.of(2000, 2, 29), true, 29}, + {DAY_OF_MONTH, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 29}, + {DAY_OF_YEAR, LocalDate.of(2000, 2, 29), true, 60}, + {DAY_OF_YEAR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 60}, + + {HOUR_OF_DAY, LocalTime.of(5, 4, 3, 200), true, 5}, + {HOUR_OF_DAY, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 5}, + + {MINUTE_OF_DAY, LocalTime.of(5, 4, 3, 200), true, 5*60 + 4}, + {MINUTE_OF_DAY, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 5*60 + 4}, + {MINUTE_OF_HOUR, LocalTime.of(5, 4, 3, 200), true, 4}, + {MINUTE_OF_HOUR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 4}, + + {SECOND_OF_DAY, LocalTime.of(5, 4, 3, 200), true, 5*3600 + 4*60 + 3}, + {SECOND_OF_DAY, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 5*3600 + 4*60 + 3}, + {SECOND_OF_MINUTE, LocalTime.of(5, 4, 3, 200), true, 3}, + {SECOND_OF_MINUTE, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 3}, + + {NANO_OF_SECOND, LocalTime.of(5, 4, 3, 200), true, 200}, + {NANO_OF_SECOND, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 200}, + + {YEAR, LocalTime.of(5, 4, 3, 200), false, -1}, + {MONTH_OF_YEAR, LocalTime.of(5, 4, 3, 200), false, -1}, + {DAY_OF_MONTH, LocalTime.of(5, 4, 3, 200), false, -1}, + {DAY_OF_YEAR, LocalTime.of(5, 4, 3, 200), false, -1}, + {HOUR_OF_DAY, LocalDate.of(2000, 2, 29), false, -1}, + {MINUTE_OF_DAY, LocalDate.of(2000, 2, 29), false, -1}, + {MINUTE_OF_HOUR, LocalDate.of(2000, 2, 29), false, -1}, + {SECOND_OF_DAY, LocalDate.of(2000, 2, 29), false, -1}, + {SECOND_OF_MINUTE, LocalDate.of(2000, 2, 29), false, -1}, + {NANO_OF_SECOND, LocalDate.of(2000, 2, 29), false, -1}, + }; + } + + @Test(dataProvider = "fieldAndAccessor") + public void test_supportedAccessor(ChronoField field, TemporalAccessor accessor, boolean isSupported, long value) { + assertEquals(field.isSupportedBy(accessor), isSupported); + if (isSupported) { + assertEquals(field.getFrom(accessor), value); + } + } + + //----------------------------------------------------------------------- + // range() and rangeRefinedBy(TemporalAccessor temporal) + //----------------------------------------------------------------------- + @Test + public void test_range() { + assertEquals(MONTH_OF_YEAR.range(), ValueRange.of(1, 12)); + assertEquals(MONTH_OF_YEAR.rangeRefinedBy(LocalDate.of(2000, 2, 29)), ValueRange.of(1, 12)); + + assertEquals(DAY_OF_MONTH.range(), ValueRange.of(1, 28, 31)); + assertEquals(DAY_OF_MONTH.rangeRefinedBy(LocalDate.of(2000, 2, 29)), ValueRange.of(1, 29)); + } + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (ChronoField field : ChronoField.values()) { + assertEquals(ChronoField.valueOf(field.name()), field); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/time/tck/java/time/temporal/TCKChronoUnit.java Wed Jul 24 08:22:32 2013 -0300 @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2012, 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. 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal; + +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HALF_DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLENNIA; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.ChronoUnit.YEARS; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKChronoUnit { + + //----------------------------------------------------------------------- + // isDateBased(), isTimeBased() and isDurationEstimated() + //----------------------------------------------------------------------- + @DataProvider(name="chronoUnit") + Object[][] data_chronoUnit() { + return new Object[][] { + {FOREVER, false, false, true}, + {ERAS, true, false, true}, + {MILLENNIA, true, false, true}, + {CENTURIES, true, false, true}, + {DECADES, true, false, true}, + {YEARS, true, false, true}, + {MONTHS, true, false, true}, + {WEEKS, true, false, true}, + {DAYS, true, false, true}, + + {HALF_DAYS, false, true, false}, + {HOURS, false, true, false}, + {MINUTES, false, true, false}, + {SECONDS, false, true, false}, + {MICROS, false, true, false}, + {MILLIS, false, true, false}, + {NANOS, false, true, false}, + + }; + } + + @Test(dataProvider = "chronoUnit") + public void test_unitType(ChronoUnit unit, boolean isDateBased, boolean isTimeBased, boolean isDurationEstimated) { + assertEquals(unit.isDateBased(), isDateBased); + assertEquals(unit.isTimeBased(), isTimeBased); + assertEquals(unit.isDurationEstimated(), isDurationEstimated); + } + + //----------------------------------------------------------------------- + // isSupportedBy(), addTo() and between() + //----------------------------------------------------------------------- + @DataProvider(name="unitAndTemporal") + Object[][] data_unitAndTemporal() { + return new Object[][] { + {CENTURIES, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2100, 1, 10)}, + {DECADES, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2010, 1, 10)}, + {YEARS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2001, 1, 10)}, + {MONTHS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2000, 2, 10)}, + {WEEKS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2000, 1, 17)}, + {DAYS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2000, 1, 11)}, + + {HALF_DAYS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(13, 2, 3, 400)}, + {HOURS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(2, 2, 3, 400)}, + {MINUTES, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 3, 3, 400)}, + {SECONDS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 4, 400)}, + {MICROS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 3, 1000 + 400)}, + {MILLIS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 3, 1000*1000 + 400)}, + {NANOS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 3, 1 + 400)}, + + {CENTURIES, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {DECADES, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {YEARS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {MONTHS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {WEEKS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {DAYS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + + {HALF_DAYS, LocalDate.of(2000, 2, 29), false, 1, null}, + {HOURS, LocalDate.of(2000, 2, 29), false, 1, null}, + {MINUTES, LocalDate.of(2000, 2, 29), false, 1, null}, + {SECONDS, LocalDate.of(2000, 2, 29), false, 1, null}, + {MICROS, LocalDate.of(2000, 2, 29), false, 1, null}, + {MILLIS, LocalDate.of(2000, 2, 29), false, 1, null}, + {NANOS, LocalDate.of(2000, 2, 29), false, 1, null}, + + }; + } + + @Test(dataProvider = "unitAndTemporal") + public void test_unitAndTemporal(ChronoUnit unit, Temporal base, boolean isSupportedBy, long amount, Temporal target) { + assertEquals(unit.isSupportedBy(base), isSupportedBy); + if (isSupportedBy) { + Temporal result = unit.addTo(base, amount); + assertEquals(result, target); + assertEquals(unit.between(base, result), amount); + } + } + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (ChronoUnit unit : ChronoUnit.values()) { + assertEquals(ChronoUnit.valueOf(unit.name()), unit); + } + } +}
--- a/test/java/time/tck/java/time/temporal/TCKWeekFields.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/temporal/TCKWeekFields.java Wed Jul 24 08:22:32 2013 -0300 @@ -56,16 +56,22 @@ */ package tck.java.time.temporal; +import static java.time.format.ResolverStyle.LENIENT; +import static java.time.format.ResolverStyle.SMART; +import static java.time.format.ResolverStyle.STRICT; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.DAY_OF_WEEK; import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; - import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; import java.io.IOException; +import java.time.DateTimeException; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -376,14 +382,13 @@ TemporalField womField = week.weekOfMonth(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(womField).appendLiteral('-') - .appendValue(DAY_OF_WEEK).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(womField) + "-" + date.get(DAY_OF_WEEK); + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(SMART); + String str = date.getYear() + ":" + date.getMonthValue() + ":" + + date.get(womField) + ":" + date.get(DAY_OF_WEEK); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " ::" + str + "::" + i); @@ -392,6 +397,52 @@ } @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWom_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField womField = week.weekOfMonth(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(LENIENT); + int wom = date.get(womField); + int dow = date.get(DAY_OF_WEEK); + for (int j = wom - 10; j < wom + 10; j++) { + String str = date.getYear() + ":" + date.getMonthValue() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wom), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWom_strict(DayOfWeek firstDayOfWeek, int minDays) { + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField womField = week.weekOfMonth(); + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(STRICT); + String str = "2012:1:0:1"; + try { + LocalDate date = LocalDate.parse(str, f); + assertEquals(date.getYear(), 2012); + assertEquals(date.getMonthValue(), 1); + assertEquals(date.get(womField), 0); + assertEquals(date.get(DAY_OF_WEEK), 1); + } catch (DateTimeException ex) { + // expected + } + } + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWomDow(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 15); WeekFields week = WeekFields.of(firstDayOfWeek, minDays); @@ -399,14 +450,13 @@ TemporalField womField = week.weekOfMonth(); for (int i = 1; i <= 15; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(womField).appendLiteral('-') + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') .appendValue(dowField).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(womField) + "-" + date.get(dowField); + String str = date.getYear() + ":" + date.getMonthValue() + ":" + + date.get(womField) + ":" + date.get(dowField); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -415,20 +465,44 @@ } @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWomDow_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField dowField = week.dayOfWeek(); + TemporalField womField = week.weekOfMonth(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(dowField).toFormatter().withResolverStyle(LENIENT); + int wom = date.get(womField); + int dow = date.get(dowField); + for (int j = wom - 10; j < wom + 10; j++) { + String str = date.getYear() + ":" + date.getMonthValue() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wom), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoy(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 15); WeekFields week = WeekFields.of(firstDayOfWeek, minDays); TemporalField woyField = week.weekOfYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(woyField).appendLiteral('-') + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') .appendValue(DAY_OF_WEEK).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(woyField) + "-" + date.get(DAY_OF_WEEK); + String str = date.getYear() + ":" + + date.get(woyField) + ":" + date.get(DAY_OF_WEEK); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -437,6 +511,49 @@ } @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoy_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField woyField = week.weekOfYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(LENIENT); + int woy = date.get(woyField); + int dow = date.get(DAY_OF_WEEK); + for (int j = woy - 60; j < woy + 60; j++) { + String str = date.getYear() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - woy), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoy_strict(DayOfWeek firstDayOfWeek, int minDays) { + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField woyField = week.weekOfYear(); + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(STRICT); + String str = "2012:0:1"; + try { + LocalDate date = LocalDate.parse(str, f); + assertEquals(date.getYear(), 2012); + assertEquals(date.get(woyField), 0); + assertEquals(date.get(DAY_OF_WEEK), 1); + } catch (DateTimeException ex) { + // expected + } + } + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoyDow(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 15); WeekFields week = WeekFields.of(firstDayOfWeek, minDays); @@ -444,14 +561,13 @@ TemporalField woyField = week.weekOfYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(woyField).appendLiteral('-') + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') .appendValue(dowField).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(woyField) + "-" + date.get(dowField); + String str = date.getYear() + ":" + date.getMonthValue() + ":" + + date.get(woyField) + ":" + date.get(dowField); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -460,6 +576,31 @@ } @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoyDow_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField dowField = week.dayOfWeek(); + TemporalField woyField = week.weekOfYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') + .appendValue(dowField).toFormatter().withResolverStyle(LENIENT); + int woy = date.get(woyField); + int dow = date.get(dowField); + for (int j = woy - 60; j < woy + 60; j++) { + String str = date.getYear() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - woy), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoWBY(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 31); WeekFields week = WeekFields.of(firstDayOfWeek, minDays); @@ -467,12 +608,11 @@ TemporalField yowbyField = week.weekBasedYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek, week of year and year of week-based-year it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(yowbyField).appendLiteral('-') - .appendValue(wowbyField).appendLiteral('-') + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') .appendValue(DAY_OF_WEEK).toFormatter(); - String str = date.get(yowbyField) + "-" + date.get(wowbyField) + "-" + + String str = date.get(yowbyField) + ":" + date.get(wowbyField) + ":" + date.get(DAY_OF_WEEK); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -482,6 +622,51 @@ } @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoWBY_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 31); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField wowbyField = week.weekOfWeekBasedYear(); + TemporalField yowbyField = week.weekBasedYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(LENIENT); + int wowby = date.get(wowbyField); + int dow = date.get(DAY_OF_WEEK); + for (int j = wowby - 60; j < wowby + 60; j++) { + String str = date.get(yowbyField) + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wowby), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoWBY_strict(DayOfWeek firstDayOfWeek, int minDays) { + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField wowbyField = week.weekOfWeekBasedYear(); + TemporalField yowbyField = week.weekBasedYear(); + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(STRICT); + String str = "2012:0:1"; + try { + LocalDate date = LocalDate.parse(str, f); + assertEquals(date.get(yowbyField), 2012); + assertEquals(date.get(wowbyField), 0); + assertEquals(date.get(DAY_OF_WEEK), 1); + } catch (DateTimeException ex) { + // expected + } + } + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoWBYDow(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 31); WeekFields week = WeekFields.of(firstDayOfWeek, minDays); @@ -490,12 +675,11 @@ TemporalField yowbyField = week.weekBasedYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek, week of year and year of week-based-year it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(yowbyField).appendLiteral('-') - .appendValue(wowbyField).appendLiteral('-') + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') .appendValue(dowField).toFormatter(); - String str = date.get(yowbyField) + "-" + date.get(wowbyField) + "-" + + String str = date.get(yowbyField) + ":" + date.get(wowbyField) + ":" + date.get(dowField); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -504,6 +688,31 @@ } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoWBYDow_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 31); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField dowField = week.dayOfWeek(); + TemporalField wowbyField = week.weekOfWeekBasedYear(); + TemporalField yowbyField = week.weekBasedYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') + .appendValue(dowField).toFormatter().withResolverStyle(LENIENT); + int wowby = date.get(wowbyField); + int dow = date.get(dowField); + for (int j = wowby - 60; j < wowby + 60; j++) { + String str = date.get(yowbyField) + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wowby), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { @@ -587,4 +796,21 @@ assertEquals(date.get(yowbyField), wby); } + //----------------------------------------------------------------------- + // equals() and hashCode(). + //----------------------------------------------------------------------- + @Test + public void test_equals() { + WeekFields weekDef_iso = WeekFields.ISO; + WeekFields weekDef_sundayStart = WeekFields.SUNDAY_START; + + assertTrue(weekDef_iso.equals(WeekFields.of(DayOfWeek.MONDAY, 4))); + assertTrue(weekDef_sundayStart.equals(WeekFields.of(DayOfWeek.SUNDAY, 1))); + assertEquals(weekDef_iso.hashCode(), WeekFields.of(DayOfWeek.MONDAY, 4).hashCode()); + assertEquals(weekDef_sundayStart.hashCode(), WeekFields.of(DayOfWeek.SUNDAY, 1).hashCode()); + + assertFalse(weekDef_iso.equals(weekDef_sundayStart)); + assertNotEquals(weekDef_iso.hashCode(), weekDef_sundayStart.hashCode()); + } + }
--- a/test/java/time/tck/java/time/zone/TCKZoneRules.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/tck/java/time/zone/TCKZoneRules.java Wed Jul 24 08:22:32 2013 -0300 @@ -75,6 +75,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; +import java.time.OffsetDateTime; import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; @@ -83,6 +84,7 @@ import java.time.zone.ZoneOffsetTransitionRule; import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition; import java.time.zone.ZoneRules; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -918,6 +920,65 @@ assertEquals(test.nextTransition(last.getInstant()), null); } + //----------------------------------------------------------------------- + // Apia + //----------------------------------------------------------------------- + private ZoneRules pacificApia() { + return ZoneId.of("Pacific/Apia").getRules(); + } + + public void test_Apia_nextTransition_historic() { + ZoneRules test = pacificApia(); + List<ZoneOffsetTransition> trans = test.getTransitions(); + + ZoneOffsetTransition first = trans.get(0); + assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); + + for (int i = 0; i < trans.size() - 1; i++) { + ZoneOffsetTransition cur = trans.get(i); + ZoneOffsetTransition next = trans.get(i + 1); + + assertEquals(test.nextTransition(cur.getInstant()), next); + assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); + } + } + + public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() { + // transition occurred at 2011-12-30T00:00-10:00 + ZoneRules test = pacificApia(); + Instant instantBefore = LocalDate.of(2011, 12, 27).atStartOfDay(ZoneOffset.UTC).toInstant(); + ZoneOffsetTransition trans = test.nextTransition(instantBefore); + assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2011, 12, 30, 0, 0)); + assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2011, 12, 31, 0, 0)); + assertEquals(trans.isGap(), true); + assertEquals(trans.isOverlap(), false); + assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-10)), false); + assertEquals(trans.isValidOffset(ZoneOffset.ofHours(+14)), false); + assertEquals(trans.getDuration(), Duration.ofHours(24)); + assertEquals(trans.getInstant(), LocalDateTime.of(2011, 12, 31, 0, 0).toInstant(ZoneOffset.ofHours(+14))); + + ZonedDateTime zdt = ZonedDateTime.of(2011, 12, 29, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); + assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0)); + } + + public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() { + // transition occurred at 1879-07-04T00:00+12:33:04 + ZoneRules test = pacificApia(); + Instant instantBefore = LocalDate.of(1879, 7, 2).atStartOfDay(ZoneOffset.UTC).toInstant(); + ZoneOffsetTransition trans = test.nextTransition(instantBefore); + assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(1879, 7, 5, 0, 0)); + assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(1879, 7, 4, 0, 0)); + assertEquals(trans.isGap(), false); + assertEquals(trans.isOverlap(), true); + assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(+12, 33, 4)), true); + assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)), true); + assertEquals(trans.getDuration(), Duration.ofHours(-24)); + assertEquals(trans.getInstant(), LocalDateTime.of(1879, 7, 4, 0, 0).toInstant(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56))); + + ZonedDateTime zdt = ZonedDateTime.of(1879, 7, 4, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); + assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(1879, 7, 4, 1, 0, 0)); + } + //------------------------------------------------------------------------- @Test(expectedExceptions=UnsupportedOperationException.class) public void test_getTransitions_immutable() { @@ -932,6 +993,81 @@ } //----------------------------------------------------------------------- + // of() + //----------------------------------------------------------------------- + public void test_of(){ + //used for standard offset + ZoneOffset stdOffset1 = ZoneOffset.UTC; + ZoneOffset stdOffset2 = ZoneOffset.ofHours(1); + LocalDateTime time_of_stdOffsetTransition1 = LocalDateTime.of(2013, 1, 5, 1, 0); + ZoneOffsetTransition stdOffsetTransition1 = ZoneOffsetTransition.of(time_of_stdOffsetTransition1, stdOffset1, stdOffset2); + List<ZoneOffsetTransition> stdOffsetTransition_list = new ArrayList<ZoneOffsetTransition>(); + stdOffsetTransition_list.add(stdOffsetTransition1); + + //used for wall offset + ZoneOffset wallOffset1 = ZoneOffset.ofHours(2); + ZoneOffset wallOffset2 = ZoneOffset.ofHours(4); + ZoneOffset wallOffset3 = ZoneOffset.ofHours(7); + + LocalDateTime time_of_wallOffsetTransition1 = LocalDateTime.of(2013, 2, 5, 1, 0); + LocalDateTime time_of_wallOffsetTransition2 = LocalDateTime.of(2013, 3, 5, 1, 0); + LocalDateTime time_of_wallOffsetTransition3 = LocalDateTime.of(2013, 10, 5, 1, 0); + + ZoneOffsetTransition wallOffsetTransition1 = ZoneOffsetTransition.of(time_of_wallOffsetTransition1, wallOffset1, wallOffset2); + ZoneOffsetTransition wallOffsetTransition2 = ZoneOffsetTransition.of(time_of_wallOffsetTransition2, wallOffset2, wallOffset3); + ZoneOffsetTransition wallOffsetTransition3 = ZoneOffsetTransition.of(time_of_wallOffsetTransition3, wallOffset3, wallOffset1); + + List<ZoneOffsetTransition> wallOffsetTransition_list = new ArrayList<ZoneOffsetTransition>(); + wallOffsetTransition_list.add(wallOffsetTransition1); + wallOffsetTransition_list.add(wallOffsetTransition2); + wallOffsetTransition_list.add(wallOffsetTransition3); + + //used for ZoneOffsetTransitionRule + ZoneOffset ruleOffset = ZoneOffset.ofHours(3); + ZoneOffsetTransitionRule.TimeDefinition timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.valueOf("WALL"); + ZoneOffsetTransitionRule rule1 = ZoneOffsetTransitionRule.of(Month.FEBRUARY, + 2, + DayOfWeek.MONDAY, + LocalTime.of(1, 0), + false, + timeDefinition, + ZoneOffset.UTC, + ZoneOffset.UTC, + ruleOffset + ); + List<ZoneOffsetTransitionRule> rule_list = new ArrayList<ZoneOffsetTransitionRule>(); + rule_list.add(rule1); + + //Begin verification + ZoneRules zoneRule = ZoneRules.of(stdOffset1, + wallOffset1, + stdOffsetTransition_list, + wallOffsetTransition_list, + rule_list + ); + + OffsetDateTime before_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).minusSeconds(1); + OffsetDateTime after_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).plusSeconds(1);; + assertEquals(zoneRule.getStandardOffset(before_time_of_stdOffsetTransition1.toInstant()), stdOffset1); + assertEquals(zoneRule.getStandardOffset(after_time_of_stdOffsetTransition1.toInstant()), stdOffset2); + + OffsetDateTime before_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).minusSeconds(1); + OffsetDateTime after_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).plusSeconds(1); + assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition1); + assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition2); + + OffsetDateTime before_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).minusSeconds(1); + OffsetDateTime after_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).plusSeconds(1); + assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition2); + assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition3); + + OffsetDateTime before_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).minusSeconds(1); + OffsetDateTime after_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).plusSeconds(1); + assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition3.toInstant()), wallOffsetTransition3); + assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition3.toInstant()), rule1.createTransition(2014)); + } + + //----------------------------------------------------------------------- // equals() / hashCode() //----------------------------------------------------------------------- public void test_equals() {
--- a/test/java/time/test/java/time/MockSimplePeriod.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/MockSimplePeriod.java Wed Jul 24 08:22:32 2013 -0300 @@ -176,7 +176,7 @@ @Override public String toString() { - return amount + " " + unit.getName(); + return amount + " " + unit; } }
--- a/test/java/time/test/java/time/chrono/TestChronoLocalDate.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/chrono/TestChronoLocalDate.java Wed Jul 24 08:22:32 2013 -0300 @@ -60,7 +60,9 @@ import static org.testng.Assert.assertTrue; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; import java.time.chrono.Chronology; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; @@ -80,8 +82,8 @@ //----------------------------------------------------------------------- public void test_date_comparator_checkGenerics_ISO() { - List<ChronoLocalDate<LocalDate>> dates = new ArrayList<>(); - ChronoLocalDate<LocalDate> date = LocalDate.of(2013, 1, 1); + List<ChronoLocalDate> dates = new ArrayList<>(); + ChronoLocalDate date = LocalDate.of(2013, 1, 1); // Insert dates in order, no duplicates dates.add(date.minus(10, ChronoUnit.YEARS)); @@ -96,55 +98,7 @@ dates.add(date.plus(1, ChronoUnit.YEARS)); dates.add(date.plus(10, ChronoUnit.YEARS)); - List<ChronoLocalDate<LocalDate>> copy = new ArrayList<>(dates); - Collections.shuffle(copy); - Collections.sort(copy, ChronoLocalDate.timeLineOrder()); - assertEquals(copy, dates); - assertTrue(ChronoLocalDate.timeLineOrder().compare(copy.get(0), copy.get(1)) < 0); - } - - public void test_date_comparator_checkGenerics_unknown() { - List<ChronoLocalDate<?>> dates = new ArrayList<>(); - ChronoLocalDate<?> date = LocalDate.of(2013, 1, 1); - - // Insert dates in order, no duplicates - dates.add(date.minus(10, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.MONTHS)); - dates.add(date.minus(1, ChronoUnit.WEEKS)); - dates.add(date.minus(1, ChronoUnit.DAYS)); - dates.add(date); - dates.add(date.plus(1, ChronoUnit.DAYS)); - dates.add(date.plus(1, ChronoUnit.WEEKS)); - dates.add(date.plus(1, ChronoUnit.MONTHS)); - dates.add(date.plus(1, ChronoUnit.YEARS)); - dates.add(date.plus(10, ChronoUnit.YEARS)); - - List<ChronoLocalDate<?>> copy = new ArrayList<>(dates); - Collections.shuffle(copy); - Collections.sort(copy, ChronoLocalDate.timeLineOrder()); - assertEquals(copy, dates); - assertTrue(ChronoLocalDate.timeLineOrder().compare(copy.get(0), copy.get(1)) < 0); - } - - public <D extends ChronoLocalDate<D>> void test_date_comparator_checkGenerics_unknownExtends() { - List<ChronoLocalDate<D>> dates = new ArrayList<>(); - ChronoLocalDate<D> date = (ChronoLocalDate) LocalDate.of(2013, 1, 1); // TODO generics raw type - - // Insert dates in order, no duplicates - dates.add(date.minus(10, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.MONTHS)); - dates.add(date.minus(1, ChronoUnit.WEEKS)); - dates.add(date.minus(1, ChronoUnit.DAYS)); - dates.add(date); - dates.add(date.plus(1, ChronoUnit.DAYS)); - dates.add(date.plus(1, ChronoUnit.WEEKS)); - dates.add(date.plus(1, ChronoUnit.MONTHS)); - dates.add(date.plus(1, ChronoUnit.YEARS)); - dates.add(date.plus(10, ChronoUnit.YEARS)); - - List<ChronoLocalDate<D>> copy = new ArrayList<>(dates); + List<ChronoLocalDate> copy = new ArrayList<>(dates); Collections.shuffle(copy); Collections.sort(copy, ChronoLocalDate.timeLineOrder()); assertEquals(copy, dates); @@ -178,13 +132,12 @@ //----------------------------------------------------------------------- public void test_date_checkGenerics_genericsMethod() { Chronology chrono = ThaiBuddhistChronology.INSTANCE; - ChronoLocalDate<?> date = chrono.dateNow(); - // date = processOK(date); // does not compile + ChronoLocalDate date = chrono.dateNow(); + date = processOK(date); date = processClassOK(ThaiBuddhistDate.class); date = dateSupplier(); - // date = processWeird(date); // does not compile (correct) - // date = processClassWeird(ThaiBuddhistDate.class); // does not compile (correct) + date = processClassWeird(ThaiBuddhistDate.class); } public void test_date_checkGenerics_genericsMethod_concreteType() { @@ -195,12 +148,12 @@ date = processClassOK(ThaiBuddhistDate.class); date = dateSupplier(); - // date = processWeird(date); // does not compile (correct) // date = processClassWeird(ThaiBuddhistDate.class); // does not compile (correct) } - public <D extends ChronoLocalDate<D>> void test_date_checkGenerics_genericsMethod_withType() { + public <D extends ChronoLocalDate> void test_date_checkGenerics_genericsMethod_withType() { Chronology chrono = ThaiBuddhistChronology.INSTANCE; + @SuppressWarnings("unchecked") D date = (D) chrono.dateNow(); date = processOK(date); // date = processClassOK(ThaiBuddhistDate.class); // does not compile (correct) @@ -210,24 +163,40 @@ // date = processClassWeird(ThaiBuddhistDate.class); // does not compile (correct) } - private <D extends ChronoLocalDate<D>> D dateSupplier() { - return (D) (ChronoLocalDate) ThaiBuddhistChronology.INSTANCE.dateNow(); // TODO raw types + @SuppressWarnings("unchecked") + private <D extends ChronoLocalDate> D dateSupplier() { + return (D) ThaiBuddhistChronology.INSTANCE.dateNow(); } // decent generics signatures that need to work - private <D extends ChronoLocalDate<D>> D processOK(D date) { - return date; + @SuppressWarnings("unchecked") + private <D extends ChronoLocalDate> D processOK(D date) { + return (D) date.plus(1, ChronoUnit.DAYS); } - private <D extends ChronoLocalDate<D>> D processClassOK(Class<D> cls) { + private <D extends ChronoLocalDate> D processClassOK(Class<D> cls) { return null; } // weird generics signatures that shouldn't really work - private <D extends ChronoLocalDate<D>> ChronoLocalDate<D> processWeird(ChronoLocalDate<D> date) { - return date; - } - private <D extends ChronoLocalDate<D>> ChronoLocalDate<D> processClassWeird(Class<D> cls) { + private <D extends ChronoLocalDate> ChronoLocalDate processClassWeird(Class<D> cls) { return null; } + public void test_date_checkGenerics_chronoLocalDateTime1() { + LocalDateTime now = LocalDateTime.now(); + Chronology chrono = ThaiBuddhistChronology.INSTANCE; + ChronoLocalDateTime<?> ldt = chrono.localDateTime(now); + ldt = processCLDT(ldt); + } + + public void test_date_checkGenerics_chronoLocalDateTime2() { + LocalDateTime now = LocalDateTime.now(); + Chronology chrono = ThaiBuddhistChronology.INSTANCE; + ChronoLocalDateTime<? extends ChronoLocalDate> ldt = chrono.localDateTime(now); + ldt = processCLDT(ldt); + } + + private <D extends ChronoLocalDate> ChronoLocalDateTime<D> processCLDT(ChronoLocalDateTime<D> dt) { + return dt; + } }
--- a/test/java/time/test/java/time/chrono/TestExampleCode.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/chrono/TestExampleCode.java Wed Jul 24 08:22:32 2013 -0300 @@ -59,10 +59,14 @@ import static org.testng.Assert.assertEquals; +import java.time.LocalDate; import java.time.LocalTime; +import java.time.ZoneId; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; import java.time.chrono.HijrahDate; import java.time.chrono.ThaiBuddhistDate; import java.time.temporal.ChronoField; @@ -82,7 +86,7 @@ @Test public void test_chronoPackageExample() { // Print the Thai Buddhist date - ChronoLocalDate<?> now1 = Chronology.of("ThaiBuddhist").dateNow(); + ChronoLocalDate now1 = Chronology.of("ThaiBuddhist").dateNow(); int day = now1.get(ChronoField.DAY_OF_MONTH); int dow = now1.get(ChronoField.DAY_OF_WEEK); int month = now1.get(ChronoField.MONTH_OF_YEAR); @@ -93,15 +97,15 @@ // Enumerate the list of available calendars and print today for each Set<Chronology> chronos = Chronology.getAvailableChronologies(); for (Chronology chrono : chronos) { - ChronoLocalDate<?> date = chrono.dateNow(); + ChronoLocalDate date = chrono.dateNow(); System.out.printf(" %20s: %s%n", chrono.getId(), date.toString()); } // Print today's date and the last day of the year for the Thai Buddhist Calendar. - ChronoLocalDate<?> first = now1 + ChronoLocalDate first = now1 .with(ChronoField.DAY_OF_MONTH, 1) .with(ChronoField.MONTH_OF_YEAR, 1); - ChronoLocalDate<?> last = first + ChronoLocalDate last = first .plus(1, ChronoUnit.YEARS) .minus(1, ChronoUnit.DAYS); System.out.printf(" %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(), @@ -137,7 +141,7 @@ // Enumerate the list of available calendars and print today for each Set<Chronology> chronos = Chronology.getAvailableChronologies(); for (Chronology chrono : chronos) { - ChronoLocalDate<?> date = chrono.dateNow(); + ChronoLocalDate date = chrono.dateNow(); System.out.printf(" %20s: %s%n", chrono.getId(), date.toString()); } @@ -161,11 +165,31 @@ first, last); } + void HijrahExample1() { + HijrahDate hd2 = HijrahChronology.INSTANCE.date(1200, 1, 1); + + ChronoLocalDateTime<HijrahDate> hdt = hd2.atTime(LocalTime.MIDNIGHT); + ChronoZonedDateTime<HijrahDate> zhdt = hdt.atZone(ZoneId.of("GMT")); + HijrahDate hd3 = zhdt.toLocalDate(); + ChronoLocalDateTime<HijrahDate> hdt2 = zhdt.toLocalDateTime(); + HijrahDate hd4 = hdt2.toLocalDate(); + + HijrahDate hd5 = next(hd2); + } + + void test_unknownChronologyWithDateTime() { + ChronoLocalDate date = LocalDate.now(); + ChronoLocalDateTime<?> cldt = date.atTime(LocalTime.NOON); + ChronoLocalDate ld = cldt.toLocalDate(); + ChronoLocalDateTime<?> noonTomorrow = tomorrowNoon(ld); + } + @Test public void test_library() { HijrahDate date = HijrahDate.now(); HijrahDate next = next(date); ChronoLocalDateTime<HijrahDate> noonTomorrow = tomorrowNoon(date); + HijrahDate hd3 = noonTomorrow.toLocalDate(); System.out.printf(" now: %s, noon tomorrow: %s%n", date, noonTomorrow); } @@ -175,8 +199,9 @@ * @param date a specific date extending ChronoLocalDate * @return a new date in the same chronology. */ - private <D extends ChronoLocalDate<D>> D next(D date) { - return date.plus(1, ChronoUnit.DAYS); + @SuppressWarnings("unchecked") + private <D extends ChronoLocalDate> D next(D date) { + return (D) date.plus(1, ChronoUnit.DAYS); } /** @@ -186,7 +211,8 @@ * @param date a specific date extending ChronoLocalDate * @return a [@code ChronoLocalDateTime<D>} using the change chronology. */ - private <D extends ChronoLocalDate<D>> ChronoLocalDateTime<D> tomorrowNoon(D date) { - return date.plus(1, ChronoUnit.DAYS).atTime(LocalTime.of(12, 0)); + @SuppressWarnings("unchecked") + private <D extends ChronoLocalDate> ChronoLocalDateTime<D> tomorrowNoon(D date) { + return (ChronoLocalDateTime<D>) date.plus(1, ChronoUnit.DAYS).atTime(LocalTime.of(12, 0)); } }
--- a/test/java/time/test/java/time/chrono/TestJapaneseChronoImpl.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/chrono/TestJapaneseChronoImpl.java Wed Jul 24 08:22:32 2013 -0300 @@ -61,12 +61,15 @@ import java.time.LocalDate; import java.time.LocalTime; import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.time.ZoneOffset; import java.time.chrono.JapaneseChronology; +import java.time.chrono.JapaneseEra; import java.time.chrono.JapaneseDate; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.util.Calendar; +import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; @@ -85,7 +88,7 @@ @DataProvider(name="RangeVersusCalendar") Object[][] provider_rangeVersusCalendar() { return new Object[][] { - {LocalDate.of(1868, 1, 1), LocalDate.of(2100, 1, 1)}, + {LocalDate.of(1873, 1, 1), LocalDate.of(2100, 1, 1)}, }; } @@ -118,4 +121,32 @@ } } + //----------------------------------------------------------------------- + // Verify Japanese Calendar matches java.util.Calendar for number of days + // in years 1 and 2. + //----------------------------------------------------------------------- + @Test + public void test_dayOfYearVsCalendar() { + Locale locale = Locale.forLanguageTag("ja-JP-u-ca-japanese"); + Calendar cal = java.util.Calendar.getInstance(locale); + + for (JapaneseEra era : JapaneseEra.values()) { + for (int year : new int[] {6, 7}) { + JapaneseDate jd = JapaneseChronology.INSTANCE.dateYearDay(era, year, 1); + OffsetDateTime jodt = OffsetDateTime.of(LocalDate.from(jd), LocalTime.MIN, ZoneOffset.UTC); + long millis = jodt.toInstant().toEpochMilli(); + cal.setTimeZone(TimeZone.getTimeZone("GMT+00")); + cal.setTimeInMillis(millis); + + assertEquals(jd.get(ChronoField.DAY_OF_YEAR), cal.get(Calendar.DAY_OF_YEAR), + "different DAY_OF_YEAR values in " + era + ", year: " + year); + assertEquals(jd.range(ChronoField.DAY_OF_YEAR).getMaximum(), cal.getActualMaximum(Calendar.DAY_OF_YEAR), + "different maximum for DAY_OF_YEAR in " + era + ", year: " + year); + assertEquals(jd.range(ChronoField.DAY_OF_YEAR).getMinimum(), cal.getActualMinimum(Calendar.DAY_OF_YEAR), + "different minimum for DAY_OF_YEAR in " + era + ", year: " + year); + } + } + + } + }
--- a/test/java/time/test/java/time/chrono/TestJapaneseChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/chrono/TestJapaneseChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -47,9 +47,6 @@ Object[][] transitionData() { return new Object[][] { // Japanese era, yearOfEra, month, dayOfMonth, gregorianYear - { JapaneseEra.SEIREKI, Year.MIN_VALUE, 1, 1, Year.MIN_VALUE }, - { JapaneseEra.SEIREKI, 1867, 12, 31, 1867 }, - { JapaneseEra.MEIJI, 1, 1, 25, 1868 }, // Note: the dates of Meiji 1 to 5 are incorrect { JapaneseEra.MEIJI, 6, 1, 1, 1873 }, // Meiji-Taisho transition isn't accurate. 1912-07-30 is the last day of Meiji // and the first day of Taisho. @@ -84,9 +81,10 @@ Object[][] rangeData() { return new Object[][] { // field, minSmallest, minLargest, maxSmallest, maxLargest - { ChronoField.ERA, -999, -999, 2, 2}, - { ChronoField.YEAR_OF_ERA, -999999999, 1, 15, 999999999-1989 }, // depends on the current era + { ChronoField.ERA, -1, -1, 2, 2}, + { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-1989 }, // depends on the current era { ChronoField.DAY_OF_YEAR, 1, 1, 7, 366}, + { ChronoField.YEAR, 1873, 1873, 999999999, 999999999}, }; } @@ -94,9 +92,6 @@ Object[][] invalidDatesData() { return new Object[][] { // Japanese era, yearOfEra, month, dayOfMonth - { JapaneseEra.SEIREKI, Year.MIN_VALUE - 1, 1, 1 }, - { JapaneseEra.SEIREKI, 1855, 2, 29 }, - { JapaneseEra.SEIREKI, 1868, 1, 25 }, { JapaneseEra.MEIJI, 6, 2, 29 }, { JapaneseEra.MEIJI, 45, 7, 30 }, { JapaneseEra.MEIJI, 46, 1, 1 }, @@ -118,8 +113,6 @@ Object[][] invalidEraYearData() { return new Object[][] { // Japanese era, yearOfEra - { JapaneseEra.SEIREKI, Year.MIN_VALUE - 1 }, - { JapaneseEra.SEIREKI, 2012 }, { JapaneseEra.MEIJI, -1 }, { JapaneseEra.MEIJI, 0 }, { JapaneseEra.MEIJI, 46 },
--- a/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Jul 24 08:22:32 2013 -0300 @@ -28,27 +28,57 @@ import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.time.DateTimeException; +import java.time.DayOfWeek; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.Period; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; import java.time.chrono.HijrahDate; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.JapaneseDate; +import java.time.chrono.MinguoChronology; +import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistChronology; +import java.time.chrono.ThaiBuddhistDate; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjuster; import java.time.temporal.ValueRange; +import java.time.temporal.WeekFields; +import java.util.Locale; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** - * Tests for the Umm alQura chronology and data + * Tests for the Umm alQura chronology and data. + * Note: The dates used for testing are just a sample of calendar data. */ @Test public class TestUmmAlQuraChronology { + private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); + private static final ZoneId ZONE_RIYADH = ZoneId.of("Asia/Riyadh"); + + // Test for HijrahChronology Aliases @Test public void test_aliases() { HijrahChronology hc = (HijrahChronology) Chronology.of("Hijrah"); @@ -57,49 +87,43 @@ assertEquals(hc, HijrahChronology.INSTANCE, "Alias for Hijrah-umalqura"); } - //----------------------------------------------------------------------- - // regular data factory for Umm alQura dates and the corresponding ISO dates - //----------------------------------------------------------------------- - @DataProvider(name = "UmmalQuraVsISODates") - Object[][] data_of_ummalqura() { - return new Object[][]{ - - //{1318, 01, 01, 1900, 04, 30}, - //{1318, 01, 02, 1900, 05, 01}, + // Test to check if the exception is thrown for an incorrect chronology id + @Test(expectedExceptions=DateTimeException.class) + public void test_badChronology() { + Chronology test = Chronology.of("Hijrah-ummalqura"); + } - //{1318, 12, 29, 1901, 04, 18}, - //{1319, 01, 01, 1901, 04, 19}, - - //{1433, 12, 29, 2012, 11, 14}, - //{1434, 01, 01, 2012, 11, 15}, - - {1434, 02, 18, 2012, 12, 31}, - {1434, 02, 19, 2013, 01, 01}, - - //{1502, 12, 30, 2079, 10, 25}, - // not in Umm alQura data {1503, 01, 01, 2079, 10, 26}, - - // not in Umm alQura data {1503, 06, 28, 2080, 04, 18}, - // not in Umm alQura data ~/ws/Downloads + //-------------------------------------------------------------------------- + // regular data factory for Umm alQura dates and the corresponding ISO dates + //-------------------------------------------------------------------------- + @DataProvider(name = "UmmAlQuraVsISODates") + Object[][] data_UmmAlQuraVsISODates() { + return new Object[][] { + {HijrahDate.of(1318, 1, 1), LocalDate.of(1900, 04, 30)}, + {HijrahDate.of(1318, 12, 29), LocalDate.of(1901, 04, 19)}, + {HijrahDate.of(1319, 01, 01), LocalDate.of(1901, 04, 20)}, + {HijrahDate.of(1433, 12, 29), LocalDate.of(2012, 11, 14)}, + {HijrahDate.of(1434, 01, 01), LocalDate.of(2012, 11, 15)}, + {HijrahDate.of(1434, 02, 18), LocalDate.of(2012, 12, 31)}, + {HijrahDate.of(1502, 12, 29), LocalDate.of(2079, 10, 25)}, }; } - @Test(dataProvider="UmmalQuraVsISODates") - public void Test_UmmAlQuraDatesVsISO(int h_year, int h_month, int h_day, int iso_year, int iso_month, int iso_day) { - HijrahDate hd = HijrahDate.of(h_year, h_month, h_day); - LocalDate ld = LocalDate.of(iso_year, iso_month, iso_day); + // Test to verify the epoch days for given Hijrah & ISO date instances + @Test(dataProvider="UmmAlQuraVsISODates") + public void Test_UmmAlQuraVsISODates(HijrahDate hd, LocalDate ld) { assertEquals(hd.toEpochDay(), ld.toEpochDay(), "Umm alQura date and ISO date should have same epochDay"); } - + // UmmAlQura chronology ranges for year, month and days for the HijrahChronology @Test public void Test_UmmAlQuraChronoRange() { HijrahChronology chrono = HijrahChronology.INSTANCE; ValueRange year = chrono.range(YEAR); - assertEquals(year.getMinimum(), 1432, "Minimum year"); - assertEquals(year.getLargestMinimum(), 1432, "Largest minimum year"); - assertEquals(year.getMaximum(), 1435, "Largest year"); - assertEquals(year.getSmallestMaximum(), 1435, "Smallest Maximum year"); + assertEquals(year.getMinimum(), 1300, "Minimum year"); + assertEquals(year.getLargestMinimum(), 1300, "Largest minimum year"); + assertEquals(year.getMaximum(), 1600, "Largest year"); + assertEquals(year.getSmallestMaximum(), 1600, "Smallest Maximum year"); ValueRange month = chrono.range(MONTH_OF_YEAR); assertEquals(month.getMinimum(), 1, "Minimum month"); @@ -118,13 +142,17 @@ // regular data factory for dates and the corresponding range values //----------------------------------------------------------------------- @DataProvider(name = "dates") - Object[][] data_of_calendars() { + Object[][] data_dates() { return new Object[][]{ - {HijrahDate.of(1434, 5, 1), 1432, 1435, 1, 12, 1, 29, 30}, - {HijrahDate.of(1434, 6, 1), 1432, 1435, 1, 12, 1, 30, 30}, + {HijrahDate.of(1300, 5, 1), 1300, 1600, 1, 12, 1, 30, 30}, + {HijrahDate.of(1300, 6, 1), 1300, 1600, 1, 12, 1, 29, 30}, + {HijrahDate.of(1434, 12, 1), 1300, 1600, 1, 12, 1, 29, 30}, + {HijrahDate.of(1500, 4, 1), 1300, 1600, 1, 12, 1, 30, 30}, + {HijrahDate.of(1600, 6, 1), 1300, 1600, 1, 12, 1, 29, 30}, }; } + // Test to verify the min/max field ranges for given dates @Test(dataProvider="dates") public void Test_UmmAlQuraRanges(HijrahDate date, int minYear, int maxYear, @@ -163,6 +191,7 @@ } + // Check the date limits @Test public void test_hijrahDateLimits() { HijrahChronology chrono = HijrahChronology.INSTANCE; @@ -193,33 +222,547 @@ } } - @DataProvider(name="badDates") - Object[][] data_badDates() { + // Data provider to verify the dateYearDay() method + @DataProvider(name="dateYearDay") + Object[][] data_dateYearDay() { return new Object[][] { - {1317, 12, 29}, - {1317, 12, 30}, + {HijrahChronology.INSTANCE.dateYearDay(1434, 42), HijrahChronology.INSTANCE.date(1434, 02, 13)}, + {HijrahChronology.INSTANCE.dateYearDay(1330, 354), HijrahChronology.INSTANCE.date(1330, 12, 29)}, + {HijrahChronology.INSTANCE.dateYearDay(1600, 1), HijrahChronology.INSTANCE.date(1600, 1, 1)}, + {HijrahChronology.INSTANCE.dateYearDay(1400, 175), HijrahChronology.INSTANCE.date(1400, 6, 28)}, + {HijrahChronology.INSTANCE.dateYearDay(1520, 190), HijrahChronology.INSTANCE.date(1520, 7, 13)}, + {HijrahChronology.INSTANCE.dateYearDay(1521, 112), HijrahChronology.INSTANCE.date(1521, 4, 25)}, + }; + } + + // Test to verify the dateYearDay() method + @Test(dataProvider="dateYearDay") + public void test_DateYearDay(ChronoLocalDate date1, ChronoLocalDate date2) { + assertEquals(date1, date2); + } + + //----------------------------------------------------------------------- + // HijrahDate.with(DAY_OF_YEAR, n) + //----------------------------------------------------------------------- + @Test + public void test_getDayOfYear() { + HijrahDate hd1 = HijrahChronology.INSTANCE.dateYearDay(1434, 1); + for (int i = 1; i <= hd1.lengthOfYear(); i++) { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1434, i); + int doy = hd.get(DAY_OF_YEAR); + assertEquals(doy, i, "get(DAY_OF_YEAR) incorrect for " + i); + } + } + + @Test + public void test_withDayOfYear() { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1434, 1); + for (int i = 1; i <= hd.lengthOfYear(); i++) { + HijrahDate hd2 = hd.with(DAY_OF_YEAR, i); + int doy = hd2.get(DAY_OF_YEAR); + assertEquals(doy, i, "with(DAY_OF_YEAR) incorrect for " + i + " " + hd2); + } + } + + @Test(expectedExceptions=java.time.DateTimeException.class) + public void test_withDayOfYearTooSmall() { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1435, 1); + HijrahDate hd2 = hd.with(DAY_OF_YEAR, 0); + } + + @Test(expectedExceptions=java.time.DateTimeException.class) + public void test_withDayOfYearTooLarge() { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1435, 1); + HijrahDate hd2 = hd.with(DAY_OF_YEAR, hd.lengthOfYear() + 1); + } + + // Test to verify the with() method with ChronoField is set to DAY_OF_WEEK + @Test + public void test_adjustWithDayOfWeek() { + assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_WEEK, 4), HijrahDate.of(1320, 1, 15)); + assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_WEEK, 1), HijrahDate.of(1421, 11, 11)); + assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_WEEK, 6), HijrahDate.of(1529, 7, 20)); + assertEquals(HijrahChronology.INSTANCE.date(1534, 2, 10).with(ChronoField.DAY_OF_WEEK, 5), HijrahDate.of(1534, 2, 12)); + assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_WEEK, 2), HijrahDate.of(1552, 3, 26)); + } + + // Test to verify the with() method with ChronoField is set to DAY_OF_MONTH + @Test + public void test_adjustWithDayOfMonth() { + assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_MONTH, 2), HijrahDate.of(1320, 1, 2)); + assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_MONTH, 9), HijrahDate.of(1421, 11, 9)); + assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_MONTH, 13), HijrahDate.of(1529, 7, 13)); + assertEquals(HijrahChronology.INSTANCE.date(1534, 12, 10).with(ChronoField.DAY_OF_MONTH, 29), HijrahDate.of(1534, 12, 29)); + assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_MONTH, 6), HijrahDate.of(1552, 4, 6)); + } + + // Test to verify the with() method with ChronoField is set to DAY_OF_YEAR + @Test + public void test_adjustWithDayOfYear() { + assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_YEAR, 24), HijrahDate.of(1320, 1, 24)); + assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_YEAR, 135), HijrahDate.of(1421, 5, 18)); + assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_YEAR, 64), HijrahDate.of(1529, 3, 5)); + assertEquals(HijrahChronology.INSTANCE.date(1534, 2, 10).with(ChronoField.DAY_OF_YEAR, 354), HijrahDate.of(1534, 12, 29)); + assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_YEAR, 291), HijrahDate.of(1552, 10, 26)); + } + + // Data provider to get the difference between two dates in terms of days, months and years + @DataProvider(name="datesForDiff") + Object[][] data_datesForDiffs() { + return new Object[][] { + {HijrahDate.of(1350, 5, 15), HijrahDate.of(1351, 12, 29), 574, 19, 1}, + {HijrahDate.of(1434, 5, 1), HijrahDate.of(1434,6, 12), 40, 1, 0}, + {HijrahDate.of(1436, 1, 1), HijrahDate.of(1475, 12, 29), 14173, 479, 39}, + {HijrahDate.of(1500, 6, 12), HijrahDate.of(1551, 7, 12), 18102, 613, 51}, + {HijrahDate.of(1550, 3, 11), HijrahDate.of(1551, 4, 11), 384, 13, 1}, + }; + } + + // Test to verify the difference between two given dates in terms of days, months and years + @Test(dataProvider="datesForDiff") + public void test_diffBetweenDates(ChronoLocalDate from, ChronoLocalDate to, long days, long months, long years) { + assertEquals(from.until(to, ChronoUnit.DAYS), days); + assertEquals(from.until(to, ChronoUnit.MONTHS), months); + assertEquals(from.until(to, ChronoUnit.YEARS), years); + } + + // Data provider to get the difference between two dates as a period + @DataProvider(name="datesForPeriod") + Object[][] data_Period() { + return new Object[][] { + {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), Period.of(84, 2, 5)}, + {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), Period.of(31, 1, 22)}, + {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), Period.of(49, 6, 24)}, + {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), Period.of(-50, -1, -20)}, + {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), Period.of(0, 11, 28)}, + }; + } + + // Test to get the Period between two given dates + @Test(dataProvider="datesForPeriod") + public void test_until(HijrahDate h1, HijrahDate h2, Period p) { + Period period = h1.until(h2); + assertEquals(period, p); + } - {1320, 1, 29 + 1}, - {1320, 2, 30 + 1}, - {1320, 3, 29 + 1}, - {1320, 4, 29 + 1}, - {1320, 5, 30 + 1}, - {1320, 6, 29 + 1}, - {1320, 7, 30 + 1}, - {1320, 8, 30 + 1}, - {1320, 9, 29 + 1}, - {1320, 10, 30 + 1}, - {1320, 11, 30 + 1}, - {1320, 12, 30 + 1}, + // Test to get the Period between dates in different chronologies + @Test(dataProvider="datesForPeriod") + public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, Period p) { + MinguoDate m = MinguoChronology.INSTANCE.date(h2); + Period period = h1.until(m); + assertEquals(period, p); + } + + // Test to get the adjusted date from a given date using TemporalAdjuster methods + @Test + public void test_temporalDayAdjustments() { + HijrahDate date = HijrahDate.of(1554, 7, 21); + assertEquals(date.with(TemporalAdjuster.firstDayOfMonth()), HijrahDate.of(1554, 7, 1)); + assertEquals(date.with(TemporalAdjuster.lastDayOfMonth()), HijrahDate.of(1554, 7, 29)); + assertEquals(date.with(TemporalAdjuster.firstDayOfNextMonth()), HijrahDate.of(1554, 8, 1)); + assertEquals(date.with(TemporalAdjuster.firstDayOfNextYear()), HijrahDate.of(1555, 1, 1)); + assertEquals(date.with(TemporalAdjuster.firstDayOfYear()), HijrahDate.of(1554, 1, 1)); + assertEquals(date.with(TemporalAdjuster.lastDayOfYear()), HijrahDate.of(1554, 12, 30)); + } + + // Data provider for string representation of the date instances + @DataProvider(name="toString") + Object[][] data_toString() { + return new Object[][] { + {HijrahChronology.INSTANCE.date(1320, 1, 1), "Hijrah-umalqura AH 1320-01-01"}, + {HijrahChronology.INSTANCE.date(1500, 10, 28), "Hijrah-umalqura AH 1500-10-28"}, + {HijrahChronology.INSTANCE.date(1500, 10, 29), "Hijrah-umalqura AH 1500-10-29"}, + {HijrahChronology.INSTANCE.date(1434, 12, 5), "Hijrah-umalqura AH 1434-12-05"}, + {HijrahChronology.INSTANCE.date(1434, 12, 6), "Hijrah-umalqura AH 1434-12-06"}, + }; + } + + // Test to verify the returned string value of a given date instance + @Test(dataProvider="toString") + public void test_toString(ChronoLocalDate hijrahDate, String expected) { + assertEquals(hijrahDate.toString(), expected); + } + + // Data provider for maximum number of days + @DataProvider(name="monthDays") + Object[][] data_monthDays() { + return new Object[][] { + {1432, 1, 29}, + {1432, 4, 30}, + {1433, 12, 29}, + {1434, 1, 29}, + {1435, 8, 29}, + {1435, 9, 30}, + }; + } + + // Test to verify the maximum number of days by adding one month to a given date + @Test (dataProvider="monthDays") + public void test_valueRange_monthDays(int year, int month, int maxlength) { + ChronoLocalDate date = HijrahChronology.INSTANCE.date(year, month, 1); + ValueRange range = null; + for (int i=1; i<=12; i++) { + range = date.range(ChronoField.DAY_OF_MONTH); + date = date.plus(1, ChronoUnit.MONTHS); + assertEquals(range.getMaximum(), month, maxlength); + } + } + + // Test to get the last day of the month by adjusting the date with lastDayOfMonth() method + @Test(dataProvider="monthDays") + public void test_lastDayOfMonth(int year, int month, int numDays) { + HijrahDate hDate = HijrahChronology.INSTANCE.date(year, month, 1); + hDate = hDate.with(TemporalAdjuster.lastDayOfMonth()); + assertEquals(hDate.get(ChronoField.DAY_OF_MONTH), numDays); + } + + // Data provider for the 12 islamic month names in a formatted date + @DataProvider(name="patternMonthNames") + Object[][] data_patternMonthNames() { + return new Object[][] { + {1434, 1, 1, "01 AH Thu Muharram 1434"}, + {1434, 2, 1, "01 AH Fri Safar 1434"}, + {1434, 3, 1, "01 AH Sun Rabi\u02bb I 1434"},//the actual month name is Rabi Al-Awwal, but the locale data contains short form. + {1434, 4, 1, "01 AH Mon Rabi\u02bb II 1434"},//the actual month name is Rabi Al-Akhar, but the locale data contains short form. + {1434, 5, 1, "01 AH Wed Jumada I 1434"},//the actual month name is Jumada Al-Awwal, but the locale data contains short form. + {1434, 6, 1, "01 AH Thu Jumada II 1434"},//the actual month name is Jumada Al-Akhar, but the locale data contains short form. + {1434, 7, 1, "01 AH Sat Rajab 1434"}, + {1434, 8, 1, "01 AH Mon Sha\u02bbban 1434"}, + {1434, 9, 1, "01 AH Tue Ramadan 1434"}, + {1434, 10, 1, "01 AH Thu Shawwal 1434"}, + {1434, 11, 1, "01 AH Sat Dhu\u02bbl-Qi\u02bbdah 1434"}, + {1434, 12, 1, "01 AH Sun Dhu\u02bbl-Hijjah 1434"}, + }; + } + + // Test to verify the formatted dates + @Test(dataProvider="patternMonthNames") + public void test_ofPattern(int year, int month, int day, String expected) { + DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy"); + assertEquals(test.format(HijrahDate.of(year, month, day)), expected); + } + + // Data provider for localized dates + @DataProvider(name="chronoDateTimes") + Object[][] data_chronodatetimes() { + return new Object[][] { + {1432, 12, 29, "Safar 1, 1434 AH"}, + {1433, 1, 30, "Safar 30, 1434 AH"}, + {1434, 6, 30, "Rajab 30, 1435 AH"}, + }; + } + + // Test to verify the localized dates using ofLocalizedDate() method + @Test(dataProvider="chronoDateTimes") + public void test_formatterOfLocalizedDate(int year, int month, int day, String expected) { + HijrahDate hd = HijrahChronology.INSTANCE.date(year, month, day); + ChronoLocalDateTime<HijrahDate> hdt = hd.atTime(LocalTime.NOON); + hdt = hdt.plus(1, ChronoUnit.YEARS); + hdt = hdt.plus(1, ChronoUnit.MONTHS); + hdt = hdt.plus(1, ChronoUnit.DAYS); + hdt = hdt.plus(1, ChronoUnit.HOURS); + hdt = hdt.plus(1, ChronoUnit.MINUTES); + hdt = hdt.plus(1, ChronoUnit.SECONDS); + DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.forLanguageTag("en-US")); + assertEquals(df.format(hdt), expected); + } + + // Data provider to get the day of the week in a given date + // The day of the week varies if the week starts with a saturday or sunday + @DataProvider(name="dayOfWeek") + Object[][] data_dayOfweek() { + return new Object[][] { + {HijrahDate.of(1434, 6, 24), 1, 7}, + {HijrahDate.of(1432, 9, 3), 5, 4}, + {HijrahDate.of(1334, 12, 29), 7, 6}, + {HijrahDate.of(1354, 5, 24), 1, 7}, + {HijrahDate.of(1465, 10, 2), 2, 1}, }; } - @Test(dataProvider="badDates", expectedExceptions=DateTimeException.class) - public void test_badDates(int year, int month, int dom) { - HijrahChronology.INSTANCE.date(year, month, dom); + // Test to get the day of the week based on a Saturday/Sunday as the first day of the week + @Test(dataProvider="dayOfWeek") + public void test_dayOfWeek(HijrahDate date, int satStart, int sunStart) { + assertEquals(date.get(WeekFields.of(DayOfWeek.SATURDAY, 7).dayOfWeek()), satStart); + assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 7).dayOfWeek()), sunStart); + } + + // Data sample to get the epoch days of a date instance + @DataProvider(name="epochDays") + Object[][] data_epochdays() { + return new Object[][] { + {1332, -20486}, + {1334, -19777}, + {1336, -19068}, + {1432, 14950}, + {1434, 15659}, + {1534, 51096}, + {1535, 51450}, + }; + } + + // Test to verify the number of epoch days of a date instance + @Test(dataProvider="epochDays") + public void test_epochDays(int y, long epoch) { + HijrahDate date = HijrahDate.of(y, 1, 1); + assertEquals(date.toEpochDay(), epoch); + } + + // Data provider to verify whether a given hijrah year is a leap year or not + @DataProvider(name="leapYears") + Object[][] data_leapyears() { + return new Object[][] { + {1302, true}, + {1305, false}, + {1315, false}, + {1534, false}, + {1411, true}, + {1429, false}, + {1433, true}, + {1443, true}, + }; + } + + // Test to verify whether a given hijrah year is a leap year or not + @Test(dataProvider="leapYears") + public void test_leapYears(int y, boolean leapyear) { + HijrahDate date = HijrahDate.of(y, 1, 1); + assertEquals(date.isLeapYear(), leapyear); + } + + // Date samples to convert HijrahDate to LocalDate and vice versa + @DataProvider(name="samples") + Object[][] data_samples() { + return new Object[][] { + {HijrahChronology.INSTANCE.date(1319, 12, 30), LocalDate.of(1902, 4, 9)}, + {HijrahChronology.INSTANCE.date(1320, 1, 1), LocalDate.of(1902, 4, 10)}, + {HijrahChronology.INSTANCE.date(1321, 12, 30), LocalDate.of(1904, 3, 18)}, + {HijrahChronology.INSTANCE.date(1433, 7, 29), LocalDate.of(2012, 6, 19)}, + {HijrahChronology.INSTANCE.date(1434, 10, 12), LocalDate.of(2013, 8, 19)}, + {HijrahChronology.INSTANCE.date(1500, 3, 3), LocalDate.of(2077, 1, 28)}, + }; + } + + // Test to get LocalDate instance from a given HijrahDate + @Test(dataProvider="samples") + public void test_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(LocalDate.from(hijrahDate), iso); + } + + // Test to adjust HijrahDate with a given LocalDate + @Test(dataProvider="samples") + public void test_adjust_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(hijrahDate.with(iso), hijrahDate); + } + + // Test to get a HijrahDate from a calendrical + @Test(dataProvider="samples") + public void test_fromCalendrical(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(HijrahChronology.INSTANCE.date(iso), hijrahDate); + } + + // Test to verify the day of week of a given HijrahDate and LocalDate + @Test(dataProvider="samples") + public void test_dayOfWeekEqualIsoDayOfWeek(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(hijrahDate.get(ChronoField.DAY_OF_WEEK), iso.get(ChronoField.DAY_OF_WEEK), "Hijrah day of week should be same as ISO day of week"); + } + + // Test to get the local date by applying the MIN adjustment with hijrah date + @Test(dataProvider="samples") + public void test_LocalDate_adjustToHijrahDate(ChronoLocalDate hijrahDate, LocalDate localDate) { + LocalDate test = LocalDate.MIN.with(hijrahDate); + assertEquals(test, localDate); + } + + // Test to get the local date time by applying the MIN adjustment with hijrah date + @Test(dataProvider="samples") + public void test_LocalDateTime_adjustToHijrahDate(ChronoLocalDate hijrahDate, LocalDate localDate) { + LocalDateTime test = LocalDateTime.MIN.with(hijrahDate); + assertEquals(test, LocalDateTime.of(localDate, LocalTime.MIDNIGHT)); + } + + // Sample dates for comparison + @DataProvider(name="datesForComparison") + Object[][] data_datesForComparison() { + return new Object[][] { + {HijrahChronology.INSTANCE.date(1434, 6, 26), LocalDate.of(2013, 5, 5), -1, 1}, + {HijrahChronology.INSTANCE.date(1433, 4, 15), LocalDate.of(2012, 3, 15), 1, -1}, + {HijrahChronology.INSTANCE.date(1432, 5, 21), LocalDate.of(2011, 4, 22), -1, 1}, + {HijrahChronology.INSTANCE.date(1433, 7, 29), LocalDate.of(2012, 6, 2), -1, 1}, + {HijrahChronology.INSTANCE.date(1434, 10, 12), LocalDate.of(2013, 8, 2), -1, 1}, + }; + } + + // Test to compare dates in both forward and reverse order + @Test(dataProvider="datesForComparison") + public void test_compareDates(HijrahDate hdate, LocalDate ldate, int result1, int result2) { + assertEquals(ldate.compareTo(hdate), result1); + assertEquals(hdate.compareTo(ldate), result2); + } + + // Test to verify the values of various chrono fields for a given hijrah date instance + @Test + public void test_chronoFields() { + ChronoLocalDate hdate = HijrahChronology.INSTANCE.date(1434, 6, 28); + assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 3); + assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 7); + assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_MONTH), 4); + assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_YEAR), 25); + assertEquals(hdate.get(ChronoField.ERA), 1); + assertEquals(hdate.get(ChronoField.YEAR_OF_ERA), 1434); + assertEquals(hdate.get(ChronoField.MONTH_OF_YEAR), 6); + assertEquals(hdate.get(ChronoField.DAY_OF_MONTH), 28); + assertEquals(hdate.get(ChronoField.DAY_OF_WEEK), 3); + assertEquals(hdate.get(ChronoField.DAY_OF_YEAR), 175); } - void printRange(ValueRange range, Object obj, ChronoField field) { - System.err.printf(" range: min: %d, max: %d; of: %s, field: %s%n", range.getMinimum(), range.getMaximum(), obj.toString(), field.toString()); + // Test to verify the returned hijrah date after adjusting the day of week as Saturday + @Test + public void test_adjustInto() { + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 6, 28)), HijrahDate.of(1434, 7, 1)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1432, 4, 13)), HijrahDate.of(1432, 4, 14)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1433, 11, 29)), HijrahDate.of(1433, 12, 4)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 5, 10)), HijrahDate.of(1434, 5, 11)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 9, 11)), HijrahDate.of(1434, 9, 12)); + } + + //----------------------------------------------------------------------- + // zonedDateTime(TemporalAccessor) + //----------------------------------------------------------------------- + @DataProvider(name="zonedDateTime") + Object[][] data_zonedDateTime() { + return new Object[][] { + {ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {LocalDateTime.of(2012, 2, 29, 2, 7), null, null, DateTimeException.class}, + {JapaneseDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {ThaiBuddhistDate.of(2012 + 543, 2, 29), null, null, DateTimeException.class}, + {LocalDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {LocalTime.of(20, 30, 29, 0), null, null, DateTimeException.class}, + }; + } + + // Test to check the zoned date times + @Test(dataProvider="zonedDateTime") + public void test_zonedDateTime(TemporalAccessor accessor, HijrahDate expectedDate, LocalTime expectedTime, Class<?> expectedEx) { + if (expectedEx == null) { + ChronoZonedDateTime<HijrahDate> result = HijrahChronology.INSTANCE.zonedDateTime(accessor); + assertEquals(result.toLocalDate(), expectedDate); + assertEquals(HijrahDate.from(accessor), expectedDate); + assertEquals(result.toLocalTime(), expectedTime); + + } else { + try { + ChronoZonedDateTime<HijrahDate> result = HijrahChronology.INSTANCE.zonedDateTime(accessor); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } + + //----------------------------------------------------------------------- + // zonedDateTime(Instant, ZoneId ) + //----------------------------------------------------------------------- + @Test + public void test_Instant_zonedDateTime() { + OffsetDateTime offsetDateTime = OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO); + ZonedDateTime zonedDateTime = ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH); + + ChronoZonedDateTime<HijrahDate> result = HijrahChronology.INSTANCE.zonedDateTime(offsetDateTime.toInstant(), offsetDateTime.getOffset()); + assertEquals(result.toLocalDate(), HijrahChronology.INSTANCE.date(1433, 4, 7)); + assertEquals(result.toLocalTime(), LocalTime.of(2, 7, 1, 1)); + + result = HijrahChronology.INSTANCE.zonedDateTime(zonedDateTime.toInstant(), zonedDateTime.getOffset()); + assertEquals(result.toLocalDate(), HijrahChronology.INSTANCE.date(1433, 4, 7)); + assertEquals(result.toLocalTime(), LocalTime.of(2, 7, 1, 1)); + } + + //----------------------------------------------------------------------- + // localDateTime() + //----------------------------------------------------------------------- + @DataProvider(name="localDateTime") + Object[][] data_localDateTime() { + return new Object[][] { + {LocalDateTime.of(2012, 2, 29, 2, 7), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7), null}, + {ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {JapaneseDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {ThaiBuddhistDate.of(2012 + 543, 2, 29), null, null, DateTimeException.class}, + {LocalDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {LocalTime.of(20, 30, 29, 0), null, null, DateTimeException.class}, + }; + } + + // Test to verify local date time values from various date instances defined in the localDateTime data provider + @Test(dataProvider="localDateTime") + public void test_localDateTime(TemporalAccessor accessor, HijrahDate expectedDate, LocalTime expectedTime, Class<?> expectedEx) { + if (expectedEx == null) { + ChronoLocalDateTime<HijrahDate> result = HijrahChronology.INSTANCE.localDateTime(accessor); + assertEquals(result.toLocalDate(), expectedDate); + assertEquals(HijrahDate.from(accessor), expectedDate); + assertEquals(result.toLocalTime(), expectedTime); + } else { + try { + ChronoLocalDateTime<HijrahDate> result = HijrahChronology.INSTANCE.localDateTime(accessor); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } + + // Sample Hijrah & Minguo Dates + @DataProvider(name="hijrahToMinguo") + Object[][] data_hijrahToMinguo() { + return new Object[][] { + {HijrahDate.of(1350,5,15), MinguoDate.of(20,9,28)}, + {HijrahDate.of(1434,5,1), MinguoDate.of(102,3,13)}, + {HijrahDate.of(1436,1,1), MinguoDate.of(103,10,25)}, + {HijrahDate.of(1500,6,12), MinguoDate.of(166,5,5)}, + {HijrahDate.of(1550,3,11), MinguoDate.of(214,8,11)}, + }; + } + + // Test to verify the date conversion from Hijrah to Minguo chronology + @Test(dataProvider="hijrahToMinguo") + public void test_hijrahToMinguo(HijrahDate hijrah, MinguoDate minguo) { + assertEquals(MinguoChronology.INSTANCE.date(hijrah), minguo); + } + + // Sample Hijrah & Thai Dates + @DataProvider(name="hijrahToThai") + Object[][] data_hijrahToThai() { + return new Object[][] { + {HijrahDate.of(1350,5,15), ThaiBuddhistDate.of(2474,9,28)}, + {HijrahDate.of(1434,5,1), ThaiBuddhistDate.of(2556,3,13)}, + {HijrahDate.of(1436,1,1), ThaiBuddhistDate.of(2557,10,25)}, + {HijrahDate.of(1500,6,12), ThaiBuddhistDate.of(2620,5,5)}, + {HijrahDate.of(1550,3,11), ThaiBuddhistDate.of(2668,8,11)}, + }; + } + + // Test to verify the date conversion from Hijrah to Thai chronology + @Test(dataProvider="hijrahToThai") + public void test_hijrahToThai(HijrahDate hijrah, ThaiBuddhistDate thai) { + assertEquals(ThaiBuddhistChronology.INSTANCE.date(hijrah), thai); + } + + // Sample Hijrah & Japanese Dates + @DataProvider(name="hijrahToJapanese") + Object[][] data_hijrahToJapanese() { + return new Object[][] { + {HijrahDate.of(1350,5,15), "Japanese Showa 6-09-28"}, + {HijrahDate.of(1434,5,1), "Japanese Heisei 25-03-13"}, + {HijrahDate.of(1436,1,1), "Japanese Heisei 26-10-25"}, + {HijrahDate.of(1500,6,12), "Japanese Heisei 89-05-05"}, + {HijrahDate.of(1550,3,11), "Japanese Heisei 137-08-11"}, + }; + } + + // Test to verify the date conversion from Hijrah to Japanese chronology + @Test(dataProvider="hijrahToJapanese") + public void test_hijrahToJapanese(HijrahDate hijrah, String japanese) { + assertEquals(JapaneseChronology.INSTANCE.date(hijrah).toString(), japanese); } }
--- a/test/java/time/test/java/time/format/TestDateTimeTextProvider.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/format/TestDateTimeTextProvider.java Wed Jul 24 08:22:32 2013 -0300 @@ -131,18 +131,18 @@ {MONTH_OF_YEAR, 11, TextStyle.SHORT, enUS, "Nov"}, {MONTH_OF_YEAR, 12, TextStyle.SHORT, enUS, "Dec"}, - {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "Jan"}, - {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "Fev"}, - {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "Mar"}, - {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "Abr"}, - {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "Mai"}, - {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "Jun"}, - {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "Jul"}, - {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "Ago"}, - {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "Set"}, - {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "Out"}, - {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "Nov"}, - {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "Dez"}, + {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"}, + {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"}, + {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"}, + {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"}, + {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"}, + {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"}, + {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"}, + {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"}, + {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"}, + {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"}, + {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"}, + {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"}, {MONTH_OF_YEAR, 1, TextStyle.FULL, enUS, "January"}, {MONTH_OF_YEAR, 2, TextStyle.FULL, enUS, "February"},
--- a/test/java/time/test/java/time/format/TestNonIsoFormatter.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/format/TestNonIsoFormatter.java Wed Jul 24 08:22:32 2013 -0300 @@ -126,7 +126,7 @@ @Test(dataProvider="format_data") public void test_formatLocalizedDate(Chronology chrono, Locale formatLocale, Locale numberingLocale, - ChronoLocalDate<?> date, String expected) { + ChronoLocalDate date, String expected) { DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL) .withChronology(chrono).withLocale(formatLocale) .withDecimalStyle(DecimalStyle.of(numberingLocale)); @@ -136,12 +136,12 @@ @Test(dataProvider="format_data") public void test_parseLocalizedText(Chronology chrono, Locale formatLocale, Locale numberingLocale, - ChronoLocalDate<?> expected, String text) { + ChronoLocalDate expected, String text) { DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL) .withChronology(chrono).withLocale(formatLocale) .withDecimalStyle(DecimalStyle.of(numberingLocale)); TemporalAccessor temporal = dtf.parse(text); - ChronoLocalDate<?> date = chrono.date(temporal); + ChronoLocalDate date = chrono.date(temporal); assertEquals(date, expected); }
--- a/test/java/time/test/java/time/format/TestNumberPrinter.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/format/TestNumberPrinter.java Wed Jul 24 08:22:32 2013 -0300 @@ -191,7 +191,7 @@ assertEquals(buf.toString(), result); } catch (DateTimeException ex) { if (result == null || value < 0) { - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } else { throw ex; } @@ -210,7 +210,7 @@ if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } @@ -226,7 +226,7 @@ if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } @@ -242,7 +242,7 @@ if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } @@ -262,7 +262,7 @@ if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } }
--- a/test/java/time/test/java/time/format/TestReducedPrinter.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/format/TestReducedPrinter.java Wed Jul 24 08:22:32 2013 -0300 @@ -185,7 +185,7 @@ assertEquals(buf.toString(), result); } catch (DateTimeException ex) { if (result == null || value < 0) { - assertEquals(ex.getMessage().contains(YEAR.getName()), true); + assertEquals(ex.getMessage().contains(YEAR.toString()), true); } else { throw ex; }
--- a/test/java/time/test/java/time/temporal/MockFieldNoValue.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/temporal/MockFieldNoValue.java Wed Jul 24 08:22:32 2013 -0300 @@ -77,11 +77,6 @@ INSTANCE; @Override - public String getName() { - return null; - } - - @Override public TemporalUnit getBaseUnit() { return WEEKS; } @@ -96,6 +91,16 @@ return ValueRange.of(1, 20); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + //----------------------------------------------------------------------- @Override public boolean isSupportedBy(TemporalAccessor temporal) { @@ -117,4 +122,9 @@ throw new DateTimeException("Mock"); } + @Override + public String toString() { + return null; + } + }
--- a/test/java/time/test/java/time/temporal/MockFieldValue.java Tue Jul 16 09:09:09 2013 -0300 +++ b/test/java/time/test/java/time/temporal/MockFieldValue.java Wed Jul 24 08:22:32 2013 -0300 @@ -89,7 +89,7 @@ if (isSupported(field)) { return field.range(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); }